@streamoji/aitwin 0.6.4 → 0.6.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/aitwin.cjs +6 -6
- package/dist/aitwin.js +1770 -1733
- package/dist/index.d.ts +25 -1
- package/package.json +1 -1
package/dist/aitwin.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const R=require("react/jsx-runtime"),h=require("react"),us=require("@pipecat-ai/client-js"),Hn=require("@pipecat-ai/websocket-transport"),we=require("pixi.js");var xn=typeof document<"u"?document.currentScript:null;const ds="https://aitwin.bubu.social",ri={publicBase:ds},fs="0.6.4",ms={version:fs},hs={},ht="https://ai.aitwin.me",$n=`${ri.publicBase}/custom-faces`,gs=`${ri.publicBase}/aitwin-workers/v${ms.version}/visemeDiffPreview.worker.js`;function ws(e){if(e)return e;const t=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:xn&&xn.tagName.toUpperCase()==="SCRIPT"&&xn.src||new URL("aitwin.cjs",document.baseURI).href}<"u"?hs?.VITE_AITWIN_WORKER_URL:void 0;return t?.trim()?t.trim():gs}const ps="https://us-central1-streamoji-265f4.cloudfunctions.net/getAiTwin",In=3e3,Ot=16,Er=3e3,ys=4e3,vs=.85,_s=8,jn=400,Kn="eng_a7f2b9c1",un="eng_d4e8f3a2",tt="eng_c9b1e6d4",nt="visemetts",dt=tt,dn="eve",ii=new Set([un,tt,nt]),Gn={[Kn]:"oculus_direct",[tt]:"oculus_direct",[nt]:"oculus_direct",[un]:"inworld_word"},Dn={google:Kn,inworld:un,cartesia:tt,visemetts:nt};function bs(e){const t=e.trim();if(t)return t in Gn?t:Dn[t.toLowerCase()]}function si(e){const t=e?.trim();if(!t)return{};const n=t.indexOf(":");if(n<=0)return{voiceId:t};const r=bs(t.slice(0,n));if(!r)return{voiceId:t};const i=t.slice(n+1).trim();return{ttsEngineId:r,voiceId:i||void 0}}function et(e,t){const n=si(t);return{ttsEngineId:e??n.ttsEngineId,voiceId:n.voiceId}}function ai(e){return Gn[e]}function Ss(e){return e===tt}function oi(e){return e===nt}function Ts(e){if(e.ttsEngineId&&e.ttsEngineId in Gn)return e.ttsEngineId;const t=e.tts?.toLowerCase();return t&&t in Dn?Dn[t]:dt}class nn extends Error{constructor(t="AI twin not found"){super(t),this.name="AiTwinNotFoundError"}}function qn(e,...t){const n=typeof e=="string"?e:e?.brainId?.trim()||e?.knowledgeContextId?.trim();for(const r of[n,...t]){const i=r?.trim();if(i)return i}}async function ci(e,t=ps){const n=new URL(t);n.searchParams.set("id",e);const r=await fetch(n.toString());if(r.status===404)throw new nn;if(!r.ok)throw new Error(`getAiTwin failed (${r.status})`);const i=await r.json();if(!i.success)throw new nn(i.error??"AI twin not found");const{tts:s,token:o,...a}=i.data,u=String(a.authToken??o??"").trim()||void 0,d=qn(a);return{...a,ttsEngineId:Ts(i.data),authToken:u,brainId:d,knowledgeContextId:d}}const Yn="thumbnail.webp";function li(e,t=$n){const n=e.trim();if(!n)throw new Error("faceId is required");return`${t.replace(/\/$/,"")}/${n}/${Yn}`}function xr(e){const t=e?.trim();if(!t)return null;try{return li(t)}catch{return null}}function ks(e){if(!e)return null;const t=(e.binBase||e.twinBase).trim().replace(/\/$/,"");return t?`${t}/${Yn}`:null}const Es="https://us-central1-streamoji-265f4.cloudfunctions.net/getAuthToken",xs="client_6TNvp3SCs4Og0a1ijm9TommXLql1",Is="kk8Fq8EmexzP10jMIEwY3R44M5RKUEm1",As="6TNvp3SCs4Og0a1ijm9TommXLql1",Ms="Swaraj Mali";async function Nt(){const e=await fetch(Es,{method:"POST",headers:{"Content-Type":"application/json","Client-Id":xs,"Client-Secret":Is},body:JSON.stringify({userId:As,userName:Ms})});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 Ps(e,t=ht){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 Cs(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 Xt(e){return Uint8Array.from(e)}function Rs(e,t){const n=new Uint8Array(e.length+t.length);return n.set(e,0),n.set(t,e.length),n}async function Ds(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=Xt(n.subarray(0,12)),i=Xt(n.subarray(12,28)),s=Xt(n.subarray(28)),o=Xt(Rs(s,i)),a=await crypto.subtle.importKey("raw",Cs(t),{name:"AES-GCM"},!1,["decrypt"]);return crypto.subtle.decrypt({name:"AES-GCM",iv:r,tagLength:128},a,o)}let Bn=null;const Fn=new Set;function Jt(e){return e.includes("/custom-faces/")}function rn(e){const t=e.binBase.trim().replace(/\/$/,""),n=e.twinBase.trim().replace(/\/$/,"");if(!(e.encrypted||Jt(t)||Jt(n)))return{twinBase:n,binBase:t,encrypted:!1};const i=Jt(t)?t:Jt(n)?n:t;return{twinBase:i,binBase:i,encrypted:!0}}function gt(e){return rn(e).encrypted}function Ln(e,t=$n){const n=`${t.replace(/\/$/,"")}/${e}`;return{twinBase:n,binBase:n,encrypted:!0}}function ui(e,t){return(e??t)?.trim()||void 0}function di(e){Bn=rn(e);for(const t of Fn)t()}function Bs(e,t){const n=typeof globalThis.location<"u"?globalThis.location.href:void 0;if(!n)return rn(e);const r=i=>{try{return new URL(i,n).href.replace(/\/$/,"")}catch{return i}};return rn({twinBase:r(e.twinBase),binBase:r(e.binBase),encrypted:e.encrypted})}function wt(){if(!Bn)throw new Error("Twin assets not configured; call setActiveTwinAssets first");return Bn}function fi(e){return Fn.add(e),()=>Fn.delete(e)}function sn(){const e=wt();return gt(e)?`${e.binBase}/sil.bin`:`${e.twinBase}/sil.png`}function Fs(){const e=wt();return gt(e)?`${e.binBase}/idle.bin`:`${e.twinBase}/idle.mp4`}function mi(){const e=wt();return gt(e)?e.binBase:e.twinBase}function Wt(){return gt(wt())}function hi(){const e=wt();return gt(e)?`${e.binBase}/atlas.bin`:`${e.twinBase}/atlas.json`}function gi(){const e=wt();return gt(e)?`${e.binBase}/expression_atlas.bin`:`${e.twinBase}/expression_atlas.json`}const ft=[{code:"en",label:"English",visemetts:!0,cartesia:!0},{code:"es",label:"Spanish",visemetts:!0,cartesia:!0},{code:"es-MX",label:"Spanish (Mexico)",visemetts:!0,cartesia:!0},{code:"es-ES",label:"Spanish (Spain)",visemetts:!0,cartesia:!0},{code:"pt",label:"Portuguese",visemetts:!0,cartesia:!0},{code:"pt-BR",label:"Portuguese (Brazil)",visemetts:!0,cartesia:!0},{code:"pt-PT",label:"Portuguese (Portugal)",visemetts:!0,cartesia:!0},{code:"fr",label:"French",visemetts:!0,cartesia:!0},{code:"de",label:"German",visemetts:!0,cartesia:!0},{code:"it",label:"Italian",visemetts:!0,cartesia:!0},{code:"zh",label:"Chinese",visemetts:!0,cartesia:!0},{code:"ja",label:"Japanese",visemetts:!0,cartesia:!0},{code:"hi",label:"Hindi",visemetts:!0,cartesia:!0},{code:"ko",label:"Korean",visemetts:!0,cartesia:!0},{code:"ru",label:"Russian",visemetts:!0,cartesia:!0},{code:"tr",label:"Turkish",visemetts:!0,cartesia:!0},{code:"id",label:"Indonesian",visemetts:!0,cartesia:!0},{code:"ar",label:"Arabic",visemetts:!0,cartesia:!0},{code:"ar-EG",label:"Arabic (Egypt)",visemetts:!0,cartesia:!0},{code:"ar-AE",label:"Arabic (UAE)",visemetts:!0,cartesia:!0},{code:"vi",label:"Vietnamese",visemetts:!0,cartesia:!0},{code:"bn",label:"Bengali",visemetts:!0,cartesia:!0},{code:"auto",label:"Auto-detect",visemetts:!0,cartesia:!1},{code:"nl",label:"Dutch",visemetts:!1,cartesia:!0},{code:"pl",label:"Polish",visemetts:!1,cartesia:!0},{code:"sv",label:"Swedish",visemetts:!1,cartesia:!0},{code:"tl",label:"Tagalog",visemetts:!1,cartesia:!0},{code:"bg",label:"Bulgarian",visemetts:!1,cartesia:!0},{code:"ro",label:"Romanian",visemetts:!1,cartesia:!0},{code:"cs",label:"Czech",visemetts:!1,cartesia:!0},{code:"el",label:"Greek",visemetts:!1,cartesia:!0},{code:"fi",label:"Finnish",visemetts:!1,cartesia:!0},{code:"hr",label:"Croatian",visemetts:!1,cartesia:!0},{code:"ms",label:"Malay",visemetts:!1,cartesia:!0},{code:"sk",label:"Slovak",visemetts:!1,cartesia:!0},{code:"da",label:"Danish",visemetts:!1,cartesia:!0},{code:"ta",label:"Tamil",visemetts:!1,cartesia:!0},{code:"uk",label:"Ukrainian",visemetts:!1,cartesia:!0},{code:"hu",label:"Hungarian",visemetts:!1,cartesia:!0},{code:"no",label:"Norwegian",visemetts:!1,cartesia:!0},{code:"th",label:"Thai",visemetts:!1,cartesia:!0},{code:"he",label:"Hebrew",visemetts:!1,cartesia:!0},{code:"ka",label:"Georgian",visemetts:!1,cartesia:!0},{code:"te",label:"Telugu",visemetts:!1,cartesia:!0},{code:"gu",label:"Gujarati",visemetts:!1,cartesia:!0},{code:"kn",label:"Kannada",visemetts:!1,cartesia:!0},{code:"ml",label:"Malayalam",visemetts:!1,cartesia:!0},{code:"mr",label:"Marathi",visemetts:!1,cartesia:!0},{code:"pa",label:"Punjabi",visemetts:!1,cartesia:!0}],wi=ft.map(e=>e.code),Ls=new Set(wi),Os=new Set(ft.filter(e=>e.visemetts).map(e=>e.code)),Ns=new Set(ft.filter(e=>e.cartesia).map(e=>e.code)),Vs="en";function pi(e){return Ls.has(e)}function fn(e){const t=e?.trim();if(t)return t}function Us(e){return e===nt?ft.filter(t=>t.visemetts).map(t=>t.code):e===tt?ft.filter(t=>t.cartesia).map(t=>t.code):ft.filter(t=>t.visemetts&&t.cartesia).map(t=>t.code)}function Ws(e,t){const n=t.trim();return n?e===nt?Os.has(n):e===tt?Ns.has(n):pi(n):!1}function yi(e){const t=e.split(/\r?\n/);let n="",r="";for(const s of t)s.startsWith("event:")?n=s.slice(6).trim():s.startsWith("data:")&&(r=s.slice(5).trim());if(!n)return null;let i={};if(r)try{i=JSON.parse(r)}catch{i={raw:r}}return{event:n,data:i}}const vi=["aa","CH","DD","E","FF","I","O","PP","RR","SS","TH","U","kk","nn","sil"],zs=new Map(vi.map(e=>[e.toLowerCase(),e]));function mn(e){const t=(e??"").trim();return t?zs.get(t.toLowerCase())??"sil":"sil"}const Hs={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 $s(e){if(!e)return["sil"];const t=e.toLowerCase();return Hs[t]??["sil"]}function _i(e,t){const n=e.word.length;if(n<=0)return 0;const r=e.wduration;if(r<=0)return 0;const i=Math.max(0,Math.min(1,(t-e.wtime)/r));return Math.min(n-1,Math.floor(i*n))}function Et(e,t){const n=Math.max(0,Math.min(e.length-1,t));return e[n]??""}function hn(e,t){const n=e.toLowerCase().replace(/[^a-z']/g,"");return!n||Et(n,t)!=="w"||t>0&&Et(n,t-1)==="q"?!1:t===0&&/^w[aeiouy]/.test(n)}function js(e,t){const n=e.toLowerCase(),r=Et(n,t),i=n.slice(Math.max(0,t-1),t+2);return r==="i"||r==="y"?"I":i.includes("ee")||r==="e"||n.includes("ea")?"E":"aa"}function Ks(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";if(hn(n,t))return"FF";const i=Et(n,t);return i==="u"||i==="w"?"U":"O"}function Gs(e,t){const n=e.toLowerCase();if(hn(n,t))return"FF";const r=n.slice(Math.max(0,t-2),t+1);if(/qu/.test(r))return"U";const i=n.slice(Math.max(0,t-1),Math.min(n.length,t+3));return/wo|wh/.test(i)||Et(n,t)==="o"?"O":"U"}const Zt={d:"DD",t:"DD",n:"DD",s:"SS",z:"SS",k:"kk",g:"kk",c:"CH",x:"CH",j:"CH"};function qs(e,t){const n=e.toLowerCase(),r=Et(n,t);if(Zt[r])return Zt[r];for(let i=0;i<n.length;i++){const s=n[i];if(Zt[s])return Zt[s]}return"DD"}function bi(e,t,n){const r=$s(e);if(r.length===1)return r[0];const i=t.trim();if(!i)return r[0];const s=(e??"").toLowerCase(),o=Math.max(0,n);switch(s){case"aei":return js(i,o);case"o":return Ks(i,o);case"qw":return Gs(i,o);case"cdgknstxyz":return qs(i,o);default:return r[0]}}const Qn=16,On=47,Si=new Set(["aa","E","I"]),Ti=new Set(["DD","SS","kk","CH"]),Ys=[Si,Ti];function Qs(e){for(const t of Ys)if(t.has(e))return t;return null}function Xs(e){return Qs(e)!=null}function ki(e,t=Qn){return t<=0?e:Math.round(e/t)*t}function Xn(e,t=Qn){return e.map(n=>({...n,vtime:ki(n.vtime,t)}))}function Ei(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 Jn(e){if(e.length<=2)return[...e];const t=[e[0]];for(let n=1;n<e.length-1;n++){const r=e[n],i=e[n+1],s=t[t.length-1];if(!Xs(r.viseme)){t.push(r);continue}const o=r.vtime-s.vtime,a=i.vtime-r.vtime;o<On||a<On||t.push(r)}return t.push(e[e.length-1]),t}function gn(e){return Jn(Ei(Xn(e)))}function xi(e,t){let n="sil";for(const r of e){if(r.vtime>t)break;r.viseme!=="sil"&&(n=r.viseme)}return n}function wn(e){const t=Ei(Xn(e)),n=Jn(t),r=new Set(n.map(s=>s.vtime)),i=[];for(const s of t)r.has(s.vtime)||i.push({viseme:s.viseme,vtime:s.vtime});return i}function Js(e){return wn(e).map(t=>t.viseme)}const Zs=32,Ir=48;function Ii(e){let t=0;for(const n of e)t=Math.max(t,n.vtime+n.vduration);return t}function Ai(e){let t=null,n=-1;for(const r of e){if(r.viseme==="sil")continue;const i=r.vtime+r.vduration;i>n&&(t=r,n=i)}return t}function ea(e){return gn(e).find(n=>n.viseme!=="sil")??null}function lt(e){const t=Ii(e);return Ai(e)?t+jn:t}function ta(e){const t=[],n=ea(e);n&&n.vtime>0&&t.push({from:"sil",to:n.viseme,fromVtime:0,toVtime:n.vtime});const r=Ai(e),i=Ii(e);return r&&t.push({from:r.viseme,to:"sil",fromVtime:i,toVtime:i+jn}),t}function Mi(e){const t=gn(e),n=[];for(let r=0;r<t.length-1;r++){const i=t[r].viseme,s=t[r+1].viseme,o=t[r].vtime,a=t[r+1].vtime;i===s||a<=o||n.push({from:i,to:s,fromVtime:o,toVtime:a})}return n}function Pi(e){return e.length===0?[]:[...ta(e),...Mi(e)]}function na(e,t){let n=null;for(const r of e){const{transStart:i,transEnd:s}=Ci(r.fromVtime,r.toVtime,r.from,r.to);t>=i&&t<s&&(n=r)}return n}function Ci(e,t,n,r){const i=Math.max(0,t-e);if((n==="PP"||r==="PP")&&i>Ir){const d=Ir,l=t,c=l-d;return{gapMs:i,effectiveGapMs:d,holdEnd:c,transStart:c,transEnd:l}}const o=i>0?Math.max(i,Zs):0,a=e,u=e+o;return{gapMs:i,effectiveGapMs:o,holdEnd:e,transStart:a,transEnd:u}}function Ri(e,t,n,r,i,s){r.forEach(o=>{const u=String(o.word??"").trim();if(!u)return;const d=Math.round((o.start??0)*1e3),l=o.duration!=null?Math.round(o.duration*1e3):o.end!=null?Math.max(1,Math.round((o.end-(o.start??0))*1e3)):0;t.push({word:u,wtime:i+d,wduration:l,queueIndex:t.length,gesture:o.gesture??null,emphasis:o.emphasis===!0})}),n.forEach(o=>{const a=String(o.symbol??o.viseme??"").trim();if(!a)return;const u=Math.round((o.start??0)*1e3),d=Math.max(1,Math.round((o.duration??0)*1e3)),l=i+u,c=Fi(t,l),m=c?_i(c,l):0;let w;ai(s)==="oculus_direct"?(w=mn(a),w==="U"&&c&&hn(c.word,m)&&(w="FF")):w=bi(a,c?.word??"",m),e.push({viseme:w,weight:1,vtime:l,vduration:d})})}function Di(e,t){let n=t;for(const r of e){const i=Math.round((r.start??0)*1e3),s=Math.max(1,Math.round((r.duration??0)*1e3));n=Math.max(n,t+i+s)}return n}const Zn=16e3;function Bi(e){const t=Number(e);return Number.isFinite(t)&&t>0?t:Zn}function ra(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}function ia(e){return e.length>=4&&e[0]===82&&e[1]===73&&e[2]===70&&e[3]===70}function Ar(e,t,n=Zn){const r=t.byteOffset%2===0?t:t.slice(),i=new Int16Array(r.buffer,r.byteOffset,r.byteLength/2),s=new Float32Array(i.length);for(let a=0;a<i.length;a++)s[a]=i[a]>=32768?-(65536-i[a])/32768:i[a]/32767;const o=e.createBuffer(1,s.length,n);return o.copyToChannel(s,0),o}function sa(e){const t=ra(e),n=window.atob(t),r=new Uint8Array(n.length);for(let i=0;i<n.length;i++)r[i]=n.charCodeAt(i);return r}async function Mr(e,t,n=Zn){const r=sa(t),i=Bi(n);if(ia(r)){const s=r.buffer.slice(r.byteOffset,r.byteOffset+r.byteLength);return e.decodeAudioData(s)}if(r.length>=2&&r.length%2===0)return Ar(e,r,i);try{const s=r.buffer.slice(r.byteOffset,r.byteOffset+r.byteLength);return await e.decodeAudioData(s)}catch{return Ar(e,r,i)}}function Fi(e,t){for(const n of e)if(t>=n.wtime&&t<n.wtime+n.wduration)return n;return null}function Li(e,t){const n=[],r=[];let i=null,s=!1,o=!1,a=!1,u=!1,d=0,l=0,c=0,m=null,w=1,T=t,f=!1,E=null,D=0,B=!1,v=!1,k=0,L=null,A=null,ie=null;const de=()=>({visemes:[],words:[],segmentOffsetMs:0}),I=()=>{v=!1,k=0},V=()=>{m!=null&&(clearTimeout(m),m=null)},G=()=>{for(const b of r){try{b.onended=null,b.stop(0)}catch{}try{b.disconnect()}catch{}}r.length=0},ae=()=>{for(const b of r)b.playbackRate.value=w},se=()=>{if(!(f||!u||s||v||r.length>0||n.length>0)){if(a&&i&&l>0){const b=(i.currentTime-l)*1e3;if(b<D){V();const P=w>0?(D-b)/w:D-b;m=setTimeout(()=>{f||(o=!1,m=null,e.onSpeakingDone(),e.onNotify())},Math.max(0,P));return}}o=!1,V(),e.onSpeakingDone(),e.onNotify()}},re=b=>{const P=lt(b);if(P<=0){e.onSpeakingDone(),e.onNotify();return}o=!0,d=performance.now(),e.onSpeakingStart(),e.onNotify(),V();const H=w>0?P/w:P;m=setTimeout(()=>{f||(o=!1,m=null,e.onSpeakingDone(),e.onNotify())},H)},O=(b,P,H,le)=>{P.length!==0&&(c=H,P.forEach(j=>{const p=String(j.word??"").trim();if(!p)return;const S=Math.round((j.start??0)*1e3),x=j.duration!=null?Math.round(j.duration*1e3):j.end!=null?Math.max(1,Math.round((j.end-(j.start??0))*1e3)):0;b.push({word:p,wtime:c+S,wduration:x,queueIndex:b.length,gesture:j.gesture??null,emphasis:j.emphasis===!0})}))},J=(b,P,H,le,j,q)=>{H.length!==0&&(c=le,H.forEach(p=>{const S=String(p.symbol??p.viseme??"").trim();if(!S)return;const x=Math.round((p.start??0)*1e3),_=Math.max(1,Math.round((p.duration??0)*1e3)),U=c+x,Z=Fi(P,U),te=Z?_i(Z,U):0;let z;ai(q)==="oculus_direct"?(z=mn(S),z==="U"&&Z&&hn(Z.word,te)&&(z="FF")):z=bi(S,Z?.word??"",te),b.push({viseme:z,weight:1,vtime:U,vduration:_})}),e.onNotify())},W=(b,P,H,le,j,q,p)=>{O(P,le,j),J(b,P,H,j,q,p)},he=(b,P,H)=>{ie===b&&b.visemes===P||(P.length=0,H.length=0,b.visemes=P,b.words=H,b.segmentOffsetMs=0,ie=b,c=0,D=0)},K=async()=>{const b=window.AudioContext||window.webkitAudioContext;return i||(i=new b),i.state==="suspended"&&await i.resume(),E||(E=i.createMediaStreamDestination()),i},ee=(b,P)=>{if(!i)return 0;const H=i,le=H.currentTime,j=le+.02;if(P.isFirstAudio){l<=0&&(l=j);const p=(j-le)*1e3;d=performance.now()+p}P.onBeforeStart?.(j);const q=H.createBufferSource();return q.buffer=b,q.playbackRate.value=w,q.connect(H.destination),E&&q.connect(E),r.push(q),f?(r.pop(),j):(P.isFirstAudio&&(o=!0,e.onSpeakingStart()),q.onended=()=>{const p=r.indexOf(q);p>=0&&r.splice(p,1),e.onNotify(),!f&&(L&&A?$(L,A):se())},q.start(j),j)},$=async(b,P)=>{if(f||s||r.length>0)return;if(n.length===0){se();return}s=!0;let H=!1;try{const le=await K();if(f)return;const j=n[0];if(!j)return;const q=!o;if(B&&(e.shouldHoldForWarmup?.()??!1)&&(v||q&&j.newStream)||v){he(j.utterance,b,P);for(const x of n){if(f)return;x.audioBuffer||(x.audioBuffer=await Mr(le,x.audio,x.sampleRate)),a=!0,v||(v=!0,k=0,x.newStream&&x.onNewStream?.()),x.visemesQueued||(W(b,P,x.visemes,x.words,k,!0,T),x.visemesQueued=!0,k+=Math.round(x.audioBuffer.duration*1e3),D=Math.max(D,lt(b)))}e.onNotify();return}const S=n.shift();if(!S||(S.audioBuffer||(S.audioBuffer=await Mr(le,S.audio,S.sampleRate)),f))return;a=!0,V(),he(S.utterance,b,P),S.visemesQueued=!1,S.newStream&&S.onNewStream?.(),ee(S.audioBuffer,{isFirstAudio:!o,isFirstOfStream:!1,onBeforeStart:x=>{l=x,c=0,d=performance.now()+(x-le.currentTime)*1e3,b.length=0,P.length=0,W(b,P,S.visemes,S.words,0,!0,T),S.visemesQueued=!0,S.utterance.segmentOffsetMs=0}}),H=r.length>0,D=lt(b),e.onNotify()}catch(le){console.error("[avatarChunkPlayback] audio chunk failed:",le)}finally{if(s=!1,f)return;if(v){n.some(j=>!j.audioBuffer||!j.visemesQueued)&&$(b,P);return}!H&&r.length===0&&n.length>0?$(b,P):r.length===0&&n.length===0&&se()}};return{setStreamTtsEngineId:b=>{T=b},setPlaybackSpeed:b=>{w=Math.max(.1,Math.min(1,b)),ae()},getPlaybackSpeed:()=>w,setLipsyncWarmupHoldEnabled:b=>{B=b,b||I()},isWarmingUp:()=>v,releaseWarmupHold:()=>{if(v){v=!1,k=0;for(const b of n)b.newStream=!1;L&&A&&$(L,A),e.onNotify()}},resetForNewStream:b=>{f=!1,u=!1,T=b,D=0},resumeBotStream:()=>{f=!1,u=!1},clearAborted:()=>{f=!1},primeAudioContext:async()=>{const b=window.AudioContext||window.webkitAudioContext;i||(i=new b),i.state==="suspended"&&await i.resume(),i&&!E&&(E=i.createMediaStreamDestination())},stop:()=>{f=!0,V(),G(),n.length=0,s=!1,o=!1,a=!1,u=!1,c=0,l=0,d=0,D=0,L=null,A=null,ie=null,I()},markStreamComplete:b=>{if(D=Math.max(D,lt(b)),u=!0,!a&&b.length>0){re(b);return}se()},playAudioChunk:async(b,P,H,le,j,q,p)=>{if(f)return;L=b,A=P;const S=Bi(p?.sampleRate),x=p?.newStream===!0,_=de();if(!H?.trim()){if(le.length===0&&j.length===0)return;he(_,b,P),x&&p?.onNewStream?.(),W(b,P,le,j,0,!0,T),D=lt(b),!o&&D>0&&re(b),e.onNotify();return}n.push({audio:H,audioBuffer:null,utterance:_,visemes:le,words:j,isNewSegment:q,sampleRate:S,newStream:x,onNewStream:p?.onNewStream,visemesQueued:!1}),await $(b,P)},queueTimingsOnly:(b,P,H,le,j,q)=>{if(f)return;const p=de();he(p,b,P),W(b,P,H,le,0,!0,T),p.segmentOffsetMs=0,D=lt(b)},getPlaybackElapsedMs:()=>a&&i&&l>0?Math.max(0,(i.currentTime-l)*1e3*w):o?Math.max(0,(performance.now()-d)*w):0,isSpeaking:()=>o?!0:!a||!i||l<=0?!1:(i.currentTime-l)*1e3<D,getVoiceStream:()=>E?E.stream:null,getPlaybackStartPerf:()=>d,bargeIn:()=>{f=!0,u=!1,V(),G(),n.length=0,s=!1,o=!1,a=!1,c=0,l=0,d=0,D=0,L=null,A=null,ie=null,I()},interrupt:()=>{f=!0,u=!1,V(),G(),n.length=0,s=!1,o=!1,a=!1,c=0,l=0,d=0,D=0,L=null,A=null,ie=null,I()}}}function zt(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 Oi(e,t,n=120){const r=zt(e,t);if(r!=="sil")return r;let i=null;for(const s of e){if(s.vtime>t)break;const o=s.vtime+s.vduration;o<=t&&t-o<=n&&(i=s)}return i?.viseme??"sil"}function aa(e,t,n=400){const r=t-n;let i=0;for(const s of e)if(s.vtime+s.vduration<r)i+=1;else break;i>0&&e.splice(0,i)}function oa(e,t){for(const n of e)if(t>=n.wtime&&t<n.wtime+n.wduration)return n;return null}function Pr(e,t){const n=e.trim();if(!n)return null;try{const r=n.replace(/\s+/g,""),i=atob(r).length,s=Number.isFinite(t)&&(t??0)>0?Number(t):16e3;return i/2/s*1e3}catch{return null}}const pn=.5,yn=1.5,er="Olivia",tr="f786b574-daa5-4673-aa0c-cbe3e8534c02",Ht=.85;function Nn(e,t=ht,n={}){const r=`${t.replace(/\/$/,"")}/avatar_ttsWithPoses`,i=[],s=[],o=[],a=[];let u=0;const d=[],l=[];let c="",m="neutral",w="",T=dt;const f=new Set;let E=0,D=null,B=0,v=null;const k=()=>f.forEach(O=>O());let L=()=>!1;const A=Li({onSpeakingStart:()=>e("speaking"),onSpeakingDone:()=>e("done"),onNotify:k,shouldHoldForWarmup:()=>L()},dt),ie=()=>A.getPlaybackElapsedMs(),de=(O,J=c)=>{if(!n.onLipsyncDebug)return;const W=ie(),he=i,K=wn(o).map(ee=>({viseme:ee.viseme,vtimeMs:ee.vtime}));n.onLipsyncDebug({event:O,spokenText:J,mood:m,playbackAnchorPerf:A.getPlaybackStartPerf(),playbackElapsedMs:W,queueLength:he.length,activeViseme:zt(he,W),segments:l.map(ee=>({...ee,visemes:[...ee.visemes]})),fullQueueLength:o.length,compactionSkipped:K})},I=(O,J)=>{n.onLipsyncDebug&&(D={event:O,spokenText:J},E===0&&(E=requestAnimationFrame(()=>{E=0;const W=D;D=null,W&&de(W.event,W.spokenText)})))},V=(O,J,W,he,K)=>{if(!n.onLipsyncDebug)return;const ee=i.slice(J),$=W.filter(X=>String(X.symbol??X.viseme??"").trim());l.push({spokenText:O,audioOffsetMs:ee[0]?.vtime??0,isNewSegment:he,chunkDurationMs:K,receivedAtMs:performance.now(),visemes:ee.map((X,_e)=>{const oe=$[_e];return{rawSymbol:String(oe?.symbol??oe?.viseme??X.viseme).trim(),viseme:X.viseme,startSec:Number(oe?.start??0),durationSec:Number(oe?.duration??0),vtimeMs:X.vtime,vdurationMs:X.vduration}})})},G=()=>{o.length=0,a.length=0,u=0},ae=(O,J,W,he,K)=>{if(O.length===0&&J.length===0)return;Ri(o,a,O,J,u,K);const ee=Di(O,u),$=W?Pr(W,he):null;u=Math.max(ee,$!=null?u+$:u)},se=()=>{B+=1,v?.abort(),v=null,A.stop(),i.length=0,s.length=0,G(),d.length=0,m="neutral",l.length=0,c="",e("idle"),I("reset"),k()};return{setDeveloperToken:O=>{w=O},setTtsEngineId:O=>{T=O},getTtsEngineId:()=>T,speak:async(O,J)=>{se();const W=B;v=new AbortController,e("loading"),c=O,l.length=0,G();const he=w.trim();if(!he)throw new Error("Developer token required for avatar_ttsWithPoses");const K=et(J?.ttsEngineId,J?.voiceId),ee=K.ttsEngineId??T??dt;A.resetForNewStream(ee),A.setStreamTtsEngineId(ee);const $=K.voiceId??(ee===nt?dn:er),X=J?.speakingRate??Ht,_e=Math.max(pn,Math.min(yn,X)),oe={user_query:O,ttsEngineId:ee,speakingRate:_e,tenant:"aiTwin"};ii.has(ee)&&(oe.voice_id=$);const b=fn(J?.language);b&&(oe.language=b);try{const P=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${he}`},body:JSON.stringify(oe),signal:v.signal});if(!P.ok)throw new Error(`avatar_ttsWithPoses failed (${P.status})`);const H=P.body;if(!H)throw new Error("No response body");const le=H.getReader(),j=new TextDecoder;let q="",p=!0;const S=async x=>{if(W!==B)return;const _=yi(x);if(_){if(_.event==="audio"){const U=_.data.chunk,Z=_.data.visemes??[],te=_.data.words??[],z=_.data.is_new_segment??!1,be=_.data.sample_rate,Xe=Number(_.data.audio_offset_ms??0),Pt=i.length;if(ae(Z,te,U,be,ee),U){const pt=p;p=!1,await A.playAudioChunk(i,s,U,Z,te,z,{sampleRate:be,newStream:pt,audioOffsetMs:Xe}),V(O,Pt,Z,z,Pr(U,be)),I("audio_chunk",O)}else(Z.length>0||te.length>0)&&(A.queueTimingsOnly(i,s,Z,te,z,{audioOffsetMs:Xe,newStream:p}),V(O,Pt,Z,z,null),I("audio_chunk",O))}else if(_.event==="metadata"){const U=_.data.mood;typeof U=="string"&&U.trim()&&(m=U.trim());const Z=_.data.sentence_emotions;if(Array.isArray(Z)){d.length=0;for(const te of Z){if(!te||typeof te!="object")continue;const z=te;d.push({sentence_index:Number(z.sentence_index??0),text:String(z.text??""),sentiment:typeof z.sentiment=="string"?z.sentiment:void 0,emotion:String(z.emotion??m),start_word:Number(z.start_word??0),end_word:Number(z.end_word??0)})}}k(),I("metadata",O)}else if(_.event==="error")throw new Error(String(_.data.message??"avatar_ttsWithPoses stream error"))}};for(;W===B;){const{done:x,value:_}=await le.read();_&&(q+=j.decode(_,{stream:!0}));const U=q.split(`
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const R=require("react/jsx-runtime"),h=require("react"),ds=require("@pipecat-ai/client-js"),Hn=require("@pipecat-ai/websocket-transport"),we=require("pixi.js");var xn=typeof document<"u"?document.currentScript:null;const fs="https://aitwin.bubu.social",ii={publicBase:fs},ms="0.6.7",hs={version:ms},gs={},gt="https://ai.aitwin.me",$n=`${ii.publicBase}/custom-faces`,ws=`${ii.publicBase}/aitwin-workers/v${hs.version}/visemeDiffPreview.worker.js`;function ps(e){if(e)return e;const t=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:xn&&xn.tagName.toUpperCase()==="SCRIPT"&&xn.src||new URL("aitwin.cjs",document.baseURI).href}<"u"?gs?.VITE_AITWIN_WORKER_URL:void 0;return t?.trim()?t.trim():ws}const ys="https://us-central1-streamoji-265f4.cloudfunctions.net/getAiTwin",In=3e3,Ot=16,xr=3e3,vs=4e3,_s=.85,bs=8,jn=400,Kn="eng_a7f2b9c1",un="eng_d4e8f3a2",tt="eng_c9b1e6d4",nt="visemetts",ft=tt,dn="eve",si=new Set([un,tt,nt]),Gn={[Kn]:"oculus_direct",[tt]:"oculus_direct",[nt]:"oculus_direct",[un]:"inworld_word"},Dn={google:Kn,inworld:un,cartesia:tt,visemetts:nt};function Ss(e){const t=e.trim();if(t)return t in Gn?t:Dn[t.toLowerCase()]}function ai(e){const t=e?.trim();if(!t)return{};const n=t.indexOf(":");if(n<=0)return{voiceId:t};const r=Ss(t.slice(0,n));if(!r)return{voiceId:t};const i=t.slice(n+1).trim();return{ttsEngineId:r,voiceId:i||void 0}}function et(e,t){const n=ai(t);return{ttsEngineId:e??n.ttsEngineId,voiceId:n.voiceId}}function oi(e){return Gn[e]}function Ts(e){return e===tt}function ci(e){return e===nt}function ks(e){if(e.ttsEngineId&&e.ttsEngineId in Gn)return e.ttsEngineId;const t=e.tts?.toLowerCase();return t&&t in Dn?Dn[t]:ft}class nn extends Error{constructor(t="AI twin not found"){super(t),this.name="AiTwinNotFoundError"}}function qn(e,...t){const n=typeof e=="string"?e:e?.brainId?.trim()||e?.knowledgeContextId?.trim();for(const r of[n,...t]){const i=r?.trim();if(i)return i}}function Yn(e,...t){const n=typeof e=="string"?e:e?.brainUrl?.trim();for(const r of[n,...t]){const i=r?.trim();if(i)return i}}function Es(e){const t=(e??"").trim();if(!t)return;let n;try{n=new URL(t)}catch{throw new Error("brainUrl must be an http or https URL")}if(n.protocol!=="http:"&&n.protocol!=="https:")throw new Error("brainUrl must be an http or https URL");if(!n.host)throw new Error("brainUrl must be an http or https URL");if(n.hash)throw new Error("brainUrl must not include a fragment");return t}async function li(e,t=ys){const n=new URL(t);n.searchParams.set("id",e);const r=await fetch(n.toString());if(r.status===404)throw new nn;if(!r.ok)throw new Error(`getAiTwin failed (${r.status})`);const i=await r.json();if(!i.success)throw new nn(i.error??"AI twin not found");const{tts:s,token:o,...a}=i.data,u=String(a.authToken??o??"").trim()||void 0,d=qn(a),l=Yn(a);return{...a,ttsEngineId:ks(i.data),authToken:u,brainId:d,knowledgeContextId:d,brainUrl:l}}const Qn="thumbnail.webp";function ui(e,t=$n){const n=e.trim();if(!n)throw new Error("faceId is required");return`${t.replace(/\/$/,"")}/${n}/${Qn}`}function Ir(e){const t=e?.trim();if(!t)return null;try{return ui(t)}catch{return null}}function xs(e){if(!e)return null;const t=(e.binBase||e.twinBase).trim().replace(/\/$/,"");return t?`${t}/${Qn}`:null}const Is="https://us-central1-streamoji-265f4.cloudfunctions.net/getAuthToken",As="client_6TNvp3SCs4Og0a1ijm9TommXLql1",Ms="kk8Fq8EmexzP10jMIEwY3R44M5RKUEm1",Ps="6TNvp3SCs4Og0a1ijm9TommXLql1",Rs="Swaraj Mali";async function Nt(){const e=await fetch(Is,{method:"POST",headers:{"Content-Type":"application/json","Client-Id":As,"Client-Secret":Ms},body:JSON.stringify({userId:Ps,userName:Rs})});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 Cs(e,t=gt){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 Ds(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 Xt(e){return Uint8Array.from(e)}function Bs(e,t){const n=new Uint8Array(e.length+t.length);return n.set(e,0),n.set(t,e.length),n}async function Fs(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=Xt(n.subarray(0,12)),i=Xt(n.subarray(12,28)),s=Xt(n.subarray(28)),o=Xt(Bs(s,i)),a=await crypto.subtle.importKey("raw",Ds(t),{name:"AES-GCM"},!1,["decrypt"]);return crypto.subtle.decrypt({name:"AES-GCM",iv:r,tagLength:128},a,o)}let Bn=null;const Fn=new Set;function Jt(e){return e.includes("/custom-faces/")}function rn(e){const t=e.binBase.trim().replace(/\/$/,""),n=e.twinBase.trim().replace(/\/$/,"");if(!(e.encrypted||Jt(t)||Jt(n)))return{twinBase:n,binBase:t,encrypted:!1};const i=Jt(t)?t:Jt(n)?n:t;return{twinBase:i,binBase:i,encrypted:!0}}function wt(e){return rn(e).encrypted}function Ln(e,t=$n){const n=`${t.replace(/\/$/,"")}/${e}`;return{twinBase:n,binBase:n,encrypted:!0}}function di(e,t){return(e??t)?.trim()||void 0}function fi(e){Bn=rn(e);for(const t of Fn)t()}function Ls(e,t){const n=typeof globalThis.location<"u"?globalThis.location.href:void 0;if(!n)return rn(e);const r=i=>{try{return new URL(i,n).href.replace(/\/$/,"")}catch{return i}};return rn({twinBase:r(e.twinBase),binBase:r(e.binBase),encrypted:e.encrypted})}function pt(){if(!Bn)throw new Error("Twin assets not configured; call setActiveTwinAssets first");return Bn}function mi(e){return Fn.add(e),()=>Fn.delete(e)}function sn(){const e=pt();return wt(e)?`${e.binBase}/sil.bin`:`${e.twinBase}/sil.png`}function Os(){const e=pt();return wt(e)?`${e.binBase}/idle.bin`:`${e.twinBase}/idle.mp4`}function hi(){const e=pt();return wt(e)?e.binBase:e.twinBase}function Wt(){return wt(pt())}function gi(){const e=pt();return wt(e)?`${e.binBase}/atlas.bin`:`${e.twinBase}/atlas.json`}function wi(){const e=pt();return wt(e)?`${e.binBase}/expression_atlas.bin`:`${e.twinBase}/expression_atlas.json`}const mt=[{code:"en",label:"English",visemetts:!0,cartesia:!0},{code:"es",label:"Spanish",visemetts:!0,cartesia:!0},{code:"es-MX",label:"Spanish (Mexico)",visemetts:!0,cartesia:!0},{code:"es-ES",label:"Spanish (Spain)",visemetts:!0,cartesia:!0},{code:"pt",label:"Portuguese",visemetts:!0,cartesia:!0},{code:"pt-BR",label:"Portuguese (Brazil)",visemetts:!0,cartesia:!0},{code:"pt-PT",label:"Portuguese (Portugal)",visemetts:!0,cartesia:!0},{code:"fr",label:"French",visemetts:!0,cartesia:!0},{code:"de",label:"German",visemetts:!0,cartesia:!0},{code:"it",label:"Italian",visemetts:!0,cartesia:!0},{code:"zh",label:"Chinese",visemetts:!0,cartesia:!0},{code:"ja",label:"Japanese",visemetts:!0,cartesia:!0},{code:"hi",label:"Hindi",visemetts:!0,cartesia:!0},{code:"ko",label:"Korean",visemetts:!0,cartesia:!0},{code:"ru",label:"Russian",visemetts:!0,cartesia:!0},{code:"tr",label:"Turkish",visemetts:!0,cartesia:!0},{code:"id",label:"Indonesian",visemetts:!0,cartesia:!0},{code:"ar",label:"Arabic",visemetts:!0,cartesia:!0},{code:"ar-EG",label:"Arabic (Egypt)",visemetts:!0,cartesia:!0},{code:"ar-AE",label:"Arabic (UAE)",visemetts:!0,cartesia:!0},{code:"vi",label:"Vietnamese",visemetts:!0,cartesia:!0},{code:"bn",label:"Bengali",visemetts:!0,cartesia:!0},{code:"auto",label:"Auto-detect",visemetts:!0,cartesia:!1},{code:"nl",label:"Dutch",visemetts:!1,cartesia:!0},{code:"pl",label:"Polish",visemetts:!1,cartesia:!0},{code:"sv",label:"Swedish",visemetts:!1,cartesia:!0},{code:"tl",label:"Tagalog",visemetts:!1,cartesia:!0},{code:"bg",label:"Bulgarian",visemetts:!1,cartesia:!0},{code:"ro",label:"Romanian",visemetts:!1,cartesia:!0},{code:"cs",label:"Czech",visemetts:!1,cartesia:!0},{code:"el",label:"Greek",visemetts:!1,cartesia:!0},{code:"fi",label:"Finnish",visemetts:!1,cartesia:!0},{code:"hr",label:"Croatian",visemetts:!1,cartesia:!0},{code:"ms",label:"Malay",visemetts:!1,cartesia:!0},{code:"sk",label:"Slovak",visemetts:!1,cartesia:!0},{code:"da",label:"Danish",visemetts:!1,cartesia:!0},{code:"ta",label:"Tamil",visemetts:!1,cartesia:!0},{code:"uk",label:"Ukrainian",visemetts:!1,cartesia:!0},{code:"hu",label:"Hungarian",visemetts:!1,cartesia:!0},{code:"no",label:"Norwegian",visemetts:!1,cartesia:!0},{code:"th",label:"Thai",visemetts:!1,cartesia:!0},{code:"he",label:"Hebrew",visemetts:!1,cartesia:!0},{code:"ka",label:"Georgian",visemetts:!1,cartesia:!0},{code:"te",label:"Telugu",visemetts:!1,cartesia:!0},{code:"gu",label:"Gujarati",visemetts:!1,cartesia:!0},{code:"kn",label:"Kannada",visemetts:!1,cartesia:!0},{code:"ml",label:"Malayalam",visemetts:!1,cartesia:!0},{code:"mr",label:"Marathi",visemetts:!1,cartesia:!0},{code:"pa",label:"Punjabi",visemetts:!1,cartesia:!0}],pi=mt.map(e=>e.code),Ns=new Set(pi),Us=new Set(mt.filter(e=>e.visemetts).map(e=>e.code)),Vs=new Set(mt.filter(e=>e.cartesia).map(e=>e.code)),Ws="en";function yi(e){return Ns.has(e)}function fn(e){const t=e?.trim();if(t)return t}function zs(e){return e===nt?mt.filter(t=>t.visemetts).map(t=>t.code):e===tt?mt.filter(t=>t.cartesia).map(t=>t.code):mt.filter(t=>t.visemetts&&t.cartesia).map(t=>t.code)}function Hs(e,t){const n=t.trim();return n?e===nt?Us.has(n):e===tt?Vs.has(n):yi(n):!1}function vi(e){const t=e.split(/\r?\n/);let n="",r="";for(const s of t)s.startsWith("event:")?n=s.slice(6).trim():s.startsWith("data:")&&(r=s.slice(5).trim());if(!n)return null;let i={};if(r)try{i=JSON.parse(r)}catch{i={raw:r}}return{event:n,data:i}}const _i=["aa","CH","DD","E","FF","I","O","PP","RR","SS","TH","U","kk","nn","sil"],$s=new Map(_i.map(e=>[e.toLowerCase(),e]));function mn(e){const t=(e??"").trim();return t?$s.get(t.toLowerCase())??"sil":"sil"}const js={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 Ks(e){if(!e)return["sil"];const t=e.toLowerCase();return js[t]??["sil"]}function bi(e,t){const n=e.word.length;if(n<=0)return 0;const r=e.wduration;if(r<=0)return 0;const i=Math.max(0,Math.min(1,(t-e.wtime)/r));return Math.min(n-1,Math.floor(i*n))}function xt(e,t){const n=Math.max(0,Math.min(e.length-1,t));return e[n]??""}function hn(e,t){const n=e.toLowerCase().replace(/[^a-z']/g,"");return!n||xt(n,t)!=="w"||t>0&&xt(n,t-1)==="q"?!1:t===0&&/^w[aeiouy]/.test(n)}function Gs(e,t){const n=e.toLowerCase(),r=xt(n,t),i=n.slice(Math.max(0,t-1),t+2);return r==="i"||r==="y"?"I":i.includes("ee")||r==="e"||n.includes("ea")?"E":"aa"}function qs(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";if(hn(n,t))return"FF";const i=xt(n,t);return i==="u"||i==="w"?"U":"O"}function Ys(e,t){const n=e.toLowerCase();if(hn(n,t))return"FF";const r=n.slice(Math.max(0,t-2),t+1);if(/qu/.test(r))return"U";const i=n.slice(Math.max(0,t-1),Math.min(n.length,t+3));return/wo|wh/.test(i)||xt(n,t)==="o"?"O":"U"}const Zt={d:"DD",t:"DD",n:"DD",s:"SS",z:"SS",k:"kk",g:"kk",c:"CH",x:"CH",j:"CH"};function Qs(e,t){const n=e.toLowerCase(),r=xt(n,t);if(Zt[r])return Zt[r];for(let i=0;i<n.length;i++){const s=n[i];if(Zt[s])return Zt[s]}return"DD"}function Si(e,t,n){const r=Ks(e);if(r.length===1)return r[0];const i=t.trim();if(!i)return r[0];const s=(e??"").toLowerCase(),o=Math.max(0,n);switch(s){case"aei":return Gs(i,o);case"o":return qs(i,o);case"qw":return Ys(i,o);case"cdgknstxyz":return Qs(i,o);default:return r[0]}}const Xn=16,On=47,Ti=new Set(["aa","E","I"]),ki=new Set(["DD","SS","kk","CH"]),Xs=[Ti,ki];function Js(e){for(const t of Xs)if(t.has(e))return t;return null}function Zs(e){return Js(e)!=null}function Ei(e,t=Xn){return t<=0?e:Math.round(e/t)*t}function Jn(e,t=Xn){return e.map(n=>({...n,vtime:Ei(n.vtime,t)}))}function xi(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 Zn(e){if(e.length<=2)return[...e];const t=[e[0]];for(let n=1;n<e.length-1;n++){const r=e[n],i=e[n+1],s=t[t.length-1];if(!Zs(r.viseme)){t.push(r);continue}const o=r.vtime-s.vtime,a=i.vtime-r.vtime;o<On||a<On||t.push(r)}return t.push(e[e.length-1]),t}function gn(e){return Zn(xi(Jn(e)))}function Ii(e,t){let n="sil";for(const r of e){if(r.vtime>t)break;r.viseme!=="sil"&&(n=r.viseme)}return n}function wn(e){const t=xi(Jn(e)),n=Zn(t),r=new Set(n.map(s=>s.vtime)),i=[];for(const s of t)r.has(s.vtime)||i.push({viseme:s.viseme,vtime:s.vtime});return i}function ea(e){return wn(e).map(t=>t.viseme)}const ta=32,Ar=48;function Ai(e){let t=0;for(const n of e)t=Math.max(t,n.vtime+n.vduration);return t}function Mi(e){let t=null,n=-1;for(const r of e){if(r.viseme==="sil")continue;const i=r.vtime+r.vduration;i>n&&(t=r,n=i)}return t}function na(e){return gn(e).find(n=>n.viseme!=="sil")??null}function ut(e){const t=Ai(e);return Mi(e)?t+jn:t}function ra(e){const t=[],n=na(e);n&&n.vtime>0&&t.push({from:"sil",to:n.viseme,fromVtime:0,toVtime:n.vtime});const r=Mi(e),i=Ai(e);return r&&t.push({from:r.viseme,to:"sil",fromVtime:i,toVtime:i+jn}),t}function Pi(e){const t=gn(e),n=[];for(let r=0;r<t.length-1;r++){const i=t[r].viseme,s=t[r+1].viseme,o=t[r].vtime,a=t[r+1].vtime;i===s||a<=o||n.push({from:i,to:s,fromVtime:o,toVtime:a})}return n}function Ri(e){return e.length===0?[]:[...ra(e),...Pi(e)]}function ia(e,t){let n=null;for(const r of e){const{transStart:i,transEnd:s}=Ci(r.fromVtime,r.toVtime,r.from,r.to);t>=i&&t<s&&(n=r)}return n}function Ci(e,t,n,r){const i=Math.max(0,t-e);if((n==="PP"||r==="PP")&&i>Ar){const d=Ar,l=t,c=l-d;return{gapMs:i,effectiveGapMs:d,holdEnd:c,transStart:c,transEnd:l}}const o=i>0?Math.max(i,ta):0,a=e,u=e+o;return{gapMs:i,effectiveGapMs:o,holdEnd:e,transStart:a,transEnd:u}}function Di(e,t,n,r,i,s){r.forEach(o=>{const u=String(o.word??"").trim();if(!u)return;const d=Math.round((o.start??0)*1e3),l=o.duration!=null?Math.round(o.duration*1e3):o.end!=null?Math.max(1,Math.round((o.end-(o.start??0))*1e3)):0;t.push({word:u,wtime:i+d,wduration:l,queueIndex:t.length,gesture:o.gesture??null,emphasis:o.emphasis===!0})}),n.forEach(o=>{const a=String(o.symbol??o.viseme??"").trim();if(!a)return;const u=Math.round((o.start??0)*1e3),d=Math.max(1,Math.round((o.duration??0)*1e3)),l=i+u,c=Li(t,l),m=c?bi(c,l):0;let w;oi(s)==="oculus_direct"?(w=mn(a),w==="U"&&c&&hn(c.word,m)&&(w="FF")):w=Si(a,c?.word??"",m),e.push({viseme:w,weight:1,vtime:l,vduration:d})})}function Bi(e,t){let n=t;for(const r of e){const i=Math.round((r.start??0)*1e3),s=Math.max(1,Math.round((r.duration??0)*1e3));n=Math.max(n,t+i+s)}return n}const er=16e3;function Fi(e){const t=Number(e);return Number.isFinite(t)&&t>0?t:er}function sa(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}function aa(e){return e.length>=4&&e[0]===82&&e[1]===73&&e[2]===70&&e[3]===70}function Mr(e,t,n=er){const r=t.byteOffset%2===0?t:t.slice(),i=new Int16Array(r.buffer,r.byteOffset,r.byteLength/2),s=new Float32Array(i.length);for(let a=0;a<i.length;a++)s[a]=i[a]>=32768?-(65536-i[a])/32768:i[a]/32767;const o=e.createBuffer(1,s.length,n);return o.copyToChannel(s,0),o}function oa(e){const t=sa(e),n=window.atob(t),r=new Uint8Array(n.length);for(let i=0;i<n.length;i++)r[i]=n.charCodeAt(i);return r}async function Pr(e,t,n=er){const r=oa(t),i=Fi(n);if(aa(r)){const s=r.buffer.slice(r.byteOffset,r.byteOffset+r.byteLength);return e.decodeAudioData(s)}if(r.length>=2&&r.length%2===0)return Mr(e,r,i);try{const s=r.buffer.slice(r.byteOffset,r.byteOffset+r.byteLength);return await e.decodeAudioData(s)}catch{return Mr(e,r,i)}}function Li(e,t){for(const n of e)if(t>=n.wtime&&t<n.wtime+n.wduration)return n;return null}function Oi(e,t){const n=[],r=[];let i=null,s=!1,o=!1,a=!1,u=!1,d=0,l=0,c=0,m=null,w=1,S=t,f=!1,E=null,D=0,B=!1,v=!1,k=0,O=null,A=null,se=null;const le=()=>({visemes:[],words:[],segmentOffsetMs:0}),I=()=>{v=!1,k=0},U=()=>{m!=null&&(clearTimeout(m),m=null)},q=()=>{for(const _ of r){try{_.onended=null,_.stop(0)}catch{}try{_.disconnect()}catch{}}r.length=0},oe=()=>{for(const _ of r)_.playbackRate.value=w},ae=()=>{if(!(f||!u||s||v||r.length>0||n.length>0)){if(a&&i&&l>0){const _=(i.currentTime-l)*1e3;if(_<D){U();const C=w>0?(D-_)/w:D-_;m=setTimeout(()=>{f||(o=!1,m=null,e.onSpeakingDone(),e.onNotify())},Math.max(0,C));return}}o=!1,U(),e.onSpeakingDone(),e.onNotify()}},ie=_=>{const C=ut(_);if(C<=0){e.onSpeakingDone(),e.onNotify();return}o=!0,d=performance.now(),e.onSpeakingStart(),e.onNotify(),U();const $=w>0?C/w:C;m=setTimeout(()=>{f||(o=!1,m=null,e.onSpeakingDone(),e.onNotify())},$)},L=(_,C,$,re)=>{C.length!==0&&(c=$,C.forEach(K=>{const p=String(K.word??"").trim();if(!p)return;const b=Math.round((K.start??0)*1e3),x=K.duration!=null?Math.round(K.duration*1e3):K.end!=null?Math.max(1,Math.round((K.end-(K.start??0))*1e3)):0;_.push({word:p,wtime:c+b,wduration:x,queueIndex:_.length,gesture:K.gesture??null,emphasis:K.emphasis===!0})}))},Z=(_,C,$,re,K,Y)=>{$.length!==0&&(c=re,$.forEach(p=>{const b=String(p.symbol??p.viseme??"").trim();if(!b)return;const x=Math.round((p.start??0)*1e3),W=Math.max(1,Math.round((p.duration??0)*1e3)),ee=c+x,T=Li(C,ee),Q=T?bi(T,ee):0;let V;oi(Y)==="oculus_direct"?(V=mn(b),V==="U"&&T&&hn(T.word,Q)&&(V="FF")):V=Si(b,T?.word??"",Q),_.push({viseme:V,weight:1,vtime:ee,vduration:W})}),e.onNotify())},H=(_,C,$,re,K,Y,p)=>{L(C,re,K),Z(_,C,$,K,Y,p)},me=(_,C,$)=>{se===_&&_.visemes===C||(C.length=0,$.length=0,_.visemes=C,_.words=$,_.segmentOffsetMs=0,se=_,c=0,D=0)},z=async()=>{const _=window.AudioContext||window.webkitAudioContext;return i||(i=new _),i.state==="suspended"&&await i.resume(),E||(E=i.createMediaStreamDestination()),i},te=(_,C)=>{if(!i)return 0;const $=i,re=$.currentTime,K=re+.02;if(C.isFirstAudio){l<=0&&(l=K);const p=(K-re)*1e3;d=performance.now()+p}C.onBeforeStart?.(K);const Y=$.createBufferSource();return Y.buffer=_,Y.playbackRate.value=w,Y.connect($.destination),E&&Y.connect(E),r.push(Y),f?(r.pop(),K):(C.isFirstAudio&&(o=!0,e.onSpeakingStart()),Y.onended=()=>{const p=r.indexOf(Y);p>=0&&r.splice(p,1),e.onNotify(),!f&&(O&&A?j(O,A):ae())},Y.start(K),K)},j=async(_,C)=>{if(f||s||r.length>0)return;if(n.length===0){ae();return}s=!0;let $=!1;try{const re=await z();if(f)return;const K=n[0];if(!K)return;const Y=!o;if(B&&(e.shouldHoldForWarmup?.()??!1)&&(v||Y&&K.newStream)||v){me(K.utterance,_,C);for(const x of n){if(f)return;x.audioBuffer||(x.audioBuffer=await Pr(re,x.audio,x.sampleRate)),a=!0,v||(v=!0,k=0,x.newStream&&x.onNewStream?.()),x.visemesQueued||(H(_,C,x.visemes,x.words,k,!0,S),x.visemesQueued=!0,k+=Math.round(x.audioBuffer.duration*1e3),D=Math.max(D,ut(_)))}e.onNotify();return}const b=n.shift();if(!b||(b.audioBuffer||(b.audioBuffer=await Pr(re,b.audio,b.sampleRate)),f))return;a=!0,U(),me(b.utterance,_,C),b.visemesQueued=!1,b.newStream&&b.onNewStream?.(),te(b.audioBuffer,{isFirstAudio:!o,isFirstOfStream:!1,onBeforeStart:x=>{l=x,c=0,d=performance.now()+(x-re.currentTime)*1e3,_.length=0,C.length=0,H(_,C,b.visemes,b.words,0,!0,S),b.visemesQueued=!0,b.utterance.segmentOffsetMs=0}}),$=r.length>0,D=ut(_),e.onNotify()}catch(re){console.error("[avatarChunkPlayback] audio chunk failed:",re)}finally{if(s=!1,f)return;if(v){n.some(K=>!K.audioBuffer||!K.visemesQueued)&&j(_,C);return}!$&&r.length===0&&n.length>0?j(_,C):r.length===0&&n.length===0&&ae()}};return{setStreamTtsEngineId:_=>{S=_},setPlaybackSpeed:_=>{w=Math.max(.1,Math.min(1,_)),oe()},getPlaybackSpeed:()=>w,setLipsyncWarmupHoldEnabled:_=>{B=_,_||I()},isWarmingUp:()=>v,releaseWarmupHold:()=>{if(v){v=!1,k=0;for(const _ of n)_.newStream=!1;O&&A&&j(O,A),e.onNotify()}},resetForNewStream:_=>{f=!1,u=!1,S=_,D=0},resumeBotStream:()=>{f=!1,u=!1},clearAborted:()=>{f=!1},primeAudioContext:async()=>{const _=window.AudioContext||window.webkitAudioContext;i||(i=new _),i.state==="suspended"&&await i.resume(),i&&!E&&(E=i.createMediaStreamDestination())},stop:()=>{f=!0,U(),q(),n.length=0,s=!1,o=!1,a=!1,u=!1,c=0,l=0,d=0,D=0,O=null,A=null,se=null,I()},markStreamComplete:_=>{if(D=Math.max(D,ut(_)),u=!0,!a&&_.length>0){ie(_);return}ae()},playAudioChunk:async(_,C,$,re,K,Y,p)=>{if(f)return;O=_,A=C;const b=Fi(p?.sampleRate),x=p?.newStream===!0,W=le();if(!$?.trim()){if(re.length===0&&K.length===0)return;me(W,_,C),x&&p?.onNewStream?.(),H(_,C,re,K,0,!0,S),D=ut(_),!o&&D>0&&ie(_),e.onNotify();return}n.push({audio:$,audioBuffer:null,utterance:W,visemes:re,words:K,isNewSegment:Y,sampleRate:b,newStream:x,onNewStream:p?.onNewStream,visemesQueued:!1}),await j(_,C)},queueTimingsOnly:(_,C,$,re,K,Y)=>{if(f)return;const p=le();me(p,_,C),H(_,C,$,re,0,!0,S),p.segmentOffsetMs=0,D=ut(_)},getPlaybackElapsedMs:()=>a&&i&&l>0?Math.max(0,(i.currentTime-l)*1e3*w):o?Math.max(0,(performance.now()-d)*w):0,isSpeaking:()=>o?!0:!a||!i||l<=0?!1:(i.currentTime-l)*1e3<D,getVoiceStream:()=>E?E.stream:null,getPlaybackStartPerf:()=>d,bargeIn:()=>{f=!0,u=!1,U(),q(),n.length=0,s=!1,o=!1,a=!1,c=0,l=0,d=0,D=0,O=null,A=null,se=null,I()},interrupt:()=>{f=!0,u=!1,U(),q(),n.length=0,s=!1,o=!1,a=!1,c=0,l=0,d=0,D=0,O=null,A=null,se=null,I()}}}function zt(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 Ni(e,t,n=120){const r=zt(e,t);if(r!=="sil")return r;let i=null;for(const s of e){if(s.vtime>t)break;const o=s.vtime+s.vduration;o<=t&&t-o<=n&&(i=s)}return i?.viseme??"sil"}function ca(e,t,n=400){const r=t-n;let i=0;for(const s of e)if(s.vtime+s.vduration<r)i+=1;else break;i>0&&e.splice(0,i)}function la(e,t){for(const n of e)if(t>=n.wtime&&t<n.wtime+n.wduration)return n;return null}function Rr(e,t){const n=e.trim();if(!n)return null;try{const r=n.replace(/\s+/g,""),i=atob(r).length,s=Number.isFinite(t)&&(t??0)>0?Number(t):16e3;return i/2/s*1e3}catch{return null}}const pn=.5,yn=1.5,tr="Olivia",nr="f786b574-daa5-4673-aa0c-cbe3e8534c02",Ht=.85;function Nn(e,t=gt,n={}){const r=`${t.replace(/\/$/,"")}/avatar_ttsWithPoses`,i=[],s=[],o=[],a=[];let u=0;const d=[],l=[];let c="",m="neutral",w="",S=ft;const f=new Set;let E=0,D=null,B=0,v=null;const k=()=>f.forEach(L=>L());let O=()=>!1;const A=Oi({onSpeakingStart:()=>e("speaking"),onSpeakingDone:()=>e("done"),onNotify:k,shouldHoldForWarmup:()=>O()},ft),se=()=>A.getPlaybackElapsedMs(),le=(L,Z=c)=>{if(!n.onLipsyncDebug)return;const H=se(),me=i,z=wn(o).map(te=>({viseme:te.viseme,vtimeMs:te.vtime}));n.onLipsyncDebug({event:L,spokenText:Z,mood:m,playbackAnchorPerf:A.getPlaybackStartPerf(),playbackElapsedMs:H,queueLength:me.length,activeViseme:zt(me,H),segments:l.map(te=>({...te,visemes:[...te.visemes]})),fullQueueLength:o.length,compactionSkipped:z})},I=(L,Z)=>{n.onLipsyncDebug&&(D={event:L,spokenText:Z},E===0&&(E=requestAnimationFrame(()=>{E=0;const H=D;D=null,H&&le(H.event,H.spokenText)})))},U=(L,Z,H,me,z)=>{if(!n.onLipsyncDebug)return;const te=i.slice(Z),j=H.filter(J=>String(J.symbol??J.viseme??"").trim());l.push({spokenText:L,audioOffsetMs:te[0]?.vtime??0,isNewSegment:me,chunkDurationMs:z,receivedAtMs:performance.now(),visemes:te.map((J,Se)=>{const ue=j[Se];return{rawSymbol:String(ue?.symbol??ue?.viseme??J.viseme).trim(),viseme:J.viseme,startSec:Number(ue?.start??0),durationSec:Number(ue?.duration??0),vtimeMs:J.vtime,vdurationMs:J.vduration}})})},q=()=>{o.length=0,a.length=0,u=0},oe=(L,Z,H,me,z)=>{if(L.length===0&&Z.length===0)return;Di(o,a,L,Z,u,z);const te=Bi(L,u),j=H?Rr(H,me):null;u=Math.max(te,j!=null?u+j:u)},ae=()=>{B+=1,v?.abort(),v=null,A.stop(),i.length=0,s.length=0,q(),d.length=0,m="neutral",l.length=0,c="",e("idle"),I("reset"),k()};return{setDeveloperToken:L=>{w=L},setTtsEngineId:L=>{S=L},getTtsEngineId:()=>S,speak:async(L,Z)=>{ae();const H=B;v=new AbortController,e("loading"),c=L,l.length=0,q();const me=w.trim();if(!me)throw new Error("Developer token required for avatar_ttsWithPoses");const z=et(Z?.ttsEngineId,Z?.voiceId),te=z.ttsEngineId??S??ft;A.resetForNewStream(te),A.setStreamTtsEngineId(te);const j=z.voiceId??(te===nt?dn:tr),J=Z?.speakingRate??Ht,Se=Math.max(pn,Math.min(yn,J)),ue={user_query:L,ttsEngineId:te,speakingRate:Se,tenant:"aiTwin"};si.has(te)&&(ue.voice_id=j);const _=fn(Z?.language);_&&(ue.language=_);try{const C=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${me}`},body:JSON.stringify(ue),signal:v.signal});if(!C.ok)throw new Error(`avatar_ttsWithPoses failed (${C.status})`);const $=C.body;if(!$)throw new Error("No response body");const re=$.getReader(),K=new TextDecoder;let Y="",p=!0;const b=async x=>{if(H!==B)return;const W=vi(x);if(W){if(W.event==="audio"){const ee=W.data.chunk,T=W.data.visemes??[],Q=W.data.words??[],V=W.data.is_new_segment??!1,he=W.data.sample_rate,De=Number(W.data.audio_offset_ms??0),ot=i.length;if(oe(T,Q,ee,he,te),ee){const yt=p;p=!1,await A.playAudioChunk(i,s,ee,T,Q,V,{sampleRate:he,newStream:yt,audioOffsetMs:De}),U(L,ot,T,V,Rr(ee,he)),I("audio_chunk",L)}else(T.length>0||Q.length>0)&&(A.queueTimingsOnly(i,s,T,Q,V,{audioOffsetMs:De,newStream:p}),U(L,ot,T,V,null),I("audio_chunk",L))}else if(W.event==="metadata"){const ee=W.data.mood;typeof ee=="string"&&ee.trim()&&(m=ee.trim());const T=W.data.sentence_emotions;if(Array.isArray(T)){d.length=0;for(const Q of T){if(!Q||typeof Q!="object")continue;const V=Q;d.push({sentence_index:Number(V.sentence_index??0),text:String(V.text??""),sentiment:typeof V.sentiment=="string"?V.sentiment:void 0,emotion:String(V.emotion??m),start_word:Number(V.start_word??0),end_word:Number(V.end_word??0)})}}k(),I("metadata",L)}else if(W.event==="error")throw new Error(String(W.data.message??"avatar_ttsWithPoses stream error"))}};for(;H===B;){const{done:x,value:W}=await re.read();W&&(Y+=K.decode(W,{stream:!0}));const ee=Y.split(`
|
|
2
2
|
|
|
3
|
-
`);
|
|
3
|
+
`);Y=ee.pop()??"";for(const T of ee)await b(T);if(x){Y.trim()&&await b(Y.trim()),A.markStreamComplete(i),I("bot_stopped",L);break}}}catch(C){if(H!==B||C instanceof DOMException&&C.name==="AbortError")return;throw console.error("[avatarTtsLipsync]",C),ae(),e("error"),C}},stop:ae,getVisemeQueue:()=>i,getWordQueue:()=>s,getFullVisemeQueue:()=>o,getFullWordQueue:()=>a,getSentenceEmotions:()=>d,getStreamMood:()=>m,getPlaybackElapsedMs:()=>A.getPlaybackElapsedMs(),isSpeaking:()=>A.isSpeaking(),isWarmingUp:()=>A.isWarmingUp(),releaseWarmupHold:()=>A.releaseWarmupHold(),setLipsyncWarmupHold:(L,Z)=>{Z&&(O=Z),A.setLipsyncWarmupHoldEnabled(L)},getVoiceStream:()=>A.getVoiceStream(),setPlaybackSpeed:L=>{A.setPlaybackSpeed(L)},getPlaybackSpeed:()=>A.getPlaybackSpeed(),subscribe:L=>(f.add(L),()=>f.delete(L))}}const rr=16e3,ir=16e3;class ua extends Hn.ProtobufFrameSerializer{async deserialize(t){try{return await super.deserialize(t)}catch(n){if(n instanceof Error&&n.message==="Unknown frame kind")return{type:"raw",message:null};throw n}}}class da extends Hn.DailyMediaManager{constructor(){super(!0,!0,void 0,void 0,512,rr,ir)}bufferBotAudio(t,n){}}const fa=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Cr(e){return fa.test(e.trim())}function ma(e){const t=e.replace(/\/$/,"");return t.startsWith("https://")?`wss://${t.slice(8)}`:t.startsWith("http://")?`ws://${t.slice(7)}`:t}function Ui(e){if(e.wsUrl?.trim())return e.wsUrl.trim();const t=e.authToken?.trim();if(!t)throw new Error("Voice connect requires authToken (same JWT as SSE Authorization Bearer).");const n=e.apiBase??gt,r=new URL(`${ma(n)}/ws/voice`);r.searchParams.set("authToken",t),r.searchParams.set("tenant","aiTwin");const i=et(e.ttsEngineId,e.voiceId),s=i.ttsEngineId;s&&r.searchParams.set("ttsEngineId",s);const o=i.voiceId?.trim();o&&(s&&ci(s)?Cr(o)||r.searchParams.set("voiceId",o):Cr(o)&&r.searchParams.set("voiceId",o));const a=fn(e.language);a&&r.searchParams.set("language",a);const u=e.brainId?.trim()||e.personaId?.trim();u&&r.searchParams.set("brainId",u);const d=e.brainUrl?.trim();d&&r.searchParams.set("brainUrl",d);const l=e.speakingRate??Ht;r.searchParams.set("speaking_rate",String(Math.max(pn,Math.min(yn,l)))),e.ttsStream===!1?r.searchParams.set("tts_stream","false"):r.searchParams.set("tts_stream","true"),e.speakOnlyWhenSpokenTo&&r.searchParams.set("speakOnlyWhenSpokenTo","true");const c=e.avatarName?.trim();return c&&r.searchParams.set("avatarName",c),r.toString()}function An(e,t){if(!Array.isArray(e))return[];const n=[];for(const r of e)!r||typeof r!="object"||n.push({sentence_index:Number(r.sentence_index??0),text:String(r.text??""),sentiment:typeof r.sentiment=="string"?r.sentiment:void 0,emotion:String(r.emotion??t),start_word:Number(r.start_word??0),end_word:Number(r.end_word??0)});return n}function ha(e){if(!e||typeof e!="object")return null;const t=e,r=(t.data&&typeof t.data=="object"&&!Array.isArray(t.data)?t.data:null)||t;return{...r,type:String(r.type??t.type??"server-message")}}function Dr(e){return e.is_new_segment===!0||Number(e.audio_offset_ms??-1)===0?!0:Number(e.chunk_index??-1)===0}function ga(e){return e?.transport?._mediaManager?._wavStreamPlayer??null}function Vi(e,t={}){const n=[],r=[],i=[],s=[];let o=0;const a=[],u=[];let d="",l="neutral",c=tt,m=!1,w=null,S=null,f={...t},E=0,D=null;const B=new Set,v=[];let k=!1,O=null,A=!0,se="default";const le=new Set;let I=null,U=0,q=!1,oe=!1,ae=null,ie=!1;const L=()=>{ae!=null&&(clearTimeout(ae),ae=null)},Z=()=>{L(),ae=setTimeout(()=>{ae=null,A&&(z.markStreamComplete(n),ue("bot_stopped"))},450)},H=()=>B.forEach(g=>g());let me=()=>!1;const z=Oi({onSpeakingStart:()=>e("speaking"),onSpeakingDone:()=>{ie=!1,oe=!1,e("done")},onNotify:H,shouldHoldForWarmup:()=>me()},c),te=()=>{if(O)return O;const g=new MessageChannel;return g.port1.onmessage=()=>{const P=v.shift();P!==void 0&&he(P),v.length>0?g.port2.postMessage(null):k=!1},O=g,g},j=g=>{v.push(g),!k&&(k=!0,te().port2.postMessage(null))},J=()=>z.getPlaybackElapsedMs(),Se=(g,P=d)=>{if(!f.onLipsyncDebug)return;const ne=J(),ce=n,Te=wn(i).map(be=>({viseme:be.viseme,vtimeMs:be.vtime}));f.onLipsyncDebug({event:g,spokenText:P,mood:l,playbackAnchorPerf:z.getPlaybackStartPerf(),playbackElapsedMs:ne,queueLength:ce.length,activeViseme:zt(ce,ne),segments:u.map(be=>({...be,visemes:[...be.visemes]})),fullQueueLength:i.length,compactionSkipped:Te})},ue=(g,P)=>{f.onLipsyncDebug&&(D={event:g,spokenText:P},E===0&&(E=requestAnimationFrame(()=>{E=0;const ne=D;D=null,ne&&Se(ne.event,ne.spokenText)})))},_=()=>{A=!0,le.clear(),z.clearAborted()},C=()=>{const g=ga(w);if(g){se=`bot-${Date.now()}`,g.interruptedTrackIds={[se]:!0};try{g.interrupt?.()}catch{}}const P=S;try{P?.interrupt?.()}catch{}},$=g=>{if(ie&&z.isSpeaking())return!0;const P=g.context_id?.trim();return P&&le.has(P)?!0:A?!1:!(g.type==="avatar_metadata"||Dr(g))},re=g=>{A=!1,ie=!1;const P=g.context_id?.trim();P&&le.add(P),L(),q=!1,oe=!1,v.length=0,k=!1,I?.abort(),I=null,U+=1,C(),z.bargeIn(),K(),e("idle"),ue("interrupt"),H()},K=()=>{n.length=0,r.length=0,i.length=0,s.length=0,o=0,u.length=0,d="",l="neutral",a.length=0},Y=()=>{L(),oe=!1,q=!1,z.stop(),K(),ue("reset"),H()},p=()=>{Y(),e("idle"),H()},b=(g,P)=>{typeof g.mood=="string"&&g.mood.trim()&&(l=g.mood.trim()),Array.isArray(g.sentence_emotions)&&g.sentence_emotions.length>0&&(P&&(a.length=0),a.push(...An(g.sentence_emotions,l)))},x=g=>{if($({...g,type:"avatar_metadata"}))return;_(),q=!0;const P=String(g.spoken_text??g.text??"").trim();P&&(d=P),z.resetForNewStream(c),typeof g.mood=="string"&&g.mood.trim()&&(l=g.mood.trim()),a.length=0,a.push(...An(g.sentence_emotions,l)),Array.isArray(g.gestures)&&g.gestures,ue("metadata",P),H()},W=(g,P,ne,ce)=>{if(!f.onLipsyncDebug)return;const Te=n.slice(ne),be=ce.filter(ke=>String(ke.symbol??ke.viseme??"").trim());u.push({spokenText:P,audioOffsetMs:Te[0]?.vtime??0,isNewSegment:!!g.is_new_segment,chunkDurationMs:g.chunk_duration_ms!=null?Number(g.chunk_duration_ms):null,receivedAtMs:performance.now(),visemes:Te.map((ke,ze)=>{const Ne=be[ze];return{rawSymbol:String(Ne?.symbol??Ne?.viseme??ke.viseme).trim(),viseme:ke.viseme,startSec:Number(Ne?.start??0),durationSec:Number(Ne?.duration??0),vtimeMs:ke.vtime,vdurationMs:ke.vduration}})})},ee=(g,P,ne,ce)=>{if(g.length===0&&P.length===0)return;Di(i,s,g,P,o,c);const Te=Bi(g,o);let be=null;const ke=ne.trim();if(ke)try{const ze=atob(ke.replace(/\s+/g,"")).length,Ne=Number.isFinite(ce)&&(ce??0)>0?Number(ce):16e3;be=ze/2/Ne*1e3}catch{be=null}o=Math.max(Te,be!=null?o+be:o)},T=g=>{if($(g))return;const P=Dr(g);P&&(L(),_());const ne=String(g.spoken_text??g.text??"").trim(),ce=g.visemes??[],Te=g.words??[],be=String(g.chunk??"").trim(),ke=q||P||!oe;q&&(q=!1),ke&&(oe=!0),ne&&(d=ne),b(g,P),ke?(z.resetForNewStream(c),i.length=0,s.length=0,o=0):P&&z.resumeBotStream(),ee(ce,Te,be,g.sample_rate);const ze=n.length;z.playAudioChunk(n,r,be,ce,Te,P,{sampleRate:g.sample_rate,newStream:ke,audioOffsetMs:Number(g.audio_offset_ms??0),onNewStream:()=>{u.length=0}}).then(()=>{W(g,ne,ze,ce),ue("audio_chunk",ne),Z()})},Q=g=>{if($(g))return;(g.is_new_segment||Number(g.audio_offset_ms??-1)===0)&&_(),console.warn("[realtimeVoice] avatar_lipsync is deprecated — expect avatar_audio_chunk");const P=String(g.spoken_text??g.text??"").trim();P&&(d=P),b(g,!!g.is_new_segment),ee(g.visemes??[],g.words??[],"",void 0);const ne=n.length;z.queueTimingsOnly(n,r,g.visemes??[],g.words??[],!!g.is_new_segment,{audioOffsetMs:Number(g.audio_offset_ms??0)}),W(g,P,ne,g.visemes??[]),ue("lipsync",P),H()},V=async g=>{const P=String(g.text??"").trim();if(!P)return;const ne=f.authToken?.trim();if(!ne){console.error("[realtimeVoice] avatar_speak requires authToken");return}I?.abort();const ce=new AbortController;I=ce;const Te=++U;_(),z.resetForNewStream(c),d=P;const ke=`${(f.apiBase??gt).replace(/\/$/,"")}/avatar_ttsWithPoses`,ze=et(c,f.voiceId);ze.ttsEngineId&&(c=ze.ttsEngineId,z.setStreamTtsEngineId(c));const Ne=ze.voiceId?.trim()||(c===nt?dn:nr),$t=f.speakingRate??Ht,bn=Math.max(pn,Math.min(yn,$t)),Ct={user_query:P,ttsEngineId:c,speakingRate:bn,tenant:"aiTwin"};si.has(c)&&(Ct.voice_id=Ne);const vt=fn(f.language);vt&&(Ct.language=vt);try{const Be=await fetch(ke,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${ne}`},body:JSON.stringify(Ct),signal:ce.signal});if(!Be.ok)throw new Error(`avatar_ttsWithPoses failed (${Be.status})`);const $e=Be.body;if(!$e)throw new Error("No response body");const _t=$e.getReader(),Ee=new TextDecoder;let Ie="",je=!0;const Ke=async rt=>{if(Te!==U||ce.signal.aborted||!A)return;const ye=vi(rt);if(ye){if(ye.event==="audio"){const Ue=ye.data.chunk,Re=ye.data.visemes??[],Ve=ye.data.words??[],We=ye.data.is_new_segment??!1,Dt=ye.data.sample_rate,lt=Number(ye.data.audio_offset_ms??0);if(Ue){const Bt=je;je=!1,await z.playAudioChunk(n,r,Ue,Re,Ve,We,{sampleRate:Dt,newStream:Bt,audioOffsetMs:lt})}else(Re.length>0||Ve.length>0)&&z.queueTimingsOnly(n,r,Re,Ve,We,{audioOffsetMs:lt,newStream:je})}else if(ye.event==="metadata"){const Ue=ye.data.mood;typeof Ue=="string"&&Ue.trim()&&(l=Ue.trim());const Re=ye.data.sentence_emotions;Array.isArray(Re)&&(a.length=0,a.push(...An(Re,l))),H()}else if(ye.event==="error")throw new Error(String(ye.data.message??"avatar_ttsWithPoses stream error"))}};for(;!(Te!==U||ce.signal.aborted||!A);){const{done:rt,value:ye}=await _t.read();ye&&(Ie+=Ee.decode(ye,{stream:!0}));const Ue=Ie.split(`
|
|
4
4
|
|
|
5
|
-
`);xe=Le.pop()??"";for(const Pe of Le)await je(Pe);if(rt){xe.trim()&&await je(xe.trim()),Te===V&&!ue.signal.aborted&&A&&K.markStreamComplete(n);break}}}catch(Ce){if(ue.signal.aborted||!A)return;console.error("[realtimeVoice] avatar_speak failed:",Ce),e("error"),W()}finally{I===ue&&(I=null)}},be=g=>{const C=fa(g);if(!C){console.warn("[realtimeVoice] server message with no payload",g);return}const ne=String(C.type??"unknown");switch(ne!=="avatar_metadata"&&ne!=="avatar_audio_chunk"&&ne!=="avatar_lipsync"&&ne!=="avatar_interrupt"&&ne!=="error"&&console.debug("[realtimeVoice] server message",ne,C),ne){case"avatar_metadata":x(C);break;case"avatar_audio_chunk":Z(C);break;case"avatar_lipsync":te(C);break;case"avatar_interrupt":le(C);break;case"error":{const ue=String(C.message??"Voice session error");console.error("[realtimeVoice] server error:",ue),e("error"),W();break}case"avatar_speak":z(C);break}},Xe=()=>w||(T=new la,w=new us.PipecatClient({transport:new Hn.WebSocketTransport({mediaManager:T,serializer:new ca,recorderSampleRate:nr,playerSampleRate:rr}),enableCam:!1,enableMic:!0,callbacks:{onBotReady:()=>{m=!0,e("idle"),W()},onDisconnected:()=>{m=!1,p()},onError:g=>{const C=typeof g=="object"&&g!==null&&"data"in g?String(g.data??g):String(g);console.error("[realtimeVoice]",C,g),e("error"),W()},onTransportStateChanged:g=>{g==="error"&&(e("error"),W())},onServerMessage:g=>{$(g)},onUserStartedSpeaking:()=>{},onBotStartedSpeaking:()=>{b(),oe("bot_started")},onBotStoppedSpeaking:()=>{A&&J()},onUserTranscript:g=>{String(g.text??""),f.onUserTranscript?.(g.text,!!g.final)},onBotOutput:g=>{f.onBotOutput?.(g.text)}}}),w);return{setDeveloperToken:g=>{},setTtsEngineId:g=>{c=g,K.setStreamTtsEngineId(g)},getTtsEngineId:()=>c,speak:async(g,C)=>{const ne=g.trim();if(ne){if(!w||!m)throw new Error("Realtime voice is not connected. Call connect() first.");q(),await w.sendText(ne)}},stop:()=>{I?.abort(),I=null,V+=1,b(),q(),e("idle"),W()},connect:async g=>{g&&(f={...f,...g});const C=et(f.ttsEngineId,f.voiceId);if(C.ttsEngineId&&(c=C.ttsEngineId,K.setStreamTtsEngineId(c)),f={...f,ttsEngineId:c,...C.voiceId?{voiceId:C.voiceId}:{}},!f.authToken?.trim())throw new Error("Voice connect requires authToken (same JWT as SSE Authorization Bearer).");e("loading");const ne=Xe();await ne.initDevices();const ue=Ni({...f,ttsEngineId:c});console.info("[realtimeVoice] connecting (avatar_audio_chunk RTVI):",ue);try{await ne.connect({wsUrl:ue})}catch(Te){m=!1,e("error"),W();const ve=Te instanceof Error?Te.message:"Realtime voice connect failed (WebSocket 101 only means upgrade OK — check authToken/origin/RTVI handshake)";throw new Error(`${ve} — ${ue}`)}m=!0,e("idle"),W()},disconnect:async()=>{if(O(),G=!1,ae=!1,v.length=0,k=!1,I?.abort(),I=null,V+=1,b(),w)try{await w.disconnect()}catch(g){console.error("[realtimeVoice] disconnect failed:",g)}m=!1,p()},isConnected:()=>m,unlockAudio:async()=>{await K.primeAudioContext()},getVisemeQueue:()=>n,getWordQueue:()=>r,getFullVisemeQueue:()=>i,getFullWordQueue:()=>s,getSentenceEmotions:()=>a,getStreamMood:()=>l,getPlaybackElapsedMs:X,isSpeaking:()=>K.isSpeaking(),isWarmingUp:()=>K.isWarmingUp(),releaseWarmupHold:()=>K.releaseWarmupHold(),setLipsyncWarmupHold:(g,C)=>{C&&(he=C),K.setLipsyncWarmupHoldEnabled(g)},getVoiceStream:()=>K.getVoiceStream(),setPlaybackSpeed:g=>{K.setPlaybackSpeed(g)},getPlaybackSpeed:()=>K.getPlaybackSpeed(),subscribe:g=>(B.add(g),()=>B.delete(g))}}function Ui(e,t,n){return{width:e.crop?.source_width??t,height:e.crop?.source_height??n}}function Wi(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 zi(e){return e?(e.w??0)>0&&(e.h??0)>0:!1}async function Mt(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 Ds(r,t)}async function Hi(e,t){if(!t)throw new Error("Missing asset key for encrypted JSON");const n=await Mt(e,t),r=new TextDecoder().decode(n);return JSON.parse(r)}async function ha(e){const t=new Blob([e],{type:"image/webp"});return createImageBitmap(t)}async function ga(e){const t=new Blob([e],{type:"image/webp"}),n=URL.createObjectURL(t);return new Promise((r,i)=>{const s=new Image;s.decoding="async",s.onload=()=>{URL.revokeObjectURL(n),r(s)},s.onerror=()=>{URL.revokeObjectURL(n),i(new Error("Failed to decode decrypted image"))},s.src=n})}async function wa(e){const t=new Blob([e],{type:"image/png"});return createImageBitmap(t)}async function pa(e){const t=new Blob([e],{type:"image/png"}),n=URL.createObjectURL(t);return new Promise((r,i)=>{const s=new Image;s.decoding="async",s.onload=()=>{URL.revokeObjectURL(n),r(s)},s.onerror=()=>{URL.revokeObjectURL(n),i(new Error("Failed to decode decrypted PNG"))},s.src=n})}function ya(e){const t=new Blob([e],{type:"video/mp4"});return URL.createObjectURL(t)}async function va(e){const t=Fs();if(!Wt())return t;if(!e)throw new Error("Missing asset key for encrypted idle video");const n=await Mt(t,e);return ya(n)}function kt(e,t){return`${e}/${t}_minus_sil.png`}const $i=5;function vn(e){const t=e?.composite_threshold;if(typeof t=="number"&&t>0)return t;const n=e?.crop?.content_threshold;return typeof n=="number"&&n>0?n:$i}const _a=["aa","E","I","O","U","PP","FF","DD","SS","TH","CH","RR","kk","nn"],Vn=["t01_0.25","t02_0.50","t03_0.75"],ba=Vn.length,Dr=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 Br(e,t){return`${e}__${t}`}function Fr(e,t){return`pairs/${e}/${t}_minus_sil.png`}function xt(e){return`${e}_minus_sil.png`}function ir(e,t){if(t.has(e))return e;const n=/^pairs\/([^/]+)\//.exec(e);if(!n)return null;const r=n[1].split("__")[1];if(!r||r==="sil")return null;const i=xt(r);return t.has(i)?i:null}function ji(e,t){return e.filter(n=>t.has(n))}function Sa(e,t,n){const r=sr(e,t);return ji(r,n).length>0}function sr(e,t){if(e===t)return[];const n=[],r=Br(e,t);if(Dr.has(r)){for(const s of Vn)n.push(Fr(r,s));return n}const i=Br(t,e);if(Dr.has(i)){for(let s=ba-1;s>=0;s--)n.push(Fr(i,Vn[s]));return n}return[]}function Ta(e){return e<16?[1]:e<24?[1]:e<35?[0,1,2]:[0,1,2]}function ka(e,t){return Ta(t).map(r=>e[r]).filter(r=>r!=null)}function Ea(e,t,n,r){if(r<=0)return 0;const s=Math.max(1,n-t)/r,o=e-t,a=Math.floor(o/s);return Math.min(r-1,Math.max(0,a))}function Ki(e,t,n){if(!n)return`${e}/${t}`;const r=t.split("/").pop()??t,i=r.includes(".")?r.slice(0,r.lastIndexOf(".")):r;return`${e}/${i}.bin`}const xa=[.32,.24,.16,.08,0],Ia=xa.map(e=>`eyes_${e.toFixed(2)}`),Aa=["eyes_0.32","eyes_0.16","eyes_0.00"],Ma=["eyes_0.32","eyes_0.16","eyes_0.08","eyes_0.00"],ze=2,Pa=-20,an=16,Gi={fear:-20,anger:-20,sad:-10,neutral:0,love:0,happy:0,disgust:10};function Vt(e){return`brow_${e}`}function mt(e){return Gi[e]}function Qe(e){return Math.max(Pa,Math.min(an,e))}function Ca(e,t){if(e===t)return[];const n=e<t,r=n?ze:-ze,i=[];let s=e;if(s%ze!==0){const o=n?Math.ceil(s/ze)*ze:Math.floor(s/ze)*ze,a=Qe(o);if(n?a>=t:a<=t)return[t];s=a,i.push(s)}for(;;){const o=s+r;if(n?o>=t:o<=t){t!==s&&i.push(t);break}s=o,i.push(s)}return i}function Lr(e){const t=Qe(e);if(t%ze===0)return[t];const n=Math.floor(t/ze)*ze,r=Math.min(an,n+ze),i=Qe(n);return t-i<=r-t?i===r?[i]:[i,r]:i===r?[r]:[r,i]}const Ra=["fear","anger","sad","neutral","love","happy","disgust"],Da={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 Ze(e,t="neutral"){const n=String(e??"").trim().toLowerCase();return n?Da[n]??t:t}function qi(e){return e===0?null:kt(Vt(e),"eyes_standard")}function Yi(e){return qi(mt(e))}const Ba={[-20]:"anger",[-10]:"sad",0:"neutral",10:"disgust"};function ar(e,t){if(!e)return null;if(t(e))return e;const n=e.match(/^brow_(-?\d+)\/(eyes_[^/]+)_minus_sil\.png$/);if(n){const i=Number(n[1]),s=n[2];for(const a of Lr(i)){if(a===i)continue;const u=kt(Vt(a),s);if(t(u))return u}const o=Ba[i];if(o){const a=kt(o,s);if(t(a))return a}return null}const r=e.match(/^(fear|anger|sad|neutral|love|happy|disgust)\/(eyes_[^/]+)_minus_sil\.png$/);if(r){const i=r[1],s=r[2],o=mt(i);for(const a of[o,...Lr(o)]){const u=kt(Vt(a),s);if(t(u))return u}}return null}function Or(e,t){const n=Vt(mt(e));return!t||t==="eyes_standard"?Yi(e):e==="neutral"&&t==="eyes_standard"?null:kt(n,t)}function Fa(e,t){const n=[];for(const r of t)n.push(Or(e,r));for(let r=t.length-2;r>=0;r--)n.push(Or(e,t[r]));return n.push(Yi(e)),n}function La(e){return kt(Vt(e),"eyes_standard")}function Oa(e,t){return Ca(e,t).map(La)}const Na=6;function Va(e,t){for(const n of e)if(t>=n.wtime&&t<n.wtime+n.wduration)return n;return null}function Ua(e){const t=Qe(e);return t>=an?an:Qe(t+Na)}function Wa(e,t,n){const r=Qe(n);return Va(t,e)?.emphasis?Ua(r):r}function Nr(e){if(!e)return 0;const t=e.match(/^brow_(-?\d+)\//);if(!t?.[1])return null;const n=Number.parseInt(t[1],10);return Number.isFinite(n)?Qe(n):null}function Ye(e,t){return e+Math.random()*(t-e)}function Vr(){return Ye(14,32)}function za(e){if(e)return{holdMinMs:10,holdMaxMs:18,closedExtraMs:0};const t=Math.random();return t<.18?{holdMinMs:38,holdMaxMs:62,closedExtraMs:Ye(40,90)}:t<.42?{holdMinMs:26,holdMaxMs:44,closedExtraMs:Ye(12,36)}:t<.82?{holdMinMs:14,holdMaxMs:28,closedExtraMs:Math.random()<.35?Ye(8,22):0}:{holdMinMs:10,holdMaxMs:18,closedExtraMs:0}}function Ur(e,t){const n=Ye(e.holdMinMs,e.holdMaxMs);return t?n+e.closedExtraMs:n}function Ha(e={}){const{initialDelayMs:t=800+Math.random()*1200,intervalMinMs:n=2200,intervalMaxMs:r=5800,doubleBlinkChance:i=.18,doubleBlinkGapMinMs:s=120,doubleBlinkGapMaxMs:o=220,fullBlinkChance:a=.75,postEmotionChangeDelayMs:u=380,minDwellMs:d=550}=e;let l="neutral",c="neutral",m=0,w=0,T=0,f={kind:"idle",nextBlinkAt:performance.now()+t},E=null,D="__eyes_open__|neutral|brow:0";function B(I=l){D=`${E??"__eyes_open__"}|${I}|brow:${w}`}function v(I,V=l){E=I;const G=Nr(I);G!=null?w=G:I==null&&(w=0),B(V)}function k(I){return qi(I)}function L(I,V,G){const ae=Qe(V),se=Qe(G);if(m=se,ae===se){v(k(se));return}const re=[...Oa(ae,se),k(se)];f={kind:"browBlend",paths:re,index:0,holdUntil:I+Vr(),targetBrow:se},v(re[0]??null)}function A(I,V){f={kind:"idle",nextBlinkAt:I+Ye(n,r)},c=V,v(k(m),V)}function ie(I,V,G){const ae=G?Aa:Math.random()<a?Ia:Ma,se=za(G),re=ae.length-1;f={kind:"playing",paths:Fa(V,ae),index:0,holdUntil:I+Ur(se,re===0),after:"idle",blinkEmotion:V,pace:se,closedFrameIndex:re},c=V,v(f.paths[0]??null,V)}function de(I){if(f.kind==="browBlend"){for(;I>=f.holdUntil&&f.index<f.paths.length-1;)f.index+=1,f.holdUntil=I+Vr();const V=f.paths[f.index]??null;v(V),I>=f.holdUntil&&f.index>=f.paths.length-1&&(w=f.targetBrow,m=f.targetBrow,v(k(f.targetBrow)),f={kind:"idle",nextBlinkAt:I+u});return}if(f.kind==="idle"){v(k(m),c),I>=f.nextBlinkAt&&ie(I,c,!1);return}if(f.kind==="doublePause"){v(k(m),f.blinkEmotion),I>=f.resumeAt&&ie(I,f.blinkEmotion,!0);return}if(f.kind==="playing"){for(;I>=f.holdUntil&&f.index<f.paths.length-1;)f.index+=1,f.holdUntil=I+Ur(f.pace,f.index===f.closedFrameIndex);if(v(f.paths[f.index]??null,f.blinkEmotion),I>=f.holdUntil&&f.index>=f.paths.length-1){if(f.after==="resumeIdle"){A(I+u,l);return}if(f.after==="doublePause"){f={kind:"doublePause",resumeAt:I+Ye(s,o),blinkEmotion:f.blinkEmotion},v(k(m),f.blinkEmotion);return}if(f.after==="idle"&&Math.random()<i){f={kind:"doublePause",resumeAt:I+Ye(s,o),blinkEmotion:f.blinkEmotion},v(k(m),f.blinkEmotion);return}A(I,f.blinkEmotion)}}}return{advance:de,setTargetEmotion(I,V){const G=Ze(I,l);if(G===l)return;const ae=performance.now();!V?.force&&d>0&&!(l==="neutral"&&G!=="neutral")&&ae-T<d||(l=G,c=G,T=ae)},setTargetEyebrow(I){const V=Qe(I);if(V===m)return;const G=performance.now(),ae=f.kind==="browBlend"?Nr(E)??w:w;m=V,!(V===ae&&f.kind!=="browBlend")&&(f.kind==="playing"||f.kind==="doublePause"||L(G,ae,V))},snapToEmotion(I){const V=Ze(I),G=mt(V);l=V,c=V,m=G,w=G,T=performance.now(),f={kind:"idle",nextBlinkAt:performance.now()+Ye(4e3,7e3)},v(k(G),V)},getTargetEmotion:()=>l,getTargetEyebrow:()=>m,getExpressionPath:()=>E,getDrawKey:()=>D,reset(){l="neutral",c="neutral",m=0,w=0,T=0,A(performance.now()+Ye(n,r),"neutral")}}}function $a(){const e=document.createElement("video");e.muted=!0,e.playsInline=!0,e.preload="auto",e.setAttribute("playsinline",""),e.loop=!0;let t=!1,n=null,r="";const i=()=>{n&&(URL.revokeObjectURL(n),n=null)};return{async load(s){t&&r===s||(i(),t=!1,r=s,s.startsWith("blob:")&&(n=s),await new Promise((o,a)=>{const u=()=>{const d=e.duration;if(!Number.isFinite(d)||d<=0){a(new Error(`Idle video has invalid duration: ${s}`));return}t=!0,e.currentTime=0,o()};e.addEventListener("loadeddata",u,{once:!0}),e.addEventListener("error",()=>a(new Error(`Failed to load idle video: ${s}`)),{once:!0}),e.src=s,e.load()}))},isReady(){return t},getVideo(){return e},setActive(s){t&&(s?e.paused&&e.play().catch(()=>{}):e.paused||e.pause())},restart(){t&&(e.currentTime=0)},dispose(){e.pause(),e.removeAttribute("src"),e.load(),i(),t=!1,r=""}}}const ja=50,Qi=400;function Ka(e,t,n){return e.filter(r=>{const i=r.queueIndex??-1;return i>=t&&i<=n})}function Ga(e,t){const n=[];for(const r of e){const i=Ka(t,r.start_word,r.end_word);if(i.length===0)continue;const s=i[0],o=i[i.length-1];n.push({sentence:r,startMs:Math.max(0,s.wtime-ja),endMs:o.wtime+o.wduration+Qi})}return n.sort((r,i)=>r.startMs-i.startMs)}function qa(e,t,n,r="neutral"){const i=Ze(r);if(t.length===0)return i;if(n.length===0||e<n[0].wtime)return Ze(t[0]?.emotion,i);const s=Ga(t,n);let o=null;for(const d of s)e>=d.startMs&&e<=d.endMs&&(o=d);if(o)return Ze(o.sentence.emotion,i);const a=n[n.length-1],u=a.wtime+a.wduration;return e>u+Qi?Ze(t[t.length-1]?.emotion,i):i}function or(e,t,n,r,i=$i){const s=new OffscreenCanvas(n,r),o=s.getContext("2d",{willReadFrequently:!0});o.drawImage(e,0,0,n,r);const a=o.getImageData(0,0,n,r),u=o.createImageData(n,r);u.data.set(a.data);const l=new OffscreenCanvas(n,r).getContext("2d",{willReadFrequently:!0});for(const c of t){l.clearRect(0,0,n,r),l.drawImage(c,0,0,n,r);const m=l.getImageData(0,0,n,r);for(let w=0;w<u.data.length;w+=4){const T=m.data[w],f=m.data[w+1],E=m.data[w+2];Math.max(T,f,E)>i&&(u.data[w]=T,u.data[w+1]=f,u.data[w+2]=E,u.data[w+3]=255)}}return o.putImageData(u,0,0),s}let ut=null,It=null;const on=new Map;function Ya(){ut=null,It=null,on.clear()}fi(Ya);function Qa(e){return e??It??void 0}function cr(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 Xa(e){return Wt()?pa(await Mt(sn(),e??"")):cr(sn())}async function Wr(e,t,n,r){const i=n?await Hi(e,r):await fetch(e).then(d=>{if(!d.ok)throw new Error(`Failed to load ${e}`);return d.json()}),s=i.sheets?.[0];if(!s?.path)throw new Error(`${e} has no sheets[0].path`);const o=n?await ga(await Mt(Ki(t,s.path,n),r??"")):await cr(`${t}/${s.path}`),a=new Map;for(const d of i.cells??[])d.path&&a.set(d.path,d);const u=new Map;for(const d of i.sheets??[])u.set(d.index,d);return{atlas:o,atlasMeta:i,cellByPath:a,sheetByIndex:u,diffBase:t}}async function Un(e){const t=Qa(e),n=Wt();if(n&&!t)throw new Error("Encrypted assets enabled but no key provided");if(ut&&(!n||It===(t??null))){const s=await ut;return{...At(s),visemePaths:[...s.viseme.cellByPath.keys()]}}It=t??null,on.clear();const r=mi();ut=(async()=>{const s=await Xa(t),o=await Wr(hi(),r,n,t);let a=null;try{a=await Wr(gi(),r,n,t)}catch{a=null}return{sil:s,viseme:o,expression:a}})();const i=await ut;return{...At(i),visemePaths:[...i.viseme.cellByPath.keys()]}}async function lr(e){if(await Un(e),!ut)throw new Error("Assets not loaded");return ut}function At(e){return Ui(e.viseme.atlasMeta,e.sil.naturalWidth,e.sil.naturalHeight)}function Ja(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 cn(e,t,n){const r=`${t.diffBase}::${n}`,i=on.get(r);if(i)return i;const s=(async()=>{const o=t.cellByPath.get(n);if(!o)throw new Error(`No atlas cell for path: ${n}`);const a=Wi(t.atlasMeta,o),u=At(e);if(zi(o)){const c=Ja(t,o),m=document.createElement("canvas");m.width=u.width,m.height=u.height;const w=m.getContext("2d");return w.fillStyle="#000",w.fillRect(0,0,u.width,u.height),w.drawImage(c,a.x,a.y),m}const d=`${t.diffBase}/${n}`,l=await cr(d);if(l.naturalWidth===u.width&&l.naturalHeight===u.height)return l;throw new Error(`Diff PNG wrong size for ${n}`)})();return on.set(r,s),s}async function Mn(e,t,n,r,i,s){if(i){const{width:w,height:T}=i;if(s&&!s()||t.readyState<HTMLMediaElement.HAVE_CURRENT_DATA)return;const f=document.createElement("canvas");f.width=w,f.height=T;const E=f.getContext("2d");if(E.clearRect(0,0,w,T),E.drawImage(t,0,0,w,T),s&&!s())return;(e.width!==w||e.height!==T)&&(e.width=w,e.height=T);const D=e.getContext("2d");D.clearRect(0,0,w,T),D.drawImage(f,0,0);return}const o=await lr(),a=vn(o.viseme.atlasMeta),{width:u,height:d}=At(o);(e.width!==u||e.height!==d)&&(e.width=u,e.height=d);const l=[],c=e.getContext("2d");if(c.clearRect(0,0,u,d),t.readyState<HTMLMediaElement.HAVE_CURRENT_DATA){const w=o.sil;c.drawImage(w,0,0,u,d);return}if(l.length===0){c.drawImage(t,0,0,u,d);return}const m=or(t,l,u,d,a);c.drawImage(m,0,0)}async function Wn(e,t,n){const r=await lr(It??void 0),i=vn(r.viseme.atlasMeta),{width:s,height:o}=At(r);(e.width!==s||e.height!==o)&&(e.width=s,e.height=o);const a=[];if(t.mouthPath){const l=new Set(r.viseme.cellByPath.keys()),c=ir(t.mouthPath,l)??(l.has(t.mouthPath)?t.mouthPath:null);c&&a.push(await cn(r,r.viseme,c))}if(t.expressionPath&&r.expression){const l=ar(t.expressionPath,c=>r.expression.cellByPath.has(c));l&&a.push(await cn(r,r.expression,l))}const u=e.getContext("2d");if(u.clearRect(0,0,s,o),a.length===0){u.drawImage(r.sil,0,0,s,o);return}const d=or(r.sil,a,s,o,i);u.drawImage(d,0,0)}async function Za(e,t){const n=await lr(It??void 0),r=vn(n.viseme.atlasMeta),{width:i,height:s}=At(n),o=[];if(e.mouthPath){const l=new Set(n.viseme.cellByPath.keys()),c=ir(e.mouthPath,l)??(l.has(e.mouthPath)?e.mouthPath:null);c&&o.push(await cn(n,n.viseme,c))}if(e.expressionPath&&n.expression){const l=ar(e.expressionPath,c=>n.expression.cellByPath.has(c));l&&o.push(await cn(n,n.expression,l))}const a=new OffscreenCanvas(i,s),u=a.getContext("2d");if(o.length===0)return u.drawImage(n.sil,0,0,i,s),a.transferToImageBitmap();const d=or(n.sil,o,i,s,r);return u.drawImage(d,0,0),a.transferToImageBitmap()}async function eo(e){await Wn(e,{mouthPath:null,expressionPath:null})}const en={fontFamily:"system-ui, -apple-system, sans-serif",fontSize:"clamp(0.875rem, 2.5vw, 1.125rem)",color:"rgba(255,255,255,0.85)"};function to(e){return e.length===0?"":e.map(t=>t.word).join(" ")}function no(e){if(!e)return{enabled:!1,style:en};const t=e===!0?{}:e;return{enabled:!0,style:{fontFamily:t.fontFamily??en.fontFamily,fontSize:t.fontSize??en.fontSize,color:t.color??en.color}}}const ro={position:"absolute",bottom:0,left:0,right:0,display:"flex",justifyContent:"center",padding:"0.75rem 1rem",pointerEvents:"none"},io={display:"inline-block",maxWidth:"100%",padding:"0.45rem 0.85rem",borderRadius:"0.75rem",background:"rgba(0,0,0,0.55)",lineHeight:1.4,textAlign:"center"},so={display:"-webkit-box",WebkitLineClamp:2,WebkitBoxOrient:"vertical",overflow:"hidden",maxWidth:"100%",margin:0};function ao({text:e,style:t}){return R.jsx("div",{style:ro,"aria-live":"polite","aria-atomic":"true",children:R.jsx("div",{style:{...io,fontFamily:t.fontFamily,fontSize:t.fontSize,color:t.color},children:R.jsx("p",{style:so,children:e})})})}const oo={inset:0,overflow:"hidden",pointerEvents:"none",position:"absolute",zIndex:3},co={filter:"blur(22px)",height:"100%",inset:0,objectFit:"cover",objectPosition:"top",position:"absolute",transform:"scale(1.08)",width:"100%"},lo={backdropFilter:"blur(10px)",WebkitBackdropFilter:"blur(10px)",inset:0,position:"absolute"};function uo({thumbnailUrl:e}){const[t,n]=h.useState(!1);h.useEffect(()=>{n(!1)},[e]);const r=!!e&&t;return R.jsxs("div",{style:oo,"aria-hidden":!0,children:[e?R.jsx("img",{src:e,alt:"",style:{...co,opacity:r?1:0,transition:"opacity 0.45s ease"},onLoad:()=>n(!0),onError:()=>n(!1)}):null,R.jsx("div",{style:{...lo,background:r?"rgba(0, 0, 0, 0.28)":"rgba(10, 10, 11, 0.92)"}})]})}let Xi=null;function zr(e){Xi=e}function at(){return Xi}function fo(e){return`${e.from}→${e.to}@${e.fromVtime}`}function Hr(){return{rafTicksSpeaking:0,rafTicksDeduped:0,drawsRequested:0,drawsDisplayed:0,queueSuperseded:0,workerStale:0,rifeFramesOmittedByGap:0,transitionFramesSampled:0,transitionFramesDisplayed:0,transitionFramesMissed:0,bufferTicks:0,bufferHits:0,bufferUnderruns:0,bufferPrefetched:0}}function mo(){let e=Hr();const t=new Set,n=new Set,r=new Set;let i="",s=-1,o="";const a=()=>{e=Hr(),t.clear(),n.clear(),r.clear(),i="",s=-1,o=""},u=l=>{t.add(l)},d=l=>{l&&r.add(l)};return{reset:a,onRafTickSpeaking(){e.rafTicksSpeaking+=1},onDrawDeduped(){e.rafTicksDeduped+=1},onDrawRequested(){e.drawsRequested+=1},onQueueSuperseded(){e.queueSuperseded+=1},onWorkerStale(){e.workerStale+=1},onTransitionSample(l,c){const m=fo(l);e.transitionFramesSampled+=1,m!==i&&(i=m,s=-1,o!==m&&(o=m,e.rifeFramesOmittedByGap+=l.omittedByGap)),c&&n.add(c),s>=0&&l.frameIdx>s+1&&(e.transitionFramesMissed+=l.frameIdx-s-1),s=l.frameIdx},onBufferTick(){e.bufferTicks+=1},onBufferHit(){e.bufferHits+=1},onBufferUnderrun(){e.bufferUnderruns+=1},onBufferPrefetched(){e.bufferPrefetched+=1},onBufferReset(){},onDrawDisplayed(l,c){if(e.drawsDisplayed+=1,l.transitionMeta){e.transitionFramesDisplayed+=1;const w=l.transitionMeta;u(w.fromVtime),u(w.toVtime),d(l.mouthPath);return}if(l.label.includes("→")){e.transitionFramesDisplayed+=1;return}const m=l.label.trim();if(!(!m||m==="sil")){for(const w of c)if(w.viseme===m&&l.elapsedMs>=w.vtime&&l.elapsedMs<w.vtime+w.vduration){u(w.vtime);break}}},snapshot(l,c){let m=0,w=0;for(const B of l)if(B.viseme!=="sil"){if(B.vtime>=c)break;m+=1,t.has(B.vtime)&&(w+=1)}const T=m>0?Math.round(w/m*100):100,f=e.queueSuperseded+e.workerStale+Math.max(0,e.drawsRequested-e.drawsDisplayed),E=m-w,D=e.bufferTicks>0?Math.round(e.bufferHits/e.bufferTicks*100):100;return{...e,bufferHitRate:D,renderLoss:f,visemeSlotsTotal:m,visemeSlotsCovered:w,visemeCoveragePct:T,transitionFramesUniqueSampled:n.size,transitionFramesUniquePainted:r.size,drawsDeduped:e.rafTicksDeduped,renderSkips:e.rafTicksDeduped+f,visemesShown:w,visemesSkipped:E,rifeTransitionFramesSkipped:e.transitionFramesMissed}}}}const Ji=jn,ho=200,$r=300,go=100,wo=600,Zi="__sil__";function jr(e){return e.lastDrawnKey?e.lastDrawnKey.split("|")[0]===Zi:!1}function ur(){return{lastDrawnKey:""}}function Be(e){e.lastDrawnKey="",e.transitionCache=void 0}function po(e,t){if(t?.transitionCache&&t.transitionCache.queueLength===e.length)return t.transitionCache.transitions;const n=Pi(e);return t&&(t.transitionCache={queueLength:e.length,transitions:n}),n}function yo(e,t){let n="sil";for(const r of e)r.viseme!=="sil"&&(t!=null&&r.vtime>t||(n=r.viseme));return n}function vo(e,t,n,r=120){if(n!=="sil")return n;const i=Oi(e,t,r);return i!=="sil"?i:yo(e,t)}function _o(e,t){return e==="sil"?!1:t?Sa(e,"sil",t):sr(e,"sil").length>0}function bo(){return Ji+wo}function ln(e){return e??Zi}function dr(e,t,n,r,i=go){if(e.length===0)return{diffPath:null,label:"sil"};if(t>=lt(e))return{diffPath:null,label:"sil"};const s=po(e,r),o=na(s,t);if(o){const d=Ci(o.fromVtime,o.toVtime,o.from,o.to);if(t>=d.transStart&&t<d.transEnd){let l=sr(o.from,o.to);n&&(l=ji(l,n));const c=ka(l,d.effectiveGapMs);if(c.length>0){const m=Ea(t,d.transStart,d.transEnd,c.length);return{diffPath:c[m]??c[c.length-1],label:`${o.from}→${o.to}`,transitionMeta:{from:o.from,to:o.to,fromVtime:o.fromVtime,toVtime:o.toVtime,frameIdx:m,frameCount:c.length,fullFrameCount:l.length,omittedByGap:Math.max(0,l.length-c.length)}}}return{diffPath:xt(o.to),label:o.to}}}const a=gn(e);let u=xi(a,t);return u==="sil"&&(u=Oi(e,t,i)),u==="sil"?{diffPath:null,label:"sil"}:{diffPath:xt(u),label:u}}function Ut(e,t){const n=t??ln(e.expressionPath);return`${ln(e.mouthPath)}|${n}`}function Kr(e,t,n,r,i,s,o,a,u,d){const l=dr(t,n,u,s),c={mouthPath:l.diffPath,expressionPath:r},m=Ut(c,i),w=at();if(l.transitionMeta&&w?.onTransitionSample(l.transitionMeta,l.diffPath),m===s.lastDrawnKey){w?.onDrawDeduped();return}w?.onDrawRequested(),a(l),s.lastDrawnKey=m,o(e,c,m,T=>{T===m&&(s.lastDrawnKey=m)})}function Pn(e,t,n,r,i,s,o=null,a=null){const u={mouthPath:a,expressionPath:t},d=o!=null?`|idle@${Math.round(o*1e3)}`:"",l=Ut(u,n)+d;!(o!=null)&&l===r.lastDrawnKey||(s(o!=null?t?"idle · blink":"idle":t?"blink":"sil"),i(e,u,l,m=>{m===l&&(r.lastDrawnKey=l)}))}function es(e,t,n,r,i=Ot,s){if(n<=t||e.length===0)return[];const o=s??ur(),a=[];let u="";for(let d=t;d<n;d+=i){const l=dr(e,d,r,o),c=ln(l.diffPath);c!==u&&(u=c,a.push({displayAtMs:d,mouthPath:l.diffPath,mouthKey:c,label:l.label}))}return a}const So=3;function fr(e){let t=0;const n=[];let r=!1,i=!1;const s=async()=>{if(!r){r=!0;try{for(;n.length>0;){const a=n.shift(),u=++t;await e(a.diffs,u,a)&&u===t&&a.onDisplayed?.(a.drawKey)}}finally{r=!1,n.length>0&&s()}}},o=()=>{i||(i=!0,queueMicrotask(()=>{i=!1,s()}))};return{enqueue(a,u,d){const l=n.findIndex(c=>c.drawKey===u);l>=0?n[l]={diffs:a,drawKey:u,onDisplayed:d}:(n.length>=So&&(n.shift(),at()?.onQueueSuperseded()),n.push({diffs:a,drawKey:u,onDisplayed:d})),o()},reset(){t+=1,n.length=0},isLatestSeq(a){return a===t},getLatestSeq(){return t}}}function To(e,t=2){const n=[],r=new Set;let i=0,s=!1,o=0;const a=(d,l)=>`${d}|${l}`,u=async()=>{if(!s){s=!0;try{for(;i<t&&n.length>0;){const d=n.shift(),l=a(d.displayAtMs,d.drawKey);if(r.has(l))continue;r.add(l),i+=1;const c=o;try{await e(d)}finally{if(r.delete(l),i-=1,c!==o)return}}}finally{s=!1,n.length>0&&i<t&&u()}}};return{enqueue(d){const l=a(d.displayAtMs,d.drawKey);r.has(l)||n.some(c=>a(c.displayAtMs,c.drawKey)===l)||(n.push(d),u())},isQueuedOrInflight(d,l){const c=a(d,l);return r.has(c)?!0:n.some(m=>a(m.displayAtMs,m.drawKey)===c)},reset(){o+=1,n.length=0,r.clear(),i=0},pendingCount(){return n.length+i}}}function ko(){const e=new Map,t=n=>{n.bitmap.close()};return{has(n,r){return e.has(r)},markRendered(n,r,i,s,o){const a=e.get(r);a&&t(a),e.set(r,{displayAtMs:n,mouthKey:r,label:i,mouthPath:s,bitmap:o})},findForMouthKey(n){return e.get(n)??null},removeThrough(n){},pruneBefore(n){},reset(){for(const n of e.values())t(n);e.clear()},size(){return e.size}}}function Eo(e,t,n,r,i,s){const o=es(t,n,r,i,Ot,s);if(o.length===0)return{ready:0,total:0};let a=0;for(const u of o)e.has(u.displayAtMs,u.mouthKey)&&(a+=1);return{ready:a,total:o.length}}function xo(e){const t=ko(),n=ur(),r=new Set;let i="",s=null;const o=To(async c=>{try{if(!e.supportsBufferedPlayback)return;const m=await e.compositePrefetchFrame(c.diffs,c.mouthKey);if(!m)return;t.markRendered(c.displayAtMs,c.mouthKey,c.label,c.mouthPath,m),at()?.onBufferPrefetched()}finally{r.delete(c.mouthKey)}},_s),a=c=>{for(const m of c)t.has(m.displayAtMs,m.mouthKey)||r.has(m.mouthKey)||o.isQueuedOrInflight(0,m.mouthKey)||(r.add(m.mouthKey),o.enqueue({...m,displayAtMs:0,drawKey:m.mouthKey,diffs:{mouthPath:m.mouthPath,expressionPath:null}}))},u=(c,m,w,T=In)=>{if(!e.supportsBufferedPlayback)return;const f=Math.max(0,m-Ot*4),E=es(c,f,m+T,w,Ot,n);a(E)},d=(c,m)=>{i=c,s=m},l=(c,m)=>!(i!==c||s!==m);return{reset(){t.reset(),o.reset(),r.clear(),Be(n),i="",s=null,at()?.onBufferReset()},markExternallyDisplayed(c,m){d(c.split("|")[0]??c,m)},warmupTick(c){e.supportsBufferedPlayback&&u(c.queue,0,c.availablePaths,Math.max(Er,In))},isWarmupReady(c,m=Er){if(!e.supportsBufferedPlayback)return!0;const{ready:w,total:T}=Eo(t,c.queue,0,m,c.availablePaths,n);return T===0?!1:w/T>=vs},getBufferedFrameCount:()=>t.size(),tick(c){const m=at();m?.onBufferTick(),u(c.queue,c.elapsedMs,c.availablePaths),t.pruneBefore(c.elapsedMs-In);const w=dr(c.queue,c.elapsedMs,c.availablePaths,n),T=ln(w.diffPath),f=Ut({mouthPath:w.diffPath,expressionPath:c.expressionPath},c.expressionDrawKey),E=()=>(d(T,c.expressionPath),m?.onBufferHit(),{usedBuffer:!0,underrun:!1,held:!0});if(l(T,c.expressionPath)||c.playbackState.lastDrawnKey===f)return E();const D=t.findForMouthKey(T,c.elapsedMs,Ot);return D&&c.expressionPath!=null?(m?.onBufferHit(),{usedBuffer:!1,underrun:!1,held:!1}):D?(e.blitBitmap(c.canvas,D.bitmap),d(D.mouthKey,c.expressionPath),c.playbackState.lastDrawnKey=f,c.onStatus({diffPath:D.mouthPath,label:D.label}),c.onDisplayed(f,D.mouthPath,D.label),m?.onBufferHit(),{usedBuffer:!0,underrun:!1,held:!1}):(m?.onBufferUnderrun(),{usedBuffer:!1,underrun:!0,held:!1})}}}const Io=`
|
|
5
|
+
`);Ie=Ue.pop()??"";for(const Re of Ue)await Ke(Re);if(rt){Ie.trim()&&await Ke(Ie.trim()),Te===U&&!ce.signal.aborted&&A&&z.markStreamComplete(n);break}}}catch(Be){if(ce.signal.aborted||!A)return;console.error("[realtimeVoice] avatar_speak failed:",Be),e("error"),H()}finally{I===ce&&(I=null)}},he=g=>{const P=ha(g);if(!P){console.warn("[realtimeVoice] server message with no payload",g);return}const ne=String(P.type??"unknown");switch(ne!=="avatar_metadata"&&ne!=="avatar_audio_chunk"&&ne!=="avatar_lipsync"&&ne!=="avatar_interrupt"&&ne!=="error"&&console.debug("[realtimeVoice] server message",ne,P),ne){case"avatar_metadata":x(P);break;case"avatar_audio_chunk":T(P);break;case"avatar_lipsync":Q(P);break;case"avatar_interrupt":re(P);break;case"error":{const ce=String(P.message??"Voice session error");console.error("[realtimeVoice] server error:",ce),e("error"),H();break}case"avatar_speak":V(P);break}},De=()=>w||(S=new da,w=new ds.PipecatClient({transport:new Hn.WebSocketTransport({mediaManager:S,serializer:new ua,recorderSampleRate:rr,playerSampleRate:ir}),enableCam:!1,enableMic:!0,callbacks:{onBotReady:()=>{m=!0,e("idle"),H()},onDisconnected:()=>{m=!1,p()},onError:g=>{const P=typeof g=="object"&&g!==null&&"data"in g?String(g.data??g):String(g);console.error("[realtimeVoice]",P,g),e("error"),H()},onTransportStateChanged:g=>{g==="error"&&(e("error"),H())},onServerMessage:g=>{j(g)},onUserStartedSpeaking:()=>{},onBotStartedSpeaking:()=>{_(),ue("bot_started")},onBotStoppedSpeaking:()=>{A&&Z()},onUserTranscript:g=>{String(g.text??""),f.onUserTranscript?.(g.text,!!g.final)},onBotOutput:g=>{f.onBotOutput?.(g.text)}}}),w);return{setDeveloperToken:g=>{},setTtsEngineId:g=>{c=g,z.setStreamTtsEngineId(g)},getTtsEngineId:()=>c,speak:async(g,P)=>{const ne=g.trim();if(ne){if(!w||!m)throw new Error("Realtime voice is not connected. Call connect() first.");Y(),await w.sendText(ne)}},stop:()=>{I?.abort(),I=null,U+=1,_(),Y(),e("idle"),H()},connect:async g=>{g&&(f={...f,...g});const P=et(f.ttsEngineId,f.voiceId);if(P.ttsEngineId&&(c=P.ttsEngineId,z.setStreamTtsEngineId(c)),f={...f,ttsEngineId:c,...P.voiceId?{voiceId:P.voiceId}:{}},!f.authToken?.trim())throw new Error("Voice connect requires authToken (same JWT as SSE Authorization Bearer).");e("loading");const ne=De();await ne.initDevices();const ce=Ui({...f,ttsEngineId:c});console.info("[realtimeVoice] connecting (avatar_audio_chunk RTVI):",ce);try{await ne.connect({wsUrl:ce})}catch(Te){m=!1,e("error"),H();const be=Te instanceof Error?Te.message:"Realtime voice connect failed (WebSocket 101 only means upgrade OK — check authToken/origin/RTVI handshake)";throw new Error(`${be} — ${ce}`)}m=!0,e("idle"),H()},disconnect:async()=>{if(L(),q=!1,oe=!1,v.length=0,k=!1,I?.abort(),I=null,U+=1,_(),w)try{await w.disconnect()}catch(g){console.error("[realtimeVoice] disconnect failed:",g)}m=!1,p()},isConnected:()=>m,unlockAudio:async()=>{await z.primeAudioContext()},getVisemeQueue:()=>n,getWordQueue:()=>r,getFullVisemeQueue:()=>i,getFullWordQueue:()=>s,getSentenceEmotions:()=>a,getStreamMood:()=>l,getPlaybackElapsedMs:J,isSpeaking:()=>z.isSpeaking(),isWarmingUp:()=>z.isWarmingUp(),releaseWarmupHold:()=>z.releaseWarmupHold(),setLipsyncWarmupHold:(g,P)=>{P&&(me=P),z.setLipsyncWarmupHoldEnabled(g)},getVoiceStream:()=>z.getVoiceStream(),setPlaybackSpeed:g=>{z.setPlaybackSpeed(g)},getPlaybackSpeed:()=>z.getPlaybackSpeed(),subscribe:g=>(B.add(g),()=>B.delete(g))}}function Wi(e,t,n){return{width:e.crop?.source_width??t,height:e.crop?.source_height??n}}function zi(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 Hi(e){return e?(e.w??0)>0&&(e.h??0)>0:!1}async function Pt(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 Fs(r,t)}async function $i(e,t){if(!t)throw new Error("Missing asset key for encrypted JSON");const n=await Pt(e,t),r=new TextDecoder().decode(n);return JSON.parse(r)}async function wa(e){const t=new Blob([e],{type:"image/webp"});return createImageBitmap(t)}async function pa(e){const t=new Blob([e],{type:"image/webp"}),n=URL.createObjectURL(t);return new Promise((r,i)=>{const s=new Image;s.decoding="async",s.onload=()=>{URL.revokeObjectURL(n),r(s)},s.onerror=()=>{URL.revokeObjectURL(n),i(new Error("Failed to decode decrypted image"))},s.src=n})}async function ya(e){const t=new Blob([e],{type:"image/png"});return createImageBitmap(t)}async function va(e){const t=new Blob([e],{type:"image/png"}),n=URL.createObjectURL(t);return new Promise((r,i)=>{const s=new Image;s.decoding="async",s.onload=()=>{URL.revokeObjectURL(n),r(s)},s.onerror=()=>{URL.revokeObjectURL(n),i(new Error("Failed to decode decrypted PNG"))},s.src=n})}function _a(e){const t=new Blob([e],{type:"video/mp4"});return URL.createObjectURL(t)}async function ba(e){const t=Os();if(!Wt())return t;if(!e)throw new Error("Missing asset key for encrypted idle video");const n=await Pt(t,e);return _a(n)}function Et(e,t){return`${e}/${t}_minus_sil.png`}const ji=5;function vn(e){const t=e?.composite_threshold;if(typeof t=="number"&&t>0)return t;const n=e?.crop?.content_threshold;return typeof n=="number"&&n>0?n:ji}const Sa=["aa","E","I","O","U","PP","FF","DD","SS","TH","CH","RR","kk","nn"],Un=["t01_0.25","t02_0.50","t03_0.75"],Ta=Un.length,Br=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 Fr(e,t){return`${e}__${t}`}function Lr(e,t){return`pairs/${e}/${t}_minus_sil.png`}function It(e){return`${e}_minus_sil.png`}function sr(e,t){if(t.has(e))return e;const n=/^pairs\/([^/]+)\//.exec(e);if(!n)return null;const r=n[1].split("__")[1];if(!r||r==="sil")return null;const i=It(r);return t.has(i)?i:null}function Ki(e,t){return e.filter(n=>t.has(n))}function ka(e,t,n){const r=ar(e,t);return Ki(r,n).length>0}function ar(e,t){if(e===t)return[];const n=[],r=Fr(e,t);if(Br.has(r)){for(const s of Un)n.push(Lr(r,s));return n}const i=Fr(t,e);if(Br.has(i)){for(let s=Ta-1;s>=0;s--)n.push(Lr(i,Un[s]));return n}return[]}function Ea(e){return e<16?[1]:e<24?[1]:e<35?[0,1,2]:[0,1,2]}function xa(e,t){return Ea(t).map(r=>e[r]).filter(r=>r!=null)}function Ia(e,t,n,r){if(r<=0)return 0;const s=Math.max(1,n-t)/r,o=e-t,a=Math.floor(o/s);return Math.min(r-1,Math.max(0,a))}function Gi(e,t,n){if(!n)return`${e}/${t}`;const r=t.split("/").pop()??t,i=r.includes(".")?r.slice(0,r.lastIndexOf(".")):r;return`${e}/${i}.bin`}const Aa=[.32,.24,.16,.08,0],Ma=Aa.map(e=>`eyes_${e.toFixed(2)}`),Pa=["eyes_0.32","eyes_0.16","eyes_0.00"],Ra=["eyes_0.32","eyes_0.16","eyes_0.08","eyes_0.00"],He=2,Ca=-20,an=16,qi={fear:-20,anger:-20,sad:-10,neutral:0,love:0,happy:0,disgust:10};function Ut(e){return`brow_${e}`}function ht(e){return qi[e]}function Xe(e){return Math.max(Ca,Math.min(an,e))}function Da(e,t){if(e===t)return[];const n=e<t,r=n?He:-He,i=[];let s=e;if(s%He!==0){const o=n?Math.ceil(s/He)*He:Math.floor(s/He)*He,a=Xe(o);if(n?a>=t:a<=t)return[t];s=a,i.push(s)}for(;;){const o=s+r;if(n?o>=t:o<=t){t!==s&&i.push(t);break}s=o,i.push(s)}return i}function Or(e){const t=Xe(e);if(t%He===0)return[t];const n=Math.floor(t/He)*He,r=Math.min(an,n+He),i=Xe(n);return t-i<=r-t?i===r?[i]:[i,r]:i===r?[r]:[r,i]}const Ba=["fear","anger","sad","neutral","love","happy","disgust"],Fa={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 Ze(e,t="neutral"){const n=String(e??"").trim().toLowerCase();return n?Fa[n]??t:t}function Yi(e){return e===0?null:Et(Ut(e),"eyes_standard")}function Qi(e){return Yi(ht(e))}const La={[-20]:"anger",[-10]:"sad",0:"neutral",10:"disgust"};function or(e,t){if(!e)return null;if(t(e))return e;const n=e.match(/^brow_(-?\d+)\/(eyes_[^/]+)_minus_sil\.png$/);if(n){const i=Number(n[1]),s=n[2];for(const a of Or(i)){if(a===i)continue;const u=Et(Ut(a),s);if(t(u))return u}const o=La[i];if(o){const a=Et(o,s);if(t(a))return a}return null}const r=e.match(/^(fear|anger|sad|neutral|love|happy|disgust)\/(eyes_[^/]+)_minus_sil\.png$/);if(r){const i=r[1],s=r[2],o=ht(i);for(const a of[o,...Or(o)]){const u=Et(Ut(a),s);if(t(u))return u}}return null}function Nr(e,t){const n=Ut(ht(e));return!t||t==="eyes_standard"?Qi(e):e==="neutral"&&t==="eyes_standard"?null:Et(n,t)}function Oa(e,t){const n=[];for(const r of t)n.push(Nr(e,r));for(let r=t.length-2;r>=0;r--)n.push(Nr(e,t[r]));return n.push(Qi(e)),n}function Na(e){return Et(Ut(e),"eyes_standard")}function Ua(e,t){return Da(e,t).map(Na)}const Va=6;function Wa(e,t){for(const n of e)if(t>=n.wtime&&t<n.wtime+n.wduration)return n;return null}function za(e){const t=Xe(e);return t>=an?an:Xe(t+Va)}function Ha(e,t,n){const r=Xe(n);return Wa(t,e)?.emphasis?za(r):r}function Ur(e){if(!e)return 0;const t=e.match(/^brow_(-?\d+)\//);if(!t?.[1])return null;const n=Number.parseInt(t[1],10);return Number.isFinite(n)?Xe(n):null}function Qe(e,t){return e+Math.random()*(t-e)}function Vr(){return Qe(14,32)}function $a(e){if(e)return{holdMinMs:10,holdMaxMs:18,closedExtraMs:0};const t=Math.random();return t<.18?{holdMinMs:38,holdMaxMs:62,closedExtraMs:Qe(40,90)}:t<.42?{holdMinMs:26,holdMaxMs:44,closedExtraMs:Qe(12,36)}:t<.82?{holdMinMs:14,holdMaxMs:28,closedExtraMs:Math.random()<.35?Qe(8,22):0}:{holdMinMs:10,holdMaxMs:18,closedExtraMs:0}}function Wr(e,t){const n=Qe(e.holdMinMs,e.holdMaxMs);return t?n+e.closedExtraMs:n}function ja(e={}){const{initialDelayMs:t=800+Math.random()*1200,intervalMinMs:n=2200,intervalMaxMs:r=5800,doubleBlinkChance:i=.18,doubleBlinkGapMinMs:s=120,doubleBlinkGapMaxMs:o=220,fullBlinkChance:a=.75,postEmotionChangeDelayMs:u=380,minDwellMs:d=550}=e;let l="neutral",c="neutral",m=0,w=0,S=0,f={kind:"idle",nextBlinkAt:performance.now()+t},E=null,D="__eyes_open__|neutral|brow:0";function B(I=l){D=`${E??"__eyes_open__"}|${I}|brow:${w}`}function v(I,U=l){E=I;const q=Ur(I);q!=null?w=q:I==null&&(w=0),B(U)}function k(I){return Yi(I)}function O(I,U,q){const oe=Xe(U),ae=Xe(q);if(m=ae,oe===ae){v(k(ae));return}const ie=[...Ua(oe,ae),k(ae)];f={kind:"browBlend",paths:ie,index:0,holdUntil:I+Vr(),targetBrow:ae},v(ie[0]??null)}function A(I,U){f={kind:"idle",nextBlinkAt:I+Qe(n,r)},c=U,v(k(m),U)}function se(I,U,q){const oe=q?Pa:Math.random()<a?Ma:Ra,ae=$a(q),ie=oe.length-1;f={kind:"playing",paths:Oa(U,oe),index:0,holdUntil:I+Wr(ae,ie===0),after:"idle",blinkEmotion:U,pace:ae,closedFrameIndex:ie},c=U,v(f.paths[0]??null,U)}function le(I){if(f.kind==="browBlend"){for(;I>=f.holdUntil&&f.index<f.paths.length-1;)f.index+=1,f.holdUntil=I+Vr();const U=f.paths[f.index]??null;v(U),I>=f.holdUntil&&f.index>=f.paths.length-1&&(w=f.targetBrow,m=f.targetBrow,v(k(f.targetBrow)),f={kind:"idle",nextBlinkAt:I+u});return}if(f.kind==="idle"){v(k(m),c),I>=f.nextBlinkAt&&se(I,c,!1);return}if(f.kind==="doublePause"){v(k(m),f.blinkEmotion),I>=f.resumeAt&&se(I,f.blinkEmotion,!0);return}if(f.kind==="playing"){for(;I>=f.holdUntil&&f.index<f.paths.length-1;)f.index+=1,f.holdUntil=I+Wr(f.pace,f.index===f.closedFrameIndex);if(v(f.paths[f.index]??null,f.blinkEmotion),I>=f.holdUntil&&f.index>=f.paths.length-1){if(f.after==="resumeIdle"){A(I+u,l);return}if(f.after==="doublePause"){f={kind:"doublePause",resumeAt:I+Qe(s,o),blinkEmotion:f.blinkEmotion},v(k(m),f.blinkEmotion);return}if(f.after==="idle"&&Math.random()<i){f={kind:"doublePause",resumeAt:I+Qe(s,o),blinkEmotion:f.blinkEmotion},v(k(m),f.blinkEmotion);return}A(I,f.blinkEmotion)}}}return{advance:le,setTargetEmotion(I,U){const q=Ze(I,l);if(q===l)return;const oe=performance.now();!U?.force&&d>0&&!(l==="neutral"&&q!=="neutral")&&oe-S<d||(l=q,c=q,S=oe)},setTargetEyebrow(I){const U=Xe(I);if(U===m)return;const q=performance.now(),oe=f.kind==="browBlend"?Ur(E)??w:w;m=U,!(U===oe&&f.kind!=="browBlend")&&(f.kind==="playing"||f.kind==="doublePause"||O(q,oe,U))},snapToEmotion(I){const U=Ze(I),q=ht(U);l=U,c=U,m=q,w=q,S=performance.now(),f={kind:"idle",nextBlinkAt:performance.now()+Qe(4e3,7e3)},v(k(q),U)},getTargetEmotion:()=>l,getTargetEyebrow:()=>m,getExpressionPath:()=>E,getDrawKey:()=>D,reset(){l="neutral",c="neutral",m=0,w=0,S=0,A(performance.now()+Qe(n,r),"neutral")}}}function Ka(){const e=document.createElement("video");e.muted=!0,e.playsInline=!0,e.preload="auto",e.setAttribute("playsinline",""),e.loop=!0;let t=!1,n=null,r="";const i=()=>{n&&(URL.revokeObjectURL(n),n=null)};return{async load(s){t&&r===s||(i(),t=!1,r=s,s.startsWith("blob:")&&(n=s),await new Promise((o,a)=>{const u=()=>{const d=e.duration;if(!Number.isFinite(d)||d<=0){a(new Error(`Idle video has invalid duration: ${s}`));return}t=!0,e.currentTime=0,o()};e.addEventListener("loadeddata",u,{once:!0}),e.addEventListener("error",()=>a(new Error(`Failed to load idle video: ${s}`)),{once:!0}),e.src=s,e.load()}))},isReady(){return t},getVideo(){return e},setActive(s){t&&(s?e.paused&&e.play().catch(()=>{}):e.paused||e.pause())},restart(){t&&(e.currentTime=0)},dispose(){e.pause(),e.removeAttribute("src"),e.load(),i(),t=!1,r=""}}}const Ga=50,Xi=400;function qa(e,t,n){return e.filter(r=>{const i=r.queueIndex??-1;return i>=t&&i<=n})}function Ya(e,t){const n=[];for(const r of e){const i=qa(t,r.start_word,r.end_word);if(i.length===0)continue;const s=i[0],o=i[i.length-1];n.push({sentence:r,startMs:Math.max(0,s.wtime-Ga),endMs:o.wtime+o.wduration+Xi})}return n.sort((r,i)=>r.startMs-i.startMs)}function Qa(e,t,n,r="neutral"){const i=Ze(r);if(t.length===0)return i;if(n.length===0||e<n[0].wtime)return Ze(t[0]?.emotion,i);const s=Ya(t,n);let o=null;for(const d of s)e>=d.startMs&&e<=d.endMs&&(o=d);if(o)return Ze(o.sentence.emotion,i);const a=n[n.length-1],u=a.wtime+a.wduration;return e>u+Xi?Ze(t[t.length-1]?.emotion,i):i}function cr(e,t,n,r,i=ji){const s=new OffscreenCanvas(n,r),o=s.getContext("2d",{willReadFrequently:!0});o.drawImage(e,0,0,n,r);const a=o.getImageData(0,0,n,r),u=o.createImageData(n,r);u.data.set(a.data);const l=new OffscreenCanvas(n,r).getContext("2d",{willReadFrequently:!0});for(const c of t){l.clearRect(0,0,n,r),l.drawImage(c,0,0,n,r);const m=l.getImageData(0,0,n,r);for(let w=0;w<u.data.length;w+=4){const S=m.data[w],f=m.data[w+1],E=m.data[w+2];Math.max(S,f,E)>i&&(u.data[w]=S,u.data[w+1]=f,u.data[w+2]=E,u.data[w+3]=255)}}return o.putImageData(u,0,0),s}let dt=null,At=null;const on=new Map;function Xa(){dt=null,At=null,on.clear()}mi(Xa);function Ja(e){return e??At??void 0}function lr(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 Za(e){return Wt()?va(await Pt(sn(),e??"")):lr(sn())}async function zr(e,t,n,r){const i=n?await $i(e,r):await fetch(e).then(d=>{if(!d.ok)throw new Error(`Failed to load ${e}`);return d.json()}),s=i.sheets?.[0];if(!s?.path)throw new Error(`${e} has no sheets[0].path`);const o=n?await pa(await Pt(Gi(t,s.path,n),r??"")):await lr(`${t}/${s.path}`),a=new Map;for(const d of i.cells??[])d.path&&a.set(d.path,d);const u=new Map;for(const d of i.sheets??[])u.set(d.index,d);return{atlas:o,atlasMeta:i,cellByPath:a,sheetByIndex:u,diffBase:t}}async function Vn(e){const t=Ja(e),n=Wt();if(n&&!t)throw new Error("Encrypted assets enabled but no key provided");if(dt&&(!n||At===(t??null))){const s=await dt;return{...Mt(s),visemePaths:[...s.viseme.cellByPath.keys()]}}At=t??null,on.clear();const r=hi();dt=(async()=>{const s=await Za(t),o=await zr(gi(),r,n,t);let a=null;try{a=await zr(wi(),r,n,t)}catch{a=null}return{sil:s,viseme:o,expression:a}})();const i=await dt;return{...Mt(i),visemePaths:[...i.viseme.cellByPath.keys()]}}async function ur(e){if(await Vn(e),!dt)throw new Error("Assets not loaded");return dt}function Mt(e){return Wi(e.viseme.atlasMeta,e.sil.naturalWidth,e.sil.naturalHeight)}function eo(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 cn(e,t,n){const r=`${t.diffBase}::${n}`,i=on.get(r);if(i)return i;const s=(async()=>{const o=t.cellByPath.get(n);if(!o)throw new Error(`No atlas cell for path: ${n}`);const a=zi(t.atlasMeta,o),u=Mt(e);if(Hi(o)){const c=eo(t,o),m=document.createElement("canvas");m.width=u.width,m.height=u.height;const w=m.getContext("2d");return w.fillStyle="#000",w.fillRect(0,0,u.width,u.height),w.drawImage(c,a.x,a.y),m}const d=`${t.diffBase}/${n}`,l=await lr(d);if(l.naturalWidth===u.width&&l.naturalHeight===u.height)return l;throw new Error(`Diff PNG wrong size for ${n}`)})();return on.set(r,s),s}async function Mn(e,t,n,r,i,s){if(i){const{width:w,height:S}=i;if(s&&!s()||t.readyState<HTMLMediaElement.HAVE_CURRENT_DATA)return;const f=document.createElement("canvas");f.width=w,f.height=S;const E=f.getContext("2d");if(E.clearRect(0,0,w,S),E.drawImage(t,0,0,w,S),s&&!s())return;(e.width!==w||e.height!==S)&&(e.width=w,e.height=S);const D=e.getContext("2d");D.clearRect(0,0,w,S),D.drawImage(f,0,0);return}const o=await ur(),a=vn(o.viseme.atlasMeta),{width:u,height:d}=Mt(o);(e.width!==u||e.height!==d)&&(e.width=u,e.height=d);const l=[],c=e.getContext("2d");if(c.clearRect(0,0,u,d),t.readyState<HTMLMediaElement.HAVE_CURRENT_DATA){const w=o.sil;c.drawImage(w,0,0,u,d);return}if(l.length===0){c.drawImage(t,0,0,u,d);return}const m=cr(t,l,u,d,a);c.drawImage(m,0,0)}async function Wn(e,t,n){const r=await ur(At??void 0),i=vn(r.viseme.atlasMeta),{width:s,height:o}=Mt(r);(e.width!==s||e.height!==o)&&(e.width=s,e.height=o);const a=[];if(t.mouthPath){const l=new Set(r.viseme.cellByPath.keys()),c=sr(t.mouthPath,l)??(l.has(t.mouthPath)?t.mouthPath:null);c&&a.push(await cn(r,r.viseme,c))}if(t.expressionPath&&r.expression){const l=or(t.expressionPath,c=>r.expression.cellByPath.has(c));l&&a.push(await cn(r,r.expression,l))}const u=e.getContext("2d");if(u.clearRect(0,0,s,o),a.length===0){u.drawImage(r.sil,0,0,s,o);return}const d=cr(r.sil,a,s,o,i);u.drawImage(d,0,0)}async function to(e,t){const n=await ur(At??void 0),r=vn(n.viseme.atlasMeta),{width:i,height:s}=Mt(n),o=[];if(e.mouthPath){const l=new Set(n.viseme.cellByPath.keys()),c=sr(e.mouthPath,l)??(l.has(e.mouthPath)?e.mouthPath:null);c&&o.push(await cn(n,n.viseme,c))}if(e.expressionPath&&n.expression){const l=or(e.expressionPath,c=>n.expression.cellByPath.has(c));l&&o.push(await cn(n,n.expression,l))}const a=new OffscreenCanvas(i,s),u=a.getContext("2d");if(o.length===0)return u.drawImage(n.sil,0,0,i,s),a.transferToImageBitmap();const d=cr(n.sil,o,i,s,r);return u.drawImage(d,0,0),a.transferToImageBitmap()}async function no(e){await Wn(e,{mouthPath:null,expressionPath:null})}const en={fontFamily:"system-ui, -apple-system, sans-serif",fontSize:"clamp(0.875rem, 2.5vw, 1.125rem)",color:"rgba(255,255,255,0.85)"};function ro(e){return e.length===0?"":e.map(t=>t.word).join(" ")}function io(e){if(!e)return{enabled:!1,style:en};const t=e===!0?{}:e;return{enabled:!0,style:{fontFamily:t.fontFamily??en.fontFamily,fontSize:t.fontSize??en.fontSize,color:t.color??en.color}}}const so={position:"absolute",bottom:0,left:0,right:0,display:"flex",justifyContent:"center",padding:"0.75rem 1rem",pointerEvents:"none"},ao={display:"inline-block",maxWidth:"100%",padding:"0.45rem 0.85rem",borderRadius:"0.75rem",background:"rgba(0,0,0,0.55)",lineHeight:1.4,textAlign:"center"},oo={display:"-webkit-box",WebkitLineClamp:2,WebkitBoxOrient:"vertical",overflow:"hidden",maxWidth:"100%",margin:0};function co({text:e,style:t}){return R.jsx("div",{style:so,"aria-live":"polite","aria-atomic":"true",children:R.jsx("div",{style:{...ao,fontFamily:t.fontFamily,fontSize:t.fontSize,color:t.color},children:R.jsx("p",{style:oo,children:e})})})}const lo={inset:0,overflow:"hidden",pointerEvents:"none",position:"absolute",zIndex:3},uo={filter:"blur(22px)",height:"100%",inset:0,objectFit:"cover",objectPosition:"top",position:"absolute",transform:"scale(1.08)",width:"100%"},fo={backdropFilter:"blur(10px)",WebkitBackdropFilter:"blur(10px)",inset:0,position:"absolute"};function mo({thumbnailUrl:e}){const[t,n]=h.useState(!1);h.useEffect(()=>{n(!1)},[e]);const r=!!e&&t;return R.jsxs("div",{style:lo,"aria-hidden":!0,children:[e?R.jsx("img",{src:e,alt:"",style:{...uo,opacity:r?1:0,transition:"opacity 0.45s ease"},onLoad:()=>n(!0),onError:()=>n(!1)}):null,R.jsx("div",{style:{...fo,background:r?"rgba(0, 0, 0, 0.28)":"rgba(10, 10, 11, 0.92)"}})]})}let Ji=null;function Hr(e){Ji=e}function at(){return Ji}function ho(e){return`${e.from}→${e.to}@${e.fromVtime}`}function $r(){return{rafTicksSpeaking:0,rafTicksDeduped:0,drawsRequested:0,drawsDisplayed:0,queueSuperseded:0,workerStale:0,rifeFramesOmittedByGap:0,transitionFramesSampled:0,transitionFramesDisplayed:0,transitionFramesMissed:0,bufferTicks:0,bufferHits:0,bufferUnderruns:0,bufferPrefetched:0}}function go(){let e=$r();const t=new Set,n=new Set,r=new Set;let i="",s=-1,o="";const a=()=>{e=$r(),t.clear(),n.clear(),r.clear(),i="",s=-1,o=""},u=l=>{t.add(l)},d=l=>{l&&r.add(l)};return{reset:a,onRafTickSpeaking(){e.rafTicksSpeaking+=1},onDrawDeduped(){e.rafTicksDeduped+=1},onDrawRequested(){e.drawsRequested+=1},onQueueSuperseded(){e.queueSuperseded+=1},onWorkerStale(){e.workerStale+=1},onTransitionSample(l,c){const m=ho(l);e.transitionFramesSampled+=1,m!==i&&(i=m,s=-1,o!==m&&(o=m,e.rifeFramesOmittedByGap+=l.omittedByGap)),c&&n.add(c),s>=0&&l.frameIdx>s+1&&(e.transitionFramesMissed+=l.frameIdx-s-1),s=l.frameIdx},onBufferTick(){e.bufferTicks+=1},onBufferHit(){e.bufferHits+=1},onBufferUnderrun(){e.bufferUnderruns+=1},onBufferPrefetched(){e.bufferPrefetched+=1},onBufferReset(){},onDrawDisplayed(l,c){if(e.drawsDisplayed+=1,l.transitionMeta){e.transitionFramesDisplayed+=1;const w=l.transitionMeta;u(w.fromVtime),u(w.toVtime),d(l.mouthPath);return}if(l.label.includes("→")){e.transitionFramesDisplayed+=1;return}const m=l.label.trim();if(!(!m||m==="sil")){for(const w of c)if(w.viseme===m&&l.elapsedMs>=w.vtime&&l.elapsedMs<w.vtime+w.vduration){u(w.vtime);break}}},snapshot(l,c){let m=0,w=0;for(const B of l)if(B.viseme!=="sil"){if(B.vtime>=c)break;m+=1,t.has(B.vtime)&&(w+=1)}const S=m>0?Math.round(w/m*100):100,f=e.queueSuperseded+e.workerStale+Math.max(0,e.drawsRequested-e.drawsDisplayed),E=m-w,D=e.bufferTicks>0?Math.round(e.bufferHits/e.bufferTicks*100):100;return{...e,bufferHitRate:D,renderLoss:f,visemeSlotsTotal:m,visemeSlotsCovered:w,visemeCoveragePct:S,transitionFramesUniqueSampled:n.size,transitionFramesUniquePainted:r.size,drawsDeduped:e.rafTicksDeduped,renderSkips:e.rafTicksDeduped+f,visemesShown:w,visemesSkipped:E,rifeTransitionFramesSkipped:e.transitionFramesMissed}}}}const Zi=jn,wo=200,jr=300,po=100,yo=600,es="__sil__";function Kr(e){return e.lastDrawnKey?e.lastDrawnKey.split("|")[0]===es:!1}function dr(){return{lastDrawnKey:""}}function Oe(e){e.lastDrawnKey="",e.transitionCache=void 0}function vo(e,t){if(t?.transitionCache&&t.transitionCache.queueLength===e.length)return t.transitionCache.transitions;const n=Ri(e);return t&&(t.transitionCache={queueLength:e.length,transitions:n}),n}function _o(e,t){let n="sil";for(const r of e)r.viseme!=="sil"&&(t!=null&&r.vtime>t||(n=r.viseme));return n}function bo(e,t,n,r=120){if(n!=="sil")return n;const i=Ni(e,t,r);return i!=="sil"?i:_o(e,t)}function So(e,t){return e==="sil"?!1:t?ka(e,"sil",t):ar(e,"sil").length>0}function To(){return Zi+yo}function ln(e){return e??es}function fr(e,t,n,r,i=po){if(e.length===0)return{diffPath:null,label:"sil"};if(t>=ut(e))return{diffPath:null,label:"sil"};const s=vo(e,r),o=ia(s,t);if(o){const d=Ci(o.fromVtime,o.toVtime,o.from,o.to);if(t>=d.transStart&&t<d.transEnd){let l=ar(o.from,o.to);n&&(l=Ki(l,n));const c=xa(l,d.effectiveGapMs);if(c.length>0){const m=Ia(t,d.transStart,d.transEnd,c.length);return{diffPath:c[m]??c[c.length-1],label:`${o.from}→${o.to}`,transitionMeta:{from:o.from,to:o.to,fromVtime:o.fromVtime,toVtime:o.toVtime,frameIdx:m,frameCount:c.length,fullFrameCount:l.length,omittedByGap:Math.max(0,l.length-c.length)}}}return{diffPath:It(o.to),label:o.to}}}const a=gn(e);let u=Ii(a,t);return u==="sil"&&(u=Ni(e,t,i)),u==="sil"?{diffPath:null,label:"sil"}:{diffPath:It(u),label:u}}function Vt(e,t){const n=t??ln(e.expressionPath);return`${ln(e.mouthPath)}|${n}`}function Gr(e,t,n,r,i,s,o,a,u,d){const l=fr(t,n,u,s),c={mouthPath:l.diffPath,expressionPath:r},m=Vt(c,i),w=at();if(l.transitionMeta&&w?.onTransitionSample(l.transitionMeta,l.diffPath),m===s.lastDrawnKey){w?.onDrawDeduped();return}w?.onDrawRequested(),a(l),s.lastDrawnKey=m,o(e,c,m,S=>{S===m&&(s.lastDrawnKey=m)})}function Pn(e,t,n,r,i,s,o=null,a=null){const u={mouthPath:a,expressionPath:t},d=o!=null?`|idle@${Math.round(o*1e3)}`:"",l=Vt(u,n)+d;!(o!=null)&&l===r.lastDrawnKey||(s(o!=null?t?"idle · blink":"idle":t?"blink":"sil"),i(e,u,l,m=>{m===l&&(r.lastDrawnKey=l)}))}function ts(e,t,n,r,i=Ot,s){if(n<=t||e.length===0)return[];const o=s??dr(),a=[];let u="";for(let d=t;d<n;d+=i){const l=fr(e,d,r,o),c=ln(l.diffPath);c!==u&&(u=c,a.push({displayAtMs:d,mouthPath:l.diffPath,mouthKey:c,label:l.label}))}return a}const ko=3;function mr(e){let t=0;const n=[];let r=!1,i=!1;const s=async()=>{if(!r){r=!0;try{for(;n.length>0;){const a=n.shift(),u=++t;await e(a.diffs,u,a)&&u===t&&a.onDisplayed?.(a.drawKey)}}finally{r=!1,n.length>0&&s()}}},o=()=>{i||(i=!0,queueMicrotask(()=>{i=!1,s()}))};return{enqueue(a,u,d){const l=n.findIndex(c=>c.drawKey===u);l>=0?n[l]={diffs:a,drawKey:u,onDisplayed:d}:(n.length>=ko&&(n.shift(),at()?.onQueueSuperseded()),n.push({diffs:a,drawKey:u,onDisplayed:d})),o()},reset(){t+=1,n.length=0},isLatestSeq(a){return a===t},getLatestSeq(){return t}}}function Eo(e,t=2){const n=[],r=new Set;let i=0,s=!1,o=0;const a=(d,l)=>`${d}|${l}`,u=async()=>{if(!s){s=!0;try{for(;i<t&&n.length>0;){const d=n.shift(),l=a(d.displayAtMs,d.drawKey);if(r.has(l))continue;r.add(l),i+=1;const c=o;try{await e(d)}finally{if(r.delete(l),i-=1,c!==o)return}}}finally{s=!1,n.length>0&&i<t&&u()}}};return{enqueue(d){const l=a(d.displayAtMs,d.drawKey);r.has(l)||n.some(c=>a(c.displayAtMs,c.drawKey)===l)||(n.push(d),u())},isQueuedOrInflight(d,l){const c=a(d,l);return r.has(c)?!0:n.some(m=>a(m.displayAtMs,m.drawKey)===c)},reset(){o+=1,n.length=0,r.clear(),i=0},pendingCount(){return n.length+i}}}function xo(){const e=new Map,t=n=>{n.bitmap.close()};return{has(n,r){return e.has(r)},markRendered(n,r,i,s,o){const a=e.get(r);a&&t(a),e.set(r,{displayAtMs:n,mouthKey:r,label:i,mouthPath:s,bitmap:o})},findForMouthKey(n){return e.get(n)??null},removeThrough(n){},pruneBefore(n){},reset(){for(const n of e.values())t(n);e.clear()},size(){return e.size}}}function Io(e,t,n,r,i,s){const o=ts(t,n,r,i,Ot,s);if(o.length===0)return{ready:0,total:0};let a=0;for(const u of o)e.has(u.displayAtMs,u.mouthKey)&&(a+=1);return{ready:a,total:o.length}}function Ao(e){const t=xo(),n=dr(),r=new Set;let i="",s=null;const o=Eo(async c=>{try{if(!e.supportsBufferedPlayback)return;const m=await e.compositePrefetchFrame(c.diffs,c.mouthKey);if(!m)return;t.markRendered(c.displayAtMs,c.mouthKey,c.label,c.mouthPath,m),at()?.onBufferPrefetched()}finally{r.delete(c.mouthKey)}},bs),a=c=>{for(const m of c)t.has(m.displayAtMs,m.mouthKey)||r.has(m.mouthKey)||o.isQueuedOrInflight(0,m.mouthKey)||(r.add(m.mouthKey),o.enqueue({...m,displayAtMs:0,drawKey:m.mouthKey,diffs:{mouthPath:m.mouthPath,expressionPath:null}}))},u=(c,m,w,S=In)=>{if(!e.supportsBufferedPlayback)return;const f=Math.max(0,m-Ot*4),E=ts(c,f,m+S,w,Ot,n);a(E)},d=(c,m)=>{i=c,s=m},l=(c,m)=>!(i!==c||s!==m);return{reset(){t.reset(),o.reset(),r.clear(),Oe(n),i="",s=null,at()?.onBufferReset()},markExternallyDisplayed(c,m){d(c.split("|")[0]??c,m)},warmupTick(c){e.supportsBufferedPlayback&&u(c.queue,0,c.availablePaths,Math.max(xr,In))},isWarmupReady(c,m=xr){if(!e.supportsBufferedPlayback)return!0;const{ready:w,total:S}=Io(t,c.queue,0,m,c.availablePaths,n);return S===0?!1:w/S>=_s},getBufferedFrameCount:()=>t.size(),tick(c){const m=at();m?.onBufferTick(),u(c.queue,c.elapsedMs,c.availablePaths),t.pruneBefore(c.elapsedMs-In);const w=fr(c.queue,c.elapsedMs,c.availablePaths,n),S=ln(w.diffPath),f=Vt({mouthPath:w.diffPath,expressionPath:c.expressionPath},c.expressionDrawKey),E=()=>(d(S,c.expressionPath),m?.onBufferHit(),{usedBuffer:!0,underrun:!1,held:!0});if(l(S,c.expressionPath)||c.playbackState.lastDrawnKey===f)return E();const D=t.findForMouthKey(S,c.elapsedMs,Ot);return D&&c.expressionPath!=null?(m?.onBufferHit(),{usedBuffer:!1,underrun:!1,held:!1}):D?(e.blitBitmap(c.canvas,D.bitmap),d(D.mouthKey,c.expressionPath),c.playbackState.lastDrawnKey=f,c.onStatus({diffPath:D.mouthPath,label:D.label}),c.onDisplayed(f,D.mouthPath,D.label),m?.onBufferHit(),{usedBuffer:!0,underrun:!1,held:!1}):(m?.onBufferUnderrun(),{usedBuffer:!1,underrun:!0,held:!1})}}}const Mo=`
|
|
6
6
|
in vec2 aPosition;
|
|
7
7
|
out vec2 vTextureCoord;
|
|
8
8
|
|
|
@@ -30,7 +30,7 @@ void main(void)
|
|
|
30
30
|
gl_Position = filterVertexPosition();
|
|
31
31
|
vTextureCoord = filterTextureCoord();
|
|
32
32
|
}
|
|
33
|
-
`,
|
|
33
|
+
`,Po=`
|
|
34
34
|
in vec2 vTextureCoord;
|
|
35
35
|
out vec4 finalColor;
|
|
36
36
|
|
|
@@ -44,5 +44,5 @@ void main(void)
|
|
|
44
44
|
float keep = step(uThreshold + 1e-6, peak);
|
|
45
45
|
finalColor = vec4(color.rgb, keep);
|
|
46
46
|
}
|
|
47
|
-
`;function Gr(e=5){const t=new we.Filter({glProgram:we.GlProgram.from({vertex:Io,fragment:Ao,name:"threshold-key-filter"}),resources:{thresholdUniforms:{uThreshold:{value:e/255,type:"f32"}}}});return t.setThreshold=n=>{t.resources.thresholdUniforms.uniforms.uThreshold=n/255},t.getThreshold=()=>Math.round(t.resources.thresholdUniforms.uniforms.uThreshold*255),t}function Mo(e,t,n){return e>n||t>n}function Po(e){return e?e.getParameter(e.MAX_TEXTURE_SIZE):4096}function Co(e,t){return t!=null&&t>0?Math.floor(t):Po(e)}function Ro(e,t){const n=document.createElement("canvas");n.width=t.w,n.height=t.h;const r=n.getContext("2d");if(!r)throw new Error("Failed to acquire 2d context for atlas cell crop");return r.drawImage(e,t.x,t.y,t.w,t.h,0,0,t.w,t.h),n}function ts(e){return fetch(e).then(t=>{if(!t.ok)throw new Error(`Failed to load image: ${e}`);return t.blob()}).then(t=>createImageBitmap(t))}async function qr(e,t,n,r,i){const s=n?await Hi(e,i):await fetch(e).then(c=>{if(!c.ok)throw new Error(`Failed to load ${e}`);return c.json()}),o=s.sheets?.[0];if(!o?.path)throw new Error(`${e} has no sheets[0].path`);const a=new Map,u=async(c,m)=>{const w=Ki(t,m,n),T=n?await ha(await Mt(w,i??"")):await ts(w);if(Mo(T.width,T.height,r))return console.info(`[PixiVisemeCompositor] Sheet ${m} (${T.width}x${T.height}) exceeds MAX_TEXTURE_SIZE=${r}; using per-cell crops.`),{mode:"cells",bitmap:T};const f=we.Texture.from(T);return f.source.scaleMode="nearest",{mode:"full",texture:f}};a.set(o.index,await u(o.index,o.path));for(const c of s.sheets??[])c.index!==o.index&&c.path&&a.set(c.index,await u(c.index,c.path));const d=new Map;for(const c of s.cells??[])c.path&&d.set(c.path,c);const l=new Map;for(const c of s.sheets??[])l.set(c.index,c);return{atlasMeta:s,cellByPath:d,sheetByIndex:l,diffBase:t,sheets:a}}async function Do(e,t={}){const n=new we.Application;try{await n.init({canvas:e,width:842,height:1264,preference:"webgl",autoStart:!1,antialias:!1,resolution:1,autoDensity:!1,backgroundAlpha:1,backgroundColor:0,powerPreference:"high-performance"})}catch(p){throw n.destroy({removeView:!1}),p}if(n.renderer.type!==we.RendererType.WEBGL)throw n.destroy({removeView:!1}),new Error("Pixi did not initialize a WebGL renderer");const r=Co(n.renderer.gl,t.maxTextureSize);let i=!1,s=!1,o=!1;const a=n.canvas,u=()=>{i=!0,!s&&!o&&(s=!0,t.onWebGlContextLost?.())};a.addEventListener("webglcontextlost",u);const d=new we.Sprite(we.Texture.EMPTY),l=new we.Sprite(we.Texture.EMPTY);l.visible=!1,l.alpha=0;const c=new we.Sprite(we.Texture.EMPTY),m=new we.Sprite(we.Texture.EMPTY),w=new we.Sprite(we.Texture.EMPTY);w.visible=!1;const T=Gr(5),f=Gr(5);c.filters=[T],m.filters=[f],n.stage.addChild(d),n.stage.addChild(l),n.stage.addChild(c),n.stage.addChild(m),n.stage.addChild(w);let E=null,D=null,B=null,v=null,k=null,L=null,A=null,ie=842,de=1264,I=null,V=5;const G=new Map;let ae=null,se=null,re=null;const O=fi(()=>{G.clear(),L=null,A=null,E=null,I=null}),J=(p,S)=>{ie=p,de=S,n.renderer.resize(p,S),(e.width!==p||e.height!==S)&&(e.width=p,e.height=S)},W=()=>{c.visible=!1,m.visible=!1,c.texture=we.Texture.EMPTY,m.texture=we.Texture.EMPTY,ae=null,se=null},he=()=>{k=null,l.visible=!1,l.alpha=0},K=()=>{d.visible=!0,d.width=ie,d.height=de,d.x=0,d.y=0},ee=()=>{l.width=ie,l.height=de,l.x=0,l.y=0},$=()=>{w.visible=!1,he(),E&&(d.texture=E,K())},X=()=>{!k&&!l.visible||$()},_e=p=>{if(o||i||!E){$();return}const S=Math.max(0,p);if(!D||S<=0){$();return}W(),w.visible=!1,d.texture=D,K(),l.texture=E,ee(),l.alpha=0,l.visible=!0,k={startMs:performance.now(),durationMs:S},q()},oe=(p=performance.now())=>{if(!k)return!1;if(o||i)return X(),!1;const S=(p-k.startMs)/Math.max(1,k.durationMs);if(S>=1)return $(),q(),!1;const x=Math.min(1,Math.max(0,S)),_=x*x*(3-2*x);return l.alpha=_,l.visible=!0,q(),!0},b=()=>{if(B){try{B.resource=null}catch{}B.destroy(),B=null}D&&(D.destroy(!1),D=null),v=null},P=(p,S)=>{const x=p.cellByPath.get(S);if(!x||!zi(x))return null;const _=`${p.diffBase}::${S}`;let U=G.get(_);if(!U){const Z=x.sheet??0,te=p.sheets.get(Z);if(!te)return null;let z,be=!1;if(te.mode==="full")z=new we.Texture({source:te.texture.source,frame:new we.Rectangle(x.x,x.y,x.w,x.h)});else{const Xe=Ro(te.bitmap,x);z=we.Texture.from(Xe),z.source.scaleMode="nearest",be=!0}U={texture:z,ownsSource:be},G.set(_,U)}return{texture:U.texture,cell:x}},H=(p,S,x,_)=>{if(!_||!x)return p.visible=!1,p.texture=we.Texture.EMPTY,!1;const U=P(x,_);if(!U)return p.visible=!1,p.texture=we.Texture.EMPTY,!1;const Z=Wi(x.atlasMeta,U.cell);return S.setThreshold(V),p.texture=U.texture,p.x=Z.x,p.y=Z.y,p.width=U.cell.w,p.height=U.cell.h,p.visible=!0,!0},le=p=>{if(!p||!L)return null;const S=I??new Set(L.cellByPath.keys());return ir(p,S)??(S.has(p)?p:null)},j=p=>{w.visible=!1,$();const S=le(p.mouthPath),x=p.expressionPath&&A?ar(p.expressionPath,_=>A.cellByPath.has(_)):null;S!==ae?(H(c,T,L,S),ae=S):S?c.visible=!0:c.visible=!1,x!==se?(H(m,f,A,x),se=x):x?m.visible=!0:m.visible=!1},q=()=>{if(!(o||i||document.hidden))try{n.render()}catch{}};return{async loadAssets(p){if(o)return{width:ie,height:de,visemePaths:[]};const S=Wt();if(S&&!p)throw new Error("Encrypted assets enabled but no key provided");const x=S?await wa(await Mt(sn(),p??"")):await ts(sn());E&&E.destroy(!0),E=we.Texture.from(x),E.source.scaleMode="linear";const _=mi();L=await qr(hi(),_,S,r,p);try{A=await qr(gi(),_,S,r,p)}catch(Z){console.warn("[PixiVisemeCompositor] expression atlas unavailable:",Z),A=null}const U=Ui(L.atlasMeta,x.width,x.height);return J(U.width,U.height),V=vn(L.atlasMeta),T.setThreshold(V),f.setThreshold(V),I=new Set(L.cellByPath.keys()),G.clear(),$(),W(),q(),{width:U.width,height:U.height,visemePaths:[...L.cellByPath.keys()]}},getVisemeAtlasPaths(){return I},drawLiveFrame(p){o||i||!E||(X(),j(p),q())},drawIdleVideo(p,S){o||i||document.hidden||S&&!S()||p.readyState<HTMLMediaElement.HAVE_CURRENT_DATA||(he(),W(),w.visible=!1,!D||v!==p?(b(),B=new we.VideoSource({resource:p,autoPlay:!1,updateFPS:0}),B.autoUpdate=!1,D=new we.Texture({source:B}),v=p):D.source.update(),d.texture=D,K(),q())},beginIdleToSilCrossfade:_e,tickIdleToSilCrossfade:oe,finishIdleToSilCrossfade:X,isIdleToSilCrossfading(){return k!=null},renderSilOnly(){o||i||!E||(W(),$(),q())},blitBitmap(p){o||i||(X(),W(),re&&(re.destroy(!0),re=null),re=we.Texture.from(p),w.texture=re,w.visible=!0,w.x=0,w.y=0,w.width=ie,w.height=de,d.visible=!1,q())},async compositePrefetchFrame(p){return null},renderFrame:q,isContextLost(){return i},dispose(){if(o)return;o=!0,a.removeEventListener("webglcontextlost",u),O(),b(),re&&(re.destroy(!0),re=null);for(const{texture:S,ownsSource:x}of G.values())S.destroy(x);G.clear(),E&&(E.destroy(!0),E=null);const p=S=>{S.mode==="full"?S.texture.destroy(!0):S.bitmap.close()};if(L)for(const S of L.sheets.values())p(S);if(A)for(const S of A.sheets.values())p(S);T.destroy(!0),f.destroy(!0),n.destroy({removeView:!1},{children:!0,texture:!0})}}}const Yr=-1,tn=1e5,Qr=new Map;async function Bo(e){let t=Qr.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),Qr.set(e,t)}return new Worker(t,{name:"visemeDiffPreview"})}function Fo(){return typeof Worker<"u"&&typeof OffscreenCanvas<"u"}function zn(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 Xr(e,t){let n=0,r=null;const i=fr(async(s,o)=>(await Un(),await Wn(e,s),i.isLatestSeq(o)));return{usesWorker:!1,usesPixi:!1,async loadAssets(s){const o=await Un(s);return r=o.visemePaths?new Set(o.visemePaths):null,o},getVisemeAtlasPaths(){return r},async renderSilOnly(){n+=1,i.reset(),await eo(e)},drawLiveFrame(s,o,a,u){i.enqueue(o,a,u)},async compositePrefetchFrame(s,o){try{return await Za(s)}catch{return null}},blitBitmap(s,o){zn(s,o)},drawIdleVideo(){},beginIdleToSilCrossfade(){},tickIdleToSilCrossfade(){return!1},finishIdleToSilCrossfade(){},isIdleToSilCrossfading(){return!1},supportsBufferedPlayback:!0,async renderViseme(s,o){n+=1;const a=n;t.onStatus?.(o),await Wn(s,{mouthPath:xt(o),expressionPath:null})},dispose(){n+=1,i.reset()}}}function Lo(e,t,n){let r=null,i=1,s=0,o=!1,a=!1,u=null;const d=new Map,l=new Map;let c=tn;const m=fr(async(B,v,k)=>(d.set(v,{drawKey:k.drawKey,onDisplayed:k.onDisplayed}),await E({type:"drawFrame",diffPath:B.mouthPath,expressionDiffPath:B.expressionPath,liveSeq:v},void 0,!0),!1)),w=B=>{if(B===Yr){let L=-1,A;for(const[ie,de]of d)ie>=L&&(L=ie,A=de);L>=0&&d.delete(L),A?.onDisplayed?.(A.drawKey);return}const v=-B,k=d.get(v);d.delete(v),k?.onDisplayed?.(k.drawKey)},T=new Map,f=(B,v)=>{a||!r||r.postMessage(B,[])},E=(B,v,k=!1)=>{if(a)return Promise.resolve();const L=i++;return new Promise((A,ie)=>{T.set(L,{resolve:de=>A(de),reject:ie,generation:typeof B.generation=="number"?B.generation:void 0,expectRenderDone:k}),f({...B,requestId:L})})},D=(async()=>{r=await Bo(n),r.onmessage=B=>{if(a)return;const v=B.data;if(v.type==="status"){t.onStatus?.(v.label);return}if(v.type==="frame"){if(v.generation<=-tn){const A=-v.generation,ie=l.get(A);l.delete(A),ie?.resolve(v.bitmap);return}const L=v.generation<0;if(!L&&v.generation!==s){v.bitmap.close();return}if(L&&!(v.generation===Yr)){const ie=-v.generation;if(!m.isLatestSeq(ie)){at()?.onWorkerStale(),v.bitmap.close();return}}if(L&&t.shouldAcceptLiveFrame&&!t.shouldAcceptLiveFrame()){at()?.onWorkerStale(),v.bitmap.close();return}zn(e,v.bitmap),v.bitmap.close(),L&&w(v.generation);return}const k=T.get(v.requestId);if(k)switch(v.type){case"ready":T.delete(v.requestId),k.resolve();break;case"loadAssetsDone":T.delete(v.requestId),u=v.visemePaths?.length?new Set(v.visemePaths):null,k.resolve({width:v.width,height:v.height,visemePaths:v.visemePaths});break;case"renderDone":if(k.expectRenderDone&&k.generation!=null&&v.generation!==k.generation)return;T.delete(v.requestId),k.resolve();break;case"renderAborted":T.delete(v.requestId),k.resolve();break;case"error":T.delete(v.requestId),t.onError?.(v.message),k.reject(new Error(v.message));break}},r.onerror=B=>{if(a)return;const v=B.message||"Worker error";t.onError?.(v);for(const[,k]of T)k.reject(new Error(v));T.clear()},await E({type:"init"}),o=!0})();return{usesWorker:!0,usesPixi:!1,async loadAssets(B){if(a)return{width:842,height:1264};if(await D,a)return{width:842,height:1264};if(!o)throw new Error("Worker init failed");return await E({type:"loadAssets",keyHex:B,urls:Bs(wt())})??{width:842,height:1264}},getVisemeAtlasPaths(){return u},async renderSilOnly(){if(a||(await D,a))return;s+=1,m.reset(),d.clear(),l.forEach(({resolve:v})=>v(null)),l.clear(),c=tn;const B=s;await E({type:"cancelLiveDraws"}),await E({type:"renderSil",generation:B},void 0,!0)},drawLiveFrame(B,v,k,L){a||D.then(()=>{a||m.enqueue(v,k,L)})},compositePrefetchFrame(B,v){return a?Promise.resolve(null):D.then(()=>{if(a)return null;const k=++c;return new Promise(L=>{l.set(k,{resolve:L}),E({type:"drawFrame",diffPath:B.mouthPath,expressionDiffPath:B.expressionPath,liveSeq:k},void 0,!0).catch(()=>{l.delete(k),L(null)})})})},blitBitmap(B,v){zn(B,v)},drawIdleVideo(){},beginIdleToSilCrossfade(){},tickIdleToSilCrossfade(){return!1},finishIdleToSilCrossfade(){},isIdleToSilCrossfading(){return!1},supportsBufferedPlayback:!0,async renderViseme(B,v,k={}){if(a||(await D,a))return;s+=1,m.reset(),d.clear();const L=s;try{await E({type:"cancelLiveDraws"}),await E({type:"renderViseme",generation:L,to:v,from:k.from,transitionDurationMs:k.transitionDurationMs,gapMs:k.gapMs,threshold:k.threshold},void 0,!0)}catch(A){if(A?.name==="AbortError")return;throw A}},dispose(){if(!a){a=!0,s+=1,m.reset(),d.clear(),l.forEach(({resolve:B})=>B(null)),l.clear(),c=tn;for(const[,B]of T)B.resolve();T.clear(),r?.terminate(),r=null}}}}async function Oo(e,t){const n=await Do(e,{onWebGlContextLost:t.onWebGlContextLost,maxTextureSize:t.pixiMaxTextureSize});let r=0,i=null,s=!1;const o=fr(async(a,u)=>s?!1:t.shouldAcceptLiveFrame&&!t.shouldAcceptLiveFrame()?(at()?.onWorkerStale(),!1):(n.drawLiveFrame(a),o.isLatestSeq(u)));return{usesWorker:!1,usesPixi:!0,async loadAssets(a){if(s)return{width:842,height:1264};const u=await n.loadAssets(a);return i=u.visemePaths?.length?new Set(u.visemePaths):null,u},getVisemeAtlasPaths(){return i},async renderSilOnly(){s||(r+=1,o.reset(),n.renderSilOnly())},drawLiveFrame(a,u,d,l){s||o.enqueue(u,d,l)},async compositePrefetchFrame(a,u){if(s)return null;try{return await n.compositePrefetchFrame(a)}catch{return null}},blitBitmap(a,u){s||t.shouldAcceptLiveFrame&&!t.shouldAcceptLiveFrame()||n.blitBitmap(u)},drawIdleVideo(a,u){s||n.drawIdleVideo(a,u)},beginIdleToSilCrossfade(a){s||n.beginIdleToSilCrossfade(a)},tickIdleToSilCrossfade(a){return s?!1:n.tickIdleToSilCrossfade(a)},finishIdleToSilCrossfade(){s||n.finishIdleToSilCrossfade()},isIdleToSilCrossfading(){return s?!1:n.isIdleToSilCrossfading()},supportsBufferedPlayback:!1,async renderViseme(a,u){if(s)return;r+=1;const d=r;o.reset(),t.onStatus?.(u),n.drawLiveFrame({mouthPath:xt(u),expressionPath:null})},dispose(){s||(s=!0,r+=1,o.reset(),n.dispose())}}}function Jr(e,t){if(!Fo())return Xr(e,t);const n=ws(t.workerScriptUrl);try{return Lo(e,t,n)}catch{return Xr(e,t)}}function No(e,t={}){if(t.preferLegacyRenderer)return Jr(e,t);let n=null,r=!1,i=null,s=!1;const o=()=>n?Promise.resolve(n):(i||(i=(async()=>{try{const a=await Oo(e,t);if(s)throw a.dispose(),new Error("Renderer disposed during Pixi init");return r=!0,n=a,a}catch(a){if(s)throw a instanceof Error?a:new Error(String(a));return console.warn("[AiTwin] Pixi WebGL renderer unavailable, using Canvas2D fallback:",a),n=Jr(e,t),r=!1,n}})()),i);return{get usesWorker(){return n?.usesWorker??!1},get usesPixi(){return r},async loadAssets(a){return(await o()).loadAssets(a)},getVisemeAtlasPaths(){return n?.getVisemeAtlasPaths()??null},async renderSilOnly(){return(await o()).renderSilOnly()},drawLiveFrame(a,u,d,l){o().then(c=>{s||c.drawLiveFrame(a,u,d,l)})},async compositePrefetchFrame(a,u){return(await o()).compositePrefetchFrame(a,u)},blitBitmap(a,u){n&&n.blitBitmap(a,u)},drawIdleVideo(a,u){n?.usesPixi&&n.drawIdleVideo(a,u)},beginIdleToSilCrossfade(a){n?.beginIdleToSilCrossfade(a)},tickIdleToSilCrossfade(a){return n?.tickIdleToSilCrossfade(a)??!1},finishIdleToSilCrossfade(){n?.finishIdleToSilCrossfade()},isIdleToSilCrossfading(){return n?.isIdleToSilCrossfading()??!1},get supportsBufferedPlayback(){return n?.supportsBufferedPlayback??!1},async renderViseme(a,u,d){return(await o()).renderViseme(a,u,d)},dispose(){s=!0,i=null,n?.dispose(),n=null}}}class Vo extends Error{constructor(t,n){super(`${t} timed out after ${Math.round(n/1e3)}s`),this.name="LoadTimeoutError"}}function Cn(e,t,n){return new Promise((r,i)=>{const s=globalThis.setTimeout(()=>{i(new Vo(n,t))},t);e.then(o=>{globalThis.clearTimeout(s),r(o)},o=>{globalThis.clearTimeout(s),i(o)})})}const Uo={overflow:"hidden",position:"relative",display:"inline-block",lineHeight:0},Wo={display:"block",maxWidth:"100%",height:"auto"},zo={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 Rn(e){return Ss(e)?tr:oi(e)?dn:er}function Je(e,t){return t?.isSpeaking()||t?.isWarmingUp()?t:e.isSpeaking()||e.isWarmingUp()?e:t?.isConnected()?t:e}const ns=h.forwardRef(function({id:t,avatarId:n,faceId:r,assets:i,authToken:s,apiBase:o,ttsEngineId:a,voiceId:u,language:d,speakingRate:l=Ht,className:c,style:m,canvasStyle:w,onStatusChange:T,onDisplayStatus:f,onError:E,onReady:D,showErrorOverlay:B=!0,loadingThumbnailUrl:v,onUserTranscript:k,onBotOutput:L,onRealtimeLipsyncDebug:A,onFrameRenderStats:ie,lipsyncBufferedPlayback:de=!0,lipsyncPlaybackWarmupMs:I=1500,idleHandoffHoldMs:V=ho,pixiMaxTextureSize:G,captions:ae},se){const re=h.useRef(null),O=h.useRef(null),J=h.useRef(null),W=h.useRef(de);W.current=de;const he=h.useRef(I);he.current=I;const K=h.useRef(V);K.current=V;const ee=h.useRef(0),$=h.useRef(ur()),X=h.useRef(Ha()),_e=h.useRef(!1),oe=h.useRef(null),b=h.useRef(null),P=h.useRef(0),H=h.useRef(0),le=h.useRef(0),j=h.useRef(null),q=h.useRef(null),p=h.useRef(!1),S=h.useRef(!1),x=h.useRef(!1),_=h.useRef(!1),U=h.useRef("sil"),Z=h.useRef(0),te=h.useRef(!1),z=h.useRef(null),be=h.useRef(!1),[Xe,Pt]=h.useState("idle"),[pt,Ct]=h.useState(null),[ot,_n]=h.useState(!1),[g,C]=h.useState(!1),[ne,ue]=h.useState(!1),[Te,ve]=h.useState(),[ke,We]=h.useState({width:842,height:1264}),[Fe,$t]=h.useState(null),[bn,Rt]=h.useState(0),yt=h.useRef(!1),Ce=h.useRef(s??null),He=o?.trim()||ht,vt=h.useRef(null),Ie=h.useRef(null),{ttsEngineId:xe,voiceId:$e}=h.useMemo(()=>{const y=et(a,u),M=y.ttsEngineId??dt;return{ttsEngineId:M,voiceId:y.voiceId??Rn(M)}},[a,u]),je=h.useRef(!1),rt=h.useRef({width:842,height:1264}),pe=h.useRef(null),Le=h.useRef("sil"),Pe=h.useRef(""),Oe=h.useMemo(()=>no(ae),[ae]),Ne=h.useCallback(()=>{Pe.current="",$t(null)},[]);h.useEffect(()=>{Oe.enabled||Ne()},[Oe.enabled,Ne]);const Dt=h.useCallback(y=>{if(!Oe.enabled)return;const M=y.isSpeaking(),N=y.isWarmingUp();if(!M||N){Pe.current&&Ne();return}const F=to(y.getWordQueue());if(!F){Pe.current&&Ne();return}F!==Pe.current&&(Pe.current=F,$t(F))},[Oe.enabled,Ne]),ct=h.useRef(void 0),Bt=h.useRef(new Map),mr=h.useRef(D),hr=h.useRef(T),ye=h.useRef(f),gr=h.useRef(E),wr=h.useRef(k),pr=h.useRef(L),jt=h.useRef(A),yr=h.useRef(ie),_t=h.useRef(mo());mr.current=D,hr.current=T,ye.current=f,gr.current=E,wr.current=k,pr.current=L,jt.current=A,yr.current=ie,h.useEffect(()=>{const y=_t.current;return zr(y),()=>zr(null)},[]);const vr=h.useCallback(y=>{const M=et(y?.ttsEngineId??a,y?.voiceId??u),N=M.ttsEngineId??Ie.current?.ttsEngineId??dt,F=M.voiceId??Ie.current?.voiceId??Rn(N);return{ttsEngineId:N,voiceId:F}},[a,u]),it=h.useCallback(y=>{Ct(y),ue(!0),gr.current?.(y)},[]),Ft=h.useCallback(y=>{Pt(y),hr.current?.(y)},[]),fe=h.useRef(Nn(Ft,He,{onLipsyncDebug:y=>jt.current?.(y)})),me=h.useRef(null),_r=h.useRef(()=>{});h.useEffect(()=>(fe.current=Nn(Ft,He,{onLipsyncDebug:y=>jt.current?.(y)}),s&&fe.current.setDeveloperToken(s),fe.current.setTtsEngineId(xe),()=>{fe.current.stop();const y=me.current;y&&(y.disconnect(),me.current=null)}),[Ft,He]);const br=h.useCallback(()=>(me.current||(me.current=Vi(Ft,{speakingRate:l,language:d,onUserTranscript:(y,M)=>wr.current?.(y,M),onBotOutput:y=>pr.current?.(y),onLipsyncDebug:y=>jt.current?.(y)}),me.current.setTtsEngineId(xe),_r.current(!0)),me.current),[Ft,l,d,xe]),Re=h.useCallback(()=>{j.current!=null&&(clearTimeout(j.current),j.current=null)},[]),De=h.useCallback(()=>{q.current!=null&&(clearTimeout(q.current),q.current=null),x.current=!1},[]),Kt=h.useCallback(()=>{if(_.current)return;const y=O.current;if(_.current=!0,De(),p.current=!1,S.current=!1,!be.current||!z.current){y?.renderSilOnly();return}z.current.setActive(!1);const M=z.current.getVideo();if(y?.usesPixi){y.drawIdleVideo(M),y.beginIdleToSilCrossfade($r);return}(async()=>{const N=re.current;N&&await Mn(N,M,null,void 0,rt.current).catch(()=>{}),await new Promise(F=>setTimeout(F,$r)),_.current&&await y?.renderSilOnly()})()},[De]),Sr=h.useCallback(()=>{!be.current||!z.current||(_.current=!1,O.current?.finishIdleToSilCrossfade(),De(),x.current=!0,q.current=setTimeout(()=>{if(q.current=null,Je(fe.current,me.current).isSpeaking()){x.current=!1;return}if(p.current){x.current=!1;return}const y=z.current;if(!y){x.current=!1;return}y.restart(),y.setActive(!0);const M=y.getVideo();let N=!1;const F=()=>{N||(N=!0,M.removeEventListener("playing",Q),x.current=!1)},Q=()=>{F()};if(M.addEventListener("playing",Q,{once:!0}),M.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA&&!M.paused){F();return}setTimeout(F,300)},K.current))},[De]),bt=h.useCallback(()=>{if(Re(),ye.current?.("sil"),p.current=!1,_.current=!1,!be.current||!z.current){x.current=!1;return}Sr()},[Re,Sr]),Sn=h.useCallback(async y=>{const M=H.current,N=O.current,F=re.current,Q=()=>{y?.fallbackOnly||(p.current=!1)};if(!N||!F||!ot){Q();return}if(Je(fe.current,me.current).isSpeaking()){Q();return}if(y?.fallbackOnly){if(!p.current||(Be($.current),await N.renderSilOnly(),M!==H.current)||Je(fe.current,me.current).isSpeaking())return;bt();return}if(jr($.current)){Be($.current),bt();return}if(W.current&&N.supportsBufferedPlayback&&!y?.fallbackOnly){if(Be($.current),J.current?.reset(),await N.renderSilOnly(),M!==H.current||Je(fe.current,me.current).isSpeaking())return;bt();return}const Ee=vo(Je(fe.current,me.current).getVisemeQueue(),Z.current,U.current),Ve=_o(Ee,pe.current);if(Be($.current),!Ve){if(await N.renderSilOnly(),M!==H.current||Je(fe.current,me.current).isSpeaking())return;bt();return}try{await N.renderViseme(F,"sil",{from:Ee,transitionDurationMs:Ji})}catch(Me){if(Me?.name!=="AbortError")throw Me}if(M!==H.current){Q();return}if(Je(fe.current,me.current).isSpeaking()){Q();return}bt()},[ot,bt]),St=h.useCallback(()=>{if(S.current||p.current)return;S.current=!0,p.current=!0,Re();const y=H.current;Sn().finally(()=>{S.current=!1}),j.current=setTimeout(()=>{j.current=null,y===H.current&&Sn({fallbackOnly:!0})},bo())},[Re,Sn]),Tr=h.useCallback(async()=>{const y=Math.floor(Date.now()/1e3);if(vt.current&&y<vt.current.expiresAt-60)return vt.current.key;const M=Ce.current??await Nt();Ce.current=M,fe.current.setDeveloperToken(M);const N=await Ps(M,He);return vt.current={key:N.value,expiresAt:N.expiresAt},N.value},[He]);h.useEffect(()=>{s&&(Ce.current=s,fe.current.setDeveloperToken(s))},[s]),h.useEffect(()=>{fe.current.setTtsEngineId(xe),me.current?.setTtsEngineId(xe),Ie.current&&(Ie.current.ttsEngineId=xe)},[xe]),h.useEffect(()=>{Ie.current&&(Ie.current.voiceId=$e)},[$e]);const Ke=h.useMemo(()=>ui(n,r),[n,r]),os=h.useMemo(()=>i?JSON.stringify(i):Ke?`face:${Ke}`:`id:${t??""}`,[i,Ke,t]),cs=h.useMemo(()=>{const y=v?.trim();return y||(xr(Ke)??xr(Te)??ks(i))},[v,Ke,Te,i]);return h.useEffect(()=>{if(!t&&!i&&!Ke){it("AiTwin requires `assets`, `avatarId`/`faceId`, or `id`");return}let y=!1;je.current=!1,_n(!1),C(!1),ue(!1),ve(Ke),Ct(null),Ie.current=null,z.current=null,be.current=!1;const M=re.current;if(!M)return;let N=null;return(async()=>{try{let F,Q,Se,Ee;if(i)F=i,Q=xe,Se=$e;else if(Ke)ye.current?.("loadFace"),F=Ln(Ke),Q=xe,Se=$e;else{ye.current?.("getAiTwin");const Y=await Cn(ci(t),3e4,"getAiTwin");if(y)return;if(!Y.faceId?.trim())throw new Error("getAiTwin returned no faceId");ve(Y.faceId.trim());const ce=et(a,u);Q=ce.ttsEngineId??Y.ttsEngineId,Se=ce.voiceId??Y.voiceId??Rn(Q),Ee=qn(Y),F=Ln(Y.faceId)}Ie.current={ttsEngineId:Q,voiceId:Se,brainId:Ee},di(F),z.current=$a();const Ve=!!(i&&!gt(i));N=No(M,{preferLegacyRenderer:Ve,pixiMaxTextureSize:G,onStatus:Y=>{y||ye.current?.(Y)},onError:Y=>{y||it(Y)},shouldAcceptLiveFrame:()=>{if(_e.current)return!0;if(p.current)return!1;const Y=Je(fe.current,me.current);return Y.isSpeaking()||Y.isWarmingUp()},onWebGlContextLost:()=>{y||yt.current||(yt.current=!0,queueMicrotask(()=>{y||Rt(Y=>Y+1)}))}}),O.current=N,J.current=xo(N),yt.current=!1;const Me=Y=>{const ce=()=>{if(!Y||he.current<=0)return!1;const Ae=O.current;return Ae?W.current&&Ae.supportsBufferedPlayback?!0:Ae.usesPixi:!1};fe.current.setLipsyncWarmupHold(Y,ce),me.current?.setLipsyncWarmupHold(Y,ce)};_r.current=Me,Me(!0),ye.current?.("auth");const Ge=Ce.current??s??await Cn(Nt(),3e4,"getAuthToken");if(y)return;Ce.current=Ge,fe.current.setDeveloperToken(Ge),fe.current.setTtsEngineId(Q);const Gt=Wt()?await Tr():void 0;if(y)return;ye.current?.("loadAssets");const ge=await Cn(N.loadAssets(Gt),18e4,"load face assets");if(!y&&ge.width>0&&ge.height>0&&(rt.current=ge,We(ge)),y)return;pe.current=N.getVisemeAtlasPaths(),je.current=!0,_n(!0),mr.current?.(),N.renderSilOnly().then(()=>{y||ye.current?.("sil")}),(async()=>{try{const Y=await va(Gt);if(await z.current.load(Y),y)return;be.current=!0,C(!0),Be($.current),z.current.setActive(!0);const ce=z.current.getVideo();N.usesPixi?N.drawIdleVideo(ce):await Mn(M,ce,null,void 0,rt.current)}catch(Y){if(y)return;be.current=!1,C(!1),console.warn("[AiTwin] Idle video unavailable:",Y)}finally{y||(ue(!0),ye.current?.("idle"))}})()}catch(F){if(y)return;if(F instanceof nn){it(F.message);return}it(F instanceof Error?F.message:"Failed to load AI twin")}})(),()=>{y=!0,z.current?.dispose(),N?.dispose(),O.current=null}},[os,i,Ke,t,xe,$e,a,u,s,G,Tr,it,bn]),h.useEffect(()=>{const y={current:!1},M=()=>{const N=re.current,F=O.current,Q=Je(fe.current,me.current);if(!N||!F||!ot){P.current=requestAnimationFrame(M);return}if(document.hidden){z.current?.setActive(!1),P.current=requestAnimationFrame(M);return}const Se=Q.isSpeaking(),Ee=Q.isWarmingUp(),Ve=Se&&!te.current,Me=te.current&&!Se;Ve&&(Re(),De(),p.current=!1,S.current=!1,Be($.current),J.current?.reset(),_t.current.reset(),ct.current=void 0,le.current=0,U.current="sil",Z.current=0,Kt()),Me&&(X.current.reset(),z.current?.setActive(!1),J.current?.reset(),F.finishIdleToSilCrossfade(),Ne(),St());const Ge=Me||p.current||x.current||_.current,Gt=de&&F.supportsBufferedPlayback;if(Ee){if(Kt(),be.current&&z.current?.setActive(!1),F.usesPixi&&F.isIdleToSilCrossfading()){F.tickIdleToSilCrossfade(performance.now()),Q.getVisemeQueue().length>0&&ee.current===0&&(ee.current=performance.now()),te.current=Q.isSpeaking(),P.current=requestAnimationFrame(M);return}const ge=Q.getVisemeQueue();ge.length>0&&ee.current===0&&(ee.current=performance.now()),X.current.advance(performance.now());const Y=X.current.getExpressionPath(),ce=X.current.getDrawKey(),Ae={queue:ge,elapsedMs:0,expressionPath:Y,expressionDrawKey:ce,availablePaths:pe.current};let Ue=!1;Gt&&J.current?(J.current.warmupTick(Ae),Ue=J.current.isWarmupReady(Ae,he.current)):F.usesPixi&&Kr(N,ge,0,Y,ce,$.current,(Tt,qt,Tn,Yt)=>{F.drawLiveFrame(Tt,qt,Tn,qe=>{Yt?.(qe),Q.isWarmingUp()&&qe!==""&&!jr({lastDrawnKey:qe})&&(ee.current=0,Q.releaseWarmupHold())})},Tt=>{ye.current?.(Tt.label)},pe.current);const st=ee.current>0&&performance.now()-ee.current>ys;ye.current?.(Ue?"buffer ready":"buffering lipsync…"),(Ue||st)&&(ee.current=0,Q.releaseWarmupHold()),Dt(Q),te.current=Q.isSpeaking(),P.current=requestAnimationFrame(M);return}if(Se){Kt(),be.current&&z.current?.setActive(!1),F.usesPixi&&F.isIdleToSilCrossfading()&&F.finishIdleToSilCrossfade();const ge=Q.getVisemeQueue(),Y=Q.getPlaybackElapsedMs();aa(ge,Y),Z.current=Y;const ce=ge.length>0?zt(ge,Y):"sil";ce!=="sil"&&(U.current=ce);const Ae=qa(Y,Q.getSentenceEmotions(),Q.getWordQueue(),Q.getStreamMood());X.current.setTargetEmotion(Ae),X.current.setTargetEyebrow(Wa(Y,Q.getWordQueue(),mt(Ae))),X.current.advance(performance.now());const Ue=X.current.getExpressionPath(),st=X.current.getDrawKey(),Tt=(qe,kn,Lt,En)=>{const kr={label:Le.current,elapsedMs:Y,mouthPath:kn.mouthPath,transitionMeta:ct.current};Bt.current.set(Lt,kr),J.current?.markExternallyDisplayed(Lt,Ue),F.drawLiveFrame(qe,kn,Lt,Qt=>{const ls=Bt.current.get(Qt)??kr;Bt.current.delete(Qt),_t.current.onDrawDisplayed(ls,ge),J.current?.markExternallyDisplayed(Qt,Ue),En?.(Qt)})},qt=qe=>{Le.current=qe.label,ct.current=qe.transitionMeta,ye.current?.(qe.label)},Tn=de&&F.supportsBufferedPlayback;let Yt=!1;Tn&&J.current&&(Yt=J.current.tick({canvas:N,queue:ge,elapsedMs:Y,expressionPath:Ue,expressionDrawKey:st,playbackState:$.current,availablePaths:pe.current,onStatus:qt,onDisplayed:(kn,Lt,En)=>{_t.current.onDrawDisplayed({label:En,elapsedMs:Y,mouthPath:Lt,transitionMeta:ct.current},ge)}}).usedBuffer),Yt||Kr(N,ge,Y,Ue,st,$.current,Tt,qt,pe.current),_t.current.onRafTickSpeaking(),yr.current?.(_t.current.snapshot(ge,Y))}else if(!Ge&&_e.current){z.current?.setActive(!1),X.current.advance(performance.now());const ge=X.current.getExpressionPath(),Y=X.current.getDrawKey();Pn(N,ge,Y,$.current,(ce,Ae,Ue,st)=>F.drawLiveFrame(ce,Ae,Ue,st),ce=>{if(b.current){ye.current?.(b.current);return}const Ae=X.current.getTargetEmotion();ye.current?.(ce==="sil"||ce==="blink"?`${Ae}${ce==="blink"?" · blink":""}`:ce)},null,oe.current)}else if(!Ge&&be.current&&z.current){const ge=z.current,Y=ge.getVideo();if(Y.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA){ge.setActive(!0);const ce=()=>!Q.isSpeaking()&&!p.current&&!x.current&&!_e.current;F.usesPixi?(F.drawIdleVideo(Y,ce),ce()&&ye.current?.("idle")):y.current||(y.current=!0,Mn(N,Y,null,void 0,rt.current,ce).then(()=>ye.current?.("idle")).finally(()=>{y.current=!1}))}else Pn(N,null,"__sil__",$.current,(ce,Ae,Ue,st)=>F.drawLiveFrame(ce,Ae,Ue,st),ce=>ye.current?.(ce))}else Ge||Pn(N,null,"__sil__",$.current,(ge,Y,ce,Ae)=>F.drawLiveFrame(ge,Y,ce,Ae),ge=>ye.current?.(ge));Oe.enabled&&Dt(Q),te.current=Se,P.current=requestAnimationFrame(M)};return P.current=requestAnimationFrame(M),()=>{cancelAnimationFrame(P.current),Re(),De(),fe.current.stop(),me.current?.stop()}},[ot,g,St,Re,De,Kt,Dt,Ne,Oe.enabled]),h.useImperativeHandle(se,()=>({speakText:async(y,M)=>{const N=y.trim();if(!N)return;const F=O.current;if(!F||!je.current&&!ot)throw new Error("AI twin is not ready");const{ttsEngineId:Q,voiceId:Se}=vr(M);Ct(null),Ne(),H.current+=1,Re(),De(),p.current=!1,S.current=!1,U.current="sil",Z.current=0,Be($.current),_e.current=!1,oe.current=null,b.current=null,X.current.reset(),te.current=!1,_.current=!1,F.finishIdleToSilCrossfade();try{await fe.current.speak(N,{voiceId:Se,speakingRate:M?.speakingRate??l,ttsEngineId:Q,language:M?.language??d})}catch(Ee){throw _.current=!1,F.finishIdleToSilCrossfade(),St(),it(Ee instanceof Error?Ee.message:"TTS failed"),Ee}},stop:()=>{H.current+=1,Re(),De(),p.current=!1,S.current=!1,_.current=!1,O.current?.finishIdleToSilCrossfade(),fe.current.stop(),me.current?.stop(),Be($.current),J.current?.reset(),ee.current=0,te.current=!1,Ne(),St()},setTtsEngineId:y=>{fe.current.setTtsEngineId(y),me.current?.setTtsEngineId(y),Ie.current&&(Ie.current.ttsEngineId=y)},renderViseme:async(y,M)=>{const N=O.current,F=re.current;if(!N||!F||!je.current)throw new Error("AI twin is not ready");await N.renderViseme(F,y,{from:M?.from,transitionDurationMs:M?.transitionDurationMs,gapMs:M?.gapMs,onStatus:Q=>ye.current?.(Q)})},setEmotion:y=>{if(!je.current)throw new Error("AI twin is not ready");const M=O.current,N=re.current;if(!M||!N)throw new Error("AI twin is not ready");H.current+=1,Re(),De(),p.current=!1,S.current=!1,x.current=!1,_.current=!1,fe.current.stop(),me.current?.stop(),Be($.current),J.current?.reset(),ee.current=0,te.current=!1,M.finishIdleToSilCrossfade(),z.current?.setActive(!1);const F=Ze(y);_e.current=!0,oe.current=null,b.current=null,X.current.snapToEmotion(F);const Q=X.current.getExpressionPath(),Se=X.current.getDrawKey(),Ee={mouthPath:null,expressionPath:Q},Ve=Ut(Ee,Se);$.current.lastDrawnKey="",M.drawLiveFrame(N,Ee,Ve,Ge=>{Ge===Ve&&($.current.lastDrawnKey=Ve)});const Me=mt(F);ye.current?.(Q?`${F} · brow ${Me>0?"+":""}${Me}`:`${F} · brow 0 (sil base)`)},getEmotion:()=>_e.current?X.current.getTargetEmotion():null,clearEmotionPreview:()=>{_e.current=!1,oe.current=null,b.current=null,X.current.reset(),Be($.current),ye.current?.("idle")},setViseme:y=>{if(!je.current)throw new Error("AI twin is not ready");const M=O.current,N=re.current;if(!M||!N)throw new Error("AI twin is not ready");H.current+=1,Re(),De(),p.current=!1,S.current=!1,x.current=!1,_.current=!1,fe.current.stop(),me.current?.stop(),Be($.current),J.current?.reset(),ee.current=0,te.current=!1,M.finishIdleToSilCrossfade(),z.current?.setActive(!1);const F=mn(y);_e.current=!0,b.current=F,oe.current=F==="sil"?null:xt(F),X.current.snapToEmotion("neutral");const Q=X.current.getExpressionPath(),Se=X.current.getDrawKey(),Ve={mouthPath:oe.current,expressionPath:Q},Me=Ut(Ve,Se);$.current.lastDrawnKey="",M.drawLiveFrame(N,Ve,Me,Ge=>{Ge===Me&&($.current.lastDrawnKey=Me)}),ye.current?.(F)},getViseme:()=>_e.current?b.current:null,isReady:()=>je.current,getStatus:()=>Xe,connect:async(y={})=>{Ct(null);try{let M=y.authToken?.trim();M||(M=Ce.current??s??await Nt(),Ce.current=M);const N=et(y.ttsEngineId??a,y.voiceId??u),F=N.voiceId??Ie.current?.voiceId,Q=y.brainId?.trim()||y.personaId?.trim()||Ie.current?.brainId,Se=N.ttsEngineId??Ie.current?.ttsEngineId??xe,Ee=br();Se&&Ee.setTtsEngineId(Se),await Ee.unlockAudio(),await Ee.connect({...y,apiBase:y.apiBase?.trim()||He,authToken:M,voiceId:F,brainId:Q,ttsEngineId:Se,speakingRate:y.speakingRate??l,language:y.language??d})}catch(M){throw it(M instanceof Error?M.message:"Voice connect failed"),M}},disconnect:async()=>{const y=me.current;y&&(H.current+=1,Re(),De(),p.current=!1,S.current=!1,_.current=!1,O.current?.finishIdleToSilCrossfade(),Be($.current),J.current?.reset(),ee.current=0,te.current=!1,await y.disconnect(),St())},isConnected:()=>me.current?.isConnected()??!1,getVoiceStream:()=>me.current?.getVoiceStream()??fe.current?.getVoiceStream()??null,setMuted:y=>{const M=fe.current,N=me.current;M?.setMuted?.(y),N?.setMuted?.(y)},isMuted:()=>{const y=me.current,M=fe.current;return y?.isMuted?.()??M?.isMuted?.()??!1},getBrainId:()=>Ie.current?.brainId?.trim()||null,getPersonaId:()=>Ie.current?.brainId?.trim()||null}),[ot,l,d,s,xe,$e,Re,De,St,it,vr,br,Xe,He]),R.jsxs("div",{className:c,style:{...Uo,...m},children:[R.jsx("canvas",{ref:re,width:ke.width,height:ke.height,style:{...Wo,...w},"aria-label":t?`AI twin ${t}`:"AI twin face"}),!ne&&!pt?R.jsx(uo,{thumbnailUrl:cs}):null,B&&pt?R.jsx("div",{style:zo,children:pt}):null,Oe.enabled&&Fe?R.jsx(ao,{text:Fe,style:Oe.style},Fe):null]})});async function Ho(e){try{const t=await e.json();if(typeof t.detail=="string"&&t.detail.trim())return t.detail;if(typeof t.error=="string"&&t.error.trim())return t.error}catch{}return`avatarReply failed (${e.status})`}async function rs(e){const t=e.message.trim();if(!t)throw new Error("Message is required");const n=e.authToken.trim();if(!n)throw new Error("Auth token is required");const r=(e.apiBase?.trim()||ht).replace(/\/$/,""),i=await fetch(`${r}/avatarReply`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${n}`,Accept:"text/event-stream"},body:JSON.stringify({message:t,history:e.history??[],brainId:e.brainId?.trim()||e.personaId?.trim()||""})});if(!i.ok)throw new Error(await Ho(i));if(!i.body)throw new Error("avatarReply response body is empty");const s=i.body.getReader(),o=new TextDecoder;let a="",u="",d="",l="";for(;;){const{done:c,value:m}=await s.read();if(c)break;a+=o.decode(m,{stream:!0});const w=a.split(`
|
|
48
|
-
`);a=w.pop()||"";for(const T of w){if(T.startsWith("event: ")){l=T.slice(7).trim();continue}if(!T.startsWith("data: "))continue;const f=T.slice(6).trim();if(!f)continue;let E;try{E=JSON.parse(f)}catch{continue}if(l==="spokenText")u=E.text||"",e.onSpokenText?.(u);else if(l==="displayText")d=E.text||"";else if(l==="error")throw new Error(E.error||"avatarReply stream error")}}if(!u.trim()||!d.trim())throw new Error("avatarReply stream missing displayText or spokenText");return{displayText:d.trim(),spokenText:u.trim()}}function $o({muted:e}){return e?R.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none","aria-hidden":!0,children:[R.jsx("path",{d:"M11 5 6.5 9H3v6h3.5L11 19V5Z",fill:"currentColor"}),R.jsx("path",{d:"m16 9.5 5 5m0-5-5 5",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round"})]}):R.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none","aria-hidden":!0,children:[R.jsx("path",{d:"M11 5 6.5 9H3v6h3.5L11 19V5Z",fill:"currentColor"}),R.jsx("path",{d:"M15.5 8.5a4.5 4.5 0 0 1 0 7M18.5 6a8 8 0 0 1 0 12",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round"})]})}function jo(){return R.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":!0,children:R.jsx("path",{d:"M8 5.5v13l11-6.5L8 5.5Z"})})}function Ko(){return R.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":!0,children:R.jsx("rect",{x:"6",y:"6",width:"12",height:"12",rx:"1.5"})})}function Go(){return R.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none","aria-hidden":!0,children:R.jsx("path",{d:"M5 6.5A2.5 2.5 0 0 1 7.5 4h9A2.5 2.5 0 0 1 19 6.5v7A2.5 2.5 0 0 1 16.5 16H10l-4 3.5V16H7.5A2.5 2.5 0 0 1 5 13.5v-7Z",stroke:"currentColor",strokeWidth:"2",strokeLinejoin:"round"})})}function is({className:e}){return R.jsx("span",{className:e??"aitwin-widget__spinner","aria-hidden":!0,children:R.jsx("svg",{viewBox:"0 0 24 24",fill:"none",children:R.jsx("circle",{cx:"12",cy:"12",r:"9",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeDasharray:"40 20"})})})}function qo({muted:e,onToggle:t}){return R.jsx("button",{type:"button",className:"aitwin-widget__mute",onClick:t,"aria-label":e?"Unmute":"Mute","aria-pressed":e,children:R.jsx($o,{muted:e})})}function Yo(){return R.jsxs("div",{className:"aitwin-widget__connecting",role:"status","aria-live":"polite",children:[R.jsx(is,{className:"aitwin-widget__spinner aitwin-widget__spinner--accent"}),R.jsx("span",{children:"Connecting..."})]})}function Qo(e){const t=e.connecting||e.textSending||e.status==="loading"||e.status==="speaking",n=e.connecting?"Connecting...":e.connected?"End Talk":"Talk",r=["aitwin-widget__action",e.textMode&&!e.connecting?"":"aitwin-widget__action--primary",e.connecting?"aitwin-widget__action--connecting":""].filter(Boolean).join(" ");return R.jsxs("div",{className:"aitwin-widget__controls",children:[R.jsxs("div",{className:"aitwin-widget__actions",children:[R.jsxs("button",{type:"button",className:r,onClick:e.onTalk,disabled:!e.ready||e.connecting||e.textSending,"aria-busy":e.connecting,children:[e.connecting?R.jsx(is,{className:"aitwin-widget__spinner aitwin-widget__spinner--on-accent"}):e.connected?R.jsx(Ko,{}):R.jsx(jo,{}),R.jsx("span",{children:n})]}),R.jsxs("button",{type:"button",className:e.textMode?"aitwin-widget__action aitwin-widget__action--primary":"aitwin-widget__action",onClick:e.onTextMode,disabled:!e.ready||e.connecting||e.textSending,"aria-pressed":e.textMode,children:[R.jsx(Go,{}),R.jsx("span",{children:"Text"})]})]}),e.textMode?R.jsxs("form",{className:"aitwin-widget__composer",onSubmit:i=>{i.preventDefault(),e.onSendText()},children:[R.jsx("input",{type:"text",className:"aitwin-widget__composer-input",value:e.textDraft,onChange:i=>e.onTextDraftChange(i.target.value),placeholder:e.textSending?"Getting reply...":"Type a message…",autoComplete:"off",disabled:!e.ready||t}),R.jsx("button",{type:"submit",className:"aitwin-widget__composer-send",disabled:!e.ready||t||!e.textDraft.trim()&&!e.textSending,"aria-busy":e.textSending,children:e.textSending?"…":"Send"})]}):null,e.error?R.jsx("p",{className:"aitwin-widget__controls-error",role:"alert",children:e.error}):null]})}const Zr=97,Xo=3500;function Jo(e,t){const n=Math.max(0,e),r=1-Math.exp(-n/Xo);return Math.min(Zr,Math.round(r*Zr))}function Zo(e){const[t,n]=h.useState(null),[r,i]=h.useState(()=>Date.now());return h.useEffect(()=>{if(!e){n(null);return}const s=Date.now();n(s),i(s);let o=0;const a=()=>{i(Date.now()),o=window.requestAnimationFrame(a)};return o=window.requestAnimationFrame(a),()=>{window.cancelAnimationFrame(o)}},[e]),e?t==null?0:Jo(r-t):100}const ec="M259.01,593.87v-101.49c.33-6.31,4.94-11.26,10.21-11.88,6.42-.75,13.18,4.99,13.13,12.92-.42,45.09-.83,90.17-1.25,135.26.03,1.56.56,15.43,11.95,23.2,6.18,4.21,12.57,4.6,15.42,4.58-.42-112.77-.83-225.54-1.25-338.31-.08-2.55-1.03-46.36,21.17-55.34,2.05-.83,4.42-1.41,7.17-1.56v453.42c.07,12.06,1.98,37.84,19.03,62.73,7.01,10.23,14.79,17.71,21.4,22.99V222.42c-.01-3.72.48-11.67,5.35-19.87,7-11.77,18.13-15.82,21.4-16.95,10.42-3.61,19.49-2.06,23.48-1.11v684.96c.59,4.03,1.78,9.72,4.45,16.12,1.93,4.63,8.84,20.57,26.47,31.26,13.48,8.18,26.56,9.23,32.86,9.31-1.3-256.11-2.59-512.22-3.89-768.33.76-16.43,14.57-28.94,29.73-28.34,13.53.53,25.39,11.39,27.23,25.84-1.1,264.68-2.2,529.35-3.3,794.03,4.33.92,22.38,4.25,38.94-6.53,10.26-6.68,15.24-15.72,17.09-19.17,5.55-10.36,6.42-19.98,6.53-25.01-.72-246.99-1.43-493.97-2.15-740.96,2.27-.06,34.75-.44,48.29,22.68,3.41,5.83,4.87,11.86,5.34,17.19v674.68c5.92-2.16,39.19-14.94,50.16-47.79,3.12-9.34,3.68-18.03,3.33-25.01.03-193.22.06-386.43.09-579.65,4.12,1.18,28.28,8.48,36.17,30.08,1.64,4.49,2.32,8.88,2.43,12.92.02,146.42.05,292.84.07,439.25,3.82-1.71,19.51-9.22,25.56-26.47,2.15-6.12,2.48-11.73,2.29-15.89.01-114.91.03-229.81.04-344.72,2.36-.1,7.51.02,12.74,3.13,9.1,5.4,10.87,15.35,11.12,16.88.35,11.49.69,22.97,1.04,34.46.46,37.05.93,74.1,1.39,111.15v152.69c3.39-.72,9.77-2.67,14.31-8.34,3.62-4.52,4.51-9.46,5.56-15.28.91-5.04.95-9.31.83-12.23.02-38.81.03-77.62.05-116.43";function tc({className:e="aitwin-widget__logo",strokeWidth:t=15,durationMs:n=2600,delayMs:r=0,loop:i=!1}){return R.jsx("svg",{viewBox:"0 0 1080 1080",className:e,role:"img","aria-label":"AITWIN logo",children:R.jsx("path",{className:i?"aitwin-widget__logo-draw aitwin-widget__logo-draw--loop":"aitwin-widget__logo-draw",d:ec,fill:"none",stroke:"currentColor",strokeWidth:t,strokeMiterlimit:10,pathLength:1,style:{animationDuration:`${n}ms`,animationDelay:`${r}ms`}})})}function nc({progress:e}){const t=Math.max(0,Math.min(100,Math.round(e)));return R.jsx("div",{className:"aitwin-widget__face-loading","aria-live":"polite","aria-label":`Loading ${t} percent`,children:R.jsxs("div",{className:"aitwin-widget__face-loading-content",children:[R.jsx(tc,{className:"aitwin-widget__logo",loop:!0,durationMs:2600}),R.jsxs("div",{className:"aitwin-widget__face-loading-bar-wrap",children:[R.jsx("div",{role:"progressbar","aria-valuenow":t,"aria-valuemin":0,"aria-valuemax":100,className:"aitwin-widget__face-loading-track",children:R.jsx("div",{className:"aitwin-widget__face-loading-fill",style:{width:`${t}%`}})}),R.jsxs("p",{className:"aitwin-widget__face-loading-pct",children:[t,"%"]})]})]})})}function ei(e){const t=e.id?.trim()||void 0,n=e.faceId?.trim()||e.avatarId?.trim()||void 0;return{id:n?void 0:t,faceId:n,authToken:e.authToken?.trim()||void 0,apiBase:e.apiBase?.trim()||void 0,voiceId:e.voiceId?.trim()||void 0,speakingRate:e.speakingRate,language:e.language}}function rc(e){return[e.id??"",e.faceId??"",e.authToken?.slice(0,16)??"",e.voiceId??"",e.apiBase??"",String(e.speakingRate??"")].join("|")}const ti={display:"flex",alignItems:"center",justifyContent:"center",width:"100%",height:"100%",lineHeight:0},ic={display:"block",height:"100%",width:"100%",objectFit:"cover",objectPosition:"top"},sc=h.forwardRef(function({options:t},n){const r=h.useRef(null),i=h.useRef(t);i.current={...i.current,onReady:t.onReady,onStatusChange:t.onStatusChange,onError:t.onError,onUserTranscript:t.onUserTranscript,onBotOutput:t.onBotOutput};const[s,o]=h.useState(!!t.showControls),[a,u]=h.useState(()=>ei(t)),[d,l]=h.useState(!1),[c,m]=h.useState(!1),[w,T]=h.useState(!1),[f,E]=h.useState(!1),[D,B]=h.useState("idle"),[v,k]=h.useState(null),[L,A]=h.useState(!1),[ie,de]=h.useState(!1),[I,V]=h.useState(""),[G,ae]=h.useState(!1),[se,re]=h.useState([]),[O,J]=h.useState(t.brainId?.trim()||t.personaId?.trim()||void 0),W=h.useCallback(_=>{i.current={...i.current,..._},_.showControls!==void 0&&o(!!_.showControls),(_.brainId!==void 0||_.personaId!==void 0)&&J((_.brainId??_.personaId)?.trim()||void 0),u(U=>ei({id:_.id??U.id,faceId:_.faceId??_.avatarId??U.faceId,authToken:_.authToken??U.authToken,apiBase:_.apiBase??U.apiBase,voiceId:_.voiceId??U.voiceId,speakingRate:_.speakingRate??U.speakingRate,language:_.language??U.language}))},[]);h.useImperativeHandle(n,()=>({getTwin:()=>r.current,applyOptions:W}),[W]),h.useEffect(()=>{W(t)},[W,t.id,t.faceId,t.avatarId,t.authToken,t.apiBase,t.voiceId,t.speakingRate,t.showControls,t.brainId,t.personaId]);const he=h.useCallback(()=>{l(!0),k(null)},[]),K=h.useCallback(_=>{_==="idle"&&m(!0)},[]),ee=h.useCallback(_=>{B(_),i.current.onStatusChange?.(_)},[]),$=h.useCallback(_=>{k(_),l(!1),m(!1),E(!1),i.current.onError?.(_)},[]),X=h.useCallback((_,U)=>{i.current.onUserTranscript?.(_,U)},[]),_e=h.useCallback(_=>{i.current.onBotOutput?.(_)},[]);h.useEffect(()=>{if(!s)return;const _=window.setInterval(()=>{T(!!r.current?.isConnected())},400);return()=>window.clearInterval(_)},[s,a]);const oe=rc(a),b=!!(a.id||a.faceId),P=d&&c,H=b&&!P&&!v,le=Zo(H),j=h.useRef(oe);h.useEffect(()=>{P&&i.current.onReady?.()},[P]),h.useEffect(()=>{P&&r.current?.setMuted(L)},[P,L,a]),h.useEffect(()=>{re([])},[a.id,a.faceId]),h.useEffect(()=>{j.current!==oe&&(j.current=oe,l(!1),m(!1),k(null),E(!1),T(!1),B("idle"))},[oe]);const q=()=>{const _=r.current;if(!_?.isReady())return;if(k(null),de(!1),_.isConnected()){E(!1),_.disconnect().finally(()=>{T(!1)});return}E(!0);const U={authToken:a.authToken,voiceId:a.voiceId,speakingRate:a.speakingRate,language:a.language,apiBase:a.apiBase};_.connect(U).then(()=>{T(!!_.isConnected())}).catch(Z=>{const te=Z instanceof Error?Z.message:"Failed to connect voice.";k(te),i.current.onError?.(te)}).finally(()=>{E(!1)})},p=()=>{de(_=>!_),k(null)},S=()=>{const _=I.trim(),U=r.current;!_||!U?.isReady()||G||(k(null),V(""),ae(!0),i.current.onUserTranscript?.(_,!0),(async()=>{try{const Z=a.authToken?.trim()||await Nt(),te=O||U.getBrainId()?.trim()||void 0,z=await rs({message:_,authToken:Z,apiBase:a.apiBase||ht,brainId:te,history:se});re(be=>[...be,{role:"user",content:_},{role:"assistant",content:z.displayText}]),i.current.onBotOutput?.(z.displayText),await U.speakText(z.spokenText,{voiceId:a.voiceId,speakingRate:a.speakingRate,language:a.language})}catch(Z){const te=Z instanceof Error?Z.message:"Failed to get reply.";k(te),i.current.onError?.(te)}finally{ae(!1)}})())},x=()=>{const _=!L;A(_),r.current?.setMuted(_)};return R.jsxs("div",{className:"aitwin-widget__layout",children:[R.jsxs("div",{className:"aitwin-widget__stage",children:[b?R.jsx("div",{style:ti,children:R.jsx(ns,{ref:r,id:a.id,faceId:a.faceId,authToken:a.authToken,apiBase:a.apiBase,voiceId:a.voiceId,speakingRate:a.speakingRate,language:a.language,style:ti,canvasStyle:ic,onReady:he,onDisplayStatus:K,onStatusChange:ee,onError:$,onUserTranscript:X,onBotOutput:_e,loadingThumbnailUrl:t.loadingThumbnailUrl},oe)}):R.jsx("p",{className:"aitwin-widget__hint",style:{padding:16},children:"Pass id or faceId to load a twin."}),H?R.jsx(nc,{progress:le}):null,s?R.jsx(qo,{muted:L,onToggle:x}):null,s&&f?R.jsx(Yo,{}):null]}),s?R.jsx(Qo,{ready:P,connected:w,connecting:f,status:D,textMode:ie,textDraft:I,textSending:G,error:v,onTalk:q,onTextMode:p,onTextDraftChange:V,onSendText:S}):null]})}),ac=".aitwin-widget{--aitwin-border: rgba(255, 255, 255, .12);--aitwin-text: #f4f4f5;--aitwin-muted: #a1a1aa;--aitwin-accent: #f97316;--aitwin-accent-hover: #fb923c;--aitwin-font: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif;--aitwin-size: 1;--aitwin-stage-width: calc(200px * var(--aitwin-size));--aitwin-stage-height: calc(267px * var(--aitwin-size));--aitwin-action-height: calc(40px * var(--aitwin-size));--aitwin-action-font: calc(13px * var(--aitwin-size));--aitwin-action-radius: calc(10px * var(--aitwin-size));--aitwin-action-gap: calc(6px * var(--aitwin-size));--aitwin-mute-size: calc(28px * var(--aitwin-size));--aitwin-layout-gap: calc(8px * var(--aitwin-size));box-sizing:border-box;color:var(--aitwin-text);font-family:var(--aitwin-font);font-size:calc(12px * var(--aitwin-size));line-height:1.45;width:fit-content;max-width:100%}.aitwin-widget *,.aitwin-widget *:before,.aitwin-widget *:after{box-sizing:border-box}.aitwin-widget__layout{display:flex;flex-direction:column;gap:var(--aitwin-layout-gap);width:fit-content;max-width:100%}.aitwin-widget__stage{align-items:center;background:#0a0a0b;border:1px solid var(--aitwin-border);border-radius:calc(10px * var(--aitwin-size));display:flex;flex-shrink:0;height:var(--aitwin-stage-height);justify-content:center;line-height:0;overflow:hidden;position:relative;width:var(--aitwin-stage-width)}.aitwin-widget__stage .aitwin-root,.aitwin-widget__stage canvas{display:block;height:100%;object-fit:cover;object-position:top;width:100%}.aitwin-widget__hint{color:var(--aitwin-muted);font-size:calc(11px * var(--aitwin-size));margin:0}.aitwin-widget__mute{align-items:center;background:#28282cb8;border:none;border-radius:999px;color:#fff;cursor:pointer;display:inline-flex;height:var(--aitwin-mute-size);justify-content:center;padding:0;position:absolute;right:calc(8px * var(--aitwin-size));top:calc(8px * var(--aitwin-size));width:var(--aitwin-mute-size);z-index:2}.aitwin-widget__mute:hover{background:#37373cd9}.aitwin-widget__mute svg{height:calc(15px * var(--aitwin-size));width:calc(15px * var(--aitwin-size))}.aitwin-widget__controls{display:flex;flex-direction:column;gap:var(--aitwin-action-gap);width:var(--aitwin-stage-width)}.aitwin-widget__actions{display:grid;gap:var(--aitwin-action-gap);grid-template-columns:1fr 1fr;width:100%}.aitwin-widget__action{align-items:center;background:transparent;border:1.5px solid var(--aitwin-accent);border-radius:999px;color:var(--aitwin-accent);cursor:pointer;display:inline-flex;font-family:inherit;font-size:var(--aitwin-action-font);font-weight:600;gap:calc(6px * var(--aitwin-size));height:var(--aitwin-action-height);justify-content:center;padding:0 calc(10px * var(--aitwin-size))}.aitwin-widget__action svg{flex-shrink:0;height:calc(12px * var(--aitwin-size));width:calc(12px * var(--aitwin-size))}.aitwin-widget__action:hover:not(:disabled){background:#f973161a}.aitwin-widget__action:disabled{cursor:not-allowed;opacity:.45}.aitwin-widget__action--primary{background:var(--aitwin-accent);border-color:transparent;color:#fff}.aitwin-widget__action--primary:hover:not(:disabled){background:var(--aitwin-accent-hover)}.aitwin-widget__action--connecting:disabled{cursor:progress;opacity:1}.aitwin-widget__spinner{display:inline-flex;flex-shrink:0;height:calc(14px * var(--aitwin-size));width:calc(14px * var(--aitwin-size))}.aitwin-widget__spinner svg{animation:aitwin-widget-spin .8s linear infinite;display:block;height:100%;width:100%}.aitwin-widget__spinner--accent{color:var(--aitwin-accent);height:calc(16px * var(--aitwin-size));width:calc(16px * var(--aitwin-size))}.aitwin-widget__spinner--on-accent{color:#fff}@keyframes aitwin-widget-spin{to{transform:rotate(360deg)}}.aitwin-widget__connecting{align-items:center;backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);background:#ffffffe0;border-radius:999px;bottom:calc(14px * var(--aitwin-size));box-shadow:0 4px 16px #0000001f;color:#3f3f46;display:inline-flex;font-size:calc(12px * var(--aitwin-size));font-weight:600;gap:calc(8px * var(--aitwin-size));left:50%;line-height:1;padding:calc(8px * var(--aitwin-size)) calc(14px * var(--aitwin-size));pointer-events:none;position:absolute;transform:translate(-50%);z-index:3}.aitwin-widget__face-loading{background:transparent;inset:0;overflow:hidden;pointer-events:none;position:absolute;z-index:4}.aitwin-widget__face-loading-content{align-items:center;display:flex;flex-direction:column;gap:calc(12px * var(--aitwin-size));inset:0;justify-content:center;padding:calc(24px * var(--aitwin-size));position:absolute;z-index:1}.aitwin-widget__logo{color:#fff;display:block;flex-shrink:0;height:calc(64px * var(--aitwin-size));margin-bottom:calc(4px * var(--aitwin-size));width:calc(64px * var(--aitwin-size))}.aitwin-widget__logo-draw{stroke-dasharray:1;stroke-dashoffset:1;animation:aitwin-widget-logo-draw 2.6s ease-in-out forwards}.aitwin-widget__logo-draw--loop{animation:aitwin-widget-logo-draw-loop 2.6s ease-in-out infinite}@keyframes aitwin-widget-logo-draw{to{stroke-dashoffset:0}}@keyframes aitwin-widget-logo-draw-loop{0%{stroke-dashoffset:1}45%{stroke-dashoffset:0}55%{stroke-dashoffset:0}to{stroke-dashoffset:-1}}@media(prefers-reduced-motion:reduce){.aitwin-widget__logo-draw,.aitwin-widget__logo-draw--loop{animation:none;stroke-dashoffset:0}}.aitwin-widget__face-loading-bar-wrap{max-width:calc(220px * var(--aitwin-size));width:100%}.aitwin-widget__face-loading-track{background:#fff3;border-radius:999px;height:calc(4px * var(--aitwin-size));overflow:hidden;width:100%}.aitwin-widget__face-loading-fill{background:var(--aitwin-accent);border-radius:999px;height:100%;transition:width .3s ease-out}.aitwin-widget__face-loading-pct{color:#ffffffbf;font-size:calc(12px * var(--aitwin-size));margin:calc(8px * var(--aitwin-size)) 0 0;text-align:center}.aitwin-widget__composer{display:grid;gap:var(--aitwin-action-gap);grid-template-columns:1fr auto;width:100%}.aitwin-widget__composer-input{background:#ffffff0a;border:1px solid var(--aitwin-border);border-radius:var(--aitwin-action-radius);color:var(--aitwin-text);font-family:inherit;font-size:calc(12px * var(--aitwin-size));min-width:0;outline:none;padding:calc(8px * var(--aitwin-size)) calc(10px * var(--aitwin-size))}.aitwin-widget__composer-input:focus{border-color:#f973168c}.aitwin-widget__composer-send{background:var(--aitwin-accent);border:none;border-radius:var(--aitwin-action-radius);color:#fff;cursor:pointer;font-family:inherit;font-size:calc(12px * var(--aitwin-size));font-weight:600;padding:0 calc(12px * var(--aitwin-size))}.aitwin-widget__composer-send:disabled{cursor:not-allowed;opacity:.45}.aitwin-widget__controls-error{color:#fecaca;font-size:calc(11px * var(--aitwin-size));margin:0}.aitwin-widget--float{bottom:20px;filter:drop-shadow(0 12px 32px rgba(0,0,0,.45));height:fit-content;margin:0;max-width:calc(100vw - 40px);position:fixed;right:20px;width:fit-content;z-index:2147483000}",ni="data-aitwin-widget-style";function ss(){if(typeof document>"u")return;const e=ac.trim();if(!e){console.warn("[AiTwinWidget] styles.css?inline resolved empty — chrome will be unstyled");return}const t=document.querySelector(`style[${ni}]`);if(t){if((t.textContent??"").trim().length>0)return;t.textContent=e;return}const n=document.createElement("style");n.setAttribute(ni,"1"),n.textContent=e,(document.head??document.documentElement).appendChild(n)}typeof document<"u"&&ss();const oc=h.forwardRef(function(t,n){ss();const r=h.useRef(null);h.useImperativeHandle(n,()=>({speakText:async(s,o)=>{const a=r.current?.getTwin();if(!a)throw new Error("AiTwinWidget: twin is not mounted");return a.speakText(s,o)},connect:async s=>{const o=r.current?.getTwin();if(!o)throw new Error("AiTwinWidget: twin is not mounted");return o.connect(s)},disconnect:async()=>{const s=r.current?.getTwin();if(s)return s.disconnect()},stop:()=>{r.current?.getTwin()?.stop()},isReady:()=>!!r.current?.getTwin()?.isReady(),isConnected:()=>!!r.current?.getTwin()?.isConnected(),getTwin:()=>r.current?.getTwin()??null}),[]);const i=!!t.float;return R.jsx("div",{className:i?"aitwin-widget aitwin-widget--float":"aitwin-widget",children:R.jsx(sc,{ref:r,options:t})})}),cc=new Set([".png",".jpg",".jpeg",".webp"]);function as(e=".png"){const t=e.toLowerCase();return cc.has(t)?`source${t}`:"source.png"}function lc(e,t=$n,n=".png"){const r=e.trim();if(!r)throw new Error("faceId is required");return`${t.replace(/\/$/,"")}/${r}/${as(n)}`}exports.AI_TWIN_THUMBNAIL_FILENAME=Yn;exports.AiTwin=ns;exports.AiTwinNotFoundError=nn;exports.AiTwinWidget=oc;exports.CONSONANT_SKIP_GROUP=Ti;exports.DEFAULT_TTS_ENGINE_ID=dt;exports.DEFAULT_TTS_LANGUAGE=Vs;exports.EMOTION_TO_EYEBROW=Gi;exports.EXPRESSION_ATLAS_EMOTIONS=Ra;exports.MIC_SAMPLE_RATE=nr;exports.OCULUS_VISEME_IDS=vi;exports.PLAYBACK_SAMPLE_RATE=rr;exports.SPEAKING_RATE_MAX=yn;exports.SPEAKING_RATE_MIN=pn;exports.TTS_ENGINE_CARTESIA=tt;exports.TTS_ENGINE_GOOGLE=Kn;exports.TTS_ENGINE_INWORLD=un;exports.TTS_ENGINE_VISEMETTS=nt;exports.TTS_LANGUAGE_CATALOG=ft;exports.TTS_LANGUAGE_CODES=wi;exports.VISEME_IDS=_a;exports.VISEME_SKIP_GAP_MS=On;exports.VISEME_TEST_CARTESIA_VOICE_ID=tr;exports.VISEME_TEST_SPEAKING_RATE=Ht;exports.VISEME_TEST_VISEMETTS_VOICE_ID=dn;exports.VISEME_TEST_VOICE_ID=er;exports.VISEME_VTIME_GRID_MS=Qn;exports.VOWEL_SKIP_GROUP=Si;exports.aiTwinSourceFilename=as;exports.buildPlaybackTransitions=Pi;exports.buildPlaybackVisemeSeries=gn;exports.buildRawVisemeTransitions=Mi;exports.buildVoiceWebSocketUrl=Ni;exports.compactSkippableVisemes=Jn;exports.createAvatarTtsLipsyncController=Nn;exports.createRealtimeVoiceLipsyncController=Vi;exports.emotionToEyebrow=mt;exports.faceAssetUrls=Ln;exports.fetchAiTwin=ci;exports.fetchAvatarReply=rs;exports.fetchDevAuthToken=Nt;exports.getAiTwinSourceUrl=lc;exports.getAiTwinThumbnailUrl=li;exports.isTtsLanguageCode=pi;exports.isTtsLanguageSupported=Ws;exports.listSkippedVisemeEntries=wn;exports.listSkippedVisemes=Js;exports.normalizeOculusViseme=mn;exports.normalizeStreamEmotion=Ze;exports.normalizeTtsLanguage=fn;exports.parsePackedVoiceId=si;exports.resolveDirectFaceId=ui;exports.resolveTwinBrainId=qn;exports.resolveVisemeAtTime=zt;exports.resolveVisemeFromPlaybackSeries=xi;exports.resolveWordAtTime=oa;exports.setActiveTwinAssets=di;exports.snapVisemeQueueToGrid=Xn;exports.snapVisemeVtimeToGrid=ki;exports.splitVoiceIdSpec=et;exports.ttsLanguagesForEngine=Us;
|
|
47
|
+
`;function qr(e=5){const t=new we.Filter({glProgram:we.GlProgram.from({vertex:Mo,fragment:Po,name:"threshold-key-filter"}),resources:{thresholdUniforms:{uThreshold:{value:e/255,type:"f32"}}}});return t.setThreshold=n=>{t.resources.thresholdUniforms.uniforms.uThreshold=n/255},t.getThreshold=()=>Math.round(t.resources.thresholdUniforms.uniforms.uThreshold*255),t}function Ro(e,t,n){return e>n||t>n}function Co(e){return e?e.getParameter(e.MAX_TEXTURE_SIZE):4096}function Do(e,t){return t!=null&&t>0?Math.floor(t):Co(e)}function Bo(e,t){const n=document.createElement("canvas");n.width=t.w,n.height=t.h;const r=n.getContext("2d");if(!r)throw new Error("Failed to acquire 2d context for atlas cell crop");return r.drawImage(e,t.x,t.y,t.w,t.h,0,0,t.w,t.h),n}function ns(e){return fetch(e).then(t=>{if(!t.ok)throw new Error(`Failed to load image: ${e}`);return t.blob()}).then(t=>createImageBitmap(t))}async function Yr(e,t,n,r,i){const s=n?await $i(e,i):await fetch(e).then(c=>{if(!c.ok)throw new Error(`Failed to load ${e}`);return c.json()}),o=s.sheets?.[0];if(!o?.path)throw new Error(`${e} has no sheets[0].path`);const a=new Map,u=async(c,m)=>{const w=Gi(t,m,n),S=n?await wa(await Pt(w,i??"")):await ns(w);if(Ro(S.width,S.height,r))return console.info(`[PixiVisemeCompositor] Sheet ${m} (${S.width}x${S.height}) exceeds MAX_TEXTURE_SIZE=${r}; using per-cell crops.`),{mode:"cells",bitmap:S};const f=we.Texture.from(S);return f.source.scaleMode="nearest",{mode:"full",texture:f}};a.set(o.index,await u(o.index,o.path));for(const c of s.sheets??[])c.index!==o.index&&c.path&&a.set(c.index,await u(c.index,c.path));const d=new Map;for(const c of s.cells??[])c.path&&d.set(c.path,c);const l=new Map;for(const c of s.sheets??[])l.set(c.index,c);return{atlasMeta:s,cellByPath:d,sheetByIndex:l,diffBase:t,sheets:a}}async function Fo(e,t={}){const n=new we.Application;try{await n.init({canvas:e,width:842,height:1264,preference:"webgl",autoStart:!1,antialias:!1,resolution:1,autoDensity:!1,backgroundAlpha:1,backgroundColor:0,powerPreference:"high-performance"})}catch(p){throw n.destroy({removeView:!1}),p}if(n.renderer.type!==we.RendererType.WEBGL)throw n.destroy({removeView:!1}),new Error("Pixi did not initialize a WebGL renderer");const r=Do(n.renderer.gl,t.maxTextureSize);let i=!1,s=!1,o=!1;const a=n.canvas,u=()=>{i=!0,!s&&!o&&(s=!0,t.onWebGlContextLost?.())};a.addEventListener("webglcontextlost",u);const d=new we.Sprite(we.Texture.EMPTY),l=new we.Sprite(we.Texture.EMPTY);l.visible=!1,l.alpha=0;const c=new we.Sprite(we.Texture.EMPTY),m=new we.Sprite(we.Texture.EMPTY),w=new we.Sprite(we.Texture.EMPTY);w.visible=!1;const S=qr(5),f=qr(5);c.filters=[S],m.filters=[f],n.stage.addChild(d),n.stage.addChild(l),n.stage.addChild(c),n.stage.addChild(m),n.stage.addChild(w);let E=null,D=null,B=null,v=null,k=null,O=null,A=null,se=842,le=1264,I=null,U=5;const q=new Map;let oe=null,ae=null,ie=null;const L=mi(()=>{q.clear(),O=null,A=null,E=null,I=null}),Z=(p,b)=>{se=p,le=b,n.renderer.resize(p,b),(e.width!==p||e.height!==b)&&(e.width=p,e.height=b)},H=()=>{c.visible=!1,m.visible=!1,c.texture=we.Texture.EMPTY,m.texture=we.Texture.EMPTY,oe=null,ae=null},me=()=>{k=null,l.visible=!1,l.alpha=0},z=()=>{d.visible=!0,d.width=se,d.height=le,d.x=0,d.y=0},te=()=>{l.width=se,l.height=le,l.x=0,l.y=0},j=()=>{w.visible=!1,me(),E&&(d.texture=E,z())},J=()=>{!k&&!l.visible||j()},Se=p=>{if(o||i||!E){j();return}const b=Math.max(0,p);if(!D||b<=0){j();return}H(),w.visible=!1,d.texture=D,z(),l.texture=E,te(),l.alpha=0,l.visible=!0,k={startMs:performance.now(),durationMs:b},Y()},ue=(p=performance.now())=>{if(!k)return!1;if(o||i)return J(),!1;const b=(p-k.startMs)/Math.max(1,k.durationMs);if(b>=1)return j(),Y(),!1;const x=Math.min(1,Math.max(0,b)),W=x*x*(3-2*x);return l.alpha=W,l.visible=!0,Y(),!0},_=()=>{if(B){try{B.resource=null}catch{}B.destroy(),B=null}D&&(D.destroy(!1),D=null),v=null},C=(p,b)=>{const x=p.cellByPath.get(b);if(!x||!Hi(x))return null;const W=`${p.diffBase}::${b}`;let ee=q.get(W);if(!ee){const T=x.sheet??0,Q=p.sheets.get(T);if(!Q)return null;let V,he=!1;if(Q.mode==="full")V=new we.Texture({source:Q.texture.source,frame:new we.Rectangle(x.x,x.y,x.w,x.h)});else{const De=Bo(Q.bitmap,x);V=we.Texture.from(De),V.source.scaleMode="nearest",he=!0}ee={texture:V,ownsSource:he},q.set(W,ee)}return{texture:ee.texture,cell:x}},$=(p,b,x,W)=>{if(!W||!x)return p.visible=!1,p.texture=we.Texture.EMPTY,!1;const ee=C(x,W);if(!ee)return p.visible=!1,p.texture=we.Texture.EMPTY,!1;const T=zi(x.atlasMeta,ee.cell);return b.setThreshold(U),p.texture=ee.texture,p.x=T.x,p.y=T.y,p.width=ee.cell.w,p.height=ee.cell.h,p.visible=!0,!0},re=p=>{if(!p||!O)return null;const b=I??new Set(O.cellByPath.keys());return sr(p,b)??(b.has(p)?p:null)},K=p=>{w.visible=!1,j();const b=re(p.mouthPath),x=p.expressionPath&&A?or(p.expressionPath,W=>A.cellByPath.has(W)):null;b!==oe?($(c,S,O,b),oe=b):b?c.visible=!0:c.visible=!1,x!==ae?($(m,f,A,x),ae=x):x?m.visible=!0:m.visible=!1},Y=()=>{if(!(o||i||document.hidden))try{n.render()}catch{}};return{async loadAssets(p){if(o)return{width:se,height:le,visemePaths:[]};const b=Wt();if(b&&!p)throw new Error("Encrypted assets enabled but no key provided");const x=b?await ya(await Pt(sn(),p??"")):await ns(sn());E&&E.destroy(!0),E=we.Texture.from(x),E.source.scaleMode="linear";const W=hi();O=await Yr(gi(),W,b,r,p);try{A=await Yr(wi(),W,b,r,p)}catch(T){console.warn("[PixiVisemeCompositor] expression atlas unavailable:",T),A=null}const ee=Wi(O.atlasMeta,x.width,x.height);return Z(ee.width,ee.height),U=vn(O.atlasMeta),S.setThreshold(U),f.setThreshold(U),I=new Set(O.cellByPath.keys()),q.clear(),j(),H(),Y(),{width:ee.width,height:ee.height,visemePaths:[...O.cellByPath.keys()]}},getVisemeAtlasPaths(){return I},drawLiveFrame(p){o||i||!E||(J(),K(p),Y())},drawIdleVideo(p,b){o||i||document.hidden||b&&!b()||p.readyState<HTMLMediaElement.HAVE_CURRENT_DATA||(me(),H(),w.visible=!1,!D||v!==p?(_(),B=new we.VideoSource({resource:p,autoPlay:!1,updateFPS:0}),B.autoUpdate=!1,D=new we.Texture({source:B}),v=p):D.source.update(),d.texture=D,z(),Y())},beginIdleToSilCrossfade:Se,tickIdleToSilCrossfade:ue,finishIdleToSilCrossfade:J,isIdleToSilCrossfading(){return k!=null},renderSilOnly(){o||i||!E||(H(),j(),Y())},blitBitmap(p){o||i||(J(),H(),ie&&(ie.destroy(!0),ie=null),ie=we.Texture.from(p),w.texture=ie,w.visible=!0,w.x=0,w.y=0,w.width=se,w.height=le,d.visible=!1,Y())},async compositePrefetchFrame(p){return null},renderFrame:Y,isContextLost(){return i},dispose(){if(o)return;o=!0,a.removeEventListener("webglcontextlost",u),L(),_(),ie&&(ie.destroy(!0),ie=null);for(const{texture:b,ownsSource:x}of q.values())b.destroy(x);q.clear(),E&&(E.destroy(!0),E=null);const p=b=>{b.mode==="full"?b.texture.destroy(!0):b.bitmap.close()};if(O)for(const b of O.sheets.values())p(b);if(A)for(const b of A.sheets.values())p(b);S.destroy(!0),f.destroy(!0),n.destroy({removeView:!1},{children:!0,texture:!0})}}}const Qr=-1,tn=1e5,Xr=new Map;async function Lo(e){let t=Xr.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),Xr.set(e,t)}return new Worker(t,{name:"visemeDiffPreview"})}function Oo(){return typeof Worker<"u"&&typeof OffscreenCanvas<"u"}function zn(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 Jr(e,t){let n=0,r=null;const i=mr(async(s,o)=>(await Vn(),await Wn(e,s),i.isLatestSeq(o)));return{usesWorker:!1,usesPixi:!1,async loadAssets(s){const o=await Vn(s);return r=o.visemePaths?new Set(o.visemePaths):null,o},getVisemeAtlasPaths(){return r},async renderSilOnly(){n+=1,i.reset(),await no(e)},drawLiveFrame(s,o,a,u){i.enqueue(o,a,u)},async compositePrefetchFrame(s,o){try{return await to(s)}catch{return null}},blitBitmap(s,o){zn(s,o)},drawIdleVideo(){},beginIdleToSilCrossfade(){},tickIdleToSilCrossfade(){return!1},finishIdleToSilCrossfade(){},isIdleToSilCrossfading(){return!1},supportsBufferedPlayback:!0,async renderViseme(s,o){n+=1;const a=n;t.onStatus?.(o),await Wn(s,{mouthPath:It(o),expressionPath:null})},dispose(){n+=1,i.reset()}}}function No(e,t,n){let r=null,i=1,s=0,o=!1,a=!1,u=null;const d=new Map,l=new Map;let c=tn;const m=mr(async(B,v,k)=>(d.set(v,{drawKey:k.drawKey,onDisplayed:k.onDisplayed}),await E({type:"drawFrame",diffPath:B.mouthPath,expressionDiffPath:B.expressionPath,liveSeq:v},void 0,!0),!1)),w=B=>{if(B===Qr){let O=-1,A;for(const[se,le]of d)se>=O&&(O=se,A=le);O>=0&&d.delete(O),A?.onDisplayed?.(A.drawKey);return}const v=-B,k=d.get(v);d.delete(v),k?.onDisplayed?.(k.drawKey)},S=new Map,f=(B,v)=>{a||!r||r.postMessage(B,[])},E=(B,v,k=!1)=>{if(a)return Promise.resolve();const O=i++;return new Promise((A,se)=>{S.set(O,{resolve:le=>A(le),reject:se,generation:typeof B.generation=="number"?B.generation:void 0,expectRenderDone:k}),f({...B,requestId:O})})},D=(async()=>{r=await Lo(n),r.onmessage=B=>{if(a)return;const v=B.data;if(v.type==="status"){t.onStatus?.(v.label);return}if(v.type==="frame"){if(v.generation<=-tn){const A=-v.generation,se=l.get(A);l.delete(A),se?.resolve(v.bitmap);return}const O=v.generation<0;if(!O&&v.generation!==s){v.bitmap.close();return}if(O&&!(v.generation===Qr)){const se=-v.generation;if(!m.isLatestSeq(se)){at()?.onWorkerStale(),v.bitmap.close();return}}if(O&&t.shouldAcceptLiveFrame&&!t.shouldAcceptLiveFrame()){at()?.onWorkerStale(),v.bitmap.close();return}zn(e,v.bitmap),v.bitmap.close(),O&&w(v.generation);return}const k=S.get(v.requestId);if(k)switch(v.type){case"ready":S.delete(v.requestId),k.resolve();break;case"loadAssetsDone":S.delete(v.requestId),u=v.visemePaths?.length?new Set(v.visemePaths):null,k.resolve({width:v.width,height:v.height,visemePaths:v.visemePaths});break;case"renderDone":if(k.expectRenderDone&&k.generation!=null&&v.generation!==k.generation)return;S.delete(v.requestId),k.resolve();break;case"renderAborted":S.delete(v.requestId),k.resolve();break;case"error":S.delete(v.requestId),t.onError?.(v.message),k.reject(new Error(v.message));break}},r.onerror=B=>{if(a)return;const v=B.message||"Worker error";t.onError?.(v);for(const[,k]of S)k.reject(new Error(v));S.clear()},await E({type:"init"}),o=!0})();return{usesWorker:!0,usesPixi:!1,async loadAssets(B){if(a)return{width:842,height:1264};if(await D,a)return{width:842,height:1264};if(!o)throw new Error("Worker init failed");return await E({type:"loadAssets",keyHex:B,urls:Ls(pt())})??{width:842,height:1264}},getVisemeAtlasPaths(){return u},async renderSilOnly(){if(a||(await D,a))return;s+=1,m.reset(),d.clear(),l.forEach(({resolve:v})=>v(null)),l.clear(),c=tn;const B=s;await E({type:"cancelLiveDraws"}),await E({type:"renderSil",generation:B},void 0,!0)},drawLiveFrame(B,v,k,O){a||D.then(()=>{a||m.enqueue(v,k,O)})},compositePrefetchFrame(B,v){return a?Promise.resolve(null):D.then(()=>{if(a)return null;const k=++c;return new Promise(O=>{l.set(k,{resolve:O}),E({type:"drawFrame",diffPath:B.mouthPath,expressionDiffPath:B.expressionPath,liveSeq:k},void 0,!0).catch(()=>{l.delete(k),O(null)})})})},blitBitmap(B,v){zn(B,v)},drawIdleVideo(){},beginIdleToSilCrossfade(){},tickIdleToSilCrossfade(){return!1},finishIdleToSilCrossfade(){},isIdleToSilCrossfading(){return!1},supportsBufferedPlayback:!0,async renderViseme(B,v,k={}){if(a||(await D,a))return;s+=1,m.reset(),d.clear();const O=s;try{await E({type:"cancelLiveDraws"}),await E({type:"renderViseme",generation:O,to:v,from:k.from,transitionDurationMs:k.transitionDurationMs,gapMs:k.gapMs,threshold:k.threshold},void 0,!0)}catch(A){if(A?.name==="AbortError")return;throw A}},dispose(){if(!a){a=!0,s+=1,m.reset(),d.clear(),l.forEach(({resolve:B})=>B(null)),l.clear(),c=tn;for(const[,B]of S)B.resolve();S.clear(),r?.terminate(),r=null}}}}async function Uo(e,t){const n=await Fo(e,{onWebGlContextLost:t.onWebGlContextLost,maxTextureSize:t.pixiMaxTextureSize});let r=0,i=null,s=!1;const o=mr(async(a,u)=>s?!1:t.shouldAcceptLiveFrame&&!t.shouldAcceptLiveFrame()?(at()?.onWorkerStale(),!1):(n.drawLiveFrame(a),o.isLatestSeq(u)));return{usesWorker:!1,usesPixi:!0,async loadAssets(a){if(s)return{width:842,height:1264};const u=await n.loadAssets(a);return i=u.visemePaths?.length?new Set(u.visemePaths):null,u},getVisemeAtlasPaths(){return i},async renderSilOnly(){s||(r+=1,o.reset(),n.renderSilOnly())},drawLiveFrame(a,u,d,l){s||o.enqueue(u,d,l)},async compositePrefetchFrame(a,u){if(s)return null;try{return await n.compositePrefetchFrame(a)}catch{return null}},blitBitmap(a,u){s||t.shouldAcceptLiveFrame&&!t.shouldAcceptLiveFrame()||n.blitBitmap(u)},drawIdleVideo(a,u){s||n.drawIdleVideo(a,u)},beginIdleToSilCrossfade(a){s||n.beginIdleToSilCrossfade(a)},tickIdleToSilCrossfade(a){return s?!1:n.tickIdleToSilCrossfade(a)},finishIdleToSilCrossfade(){s||n.finishIdleToSilCrossfade()},isIdleToSilCrossfading(){return s?!1:n.isIdleToSilCrossfading()},supportsBufferedPlayback:!1,async renderViseme(a,u){if(s)return;r+=1;const d=r;o.reset(),t.onStatus?.(u),n.drawLiveFrame({mouthPath:It(u),expressionPath:null})},dispose(){s||(s=!0,r+=1,o.reset(),n.dispose())}}}function Zr(e,t){if(!Oo())return Jr(e,t);const n=ps(t.workerScriptUrl);try{return No(e,t,n)}catch{return Jr(e,t)}}function Vo(e,t={}){if(t.preferLegacyRenderer)return Zr(e,t);let n=null,r=!1,i=null,s=!1;const o=()=>n?Promise.resolve(n):(i||(i=(async()=>{try{const a=await Uo(e,t);if(s)throw a.dispose(),new Error("Renderer disposed during Pixi init");return r=!0,n=a,a}catch(a){if(s)throw a instanceof Error?a:new Error(String(a));return console.warn("[AiTwin] Pixi WebGL renderer unavailable, using Canvas2D fallback:",a),n=Zr(e,t),r=!1,n}})()),i);return{get usesWorker(){return n?.usesWorker??!1},get usesPixi(){return r},async loadAssets(a){return(await o()).loadAssets(a)},getVisemeAtlasPaths(){return n?.getVisemeAtlasPaths()??null},async renderSilOnly(){return(await o()).renderSilOnly()},drawLiveFrame(a,u,d,l){o().then(c=>{s||c.drawLiveFrame(a,u,d,l)})},async compositePrefetchFrame(a,u){return(await o()).compositePrefetchFrame(a,u)},blitBitmap(a,u){n&&n.blitBitmap(a,u)},drawIdleVideo(a,u){n?.usesPixi&&n.drawIdleVideo(a,u)},beginIdleToSilCrossfade(a){n?.beginIdleToSilCrossfade(a)},tickIdleToSilCrossfade(a){return n?.tickIdleToSilCrossfade(a)??!1},finishIdleToSilCrossfade(){n?.finishIdleToSilCrossfade()},isIdleToSilCrossfading(){return n?.isIdleToSilCrossfading()??!1},get supportsBufferedPlayback(){return n?.supportsBufferedPlayback??!1},async renderViseme(a,u,d){return(await o()).renderViseme(a,u,d)},dispose(){s=!0,i=null,n?.dispose(),n=null}}}class Wo extends Error{constructor(t,n){super(`${t} timed out after ${Math.round(n/1e3)}s`),this.name="LoadTimeoutError"}}function Rn(e,t,n){return new Promise((r,i)=>{const s=globalThis.setTimeout(()=>{i(new Wo(n,t))},t);e.then(o=>{globalThis.clearTimeout(s),r(o)},o=>{globalThis.clearTimeout(s),i(o)})})}const zo={overflow:"hidden",position:"relative",display:"inline-block",lineHeight:0},Ho={display:"block",maxWidth:"100%",height:"auto"},$o={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 Cn(e){return Ts(e)?nr:ci(e)?dn:tr}function Je(e,t){return t?.isSpeaking()||t?.isWarmingUp()?t:e.isSpeaking()||e.isWarmingUp()?e:t?.isConnected()?t:e}const rs=h.forwardRef(function({id:t,avatarId:n,faceId:r,assets:i,authToken:s,apiBase:o,ttsEngineId:a,voiceId:u,language:d,speakingRate:l=Ht,className:c,style:m,canvasStyle:w,onStatusChange:S,onDisplayStatus:f,onError:E,onReady:D,showErrorOverlay:B=!0,loadingThumbnailUrl:v,onUserTranscript:k,onBotOutput:O,onRealtimeLipsyncDebug:A,onFrameRenderStats:se,lipsyncBufferedPlayback:le=!0,lipsyncPlaybackWarmupMs:I=1500,idleHandoffHoldMs:U=wo,pixiMaxTextureSize:q,captions:oe},ae){const ie=h.useRef(null),L=h.useRef(null),Z=h.useRef(null),H=h.useRef(le);H.current=le;const me=h.useRef(I);me.current=I;const z=h.useRef(U);z.current=U;const te=h.useRef(0),j=h.useRef(dr()),J=h.useRef(ja()),Se=h.useRef(!1),ue=h.useRef(null),_=h.useRef(null),C=h.useRef(0),$=h.useRef(0),re=h.useRef(0),K=h.useRef(null),Y=h.useRef(null),p=h.useRef(!1),b=h.useRef(!1),x=h.useRef(!1),W=h.useRef(!1),ee=h.useRef("sil"),T=h.useRef(0),Q=h.useRef(!1),V=h.useRef(null),he=h.useRef(!1),[De,ot]=h.useState("idle"),[yt,Rt]=h.useState(null),[ct,_n]=h.useState(!1),[g,P]=h.useState(!1),[ne,ce]=h.useState(!1),[Te,be]=h.useState(),[ke,ze]=h.useState({width:842,height:1264}),[Ne,$t]=h.useState(null),[bn,Ct]=h.useState(0),vt=h.useRef(!1),Be=h.useRef(s??null),$e=o?.trim()||gt,_t=h.useRef(null),Ee=h.useRef(null),{ttsEngineId:Ie,voiceId:je}=h.useMemo(()=>{const y=et(a,u),M=y.ttsEngineId??ft;return{ttsEngineId:M,voiceId:y.voiceId??Cn(M)}},[a,u]),Ke=h.useRef(!1),rt=h.useRef({width:842,height:1264}),ye=h.useRef(null),Ue=h.useRef("sil"),Re=h.useRef(""),Ve=h.useMemo(()=>io(oe),[oe]),We=h.useCallback(()=>{Re.current="",$t(null)},[]);h.useEffect(()=>{Ve.enabled||We()},[Ve.enabled,We]);const Dt=h.useCallback(y=>{if(!Ve.enabled)return;const M=y.isSpeaking(),N=y.isWarmingUp();if(!M||N){Re.current&&We();return}const F=ro(y.getWordQueue());if(!F){Re.current&&We();return}F!==Re.current&&(Re.current=F,$t(F))},[Ve.enabled,We]),lt=h.useRef(void 0),Bt=h.useRef(new Map),hr=h.useRef(D),gr=h.useRef(S),ve=h.useRef(f),wr=h.useRef(E),pr=h.useRef(k),yr=h.useRef(O),jt=h.useRef(A),vr=h.useRef(se),bt=h.useRef(go());hr.current=D,gr.current=S,ve.current=f,wr.current=E,pr.current=k,yr.current=O,jt.current=A,vr.current=se,h.useEffect(()=>{const y=bt.current;return Hr(y),()=>Hr(null)},[]);const _r=h.useCallback(y=>{const M=et(y?.ttsEngineId??a,y?.voiceId??u),N=M.ttsEngineId??Ee.current?.ttsEngineId??ft,F=M.voiceId??Ee.current?.voiceId??Cn(N);return{ttsEngineId:N,voiceId:F}},[a,u]),it=h.useCallback(y=>{Rt(y),ce(!0),wr.current?.(y)},[]),Ft=h.useCallback(y=>{ot(y),gr.current?.(y)},[]),de=h.useRef(Nn(Ft,$e,{onLipsyncDebug:y=>jt.current?.(y)})),fe=h.useRef(null),br=h.useRef(()=>{});h.useEffect(()=>(de.current=Nn(Ft,$e,{onLipsyncDebug:y=>jt.current?.(y)}),s&&de.current.setDeveloperToken(s),de.current.setTtsEngineId(Ie),()=>{de.current.stop();const y=fe.current;y&&(y.disconnect(),fe.current=null)}),[Ft,$e]);const Sr=h.useCallback(()=>(fe.current||(fe.current=Vi(Ft,{speakingRate:l,language:d,onUserTranscript:(y,M)=>pr.current?.(y,M),onBotOutput:y=>yr.current?.(y),onLipsyncDebug:y=>jt.current?.(y)}),fe.current.setTtsEngineId(Ie),br.current(!0)),fe.current),[Ft,l,d,Ie]),Fe=h.useCallback(()=>{K.current!=null&&(clearTimeout(K.current),K.current=null)},[]),Le=h.useCallback(()=>{Y.current!=null&&(clearTimeout(Y.current),Y.current=null),x.current=!1},[]),Kt=h.useCallback(()=>{if(W.current)return;const y=L.current;if(W.current=!0,Le(),p.current=!1,b.current=!1,!he.current||!V.current){y?.renderSilOnly();return}V.current.setActive(!1);const M=V.current.getVideo();if(y?.usesPixi){y.drawIdleVideo(M),y.beginIdleToSilCrossfade(jr);return}(async()=>{const N=ie.current;N&&await Mn(N,M,null,void 0,rt.current).catch(()=>{}),await new Promise(F=>setTimeout(F,jr)),W.current&&await y?.renderSilOnly()})()},[Le]),Tr=h.useCallback(()=>{!he.current||!V.current||(W.current=!1,L.current?.finishIdleToSilCrossfade(),Le(),x.current=!0,Y.current=setTimeout(()=>{if(Y.current=null,Je(de.current,fe.current).isSpeaking()){x.current=!1;return}if(p.current){x.current=!1;return}const y=V.current;if(!y){x.current=!1;return}y.restart(),y.setActive(!0);const M=y.getVideo();let N=!1;const F=()=>{N||(N=!0,M.removeEventListener("playing",X),x.current=!1)},X=()=>{F()};if(M.addEventListener("playing",X,{once:!0}),M.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA&&!M.paused){F();return}setTimeout(F,300)},z.current))},[Le]),St=h.useCallback(()=>{if(Fe(),ve.current?.("sil"),p.current=!1,W.current=!1,!he.current||!V.current){x.current=!1;return}Tr()},[Fe,Tr]),Sn=h.useCallback(async y=>{const M=$.current,N=L.current,F=ie.current,X=()=>{y?.fallbackOnly||(p.current=!1)};if(!N||!F||!ct){X();return}if(Je(de.current,fe.current).isSpeaking()){X();return}if(y?.fallbackOnly){if(!p.current||(Oe(j.current),await N.renderSilOnly(),M!==$.current)||Je(de.current,fe.current).isSpeaking())return;St();return}if(Kr(j.current)){Oe(j.current),St();return}if(H.current&&N.supportsBufferedPlayback&&!y?.fallbackOnly){if(Oe(j.current),Z.current?.reset(),await N.renderSilOnly(),M!==$.current||Je(de.current,fe.current).isSpeaking())return;St();return}const xe=bo(Je(de.current,fe.current).getVisemeQueue(),T.current,ee.current),Me=So(xe,ye.current);if(Oe(j.current),!Me){if(await N.renderSilOnly(),M!==$.current||Je(de.current,fe.current).isSpeaking())return;St();return}try{await N.renderViseme(F,"sil",{from:xe,transitionDurationMs:Zi})}catch(Ce){if(Ce?.name!=="AbortError")throw Ce}if(M!==$.current){X();return}if(Je(de.current,fe.current).isSpeaking()){X();return}St()},[ct,St]),Tt=h.useCallback(()=>{if(b.current||p.current)return;b.current=!0,p.current=!0,Fe();const y=$.current;Sn().finally(()=>{b.current=!1}),K.current=setTimeout(()=>{K.current=null,y===$.current&&Sn({fallbackOnly:!0})},To())},[Fe,Sn]),kr=h.useCallback(async()=>{const y=Math.floor(Date.now()/1e3);if(_t.current&&y<_t.current.expiresAt-60)return _t.current.key;const M=Be.current??await Nt();Be.current=M,de.current.setDeveloperToken(M);const N=await Cs(M,$e);return _t.current={key:N.value,expiresAt:N.expiresAt},N.value},[$e]);h.useEffect(()=>{s&&(Be.current=s,de.current.setDeveloperToken(s))},[s]),h.useEffect(()=>{de.current.setTtsEngineId(Ie),fe.current?.setTtsEngineId(Ie),Ee.current&&(Ee.current.ttsEngineId=Ie)},[Ie]),h.useEffect(()=>{Ee.current&&(Ee.current.voiceId=je)},[je]);const Ge=h.useMemo(()=>di(n,r),[n,r]),cs=h.useMemo(()=>i?JSON.stringify(i):Ge?`face:${Ge}`:`id:${t??""}`,[i,Ge,t]),ls=h.useMemo(()=>{const y=v?.trim();return y||(Ir(Ge)??Ir(Te)??xs(i))},[v,Ge,Te,i]);return h.useEffect(()=>{if(!t&&!i&&!Ge){it("AiTwin requires `assets`, `avatarId`/`faceId`, or `id`");return}let y=!1;Ke.current=!1,_n(!1),P(!1),ce(!1),be(Ge),Rt(null),Ee.current=null,V.current=null,he.current=!1;const M=ie.current;if(!M)return;let N=null;return(async()=>{try{let F,X,Ae,xe,Me;if(i)F=i,X=Ie,Ae=je;else if(Ge)ve.current?.("loadFace"),F=Ln(Ge),X=Ie,Ae=je;else{ve.current?.("getAiTwin");const G=await Rn(li(t),3e4,"getAiTwin");if(y)return;if(!G.faceId?.trim())throw new Error("getAiTwin returned no faceId");be(G.faceId.trim());const _e=et(a,u);X=_e.ttsEngineId??G.ttsEngineId,Ae=_e.voiceId??G.voiceId??Cn(X),xe=qn(G),Me=Yn(G),F=Ln(G.faceId)}Ee.current={ttsEngineId:X,voiceId:Ae,brainId:xe,brainUrl:Me},fi(F),V.current=Ka();const Ce=!!(i&&!wt(i));N=Vo(M,{preferLegacyRenderer:Ce,pixiMaxTextureSize:q,onStatus:G=>{y||ve.current?.(G)},onError:G=>{y||it(G)},shouldAcceptLiveFrame:()=>{if(Se.current)return!0;if(p.current)return!1;const G=Je(de.current,fe.current);return G.isSpeaking()||G.isWarmingUp()},onWebGlContextLost:()=>{y||vt.current||(vt.current=!0,queueMicrotask(()=>{y||Ct(G=>G+1)}))}}),L.current=N,Z.current=Ao(N),vt.current=!1;const qe=G=>{const _e=()=>{if(!G||me.current<=0)return!1;const Pe=L.current;return Pe?H.current&&Pe.supportsBufferedPlayback?!0:Pe.usesPixi:!1};de.current.setLipsyncWarmupHold(G,_e),fe.current?.setLipsyncWarmupHold(G,_e)};br.current=qe,qe(!0),ve.current?.("auth");const Gt=Be.current??s??await Rn(Nt(),3e4,"getAuthToken");if(y)return;Be.current=Gt,de.current.setDeveloperToken(Gt),de.current.setTtsEngineId(X);const pe=Wt()?await kr():void 0;if(y)return;ve.current?.("loadAssets");const ge=await Rn(N.loadAssets(pe),18e4,"load face assets");if(!y&&ge.width>0&&ge.height>0&&(rt.current=ge,ze(ge)),y)return;ye.current=N.getVisemeAtlasPaths(),Ke.current=!0,_n(!0),hr.current?.(),N.renderSilOnly().then(()=>{y||ve.current?.("sil")}),(async()=>{try{const G=await ba(pe);if(await V.current.load(G),y)return;he.current=!0,P(!0),Oe(j.current),V.current.setActive(!0);const _e=V.current.getVideo();N.usesPixi?N.drawIdleVideo(_e):await Mn(M,_e,null,void 0,rt.current)}catch(G){if(y)return;he.current=!1,P(!1),console.warn("[AiTwin] Idle video unavailable:",G)}finally{y||(ce(!0),ve.current?.("idle"))}})()}catch(F){if(y)return;if(F instanceof nn){it(F.message);return}it(F instanceof Error?F.message:"Failed to load AI twin")}})(),()=>{y=!0,V.current?.dispose(),N?.dispose(),L.current=null}},[cs,i,Ge,t,Ie,je,a,u,s,q,kr,it,bn]),h.useEffect(()=>{const y={current:!1},M=()=>{const N=ie.current,F=L.current,X=Je(de.current,fe.current);if(!N||!F||!ct){C.current=requestAnimationFrame(M);return}if(document.hidden){V.current?.setActive(!1),C.current=requestAnimationFrame(M);return}const Ae=X.isSpeaking(),xe=X.isWarmingUp(),Me=Ae&&!Q.current,Ce=Q.current&&!Ae;Me&&(Fe(),Le(),p.current=!1,b.current=!1,Oe(j.current),Z.current?.reset(),bt.current.reset(),lt.current=void 0,re.current=0,ee.current="sil",T.current=0,Kt()),Ce&&(J.current.reset(),V.current?.setActive(!1),Z.current?.reset(),F.finishIdleToSilCrossfade(),We(),Tt());const qe=Ce||p.current||x.current||W.current,Gt=le&&F.supportsBufferedPlayback;if(xe){if(Kt(),he.current&&V.current?.setActive(!1),F.usesPixi&&F.isIdleToSilCrossfading()){F.tickIdleToSilCrossfade(performance.now()),X.getVisemeQueue().length>0&&te.current===0&&(te.current=performance.now()),Q.current=X.isSpeaking(),C.current=requestAnimationFrame(M);return}const pe=X.getVisemeQueue();pe.length>0&&te.current===0&&(te.current=performance.now()),J.current.advance(performance.now());const ge=J.current.getExpressionPath(),G=J.current.getDrawKey(),_e={queue:pe,elapsedMs:0,expressionPath:ge,expressionDrawKey:G,availablePaths:ye.current};let Pe=!1;Gt&&Z.current?(Z.current.warmupTick(_e),Pe=Z.current.isWarmupReady(_e,me.current)):F.usesPixi&&Gr(N,pe,0,ge,G,j.current,(kt,qt,Tn,Yt)=>{F.drawLiveFrame(kt,qt,Tn,Ye=>{Yt?.(Ye),X.isWarmingUp()&&Ye!==""&&!Kr({lastDrawnKey:Ye})&&(te.current=0,X.releaseWarmupHold())})},kt=>{ve.current?.(kt.label)},ye.current);const st=te.current>0&&performance.now()-te.current>vs;ve.current?.(Pe?"buffer ready":"buffering lipsync…"),(Pe||st)&&(te.current=0,X.releaseWarmupHold()),Dt(X),Q.current=X.isSpeaking(),C.current=requestAnimationFrame(M);return}if(Ae){Kt(),he.current&&V.current?.setActive(!1),F.usesPixi&&F.isIdleToSilCrossfading()&&F.finishIdleToSilCrossfade();const pe=X.getVisemeQueue(),ge=X.getPlaybackElapsedMs();ca(pe,ge),T.current=ge;const G=pe.length>0?zt(pe,ge):"sil";G!=="sil"&&(ee.current=G);const _e=Qa(ge,X.getSentenceEmotions(),X.getWordQueue(),X.getStreamMood());J.current.setTargetEmotion(_e),J.current.setTargetEyebrow(Ha(ge,X.getWordQueue(),ht(_e))),J.current.advance(performance.now());const Pe=J.current.getExpressionPath(),st=J.current.getDrawKey(),kt=(Ye,kn,Lt,En)=>{const Er={label:Ue.current,elapsedMs:ge,mouthPath:kn.mouthPath,transitionMeta:lt.current};Bt.current.set(Lt,Er),Z.current?.markExternallyDisplayed(Lt,Pe),F.drawLiveFrame(Ye,kn,Lt,Qt=>{const us=Bt.current.get(Qt)??Er;Bt.current.delete(Qt),bt.current.onDrawDisplayed(us,pe),Z.current?.markExternallyDisplayed(Qt,Pe),En?.(Qt)})},qt=Ye=>{Ue.current=Ye.label,lt.current=Ye.transitionMeta,ve.current?.(Ye.label)},Tn=le&&F.supportsBufferedPlayback;let Yt=!1;Tn&&Z.current&&(Yt=Z.current.tick({canvas:N,queue:pe,elapsedMs:ge,expressionPath:Pe,expressionDrawKey:st,playbackState:j.current,availablePaths:ye.current,onStatus:qt,onDisplayed:(kn,Lt,En)=>{bt.current.onDrawDisplayed({label:En,elapsedMs:ge,mouthPath:Lt,transitionMeta:lt.current},pe)}}).usedBuffer),Yt||Gr(N,pe,ge,Pe,st,j.current,kt,qt,ye.current),bt.current.onRafTickSpeaking(),vr.current?.(bt.current.snapshot(pe,ge))}else if(!qe&&Se.current){V.current?.setActive(!1),J.current.advance(performance.now());const pe=J.current.getExpressionPath(),ge=J.current.getDrawKey();Pn(N,pe,ge,j.current,(G,_e,Pe,st)=>F.drawLiveFrame(G,_e,Pe,st),G=>{if(_.current){ve.current?.(_.current);return}const _e=J.current.getTargetEmotion();ve.current?.(G==="sil"||G==="blink"?`${_e}${G==="blink"?" · blink":""}`:G)},null,ue.current)}else if(!qe&&he.current&&V.current){const pe=V.current,ge=pe.getVideo();if(ge.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA){pe.setActive(!0);const G=()=>!X.isSpeaking()&&!p.current&&!x.current&&!Se.current;F.usesPixi?(F.drawIdleVideo(ge,G),G()&&ve.current?.("idle")):y.current||(y.current=!0,Mn(N,ge,null,void 0,rt.current,G).then(()=>ve.current?.("idle")).finally(()=>{y.current=!1}))}else Pn(N,null,"__sil__",j.current,(G,_e,Pe,st)=>F.drawLiveFrame(G,_e,Pe,st),G=>ve.current?.(G))}else qe||Pn(N,null,"__sil__",j.current,(pe,ge,G,_e)=>F.drawLiveFrame(pe,ge,G,_e),pe=>ve.current?.(pe));Ve.enabled&&Dt(X),Q.current=Ae,C.current=requestAnimationFrame(M)};return C.current=requestAnimationFrame(M),()=>{cancelAnimationFrame(C.current),Fe(),Le(),de.current.stop(),fe.current?.stop()}},[ct,g,Tt,Fe,Le,Kt,Dt,We,Ve.enabled]),h.useImperativeHandle(ae,()=>({speakText:async(y,M)=>{const N=y.trim();if(!N)return;const F=L.current;if(!F||!Ke.current&&!ct)throw new Error("AI twin is not ready");const{ttsEngineId:X,voiceId:Ae}=_r(M);Rt(null),We(),$.current+=1,Fe(),Le(),p.current=!1,b.current=!1,ee.current="sil",T.current=0,Oe(j.current),Se.current=!1,ue.current=null,_.current=null,J.current.reset(),Q.current=!1,W.current=!1,F.finishIdleToSilCrossfade();try{await de.current.speak(N,{voiceId:Ae,speakingRate:M?.speakingRate??l,ttsEngineId:X,language:M?.language??d})}catch(xe){throw W.current=!1,F.finishIdleToSilCrossfade(),Tt(),it(xe instanceof Error?xe.message:"TTS failed"),xe}},stop:()=>{$.current+=1,Fe(),Le(),p.current=!1,b.current=!1,W.current=!1,L.current?.finishIdleToSilCrossfade(),de.current.stop(),fe.current?.stop(),Oe(j.current),Z.current?.reset(),te.current=0,Q.current=!1,We(),Tt()},setTtsEngineId:y=>{de.current.setTtsEngineId(y),fe.current?.setTtsEngineId(y),Ee.current&&(Ee.current.ttsEngineId=y)},renderViseme:async(y,M)=>{const N=L.current,F=ie.current;if(!N||!F||!Ke.current)throw new Error("AI twin is not ready");await N.renderViseme(F,y,{from:M?.from,transitionDurationMs:M?.transitionDurationMs,gapMs:M?.gapMs,onStatus:X=>ve.current?.(X)})},setEmotion:y=>{if(!Ke.current)throw new Error("AI twin is not ready");const M=L.current,N=ie.current;if(!M||!N)throw new Error("AI twin is not ready");$.current+=1,Fe(),Le(),p.current=!1,b.current=!1,x.current=!1,W.current=!1,de.current.stop(),fe.current?.stop(),Oe(j.current),Z.current?.reset(),te.current=0,Q.current=!1,M.finishIdleToSilCrossfade(),V.current?.setActive(!1);const F=Ze(y);Se.current=!0,ue.current=null,_.current=null,J.current.snapToEmotion(F);const X=J.current.getExpressionPath(),Ae=J.current.getDrawKey(),xe={mouthPath:null,expressionPath:X},Me=Vt(xe,Ae);j.current.lastDrawnKey="",M.drawLiveFrame(N,xe,Me,qe=>{qe===Me&&(j.current.lastDrawnKey=Me)});const Ce=ht(F);ve.current?.(X?`${F} · brow ${Ce>0?"+":""}${Ce}`:`${F} · brow 0 (sil base)`)},getEmotion:()=>Se.current?J.current.getTargetEmotion():null,clearEmotionPreview:()=>{Se.current=!1,ue.current=null,_.current=null,J.current.reset(),Oe(j.current),ve.current?.("idle")},setViseme:y=>{if(!Ke.current)throw new Error("AI twin is not ready");const M=L.current,N=ie.current;if(!M||!N)throw new Error("AI twin is not ready");$.current+=1,Fe(),Le(),p.current=!1,b.current=!1,x.current=!1,W.current=!1,de.current.stop(),fe.current?.stop(),Oe(j.current),Z.current?.reset(),te.current=0,Q.current=!1,M.finishIdleToSilCrossfade(),V.current?.setActive(!1);const F=mn(y);Se.current=!0,_.current=F,ue.current=F==="sil"?null:It(F),J.current.snapToEmotion("neutral");const X=J.current.getExpressionPath(),Ae=J.current.getDrawKey(),Me={mouthPath:ue.current,expressionPath:X},Ce=Vt(Me,Ae);j.current.lastDrawnKey="",M.drawLiveFrame(N,Me,Ce,qe=>{qe===Ce&&(j.current.lastDrawnKey=Ce)}),ve.current?.(F)},getViseme:()=>Se.current?_.current:null,isReady:()=>Ke.current,getStatus:()=>De,connect:async(y={})=>{Rt(null);try{let M=y.authToken?.trim();M||(M=Be.current??s??await Nt(),Be.current=M);const N=et(y.ttsEngineId??a,y.voiceId??u),F=N.voiceId??Ee.current?.voiceId,X=y.brainId?.trim()||y.personaId?.trim()||Ee.current?.brainId,Ae=y.brainUrl?.trim()||Ee.current?.brainUrl,xe=N.ttsEngineId??Ee.current?.ttsEngineId??Ie,Me=Sr();xe&&Me.setTtsEngineId(xe),await Me.unlockAudio(),await Me.connect({...y,apiBase:y.apiBase?.trim()||$e,authToken:M,voiceId:F,brainId:X,brainUrl:Ae,ttsEngineId:xe,speakingRate:y.speakingRate??l,language:y.language??d})}catch(M){throw it(M instanceof Error?M.message:"Voice connect failed"),M}},disconnect:async()=>{const y=fe.current;y&&($.current+=1,Fe(),Le(),p.current=!1,b.current=!1,W.current=!1,L.current?.finishIdleToSilCrossfade(),Oe(j.current),Z.current?.reset(),te.current=0,Q.current=!1,await y.disconnect(),Tt())},isConnected:()=>fe.current?.isConnected()??!1,getVoiceStream:()=>fe.current?.getVoiceStream()??de.current?.getVoiceStream()??null,setMuted:y=>{const M=de.current,N=fe.current;M?.setMuted?.(y),N?.setMuted?.(y)},isMuted:()=>{const y=fe.current,M=de.current;return y?.isMuted?.()??M?.isMuted?.()??!1},getBrainId:()=>Ee.current?.brainId?.trim()||null,getPersonaId:()=>Ee.current?.brainId?.trim()||null,getBrainUrl:()=>Ee.current?.brainUrl?.trim()||null}),[ct,l,d,s,Ie,je,Fe,Le,Tt,it,_r,Sr,De,$e]),R.jsxs("div",{className:c,style:{...zo,...m},children:[R.jsx("canvas",{ref:ie,width:ke.width,height:ke.height,style:{...Ho,...w},"aria-label":t?`AI twin ${t}`:"AI twin face"}),!ne&&!yt?R.jsx(mo,{thumbnailUrl:ls}):null,B&&yt?R.jsx("div",{style:$o,children:yt}):null,Ve.enabled&&Ne?R.jsx(co,{text:Ne,style:Ve.style},Ne):null]})});async function jo(e){try{const t=await e.json();if(typeof t.detail=="string"&&t.detail.trim())return t.detail;if(typeof t.error=="string"&&t.error.trim())return t.error}catch{}return`avatarReply failed (${e.status})`}async function is(e){const t=e.message.trim();if(!t)throw new Error("Message is required");const n=e.authToken.trim();if(!n)throw new Error("Auth token is required");const r=(e.apiBase?.trim()||gt).replace(/\/$/,""),i=await fetch(`${r}/avatarReply`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${n}`,Accept:"text/event-stream"},body:JSON.stringify({message:t,history:e.history??[],brainId:e.brainId?.trim()||e.personaId?.trim()||"",tenant:"aiTwin"})});if(!i.ok)throw new Error(await jo(i));if(!i.body)throw new Error("avatarReply response body is empty");const s=i.body.getReader(),o=new TextDecoder;let a="",u="",d="",l="";for(;;){const{done:c,value:m}=await s.read();if(c)break;a+=o.decode(m,{stream:!0});const w=a.split(`
|
|
48
|
+
`);a=w.pop()||"";for(const S of w){if(S.startsWith("event: ")){l=S.slice(7).trim();continue}if(!S.startsWith("data: "))continue;const f=S.slice(6).trim();if(!f)continue;let E;try{E=JSON.parse(f)}catch{continue}if(l==="spokenText")u=E.text||"",e.onSpokenText?.(u);else if(l==="displayText")d=E.text||"";else if(l==="error")throw new Error(E.error||"avatarReply stream error")}}if(!u.trim()||!d.trim())throw new Error("avatarReply stream missing displayText or spokenText");return{displayText:d.trim(),spokenText:u.trim()}}function Ko({muted:e}){return e?R.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none","aria-hidden":!0,children:[R.jsx("path",{d:"M11 5 6.5 9H3v6h3.5L11 19V5Z",fill:"currentColor"}),R.jsx("path",{d:"m16 9.5 5 5m0-5-5 5",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round"})]}):R.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none","aria-hidden":!0,children:[R.jsx("path",{d:"M11 5 6.5 9H3v6h3.5L11 19V5Z",fill:"currentColor"}),R.jsx("path",{d:"M15.5 8.5a4.5 4.5 0 0 1 0 7M18.5 6a8 8 0 0 1 0 12",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round"})]})}function Go(){return R.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":!0,children:R.jsx("path",{d:"M8 5.5v13l11-6.5L8 5.5Z"})})}function qo(){return R.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":!0,children:R.jsx("rect",{x:"6",y:"6",width:"12",height:"12",rx:"1.5"})})}function Yo(){return R.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none","aria-hidden":!0,children:R.jsx("path",{d:"M5 6.5A2.5 2.5 0 0 1 7.5 4h9A2.5 2.5 0 0 1 19 6.5v7A2.5 2.5 0 0 1 16.5 16H10l-4 3.5V16H7.5A2.5 2.5 0 0 1 5 13.5v-7Z",stroke:"currentColor",strokeWidth:"2",strokeLinejoin:"round"})})}function ss({className:e}){return R.jsx("span",{className:e??"aitwin-widget__spinner","aria-hidden":!0,children:R.jsx("svg",{viewBox:"0 0 24 24",fill:"none",children:R.jsx("circle",{cx:"12",cy:"12",r:"9",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeDasharray:"40 20"})})})}function Qo({muted:e,onToggle:t}){return R.jsx("button",{type:"button",className:"aitwin-widget__mute",onClick:t,"aria-label":e?"Unmute":"Mute","aria-pressed":e,children:R.jsx(Ko,{muted:e})})}function Xo(){return R.jsxs("div",{className:"aitwin-widget__connecting",role:"status","aria-live":"polite",children:[R.jsx(ss,{className:"aitwin-widget__spinner aitwin-widget__spinner--accent"}),R.jsx("span",{children:"Connecting..."})]})}function Jo(e){const t=e.connecting||e.textSending||e.status==="loading"||e.status==="speaking",n=e.connecting?"Connecting...":e.connected?"End Talk":"Talk",r=["aitwin-widget__action",e.textMode&&!e.connecting?"":"aitwin-widget__action--primary",e.connecting?"aitwin-widget__action--connecting":""].filter(Boolean).join(" ");return R.jsxs("div",{className:"aitwin-widget__controls",children:[R.jsxs("div",{className:"aitwin-widget__actions",children:[R.jsxs("button",{type:"button",className:r,onClick:e.onTalk,disabled:!e.ready||e.connecting||e.textSending,"aria-busy":e.connecting,children:[e.connecting?R.jsx(ss,{className:"aitwin-widget__spinner aitwin-widget__spinner--on-accent"}):e.connected?R.jsx(qo,{}):R.jsx(Go,{}),R.jsx("span",{children:n})]}),R.jsxs("button",{type:"button",className:e.textMode?"aitwin-widget__action aitwin-widget__action--primary":"aitwin-widget__action",onClick:e.onTextMode,disabled:!e.ready||e.connecting||e.textSending,"aria-pressed":e.textMode,children:[R.jsx(Yo,{}),R.jsx("span",{children:"Text"})]})]}),e.textMode?R.jsxs("form",{className:"aitwin-widget__composer",onSubmit:i=>{i.preventDefault(),e.onSendText()},children:[R.jsx("input",{type:"text",className:"aitwin-widget__composer-input",value:e.textDraft,onChange:i=>e.onTextDraftChange(i.target.value),placeholder:e.textSending?"Getting reply...":"Type a message…",autoComplete:"off",disabled:!e.ready||t}),R.jsx("button",{type:"submit",className:"aitwin-widget__composer-send",disabled:!e.ready||t||!e.textDraft.trim()&&!e.textSending,"aria-busy":e.textSending,children:e.textSending?"…":"Send"})]}):null,e.error?R.jsx("p",{className:"aitwin-widget__controls-error",role:"alert",children:e.error}):null]})}const ei=97,Zo=3500;function ec(e,t){const n=Math.max(0,e),r=1-Math.exp(-n/Zo);return Math.min(ei,Math.round(r*ei))}function tc(e){const[t,n]=h.useState(null),[r,i]=h.useState(()=>Date.now());return h.useEffect(()=>{if(!e){n(null);return}const s=Date.now();n(s),i(s);let o=0;const a=()=>{i(Date.now()),o=window.requestAnimationFrame(a)};return o=window.requestAnimationFrame(a),()=>{window.cancelAnimationFrame(o)}},[e]),e?t==null?0:ec(r-t):100}const nc="M259.01,593.87v-101.49c.33-6.31,4.94-11.26,10.21-11.88,6.42-.75,13.18,4.99,13.13,12.92-.42,45.09-.83,90.17-1.25,135.26.03,1.56.56,15.43,11.95,23.2,6.18,4.21,12.57,4.6,15.42,4.58-.42-112.77-.83-225.54-1.25-338.31-.08-2.55-1.03-46.36,21.17-55.34,2.05-.83,4.42-1.41,7.17-1.56v453.42c.07,12.06,1.98,37.84,19.03,62.73,7.01,10.23,14.79,17.71,21.4,22.99V222.42c-.01-3.72.48-11.67,5.35-19.87,7-11.77,18.13-15.82,21.4-16.95,10.42-3.61,19.49-2.06,23.48-1.11v684.96c.59,4.03,1.78,9.72,4.45,16.12,1.93,4.63,8.84,20.57,26.47,31.26,13.48,8.18,26.56,9.23,32.86,9.31-1.3-256.11-2.59-512.22-3.89-768.33.76-16.43,14.57-28.94,29.73-28.34,13.53.53,25.39,11.39,27.23,25.84-1.1,264.68-2.2,529.35-3.3,794.03,4.33.92,22.38,4.25,38.94-6.53,10.26-6.68,15.24-15.72,17.09-19.17,5.55-10.36,6.42-19.98,6.53-25.01-.72-246.99-1.43-493.97-2.15-740.96,2.27-.06,34.75-.44,48.29,22.68,3.41,5.83,4.87,11.86,5.34,17.19v674.68c5.92-2.16,39.19-14.94,50.16-47.79,3.12-9.34,3.68-18.03,3.33-25.01.03-193.22.06-386.43.09-579.65,4.12,1.18,28.28,8.48,36.17,30.08,1.64,4.49,2.32,8.88,2.43,12.92.02,146.42.05,292.84.07,439.25,3.82-1.71,19.51-9.22,25.56-26.47,2.15-6.12,2.48-11.73,2.29-15.89.01-114.91.03-229.81.04-344.72,2.36-.1,7.51.02,12.74,3.13,9.1,5.4,10.87,15.35,11.12,16.88.35,11.49.69,22.97,1.04,34.46.46,37.05.93,74.1,1.39,111.15v152.69c3.39-.72,9.77-2.67,14.31-8.34,3.62-4.52,4.51-9.46,5.56-15.28.91-5.04.95-9.31.83-12.23.02-38.81.03-77.62.05-116.43";function rc({className:e="aitwin-widget__logo",strokeWidth:t=15,durationMs:n=2600,delayMs:r=0,loop:i=!1}){return R.jsx("svg",{viewBox:"0 0 1080 1080",className:e,role:"img","aria-label":"AITWIN logo",children:R.jsx("path",{className:i?"aitwin-widget__logo-draw aitwin-widget__logo-draw--loop":"aitwin-widget__logo-draw",d:nc,fill:"none",stroke:"currentColor",strokeWidth:t,strokeMiterlimit:10,pathLength:1,style:{animationDuration:`${n}ms`,animationDelay:`${r}ms`}})})}function ic({progress:e}){const t=Math.max(0,Math.min(100,Math.round(e)));return R.jsx("div",{className:"aitwin-widget__face-loading","aria-live":"polite","aria-label":`Loading ${t} percent`,children:R.jsxs("div",{className:"aitwin-widget__face-loading-content",children:[R.jsx(rc,{className:"aitwin-widget__logo",loop:!0,durationMs:2600}),R.jsxs("div",{className:"aitwin-widget__face-loading-bar-wrap",children:[R.jsx("div",{role:"progressbar","aria-valuenow":t,"aria-valuemin":0,"aria-valuemax":100,className:"aitwin-widget__face-loading-track",children:R.jsx("div",{className:"aitwin-widget__face-loading-fill",style:{width:`${t}%`}})}),R.jsxs("p",{className:"aitwin-widget__face-loading-pct",children:[t,"%"]})]})]})})}function ti(e){const t=e.id?.trim()||void 0,n=e.faceId?.trim()||e.avatarId?.trim()||void 0;return{id:n?void 0:t,faceId:n,authToken:e.authToken?.trim()||void 0,apiBase:e.apiBase?.trim()||void 0,voiceId:e.voiceId?.trim()||void 0,speakingRate:e.speakingRate,language:e.language}}function sc(e){return[e.id??"",e.faceId??"",e.authToken?.slice(0,16)??"",e.voiceId??"",e.apiBase??"",String(e.speakingRate??"")].join("|")}const ni={display:"flex",alignItems:"center",justifyContent:"center",width:"100%",height:"100%",lineHeight:0},ac={display:"block",height:"100%",width:"100%",objectFit:"cover",objectPosition:"top"},oc=h.forwardRef(function({options:t},n){const r=h.useRef(null),i=h.useRef(t);i.current={...i.current,onReady:t.onReady,onStatusChange:t.onStatusChange,onError:t.onError,onUserTranscript:t.onUserTranscript,onBotOutput:t.onBotOutput};const[s,o]=h.useState(!!t.showControls),[a,u]=h.useState(()=>ti(t)),[d,l]=h.useState(!1),[c,m]=h.useState(!1),[w,S]=h.useState(!1),[f,E]=h.useState(!1),[D,B]=h.useState("idle"),[v,k]=h.useState(null),[O,A]=h.useState(!1),[se,le]=h.useState(!1),[I,U]=h.useState(""),[q,oe]=h.useState(!1),[ae,ie]=h.useState([]),[L,Z]=h.useState(t.brainId?.trim()||t.personaId?.trim()||void 0),[H,me]=h.useState(t.brainUrl?.trim()||void 0),z=h.useCallback(T=>{i.current={...i.current,...T},T.showControls!==void 0&&o(!!T.showControls),(T.brainId!==void 0||T.personaId!==void 0)&&Z((T.brainId??T.personaId)?.trim()||void 0),T.brainUrl!==void 0&&me(T.brainUrl.trim()||void 0),u(Q=>ti({id:T.id??Q.id,faceId:T.faceId??T.avatarId??Q.faceId,authToken:T.authToken??Q.authToken,apiBase:T.apiBase??Q.apiBase,voiceId:T.voiceId??Q.voiceId,speakingRate:T.speakingRate??Q.speakingRate,language:T.language??Q.language}))},[]);h.useImperativeHandle(n,()=>({getTwin:()=>r.current,applyOptions:z}),[z]),h.useEffect(()=>{z(t)},[z,t.id,t.faceId,t.avatarId,t.authToken,t.apiBase,t.voiceId,t.speakingRate,t.showControls,t.brainId,t.personaId,t.brainUrl]);const te=h.useCallback(()=>{l(!0),k(null)},[]),j=h.useCallback(T=>{T==="idle"&&m(!0)},[]),J=h.useCallback(T=>{B(T),i.current.onStatusChange?.(T)},[]),Se=h.useCallback(T=>{k(T),l(!1),m(!1),E(!1),i.current.onError?.(T)},[]),ue=h.useCallback((T,Q)=>{i.current.onUserTranscript?.(T,Q)},[]),_=h.useCallback(T=>{i.current.onBotOutput?.(T)},[]);h.useEffect(()=>{if(!s)return;const T=window.setInterval(()=>{S(!!r.current?.isConnected())},400);return()=>window.clearInterval(T)},[s,a]);const C=sc(a),$=!!(a.id||a.faceId),re=d&&c,K=$&&!re&&!v,Y=tc(K),p=h.useRef(C);h.useEffect(()=>{re&&i.current.onReady?.()},[re]),h.useEffect(()=>{re&&r.current?.setMuted(O)},[re,O,a]),h.useEffect(()=>{ie([])},[a.id,a.faceId]),h.useEffect(()=>{p.current!==C&&(p.current=C,l(!1),m(!1),k(null),E(!1),S(!1),B("idle"))},[C]);const b=()=>{const T=r.current;if(!T?.isReady())return;if(k(null),le(!1),T.isConnected()){E(!1),T.disconnect().finally(()=>{S(!1)});return}E(!0);const Q={authToken:a.authToken,voiceId:a.voiceId,speakingRate:a.speakingRate,language:a.language,apiBase:a.apiBase,...L?{brainId:L}:{},...H?{brainUrl:H}:{}};T.connect(Q).then(()=>{S(!!T.isConnected())}).catch(V=>{const he=V instanceof Error?V.message:"Failed to connect voice.";k(he),i.current.onError?.(he)}).finally(()=>{E(!1)})},x=()=>{le(T=>!T),k(null)},W=()=>{const T=I.trim(),Q=r.current;!T||!Q?.isReady()||q||(k(null),U(""),oe(!0),i.current.onUserTranscript?.(T,!0),(async()=>{try{const V=a.authToken?.trim()||await Nt(),he=L||Q.getBrainId()?.trim()||void 0,De=await is({message:T,authToken:V,apiBase:a.apiBase||gt,brainId:he,history:ae});ie(ot=>[...ot,{role:"user",content:T},{role:"assistant",content:De.displayText}]),i.current.onBotOutput?.(De.displayText),await Q.speakText(De.spokenText,{voiceId:a.voiceId,speakingRate:a.speakingRate,language:a.language})}catch(V){const he=V instanceof Error?V.message:"Failed to get reply.";k(he),i.current.onError?.(he)}finally{oe(!1)}})())},ee=()=>{const T=!O;A(T),r.current?.setMuted(T)};return R.jsxs("div",{className:"aitwin-widget__layout",children:[R.jsxs("div",{className:"aitwin-widget__stage",children:[$?R.jsx("div",{style:ni,children:R.jsx(rs,{ref:r,id:a.id,faceId:a.faceId,authToken:a.authToken,apiBase:a.apiBase,voiceId:a.voiceId,speakingRate:a.speakingRate,language:a.language,style:ni,canvasStyle:ac,onReady:te,onDisplayStatus:j,onStatusChange:J,onError:Se,onUserTranscript:ue,onBotOutput:_,loadingThumbnailUrl:t.loadingThumbnailUrl},C)}):R.jsx("p",{className:"aitwin-widget__hint",style:{padding:16},children:"Pass id or faceId to load a twin."}),K?R.jsx(ic,{progress:Y}):null,s?R.jsx(Qo,{muted:O,onToggle:ee}):null,s&&f?R.jsx(Xo,{}):null]}),s?R.jsx(Jo,{ready:re,connected:w,connecting:f,status:D,textMode:se,textDraft:I,textSending:q,error:v,onTalk:b,onTextMode:x,onTextDraftChange:U,onSendText:W}):null]})}),cc=".aitwin-widget{--aitwin-border: rgba(255, 255, 255, .12);--aitwin-text: #f4f4f5;--aitwin-muted: #a1a1aa;--aitwin-accent: #f97316;--aitwin-accent-hover: #fb923c;--aitwin-font: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif;--aitwin-size: 1;--aitwin-stage-width: calc(200px * var(--aitwin-size));--aitwin-stage-height: calc(267px * var(--aitwin-size));--aitwin-action-height: calc(40px * var(--aitwin-size));--aitwin-action-font: calc(13px * var(--aitwin-size));--aitwin-action-radius: calc(10px * var(--aitwin-size));--aitwin-action-gap: calc(6px * var(--aitwin-size));--aitwin-mute-size: calc(28px * var(--aitwin-size));--aitwin-layout-gap: calc(8px * var(--aitwin-size));box-sizing:border-box;color:var(--aitwin-text);font-family:var(--aitwin-font);font-size:calc(12px * var(--aitwin-size));line-height:1.45;width:fit-content;max-width:100%}.aitwin-widget *,.aitwin-widget *:before,.aitwin-widget *:after{box-sizing:border-box}.aitwin-widget__layout{display:flex;flex-direction:column;gap:var(--aitwin-layout-gap);width:fit-content;max-width:100%}.aitwin-widget__stage{align-items:center;background:#0a0a0b;border:1px solid var(--aitwin-border);border-radius:calc(10px * var(--aitwin-size));display:flex;flex-shrink:0;height:var(--aitwin-stage-height);justify-content:center;line-height:0;overflow:hidden;position:relative;width:var(--aitwin-stage-width)}.aitwin-widget__stage .aitwin-root,.aitwin-widget__stage canvas{display:block;height:100%;object-fit:cover;object-position:top;width:100%}.aitwin-widget__hint{color:var(--aitwin-muted);font-size:calc(11px * var(--aitwin-size));margin:0}.aitwin-widget__mute{align-items:center;background:#28282cb8;border:none;border-radius:999px;color:#fff;cursor:pointer;display:inline-flex;height:var(--aitwin-mute-size);justify-content:center;padding:0;position:absolute;right:calc(8px * var(--aitwin-size));top:calc(8px * var(--aitwin-size));width:var(--aitwin-mute-size);z-index:2}.aitwin-widget__mute:hover{background:#37373cd9}.aitwin-widget__mute svg{height:calc(15px * var(--aitwin-size));width:calc(15px * var(--aitwin-size))}.aitwin-widget__controls{display:flex;flex-direction:column;gap:var(--aitwin-action-gap);width:var(--aitwin-stage-width)}.aitwin-widget__actions{display:grid;gap:var(--aitwin-action-gap);grid-template-columns:1fr 1fr;width:100%}.aitwin-widget__action{align-items:center;background:transparent;border:1.5px solid var(--aitwin-accent);border-radius:999px;color:var(--aitwin-accent);cursor:pointer;display:inline-flex;font-family:inherit;font-size:var(--aitwin-action-font);font-weight:600;gap:calc(6px * var(--aitwin-size));height:var(--aitwin-action-height);justify-content:center;padding:0 calc(10px * var(--aitwin-size))}.aitwin-widget__action svg{flex-shrink:0;height:calc(12px * var(--aitwin-size));width:calc(12px * var(--aitwin-size))}.aitwin-widget__action:hover:not(:disabled){background:#f973161a}.aitwin-widget__action:disabled{cursor:not-allowed;opacity:.45}.aitwin-widget__action--primary{background:var(--aitwin-accent);border-color:transparent;color:#fff}.aitwin-widget__action--primary:hover:not(:disabled){background:var(--aitwin-accent-hover)}.aitwin-widget__action--connecting:disabled{cursor:progress;opacity:1}.aitwin-widget__spinner{display:inline-flex;flex-shrink:0;height:calc(14px * var(--aitwin-size));width:calc(14px * var(--aitwin-size))}.aitwin-widget__spinner svg{animation:aitwin-widget-spin .8s linear infinite;display:block;height:100%;width:100%}.aitwin-widget__spinner--accent{color:var(--aitwin-accent);height:calc(16px * var(--aitwin-size));width:calc(16px * var(--aitwin-size))}.aitwin-widget__spinner--on-accent{color:#fff}@keyframes aitwin-widget-spin{to{transform:rotate(360deg)}}.aitwin-widget__connecting{align-items:center;backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);background:#ffffffe0;border-radius:999px;bottom:calc(14px * var(--aitwin-size));box-shadow:0 4px 16px #0000001f;color:#3f3f46;display:inline-flex;font-size:calc(12px * var(--aitwin-size));font-weight:600;gap:calc(8px * var(--aitwin-size));left:50%;line-height:1;padding:calc(8px * var(--aitwin-size)) calc(14px * var(--aitwin-size));pointer-events:none;position:absolute;transform:translate(-50%);z-index:3}.aitwin-widget__face-loading{background:transparent;inset:0;overflow:hidden;pointer-events:none;position:absolute;z-index:4}.aitwin-widget__face-loading-content{align-items:center;display:flex;flex-direction:column;gap:calc(12px * var(--aitwin-size));inset:0;justify-content:center;padding:calc(24px * var(--aitwin-size));position:absolute;z-index:1}.aitwin-widget__logo{color:#fff;display:block;flex-shrink:0;height:calc(64px * var(--aitwin-size));margin-bottom:calc(4px * var(--aitwin-size));width:calc(64px * var(--aitwin-size))}.aitwin-widget__logo-draw{stroke-dasharray:1;stroke-dashoffset:1;animation:aitwin-widget-logo-draw 2.6s ease-in-out forwards}.aitwin-widget__logo-draw--loop{animation:aitwin-widget-logo-draw-loop 2.6s ease-in-out infinite}@keyframes aitwin-widget-logo-draw{to{stroke-dashoffset:0}}@keyframes aitwin-widget-logo-draw-loop{0%{stroke-dashoffset:1}45%{stroke-dashoffset:0}55%{stroke-dashoffset:0}to{stroke-dashoffset:-1}}@media(prefers-reduced-motion:reduce){.aitwin-widget__logo-draw,.aitwin-widget__logo-draw--loop{animation:none;stroke-dashoffset:0}}.aitwin-widget__face-loading-bar-wrap{max-width:calc(220px * var(--aitwin-size));width:100%}.aitwin-widget__face-loading-track{background:#fff3;border-radius:999px;height:calc(4px * var(--aitwin-size));overflow:hidden;width:100%}.aitwin-widget__face-loading-fill{background:var(--aitwin-accent);border-radius:999px;height:100%;transition:width .3s ease-out}.aitwin-widget__face-loading-pct{color:#ffffffbf;font-size:calc(12px * var(--aitwin-size));margin:calc(8px * var(--aitwin-size)) 0 0;text-align:center}.aitwin-widget__composer{display:grid;gap:var(--aitwin-action-gap);grid-template-columns:1fr auto;width:100%}.aitwin-widget__composer-input{background:#ffffff0a;border:1px solid var(--aitwin-border);border-radius:var(--aitwin-action-radius);color:var(--aitwin-text);font-family:inherit;font-size:calc(12px * var(--aitwin-size));min-width:0;outline:none;padding:calc(8px * var(--aitwin-size)) calc(10px * var(--aitwin-size))}.aitwin-widget__composer-input:focus{border-color:#f973168c}.aitwin-widget__composer-send{background:var(--aitwin-accent);border:none;border-radius:var(--aitwin-action-radius);color:#fff;cursor:pointer;font-family:inherit;font-size:calc(12px * var(--aitwin-size));font-weight:600;padding:0 calc(12px * var(--aitwin-size))}.aitwin-widget__composer-send:disabled{cursor:not-allowed;opacity:.45}.aitwin-widget__controls-error{color:#fecaca;font-size:calc(11px * var(--aitwin-size));margin:0}.aitwin-widget--float{bottom:20px;filter:drop-shadow(0 12px 32px rgba(0,0,0,.45));height:fit-content;margin:0;max-width:calc(100vw - 40px);position:fixed;right:20px;width:fit-content;z-index:2147483000}",ri="data-aitwin-widget-style";function as(){if(typeof document>"u")return;const e=cc.trim();if(!e){console.warn("[AiTwinWidget] styles.css?inline resolved empty — chrome will be unstyled");return}const t=document.querySelector(`style[${ri}]`);if(t){if((t.textContent??"").trim().length>0)return;t.textContent=e;return}const n=document.createElement("style");n.setAttribute(ri,"1"),n.textContent=e,(document.head??document.documentElement).appendChild(n)}typeof document<"u"&&as();const lc=h.forwardRef(function(t,n){as();const r=h.useRef(null);h.useImperativeHandle(n,()=>({speakText:async(s,o)=>{const a=r.current?.getTwin();if(!a)throw new Error("AiTwinWidget: twin is not mounted");return a.speakText(s,o)},connect:async s=>{const o=r.current?.getTwin();if(!o)throw new Error("AiTwinWidget: twin is not mounted");return o.connect(s)},disconnect:async()=>{const s=r.current?.getTwin();if(s)return s.disconnect()},stop:()=>{r.current?.getTwin()?.stop()},isReady:()=>!!r.current?.getTwin()?.isReady(),isConnected:()=>!!r.current?.getTwin()?.isConnected(),getTwin:()=>r.current?.getTwin()??null}),[]);const i=!!t.float;return R.jsx("div",{className:i?"aitwin-widget aitwin-widget--float":"aitwin-widget",children:R.jsx(oc,{ref:r,options:t})})}),uc=new Set([".png",".jpg",".jpeg",".webp"]);function os(e=".png"){const t=e.toLowerCase();return uc.has(t)?`source${t}`:"source.png"}function dc(e,t=$n,n=".png"){const r=e.trim();if(!r)throw new Error("faceId is required");return`${t.replace(/\/$/,"")}/${r}/${os(n)}`}exports.AI_TWIN_THUMBNAIL_FILENAME=Qn;exports.AiTwin=rs;exports.AiTwinNotFoundError=nn;exports.AiTwinWidget=lc;exports.CONSONANT_SKIP_GROUP=ki;exports.DEFAULT_TTS_ENGINE_ID=ft;exports.DEFAULT_TTS_LANGUAGE=Ws;exports.EMOTION_TO_EYEBROW=qi;exports.EXPRESSION_ATLAS_EMOTIONS=Ba;exports.MIC_SAMPLE_RATE=rr;exports.OCULUS_VISEME_IDS=_i;exports.PLAYBACK_SAMPLE_RATE=ir;exports.SPEAKING_RATE_MAX=yn;exports.SPEAKING_RATE_MIN=pn;exports.TTS_ENGINE_CARTESIA=tt;exports.TTS_ENGINE_GOOGLE=Kn;exports.TTS_ENGINE_INWORLD=un;exports.TTS_ENGINE_VISEMETTS=nt;exports.TTS_LANGUAGE_CATALOG=mt;exports.TTS_LANGUAGE_CODES=pi;exports.VISEME_IDS=Sa;exports.VISEME_SKIP_GAP_MS=On;exports.VISEME_TEST_CARTESIA_VOICE_ID=nr;exports.VISEME_TEST_SPEAKING_RATE=Ht;exports.VISEME_TEST_VISEMETTS_VOICE_ID=dn;exports.VISEME_TEST_VOICE_ID=tr;exports.VISEME_VTIME_GRID_MS=Xn;exports.VOWEL_SKIP_GROUP=Ti;exports.aiTwinSourceFilename=os;exports.buildPlaybackTransitions=Ri;exports.buildPlaybackVisemeSeries=gn;exports.buildRawVisemeTransitions=Pi;exports.buildVoiceWebSocketUrl=Ui;exports.compactSkippableVisemes=Zn;exports.createAvatarTtsLipsyncController=Nn;exports.createRealtimeVoiceLipsyncController=Vi;exports.emotionToEyebrow=ht;exports.faceAssetUrls=Ln;exports.fetchAiTwin=li;exports.fetchAvatarReply=is;exports.fetchDevAuthToken=Nt;exports.getAiTwinSourceUrl=dc;exports.getAiTwinThumbnailUrl=ui;exports.isTtsLanguageCode=yi;exports.isTtsLanguageSupported=Hs;exports.listSkippedVisemeEntries=wn;exports.listSkippedVisemes=ea;exports.normalizeOculusViseme=mn;exports.normalizeStreamEmotion=Ze;exports.normalizeTtsLanguage=fn;exports.parsePackedVoiceId=ai;exports.parseTwinBrainUrl=Es;exports.resolveDirectFaceId=di;exports.resolveTwinBrainId=qn;exports.resolveTwinBrainUrl=Yn;exports.resolveVisemeAtTime=zt;exports.resolveVisemeFromPlaybackSeries=Ii;exports.resolveWordAtTime=la;exports.setActiveTwinAssets=fi;exports.snapVisemeQueueToGrid=Jn;exports.snapVisemeVtimeToGrid=Ei;exports.splitVoiceIdSpec=et;exports.ttsLanguagesForEngine=zs;
|