@streamoji/aitwin 0.1.4 → 0.1.6

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/README.md CHANGED
@@ -53,7 +53,7 @@ Provide **`id`** (cloud twin) **or** **`assets`** (fixed URLs). One is required.
53
53
  | `id` | Twin id for `getAiTwin` (e.g. `olivia`) |
54
54
  | `assets` | `{ twinBase, binBase, encrypted }` — skip `getAiTwin` (lab / custom CDN) |
55
55
  | `authToken` | Bearer for TTS + encrypted assets; omitted → dev `getAuthToken` |
56
- | `ttsEngineId` | TTS engine when using `assets` (default Google) |
56
+ | `ttsEngineId` | TTS engine when using `assets` (default Cartesia) |
57
57
  | `voiceId` | Override TTS voice |
58
58
  | `speakingRate` | Default `0.85` |
59
59
  | `showErrorOverlay` | Canvas error overlay (default `true`) |
package/dist/aitwin.cjs CHANGED
@@ -1,3 +1,3 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const Me=require("react/jsx-runtime"),_=require("react"),At="https://pub-607ad1fc22e2400eb57d17240aab857c.r2.dev",ot={publicBase:At},vt="0.1.4",Rt={version:vt},Ae="https://ai.streamoji.com",bt=`${ot.publicBase}/custom-faces`,Dt=`${ot.publicBase}/aitwin-workers/v${Rt.version}/visemeDiffPreview.worker.js`,xt="https://us-central1-streamoji-265f4.cloudfunctions.net/getAiTwin",te="eng_a7f2b9c1",we="eng_d4e8f3a2",ge="eng_c9b1e6d4",He=we,Ct=new Set([we,ge]),at={[te]:"oculus_direct",[ge]:"oculus_direct",[we]:"inworld_word"},je={google:te,inworld:we,cartesia:ge};function Mt(e){return at[e]}function Pt(e){return e===ge}function Ft(e){if(e.ttsEngineId&&e.ttsEngineId in at)return e.ttsEngineId;const t=e.tts?.toLowerCase();return t&&t in je?je[t]:He}class ve extends Error{constructor(t="AI twin not found"){super(t),this.name="AiTwinNotFoundError"}}async function ct(e,t=xt){const n=new URL(t);n.searchParams.set("id",e);const r=await fetch(n.toString());if(r.status===404)throw new ve;if(!r.ok)throw new Error(`getAiTwin failed (${r.status})`);const s=await r.json();if(!s.success)throw new ve(s.error??"AI twin not found");const{tts:o,...a}=s.data;return{...a,ttsEngineId:Ft(s.data)}}const Ot="https://us-central1-streamoji-265f4.cloudfunctions.net/getAuthToken",Lt="client_6TNvp3SCs4Og0a1ijm9TommXLql1",Nt="kk8Fq8EmexzP10jMIEwY3R44M5RKUEm1",Ut="6TNvp3SCs4Og0a1ijm9TommXLql1",Bt="Swaraj Mali";async function Fe(){const e=await fetch(Ot,{method:"POST",headers:{"Content-Type":"application/json","Client-Id":Lt,"Client-Secret":Nt},body:JSON.stringify({userId:Ut,userName:Bt})});if(!e.ok)throw new Error(`getAuthToken failed (${e.status})`);const t=await e.json(),n=t.authToken??t.token??"";if(!n.trim())throw new Error("getAuthToken returned no token");return n}async function Vt(e,t=Ae){const n=await fetch(`${t.replace(/\/$/,"")}/api/session-value`,{headers:{Authorization:`Bearer ${e}`}});if(!n.ok)throw new Error(`/api/session-value failed (${n.status})`);const r=await n.json();if(!r.value)throw new Error("Session value response missing value");return r}function $t(e){const t=e.trim();if(t.length%2!==0)throw new Error("Invalid hex key");const n=new Uint8Array(t.length/2);for(let r=0;r<t.length;r+=2)n[r/2]=Number.parseInt(t.slice(r,r+2),16);return n}function Se(e){return Uint8Array.from(e)}function Ht(e,t){const n=new Uint8Array(e.length+t.length);return n.set(e,0),n.set(t,e.length),n}async function Wt(e,t){if(!t)throw new Error("Asset key is required for encrypted assets");if(e.byteLength<28)throw new Error("Encrypted payload too small");const n=new Uint8Array(e),r=Se(n.subarray(0,12)),s=Se(n.subarray(12,28)),o=Se(n.subarray(28)),a=Se(Ht(o,s)),c=await crypto.subtle.importKey("raw",$t(t),{name:"AES-GCM"},!1,["decrypt"]);return crypto.subtle.decrypt({name:"AES-GCM",iv:r,tagLength:128},c,a)}let Oe=null;const Le=new Set;function Kt(e,t=bt){const n=`${t.replace(/\/$/,"")}/${e}`;return{twinBase:n,binBase:n,encrypted:!0}}function qt(e){Oe=e;for(const t of Le)t()}function ne(){if(!Oe)throw new Error("Twin assets not configured; call setActiveTwinAssets first");return Oe}function Gt(e){return Le.add(e),()=>Le.delete(e)}function jt(){return`${ne().twinBase}/sil.png`}function zt(){return`${ne().twinBase}/idle.mp4`}function Qt(){const{encrypted:e,binBase:t,twinBase:n}=ne();return e?t:n}function ut(){return ne().encrypted}function Jt(){const{binBase:e,twinBase:t,encrypted:n}=ne();return n?`${e}/atlas.bin`:`${t}/atlas.json`}function Xt(){const{binBase:e,twinBase:t,encrypted:n}=ne();return n?`${e}/expression_atlas.bin`:`${t}/expression_atlas.json`}function Yt(e){const t=e.split(/\r?\n/);let n="",r="";for(const o of t)o.startsWith("event:")?n=o.slice(6).trim():o.startsWith("data:")&&(r=o.slice(5).trim());if(!n)return null;let s={};if(r)try{s=JSON.parse(r)}catch{s={raw:r}}return{event:n,data:s}}const lt=["aa","CH","DD","E","FF","I","O","PP","RR","SS","TH","U","kk","nn","sil"],Zt=new Map(lt.map(e=>[e.toLowerCase(),e]));function ft(e){const t=(e??"").trim();return t?Zt.get(t.toLowerCase())??"sil":"sil"}const en={aei:["aa","E","I"],o:["O","U"],ee:["I"],bmp:["PP"],fv:["FF"],l:["nn"],r:["RR"],th:["TH"],qw:["U","O"],cdgknstxyz:["DD","SS","kk","CH"]};function tn(e){if(!e)return["sil"];const t=e.toLowerCase();return en[t]??["sil"]}function nn(e,t){const n=e.word.length;if(n<=0)return 0;const r=e.wduration;if(r<=0)return 0;const s=Math.max(0,Math.min(1,(t-e.wtime)/r));return Math.min(n-1,Math.floor(s*n))}function be(e,t){const n=Math.max(0,Math.min(e.length-1,t));return e[n]??""}function rn(e,t){const n=e.toLowerCase(),r=be(n,t),s=n.slice(Math.max(0,t-1),t+2);return r==="i"||r==="y"?"I":s.includes("ee")||r==="e"||n.includes("ea")?"E":"aa"}function sn(e,t){const n=e.toLowerCase(),r=n.slice(Math.max(0,t-1),Math.min(n.length,t+3));if(/oo|ou|uw/.test(r))return"U";const s=be(n,t);return s==="u"||s==="w"?"U":"O"}function on(e,t){const n=e.toLowerCase(),r=n.slice(Math.max(0,t-2),t+1);if(/qu/.test(r))return"U";const s=n.slice(Math.max(0,t-1),Math.min(n.length,t+3));return/wo|wh/.test(s)||be(n,t)==="o"?"O":"U"}const Te={d:"DD",t:"DD",n:"DD",s:"SS",z:"SS",k:"kk",g:"kk",c:"CH",x:"CH",j:"CH"};function an(e,t){const n=e.toLowerCase(),r=be(n,t);if(Te[r])return Te[r];for(let s=0;s<n.length;s++){const o=n[s];if(Te[o])return Te[o]}return"DD"}function cn(e,t,n){const r=tn(e);if(r.length===1)return r[0];const s=t.trim();if(!s)return r[0];const o=(e??"").toLowerCase(),a=Math.max(0,n);switch(o){case"aei":return rn(s,a);case"o":return sn(s,a);case"qw":return on(s,a);case"cdgknstxyz":return an(s,a);default:return r[0]}}function un(e){let t=e.trim();const n=t.indexOf(",");t.startsWith("data:")&&n>=0&&(t=t.slice(n+1)),t=t.replace(/\s+/g,"").replace(/-/g,"+").replace(/_/g,"/");const r=t.length%4;return r!==0&&(t+="=".repeat(4-r)),t}const ln=24e3;function fn(e){return e.length>=4&&e[0]===82&&e[1]===73&&e[2]===70&&e[3]===70}function ze(e,t,n=ln){const r=t.byteOffset%2===0?t:t.slice(),s=new Int16Array(r.buffer,r.byteOffset,r.byteLength/2),o=new Float32Array(s.length);for(let c=0;c<s.length;c++)o[c]=s[c]>=32768?-(65536-s[c])/32768:s[c]/32767;const a=e.createBuffer(1,o.length,n);return a.copyToChannel(o,0),a}function dn(e){const t=un(e),n=window.atob(t),r=new Uint8Array(n.length);for(let s=0;s<n.length;s++)r[s]=n.charCodeAt(s);return r}async function hn(e,t){const n=dn(t);if(fn(n)){const r=n.buffer.slice(n.byteOffset,n.byteOffset+n.byteLength);return e.decodeAudioData(r)}if(n.length>=2&&n.length%2===0)return ze(e,n);try{const r=n.buffer.slice(n.byteOffset,n.byteOffset+n.byteLength);return await e.decodeAudioData(r)}catch{return ze(e,n)}}function dt(e,t){let n=null;for(const r of e)t<r.vtime||t>=r.vtime+r.vduration||(!n||r.vtime>=n.vtime)&&(n=r);return n?n.viseme:"sil"}function ht(e,t){for(const n of e)if(t>=n.wtime&&t<n.wtime+n.wduration)return n;return null}function Qe(e){let t=0;for(const n of e)t=Math.max(t,n.vtime+n.vduration);return t}const _t=.5,mt=1.5,We="Olivia",wt="f786b574-daa5-4673-aa0c-cbe3e8534c02",Ke=.85;function gt(e,t=Ae){const n=`${t.replace(/\/$/,"")}/avatar_ttsWithPoses`,r=[],s=[],o=[];let a="neutral";const c=[],u=[];let m=null,d=!1,T=!1,f=!1,i=!1,g=0,v=0,E=0,$=0,F=null,B=1,Q="",w=te,y=te,b=!1;const R=new Set,H=()=>{for(const h of u)h.playbackRate.value=B},W=()=>R.forEach(h=>h()),ie=()=>{F!=null&&(clearTimeout(F),F=null)},Ee=()=>{for(const h of u)try{h.stop()}catch{}u.length=0},Y=()=>{b=!0,ie(),Ee(),c.length=0,d=!1,T=!1,f=!1,i=!1,r.length=0,s.length=0,o.length=0,a="neutral",E=0,$=0,v=0,e("idle"),W()},K=()=>{!i||d||u.length>0||c.length>0||(T=!1,ie(),e("done"),W())},ye=()=>{const h=Qe(r);if(h<=0){e("done"),W();return}T=!0,g=performance.now(),e("speaking"),W(),ie();const D=B>0?h/B:h;F=setTimeout(()=>{b||(T=!1,F=null,e("done"),W())},D)},xe=(h,D,N)=>{h.length!==0&&(N&&(E=D),h.forEach(M=>{const O=String(M.word??"").trim();if(!O)return;const z=Math.round((M.start??0)*1e3),U=Math.round((M.duration??0)*1e3);s.push({word:O,wtime:E+z,wduration:U,queueIndex:s.length})}))},oe=(h,D,N,M)=>{h.length!==0&&(N&&(E=D),h.forEach(S=>{const O=String(S.symbol??"").trim();if(!O)return;const z=Math.round((S.start??0)*1e3),U=Math.max(1,Math.round((S.duration??0)*1e3)),P=E+z;let x;if(Mt(M)==="oculus_direct")x=ft(O);else{const C=ht(s,P),J=C?nn(C,P):0;x=cn(O,C?.word??"",J)}r.push({viseme:x,weight:1,vtime:P,vduration:U})}),W())},re=(h,D,N,M,S)=>{xe(D,N,M),oe(h,N,M,S)},pe=async(h,D,N,M)=>{if(b||!h?.trim()){(D.length>0||N.length>0)&&!f&&re(D,N,E,M,y);return}if(d){c.push({audio:h,visemes:D,words:N,isNewSegment:M});return}d=!0;try{const S=window.AudioContext||window.webkitAudioContext,O=m??new S;O.state==="suspended"&&await O.resume(),m=O;const z=await hn(O,h);f=!0;const U=O.currentTime;let P=$;const x=!T;P<U&&(P=U+.1),$=P+z.duration;const C=O.createBufferSource();if(C.buffer=z,C.playbackRate.value=B,C.connect(O.destination),u.push(C),b){u.pop();return}if(x){T=!0,e("speaking"),v=P,E=0,r.length=0,s.length=0;const V=(P-U)*1e3;g=performance.now()+V}C.onended=()=>{const V=u.indexOf(C);V>=0&&u.splice(V,1),K(),W()},C.start(P);const J=(P-v)*1e3;re(D,N,J,M,y)}catch(S){console.error("[avatarTtsLipsync] audio chunk failed:",S)}finally{d=!1;const S=c.shift();S?await pe(S.audio,S.visemes,S.words,S.isNewSegment):K()}},Z=()=>{if(i=!0,!f&&r.length>0){ye();return}K()};return{setDeveloperToken:h=>{Q=h},setTtsEngineId:h=>{w=h},getTtsEngineId:()=>w,speak:async(h,D)=>{Y(),b=!1,e("loading");const N=Q.trim();if(!N)throw new Error("Developer token required for avatar_ttsWithPoses");const M=D?.ttsEngineId??w??He;y=M;const S=D?.voiceId??We,O=D?.speakingRate??Ke,z=Math.max(_t,Math.min(mt,O)),U={user_query:h,ttsEngineId:M,speakingRate:z};Ct.has(M)&&(U.voice_id=S);try{const P=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${N}`},body:JSON.stringify(U)});if(!P.ok)throw new Error(`avatar_ttsWithPoses failed (${P.status})`);const x=P.body;if(!x)throw new Error("No response body");const C=x.getReader(),J=new TextDecoder;let V="";const ce=async ue=>{const l=Yt(ue);if(l){if(l.event==="audio"){const p=l.data.chunk,k=l.data.visemes??[],I=l.data.words??[],A=l.data.is_new_segment??!1;if(p)await pe(p,k,I,A);else if(k.length>0||I.length>0){const q=A&&r.length>0?Qe(r):E;re(k,I,q,A,M)}}else if(l.event==="metadata"){const p=l.data.mood;typeof p=="string"&&p.trim()&&(a=p.trim());const k=l.data.sentence_emotions;if(Array.isArray(k)){o.length=0;for(const I of k){if(!I||typeof I!="object")continue;const A=I;o.push({sentence_index:Number(A.sentence_index??0),text:String(A.text??""),sentiment:typeof A.sentiment=="string"?A.sentiment:void 0,emotion:String(A.emotion??a),start_word:Number(A.start_word??0),end_word:Number(A.end_word??0)})}}W()}else if(l.event==="error")throw new Error(String(l.data.message??"avatar_ttsWithPoses stream error"))}};for(;;){const{done:ue,value:l}=await C.read();l&&(V+=J.decode(l,{stream:!0}));const p=V.split(`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const Oe=require("react/jsx-runtime"),p=require("react");var Pe=typeof document<"u"?document.currentScript:null;const xt="https://pub-607ad1fc22e2400eb57d17240aab857c.r2.dev",lt={publicBase:xt},Ct="0.1.6",Mt={version:Ct},Ft={},ke="https://ai.streamoji.com",Ot=`${lt.publicBase}/custom-faces`,Pt=`${lt.publicBase}/aitwin-workers/v${Mt.version}/visemeDiffPreview.worker.js`;function Lt(e){if(e)return e;const t=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:Pe&&Pe.tagName.toUpperCase()==="SCRIPT"&&Pe.src||new URL("aitwin.cjs",document.baseURI).href}<"u"?Ft?.VITE_AITWIN_WORKER_URL:void 0;return t?.trim()?t.trim():Pt}const Ut="https://us-central1-streamoji-265f4.cloudfunctions.net/getAiTwin",Ke="eng_a7f2b9c1",Re="eng_d4e8f3a2",ae="eng_c9b1e6d4",re=ae,Nt=new Set([Re,ae]),ft={[Ke]:"oculus_direct",[ae]:"oculus_direct",[Re]:"inworld_word"},Je={google:Ke,inworld:Re,cartesia:ae};function Bt(e){return ft[e]}function Vt(e){return e===ae}function $t(e){if(e.ttsEngineId&&e.ttsEngineId in ft)return e.ttsEngineId;const t=e.tts?.toLowerCase();return t&&t in Je?Je[t]:re}class Ae extends Error{constructor(t="AI twin not found"){super(t),this.name="AiTwinNotFoundError"}}async function dt(e,t=Ut){const n=new URL(t);n.searchParams.set("id",e);const r=await fetch(n.toString());if(r.status===404)throw new Ae;if(!r.ok)throw new Error(`getAiTwin failed (${r.status})`);const s=await r.json();if(!s.success)throw new Ae(s.error??"AI twin not found");const{tts:i,...a}=s.data;return{...a,ttsEngineId:$t(s.data)}}const Ht="https://us-central1-streamoji-265f4.cloudfunctions.net/getAuthToken",qt="client_6TNvp3SCs4Og0a1ijm9TommXLql1",Wt="kk8Fq8EmexzP10jMIEwY3R44M5RKUEm1",Kt="6TNvp3SCs4Og0a1ijm9TommXLql1",Gt="Swaraj Mali";async function Ue(){const e=await fetch(Ht,{method:"POST",headers:{"Content-Type":"application/json","Client-Id":qt,"Client-Secret":Wt},body:JSON.stringify({userId:Kt,userName:Gt})});if(!e.ok)throw new Error(`getAuthToken failed (${e.status})`);const t=await e.json(),n=t.authToken??t.token??"";if(!n.trim())throw new Error("getAuthToken returned no token");return n}async function jt(e,t=ke){const n=await fetch(`${t.replace(/\/$/,"")}/api/session-value`,{headers:{Authorization:`Bearer ${e}`}});if(!n.ok)throw new Error(`/api/session-value failed (${n.status})`);const r=await n.json();if(!r.value)throw new Error("Session value response missing value");return r}function zt(e){const t=e.trim();if(t.length%2!==0)throw new Error("Invalid hex key");const n=new Uint8Array(t.length/2);for(let r=0;r<t.length;r+=2)n[r/2]=Number.parseInt(t.slice(r,r+2),16);return n}function Ee(e){return Uint8Array.from(e)}function Qt(e,t){const n=new Uint8Array(e.length+t.length);return n.set(e,0),n.set(t,e.length),n}async function Jt(e,t){if(!t)throw new Error("Asset key is required for encrypted assets");if(e.byteLength<28)throw new Error("Encrypted payload too small");const n=new Uint8Array(e),r=Ee(n.subarray(0,12)),s=Ee(n.subarray(12,28)),i=Ee(n.subarray(28)),a=Ee(Qt(i,s)),c=await crypto.subtle.importKey("raw",zt(t),{name:"AES-GCM"},!1,["decrypt"]);return crypto.subtle.decrypt({name:"AES-GCM",iv:r,tagLength:128},c,a)}let Ne=null;const Be=new Set;function Yt(e,t=Ot){const n=`${t.replace(/\/$/,"")}/${e}`;return{twinBase:n,binBase:n,encrypted:!0}}function Xt(e){Ne=e;for(const t of Be)t()}function Zt(e,t){const n=typeof globalThis.location<"u"?globalThis.location.href:void 0;if(!n)return e;const r=s=>{try{return new URL(s,n).href.replace(/\/$/,"")}catch{return s}};return{twinBase:r(e.twinBase),binBase:r(e.binBase),encrypted:e.encrypted}}function se(){if(!Ne)throw new Error("Twin assets not configured; call setActiveTwinAssets first");return Ne}function en(e){return Be.add(e),()=>Be.delete(e)}function tn(){return`${se().twinBase}/sil.png`}function nn(){return`${se().twinBase}/idle.mp4`}function rn(){const{encrypted:e,binBase:t,twinBase:n}=se();return e?t:n}function ht(){return se().encrypted}function sn(){const{binBase:e,twinBase:t,encrypted:n}=se();return n?`${e}/atlas.bin`:`${t}/atlas.json`}function on(){const{binBase:e,twinBase:t,encrypted:n}=se();return n?`${e}/expression_atlas.bin`:`${t}/expression_atlas.json`}function an(e){const t=e.split(/\r?\n/);let n="",r="";for(const i of t)i.startsWith("event:")?n=i.slice(6).trim():i.startsWith("data:")&&(r=i.slice(5).trim());if(!n)return null;let s={};if(r)try{s=JSON.parse(r)}catch{s={raw:r}}return{event:n,data:s}}const _t=["aa","CH","DD","E","FF","I","O","PP","RR","SS","TH","U","kk","nn","sil"],cn=new Map(_t.map(e=>[e.toLowerCase(),e]));function mt(e){const t=(e??"").trim();return t?cn.get(t.toLowerCase())??"sil":"sil"}const un={aei:["aa","E","I"],o:["O","U"],ee:["I"],bmp:["PP"],fv:["FF"],l:["nn"],r:["RR"],th:["TH"],qw:["U","O"],cdgknstxyz:["DD","SS","kk","CH"]};function ln(e){if(!e)return["sil"];const t=e.toLowerCase();return un[t]??["sil"]}function fn(e,t){const n=e.word.length;if(n<=0)return 0;const r=e.wduration;if(r<=0)return 0;const s=Math.max(0,Math.min(1,(t-e.wtime)/r));return Math.min(n-1,Math.floor(s*n))}function be(e,t){const n=Math.max(0,Math.min(e.length-1,t));return e[n]??""}function dn(e,t){const n=e.toLowerCase(),r=be(n,t),s=n.slice(Math.max(0,t-1),t+2);return r==="i"||r==="y"?"I":s.includes("ee")||r==="e"||n.includes("ea")?"E":"aa"}function hn(e,t){const n=e.toLowerCase(),r=n.slice(Math.max(0,t-1),Math.min(n.length,t+3));if(/oo|ou|uw/.test(r))return"U";const s=be(n,t);return s==="u"||s==="w"?"U":"O"}function _n(e,t){const n=e.toLowerCase(),r=n.slice(Math.max(0,t-2),t+1);if(/qu/.test(r))return"U";const s=n.slice(Math.max(0,t-1),Math.min(n.length,t+3));return/wo|wh/.test(s)||be(n,t)==="o"?"O":"U"}const Se={d:"DD",t:"DD",n:"DD",s:"SS",z:"SS",k:"kk",g:"kk",c:"CH",x:"CH",j:"CH"};function mn(e,t){const n=e.toLowerCase(),r=be(n,t);if(Se[r])return Se[r];for(let s=0;s<n.length;s++){const i=n[s];if(Se[i])return Se[i]}return"DD"}function wn(e,t,n){const r=ln(e);if(r.length===1)return r[0];const s=t.trim();if(!s)return r[0];const i=(e??"").toLowerCase(),a=Math.max(0,n);switch(i){case"aei":return dn(s,a);case"o":return hn(s,a);case"qw":return _n(s,a);case"cdgknstxyz":return mn(s,a);default:return r[0]}}function gn(e){let t=e.trim();const n=t.indexOf(",");t.startsWith("data:")&&n>=0&&(t=t.slice(n+1)),t=t.replace(/\s+/g,"").replace(/-/g,"+").replace(/_/g,"/");const r=t.length%4;return r!==0&&(t+="=".repeat(4-r)),t}const yn=24e3;function pn(e){return e.length>=4&&e[0]===82&&e[1]===73&&e[2]===70&&e[3]===70}function Ye(e,t,n=yn){const r=t.byteOffset%2===0?t:t.slice(),s=new Int16Array(r.buffer,r.byteOffset,r.byteLength/2),i=new Float32Array(s.length);for(let c=0;c<s.length;c++)i[c]=s[c]>=32768?-(65536-s[c])/32768:s[c]/32767;const a=e.createBuffer(1,i.length,n);return a.copyToChannel(i,0),a}function En(e){const t=gn(e),n=window.atob(t),r=new Uint8Array(n.length);for(let s=0;s<n.length;s++)r[s]=n.charCodeAt(s);return r}async function Sn(e,t){const n=En(t);if(pn(n)){const r=n.buffer.slice(n.byteOffset,n.byteOffset+n.byteLength);return e.decodeAudioData(r)}if(n.length>=2&&n.length%2===0)return Ye(e,n);try{const r=n.buffer.slice(n.byteOffset,n.byteOffset+n.byteLength);return await e.decodeAudioData(r)}catch{return Ye(e,n)}}function wt(e,t){let n=null;for(const r of e)t<r.vtime||t>=r.vtime+r.vduration||(!n||r.vtime>=n.vtime)&&(n=r);return n?n.viseme:"sil"}function gt(e,t){for(const n of e)if(t>=n.wtime&&t<n.wtime+n.wduration)return n;return null}function Xe(e){let t=0;for(const n of e)t=Math.max(t,n.vtime+n.vduration);return t}const yt=.5,pt=1.5,Ge="Olivia",Et="f786b574-daa5-4673-aa0c-cbe3e8534c02",je=.85;function St(e,t=ke){const n=`${t.replace(/\/$/,"")}/avatar_ttsWithPoses`,r=[],s=[],i=[];let a="neutral";const c=[],l=[];let d=null,m=!1,_=!1,I=!1,o=!1,x=0,w=0,u=0,g=0,E=null,R=1,$="",y=re,S=re,C=!1;const D=new Set,q=()=>{for(const h of l)h.playbackRate.value=R},W=()=>D.forEach(h=>h()),ce=()=>{E!=null&&(clearTimeout(E),E=null)},ge=()=>{for(const h of l)try{h.stop()}catch{}l.length=0},X=()=>{C=!0,ce(),ge(),c.length=0,m=!1,_=!1,I=!1,o=!1,r.length=0,s.length=0,i.length=0,a="neutral",u=0,g=0,w=0,e("idle"),W()},K=()=>{!o||m||l.length>0||c.length>0||(_=!1,ce(),e("done"),W())},ye=()=>{const h=Xe(r);if(h<=0){e("done"),W();return}_=!0,x=performance.now(),e("speaking"),W(),ce();const M=R>0?h/R:h;E=setTimeout(()=>{C||(_=!1,E=null,e("done"),W())},M)},xe=(h,M,B)=>{h.length!==0&&(B&&(u=M),h.forEach(P=>{const U=String(P.word??"").trim();if(!U)return;const Q=Math.round((P.start??0)*1e3),V=Math.round((P.duration??0)*1e3);s.push({word:U,wtime:u+Q,wduration:V,queueIndex:s.length})}))},ue=(h,M,B,P)=>{h.length!==0&&(B&&(u=M),h.forEach(k=>{const U=String(k.symbol??"").trim();if(!U)return;const Q=Math.round((k.start??0)*1e3),V=Math.max(1,Math.round((k.duration??0)*1e3)),L=u+Q;let F;if(Bt(P)==="oculus_direct")F=mt(U);else{const O=gt(s,L),J=O?fn(O,L):0;F=wn(U,O?.word??"",J)}r.push({viseme:F,weight:1,vtime:L,vduration:V})}),W())},ie=(h,M,B,P,k)=>{xe(M,B,P),ue(h,B,P,k)},pe=async(h,M,B,P)=>{if(C||!h?.trim()){(M.length>0||B.length>0)&&!I&&ie(M,B,u,P,S);return}if(m){c.push({audio:h,visemes:M,words:B,isNewSegment:P});return}m=!0;try{const k=window.AudioContext||window.webkitAudioContext,U=d??new k;U.state==="suspended"&&await U.resume(),d=U;const Q=await Sn(U,h);I=!0;const V=U.currentTime;let L=g;const F=!_;L<V&&(L=V+.1),g=L+Q.duration;const O=U.createBufferSource();if(O.buffer=Q,O.playbackRate.value=R,O.connect(U.destination),l.push(O),C){l.pop();return}if(F){_=!0,e("speaking"),w=L,u=0,r.length=0,s.length=0;const H=(L-V)*1e3;x=performance.now()+H}O.onended=()=>{const H=l.indexOf(O);H>=0&&l.splice(H,1),K(),W()},O.start(L);const J=(L-w)*1e3;ie(M,B,J,P,S)}catch(k){console.error("[avatarTtsLipsync] audio chunk failed:",k)}finally{m=!1;const k=c.shift();k?await pe(k.audio,k.visemes,k.words,k.isNewSegment):K()}},Z=()=>{if(o=!0,!I&&r.length>0){ye();return}K()};return{setDeveloperToken:h=>{$=h},setTtsEngineId:h=>{y=h},getTtsEngineId:()=>y,speak:async(h,M)=>{X(),C=!1,e("loading");const B=$.trim();if(!B)throw new Error("Developer token required for avatar_ttsWithPoses");const P=M?.ttsEngineId??y??re;S=P;const k=M?.voiceId??Ge,U=M?.speakingRate??je,Q=Math.max(yt,Math.min(pt,U)),V={user_query:h,ttsEngineId:P,speakingRate:Q};Nt.has(P)&&(V.voice_id=k);try{const L=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${B}`},body:JSON.stringify(V)});if(!L.ok)throw new Error(`avatar_ttsWithPoses failed (${L.status})`);const F=L.body;if(!F)throw new Error("No response body");const O=F.getReader(),J=new TextDecoder;let H="";const fe=async de=>{const f=an(de);if(f){if(f.event==="audio"){const T=f.data.chunk,A=f.data.visemes??[],v=f.data.words??[],b=f.data.is_new_segment??!1;if(T)await pe(T,A,v,b);else if(A.length>0||v.length>0){const G=b&&r.length>0?Xe(r):u;ie(A,v,G,b,P)}}else if(f.event==="metadata"){const T=f.data.mood;typeof T=="string"&&T.trim()&&(a=T.trim());const A=f.data.sentence_emotions;if(Array.isArray(A)){i.length=0;for(const v of A){if(!v||typeof v!="object")continue;const b=v;i.push({sentence_index:Number(b.sentence_index??0),text:String(b.text??""),sentiment:typeof b.sentiment=="string"?b.sentiment:void 0,emotion:String(b.emotion??a),start_word:Number(b.start_word??0),end_word:Number(b.end_word??0)})}}W()}else if(f.event==="error")throw new Error(String(f.data.message??"avatar_ttsWithPoses stream error"))}};for(;;){const{done:de,value:f}=await O.read();f&&(H+=J.decode(f,{stream:!0}));const T=H.split(`
2
2
 
3
- `);V=p.pop()??"";for(const k of p)await ce(k);if(ue){V.trim()&&await ce(V.trim()),b||Z();break}}}catch(P){throw console.error("[avatarTtsLipsync]",P),Y(),e("error"),P}},stop:Y,getVisemeQueue:()=>r,getWordQueue:()=>s,getSentenceEmotions:()=>o,getStreamMood:()=>a,getPlaybackElapsedMs:()=>T?f&&m&&v>0?Math.max(0,(m.currentTime-v)*1e3):Math.max(0,(performance.now()-g)*B):0,isSpeaking:()=>T,setPlaybackSpeed:h=>{B=Math.max(.1,Math.min(1,h)),H()},getPlaybackSpeed:()=>B,subscribe:h=>(R.add(h),()=>R.delete(h))}}function _n(e,t,n){return{width:e.crop?.source_width??t,height:e.crop?.source_height??n}}function mn(e,t){const n=e.crop;return{x:t?.source_x??n?.x??0,y:t?.source_y??n?.y??0,width:t?.source_w??n?.width??e.frame_width??0,height:t?.source_h??n?.height??e.frame_height??0}}function wn(e){return e?(e.w??0)>0&&(e.h??0)>0:!1}async function Et(e,t){const n=await fetch(e);if(!n.ok)throw new Error(`Failed to load encrypted asset: ${e}`);const r=await n.arrayBuffer();return Wt(r,t)}async function gn(e,t){if(!t)throw new Error("Missing asset key for encrypted JSON");const n=await Et(e,t),r=new TextDecoder().decode(n);return JSON.parse(r)}async function En(e){const t=new Blob([e],{type:"image/webp"}),n=URL.createObjectURL(t);return new Promise((r,s)=>{const o=new Image;o.decoding="async",o.onload=()=>{URL.revokeObjectURL(n),r(o)},o.onerror=()=>{URL.revokeObjectURL(n),s(new Error("Failed to decode decrypted image"))},o.src=n})}function yt(e,t){return`${e}/${t}_minus_sil.png`}const qe=15,yn=["aa","E","I","O","U","PP","FF","DD","SS","TH","CH","RR","kk","nn"],Ne=["t01_0.17","t02_0.33","t03_0.50","t04_0.67","t05_0.83"],pn=Ne.length,Je=new Set(["aa__kk","aa__nn","aa__sil","CH__aa","CH__DD","CH__E","CH__FF","CH__I","CH__kk","CH__nn","CH__O","CH__PP","CH__RR","CH__sil","CH__SS","CH__TH","CH__U","DD__aa","DD__E","DD__FF","DD__I","DD__kk","DD__nn","DD__O","DD__PP","DD__RR","DD__sil","DD__SS","DD__TH","DD__U","E__aa","E__FF","E__I","E__kk","E__nn","E__O","E__PP","E__RR","E__sil","E__SS","E__TH","E__U","FF__aa","FF__I","FF__kk","FF__nn","FF__O","FF__PP","FF__RR","FF__sil","FF__SS","FF__TH","FF__U","I__aa","I__kk","I__nn","I__O","I__PP","I__RR","I__sil","I__SS","I__TH","I__U","kk__nn","kk__sil","nn__sil","O__aa","O__kk","O__nn","O__PP","O__RR","O__sil","O__SS","O__TH","O__U","PP__aa","PP__kk","PP__nn","PP__RR","PP__sil","PP__SS","PP__TH","PP__U","RR__aa","RR__kk","RR__nn","RR__sil","RR__SS","RR__TH","RR__U","SS__aa","SS__kk","SS__nn","SS__sil","SS__TH","SS__U","TH__aa","TH__kk","TH__nn","TH__sil","TH__U","U__aa","U__kk","U__nn","U__sil"]);function Xe(e,t){return`${e}__${t}`}function Ye(e,t){return`pairs/${e}/${t}_minus_sil.png`}function Ue(e){return`${e}_minus_sil.png`}function Sn(e,t){if(e===t)return[];const n=[],r=Xe(e,t);if(Je.has(r)){for(const o of Ne)n.push(Ye(r,o));return n}const s=Xe(t,e);if(Je.has(s)){for(let o=pn-1;o>=0;o--)n.push(Ye(s,Ne[o]));return n}return[]}function Tn(e){return e<16?[]:e<35?[2]:e<51?[0,4]:e<67?[0,2,4]:e<83?[0,1,2,3]:[0,1,2,3,4]}function kn(e,t){return Tn(t).map(r=>e[r]).filter(r=>r!=null)}function In(e,t,n,r){if(r<=0)return 0;const o=Math.max(1,n-t)/r,a=e-t,c=Math.floor(a/o);return Math.min(r-1,Math.max(0,c))}function An(e,t,n){if(!n)return`${e}/${t}`;const r=t.split("/").pop()??t,s=r.includes(".")?r.slice(0,r.lastIndexOf(".")):r;return`${e}/${s}.bin`}const vn=[.32,.24,.16,.08,0],De=vn.map(e=>`eyes_${e.toFixed(2)}`),Rn=["eyes_0.32","eyes_0.16","eyes_0.00"],bn=["eyes_0.32","eyes_0.16","eyes_0.08","eyes_0.00"],Dn={fear:"fear",afraid:"fear",anxiety:"fear",anger:"anger",angry:"anger",mad:"anger",sad:"sad",sadness:"sad",sorrow:"sad",neutral:"neutral",calm:"neutral",love:"love",loving:"love",affection:"love",happy:"happy",happiness:"happy",joy:"happy",joyful:"happy",excited:"happy",disgust:"disgust",disgusted:"disgust"};function se(e,t="neutral"){const n=String(e??"").trim().toLowerCase();return n?Dn[n]??t:t}function j(e){return e==="neutral"?null:yt(e,"eyes_standard")}function Be(e,t){return!t||t==="eyes_standard"?j(e):e==="neutral"&&t==="eyes_standard"?null:yt(e,t)}function xn(e){if(!e)return"open";const t=e.match(/\/(eyes_[^/]+)_minus_sil\.png$/);if(!t?.[1])return"open";const n=t[1];return De.includes(n)?n:"open"}function Cn(e){return e==="open"?-1:De.indexOf(e)}function Mn(e,t){const n=[];for(const r of t)n.push(Be(e,r));for(let r=t.length-2;r>=0;r--)n.push(Be(e,t[r]));return n.push(j(e)),n}function Pn(e,t){if(t==="open")return[j(e)];const n=Cn(t);if(n<0)return[j(e)];const r=[];for(let s=n;s>=0;s--)r.push(Be(e,De[s]));return r.push(j(e)),r}const Fn=["t01_0.20","t02_0.40","t03_0.60","t04_0.80"];function On(e,t){return`${e}__${t}`}function Ln(e,t,n){return`pairs/${On(e,t)}/${n}_minus_sil.png`}function Nn(e,t){return Fn.map(n=>Ln(e,t,n))}function he(e,t){return e+Math.random()*(t-e)}function ke(){return he(14,32)}function Un(e={}){const{initialDelayMs:t=800+Math.random()*1200,intervalMinMs:n=2200,intervalMaxMs:r=5800,doubleBlinkChance:s=.18,doubleBlinkGapMinMs:o=120,doubleBlinkGapMaxMs:a=220,fullBlinkChance:c=.75,postEmotionChangeDelayMs:u=380,minDwellMs:m=550}=e;let d="neutral",T="neutral",f=0,i={kind:"idle",nextBlinkAt:performance.now()+t},g=null,v="__eyes_open__|neutral";function E(w,y){g=w,v=`${w??"__eyes_open__"}|${y}`}function $(w,y){i={kind:"idle",nextBlinkAt:w+he(n,r)},T=y,E(j(y),y)}function F(w,y,b){const R=b?Rn:Math.random()<c?De:bn;i={kind:"playing",paths:Mn(y,R),index:0,holdUntil:w+ke(),after:"idle",blinkEmotion:y},T=y,E(i.paths[0]??null,y)}function B(w,y,b){const R=xn(g),H=[];if(R!=="open"){const W=Pn(y,R);H.push(...W.slice(0,-1))}H.push(...Nn(y,b)),H.push(j(b)),i={kind:"emotionBlend",paths:H,index:0,holdUntil:w+ke(),thenEmotion:b},E(H[0]??null,y)}function Q(w){if(i.kind==="emotionBlend"){for(;w>=i.holdUntil&&i.index<i.paths.length-1;)i.index+=1,i.holdUntil=w+ke();const y=i.paths[i.index]??null;E(y,i.thenEmotion),w>=i.holdUntil&&i.index>=i.paths.length-1&&(d=i.thenEmotion,T=i.thenEmotion,E(j(i.thenEmotion),i.thenEmotion),i={kind:"idle",nextBlinkAt:w+u});return}if(i.kind==="idle"){E(j(T),T),w>=i.nextBlinkAt&&F(w,T,!1);return}if(i.kind==="doublePause"){E(j(i.blinkEmotion),i.blinkEmotion),w>=i.resumeAt&&F(w,i.blinkEmotion,!0);return}if(i.kind==="playing"){for(;w>=i.holdUntil&&i.index<i.paths.length-1;)i.index+=1,i.holdUntil=w+ke();if(E(i.paths[i.index]??null,i.blinkEmotion),w>=i.holdUntil&&i.index>=i.paths.length-1){if(i.after==="resumeIdle"){$(w+u,d);return}if(i.after==="doublePause"){i={kind:"doublePause",resumeAt:w+he(o,a),blinkEmotion:i.blinkEmotion},E(j(i.blinkEmotion),i.blinkEmotion);return}if(i.after==="idle"&&Math.random()<s){i={kind:"doublePause",resumeAt:w+he(o,a),blinkEmotion:i.blinkEmotion},E(j(i.blinkEmotion),i.blinkEmotion);return}$(w,i.blinkEmotion)}}}return{advance:Q,setTargetEmotion(w){const y=se(w,d);if(y===d&&i.kind!=="emotionBlend")return;const b=performance.now();if(m>0&&y!==d&&i.kind!=="emotionBlend"&&!(d==="neutral"&&y!=="neutral")&&b-f<m)return;const R=d;if(d=y,f=b,i.kind==="playing"){B(b,T,y);return}if(i.kind==="emotionBlend"){i={...i,thenEmotion:y};return}B(b,R,y)},getTargetEmotion:()=>d,getExpressionPath:()=>g,getDrawKey:()=>v,reset(){d="neutral",T="neutral",f=0,$(performance.now()+he(n,r),"neutral")}}}function Bn(e){const t=document.createElement("video");t.muted=!0,t.playsInline=!0,t.preload="auto",t.setAttribute("playsinline",""),t.loop=!0;let n=!1;return{async load(){n||await new Promise((r,s)=>{const o=()=>{const a=t.duration;if(!Number.isFinite(a)||a<=0){s(new Error(`Idle video has invalid duration: ${e}`));return}n=!0,t.currentTime=0,r()};t.addEventListener("loadeddata",o,{once:!0}),t.addEventListener("error",()=>s(new Error(`Failed to load idle video: ${e}`)),{once:!0}),t.src=e,t.load()})},isReady(){return n},getVideo(){return t},setActive(r){n&&(r?t.paused&&t.play().catch(()=>{}):t.paused||t.pause())},restart(){n&&(t.currentTime=0)}}}const Vn=50,pt=400;function $n(e,t,n){return e.filter(r=>{const s=r.queueIndex??-1;return s>=t&&s<=n})}function Hn(e,t){const n=[];for(const r of e){const s=$n(t,r.start_word,r.end_word);if(s.length===0)continue;const o=s[0],a=s[s.length-1];n.push({sentence:r,startMs:Math.max(0,o.wtime-Vn),endMs:a.wtime+a.wduration+pt})}return n.sort((r,s)=>r.startMs-s.startMs)}function Wn(e,t,n,r="neutral"){const s=se(r);if(t.length===0)return s;if(n.length===0||e<n[0].wtime)return se(t[0]?.emotion,s);const o=Hn(t,n);let a=null;for(const m of o)e>=m.startMs&&e<=m.endMs&&(a=m);if(a)return se(a.sentence.emotion,s);const c=n[n.length-1],u=c.wtime+c.wduration;return e>u+pt?se(t[t.length-1]?.emotion,s):s}function St(e,t,n,r,s=qe){const o=new OffscreenCanvas(n,r),a=o.getContext("2d",{willReadFrequently:!0});a.drawImage(e,0,0,n,r);const c=a.getImageData(0,0,n,r),u=a.createImageData(n,r);u.data.set(c.data);const d=new OffscreenCanvas(n,r).getContext("2d",{willReadFrequently:!0});for(const T of t){d.clearRect(0,0,n,r),d.drawImage(T,0,0,n,r);const f=d.getImageData(0,0,n,r);for(let i=0;i<u.data.length;i+=4){const g=f.data[i],v=f.data[i+1],E=f.data[i+2];Math.max(g,v,E)>s&&(u.data[i]=g,u.data[i+1]=v,u.data[i+2]=E,u.data[i+3]=255)}}return a.putImageData(u,0,0),o}let ee=null,_e=null;const Re=new Map;function Kn(){ee=null,_e=null,Re.clear()}Gt(Kn);function qn(e){return e??_e??void 0}function Ge(e){return new Promise((t,n)=>{const r=new Image;r.decoding="async",r.onload=()=>t(r),r.onerror=()=>n(new Error(`Failed to load image: ${e}`)),r.src=e})}async function Ze(e,t,n,r){const s=n?await gn(e,r):await fetch(e).then(m=>{if(!m.ok)throw new Error(`Failed to load ${e}`);return m.json()}),o=s.sheets?.[0];if(!o?.path)throw new Error(`${e} has no sheets[0].path`);const a=n?await En(await Et(An(t,o.path,n),r??"")):await Ge(`${t}/${o.path}`),c=new Map;for(const m of s.cells??[])m.path&&c.set(m.path,m);const u=new Map;for(const m of s.sheets??[])u.set(m.index,m);return{atlas:a,atlasMeta:s,cellByPath:c,sheetByIndex:u,diffBase:t}}async function Ve(e){const t=qn(e),n=ut();if(n&&!t)throw new Error("Encrypted assets enabled but no key provided");if(ee&&(!n||_e===(t??null))){const o=await ee;return me(o)}_e=t??null,Re.clear();const r=Qt();ee=(async()=>{const o=await Ge(jt()),a=await Ze(Jt(),r,n,t);let c=null;try{c=await Ze(Xt(),r,n,t)}catch{c=null}return{sil:o,viseme:a,expression:c}})();const s=await ee;return me(s)}async function Tt(e){if(await Ve(e),!ee)throw new Error("Assets not loaded");return ee}function me(e){return _n(e.viseme.atlasMeta,e.sil.naturalWidth,e.sil.naturalHeight)}function Gn(e,t){const n=document.createElement("canvas");return n.width=t.w,n.height=t.h,n.getContext("2d",{willReadFrequently:!0}).drawImage(e.atlas,t.x,t.y,t.w,t.h,0,0,t.w,t.h),n}async function et(e,t,n){const r=`${t.diffBase}::${n}`,s=Re.get(r);if(s)return s;const o=(async()=>{const a=t.cellByPath.get(n);if(!a)throw new Error(`No atlas cell for path: ${n}`);const c=mn(t.atlasMeta,a),u=me(e);if(wn(a)){const T=Gn(t,a),f=document.createElement("canvas");f.width=u.width,f.height=u.height;const i=f.getContext("2d");return i.fillStyle="#000",i.fillRect(0,0,u.width,u.height),i.drawImage(T,c.x,c.y),f}const m=`${t.diffBase}/${n}`,d=await Ge(m);if(d.naturalWidth===u.width&&d.naturalHeight===u.height)return d;throw new Error(`Diff PNG wrong size for ${n}`)})();return Re.set(r,o),o}async function tt(e,t,n,r=qe,s,o){if(s){const{width:f,height:i}=s;if(o&&!o()||t.readyState<HTMLMediaElement.HAVE_CURRENT_DATA)return;const g=document.createElement("canvas");g.width=f,g.height=i;const v=g.getContext("2d");if(v.clearRect(0,0,f,i),v.drawImage(t,0,0,f,i),o&&!o())return;(e.width!==f||e.height!==i)&&(e.width=f,e.height=i);const E=e.getContext("2d");E.clearRect(0,0,f,i),E.drawImage(g,0,0);return}const a=await Tt(),{width:c,height:u}=me(a);(e.width!==c||e.height!==u)&&(e.width=c,e.height=u);const m=[],d=e.getContext("2d");if(d.clearRect(0,0,c,u),t.readyState<HTMLMediaElement.HAVE_CURRENT_DATA){const f=a.sil;d.drawImage(f,0,0,c,u);return}if(m.length===0){d.drawImage(t,0,0,c,u);return}const T=St(t,m,c,u,r);d.drawImage(T,0,0)}async function $e(e,t,n=qe){const r=await Tt(_e??void 0),{width:s,height:o}=me(r);(e.width!==s||e.height!==o)&&(e.width=s,e.height=o);const a=[];t.mouthPath&&a.push(await et(r,r.viseme,t.mouthPath)),t.expressionPath&&r.expression&&a.push(await et(r,r.expression,t.expressionPath));const c=e.getContext("2d");if(c.clearRect(0,0,s,o),a.length===0){c.drawImage(r.sil,0,0,s,o);return}const u=St(r.sil,a,s,o,n);c.drawImage(u,0,0)}async function jn(e){await $e(e,{mouthPath:null,expressionPath:null})}function zn(e){const t=new Map;for(const n of e)t.has(n.vtime)||t.set(n.vtime,n);return[...t.values()].sort((n,r)=>n.vtime-r.vtime)}function Qn(e){const t=zn(e),n=[];for(let r=0;r<t.length-1;r++){const s=t[r].viseme,o=t[r+1].viseme,a=t[r].vtime,c=t[r+1].vtime;s===o||c<=a||n.push({from:s,to:o,fromVtime:a,toVtime:c})}return n}function Jn(e,t){let n=null;for(const r of e)t>=r.fromVtime&&t<r.toVtime&&(n=r);return n}function Xn(e,t){return{gapMs:Math.max(0,t-e),holdEnd:e,transStart:e}}const Yn=500,Zn="__sil__";function er(){return{lastDrawnKey:""}}function de(e){e.lastDrawnKey=""}function nt(e){return e??Zn}function tr(e,t){if(e.length===0)return{diffPath:null,label:"sil"};const n=Qn(e),r=Jn(n,t);if(r){const o=r.toVtime-r.fromVtime,a=Xn(r.fromVtime,r.toVtime);if(t>=a.transStart&&t<r.toVtime){const c=Sn(r.from,r.to),u=kn(c,o);if(u.length>0){const m=In(t,a.transStart,r.toVtime,u.length);return{diffPath:u[m]??u[u.length-1],label:`${r.from}→${r.to}`}}return{diffPath:Ue(r.to),label:r.to}}}const s=dt(e,t);return s==="sil"?{diffPath:null,label:"sil"}:{diffPath:Ue(s),label:s}}function kt(e,t){const n=t??nt(e.expressionPath);return`${nt(e.mouthPath)}|${n}`}function nr(e,t,n,r,s,o,a,c){const u=tr(t,n),m={mouthPath:u.diffPath,expressionPath:r},d=kt(m,s);d!==o.lastDrawnKey&&(o.lastDrawnKey=d,c(u.label),a(e,m))}function rt(e,t,n,r,s,o,a=null){const c={mouthPath:null,expressionPath:t},u=a!=null?`|idle@${Math.round(a*1e3)}`:"",m=kt(c,n)+u;!(a!=null)&&m===r.lastDrawnKey||(r.lastDrawnKey=m,o(a!=null?"idle":"sil"),s(e,c))}const st=new Map;async function rr(e){let t=st.get(e);if(!t){const n=await fetch(e);if(!n.ok)throw new Error(`Failed to fetch worker script (${n.status}): ${e}`);const r=await n.blob();t=URL.createObjectURL(r),st.set(e,t)}return new Worker(t,{name:"visemeDiffPreview"})}function sr(){return typeof Worker<"u"&&typeof OffscreenCanvas<"u"}function ir(e,t){(e.width!==t.width||e.height!==t.height)&&(e.width=t.width,e.height=t.height);const n=e.getContext("2d");n&&n.drawImage(t,0,0)}function it(e,t){let n=0;return{usesWorker:!1,async loadAssets(r){return await Ve(r)},async renderSilOnly(){n+=1,await jn(e)},async drawLiveFrame(r,s){await Ve(),await $e(r,s)},async renderViseme(r,s){n+=1;const o=n;t.onStatus?.(s),await $e(r,{mouthPath:Ue(s),expressionPath:null})},dispose(){n+=1}}}function or(e,t,n){let r=null,s=1,o=0,a=!1,c=!1;const u=new Map,m=(f,i)=>{c||!r||r.postMessage(f,[])},d=(f,i,g=!1)=>{if(c)return Promise.resolve();const v=s++;return new Promise((E,$)=>{u.set(v,{resolve:F=>E(F),reject:$,generation:typeof f.generation=="number"?f.generation:void 0,expectRenderDone:g}),m({...f,requestId:v})})},T=(async()=>{r=await rr(n),r.onmessage=f=>{if(c)return;const i=f.data;if(i.type==="status"){t.onStatus?.(i.label);return}if(i.type==="frame"){const v=i.generation<0;if(!v&&i.generation!==o){i.bitmap.close();return}if(v&&t.shouldAcceptLiveFrame&&!t.shouldAcceptLiveFrame()){i.bitmap.close();return}ir(e,i.bitmap),i.bitmap.close();return}const g=u.get(i.requestId);if(g)switch(i.type){case"ready":u.delete(i.requestId),g.resolve();break;case"loadAssetsDone":u.delete(i.requestId),g.resolve({width:i.width,height:i.height});break;case"renderDone":if(g.expectRenderDone&&g.generation!=null&&i.generation!==g.generation)return;u.delete(i.requestId),g.resolve();break;case"renderAborted":u.delete(i.requestId),g.resolve();break;case"error":u.delete(i.requestId),t.onError?.(i.message),g.reject(new Error(i.message));break}},r.onerror=f=>{if(c)return;const i=f.message||"Worker error";t.onError?.(i);for(const[,g]of u)g.reject(new Error(i));u.clear()},await d({type:"init"}),a=!0})();return{usesWorker:!0,async loadAssets(f){if(c)return{width:842,height:1264};if(await T,c)return{width:842,height:1264};if(!a)throw new Error("Worker init failed");return await d({type:"loadAssets",keyHex:f,urls:ne()})??{width:842,height:1264}},async renderSilOnly(){if(c||(await T,c))return;o+=1;const f=o;await d({type:"renderSil",generation:f},void 0,!0)},async drawLiveFrame(f,i){c||(await T,!c&&await d({type:"drawFrame",diffPath:i.mouthPath,expressionDiffPath:i.expressionPath},void 0,!0))},async renderViseme(f,i,g={}){if(c||(await T,c))return;o+=1;const v=o;try{await d({type:"renderViseme",generation:v,to:i,from:g.from,transitionDurationMs:g.transitionDurationMs,gapMs:g.gapMs,threshold:g.threshold},void 0,!0)}catch(E){if(E?.name==="AbortError")return;throw E}},dispose(){if(!c){c=!0,o+=1;for(const[,f]of u)f.resolve();u.clear(),r?.terminate(),r=null}}}}function ar(e,t={}){if(!sr())return it(e,t);const n=t.workerScriptUrl??Dt;try{return or(e,t,n)}catch{return it(e,t)}}class cr extends Error{constructor(t,n){super(`${t} timed out after ${Math.round(n/1e3)}s`),this.name="LoadTimeoutError"}}function Pe(e,t,n){return new Promise((r,s)=>{const o=globalThis.setTimeout(()=>{s(new cr(n,t))},t);e.then(a=>{globalThis.clearTimeout(o),r(a)},a=>{globalThis.clearTimeout(o),s(a)})})}const ur={position:"relative",display:"inline-block",lineHeight:0},lr={display:"block",maxWidth:"100%",height:"auto"},fr={position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",padding:"1rem",background:"rgba(0,0,0,0.55)",color:"#fff",fontSize:"0.875rem",textAlign:"center"};function Ie(e){return Pt(e)?wt:We}const dr=_.forwardRef(function({id:t,assets:n,authToken:r,ttsEngineId:s=te,voiceId:o,speakingRate:a=Ke,className:c,style:u,canvasStyle:m,onStatusChange:d,onDisplayStatus:T,onError:f,onReady:i,showErrorOverlay:g=!0},v){const E=_.useRef(null),$=_.useRef(null),F=_.useRef(er()),B=_.useRef(Un()),Q=_.useRef(0),w=_.useRef(0),y=_.useRef(null),b=_.useRef(!1),R=_.useRef(null),H=_.useRef(!1),[W,ie]=_.useState("idle"),[Ee,Y]=_.useState(null),[K,ye]=_.useState(!1),[xe,oe]=_.useState(!1),[re,pe]=_.useState({width:842,height:1264}),Z=_.useRef(r??null),ae=_.useRef(null),h=_.useRef(null),D=_.useRef(!1),N=_.useRef({width:842,height:1264}),M=_.useRef(i),S=_.useRef(T),O=_.useRef(f);M.current=i,S.current=T,O.current=f;const z=_.useCallback(l=>{const p=l?.ttsEngineId??s??h.current?.ttsEngineId??te,k=l?.voiceId??o??h.current?.voiceId??Ie(p);return{ttsEngineId:p,voiceId:k}},[s,o]),U=_.useCallback(l=>{Y(l),O.current?.(l)},[]),P=_.useCallback(l=>{ie(l),d?.(l)},[d]),x=_.useRef(gt(P,Ae)),C=_.useCallback(()=>{y.current!=null&&(clearTimeout(y.current),y.current=null)},[]),J=_.useCallback(async()=>{const l=w.current,p=$.current;!p||!K||x.current.isSpeaking()||(de(F.current),await p.renderSilOnly(),l===w.current&&(x.current.isSpeaking()||(S.current?.("sil"),H.current&&R.current&&(R.current.restart(),R.current.setActive(!0)))))},[K]),V=_.useCallback(()=>{C();const l=w.current;J(),y.current=setTimeout(()=>{y.current=null,l===w.current&&J()},Yn)},[C,J]),ce=_.useCallback(async()=>{const l=Math.floor(Date.now()/1e3);if(ae.current&&l<ae.current.expiresAt-60)return ae.current.key;const p=Z.current??await Fe();Z.current=p,x.current.setDeveloperToken(p);const k=await Vt(p,Ae);return ae.current={key:k.value,expiresAt:k.expiresAt},k.value},[]);_.useEffect(()=>{r&&(Z.current=r,x.current.setDeveloperToken(r))},[r]),_.useEffect(()=>{x.current.setTtsEngineId(s),h.current&&(h.current.ttsEngineId=s)},[s]),_.useEffect(()=>{const l=o??Ie(s);h.current&&(h.current.voiceId=l)},[o,s]);const ue=_.useMemo(()=>n?JSON.stringify(n):`id:${t??""}`,[n,t]);return _.useEffect(()=>{if(!t&&!n){U("AiTwin requires either `id` or `assets`");return}let l=!1;D.current=!1,ye(!1),oe(!1),Y(null),h.current=null,R.current=null,H.current=!1;const p=E.current;if(!p)return;let k=null;return(async()=>{try{let I,A,q;if(n)I=n,A=s,q=o??Ie(A);else{S.current?.("getAiTwin");const L=await Pe(ct(t),3e4,"getAiTwin");if(l)return;if(!L.faceId?.trim())throw new Error("getAiTwin returned no faceId");A=L.ttsEngineId,q=o??L.voiceId??Ie(A),I=Kt(L.faceId)}h.current={ttsEngineId:A,voiceId:q},qt(I),R.current=Bn(zt()),k=ar(p,{onStatus:L=>{l||S.current?.(L)},onError:L=>{l||U(L)},shouldAcceptLiveFrame:()=>x.current.isSpeaking()}),$.current=k,S.current?.("auth");const X=Z.current??r??await Pe(Fe(),3e4,"getAuthToken");if(l)return;Z.current=X,x.current.setDeveloperToken(X),x.current.setTtsEngineId(A);const Ce=ut()?await ce():void 0;if(l)return;S.current?.("loadAssets");const G=await Pe(k.loadAssets(Ce),18e4,"load face assets");if(!l&&G.width>0&&G.height>0&&(N.current=G,pe(G)),l)return;D.current=!0,ye(!0),M.current?.(),k.renderSilOnly().then(()=>{l||S.current?.("sil")}),(async()=>{try{if(await R.current.load(),l)return;H.current=!0,oe(!0),de(F.current),R.current.setActive(!0);const L=R.current.getVideo();await tt(p,L,null,void 0,N.current),l||S.current?.("idle")}catch(L){if(l)return;H.current=!1,oe(!1),console.warn("[AiTwin] Idle video unavailable:",L)}})()}catch(I){if(l)return;if(I instanceof ve){U(I.message);return}U(I instanceof Error?I.message:"Failed to load AI twin")}})(),()=>{l=!0,k?.dispose(),$.current=null}},[ue,n,s,o,r,ce,U]),_.useEffect(()=>{W==="done"&&K&&!x.current.isSpeaking()&&V()},[W,K,V]),_.useEffect(()=>{const l=x.current,p={current:!1},k=()=>{const I=E.current,A=$.current;if(!I||!A||!K){Q.current=requestAnimationFrame(k);return}const q=l.isSpeaking(),X=l.getPlaybackElapsedMs(),Ce=q?Wn(X,l.getSentenceEmotions(),l.getWordQueue(),l.getStreamMood()):l.getStreamMood();if(q){if(H.current&&R.current?.setActive(!1),l.getVisemeQueue().length===0){Q.current=requestAnimationFrame(k);return}B.current.setTargetEmotion(Ce),B.current.advance(performance.now());const L=B.current.getExpressionPath(),le=B.current.getDrawKey();nr(I,l.getVisemeQueue(),X,L,le,F.current,(fe,It)=>A.drawLiveFrame(fe,It),fe=>S.current?.(fe))}else if(H.current&&R.current){const G=R.current,L=G.getVideo();L.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA?(G.setActive(!0),p.current||(p.current=!0,tt(I,L,null,void 0,N.current,()=>!l.isSpeaking()).then(()=>S.current?.("idle")).finally(()=>{p.current=!1}))):rt(I,null,"__sil__",F.current,(le,fe)=>A.drawLiveFrame(le,fe),le=>S.current?.(le))}else rt(I,null,"__sil__",F.current,(G,L)=>A.drawLiveFrame(G,L),G=>S.current?.(G));b.current&&!q&&(B.current.reset(),R.current?.setActive(!1),V()),b.current=q,Q.current=requestAnimationFrame(k)};return Q.current=requestAnimationFrame(k),()=>{cancelAnimationFrame(Q.current),C(),l.stop()}},[K,xe,V,C]),_.useImperativeHandle(v,()=>({speakText:async(l,p)=>{const k=l.trim();if(!k)return;const I=$.current;if(!I||!D.current&&!K)throw new Error("AI twin is not ready");const{ttsEngineId:A,voiceId:q}=z(p);Y(null),w.current+=1,C(),de(F.current),B.current.reset(),b.current=!1;try{H.current?(R.current?.setActive(!1),R.current?.restart(),de(F.current)):await I.renderSilOnly(),await x.current.speak(k,{voiceId:q,speakingRate:p?.speakingRate??a,ttsEngineId:A})}catch(X){throw U(X instanceof Error?X.message:"TTS failed"),X}},stop:()=>{w.current+=1,C(),x.current.stop(),de(F.current),b.current=!1,V()},setTtsEngineId:l=>{x.current.setTtsEngineId(l),h.current&&(h.current.ttsEngineId=l)},renderViseme:async(l,p)=>{const k=$.current,I=E.current;if(!k||!I||!D.current)throw new Error("AI twin is not ready");await k.renderViseme(I,l,{from:p?.from,transitionDurationMs:p?.transitionDurationMs,gapMs:p?.gapMs,onStatus:A=>S.current?.(A)})},isReady:()=>D.current,getStatus:()=>W}),[K,a,C,V,U,z,W]),Me.jsxs("div",{className:c,style:{...ur,...u},children:[Me.jsx("canvas",{ref:E,width:re.width,height:re.height,style:{...lr,...m},"aria-label":t?`AI twin ${t}`:"AI twin face"}),g&&Ee?Me.jsx("div",{style:fr,children:Ee}):null]})});exports.AiTwin=dr;exports.AiTwinNotFoundError=ve;exports.DEFAULT_TTS_ENGINE_ID=He;exports.OCULUS_VISEME_IDS=lt;exports.SPEAKING_RATE_MAX=mt;exports.SPEAKING_RATE_MIN=_t;exports.TTS_ENGINE_CARTESIA=ge;exports.TTS_ENGINE_GOOGLE=te;exports.TTS_ENGINE_INWORLD=we;exports.VISEME_IDS=yn;exports.VISEME_TEST_CARTESIA_VOICE_ID=wt;exports.VISEME_TEST_SPEAKING_RATE=Ke;exports.VISEME_TEST_VOICE_ID=We;exports.createAvatarTtsLipsyncController=gt;exports.fetchAiTwin=ct;exports.fetchDevAuthToken=Fe;exports.normalizeOculusViseme=ft;exports.resolveVisemeAtTime=dt;exports.resolveWordAtTime=ht;
3
+ `);H=T.pop()??"";for(const A of T)await fe(A);if(de){H.trim()&&await fe(H.trim()),C||Z();break}}}catch(L){throw console.error("[avatarTtsLipsync]",L),X(),e("error"),L}},stop:X,getVisemeQueue:()=>r,getWordQueue:()=>s,getSentenceEmotions:()=>i,getStreamMood:()=>a,getPlaybackElapsedMs:()=>_?I&&d&&w>0?Math.max(0,(d.currentTime-w)*1e3):Math.max(0,(performance.now()-x)*R):0,isSpeaking:()=>_,setPlaybackSpeed:h=>{R=Math.max(.1,Math.min(1,h)),q()},getPlaybackSpeed:()=>R,subscribe:h=>(D.add(h),()=>D.delete(h))}}function Tn(e,t,n){return{width:e.crop?.source_width??t,height:e.crop?.source_height??n}}function In(e,t){const n=e.crop;return{x:t?.source_x??n?.x??0,y:t?.source_y??n?.y??0,width:t?.source_w??n?.width??e.frame_width??0,height:t?.source_h??n?.height??e.frame_height??0}}function kn(e){return e?(e.w??0)>0&&(e.h??0)>0:!1}async function Tt(e,t){const n=await fetch(e);if(!n.ok)throw new Error(`Failed to load encrypted asset: ${e}`);const r=await n.arrayBuffer();return Jt(r,t)}async function An(e,t){if(!t)throw new Error("Missing asset key for encrypted JSON");const n=await Tt(e,t),r=new TextDecoder().decode(n);return JSON.parse(r)}async function vn(e){const t=new Blob([e],{type:"image/webp"}),n=URL.createObjectURL(t);return new Promise((r,s)=>{const i=new Image;i.decoding="async",i.onload=()=>{URL.revokeObjectURL(n),r(i)},i.onerror=()=>{URL.revokeObjectURL(n),s(new Error("Failed to decode decrypted image"))},i.src=n})}function It(e,t){return`${e}/${t}_minus_sil.png`}const ze=15,Rn=["aa","E","I","O","U","PP","FF","DD","SS","TH","CH","RR","kk","nn"],Ve=["t01_0.17","t02_0.33","t03_0.50","t04_0.67","t05_0.83"],bn=Ve.length,Ze=new Set(["aa__kk","aa__nn","aa__sil","CH__aa","CH__DD","CH__E","CH__FF","CH__I","CH__kk","CH__nn","CH__O","CH__PP","CH__RR","CH__sil","CH__SS","CH__TH","CH__U","DD__aa","DD__E","DD__FF","DD__I","DD__kk","DD__nn","DD__O","DD__PP","DD__RR","DD__sil","DD__SS","DD__TH","DD__U","E__aa","E__FF","E__I","E__kk","E__nn","E__O","E__PP","E__RR","E__sil","E__SS","E__TH","E__U","FF__aa","FF__I","FF__kk","FF__nn","FF__O","FF__PP","FF__RR","FF__sil","FF__SS","FF__TH","FF__U","I__aa","I__kk","I__nn","I__O","I__PP","I__RR","I__sil","I__SS","I__TH","I__U","kk__nn","kk__sil","nn__sil","O__aa","O__kk","O__nn","O__PP","O__RR","O__sil","O__SS","O__TH","O__U","PP__aa","PP__kk","PP__nn","PP__RR","PP__sil","PP__SS","PP__TH","PP__U","RR__aa","RR__kk","RR__nn","RR__sil","RR__SS","RR__TH","RR__U","SS__aa","SS__kk","SS__nn","SS__sil","SS__TH","SS__U","TH__aa","TH__kk","TH__nn","TH__sil","TH__U","U__aa","U__kk","U__nn","U__sil"]);function et(e,t){return`${e}__${t}`}function tt(e,t){return`pairs/${e}/${t}_minus_sil.png`}function $e(e){return`${e}_minus_sil.png`}function Dn(e,t){if(e===t)return[];const n=[],r=et(e,t);if(Ze.has(r)){for(const i of Ve)n.push(tt(r,i));return n}const s=et(t,e);if(Ze.has(s)){for(let i=bn-1;i>=0;i--)n.push(tt(s,Ve[i]));return n}return[]}function xn(e){return e<16?[]:e<35?[2]:e<51?[0,4]:e<67?[0,2,4]:e<83?[0,1,2,3]:[0,1,2,3,4]}function Cn(e,t){return xn(t).map(r=>e[r]).filter(r=>r!=null)}function Mn(e,t,n,r){if(r<=0)return 0;const i=Math.max(1,n-t)/r,a=e-t,c=Math.floor(a/i);return Math.min(r-1,Math.max(0,c))}function Fn(e,t,n){if(!n)return`${e}/${t}`;const r=t.split("/").pop()??t,s=r.includes(".")?r.slice(0,r.lastIndexOf(".")):r;return`${e}/${s}.bin`}const On=[.32,.24,.16,.08,0],De=On.map(e=>`eyes_${e.toFixed(2)}`),Pn=["eyes_0.32","eyes_0.16","eyes_0.00"],Ln=["eyes_0.32","eyes_0.16","eyes_0.08","eyes_0.00"],Un={fear:"fear",afraid:"fear",anxiety:"fear",anger:"anger",angry:"anger",mad:"anger",sad:"sad",sadness:"sad",sorrow:"sad",neutral:"neutral",calm:"neutral",love:"love",loving:"love",affection:"love",happy:"happy",happiness:"happy",joy:"happy",joyful:"happy",excited:"happy",disgust:"disgust",disgusted:"disgust"};function oe(e,t="neutral"){const n=String(e??"").trim().toLowerCase();return n?Un[n]??t:t}function z(e){return e==="neutral"?null:It(e,"eyes_standard")}function He(e,t){return!t||t==="eyes_standard"?z(e):e==="neutral"&&t==="eyes_standard"?null:It(e,t)}function Nn(e){if(!e)return"open";const t=e.match(/\/(eyes_[^/]+)_minus_sil\.png$/);if(!t?.[1])return"open";const n=t[1];return De.includes(n)?n:"open"}function Bn(e){return e==="open"?-1:De.indexOf(e)}function Vn(e,t){const n=[];for(const r of t)n.push(He(e,r));for(let r=t.length-2;r>=0;r--)n.push(He(e,t[r]));return n.push(z(e)),n}function $n(e,t){if(t==="open")return[z(e)];const n=Bn(t);if(n<0)return[z(e)];const r=[];for(let s=n;s>=0;s--)r.push(He(e,De[s]));return r.push(z(e)),r}const Hn=["t01_0.20","t02_0.40","t03_0.60","t04_0.80"];function qn(e,t){return`${e}__${t}`}function Wn(e,t,n){return`pairs/${qn(e,t)}/${n}_minus_sil.png`}function Kn(e,t){return Hn.map(n=>Wn(e,t,n))}function _e(e,t){return e+Math.random()*(t-e)}function Te(){return _e(14,32)}function Gn(e={}){const{initialDelayMs:t=800+Math.random()*1200,intervalMinMs:n=2200,intervalMaxMs:r=5800,doubleBlinkChance:s=.18,doubleBlinkGapMinMs:i=120,doubleBlinkGapMaxMs:a=220,fullBlinkChance:c=.75,postEmotionChangeDelayMs:l=380,minDwellMs:d=550}=e;let m="neutral",_="neutral",I=0,o={kind:"idle",nextBlinkAt:performance.now()+t},x=null,w="__eyes_open__|neutral";function u(y,S){x=y,w=`${y??"__eyes_open__"}|${S}`}function g(y,S){o={kind:"idle",nextBlinkAt:y+_e(n,r)},_=S,u(z(S),S)}function E(y,S,C){const D=C?Pn:Math.random()<c?De:Ln;o={kind:"playing",paths:Vn(S,D),index:0,holdUntil:y+Te(),after:"idle",blinkEmotion:S},_=S,u(o.paths[0]??null,S)}function R(y,S,C){const D=Nn(x),q=[];if(D!=="open"){const W=$n(S,D);q.push(...W.slice(0,-1))}q.push(...Kn(S,C)),q.push(z(C)),o={kind:"emotionBlend",paths:q,index:0,holdUntil:y+Te(),thenEmotion:C},u(q[0]??null,S)}function $(y){if(o.kind==="emotionBlend"){for(;y>=o.holdUntil&&o.index<o.paths.length-1;)o.index+=1,o.holdUntil=y+Te();const S=o.paths[o.index]??null;u(S,o.thenEmotion),y>=o.holdUntil&&o.index>=o.paths.length-1&&(m=o.thenEmotion,_=o.thenEmotion,u(z(o.thenEmotion),o.thenEmotion),o={kind:"idle",nextBlinkAt:y+l});return}if(o.kind==="idle"){u(z(_),_),y>=o.nextBlinkAt&&E(y,_,!1);return}if(o.kind==="doublePause"){u(z(o.blinkEmotion),o.blinkEmotion),y>=o.resumeAt&&E(y,o.blinkEmotion,!0);return}if(o.kind==="playing"){for(;y>=o.holdUntil&&o.index<o.paths.length-1;)o.index+=1,o.holdUntil=y+Te();if(u(o.paths[o.index]??null,o.blinkEmotion),y>=o.holdUntil&&o.index>=o.paths.length-1){if(o.after==="resumeIdle"){g(y+l,m);return}if(o.after==="doublePause"){o={kind:"doublePause",resumeAt:y+_e(i,a),blinkEmotion:o.blinkEmotion},u(z(o.blinkEmotion),o.blinkEmotion);return}if(o.after==="idle"&&Math.random()<s){o={kind:"doublePause",resumeAt:y+_e(i,a),blinkEmotion:o.blinkEmotion},u(z(o.blinkEmotion),o.blinkEmotion);return}g(y,o.blinkEmotion)}}}return{advance:$,setTargetEmotion(y){const S=oe(y,m);if(S===m&&o.kind!=="emotionBlend")return;const C=performance.now();if(d>0&&S!==m&&o.kind!=="emotionBlend"&&!(m==="neutral"&&S!=="neutral")&&C-I<d)return;const D=m;if(m=S,I=C,o.kind==="playing"){R(C,_,S);return}if(o.kind==="emotionBlend"){o={...o,thenEmotion:S};return}R(C,D,S)},getTargetEmotion:()=>m,getExpressionPath:()=>x,getDrawKey:()=>w,reset(){m="neutral",_="neutral",I=0,g(performance.now()+_e(n,r),"neutral")}}}function jn(e){const t=document.createElement("video");t.muted=!0,t.playsInline=!0,t.preload="auto",t.setAttribute("playsinline",""),t.loop=!0;let n=!1;return{async load(){n||await new Promise((r,s)=>{const i=()=>{const a=t.duration;if(!Number.isFinite(a)||a<=0){s(new Error(`Idle video has invalid duration: ${e}`));return}n=!0,t.currentTime=0,r()};t.addEventListener("loadeddata",i,{once:!0}),t.addEventListener("error",()=>s(new Error(`Failed to load idle video: ${e}`)),{once:!0}),t.src=e,t.load()})},isReady(){return n},getVideo(){return t},setActive(r){n&&(r?t.paused&&t.play().catch(()=>{}):t.paused||t.pause())},restart(){n&&(t.currentTime=0)}}}const zn=50,kt=400;function Qn(e,t,n){return e.filter(r=>{const s=r.queueIndex??-1;return s>=t&&s<=n})}function Jn(e,t){const n=[];for(const r of e){const s=Qn(t,r.start_word,r.end_word);if(s.length===0)continue;const i=s[0],a=s[s.length-1];n.push({sentence:r,startMs:Math.max(0,i.wtime-zn),endMs:a.wtime+a.wduration+kt})}return n.sort((r,s)=>r.startMs-s.startMs)}function Yn(e,t,n,r="neutral"){const s=oe(r);if(t.length===0)return s;if(n.length===0||e<n[0].wtime)return oe(t[0]?.emotion,s);const i=Jn(t,n);let a=null;for(const d of i)e>=d.startMs&&e<=d.endMs&&(a=d);if(a)return oe(a.sentence.emotion,s);const c=n[n.length-1],l=c.wtime+c.wduration;return e>l+kt?oe(t[t.length-1]?.emotion,s):s}function At(e,t,n,r,s=ze){const i=new OffscreenCanvas(n,r),a=i.getContext("2d",{willReadFrequently:!0});a.drawImage(e,0,0,n,r);const c=a.getImageData(0,0,n,r),l=a.createImageData(n,r);l.data.set(c.data);const m=new OffscreenCanvas(n,r).getContext("2d",{willReadFrequently:!0});for(const _ of t){m.clearRect(0,0,n,r),m.drawImage(_,0,0,n,r);const I=m.getImageData(0,0,n,r);for(let o=0;o<l.data.length;o+=4){const x=I.data[o],w=I.data[o+1],u=I.data[o+2];Math.max(x,w,u)>s&&(l.data[o]=x,l.data[o+1]=w,l.data[o+2]=u,l.data[o+3]=255)}}return a.putImageData(l,0,0),i}let ne=null,me=null;const ve=new Map;function Xn(){ne=null,me=null,ve.clear()}en(Xn);function Zn(e){return e??me??void 0}function Qe(e){return new Promise((t,n)=>{const r=new Image;r.decoding="async",r.onload=()=>t(r),r.onerror=()=>n(new Error(`Failed to load image: ${e}`)),r.src=e})}async function nt(e,t,n,r){const s=n?await An(e,r):await fetch(e).then(d=>{if(!d.ok)throw new Error(`Failed to load ${e}`);return d.json()}),i=s.sheets?.[0];if(!i?.path)throw new Error(`${e} has no sheets[0].path`);const a=n?await vn(await Tt(Fn(t,i.path,n),r??"")):await Qe(`${t}/${i.path}`),c=new Map;for(const d of s.cells??[])d.path&&c.set(d.path,d);const l=new Map;for(const d of s.sheets??[])l.set(d.index,d);return{atlas:a,atlasMeta:s,cellByPath:c,sheetByIndex:l,diffBase:t}}async function qe(e){const t=Zn(e),n=ht();if(n&&!t)throw new Error("Encrypted assets enabled but no key provided");if(ne&&(!n||me===(t??null))){const i=await ne;return we(i)}me=t??null,ve.clear();const r=rn();ne=(async()=>{const i=await Qe(tn()),a=await nt(sn(),r,n,t);let c=null;try{c=await nt(on(),r,n,t)}catch{c=null}return{sil:i,viseme:a,expression:c}})();const s=await ne;return we(s)}async function vt(e){if(await qe(e),!ne)throw new Error("Assets not loaded");return ne}function we(e){return Tn(e.viseme.atlasMeta,e.sil.naturalWidth,e.sil.naturalHeight)}function er(e,t){const n=document.createElement("canvas");return n.width=t.w,n.height=t.h,n.getContext("2d",{willReadFrequently:!0}).drawImage(e.atlas,t.x,t.y,t.w,t.h,0,0,t.w,t.h),n}async function rt(e,t,n){const r=`${t.diffBase}::${n}`,s=ve.get(r);if(s)return s;const i=(async()=>{const a=t.cellByPath.get(n);if(!a)throw new Error(`No atlas cell for path: ${n}`);const c=In(t.atlasMeta,a),l=we(e);if(kn(a)){const _=er(t,a),I=document.createElement("canvas");I.width=l.width,I.height=l.height;const o=I.getContext("2d");return o.fillStyle="#000",o.fillRect(0,0,l.width,l.height),o.drawImage(_,c.x,c.y),I}const d=`${t.diffBase}/${n}`,m=await Qe(d);if(m.naturalWidth===l.width&&m.naturalHeight===l.height)return m;throw new Error(`Diff PNG wrong size for ${n}`)})();return ve.set(r,i),i}async function st(e,t,n,r=ze,s,i){if(s){const{width:I,height:o}=s;if(i&&!i()||t.readyState<HTMLMediaElement.HAVE_CURRENT_DATA)return;const x=document.createElement("canvas");x.width=I,x.height=o;const w=x.getContext("2d");if(w.clearRect(0,0,I,o),w.drawImage(t,0,0,I,o),i&&!i())return;(e.width!==I||e.height!==o)&&(e.width=I,e.height=o);const u=e.getContext("2d");u.clearRect(0,0,I,o),u.drawImage(x,0,0);return}const a=await vt(),{width:c,height:l}=we(a);(e.width!==c||e.height!==l)&&(e.width=c,e.height=l);const d=[],m=e.getContext("2d");if(m.clearRect(0,0,c,l),t.readyState<HTMLMediaElement.HAVE_CURRENT_DATA){const I=a.sil;m.drawImage(I,0,0,c,l);return}if(d.length===0){m.drawImage(t,0,0,c,l);return}const _=At(t,d,c,l,r);m.drawImage(_,0,0)}async function We(e,t,n=ze){const r=await vt(me??void 0),{width:s,height:i}=we(r);(e.width!==s||e.height!==i)&&(e.width=s,e.height=i);const a=[];t.mouthPath&&a.push(await rt(r,r.viseme,t.mouthPath)),t.expressionPath&&r.expression&&a.push(await rt(r,r.expression,t.expressionPath));const c=e.getContext("2d");if(c.clearRect(0,0,s,i),a.length===0){c.drawImage(r.sil,0,0,s,i);return}const l=At(r.sil,a,s,i,n);c.drawImage(l,0,0)}async function tr(e){await We(e,{mouthPath:null,expressionPath:null})}function nr(e){const t=new Map;for(const n of e)t.has(n.vtime)||t.set(n.vtime,n);return[...t.values()].sort((n,r)=>n.vtime-r.vtime)}function rr(e){const t=nr(e),n=[];for(let r=0;r<t.length-1;r++){const s=t[r].viseme,i=t[r+1].viseme,a=t[r].vtime,c=t[r+1].vtime;s===i||c<=a||n.push({from:s,to:i,fromVtime:a,toVtime:c})}return n}function sr(e,t){let n=null;for(const r of e)t>=r.fromVtime&&t<r.toVtime&&(n=r);return n}function ir(e,t){return{gapMs:Math.max(0,t-e),holdEnd:e,transStart:e}}const or=500,ar="__sil__";function cr(){return{lastDrawnKey:""}}function he(e){e.lastDrawnKey=""}function it(e){return e??ar}function ur(e,t){if(e.length===0)return{diffPath:null,label:"sil"};const n=rr(e),r=sr(n,t);if(r){const i=r.toVtime-r.fromVtime,a=ir(r.fromVtime,r.toVtime);if(t>=a.transStart&&t<r.toVtime){const c=Dn(r.from,r.to),l=Cn(c,i);if(l.length>0){const d=Mn(t,a.transStart,r.toVtime,l.length);return{diffPath:l[d]??l[l.length-1],label:`${r.from}→${r.to}`}}return{diffPath:$e(r.to),label:r.to}}}const s=wt(e,t);return s==="sil"?{diffPath:null,label:"sil"}:{diffPath:$e(s),label:s}}function Rt(e,t){const n=t??it(e.expressionPath);return`${it(e.mouthPath)}|${n}`}function lr(e,t,n,r,s,i,a,c){const l=ur(t,n),d={mouthPath:l.diffPath,expressionPath:r},m=Rt(d,s);m!==i.lastDrawnKey&&(c(l.label),a(e,d,m,_=>{_===m&&(i.lastDrawnKey=m)}))}function ot(e,t,n,r,s,i,a=null){const c={mouthPath:null,expressionPath:t},l=a!=null?`|idle@${Math.round(a*1e3)}`:"",d=Rt(c,n)+l;!(a!=null)&&d===r.lastDrawnKey||(i(a!=null?"idle":"sil"),s(e,c,d,_=>{_===d&&(r.lastDrawnKey=d)}))}function bt(e){let t=0,n=null,r=!1,s=!1;const i=async()=>{if(!r){r=!0;try{for(;n;){const c=n;n=null;const l=++t,d=await e(c.diffs,l,c);n||d&&l===t&&c.onDisplayed?.(c.drawKey)}}finally{r=!1,n&&i()}}},a=()=>{s||(s=!0,queueMicrotask(()=>{s=!1,i()}))};return{enqueue(c,l,d){n={diffs:c,drawKey:l,onDisplayed:d},a()},reset(){t+=1,n=null},isLatestSeq(c){return c===t},getLatestSeq(){return t}}}const at=-1,ct=new Map;async function fr(e){let t=ct.get(e);if(!t){const n=await fetch(e);if(!n.ok)throw new Error(`Failed to fetch worker script (${n.status}): ${e}`);const r=await n.blob();t=URL.createObjectURL(r),ct.set(e,t)}return new Worker(t,{name:"visemeDiffPreview"})}function dr(){return typeof Worker<"u"&&typeof OffscreenCanvas<"u"}function hr(e,t){(e.width!==t.width||e.height!==t.height)&&(e.width=t.width,e.height=t.height);const n=e.getContext("2d");n&&n.drawImage(t,0,0)}function ut(e,t){let n=0;const r=bt(async(s,i)=>(await qe(),await We(e,s),r.isLatestSeq(i)));return{usesWorker:!1,async loadAssets(s){return await qe(s)},async renderSilOnly(){n+=1,r.reset(),await tr(e)},drawLiveFrame(s,i,a,c){r.enqueue(i,a,c)},async renderViseme(s,i){n+=1;const a=n;t.onStatus?.(i),await We(s,{mouthPath:$e(i),expressionPath:null})},dispose(){n+=1,r.reset()}}}function _r(e,t,n){let r=null,s=1,i=0,a=!1,c=!1;const l=new Map,d=bt(async(w,u,g)=>(l.set(u,{drawKey:g.drawKey,onDisplayed:g.onDisplayed}),await o({type:"drawFrame",diffPath:w.mouthPath,expressionDiffPath:w.expressionPath,liveSeq:u},void 0,!0),!1)),m=w=>{if(w===at){let E=-1,R;for(const[$,y]of l)$>=E&&(E=$,R=y);E>=0&&l.delete(E),R?.onDisplayed?.(R.drawKey);return}const u=-w,g=l.get(u);l.delete(u),g?.onDisplayed?.(g.drawKey)},_=new Map,I=(w,u)=>{c||!r||r.postMessage(w,[])},o=(w,u,g=!1)=>{if(c)return Promise.resolve();const E=s++;return new Promise((R,$)=>{_.set(E,{resolve:y=>R(y),reject:$,generation:typeof w.generation=="number"?w.generation:void 0,expectRenderDone:g}),I({...w,requestId:E})})},x=(async()=>{r=await fr(n),r.onmessage=w=>{if(c)return;const u=w.data;if(u.type==="status"){t.onStatus?.(u.label);return}if(u.type==="frame"){const E=u.generation<0;if(!E&&u.generation!==i){u.bitmap.close();return}if(E&&!(u.generation===at)){const $=-u.generation;if(!d.isLatestSeq($)){u.bitmap.close();return}}if(E&&t.shouldAcceptLiveFrame&&!t.shouldAcceptLiveFrame()){u.bitmap.close();return}hr(e,u.bitmap),u.bitmap.close(),E&&m(u.generation);return}const g=_.get(u.requestId);if(g)switch(u.type){case"ready":_.delete(u.requestId),g.resolve();break;case"loadAssetsDone":_.delete(u.requestId),g.resolve({width:u.width,height:u.height});break;case"renderDone":if(g.expectRenderDone&&g.generation!=null&&u.generation!==g.generation)return;_.delete(u.requestId),g.resolve();break;case"renderAborted":_.delete(u.requestId),g.resolve();break;case"error":_.delete(u.requestId),t.onError?.(u.message),g.reject(new Error(u.message));break}},r.onerror=w=>{if(c)return;const u=w.message||"Worker error";t.onError?.(u);for(const[,g]of _)g.reject(new Error(u));_.clear()},await o({type:"init"}),a=!0})();return{usesWorker:!0,async loadAssets(w){if(c)return{width:842,height:1264};if(await x,c)return{width:842,height:1264};if(!a)throw new Error("Worker init failed");return await o({type:"loadAssets",keyHex:w,urls:Zt(se())})??{width:842,height:1264}},async renderSilOnly(){if(c||(await x,c))return;i+=1,d.reset(),l.clear();const w=i;await o({type:"renderSil",generation:w},void 0,!0)},drawLiveFrame(w,u,g,E){c||x.then(()=>{c||d.enqueue(u,g,E)})},async renderViseme(w,u,g={}){if(c||(await x,c))return;i+=1;const E=i;try{await o({type:"renderViseme",generation:E,to:u,from:g.from,transitionDurationMs:g.transitionDurationMs,gapMs:g.gapMs,threshold:g.threshold},void 0,!0)}catch(R){if(R?.name==="AbortError")return;throw R}},dispose(){if(!c){c=!0,i+=1,d.reset(),l.clear();for(const[,w]of _)w.resolve();_.clear(),r?.terminate(),r=null}}}}function mr(e,t={}){if(!dr())return ut(e,t);const n=Lt(t.workerScriptUrl);try{return _r(e,t,n)}catch{return ut(e,t)}}class wr extends Error{constructor(t,n){super(`${t} timed out after ${Math.round(n/1e3)}s`),this.name="LoadTimeoutError"}}function Le(e,t,n){return new Promise((r,s)=>{const i=globalThis.setTimeout(()=>{s(new wr(n,t))},t);e.then(a=>{globalThis.clearTimeout(i),r(a)},a=>{globalThis.clearTimeout(i),s(a)})})}const gr={position:"relative",display:"inline-block",lineHeight:0},yr={display:"block",maxWidth:"100%",height:"auto"},pr={position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",padding:"1rem",background:"rgba(0,0,0,0.55)",color:"#fff",fontSize:"0.875rem",textAlign:"center"};function Ie(e){return Vt(e)?Et:Ge}const Er=p.forwardRef(function({id:t,assets:n,authToken:r,ttsEngineId:s=re,voiceId:i,speakingRate:a=je,className:c,style:l,canvasStyle:d,onStatusChange:m,onDisplayStatus:_,onError:I,onReady:o,showErrorOverlay:x=!0},w){const u=p.useRef(null),g=p.useRef(null),E=p.useRef(cr()),R=p.useRef(Gn()),$=p.useRef(0),y=p.useRef(0),S=p.useRef(null),C=p.useRef(!1),D=p.useRef(null),q=p.useRef(!1),[W,ce]=p.useState("idle"),[ge,X]=p.useState(null),[K,ye]=p.useState(!1),[xe,ue]=p.useState(!1),[ie,pe]=p.useState({width:842,height:1264}),Z=p.useRef(r??null),le=p.useRef(null),h=p.useRef(null),M=p.useRef(!1),B=p.useRef({width:842,height:1264}),P=p.useRef(o),k=p.useRef(_),U=p.useRef(I);P.current=o,k.current=_,U.current=I;const Q=p.useCallback(f=>{const T=f?.ttsEngineId??s??h.current?.ttsEngineId??re,A=f?.voiceId??i??h.current?.voiceId??Ie(T);return{ttsEngineId:T,voiceId:A}},[s,i]),V=p.useCallback(f=>{X(f),U.current?.(f)},[]),L=p.useCallback(f=>{ce(f),m?.(f)},[m]),F=p.useRef(St(L,ke)),O=p.useCallback(()=>{S.current!=null&&(clearTimeout(S.current),S.current=null)},[]),J=p.useCallback(async()=>{const f=y.current,T=g.current;!T||!K||F.current.isSpeaking()||(he(E.current),await T.renderSilOnly(),f===y.current&&(F.current.isSpeaking()||(k.current?.("sil"),q.current&&D.current&&(D.current.restart(),D.current.setActive(!0)))))},[K]),H=p.useCallback(()=>{O();const f=y.current;J(),S.current=setTimeout(()=>{S.current=null,f===y.current&&J()},or)},[O,J]),fe=p.useCallback(async()=>{const f=Math.floor(Date.now()/1e3);if(le.current&&f<le.current.expiresAt-60)return le.current.key;const T=Z.current??await Ue();Z.current=T,F.current.setDeveloperToken(T);const A=await jt(T,ke);return le.current={key:A.value,expiresAt:A.expiresAt},A.value},[]);p.useEffect(()=>{r&&(Z.current=r,F.current.setDeveloperToken(r))},[r]),p.useEffect(()=>{F.current.setTtsEngineId(s),h.current&&(h.current.ttsEngineId=s)},[s]),p.useEffect(()=>{const f=i??Ie(s);h.current&&(h.current.voiceId=f)},[i,s]);const de=p.useMemo(()=>n?JSON.stringify(n):`id:${t??""}`,[n,t]);return p.useEffect(()=>{if(!t&&!n){V("AiTwin requires either `id` or `assets`");return}let f=!1;M.current=!1,ye(!1),ue(!1),X(null),h.current=null,D.current=null,q.current=!1;const T=u.current;if(!T)return;let A=null;return(async()=>{try{let v,b,G;if(n)v=n,b=s,G=i??Ie(b);else{k.current?.("getAiTwin");const N=await Le(dt(t),3e4,"getAiTwin");if(f)return;if(!N.faceId?.trim())throw new Error("getAiTwin returned no faceId");b=N.ttsEngineId,G=i??N.voiceId??Ie(b),v=Yt(N.faceId)}h.current={ttsEngineId:b,voiceId:G},Xt(v),D.current=jn(nn()),A=mr(T,{onStatus:N=>{f||k.current?.(N)},onError:N=>{f||V(N)},shouldAcceptLiveFrame:()=>F.current.isSpeaking()}),g.current=A,k.current?.("auth");const Y=Z.current??r??await Le(Ue(),3e4,"getAuthToken");if(f)return;Z.current=Y,F.current.setDeveloperToken(Y),F.current.setTtsEngineId(b);const Ce=ht()?await fe():void 0;if(f)return;k.current?.("loadAssets");const j=await Le(A.loadAssets(Ce),18e4,"load face assets");if(!f&&j.width>0&&j.height>0&&(B.current=j,pe(j)),f)return;M.current=!0,ye(!0),P.current?.(),A.renderSilOnly().then(()=>{f||k.current?.("sil")}),(async()=>{try{if(await D.current.load(),f)return;q.current=!0,ue(!0),he(E.current),D.current.setActive(!0);const N=D.current.getVideo();await st(T,N,null,void 0,B.current),f||k.current?.("idle")}catch(N){if(f)return;q.current=!1,ue(!1),console.warn("[AiTwin] Idle video unavailable:",N)}})()}catch(v){if(f)return;if(v instanceof Ae){V(v.message);return}V(v instanceof Error?v.message:"Failed to load AI twin")}})(),()=>{f=!0,A?.dispose(),g.current=null}},[de,n,s,i,r,fe,V]),p.useEffect(()=>{W==="done"&&K&&!F.current.isSpeaking()&&H()},[W,K,H]),p.useEffect(()=>{const f=F.current,T={current:!1},A=()=>{const v=u.current,b=g.current;if(!v||!b||!K){$.current=requestAnimationFrame(A);return}const G=f.isSpeaking(),Y=f.getPlaybackElapsedMs(),Ce=G?Yn(Y,f.getSentenceEmotions(),f.getWordQueue(),f.getStreamMood()):f.getStreamMood();if(G){if(q.current&&D.current?.setActive(!1),f.getVisemeQueue().length===0){$.current=requestAnimationFrame(A);return}R.current.setTargetEmotion(Ce),R.current.advance(performance.now());const N=R.current.getExpressionPath(),ee=R.current.getDrawKey();lr(v,f.getVisemeQueue(),Y,N,ee,E.current,(te,Me,Fe,Dt)=>b.drawLiveFrame(te,Me,Fe,Dt),te=>k.current?.(te))}else if(q.current&&D.current){const j=D.current,N=j.getVideo();N.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA?(j.setActive(!0),T.current||(T.current=!0,st(v,N,null,void 0,B.current,()=>!f.isSpeaking()).then(()=>k.current?.("idle")).finally(()=>{T.current=!1}))):ot(v,null,"__sil__",E.current,(ee,te,Me,Fe)=>b.drawLiveFrame(ee,te,Me,Fe),ee=>k.current?.(ee))}else ot(v,null,"__sil__",E.current,(j,N,ee,te)=>b.drawLiveFrame(j,N,ee,te),j=>k.current?.(j));C.current&&!G&&(R.current.reset(),D.current?.setActive(!1),H()),C.current=G,$.current=requestAnimationFrame(A)};return $.current=requestAnimationFrame(A),()=>{cancelAnimationFrame($.current),O(),f.stop()}},[K,xe,H,O]),p.useImperativeHandle(w,()=>({speakText:async(f,T)=>{const A=f.trim();if(!A)return;const v=g.current;if(!v||!M.current&&!K)throw new Error("AI twin is not ready");const{ttsEngineId:b,voiceId:G}=Q(T);X(null),y.current+=1,O(),he(E.current),R.current.reset(),C.current=!1;try{q.current?(D.current?.setActive(!1),D.current?.restart(),he(E.current)):await v.renderSilOnly(),await F.current.speak(A,{voiceId:G,speakingRate:T?.speakingRate??a,ttsEngineId:b})}catch(Y){throw V(Y instanceof Error?Y.message:"TTS failed"),Y}},stop:()=>{y.current+=1,O(),F.current.stop(),he(E.current),C.current=!1,H()},setTtsEngineId:f=>{F.current.setTtsEngineId(f),h.current&&(h.current.ttsEngineId=f)},renderViseme:async(f,T)=>{const A=g.current,v=u.current;if(!A||!v||!M.current)throw new Error("AI twin is not ready");await A.renderViseme(v,f,{from:T?.from,transitionDurationMs:T?.transitionDurationMs,gapMs:T?.gapMs,onStatus:b=>k.current?.(b)})},isReady:()=>M.current,getStatus:()=>W}),[K,a,O,H,V,Q,W]),Oe.jsxs("div",{className:c,style:{...gr,...l},children:[Oe.jsx("canvas",{ref:u,width:ie.width,height:ie.height,style:{...yr,...d},"aria-label":t?`AI twin ${t}`:"AI twin face"}),x&&ge?Oe.jsx("div",{style:pr,children:ge}):null]})});exports.AiTwin=Er;exports.AiTwinNotFoundError=Ae;exports.DEFAULT_TTS_ENGINE_ID=re;exports.OCULUS_VISEME_IDS=_t;exports.SPEAKING_RATE_MAX=pt;exports.SPEAKING_RATE_MIN=yt;exports.TTS_ENGINE_CARTESIA=ae;exports.TTS_ENGINE_GOOGLE=Ke;exports.TTS_ENGINE_INWORLD=Re;exports.VISEME_IDS=Rn;exports.VISEME_TEST_CARTESIA_VOICE_ID=Et;exports.VISEME_TEST_SPEAKING_RATE=je;exports.VISEME_TEST_VOICE_ID=Ge;exports.createAvatarTtsLipsyncController=St;exports.fetchAiTwin=dt;exports.fetchDevAuthToken=Ue;exports.normalizeOculusViseme=mt;exports.resolveVisemeAtTime=wt;exports.resolveWordAtTime=gt;