@streamoji/aitwin 0.7.7 → 0.7.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/aitwin.cjs CHANGED
@@ -1,8 +1,8 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const A=require("react/jsx-runtime"),d=require("react"),Ks=require("@pipecat-ai/client-js"),wn=require("@pipecat-ai/websocket-transport"),Te=require("pixi.js");var Xr=typeof document<"u"?document.currentScript:null;const qs="https://aitwin.bubu.social",Fi={publicBase:qs},Ys="0.7.7",Qs={version:Ys},Xs={},ut="https://ai.aitwin.me",Pr=`${Fi.publicBase}/custom-faces`,Js=`${Fi.publicBase}/aitwin-workers/v${Qs.version}/visemeDiffPreview.worker.js`;function Zs(e){if(e)return e;const t=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:Xr&&Xr.tagName.toUpperCase()==="SCRIPT"&&Xr.src||new URL("aitwin.cjs",document.baseURI).href}<"u"?Xs?.VITE_AITWIN_WORKER_URL:void 0;return t?.trim()?t.trim():Js}const ea="https://us-central1-streamoji-265f4.cloudfunctions.net/getAiTwin",Jr=3e3,er=16,Jn=3e3,ta=4e3,ra=.85,na=8,yn=400,vn="eng_a7f2b9c1",Cr="eng_d4e8f3a2",dt="eng_c9b1e6d4",ft="visemetts",xt=dt,Fr="eve",an=new Set([Cr,dt,ft]),_n={[vn]:"oculus_direct",[dt]:"oculus_direct",[ft]:"oculus_direct",[Cr]:"inworld_word"},on={google:vn,inworld:Cr,cartesia:dt,visemetts:ft};function ia(e){const t=e.trim();if(t)return t in _n?t:on[t.toLowerCase()]}function Bi(e){const t=e?.trim();if(!t)return{};const r=t.indexOf(":");if(r<=0)return{voiceId:t};const n=ia(t.slice(0,r));if(!n)return{voiceId:t};const i=t.slice(r+1).trim();return{ttsEngineId:n,voiceId:i||void 0}}function lt(e,t){const r=Bi(t);return{ttsEngineId:r.ttsEngineId??e,voiceId:r.voiceId}}function Di(e){return _n[e]}function Li(e){return e===dt}function Oi(e){return e===ft}function sa(e){if(e.ttsEngineId&&e.ttsEngineId in _n)return e.ttsEngineId;const t=e.tts?.toLowerCase();return t&&t in on?on[t]:xt}class kr extends Error{constructor(t="AI twin not found"){super(t),this.name="AiTwinNotFoundError"}}function bn(e,...t){const r=typeof e=="string"?e:e?.brainId?.trim()||e?.knowledgeContextId?.trim();for(const n of[r,...t]){const i=n?.trim();if(i)return i}}function Sn(e,...t){const r=typeof e=="string"?e:e?.brainUrl?.trim();for(const n of[r,...t]){const i=n?.trim();if(i)return i}}function aa(e){const t=(e??"").trim();if(!t)return;let r;try{r=new URL(t)}catch{throw new Error("brainUrl must be an http or https URL")}if(r.protocol!=="http:"&&r.protocol!=="https:")throw new Error("brainUrl must be an http or https URL");if(!r.host)throw new Error("brainUrl must be an http or https URL");if(r.hash)throw new Error("brainUrl must not include a fragment");return t}async function Ni(e,t=ea){const r=new URL(t);r.searchParams.set("id",e);const n=await fetch(r.toString());if(n.status===404)throw new kr;if(!n.ok)throw new Error(`getAiTwin failed (${n.status})`);const i=await n.json();if(!i.success)throw new kr(i.error??"AI twin not found");const{tts:s,token:o,...a}=i.data,f=String(a.authToken??o??"").trim()||void 0,m=bn(a),l=Sn(a);return{...a,ttsEngineId:sa(i.data),authToken:f,brainId:m,knowledgeContextId:m,brainUrl:l}}const Tn="thumbnail.webp";function Ui(e,t=Pr){const r=e.trim();if(!r)throw new Error("faceId is required");return`${t.replace(/\/$/,"")}/${r}/${Tn}`}function Zn(e){const t=e?.trim();if(!t)return null;try{return Ui(t)}catch{return null}}function oa(e){if(!e)return null;const t=(e.binBase||e.twinBase).trim().replace(/\/$/,"");return t?`${t}/${Tn}`:null}const ca="https://us-central1-streamoji-265f4.cloudfunctions.net/getAuthToken",la="client_6TNvp3SCs4Og0a1ijm9TommXLql1",ua="kk8Fq8EmexzP10jMIEwY3R44M5RKUEm1",da="6TNvp3SCs4Og0a1ijm9TommXLql1",fa="Swaraj Mali";async function Tr(){const e=await fetch(ca,{method:"POST",headers:{"Content-Type":"application/json","Client-Id":la,"Client-Secret":ua},body:JSON.stringify({userId:da,userName:fa})});if(!e.ok)throw new Error(`getAuthToken failed (${e.status})`);const t=await e.json(),r=t.authToken??t.token??"";if(!r.trim())throw new Error("getAuthToken returned no token");return r}async function ma(e,t=ut){const r=await fetch(`${t.replace(/\/$/,"")}/api/session-value`,{headers:{Authorization:`Bearer ${e}`}});if(!r.ok)throw new Error(`/api/session-value failed (${r.status})`);const n=await r.json();if(!n.value)throw new Error("Session value response missing value");return n}function ha(e){const t=e.trim();if(t.length%2!==0)throw new Error("Invalid hex key");const r=new Uint8Array(t.length/2);for(let n=0;n<t.length;n+=2)r[n/2]=Number.parseInt(t.slice(n,n+2),16);return r}function yr(e){return Uint8Array.from(e)}function pa(e,t){const r=new Uint8Array(e.length+t.length);return r.set(e,0),r.set(t,e.length),r}async function ga(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 r=new Uint8Array(e),n=yr(r.subarray(0,12)),i=yr(r.subarray(12,28)),s=yr(r.subarray(28)),o=yr(pa(s,i)),a=await crypto.subtle.importKey("raw",ha(t),{name:"AES-GCM"},!1,["decrypt"]);return crypto.subtle.decrypt({name:"AES-GCM",iv:n,tagLength:128},a,o)}let cn=null;const ln=new Set;function vr(e){return e.includes("/custom-faces/")}function Er(e){const t=e.binBase.trim().replace(/\/$/,""),r=e.twinBase.trim().replace(/\/$/,"");if(!(e.encrypted||vr(t)||vr(r)))return{twinBase:r,binBase:t,encrypted:!1};const i=vr(t)?t:vr(r)?r:t;return{twinBase:i,binBase:i,encrypted:!0}}function Rt(e){return Er(e).encrypted}function un(e,t=Pr){const r=`${t.replace(/\/$/,"")}/${e}`;return{twinBase:r,binBase:r,encrypted:!0}}function Vi(e,t){return(e??t)?.trim()||void 0}function Wi(e){cn=Er(e);for(const t of ln)t()}function wa(e,t){const r=typeof globalThis.location<"u"?globalThis.location.href:void 0;if(!r)return Er(e);const n=i=>{try{return new URL(i,r).href.replace(/\/$/,"")}catch{return i}};return Er({twinBase:n(e.twinBase),binBase:n(e.binBase),encrypted:e.encrypted})}function Mt(){if(!cn)throw new Error("Twin assets not configured; call setActiveTwinAssets first");return cn}function ji(e){return ln.add(e),()=>ln.delete(e)}function tr(){const e=Mt();return Rt(e)?`${e.binBase}/sil.bin`:`${e.twinBase}/sil.png`}function ya(){const e=Mt();return Rt(e)?`${e.binBase}/idle.bin`:`${e.twinBase}/idle.mp4`}function Hi(){const e=Mt();return Rt(e)?e.binBase:e.twinBase}function zt(){return Rt(Mt())}function $i(){const e=Mt();return Rt(e)?`${e.binBase}/atlas.bin`:`${e.twinBase}/atlas.json`}function zi(){const e=Mt();return Rt(e)?`${e.binBase}/expression_atlas.bin`:`${e.twinBase}/expression_atlas.json`}async function yt(e,t){const r=await fetch(e);if(!r.ok)throw new Error(`Failed to load encrypted asset: ${e}`);const n=await r.arrayBuffer();return ga(n,t)}async function Gi(e,t){if(!t)throw new Error("Missing asset key for encrypted JSON");const r=await yt(e,t),n=new TextDecoder().decode(r);return JSON.parse(n)}async function va(e){const t=new Blob([e],{type:"image/webp"});return createImageBitmap(t)}async function _a(e){const t=new Blob([e],{type:"image/webp"}),r=URL.createObjectURL(t);return new Promise((n,i)=>{const s=new Image;s.decoding="async",s.onload=()=>{URL.revokeObjectURL(r),n(s)},s.onerror=()=>{URL.revokeObjectURL(r),i(new Error("Failed to decode decrypted image"))},s.src=r})}async function ba(e){const t=new Blob([e],{type:"image/png"});return createImageBitmap(t)}async function Ki(e){const t=new Blob([e],{type:"image/png"}),r=URL.createObjectURL(t);return new Promise((n,i)=>{const s=new Image;s.decoding="async",s.onload=()=>{URL.revokeObjectURL(r),n(s)},s.onerror=()=>{URL.revokeObjectURL(r),i(new Error("Failed to decode decrypted PNG"))},s.src=r})}function qi(e){const t=new Blob([e],{type:"video/mp4"});return URL.createObjectURL(t)}async function Sa(e){const t=ya();if(!zt())return t;if(!e)throw new Error("Missing asset key for encrypted idle video");const r=await yt(t,e);return qi(r)}const sr=["open_palm","emphasis","thumbs_up","friendly_wave","point_camera"],Ta="ges",ka="m.json",xr={idle:"G_001",open_palm:"G_002",emphasis:"G_003",thumbs_up:"G_004",friendly_wave:"G_005",point_camera:"G_006"},Yi=new Set(sr),Qi={};for(const e of sr){const t=xr[e];t&&(Qi[t]=e)}function Ea(e){return!!e&&Yi.has(e)}function Ut(e){return e?Yi.has(e)?e:Qi[e]??null:null}function Xi(e,t=Pr){return`${t.replace(/\/$/,"")}/${e}/${Ta}`}function Ji(e){return`${e.replace(/\/$/,"")}/${ka}`}function Zi(e,t){const r=xr[t]??t;return`${e.replace(/\/$/,"")}/${r}.bin`}async function xa(e){const t=await fetch(Ji(e));if(!t.ok)throw new Error(`Failed to load full-body crop meta (${t.status})`);return await t.json()}async function ei(e,t,r){const n=await yt(Zi(e,t),r);return qi(n)}function Ia(e){const t=Math.min(1,Math.max(0,e));return t*t*t*(t*(t*6-15)+10)}const Aa=d.forwardRef(function({gesturesBase:t,keyHex:r,status:n,activePose:i=null,poseSynced:s=!1,style:o},a){const f=d.useRef(null),m=d.useRef(null),l=d.useRef(null),c=d.useRef(null),h=d.useRef(null),v=d.useRef(null),E=d.useRef(null),g=d.useRef({}),R=d.useRef(null),V=d.useRef(null),B=d.useRef([]),S=d.useRef(null),x=d.useRef(!1),O=d.useRef(!1),W=d.useRef(!1),G=d.useRef(!1),ie=d.useRef([]),M=d.useRef(n),U=d.useRef(0),J=d.useRef(0);M.current=n;const Q=y=>{const u=g.current[y];u&&(f.current?.pause(),W.current=!1,x.current=!0,V.current=y,O.current=B.current.length>0,se(u),re(!0),T(!1),H(p=>p+1))},ue=()=>{if(x.current)return;W.current=!1;const y=f.current;y&&(y.currentTime=0,y.play().catch(()=>{}),T(!0))};d.useImperativeHandle(a,()=>({waitForIdleCycleEnd:()=>{const y=f.current;if(!y||!Number.isFinite(y.duration)||y.duration<=0)return{promise:Promise.resolve(),cancel:()=>{}};if(y.ended||W.current)return W.current=!0,y.pause(),{promise:Promise.resolve(),cancel:()=>{}};let u;return{promise:new Promise(b=>{u={resolve:b,cancelled:!1},ie.current.push(u)}),cancel:()=>{u.cancelled=!0,ie.current=ie.current.filter(b=>b!==u)}}},resumeIdleLoop:()=>{ie.current=[],W.current&&ue()}}));const[ae,Ae]=d.useState(!1),[ke,re]=d.useState(!1),[Ke,T]=d.useState(!0),[Z,H]=d.useState(0),[j,de]=d.useState(null),[X,se]=d.useState(null),[fe,me]=d.useState({topFrac:.41,heightFrac:.59}),K=d.useCallback(()=>{const y=f.current,u=m.current;if(!y||!u)return;const p=y.videoWidth,b=y.videoHeight;if(p<1||b<1)return;(u.width!==p||u.height!==b)&&(u.width=p,u.height=b);const C=u.getContext("2d");C&&C.drawImage(y,0,0,p,b)},[]),te=d.useCallback(()=>{const y=l.current,u=c.current,p=R.current;if(!y||!u||!p)return;const b=y.videoWidth,C=y.videoHeight;if(b<1||C<1)return;(u.width!==b||u.height!==C)&&(u.width=b,u.height=C);const F=u.getContext("2d",{willReadFrequently:!0});if(!F)return;F.drawImage(y,0,0,b,C);const q=p.y_end,L=p.silHeight,$=p.seamLockPx??56,k=Math.max(1,L-q),ee=v.current;if(!ee||!ee.complete||ee.naturalWidth<1||ee.naturalHeight<=q)return;const pe=Math.max(8,Math.round($*(C/Math.max(1,k)))),Re=Math.min($,ee.naturalHeight-q);if(Re<1||pe<1)return;let Me=h.current;Me||(Me=document.createElement("canvas"),h.current=Me),(Me.width!==b||Me.height!==pe)&&(Me.width=b,Me.height=pe);const _e=Me.getContext("2d",{willReadFrequently:!0});if(!_e)return;_e.clearRect(0,0,b,pe),_e.drawImage(ee,0,q,ee.naturalWidth,Re,0,0,b,pe);const ye=F.getImageData(0,0,b,pe),w=_e.getImageData(0,0,b,pe),P=ye.data,ne=w.data,ge=Math.max(1,pe-1);for(let we=0;we<pe;we++){const ve=Ia(we/ge),Pe=1-ve,Ue=ve,Ve=we*b*4;for(let vt=0;vt<b;vt++){const We=Ve+vt*4;P[We]=ne[We]*Pe+P[We]*Ue,P[We+1]=ne[We+1]*Pe+P[We+1]*Ue,P[We+2]=ne[We+2]*Pe+P[We+2]*Ue}}F.putImageData(ye,0,0)},[]);if(d.useEffect(()=>{let y=!1;const u=[];return(async()=>{try{const p=await xa(t);if(y)return;R.current=p;const b=Math.max(1,p.silHeight),C=Math.max(0,Math.min(p.y_end,b-1));if(me({topFrac:C/b,heightFrac:1-C/b}),zt()){const $=await yt(tr(),r),k=await Ki($);if(y)return;v.current=k}const F=await ei(t,"idle",r);if(u.push(F),y){URL.revokeObjectURL(F);return}E.current=F,de(F);const q={};for(const $ of sr){const k=await ei(t,$,r);if(u.push(k),y){URL.revokeObjectURL(k);return}q[$]=k}g.current=q;const L=q.open_palm??Object.values(q)[0];L&&se(L),Ae(!0)}catch{y||Ae(!1)}})(),()=>{y=!0;for(const p of u)URL.revokeObjectURL(p);E.current=null,g.current={}}},[t,r]),d.useEffect(()=>{const y=f.current,u=m.current;if(!ae||!y||!u||!j)return;const p=()=>{x.current||(y.currentTime=0,y.play().catch(()=>{}))},b=()=>{y.play().catch(()=>{})},C=()=>{const q=B.current[0];if(O.current&&M.current==="speaking"&&q&&!x.current){if(!g.current[q]){p();return}B.current.shift(),Q(q);return}const L=ie.current.filter($=>!$.cancelled);if(L.length>0&&!x.current){ie.current=[],W.current=!0,y.pause();for(const $ of L)$.resolve();return}if(M.current==="speaking"){W.current=!0,y.pause();return}p()};y.addEventListener("loadedmetadata",b),y.addEventListener("ended",C),y.readyState>=1&&b();const F=()=>{K(),U.current=requestAnimationFrame(F)};return U.current=requestAnimationFrame(F),()=>{y.removeEventListener("loadedmetadata",b),y.removeEventListener("ended",C),cancelAnimationFrame(U.current)}},[ae,j,K]),d.useEffect(()=>{if(!ae)return;if(!(n==="speaking")){const p=G.current;if(G.current=!1,B.current=[],S.current=null,O.current=!1,!x.current)if(re(!1),p)ue();else{T(!0);const b=f.current;b?.paused&&!W.current&&b.play().catch(()=>{})}return}if(G.current=!0,!s)return;const u=Ut(i);if(u&&u!==S.current&&u!==V.current&&!B.current.includes(u)&&(B.current.push(u),S.current=u),B.current.length>0&&!x.current){const p=B.current.shift();p&&Q(p)}},[n,ae,i,s]),d.useEffect(()=>{if(!ke||!X||Z===0)return;const y=l.current;if(!y)return;y.src=X,y.currentTime=0,y.play().catch(()=>{if(x.current=!1,V.current=null,M.current==="speaking")return;re(!1),T(!0);const b=f.current;b&&(b.currentTime=0,b.play().catch(()=>{}))});const u=()=>{te(),J.current=requestAnimationFrame(u)};J.current=requestAnimationFrame(u);const p=()=>{if(x.current=!1,V.current=null,M.current==="speaking"){const C=B.current.shift();if(C){Q(C);return}y.pause();return}re(!1),T(!0),B.current=[],S.current=null,O.current=!1;const b=f.current;b&&(b.currentTime=0,b.play().catch(()=>{}))};return y.addEventListener("ended",p),()=>{cancelAnimationFrame(J.current),y.removeEventListener("ended",p)}},[ke,X,Z,te]),!j)return null;const oe=n==="speaking";return A.jsxs("div",{"aria-hidden":!0,style:{position:"absolute",inset:0,pointerEvents:"none",...o},children:[A.jsx("video",{ref:f,src:j,muted:!0,playsInline:!0,preload:"auto",style:{position:"absolute",width:1,height:1,opacity:0,overflow:"hidden"}}),A.jsx("canvas",{ref:m,style:{position:"absolute",inset:0,width:"100%",height:"100%",objectFit:"cover",zIndex:1,opacity:Ke?1:0,clipPath:oe?`inset(${fe.topFrac*100}% 0 0 0)`:void 0,transition:"opacity 650ms ease"}}),X?A.jsxs(A.Fragment,{children:[A.jsx("video",{ref:l,muted:!0,playsInline:!0,preload:"auto",style:{position:"absolute",width:1,height:1,opacity:0,overflow:"hidden"}}),A.jsx("canvas",{ref:c,style:{position:"absolute",left:0,width:"100%",top:`${fe.topFrac*100}%`,height:`${fe.heightFrac*100}%`,objectFit:"fill",zIndex:2,opacity:ke?1:0,transition:"opacity 280ms ease-in-out"}})]}):null]})}),It=[{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}],es=It.map(e=>e.code),Ra=new Set(es),Ma=new Set(It.filter(e=>e.visemetts).map(e=>e.code)),Pa=new Set(It.filter(e=>e.cartesia).map(e=>e.code)),Ca="en";function ts(e){return Ra.has(e)}function Br(e){const t=e?.trim();if(t)return t}function Fa(e){return e===ft?It.filter(t=>t.visemetts).map(t=>t.code):e===dt?It.filter(t=>t.cartesia).map(t=>t.code):It.filter(t=>t.visemetts&&t.cartesia).map(t=>t.code)}function Ba(e,t){const r=t.trim();return r?e===ft?Ma.has(r):e===dt?Pa.has(r):ts(r):!1}function rs(e){const t=e.split(/\r?\n/);let r="",n="";for(const s of t)s.startsWith("event:")?r=s.slice(6).trim():s.startsWith("data:")&&(n=s.slice(5).trim());if(!r)return null;let i={};if(n)try{i=JSON.parse(n)}catch{i={raw:n}}return{event:r,data:i}}const ns=["aa","CH","DD","E","FF","I","O","PP","RR","SS","TH","U","kk","nn","sil"],Da=new Map(ns.map(e=>[e.toLowerCase(),e]));function Dr(e){const t=(e??"").trim();return t?Da.get(t.toLowerCase())??"sil":"sil"}const La={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 Oa(e){if(!e)return["sil"];const t=e.toLowerCase();return La[t]??["sil"]}function is(e,t){const r=e.word.length;if(r<=0)return 0;const n=e.wduration;if(n<=0)return 0;const i=Math.max(0,Math.min(1,(t-e.wtime)/n));return Math.min(r-1,Math.floor(i*r))}function Wt(e,t){const r=Math.max(0,Math.min(e.length-1,t));return e[r]??""}function Lr(e,t){const r=e.toLowerCase().replace(/[^a-z']/g,"");return!r||Wt(r,t)!=="w"||t>0&&Wt(r,t-1)==="q"?!1:t===0&&/^w[aeiouy]/.test(r)}function Na(e,t){const r=e.toLowerCase(),n=Wt(r,t),i=r.slice(Math.max(0,t-1),t+2);return n==="i"||n==="y"?"I":i.includes("ee")||n==="e"||r.includes("ea")?"E":"aa"}function Ua(e,t){const r=e.toLowerCase(),n=r.slice(Math.max(0,t-1),Math.min(r.length,t+3));if(/oo|ou|uw/.test(n))return"U";if(Lr(r,t))return"FF";const i=Wt(r,t);return i==="u"||i==="w"?"U":"O"}function Va(e,t){const r=e.toLowerCase();if(Lr(r,t))return"FF";const n=r.slice(Math.max(0,t-2),t+1);if(/qu/.test(n))return"U";const i=r.slice(Math.max(0,t-1),Math.min(r.length,t+3));return/wo|wh/.test(i)||Wt(r,t)==="o"?"O":"U"}const _r={d:"DD",t:"DD",n:"DD",s:"SS",z:"SS",k:"kk",g:"kk",c:"CH",x:"CH",j:"CH"};function Wa(e,t){const r=e.toLowerCase(),n=Wt(r,t);if(_r[n])return _r[n];for(let i=0;i<r.length;i++){const s=r[i];if(_r[s])return _r[s]}return"DD"}function ss(e,t,r){const n=Oa(e);if(n.length===1)return n[0];const i=t.trim();if(!i)return n[0];const s=(e??"").toLowerCase(),o=Math.max(0,r);switch(s){case"aei":return Na(i,o);case"o":return Ua(i,o);case"qw":return Va(i,o);case"cdgknstxyz":return Wa(i,o);default:return n[0]}}const kn=16,dn=47,as=new Set(["aa","E","I"]),os=new Set(["DD","SS","kk","CH"]),ja=[as,os];function Ha(e){for(const t of ja)if(t.has(e))return t;return null}function $a(e){return Ha(e)!=null}function cs(e,t=kn){return t<=0?e:Math.round(e/t)*t}function En(e,t=kn){return e.map(r=>({...r,vtime:cs(r.vtime,t)}))}function ls(e){const t=new Map;for(const r of e)t.has(r.vtime)||t.set(r.vtime,r);return[...t.values()].sort((r,n)=>r.vtime-n.vtime)}function xn(e){if(e.length<=2)return[...e];const t=[e[0]];for(let r=1;r<e.length-1;r++){const n=e[r],i=e[r+1],s=t[t.length-1];if(!$a(n.viseme)){t.push(n);continue}const o=n.vtime-s.vtime,a=i.vtime-n.vtime;o<dn||a<dn||t.push(n)}return t.push(e[e.length-1]),t}function Or(e){return xn(ls(En(e)))}function us(e,t){let r="sil";for(const n of e){if(n.vtime>t)break;n.viseme!=="sil"&&(r=n.viseme)}return r}function Nr(e){const t=ls(En(e)),r=xn(t),n=new Set(r.map(s=>s.vtime)),i=[];for(const s of t)n.has(s.vtime)||i.push({viseme:s.viseme,vtime:s.vtime});return i}function za(e){return Nr(e).map(t=>t.viseme)}const Ga=32,ti=48;function ds(e){let t=0;for(const r of e)t=Math.max(t,r.vtime+r.vduration);return t}function fs(e){let t=null,r=-1;for(const n of e){if(n.viseme==="sil")continue;const i=n.vtime+n.vduration;i>r&&(t=n,r=i)}return t}function Ka(e){return Or(e).find(r=>r.viseme!=="sil")??null}function kt(e){const t=ds(e);return fs(e)?t+yn:t}function qa(e){const t=[],r=Ka(e);r&&r.vtime>0&&t.push({from:"sil",to:r.viseme,fromVtime:0,toVtime:r.vtime});const n=fs(e),i=ds(e);return n&&t.push({from:n.viseme,to:"sil",fromVtime:i,toVtime:i+yn}),t}function ms(e){const t=Or(e),r=[];for(let n=0;n<t.length-1;n++){const i=t[n].viseme,s=t[n+1].viseme,o=t[n].vtime,a=t[n+1].vtime;i===s||a<=o||r.push({from:i,to:s,fromVtime:o,toVtime:a})}return r}function hs(e){return e.length===0?[]:[...qa(e),...ms(e)]}function Ya(e,t,r=!1){let n=null;for(const i of e){const{transStart:s,transEnd:o}=ps(i.fromVtime,i.toVtime,i.from,i.to,r);t>=s&&t<o&&(n=i)}return n}function ps(e,t,r,n,i=!1){const s=Math.max(0,t-e);if(i&&(r==="PP"||n==="PP")&&s>ti){const l=ti,c=t,h=c-l;return{gapMs:s,effectiveGapMs:l,holdEnd:h,transStart:h,transEnd:c}}const a=s>0?Math.max(s,Ga):0,f=e,m=e+a;return{gapMs:s,effectiveGapMs:a,holdEnd:e,transStart:f,transEnd:m}}function gs(e,t,r,n,i,s){n.forEach(o=>{const f=String(o.word??"").trim();if(!f)return;const m=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:f,wtime:i+m,wduration:l,queueIndex:t.length,gesture:o.gesture??null,emphasis:o.emphasis===!0})}),r.forEach(o=>{const a=String(o.symbol??o.viseme??"").trim();if(!a)return;const f=Math.round((o.start??0)*1e3),m=Math.max(1,Math.round((o.duration??0)*1e3)),l=i+f,c=vs(t,l),h=c?is(c,l):0;let v;Di(s)==="oculus_direct"?(v=Dr(a),v==="U"&&c&&Lr(c.word,h)&&(v="FF")):v=ss(a,c?.word??"",h),e.push({viseme:v,weight:1,vtime:l,vduration:m})})}function ws(e,t){let r=t;for(const n of e){const i=Math.round((n.start??0)*1e3),s=Math.max(1,Math.round((n.duration??0)*1e3));r=Math.max(r,t+i+s)}return r}const In=16e3;function ys(e){const t=Number(e);return Number.isFinite(t)&&t>0?t:In}function Qa(e){let t=e.trim();const r=t.indexOf(",");t.startsWith("data:")&&r>=0&&(t=t.slice(r+1)),t=t.replace(/\s+/g,"").replace(/-/g,"+").replace(/_/g,"/");const n=t.length%4;return n!==0&&(t+="=".repeat(4-n)),t}function Xa(e){return e.length>=4&&e[0]===82&&e[1]===73&&e[2]===70&&e[3]===70}function ri(e,t,r=In){const n=t.byteOffset%2===0?t:t.slice(),i=new Int16Array(n.buffer,n.byteOffset,n.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,r);return o.copyToChannel(s,0),o}function Ja(e){const t=Qa(e),r=window.atob(t),n=new Uint8Array(r.length);for(let i=0;i<r.length;i++)n[i]=r.charCodeAt(i);return n}async function ni(e,t,r=In){const n=Ja(t),i=ys(r);if(Xa(n)){const s=n.buffer.slice(n.byteOffset,n.byteOffset+n.byteLength);return e.decodeAudioData(s)}if(n.length>=2&&n.length%2===0)return ri(e,n,i);try{const s=n.buffer.slice(n.byteOffset,n.byteOffset+n.byteLength);return await e.decodeAudioData(s)}catch{return ri(e,n,i)}}function vs(e,t){for(const r of e)if(t>=r.wtime&&t<r.wtime+r.wduration)return r;return null}function _s(e,t){const r=[],n=[];let i=null,s=!1,o=!1,a=!1,f=!1,m=0,l=0,c=0,h=null,v=1,E=t,g=!1,R=null,V=null,B=!1,S=0,x=!1,O=!1,W=0,G=null,ie=null,M=null,U=null,J=null;const Q=()=>({visemes:[],words:[],segmentOffsetMs:0}),ue=()=>{O=!1,W=0},ae=()=>{const u=ie;G=null,ie=null,u?.(),!g&&!s&&n.length===0&&r.length>0&&M&&U&&K(M,U)},Ae=()=>{G||(G=new Promise(u=>{ie=u}))},ke=()=>{h!=null&&(clearTimeout(h),h=null)},re=()=>{for(const u of n){try{u.onended=null,u.stop(0)}catch{}try{u.disconnect()}catch{}}n.length=0},Ke=()=>{for(const u of n)u.playbackRate.value=v},T=()=>{if(!(g||!f||s||O||n.length>0||r.length>0)){if(a&&i&&l>0){const u=(i.currentTime-l)*1e3;if(u<S){ke();const p=v>0?(S-u)/v:S-u;h=setTimeout(()=>{g||(o=!1,h=null,e.onSpeakingDone(),e.onNotify())},Math.max(0,p));return}}o=!1,ke(),e.onSpeakingDone(),e.onNotify()}},Z=u=>{const p=kt(u);if(p<=0){e.onSpeakingDone(),e.onNotify();return}o=!0,m=performance.now(),e.onSpeakingStart(),e.onNotify(),ke();const b=v>0?p/v:p;h=setTimeout(()=>{g||(o=!1,h=null,e.onSpeakingDone(),e.onNotify())},b)},H=(u,p,b,C)=>{p.length!==0&&(c=b,p.forEach(F=>{const L=String(F.word??"").trim();if(!L)return;const $=Math.round((F.start??0)*1e3),k=F.duration!=null?Math.round(F.duration*1e3):F.end!=null?Math.max(1,Math.round((F.end-(F.start??0))*1e3)):0;u.push({word:L,wtime:c+$,wduration:k,queueIndex:u.length,gesture:F.gesture??null,emphasis:F.emphasis===!0})}))},j=(u,p,b,C,F,q)=>{b.length!==0&&(c=C,b.forEach(L=>{const $=String(L.symbol??L.viseme??"").trim();if(!$)return;const k=Math.round((L.start??0)*1e3),ee=Math.max(1,Math.round((L.duration??0)*1e3)),pe=c+k,Re=vs(p,pe),Me=Re?is(Re,pe):0;let _e;Di(q)==="oculus_direct"?(_e=Dr($),_e==="U"&&Re&&Lr(Re.word,Me)&&(_e="FF")):_e=ss($,Re?.word??"",Me),u.push({viseme:_e,weight:1,vtime:pe,vduration:ee})}),e.onNotify())},de=(u,p,b,C,F,q,L)=>{H(p,C,F),j(u,p,b,F,q,L)},X=(u,p,b)=>{J===u&&u.visemes===p||(p.length=0,b.length=0,u.visemes=p,u.words=b,u.segmentOffsetMs=0,J=u,c=0,S=0)},se=u=>(V||(V=u.createGain(),V.gain.value=B?0:1,V.connect(u.destination)),V),fe=async()=>{const u=window.AudioContext||window.webkitAudioContext;return i||(i=new u,V=null,R=null),i.state==="suspended"&&await i.resume(),se(i),R||(R=i.createMediaStreamDestination()),i},me=(u,p)=>{if(!i)return 0;const b=i,C=b.currentTime,F=C+.02;if(p.isFirstAudio){l<=0&&(l=F);const L=(F-C)*1e3;m=performance.now()+L}p.onBeforeStart?.(F);const q=b.createBufferSource();return q.buffer=u,q.playbackRate.value=v,q.connect(se(b)),R&&q.connect(R),n.push(q),g?(n.pop(),F):(p.isFirstAudio&&(o=!0,e.onSpeakingStart()),q.onended=()=>{const L=n.indexOf(q);L>=0&&n.splice(L,1),e.onNotify(),!g&&(M&&U?K(M,U):T())},q.start(F),F)},K=async(u,p)=>{if(g||s||n.length>0)return;if(r.length===0){T();return}s=!0;let b=!1;try{if(G&&await G,g)return;const C=await fe();if(g)return;const F=r[0];if(!F)return;const q=!o;if(x&&(e.shouldHoldForWarmup?.()??!1)&&(O||q&&F.newStream)||O){X(F.utterance,u,p);for(const k of r){if(g)return;k.audioBuffer||(k.audioBuffer=await ni(C,k.audio,k.sampleRate)),a=!0,O||(O=!0,W=0,k.newStream&&k.onNewStream?.()),k.visemesQueued||(de(u,p,k.visemes,k.words,W,!0,E),k.visemesQueued=!0,W+=Math.round(k.audioBuffer.duration*1e3),S=Math.max(S,kt(u)))}e.onNotify();return}const $=r.shift();if(!$||($.audioBuffer||($.audioBuffer=await ni(C,$.audio,$.sampleRate)),g))return;a=!0,ke(),X($.utterance,u,p),$.visemesQueued=!1,$.newStream&&$.onNewStream?.(),me($.audioBuffer,{isFirstAudio:!o,isFirstOfStream:!1,onBeforeStart:k=>{l=k,c=0,m=performance.now()+(k-C.currentTime)*1e3,u.length=0,p.length=0,de(u,p,$.visemes,$.words,0,!0,E),$.visemesQueued=!0,$.utterance.segmentOffsetMs=0}}),b=n.length>0,S=kt(u),e.onNotify()}catch(C){console.error("[avatarChunkPlayback] audio chunk failed:",C)}finally{if(s=!1,g)return;if(O){r.some(F=>!F.audioBuffer||!F.visemesQueued)&&K(u,p);return}!b&&n.length===0&&r.length>0?K(u,p):n.length===0&&r.length===0&&T()}};return{setStreamTtsEngineId:u=>{E=u},setPlaybackSpeed:u=>{v=Math.max(.1,Math.min(1,u)),Ke()},getPlaybackSpeed:()=>v,setMuted:u=>{B=u,V&&(V.gain.value=u?0:1)},isMuted:()=>B,setLipsyncWarmupHoldEnabled:u=>{x=u,u||ue()},isWarmingUp:()=>O,releaseWarmupHold:()=>{if(O){O=!1,W=0;for(const u of r)u.newStream=!1;M&&U&&K(M,U),e.onNotify()}},resetForNewStream:u=>{g=!1,f=!1,E=u,S=0},resumeBotStream:()=>{g=!1,f=!1},clearAborted:()=>{g=!1},primeAudioContext:async()=>{const u=window.AudioContext||window.webkitAudioContext;i||(i=new u,V=null,R=null),i.state==="suspended"&&await i.resume(),se(i),R||(R=i.createMediaStreamDestination())},armStartHold:Ae,releaseStartHold:ae,stop:()=>{g=!0,ae(),ke(),re(),r.length=0,s=!1,o=!1,a=!1,f=!1,c=0,l=0,m=0,S=0,M=null,U=null,J=null,ue()},markStreamComplete:u=>{if(S=Math.max(S,kt(u)),f=!0,!a&&u.length>0){Z(u);return}T()},playAudioChunk:async(u,p,b,C,F,q,L)=>{if(g)return;M=u,U=p;const $=ys(L?.sampleRate),k=L?.newStream===!0,ee=Q();if(!b?.trim()){if(C.length===0&&F.length===0)return;X(ee,u,p),k&&L?.onNewStream?.(),de(u,p,C,F,0,!0,E),S=kt(u),!o&&S>0&&Z(u),e.onNotify();return}r.push({audio:b,audioBuffer:null,utterance:ee,visemes:C,words:F,isNewSegment:q,sampleRate:$,newStream:k,onNewStream:L?.onNewStream,visemesQueued:!1}),await K(u,p)},queueTimingsOnly:(u,p,b,C,F,q)=>{if(g)return;const L=Q();X(L,u,p),de(u,p,b,C,0,!0,E),L.segmentOffsetMs=0,S=kt(u)},getPlaybackElapsedMs:()=>a&&i&&l>0?Math.max(0,(i.currentTime-l)*1e3*v):o?Math.max(0,(performance.now()-m)*v):0,isSpeaking:()=>o?!0:!a||!i||l<=0?!1:(i.currentTime-l)*1e3<S,getVoiceStream:()=>R?R.stream:null,getPlaybackStartPerf:()=>m,bargeIn:()=>{g=!0,ae(),f=!1,ke(),re(),r.length=0,s=!1,o=!1,a=!1,c=0,l=0,m=0,S=0,M=null,U=null,J=null,ue()},interrupt:()=>{g=!0,ae(),f=!1,ke(),re(),r.length=0,s=!1,o=!1,a=!1,c=0,l=0,m=0,S=0,M=null,U=null,J=null,ue()}}}function ar(e,t){let r=null;for(const n of e)t<n.vtime||t>=n.vtime+n.vduration||(!r||n.vtime>=r.vtime)&&(r=n);return r?r.viseme:"sil"}function bs(e,t,r=120){const n=ar(e,t);if(n!=="sil")return n;let i=null;for(const s of e){if(s.vtime>t)break;const o=s.vtime+s.vduration;o<=t&&t-o<=r&&(i=s)}return i?.viseme??"sil"}function Za(e,t,r=400){const n=t-r;let i=0;for(const s of e)if(s.vtime+s.vduration<n)i+=1;else break;i>0&&e.splice(0,i)}function Ss(e,t){for(const r of e)if(t>=r.wtime&&t<r.wtime+r.wduration)return r;return null}function ii(e,t,r){const n=Ss(e,t);if(n?.gesture&&r(n.gesture))return n.gesture;for(const i of e)if(i.wtime>=t&&i.gesture&&r(i.gesture))return i.gesture;for(const i of e)if(i.gesture&&r(i.gesture))return i.gesture;return null}function si(e,t){const r=e.trim();if(!r)return null;try{const n=r.replace(/\s+/g,""),i=atob(n).length,s=Number.isFinite(t)&&(t??0)>0?Number(t):16e3;return i/2/s*1e3}catch{return null}}const Ur=.5,Vr=1.5,An="Olivia",Rn="f786b574-daa5-4673-aa0c-cbe3e8534c02",or=.85;function fn(e,t=ut,r={}){const n=`${t.replace(/\/$/,"")}/avatar_ttsWithPoses`,i=[],s=[],o=[],a=[];let f=0;const m=[],l=[];let c="",h="neutral",v="",E=xt,g=!!r.fullBody;const R=new Set;let V=0,B=null,S=0,x=null;const O=()=>R.forEach(T=>T());let W=()=>!1;const G=_s({onSpeakingStart:()=>e("speaking"),onSpeakingDone:()=>e("done"),onNotify:O,shouldHoldForWarmup:()=>W()},xt),ie=()=>G.getPlaybackElapsedMs(),M=(T,Z=c)=>{if(!r.onLipsyncDebug)return;const H=ie(),j=i,de=Nr(o).map(X=>({viseme:X.viseme,vtimeMs:X.vtime}));r.onLipsyncDebug({event:T,spokenText:Z,mood:h,playbackAnchorPerf:G.getPlaybackStartPerf(),playbackElapsedMs:H,queueLength:j.length,activeViseme:ar(j,H),segments:l.map(X=>({...X,visemes:[...X.visemes]})),fullQueueLength:o.length,compactionSkipped:de})},U=(T,Z)=>{r.onLipsyncDebug&&(B={event:T,spokenText:Z},V===0&&(V=requestAnimationFrame(()=>{V=0;const H=B;B=null,H&&M(H.event,H.spokenText)})))},J=(T,Z,H,j,de)=>{if(!r.onLipsyncDebug)return;const X=i.slice(Z),se=H.filter(fe=>String(fe.symbol??fe.viseme??"").trim());l.push({spokenText:T,audioOffsetMs:X[0]?.vtime??0,isNewSegment:j,chunkDurationMs:de,receivedAtMs:performance.now(),visemes:X.map((fe,me)=>{const K=se[me];return{rawSymbol:String(K?.symbol??K?.viseme??fe.viseme).trim(),viseme:fe.viseme,startSec:Number(K?.start??0),durationSec:Number(K?.duration??0),vtimeMs:fe.vtime,vdurationMs:fe.vduration}})})},Q=()=>{o.length=0,a.length=0,f=0},ue=(T,Z,H,j,de)=>{if(T.length===0&&Z.length===0)return;gs(o,a,T,Z,f,de);const X=ws(T,f),se=H?si(H,j):null;f=Math.max(X,se!=null?f+se:f)},ae=()=>{S+=1,x?.abort(),x=null,G.stop(),i.length=0,s.length=0,Q(),m.length=0,h="neutral",l.length=0,c="",e("idle"),U("reset"),O()},Ae=T=>{const Z=lt(T?.ttsEngineId,T?.voiceId),H=Z.ttsEngineId??E??xt,j=Z.voiceId??(H===ft?Fr:An),de=T?.speakingRate??or,X=Math.max(Ur,Math.min(Vr,de));return{engineId:H,voiceId:j,speakingRate:X,language:Br(T?.language)}},ke=async T=>{ae();const Z=S;x=new AbortController,e("loading"),c=T.debugSpokenFallback,l.length=0,Q();const H=v.trim();if(!H)throw new Error("Developer token required for avatar_ttsWithPoses");G.resetForNewStream(T.engineId),G.setStreamTtsEngineId(T.engineId),T.delayPlayback&&G.armStartHold();let j="",de="";try{const X=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${H}`,Accept:"text/event-stream"},body:JSON.stringify(T.requestBody),signal:x.signal});if(!X.ok)throw new Error(`avatar_ttsWithPoses failed (${X.status})`);const se=X.body;if(!se)throw new Error("No response body");const fe=se.getReader(),me=new TextDecoder;let K="",te=!0;const oe=()=>j||T.debugSpokenFallback,y=async u=>{if(Z!==S)return;const p=rs(u);if(p){if(p.event==="spokenText"){const b=typeof p.data.text=="string"?p.data.text.trim():"";b&&(j=b,c=b,T.onSpokenText?.(b),O());return}if(p.event==="displayText"){const b=typeof p.data.text=="string"?p.data.text.trim():"";b&&(de=b,T.onDisplayText?.(b),O());return}if(p.event!=="done"){if(p.event==="audio"){const b=p.data.chunk,C=p.data.visemes??[],F=p.data.words??[],q=p.data.is_new_segment??!1,L=p.data.sample_rate,$=Number(p.data.audio_offset_ms??0),k=i.length,ee=oe();if(ue(C,F,b,L,T.engineId),b){const pe=te;te=!1,await G.playAudioChunk(i,s,b,C,F,q,{sampleRate:L,newStream:pe,audioOffsetMs:$}),J(ee,k,C,q,si(b,L)),U("audio_chunk",ee)}else(C.length>0||F.length>0)&&(G.queueTimingsOnly(i,s,C,F,q,{audioOffsetMs:$,newStream:te}),J(ee,k,C,q,null),U("audio_chunk",ee))}else if(p.event==="metadata"){const b=p.data.mood;typeof b=="string"&&b.trim()&&(h=b.trim());const C=p.data.spoken_text??p.data.text;typeof C=="string"&&C.trim()&&!j&&(j=C.trim(),c=j);const F=p.data.sentence_emotions;if(Array.isArray(F)){m.length=0;for(const q of F){if(!q||typeof q!="object")continue;const L=q;m.push({sentence_index:Number(L.sentence_index??0),text:String(L.text??""),sentiment:typeof L.sentiment=="string"?L.sentiment:void 0,emotion:String(L.emotion??h),start_word:Number(L.start_word??0),end_word:Number(L.end_word??0)})}}O(),U("metadata",oe())}else if(p.event==="error")throw new Error(String(p.data.message??"avatar_ttsWithPoses stream error"))}}};for(;;){if(Z!==S)return{displayText:de,spokenText:j,aborted:!0};const{done:u,value:p}=await fe.read();p&&(K+=me.decode(p,{stream:!0}));const b=K.split(`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const M=require("react/jsx-runtime"),d=require("react"),Qs=require("@pipecat-ai/client-js"),_n=require("@pipecat-ai/websocket-transport"),_e=require("pixi.js");var en=typeof document<"u"?document.currentScript:null;const Xs="https://aitwin.bubu.social",Li={publicBase:Xs},Js="0.7.8",Zs={version:Js},ea={},lt="https://ai.aitwin.me",Dr=`${Li.publicBase}/custom-faces`,ta=`${Li.publicBase}/aitwin-workers/v${Zs.version}/visemeDiffPreview.worker.js`;function ra(e){if(e)return e;const t=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:en&&en.tagName.toUpperCase()==="SCRIPT"&&en.src||new URL("aitwin.cjs",document.baseURI).href}<"u"?ea?.VITE_AITWIN_WORKER_URL:void 0;return t?.trim()?t.trim():ta}const na="https://us-central1-streamoji-265f4.cloudfunctions.net/getAiTwin",tn=3e3,nr=16,ti=3e3,ia=4e3,sa=.85,aa=8,bn=400,Sn="eng_a7f2b9c1",Lr="eng_d4e8f3a2",ut="eng_c9b1e6d4",dt="visemetts",At=ut,Or="eve",ln=new Set([Lr,ut,dt]),Tn={[Sn]:"oculus_direct",[ut]:"oculus_direct",[dt]:"oculus_direct",[Lr]:"inworld_word"},un={google:Sn,inworld:Lr,cartesia:ut,visemetts:dt};function oa(e){const t=e.trim();if(t)return t in Tn?t:un[t.toLowerCase()]}function Oi(e){const t=e?.trim();if(!t)return{};const r=t.indexOf(":");if(r<=0)return{voiceId:t};const n=oa(t.slice(0,r));if(!n)return{voiceId:t};const i=t.slice(r+1).trim();return{ttsEngineId:n,voiceId:i||void 0}}function ct(e,t){const r=Oi(t);return{ttsEngineId:r.ttsEngineId??e,voiceId:r.voiceId}}function Ni(e){return Tn[e]}function Ui(e){return e===ut}function Vi(e){return e===dt}function ca(e){if(e.ttsEngineId&&e.ttsEngineId in Tn)return e.ttsEngineId;const t=e.tts?.toLowerCase();return t&&t in un?un[t]:At}class Ar extends Error{constructor(t="AI twin not found"){super(t),this.name="AiTwinNotFoundError"}}function kn(e,...t){const r=typeof e=="string"?e:e?.brainId?.trim()||e?.knowledgeContextId?.trim();for(const n of[r,...t]){const i=n?.trim();if(i)return i}}function En(e,...t){const r=typeof e=="string"?e:e?.brainUrl?.trim();for(const n of[r,...t]){const i=n?.trim();if(i)return i}}function la(e){const t=(e??"").trim();if(!t)return;let r;try{r=new URL(t)}catch{throw new Error("brainUrl must be an http or https URL")}if(r.protocol!=="http:"&&r.protocol!=="https:")throw new Error("brainUrl must be an http or https URL");if(!r.host)throw new Error("brainUrl must be an http or https URL");if(r.hash)throw new Error("brainUrl must not include a fragment");return t}async function Wi(e,t=na){const r=new URL(t);r.searchParams.set("id",e);const n=await fetch(r.toString());if(n.status===404)throw new Ar;if(!n.ok)throw new Error(`getAiTwin failed (${n.status})`);const i=await n.json();if(!i.success)throw new Ar(i.error??"AI twin not found");const{tts:s,token:o,...a}=i.data,f=String(a.authToken??o??"").trim()||void 0,m=kn(a),u=En(a);return{...a,ttsEngineId:ca(i.data),authToken:f,brainId:m,knowledgeContextId:m,brainUrl:u}}const xn="thumbnail.webp";function ji(e,t=Dr){const r=e.trim();if(!r)throw new Error("faceId is required");return`${t.replace(/\/$/,"")}/${r}/${xn}`}function ri(e){const t=e?.trim();if(!t)return null;try{return ji(t)}catch{return null}}function ua(e){if(!e)return null;const t=(e.binBase||e.twinBase).trim().replace(/\/$/,"");return t?`${t}/${xn}`:null}const da="https://us-central1-streamoji-265f4.cloudfunctions.net/getAuthToken",fa="client_6TNvp3SCs4Og0a1ijm9TommXLql1",ma="kk8Fq8EmexzP10jMIEwY3R44M5RKUEm1",ha="6TNvp3SCs4Og0a1ijm9TommXLql1",pa="Swaraj Mali";async function Ir(){const e=await fetch(da,{method:"POST",headers:{"Content-Type":"application/json","Client-Id":fa,"Client-Secret":ma},body:JSON.stringify({userId:ha,userName:pa})});if(!e.ok)throw new Error(`getAuthToken failed (${e.status})`);const t=await e.json(),r=t.authToken??t.token??"";if(!r.trim())throw new Error("getAuthToken returned no token");return r}async function ga(e,t=lt){const r=await fetch(`${t.replace(/\/$/,"")}/api/session-value`,{headers:{Authorization:`Bearer ${e}`}});if(!r.ok)throw new Error(`/api/session-value failed (${r.status})`);const n=await r.json();if(!n.value)throw new Error("Session value response missing value");return n}function wa(e){const t=e.trim();if(t.length%2!==0)throw new Error("Invalid hex key");const r=new Uint8Array(t.length/2);for(let n=0;n<t.length;n+=2)r[n/2]=Number.parseInt(t.slice(n,n+2),16);return r}function Sr(e){return Uint8Array.from(e)}function ya(e,t){const r=new Uint8Array(e.length+t.length);return r.set(e,0),r.set(t,e.length),r}async function va(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 r=new Uint8Array(e),n=Sr(r.subarray(0,12)),i=Sr(r.subarray(12,28)),s=Sr(r.subarray(28)),o=Sr(ya(s,i)),a=await crypto.subtle.importKey("raw",wa(t),{name:"AES-GCM"},!1,["decrypt"]);return crypto.subtle.decrypt({name:"AES-GCM",iv:n,tagLength:128},a,o)}let dn=null;const fn=new Set;function Tr(e){return e.includes("/custom-faces/")}function Rr(e){const t=e.binBase.trim().replace(/\/$/,""),r=e.twinBase.trim().replace(/\/$/,"");if(!(e.encrypted||Tr(t)||Tr(r)))return{twinBase:r,binBase:t,encrypted:!1};const i=Tr(t)?t:Tr(r)?r:t;return{twinBase:i,binBase:i,encrypted:!0}}function Pt(e){return Rr(e).encrypted}function mn(e,t=Dr){const r=`${t.replace(/\/$/,"")}/${e}`;return{twinBase:r,binBase:r,encrypted:!0}}function Hi(e,t){return(e??t)?.trim()||void 0}function $i(e){dn=Rr(e);for(const t of fn)t()}function _a(e,t){const r=typeof globalThis.location<"u"?globalThis.location.href:void 0;if(!r)return Rr(e);const n=i=>{try{return new URL(i,r).href.replace(/\/$/,"")}catch{return i}};return Rr({twinBase:n(e.twinBase),binBase:n(e.binBase),encrypted:e.encrypted})}function Ct(){if(!dn)throw new Error("Twin assets not configured; call setActiveTwinAssets first");return dn}function zi(e){return fn.add(e),()=>fn.delete(e)}function ir(){const e=Ct();return Pt(e)?`${e.binBase}/sil.bin`:`${e.twinBase}/sil.png`}function ba(){const e=Ct();return Pt(e)?`${e.binBase}/idle.bin`:`${e.twinBase}/idle.mp4`}function Gi(){const e=Ct();return Pt(e)?e.binBase:e.twinBase}function Gt(){return Pt(Ct())}function Ki(){const e=Ct();return Pt(e)?`${e.binBase}/atlas.bin`:`${e.twinBase}/atlas.json`}function qi(){const e=Ct();return Pt(e)?`${e.binBase}/expression_atlas.bin`:`${e.twinBase}/expression_atlas.json`}async function vt(e,t){const r=await fetch(e);if(!r.ok)throw new Error(`Failed to load encrypted asset: ${e}`);const n=await r.arrayBuffer();return va(n,t)}async function Yi(e,t){if(!t)throw new Error("Missing asset key for encrypted JSON");const r=await vt(e,t),n=new TextDecoder().decode(r);return JSON.parse(n)}async function Sa(e){const t=new Blob([e],{type:"image/webp"});return createImageBitmap(t)}async function Ta(e){const t=new Blob([e],{type:"image/webp"}),r=URL.createObjectURL(t);return new Promise((n,i)=>{const s=new Image;s.decoding="async",s.onload=()=>{URL.revokeObjectURL(r),n(s)},s.onerror=()=>{URL.revokeObjectURL(r),i(new Error("Failed to decode decrypted image"))},s.src=r})}async function ka(e){const t=new Blob([e],{type:"image/png"});return createImageBitmap(t)}async function Qi(e){const t=new Blob([e],{type:"image/png"}),r=URL.createObjectURL(t);return new Promise((n,i)=>{const s=new Image;s.decoding="async",s.onload=()=>{URL.revokeObjectURL(r),n(s)},s.onerror=()=>{URL.revokeObjectURL(r),i(new Error("Failed to decode decrypted PNG"))},s.src=r})}function Xi(e){const t=new Blob([e],{type:"video/mp4"});return URL.createObjectURL(t)}async function Ea(e){const t=ba();if(!Gt())return t;if(!e)throw new Error("Missing asset key for encrypted idle video");const r=await vt(t,e);return Xi(r)}const cr=["open_palm","emphasis","thumbs_up","friendly_wave","point_camera"],xa="ges",Ia="m.json",Mr={idle:"G_001",open_palm:"G_002",emphasis:"G_003",thumbs_up:"G_004",friendly_wave:"G_005",point_camera:"G_006"},Ji=new Set(cr),Zi={};for(const e of cr){const t=Mr[e];t&&(Zi[t]=e)}function Aa(e){return!!e&&Ji.has(e)}function Vt(e){return e?Ji.has(e)?e:Zi[e]??null:null}function es(e,t=Dr){return`${t.replace(/\/$/,"")}/${e}/${xa}`}function ts(e){return`${e.replace(/\/$/,"")}/${Ia}`}function rs(e,t){const r=Mr[t]??t;return`${e.replace(/\/$/,"")}/${r}.bin`}async function Ra(e){const t=await fetch(ts(e));if(!t.ok)throw new Error(`Failed to load full-body crop meta (${t.status})`);return await t.json()}async function ni(e,t,r){const n=await vt(rs(e,t),r);return Xi(n)}function Ma(e){const t=Math.min(1,Math.max(0,e));return t*t*t*(t*(t*6-15)+10)}const Pa=d.forwardRef(function({gesturesBase:t,keyHex:r,status:n,activePose:i=null,poseSynced:s=!1,style:o},a){const f=d.useRef(null),m=d.useRef(null),u=d.useRef(null),l=d.useRef(null),h=d.useRef(null),v=d.useRef(null),E=d.useRef(null),g=d.useRef({}),P=d.useRef(null),j=d.useRef(null),F=d.useRef([]),S=d.useRef(null),x=d.useRef(!1),L=d.useRef(!1),H=d.useRef(!1),G=d.useRef(!1),ne=d.useRef([]),B=d.useRef(n),N=d.useRef(0),X=d.useRef(0);B.current=n;const se=w=>{const c=g.current[w];c&&(f.current?.pause(),H.current=!1,x.current=!0,j.current=w,L.current=F.current.length>0,Q(c),te(!0),T(!1),ee(p=>p+1))},de=()=>{if(x.current)return;H.current=!1;const w=f.current;w&&(w.currentTime=0,w.play().catch(()=>{}),T(!0))};d.useImperativeHandle(a,()=>({waitForIdleCycleEnd:()=>{const w=f.current;if(!w||!Number.isFinite(w.duration)||w.duration<=0)return{promise:Promise.resolve(),cancel:()=>{}};if(w.ended||H.current)return H.current=!0,w.pause(),{promise:Promise.resolve(),cancel:()=>{}};let c;return{promise:new Promise(b=>{c={resolve:b,cancelled:!1},ne.current.push(c)}),cancel:()=>{c.cancelled=!0,ne.current=ne.current.filter(b=>b!==c)}}},resumeIdleLoop:()=>{ne.current=[],H.current&&de()}}));const[ae,Ae]=d.useState(!1),[be,te]=d.useState(!1),[He,T]=d.useState(!0),[Z,ee]=d.useState(0),[z,fe]=d.useState(null),[U,Q]=d.useState(null),[ce,Se]=d.useState({topFrac:.41,heightFrac:.59}),me=d.useCallback(()=>{const w=f.current,c=m.current;if(!w||!c)return;const p=w.videoWidth,b=w.videoHeight;if(p<1||b<1)return;(c.width!==p||c.height!==b)&&(c.width=p,c.height=b);const R=c.getContext("2d");R&&R.drawImage(w,0,0,p,b)},[]),Te=d.useCallback(()=>{const w=u.current,c=l.current,p=P.current;if(!w||!c||!p)return;const b=w.videoWidth,R=w.videoHeight;if(b<1||R<1)return;(c.width!==b||c.height!==R)&&(c.width=b,c.height=R);const C=c.getContext("2d",{willReadFrequently:!0});if(!C)return;C.drawImage(w,0,0,b,R);const V=p.y_end,K=p.silHeight,J=p.seamLockPx??56,k=Math.max(1,K-V),q=v.current;if(!q||!q.complete||q.naturalWidth<1||q.naturalHeight<=V)return;const le=Math.max(8,Math.round(J*(R/Math.max(1,k)))),ge=Math.min(J,q.naturalHeight-V);if(ge<1||le<1)return;let pe=h.current;pe||(pe=document.createElement("canvas"),h.current=pe),(pe.width!==b||pe.height!==le)&&(pe.width=b,pe.height=le);const Pe=pe.getContext("2d",{willReadFrequently:!0});if(!Pe)return;Pe.clearRect(0,0,b,le),Pe.drawImage(q,0,V,q.naturalWidth,ge,0,0,b,le);const qe=C.getImageData(0,0,b,le),y=Pe.getImageData(0,0,b,le),A=qe.data,W=y.data,re=Math.max(1,le-1);for(let we=0;we<le;we++){const Re=Ma(we/re),xe=1-Re,Fe=Re,De=we*b*4;for(let ft=0;ft<b;ft++){const $e=De+ft*4;A[$e]=W[$e]*xe+A[$e]*Fe,A[$e+1]=W[$e+1]*xe+A[$e+1]*Fe,A[$e+2]=W[$e+2]*xe+A[$e+2]*Fe}}C.putImageData(qe,0,0)},[]);if(d.useEffect(()=>{let w=!1;const c=[];return(async()=>{try{const p=await Ra(t);if(w)return;P.current=p;const b=Math.max(1,p.silHeight),R=Math.max(0,Math.min(p.y_end,b-1));if(Se({topFrac:R/b,heightFrac:1-R/b}),Gt()){const J=await vt(ir(),r),k=await Qi(J);if(w)return;v.current=k}const C=await ni(t,"idle",r);if(c.push(C),w){URL.revokeObjectURL(C);return}E.current=C,fe(C);const V={};for(const J of cr){const k=await ni(t,J,r);if(c.push(k),w){URL.revokeObjectURL(k);return}V[J]=k}g.current=V;const K=V.open_palm??Object.values(V)[0];K&&Q(K),Ae(!0)}catch{w||Ae(!1)}})(),()=>{w=!0;for(const p of c)URL.revokeObjectURL(p);E.current=null,g.current={}}},[t,r]),d.useEffect(()=>{const w=f.current,c=m.current;if(!ae||!w||!c||!z)return;const p=()=>{x.current||(w.currentTime=0,w.play().catch(()=>{}))},b=()=>{w.play().catch(()=>{})},R=()=>{const V=F.current[0];if(L.current&&B.current==="speaking"&&V&&!x.current){if(!g.current[V]){p();return}F.current.shift(),se(V);return}const K=ne.current.filter(J=>!J.cancelled);if(K.length>0&&!x.current){ne.current=[],H.current=!0,w.pause();for(const J of K)J.resolve();return}if(B.current==="speaking"){H.current=!0,w.pause();return}p()};w.addEventListener("loadedmetadata",b),w.addEventListener("ended",R),w.readyState>=1&&b();const C=()=>{me(),N.current=requestAnimationFrame(C)};return N.current=requestAnimationFrame(C),()=>{w.removeEventListener("loadedmetadata",b),w.removeEventListener("ended",R),cancelAnimationFrame(N.current)}},[ae,z,me]),d.useEffect(()=>{if(!ae)return;if(!(n==="speaking")){const p=G.current;if(G.current=!1,F.current=[],S.current=null,L.current=!1,!x.current)if(te(!1),p)de();else{T(!0);const b=f.current;b?.paused&&!H.current&&b.play().catch(()=>{})}return}if(G.current=!0,!s)return;const c=Vt(i);if(c&&c!==S.current&&c!==j.current&&!F.current.includes(c)&&(F.current.push(c),S.current=c),F.current.length>0&&!x.current){const p=F.current.shift();p&&se(p)}},[n,ae,i,s]),d.useEffect(()=>{if(!be||!U||Z===0)return;const w=u.current;if(!w)return;w.src=U,w.currentTime=0,w.play().catch(()=>{if(x.current=!1,j.current=null,B.current==="speaking")return;te(!1),T(!0);const b=f.current;b&&(b.currentTime=0,b.play().catch(()=>{}))});const c=()=>{Te(),X.current=requestAnimationFrame(c)};X.current=requestAnimationFrame(c);const p=()=>{if(x.current=!1,j.current=null,B.current==="speaking"){const R=F.current.shift();if(R){se(R);return}w.pause();return}te(!1),T(!0),F.current=[],S.current=null,L.current=!1;const b=f.current;b&&(b.currentTime=0,b.play().catch(()=>{}))};return w.addEventListener("ended",p),()=>{cancelAnimationFrame(X.current),w.removeEventListener("ended",p)}},[be,U,Z,Te]),!z)return null;const ie=n==="speaking";return M.jsxs("div",{"aria-hidden":!0,style:{position:"absolute",inset:0,pointerEvents:"none",...o},children:[M.jsx("video",{ref:f,src:z,muted:!0,playsInline:!0,preload:"auto",style:{position:"absolute",width:1,height:1,opacity:0,overflow:"hidden"}}),M.jsx("canvas",{ref:m,style:{position:"absolute",inset:0,width:"100%",height:"100%",objectFit:"cover",zIndex:1,opacity:He?1:0,clipPath:ie?`inset(${ce.topFrac*100}% 0 0 0)`:void 0,transition:"opacity 650ms ease"}}),U?M.jsxs(M.Fragment,{children:[M.jsx("video",{ref:u,muted:!0,playsInline:!0,preload:"auto",style:{position:"absolute",width:1,height:1,opacity:0,overflow:"hidden"}}),M.jsx("canvas",{ref:l,style:{position:"absolute",left:0,width:"100%",top:`${ce.topFrac*100}%`,height:`${ce.heightFrac*100}%`,objectFit:"fill",zIndex:2,opacity:be?1:0,transition:"opacity 280ms ease-in-out"}})]}):null]})}),Rt=[{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}],ns=Rt.map(e=>e.code),Ca=new Set(ns),Ba=new Set(Rt.filter(e=>e.visemetts).map(e=>e.code)),Fa=new Set(Rt.filter(e=>e.cartesia).map(e=>e.code)),Da="en";function is(e){return Ca.has(e)}function Nr(e){const t=e?.trim();if(t)return t}function La(e){return e===dt?Rt.filter(t=>t.visemetts).map(t=>t.code):e===ut?Rt.filter(t=>t.cartesia).map(t=>t.code):Rt.filter(t=>t.visemetts&&t.cartesia).map(t=>t.code)}function Oa(e,t){const r=t.trim();return r?e===dt?Ba.has(r):e===ut?Fa.has(r):is(r):!1}function ss(e){const t=e.split(/\r?\n/);let r="",n="";for(const s of t)s.startsWith("event:")?r=s.slice(6).trim():s.startsWith("data:")&&(n=s.slice(5).trim());if(!r)return null;let i={};if(n)try{i=JSON.parse(n)}catch{i={raw:n}}return{event:r,data:i}}const as=["aa","CH","DD","E","FF","I","O","PP","RR","SS","TH","U","kk","nn","sil"],Na=new Map(as.map(e=>[e.toLowerCase(),e]));function Ur(e){const t=(e??"").trim();return t?Na.get(t.toLowerCase())??"sil":"sil"}const Ua={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 Va(e){if(!e)return["sil"];const t=e.toLowerCase();return Ua[t]??["sil"]}function os(e,t){const r=e.word.length;if(r<=0)return 0;const n=e.wduration;if(n<=0)return 0;const i=Math.max(0,Math.min(1,(t-e.wtime)/n));return Math.min(r-1,Math.floor(i*r))}function jt(e,t){const r=Math.max(0,Math.min(e.length-1,t));return e[r]??""}function Vr(e,t){const r=e.toLowerCase().replace(/[^a-z']/g,"");return!r||jt(r,t)!=="w"||t>0&&jt(r,t-1)==="q"?!1:t===0&&/^w[aeiouy]/.test(r)}function Wa(e,t){const r=e.toLowerCase(),n=jt(r,t),i=r.slice(Math.max(0,t-1),t+2);return n==="i"||n==="y"?"I":i.includes("ee")||n==="e"||r.includes("ea")?"E":"aa"}function ja(e,t){const r=e.toLowerCase(),n=r.slice(Math.max(0,t-1),Math.min(r.length,t+3));if(/oo|ou|uw/.test(n))return"U";if(Vr(r,t))return"FF";const i=jt(r,t);return i==="u"||i==="w"?"U":"O"}function Ha(e,t){const r=e.toLowerCase();if(Vr(r,t))return"FF";const n=r.slice(Math.max(0,t-2),t+1);if(/qu/.test(n))return"U";const i=r.slice(Math.max(0,t-1),Math.min(r.length,t+3));return/wo|wh/.test(i)||jt(r,t)==="o"?"O":"U"}const kr={d:"DD",t:"DD",n:"DD",s:"SS",z:"SS",k:"kk",g:"kk",c:"CH",x:"CH",j:"CH"};function $a(e,t){const r=e.toLowerCase(),n=jt(r,t);if(kr[n])return kr[n];for(let i=0;i<r.length;i++){const s=r[i];if(kr[s])return kr[s]}return"DD"}function cs(e,t,r){const n=Va(e);if(n.length===1)return n[0];const i=t.trim();if(!i)return n[0];const s=(e??"").toLowerCase(),o=Math.max(0,r);switch(s){case"aei":return Wa(i,o);case"o":return ja(i,o);case"qw":return Ha(i,o);case"cdgknstxyz":return $a(i,o);default:return n[0]}}const In=16,hn=47,ls=new Set(["aa","E","I"]),us=new Set(["DD","SS","kk","CH"]),za=[ls,us];function Ga(e){for(const t of za)if(t.has(e))return t;return null}function Ka(e){return Ga(e)!=null}function ds(e,t=In){return t<=0?e:Math.round(e/t)*t}function An(e,t=In){return e.map(r=>({...r,vtime:ds(r.vtime,t)}))}function fs(e){const t=new Map;for(const r of e)t.has(r.vtime)||t.set(r.vtime,r);return[...t.values()].sort((r,n)=>r.vtime-n.vtime)}function Rn(e){if(e.length<=2)return[...e];const t=[e[0]];for(let r=1;r<e.length-1;r++){const n=e[r],i=e[r+1],s=t[t.length-1];if(!Ka(n.viseme)){t.push(n);continue}const o=n.vtime-s.vtime,a=i.vtime-n.vtime;o<hn||a<hn||t.push(n)}return t.push(e[e.length-1]),t}function Wr(e){return Rn(fs(An(e)))}function ms(e,t){let r="sil";for(const n of e){if(n.vtime>t)break;n.viseme!=="sil"&&(r=n.viseme)}return r}function jr(e){const t=fs(An(e)),r=Rn(t),n=new Set(r.map(s=>s.vtime)),i=[];for(const s of t)n.has(s.vtime)||i.push({viseme:s.viseme,vtime:s.vtime});return i}function qa(e){return jr(e).map(t=>t.viseme)}const Ya=32,ii=48;function hs(e){let t=0;for(const r of e)t=Math.max(t,r.vtime+r.vduration);return t}function ps(e){let t=null,r=-1;for(const n of e){if(n.viseme==="sil")continue;const i=n.vtime+n.vduration;i>r&&(t=n,r=i)}return t}function Qa(e){return Wr(e).find(r=>r.viseme!=="sil")??null}function xt(e){const t=hs(e);return ps(e)?t+bn:t}function Xa(e){const t=[],r=Qa(e);r&&r.vtime>0&&t.push({from:"sil",to:r.viseme,fromVtime:0,toVtime:r.vtime});const n=ps(e),i=hs(e);return n&&t.push({from:n.viseme,to:"sil",fromVtime:i,toVtime:i+bn}),t}function gs(e){const t=Wr(e),r=[];for(let n=0;n<t.length-1;n++){const i=t[n].viseme,s=t[n+1].viseme,o=t[n].vtime,a=t[n+1].vtime;i===s||a<=o||r.push({from:i,to:s,fromVtime:o,toVtime:a})}return r}function ws(e){return e.length===0?[]:[...Xa(e),...gs(e)]}function Ja(e,t,r=!1){let n=null;for(const i of e){const{transStart:s,transEnd:o}=ys(i.fromVtime,i.toVtime,i.from,i.to,r);t>=s&&t<o&&(n=i)}return n}function ys(e,t,r,n,i=!1){const s=Math.max(0,t-e);if(i&&(r==="PP"||n==="PP")&&s>ii){const u=ii,l=t,h=l-u;return{gapMs:s,effectiveGapMs:u,holdEnd:h,transStart:h,transEnd:l}}const a=s>0?Math.max(s,Ya):0,f=e,m=e+a;return{gapMs:s,effectiveGapMs:a,holdEnd:e,transStart:f,transEnd:m}}function vs(e,t,r,n,i,s){n.forEach(o=>{const f=String(o.word??"").trim();if(!f)return;const m=Math.round((o.start??0)*1e3),u=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:f,wtime:i+m,wduration:u,queueIndex:t.length,gesture:o.gesture??null,emphasis:o.emphasis===!0})}),r.forEach(o=>{const a=String(o.symbol??o.viseme??"").trim();if(!a)return;const f=Math.round((o.start??0)*1e3),m=Math.max(1,Math.round((o.duration??0)*1e3)),u=i+f,l=Ss(t,u),h=l?os(l,u):0;let v;Ni(s)==="oculus_direct"?(v=Ur(a),v==="U"&&l&&Vr(l.word,h)&&(v="FF")):v=cs(a,l?.word??"",h),e.push({viseme:v,weight:1,vtime:u,vduration:m})})}function _s(e,t){let r=t;for(const n of e){const i=Math.round((n.start??0)*1e3),s=Math.max(1,Math.round((n.duration??0)*1e3));r=Math.max(r,t+i+s)}return r}const Mn=16e3;function bs(e){const t=Number(e);return Number.isFinite(t)&&t>0?t:Mn}function Za(e){let t=e.trim();const r=t.indexOf(",");t.startsWith("data:")&&r>=0&&(t=t.slice(r+1)),t=t.replace(/\s+/g,"").replace(/-/g,"+").replace(/_/g,"/");const n=t.length%4;return n!==0&&(t+="=".repeat(4-n)),t}function eo(e){return e.length>=4&&e[0]===82&&e[1]===73&&e[2]===70&&e[3]===70}function si(e,t,r=Mn){const n=t.byteOffset%2===0?t:t.slice(),i=new Int16Array(n.buffer,n.byteOffset,n.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,r);return o.copyToChannel(s,0),o}function to(e){const t=Za(e),r=window.atob(t),n=new Uint8Array(r.length);for(let i=0;i<r.length;i++)n[i]=r.charCodeAt(i);return n}async function ai(e,t,r=Mn){const n=to(t),i=bs(r);if(eo(n)){const s=n.buffer.slice(n.byteOffset,n.byteOffset+n.byteLength);return e.decodeAudioData(s)}if(n.length>=2&&n.length%2===0)return si(e,n,i);try{const s=n.buffer.slice(n.byteOffset,n.byteOffset+n.byteLength);return await e.decodeAudioData(s)}catch{return si(e,n,i)}}function Ss(e,t){for(const r of e)if(t>=r.wtime&&t<r.wtime+r.wduration)return r;return null}function Ts(e,t){const r=[],n=[];let i=null,s=!1,o=!1,a=!1,f=!1,m=0,u=0,l=0,h=null,v=1,E=t,g=!1,P=null,j=null,F=!1,S=0,x=!1,L=!1,H=0,G=null,ne=null,B=null,N=null,X=null;const se=()=>({visemes:[],words:[],segmentOffsetMs:0}),de=()=>{L=!1,H=0},ae=()=>{const c=ne;G=null,ne=null,c?.(),!g&&!s&&n.length===0&&r.length>0&&B&&N&&me(B,N)},Ae=()=>{G||(G=new Promise(c=>{ne=c}))},be=()=>{h!=null&&(clearTimeout(h),h=null)},te=()=>{for(const c of n){try{c.onended=null,c.stop(0)}catch{}try{c.disconnect()}catch{}}n.length=0},He=()=>{for(const c of n)c.playbackRate.value=v},T=()=>{if(!(g||!f||s||L||n.length>0||r.length>0)){if(a&&i&&u>0){const c=(i.currentTime-u)*1e3;if(c<S){be();const p=v>0?(S-c)/v:S-c;h=setTimeout(()=>{g||(o=!1,h=null,e.onSpeakingDone(),e.onNotify())},Math.max(0,p));return}}o=!1,be(),e.onSpeakingDone(),e.onNotify()}},Z=c=>{const p=xt(c);if(p<=0){e.onSpeakingDone(),e.onNotify();return}o=!0,m=performance.now(),e.onSpeakingStart(),e.onNotify(),be();const b=v>0?p/v:p;h=setTimeout(()=>{g||(o=!1,h=null,e.onSpeakingDone(),e.onNotify())},b)},ee=(c,p,b,R)=>{p.length!==0&&(l=b,p.forEach(C=>{const K=String(C.word??"").trim();if(!K)return;const J=Math.round((C.start??0)*1e3),k=C.duration!=null?Math.round(C.duration*1e3):C.end!=null?Math.max(1,Math.round((C.end-(C.start??0))*1e3)):0;c.push({word:K,wtime:l+J,wduration:k,queueIndex:c.length,gesture:C.gesture??null,emphasis:C.emphasis===!0})}))},z=(c,p,b,R,C,V)=>{b.length!==0&&(l=R,b.forEach(K=>{const J=String(K.symbol??K.viseme??"").trim();if(!J)return;const k=Math.round((K.start??0)*1e3),q=Math.max(1,Math.round((K.duration??0)*1e3)),le=l+k,ge=Ss(p,le),pe=ge?os(ge,le):0;let Pe;Ni(V)==="oculus_direct"?(Pe=Ur(J),Pe==="U"&&ge&&Vr(ge.word,pe)&&(Pe="FF")):Pe=cs(J,ge?.word??"",pe),c.push({viseme:Pe,weight:1,vtime:le,vduration:q})}),e.onNotify())},fe=(c,p,b,R,C,V,K)=>{ee(p,R,C),z(c,p,b,C,V,K)},U=(c,p,b)=>{X===c&&c.visemes===p||(p.length=0,b.length=0,c.visemes=p,c.words=b,c.segmentOffsetMs=0,X=c,l=0,S=0)},Q=c=>(j||(j=c.createGain(),j.gain.value=F?0:1,j.connect(c.destination)),j),ce=async()=>{const c=window.AudioContext||window.webkitAudioContext;return i||(i=new c,j=null,P=null),i.state==="suspended"&&await i.resume(),Q(i),P||(P=i.createMediaStreamDestination()),i},Se=(c,p)=>{if(!i)return 0;const b=i,R=b.currentTime,C=R+.02;if(p.isFirstAudio){u<=0&&(u=C);const K=(C-R)*1e3;m=performance.now()+K}p.onBeforeStart?.(C);const V=b.createBufferSource();return V.buffer=c,V.playbackRate.value=v,V.connect(Q(b)),P&&V.connect(P),n.push(V),g?(n.pop(),C):(p.isFirstAudio&&(o=!0,e.onSpeakingStart()),V.onended=()=>{const K=n.indexOf(V);K>=0&&n.splice(K,1),e.onNotify(),!g&&(B&&N?me(B,N):T())},V.start(C),C)},me=async(c,p)=>{if(g||s||n.length>0)return;if(r.length===0){T();return}s=!0;let b=!1;try{if(G&&await G,g)return;const R=await ce();if(g)return;const C=r[0];if(!C)return;const V=!o;if(x&&(e.shouldHoldForWarmup?.()??!1)&&(L||V&&C.newStream)||L){U(C.utterance,c,p);for(const k of r){if(g)return;k.audioBuffer||(k.audioBuffer=await ai(R,k.audio,k.sampleRate)),a=!0,L||(L=!0,H=0,k.newStream&&k.onNewStream?.()),k.visemesQueued||(fe(c,p,k.visemes,k.words,H,!0,E),k.visemesQueued=!0,H+=Math.round(k.audioBuffer.duration*1e3),S=Math.max(S,xt(c)))}e.onNotify();return}const J=r.shift();if(!J||(J.audioBuffer||(J.audioBuffer=await ai(R,J.audio,J.sampleRate)),g))return;a=!0,be(),U(J.utterance,c,p),J.visemesQueued=!1,J.newStream&&J.onNewStream?.(),Se(J.audioBuffer,{isFirstAudio:!o,isFirstOfStream:!1,onBeforeStart:k=>{u=k,l=0,m=performance.now()+(k-R.currentTime)*1e3,c.length=0,p.length=0,fe(c,p,J.visemes,J.words,0,!0,E),J.visemesQueued=!0,J.utterance.segmentOffsetMs=0}}),b=n.length>0,S=xt(c),e.onNotify()}catch(R){console.error("[avatarChunkPlayback] audio chunk failed:",R)}finally{if(s=!1,g)return;if(L){r.some(C=>!C.audioBuffer||!C.visemesQueued)&&me(c,p);return}!b&&n.length===0&&r.length>0?me(c,p):n.length===0&&r.length===0&&T()}};return{setStreamTtsEngineId:c=>{E=c},setPlaybackSpeed:c=>{v=Math.max(.1,Math.min(1,c)),He()},getPlaybackSpeed:()=>v,setMuted:c=>{F=c,j&&(j.gain.value=c?0:1)},isMuted:()=>F,setLipsyncWarmupHoldEnabled:c=>{x=c,c||de()},isWarmingUp:()=>L,releaseWarmupHold:()=>{if(L){L=!1,H=0;for(const c of r)c.newStream=!1;B&&N&&me(B,N),e.onNotify()}},resetForNewStream:c=>{g=!1,f=!1,E=c,S=0},resumeBotStream:()=>{g=!1,f=!1},clearAborted:()=>{g=!1},primeAudioContext:async()=>{const c=window.AudioContext||window.webkitAudioContext;i||(i=new c,j=null,P=null),i.state==="suspended"&&await i.resume(),Q(i),P||(P=i.createMediaStreamDestination())},armStartHold:Ae,releaseStartHold:ae,stop:()=>{g=!0,ae(),be(),te(),r.length=0,s=!1,o=!1,a=!1,f=!1,l=0,u=0,m=0,S=0,B=null,N=null,X=null,de()},markStreamComplete:c=>{if(S=Math.max(S,xt(c)),f=!0,!a&&c.length>0){Z(c);return}T()},playAudioChunk:async(c,p,b,R,C,V,K)=>{if(g)return;B=c,N=p;const J=bs(K?.sampleRate),k=K?.newStream===!0,q=se();if(!b?.trim()){if(R.length===0&&C.length===0)return;U(q,c,p),k&&K?.onNewStream?.(),fe(c,p,R,C,0,!0,E),S=xt(c),!o&&S>0&&Z(c),e.onNotify();return}r.push({audio:b,audioBuffer:null,utterance:q,visemes:R,words:C,isNewSegment:V,sampleRate:J,newStream:k,onNewStream:K?.onNewStream,visemesQueued:!1}),await me(c,p)},queueTimingsOnly:(c,p,b,R,C,V)=>{if(g)return;const K=se();U(K,c,p),fe(c,p,b,R,0,!0,E),K.segmentOffsetMs=0,S=xt(c)},getPlaybackElapsedMs:()=>a&&i&&u>0?Math.max(0,(i.currentTime-u)*1e3*v):o?Math.max(0,(performance.now()-m)*v):0,isSpeaking:()=>o?!0:!a||!i||u<=0?!1:(i.currentTime-u)*1e3<S,getVoiceStream:()=>P?P.stream:null,getPlaybackStartPerf:()=>m,bargeIn:()=>{g=!0,ae(),f=!1,be(),te(),r.length=0,s=!1,o=!1,a=!1,l=0,u=0,m=0,S=0,B=null,N=null,X=null,de()},interrupt:()=>{g=!0,ae(),f=!1,be(),te(),r.length=0,s=!1,o=!1,a=!1,l=0,u=0,m=0,S=0,B=null,N=null,X=null,de()}}}function lr(e,t){let r=null;for(const n of e)t<n.vtime||t>=n.vtime+n.vduration||(!r||n.vtime>=r.vtime)&&(r=n);return r?r.viseme:"sil"}function ks(e,t,r=120){const n=lr(e,t);if(n!=="sil")return n;let i=null;for(const s of e){if(s.vtime>t)break;const o=s.vtime+s.vduration;o<=t&&t-o<=r&&(i=s)}return i?.viseme??"sil"}function ro(e,t,r=400){const n=t-r;let i=0;for(const s of e)if(s.vtime+s.vduration<n)i+=1;else break;i>0&&e.splice(0,i)}function Es(e,t){for(const r of e)if(t>=r.wtime&&t<r.wtime+r.wduration)return r;return null}function oi(e,t,r){const n=Es(e,t);if(n?.gesture&&r(n.gesture))return n.gesture;for(const i of e)if(i.wtime>=t&&i.gesture&&r(i.gesture))return i.gesture;for(const i of e)if(i.gesture&&r(i.gesture))return i.gesture;return null}function ci(e,t){const r=e.trim();if(!r)return null;try{const n=r.replace(/\s+/g,""),i=atob(n).length,s=Number.isFinite(t)&&(t??0)>0?Number(t):16e3;return i/2/s*1e3}catch{return null}}const Hr=.5,$r=1.5,Pn="Olivia",Cn="f786b574-daa5-4673-aa0c-cbe3e8534c02",ur=.85;function pn(e,t=lt,r={}){const n=`${t.replace(/\/$/,"")}/avatar_ttsWithPoses`,i=[],s=[],o=[],a=[];let f=0;const m=[],u=[];let l="",h="neutral",v="",E=At,g=!!r.fullBody;const P=new Set;let j=0,F=null,S=0,x=null;const L=()=>P.forEach(T=>T());let H=()=>!1;const G=Ts({onSpeakingStart:()=>e("speaking"),onSpeakingDone:()=>e("done"),onNotify:L,shouldHoldForWarmup:()=>H()},At),ne=()=>G.getPlaybackElapsedMs(),B=(T,Z=l)=>{if(!r.onLipsyncDebug)return;const ee=ne(),z=i,fe=jr(o).map(U=>({viseme:U.viseme,vtimeMs:U.vtime}));r.onLipsyncDebug({event:T,spokenText:Z,mood:h,playbackAnchorPerf:G.getPlaybackStartPerf(),playbackElapsedMs:ee,queueLength:z.length,activeViseme:lr(z,ee),segments:u.map(U=>({...U,visemes:[...U.visemes]})),fullQueueLength:o.length,compactionSkipped:fe})},N=(T,Z)=>{r.onLipsyncDebug&&(F={event:T,spokenText:Z},j===0&&(j=requestAnimationFrame(()=>{j=0;const ee=F;F=null,ee&&B(ee.event,ee.spokenText)})))},X=(T,Z,ee,z,fe)=>{if(!r.onLipsyncDebug)return;const U=i.slice(Z),Q=ee.filter(ce=>String(ce.symbol??ce.viseme??"").trim());u.push({spokenText:T,audioOffsetMs:U[0]?.vtime??0,isNewSegment:z,chunkDurationMs:fe,receivedAtMs:performance.now(),visemes:U.map((ce,Se)=>{const me=Q[Se];return{rawSymbol:String(me?.symbol??me?.viseme??ce.viseme).trim(),viseme:ce.viseme,startSec:Number(me?.start??0),durationSec:Number(me?.duration??0),vtimeMs:ce.vtime,vdurationMs:ce.vduration}})})},se=()=>{o.length=0,a.length=0,f=0},de=(T,Z,ee,z,fe)=>{if(T.length===0&&Z.length===0)return;vs(o,a,T,Z,f,fe);const U=_s(T,f),Q=ee?ci(ee,z):null;f=Math.max(U,Q!=null?f+Q:f)},ae=()=>{S+=1,x?.abort(),x=null,G.stop(),i.length=0,s.length=0,se(),m.length=0,h="neutral",u.length=0,l="",e("idle"),N("reset"),L()},Ae=T=>{const Z=ct(T?.ttsEngineId,T?.voiceId),ee=Z.ttsEngineId??E??At,z=Z.voiceId??(ee===dt?Or:Pn),fe=T?.speakingRate??ur,U=Math.max(Hr,Math.min($r,fe));return{engineId:ee,voiceId:z,speakingRate:U,language:Nr(T?.language)}},be=async T=>{ae();const Z=S;x=new AbortController,e("loading"),l=T.debugSpokenFallback,u.length=0,se();const ee=v.trim();if(!ee)throw new Error("Developer token required for avatar_ttsWithPoses");G.resetForNewStream(T.engineId),G.setStreamTtsEngineId(T.engineId),T.delayPlayback&&G.armStartHold();let z="",fe="";try{const U=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${ee}`,Accept:"text/event-stream"},body:JSON.stringify(T.requestBody),signal:x.signal});if(!U.ok)throw new Error(`avatar_ttsWithPoses failed (${U.status})`);const Q=U.body;if(!Q)throw new Error("No response body");const ce=Q.getReader(),Se=new TextDecoder;let me="",Te=!0;const ie=()=>z||T.debugSpokenFallback,w=async c=>{if(Z!==S)return;const p=ss(c);if(p){if(p.event==="spokenText"){const b=typeof p.data.text=="string"?p.data.text.trim():"";b&&(z=b,l=b,T.onSpokenText?.(b),L());return}if(p.event==="displayText"){const b=typeof p.data.text=="string"?p.data.text.trim():"";b&&(fe=b,T.onDisplayText?.(b),L());return}if(p.event!=="done"){if(p.event==="audio"){const b=p.data.chunk,R=p.data.visemes??[],C=p.data.words??[],V=p.data.is_new_segment??!1,K=p.data.sample_rate,J=Number(p.data.audio_offset_ms??0),k=i.length,q=ie();if(de(R,C,b,K,T.engineId),b){const le=Te;Te=!1,await G.playAudioChunk(i,s,b,R,C,V,{sampleRate:K,newStream:le,audioOffsetMs:J}),X(q,k,R,V,ci(b,K)),N("audio_chunk",q)}else(R.length>0||C.length>0)&&(G.queueTimingsOnly(i,s,R,C,V,{audioOffsetMs:J,newStream:Te}),X(q,k,R,V,null),N("audio_chunk",q))}else if(p.event==="metadata"){const b=p.data.mood;typeof b=="string"&&b.trim()&&(h=b.trim());const R=p.data.spoken_text??p.data.text;typeof R=="string"&&R.trim()&&!z&&(z=R.trim(),l=z);const C=p.data.sentence_emotions;if(Array.isArray(C)){m.length=0;for(const V of C){if(!V||typeof V!="object")continue;const K=V;m.push({sentence_index:Number(K.sentence_index??0),text:String(K.text??""),sentiment:typeof K.sentiment=="string"?K.sentiment:void 0,emotion:String(K.emotion??h),start_word:Number(K.start_word??0),end_word:Number(K.end_word??0)})}}L(),N("metadata",ie())}else if(p.event==="error")throw new Error(String(p.data.message??"avatar_ttsWithPoses stream error"))}}};for(;;){if(Z!==S)return{displayText:fe,spokenText:z,aborted:!0};const{done:c,value:p}=await ce.read();p&&(me+=Se.decode(p,{stream:!0}));const b=me.split(`
2
2
 
3
- `);K=b.pop()??"";for(const C of b)await y(C);if(u){K.trim()&&await y(K.trim()),G.markStreamComplete(i),U("bot_stopped",oe());break}}}catch(X){if(Z!==S)return{displayText:de,spokenText:j,aborted:!0};if(X instanceof DOMException&&X.name==="AbortError")return{displayText:de,spokenText:j,aborted:!0};throw console.error("[avatarTtsLipsync]",X),ae(),e("error"),X}return{displayText:de,spokenText:j}};return{setDeveloperToken:T=>{v=T},setTtsEngineId:T=>{E=T},getTtsEngineId:()=>E,speak:async(T,Z)=>{const{engineId:H,voiceId:j,speakingRate:de,language:X}=Ae(Z),se={user_query:T,ttsEngineId:H,speakingRate:de,tenant:"aiTwin"};an.has(H)&&(se.voice_id=j),X&&(se.language=X),(Z?.fullBody??g)&&(se.fullBody=!0),await ke({requestBody:se,engineId:H,debugSpokenFallback:T,delayPlayback:Z?.delayPlayback})},speakWithReply:async(T,Z)=>{const H=T.trim();if(!H)throw new Error("Message is required");const{engineId:j,voiceId:de,speakingRate:X,language:se}=Ae(Z),fe={generateReply:!0,message:H,ttsEngineId:j,speakingRate:X,tenant:"aiTwin",history:Z?.history??[]};an.has(j)&&(fe.voice_id=de),se&&(fe.language=se),(Z?.fullBody??g)&&(fe.fullBody=!0);const K=Z?.brainId?.trim();K&&(fe.brainId=K);const te=Z?.brainUrl?.trim();te&&(fe.brainUrl=te);const oe=Z?.userName?.trim();oe&&(fe.userName=oe);const y=Z?.userEmail?.trim();y&&(fe.userEmail=y);const u=Z?.userContext?.trim();u&&(fe.userContext=u);const p=await ke({requestBody:fe,engineId:j,debugSpokenFallback:H,delayPlayback:Z?.delayPlayback,onSpokenText:Z?.onSpokenText,onDisplayText:Z?.onDisplayText});if(p.aborted)return{spokenText:p.spokenText,displayText:p.displayText};if(!p.spokenText&&!p.displayText)throw new Error("avatar_ttsWithPoses generateReply stream missing spokenText or displayText");return{spokenText:p.spokenText||p.displayText,displayText:p.displayText||p.spokenText}},stop:ae,releasePlaybackHold:()=>G.releaseStartHold(),getVisemeQueue:()=>i,getWordQueue:()=>s,getFullVisemeQueue:()=>o,getFullWordQueue:()=>a,getSentenceEmotions:()=>m,getStreamMood:()=>h,getPlaybackElapsedMs:()=>G.getPlaybackElapsedMs(),isSpeaking:()=>G.isSpeaking(),isWarmingUp:()=>G.isWarmingUp(),releaseWarmupHold:()=>G.releaseWarmupHold(),setLipsyncWarmupHold:(T,Z)=>{Z&&(W=Z),G.setLipsyncWarmupHoldEnabled(T)},getVoiceStream:()=>G.getVoiceStream(),setMuted:T=>{G.setMuted(T)},isMuted:()=>G.isMuted(),setPlaybackSpeed:T=>{G.setPlaybackSpeed(T)},getPlaybackSpeed:()=>G.getPlaybackSpeed(),subscribe:T=>(R.add(T),()=>R.delete(T))}}function rr(e){if(e==null)return!1;if(typeof e=="object"){const n=e;if(n.type==="permissions"||n.name==="NotAllowedError"||n.name==="PermissionDeniedError")return!0}const r=(e instanceof Error?`${e.name} ${e.message}`:typeof e=="string"?e:String(e)).toLowerCase();return!!(r.includes("notallowederror")||r.includes("permissiondeniederror")||r.includes("permission denied")||r.includes("permissions denied")||r.includes("microphone access denied")||(r.includes("microphone")||r.includes(" mic"))&&(r.includes("denied")||r.includes("blocked")||r.includes("not allowed")||r.includes("permission")))}async function eo(){if(typeof navigator>"u"||!navigator.permissions?.query)return!1;try{return(await navigator.permissions.query({name:"microphone"})).state==="denied"}catch{return!1}}const Mn=16e3,Pn=16e3;class to extends wn.ProtobufFrameSerializer{async deserialize(t){try{return await super.deserialize(t)}catch(r){if(r instanceof Error&&r.message==="Unknown frame kind")return{type:"raw",message:null};throw r}}}class ro extends wn.DailyMediaManager{constructor(){super(!0,!0,void 0,void 0,512,Mn,Pn)}bufferBotAudio(t,r){}}const no=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function ai(e){return no.test(e.trim())}function io(e){const t=e.replace(/\/$/,"");return t.startsWith("https://")?`wss://${t.slice(8)}`:t.startsWith("http://")?`ws://${t.slice(7)}`:t}function Ts(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 r=e.apiBase??ut,n=new URL(`${io(r)}/ws/voice`);n.searchParams.set("authToken",t),n.searchParams.set("tenant","aiTwin");const i=lt(e.ttsEngineId,e.voiceId),s=i.ttsEngineId;s&&n.searchParams.set("ttsEngineId",s);const o=i.voiceId?.trim();o&&(s&&Oi(s)?ai(o)||n.searchParams.set("voiceId",o):ai(o)&&n.searchParams.set("voiceId",o));const a=Br(e.language);a&&n.searchParams.set("language",a);const f=e.brainId?.trim()||e.personaId?.trim();f&&n.searchParams.set("brainId",f);const m=e.brainUrl?.trim();m&&n.searchParams.set("brainUrl",m);const l=e.speakingRate??or;n.searchParams.set("speaking_rate",String(Math.max(Ur,Math.min(Vr,l)))),e.ttsStream===!1?n.searchParams.set("tts_stream","false"):n.searchParams.set("tts_stream","true"),e.speakOnlyWhenSpokenTo&&n.searchParams.set("speakOnlyWhenSpokenTo","true");const c=e.avatarName?.trim();c&&n.searchParams.set("avatarName",c);const h=e.userName?.trim();h&&n.searchParams.set("userName",h);const v=e.userEmail?.trim();v&&n.searchParams.set("userEmail",v);const E=e.userContext?.trim();return E&&n.searchParams.set("userContext",E),n.toString()}function Zr(e,t){if(!Array.isArray(e))return[];const r=[];for(const n of e)!n||typeof n!="object"||r.push({sentence_index:Number(n.sentence_index??0),text:String(n.text??""),sentiment:typeof n.sentiment=="string"?n.sentiment:void 0,emotion:String(n.emotion??t),start_word:Number(n.start_word??0),end_word:Number(n.end_word??0)});return r}function so(e){if(!e||typeof e!="object")return null;const t=e,n=(t.data&&typeof t.data=="object"&&!Array.isArray(t.data)?t.data:null)||t;return{...n,type:String(n.type??t.type??"server-message")}}function oi(e){return e.is_new_segment===!0||Number(e.audio_offset_ms??-1)===0?!0:Number(e.chunk_index??-1)===0}function ao(e){return e?.transport?._mediaManager?._wavStreamPlayer??null}function ks(e,t={}){const r=[],n=[],i=[],s=[];let o=0;const a=[],f=[];let m="",l="neutral",c=dt,h=!1,v=null,E=null,g={...t},R=0,V=null;const B=new Set,S=[];let x=!1,O=null,W=!0,G="default";const ie=new Set;let M=null,U=0,J=!1,Q=!1,ue=null,ae=!1;const Ae=()=>{ue!=null&&(clearTimeout(ue),ue=null)},ke=()=>{Ae(),ue=setTimeout(()=>{ue=null,W&&(T.markStreamComplete(r),X("bot_stopped"))},450)},re=()=>B.forEach(w=>w());let Ke=()=>!1;const T=_s({onSpeakingStart:()=>e("speaking"),onSpeakingDone:()=>{ae=!1,Q=!1,e("done")},onNotify:re,shouldHoldForWarmup:()=>Ke()},c),Z=()=>{if(O)return O;const w=new MessageChannel;return w.port1.onmessage=()=>{const P=S.shift();P!==void 0&&$(P),S.length>0?w.port2.postMessage(null):x=!1},O=w,w},H=w=>{S.push(w),!x&&(x=!0,Z().port2.postMessage(null))},j=()=>T.getPlaybackElapsedMs(),de=(w,P=m)=>{if(!g.onLipsyncDebug)return;const ne=j(),ge=r,we=Nr(i).map(ve=>({viseme:ve.viseme,vtimeMs:ve.vtime}));g.onLipsyncDebug({event:w,spokenText:P,mood:l,playbackAnchorPerf:T.getPlaybackStartPerf(),playbackElapsedMs:ne,queueLength:ge.length,activeViseme:ar(ge,ne),segments:f.map(ve=>({...ve,visemes:[...ve.visemes]})),fullQueueLength:i.length,compactionSkipped:we})},X=(w,P)=>{g.onLipsyncDebug&&(V={event:w,spokenText:P},R===0&&(R=requestAnimationFrame(()=>{R=0;const ne=V;V=null,ne&&de(ne.event,ne.spokenText)})))},se=()=>{W=!0,ie.clear(),T.clearAborted()},fe=()=>{const w=ao(v);if(w){G=`bot-${Date.now()}`,w.interruptedTrackIds={[G]:!0};try{w.interrupt?.()}catch{}}const P=E;try{P?.interrupt?.()}catch{}},me=w=>{if(ae&&T.isSpeaking())return!0;const P=w.context_id?.trim();return P&&ie.has(P)?!0:W?!1:!(w.type==="avatar_metadata"||oi(w))},K=w=>{W=!1,ae=!1;const P=w.context_id?.trim();P&&ie.add(P),Ae(),J=!1,Q=!1,S.length=0,x=!1,M?.abort(),M=null,U+=1,fe(),T.bargeIn(),te(),e("idle"),X("interrupt"),re()},te=()=>{r.length=0,n.length=0,i.length=0,s.length=0,o=0,f.length=0,m="",l="neutral",a.length=0},oe=()=>{Ae(),Q=!1,J=!1,T.stop(),te(),X("reset"),re()},y=()=>{oe(),e("idle"),re()},u=(w,P)=>{typeof w.mood=="string"&&w.mood.trim()&&(l=w.mood.trim()),Array.isArray(w.sentence_emotions)&&w.sentence_emotions.length>0&&(P&&(a.length=0),a.push(...Zr(w.sentence_emotions,l)))},p=w=>{if(me({...w,type:"avatar_metadata"}))return;se(),J=!0;const P=String(w.spoken_text??w.text??"").trim();P&&(m=P),T.resetForNewStream(c),typeof w.mood=="string"&&w.mood.trim()&&(l=w.mood.trim()),a.length=0,a.push(...Zr(w.sentence_emotions,l)),Array.isArray(w.gestures)&&w.gestures,X("metadata",P),re()},b=(w,P,ne,ge)=>{if(!g.onLipsyncDebug)return;const we=r.slice(ne),ve=ge.filter(Pe=>String(Pe.symbol??Pe.viseme??"").trim());f.push({spokenText:P,audioOffsetMs:we[0]?.vtime??0,isNewSegment:!!w.is_new_segment,chunkDurationMs:w.chunk_duration_ms!=null?Number(w.chunk_duration_ms):null,receivedAtMs:performance.now(),visemes:we.map((Pe,Ue)=>{const Ve=ve[Ue];return{rawSymbol:String(Ve?.symbol??Ve?.viseme??Pe.viseme).trim(),viseme:Pe.viseme,startSec:Number(Ve?.start??0),durationSec:Number(Ve?.duration??0),vtimeMs:Pe.vtime,vdurationMs:Pe.vduration}})})},C=(w,P,ne,ge)=>{if(w.length===0&&P.length===0)return;gs(i,s,w,P,o,c);const we=ws(w,o);let ve=null;const Pe=ne.trim();if(Pe)try{const Ue=atob(Pe.replace(/\s+/g,"")).length,Ve=Number.isFinite(ge)&&(ge??0)>0?Number(ge):16e3;ve=Ue/2/Ve*1e3}catch{ve=null}o=Math.max(we,ve!=null?o+ve:o)},F=w=>{if(me(w))return;const P=oi(w);P&&(Ae(),se());const ne=String(w.spoken_text??w.text??"").trim(),ge=w.visemes??[],we=w.words??[],ve=String(w.chunk??"").trim(),Pe=J||P||!Q;J&&(J=!1),Pe&&(Q=!0),ne&&(m=ne),u(w,P),Pe?(T.resetForNewStream(c),i.length=0,s.length=0,o=0):P&&T.resumeBotStream(),C(ge,we,ve,w.sample_rate);const Ue=r.length;T.playAudioChunk(r,n,ve,ge,we,P,{sampleRate:w.sample_rate,newStream:Pe,audioOffsetMs:Number(w.audio_offset_ms??0),onNewStream:()=>{f.length=0}}).then(()=>{b(w,ne,Ue,ge),X("audio_chunk",ne),ke()})},q=w=>{if(me(w))return;(w.is_new_segment||Number(w.audio_offset_ms??-1)===0)&&se(),console.warn("[realtimeVoice] avatar_lipsync is deprecated — expect avatar_audio_chunk");const P=String(w.spoken_text??w.text??"").trim();P&&(m=P),u(w,!!w.is_new_segment),C(w.visemes??[],w.words??[],"",void 0);const ne=r.length;T.queueTimingsOnly(r,n,w.visemes??[],w.words??[],!!w.is_new_segment,{audioOffsetMs:Number(w.audio_offset_ms??0)}),b(w,P,ne,w.visemes??[]),X("lipsync",P),re()},L=async w=>{const P=String(w.text??"").trim();if(!P)return;const ne=g.authToken?.trim();if(!ne){console.error("[realtimeVoice] avatar_speak requires authToken");return}M?.abort();const ge=new AbortController;M=ge;const we=++U;se(),T.resetForNewStream(c),m=P;const Pe=`${(g.apiBase??ut).replace(/\/$/,"")}/avatar_ttsWithPoses`,Ue=lt(c,g.voiceId);Ue.ttsEngineId&&(c=Ue.ttsEngineId,T.setStreamTtsEngineId(c));const Ve=Ue.voiceId?.trim()||(c===ft?Fr:Rn),vt=g.speakingRate??or,We=Math.max(Ur,Math.min(Vr,vt)),nt={user_query:P,ttsEngineId:c,speakingRate:We,tenant:"aiTwin"};an.has(c)&&(nt.voice_id=Ve);const Gt=Br(g.language);Gt&&(nt.language=Gt),g.fullBody&&(nt.fullBody=!0);const Pt=g.fullBody?g.waitForBodyIdle?.()??null:null;let cr=!1;const Ct=()=>{cr||(cr=!0,T.releaseStartHold())};Pt&&(T.armStartHold(),Pt.promise.then(Ct));try{const mt=await fetch(Pe,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${ne}`},body:JSON.stringify(nt),signal:ge.signal});if(!mt.ok)throw new Error(`avatar_ttsWithPoses failed (${mt.status})`);const lr=mt.body;if(!lr)throw new Error("No response body");const jr=lr.getReader(),ur=new TextDecoder;let _t="",Kt=!0;const Ft=async qt=>{if(we!==U||ge.signal.aborted||!W)return;const Le=rs(qt);if(Le){if(Le.event==="audio"){const je=Le.data.chunk,He=Le.data.visemes??[],bt=Le.data.words??[],Je=Le.data.is_new_segment??!1,it=Le.data.sample_rate,St=Number(Le.data.audio_offset_ms??0);if(je){const Be=Kt;Kt=!1,await T.playAudioChunk(r,n,je,He,bt,Je,{sampleRate:it,newStream:Be,audioOffsetMs:St})}else(He.length>0||bt.length>0)&&T.queueTimingsOnly(r,n,He,bt,Je,{audioOffsetMs:St,newStream:Kt})}else if(Le.event==="metadata"){const je=Le.data.mood;typeof je=="string"&&je.trim()&&(l=je.trim());const He=Le.data.sentence_emotions;Array.isArray(He)&&(a.length=0,a.push(...Zr(He,l))),re()}else if(Le.event==="error")throw new Error(String(Le.data.message??"avatar_ttsWithPoses stream error"))}};for(;!(we!==U||ge.signal.aborted||!W);){const{done:qt,value:Le}=await jr.read();Le&&(_t+=ur.decode(Le,{stream:!0}));const je=_t.split(`
3
+ `);me=b.pop()??"";for(const R of b)await w(R);if(c){me.trim()&&await w(me.trim()),G.markStreamComplete(i),N("bot_stopped",ie());break}}}catch(U){if(Z!==S)return{displayText:fe,spokenText:z,aborted:!0};if(U instanceof DOMException&&U.name==="AbortError")return{displayText:fe,spokenText:z,aborted:!0};throw console.error("[avatarTtsLipsync]",U),ae(),e("error"),U}return{displayText:fe,spokenText:z}};return{setDeveloperToken:T=>{v=T},setTtsEngineId:T=>{E=T},getTtsEngineId:()=>E,speak:async(T,Z)=>{const{engineId:ee,voiceId:z,speakingRate:fe,language:U}=Ae(Z),Q={user_query:T,ttsEngineId:ee,speakingRate:fe,tenant:"aiTwin"};ln.has(ee)&&(Q.voice_id=z),U&&(Q.language=U),(Z?.fullBody??g)&&(Q.fullBody=!0),await be({requestBody:Q,engineId:ee,debugSpokenFallback:T,delayPlayback:Z?.delayPlayback})},speakWithReply:async(T,Z)=>{const ee=T.trim();if(!ee)throw new Error("Message is required");const{engineId:z,voiceId:fe,speakingRate:U,language:Q}=Ae(Z),ce={generateReply:!0,message:ee,ttsEngineId:z,speakingRate:U,tenant:"aiTwin",history:Z?.history??[]};ln.has(z)&&(ce.voice_id=fe),Q&&(ce.language=Q),(Z?.fullBody??g)&&(ce.fullBody=!0);const me=Z?.brainId?.trim();me&&(ce.brainId=me);const Te=Z?.brainUrl?.trim();Te&&(ce.brainUrl=Te);const ie=Z?.userName?.trim();ie&&(ce.userName=ie);const w=Z?.userEmail?.trim();w&&(ce.userEmail=w);const c=Z?.userContext?.trim();c&&(ce.userContext=c);const p=await be({requestBody:ce,engineId:z,debugSpokenFallback:ee,delayPlayback:Z?.delayPlayback,onSpokenText:Z?.onSpokenText,onDisplayText:Z?.onDisplayText});if(p.aborted)return{spokenText:p.spokenText,displayText:p.displayText};if(!p.spokenText&&!p.displayText)throw new Error("avatar_ttsWithPoses generateReply stream missing spokenText or displayText");return{spokenText:p.spokenText||p.displayText,displayText:p.displayText||p.spokenText}},stop:ae,releasePlaybackHold:()=>G.releaseStartHold(),getVisemeQueue:()=>i,getWordQueue:()=>s,getFullVisemeQueue:()=>o,getFullWordQueue:()=>a,getSentenceEmotions:()=>m,getStreamMood:()=>h,getPlaybackElapsedMs:()=>G.getPlaybackElapsedMs(),isSpeaking:()=>G.isSpeaking(),isWarmingUp:()=>G.isWarmingUp(),releaseWarmupHold:()=>G.releaseWarmupHold(),setLipsyncWarmupHold:(T,Z)=>{Z&&(H=Z),G.setLipsyncWarmupHoldEnabled(T)},getVoiceStream:()=>G.getVoiceStream(),setMuted:T=>{G.setMuted(T)},isMuted:()=>G.isMuted(),setPlaybackSpeed:T=>{G.setPlaybackSpeed(T)},getPlaybackSpeed:()=>G.getPlaybackSpeed(),subscribe:T=>(P.add(T),()=>P.delete(T))}}function sr(e){if(e==null)return!1;if(typeof e=="object"){const n=e;if(n.type==="permissions"||n.name==="NotAllowedError"||n.name==="PermissionDeniedError")return!0}const r=(e instanceof Error?`${e.name} ${e.message}`:typeof e=="string"?e:String(e)).toLowerCase();return!!(r.includes("notallowederror")||r.includes("permissiondeniederror")||r.includes("permission denied")||r.includes("permissions denied")||r.includes("microphone access denied")||(r.includes("microphone")||r.includes(" mic"))&&(r.includes("denied")||r.includes("blocked")||r.includes("not allowed")||r.includes("permission")))}async function no(){if(typeof navigator>"u"||!navigator.permissions?.query)return!1;try{return(await navigator.permissions.query({name:"microphone"})).state==="denied"}catch{return!1}}const Bn=16e3,Fn=16e3;class io extends _n.ProtobufFrameSerializer{async deserialize(t){try{return await super.deserialize(t)}catch(r){if(r instanceof Error&&r.message==="Unknown frame kind")return{type:"raw",message:null};throw r}}}class so extends _n.DailyMediaManager{constructor(){super(!0,!0,void 0,void 0,512,Bn,Fn)}bufferBotAudio(t,r){}}const ao=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function li(e){return ao.test(e.trim())}function oo(e){const t=e.replace(/\/$/,"");return t.startsWith("https://")?`wss://${t.slice(8)}`:t.startsWith("http://")?`ws://${t.slice(7)}`:t}function xs(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 r=e.apiBase??lt,n=new URL(`${oo(r)}/ws/voice`);n.searchParams.set("authToken",t),n.searchParams.set("tenant","aiTwin");const i=ct(e.ttsEngineId,e.voiceId),s=i.ttsEngineId;s&&n.searchParams.set("ttsEngineId",s);const o=i.voiceId?.trim();o&&(s&&Vi(s)?li(o)||n.searchParams.set("voiceId",o):li(o)&&n.searchParams.set("voiceId",o));const a=Nr(e.language);a&&n.searchParams.set("language",a);const f=e.brainId?.trim()||e.personaId?.trim();f&&n.searchParams.set("brainId",f);const m=e.brainUrl?.trim();m&&n.searchParams.set("brainUrl",m);const u=e.speakingRate??ur;n.searchParams.set("speaking_rate",String(Math.max(Hr,Math.min($r,u)))),e.ttsStream===!1?n.searchParams.set("tts_stream","false"):n.searchParams.set("tts_stream","true"),e.speakOnlyWhenSpokenTo&&n.searchParams.set("speakOnlyWhenSpokenTo","true");const l=e.avatarName?.trim();l&&n.searchParams.set("avatarName",l);const h=e.userName?.trim();h&&n.searchParams.set("userName",h);const v=e.userEmail?.trim();v&&n.searchParams.set("userEmail",v);const E=e.userContext?.trim();return E&&n.searchParams.set("userContext",E),n.toString()}function rn(e,t){if(!Array.isArray(e))return[];const r=[];for(const n of e)!n||typeof n!="object"||r.push({sentence_index:Number(n.sentence_index??0),text:String(n.text??""),sentiment:typeof n.sentiment=="string"?n.sentiment:void 0,emotion:String(n.emotion??t),start_word:Number(n.start_word??0),end_word:Number(n.end_word??0)});return r}function co(e){if(!e||typeof e!="object")return null;const t=e,n=(t.data&&typeof t.data=="object"&&!Array.isArray(t.data)?t.data:null)||t;return{...n,type:String(n.type??t.type??"server-message")}}function ui(e){return e.is_new_segment===!0||Number(e.audio_offset_ms??-1)===0?!0:Number(e.chunk_index??-1)===0}function lo(e){return e?.transport?._mediaManager?._wavStreamPlayer??null}function Is(e,t={}){const r=[],n=[],i=[],s=[];let o=0;const a=[],f=[];let m="",u="neutral",l=ut,h=!1,v=null,E=null,g={...t},P=0,j=null;const F=new Set,S=[];let x=!1,L=null,H=!0,G="default";const ne=new Set;let B=null,N=0,X=!1,se=!1,de=null,ae=!1;const Ae=()=>{de!=null&&(clearTimeout(de),de=null)},be=()=>{Ae(),de=setTimeout(()=>{de=null,H&&(T.markStreamComplete(r),U("bot_stopped"))},450)},te=()=>F.forEach(y=>y());let He=()=>!1;const T=Ts({onSpeakingStart:()=>e("speaking"),onSpeakingDone:()=>{ae=!1,se=!1,e("done")},onNotify:te,shouldHoldForWarmup:()=>He()},l),Z=()=>{if(L)return L;const y=new MessageChannel;return y.port1.onmessage=()=>{const A=S.shift();A!==void 0&&J(A),S.length>0?y.port2.postMessage(null):x=!1},L=y,y},ee=y=>{S.push(y),!x&&(x=!0,Z().port2.postMessage(null))},z=()=>T.getPlaybackElapsedMs(),fe=(y,A=m)=>{if(!g.onLipsyncDebug)return;const W=z(),re=r,we=jr(i).map(Re=>({viseme:Re.viseme,vtimeMs:Re.vtime}));g.onLipsyncDebug({event:y,spokenText:A,mood:u,playbackAnchorPerf:T.getPlaybackStartPerf(),playbackElapsedMs:W,queueLength:re.length,activeViseme:lr(re,W),segments:f.map(Re=>({...Re,visemes:[...Re.visemes]})),fullQueueLength:i.length,compactionSkipped:we})},U=(y,A)=>{g.onLipsyncDebug&&(j={event:y,spokenText:A},P===0&&(P=requestAnimationFrame(()=>{P=0;const W=j;j=null,W&&fe(W.event,W.spokenText)})))},Q=()=>{H=!0,ne.clear(),T.clearAborted()},ce=()=>{const y=lo(v);if(y){G=`bot-${Date.now()}`,y.interruptedTrackIds={[G]:!0};try{y.interrupt?.()}catch{}}const A=E;try{A?.interrupt?.()}catch{}},Se=y=>{if(ae&&T.isSpeaking())return!0;const A=y.context_id?.trim();return A&&ne.has(A)?!0:H?!1:!(y.type==="avatar_metadata"||ui(y))},me=y=>{H=!1,ae=!1;const A=y.context_id?.trim();A&&ne.add(A),Ae(),X=!1,se=!1,S.length=0,x=!1,B?.abort(),B=null,N+=1,ce(),T.bargeIn(),Te(),e("idle"),U("interrupt"),te()},Te=()=>{r.length=0,n.length=0,i.length=0,s.length=0,o=0,f.length=0,m="",u="neutral",a.length=0},ie=()=>{Ae(),se=!1,X=!1,T.stop(),Te(),U("reset"),te()},w=()=>{ie(),e("idle"),te()},c=(y,A)=>{typeof y.mood=="string"&&y.mood.trim()&&(u=y.mood.trim()),Array.isArray(y.sentence_emotions)&&y.sentence_emotions.length>0&&(A&&(a.length=0),a.push(...rn(y.sentence_emotions,u)))},p=y=>{if(Se({...y,type:"avatar_metadata"}))return;Q(),X=!0;const A=String(y.spoken_text??y.text??"").trim();A&&(m=A),T.resetForNewStream(l),typeof y.mood=="string"&&y.mood.trim()&&(u=y.mood.trim()),a.length=0,a.push(...rn(y.sentence_emotions,u)),Array.isArray(y.gestures)&&y.gestures,U("metadata",A),te()},b=(y,A,W,re)=>{if(!g.onLipsyncDebug)return;const we=r.slice(W),Re=re.filter(xe=>String(xe.symbol??xe.viseme??"").trim());f.push({spokenText:A,audioOffsetMs:we[0]?.vtime??0,isNewSegment:!!y.is_new_segment,chunkDurationMs:y.chunk_duration_ms!=null?Number(y.chunk_duration_ms):null,receivedAtMs:performance.now(),visemes:we.map((xe,Fe)=>{const De=Re[Fe];return{rawSymbol:String(De?.symbol??De?.viseme??xe.viseme).trim(),viseme:xe.viseme,startSec:Number(De?.start??0),durationSec:Number(De?.duration??0),vtimeMs:xe.vtime,vdurationMs:xe.vduration}})})},R=(y,A,W,re)=>{if(y.length===0&&A.length===0)return;vs(i,s,y,A,o,l);const we=_s(y,o);let Re=null;const xe=W.trim();if(xe)try{const Fe=atob(xe.replace(/\s+/g,"")).length,De=Number.isFinite(re)&&(re??0)>0?Number(re):16e3;Re=Fe/2/De*1e3}catch{Re=null}o=Math.max(we,Re!=null?o+Re:o)},C=y=>{if(Se(y))return;const A=ui(y);A&&(Ae(),Q());const W=String(y.spoken_text??y.text??"").trim(),re=y.visemes??[],we=y.words??[],Re=String(y.chunk??"").trim(),xe=X||A||!se;X&&(X=!1),xe&&(se=!0),W&&(m=W),c(y,A),xe?(T.resetForNewStream(l),i.length=0,s.length=0,o=0):A&&T.resumeBotStream(),R(re,we,Re,y.sample_rate);const Fe=r.length;T.playAudioChunk(r,n,Re,re,we,A,{sampleRate:y.sample_rate,newStream:xe,audioOffsetMs:Number(y.audio_offset_ms??0),onNewStream:()=>{f.length=0}}).then(()=>{b(y,W,Fe,re),U("audio_chunk",W),be()})},V=y=>{if(Se(y))return;(y.is_new_segment||Number(y.audio_offset_ms??-1)===0)&&Q(),console.warn("[realtimeVoice] avatar_lipsync is deprecated — expect avatar_audio_chunk");const A=String(y.spoken_text??y.text??"").trim();A&&(m=A),c(y,!!y.is_new_segment),R(y.visemes??[],y.words??[],"",void 0);const W=r.length;T.queueTimingsOnly(r,n,y.visemes??[],y.words??[],!!y.is_new_segment,{audioOffsetMs:Number(y.audio_offset_ms??0)}),b(y,A,W,y.visemes??[]),U("lipsync",A),te()},K=async y=>{const A=String(y.text??"").trim();if(!A)return;const W=g.authToken?.trim();if(!W){console.error("[realtimeVoice] avatar_speak requires authToken");return}B?.abort();const re=new AbortController;B=re;const we=++N;Q(),T.resetForNewStream(l),m=A;const xe=`${(g.apiBase??lt).replace(/\/$/,"")}/avatar_ttsWithPoses`,Fe=ct(l,g.voiceId);Fe.ttsEngineId&&(l=Fe.ttsEngineId,T.setStreamTtsEngineId(l));const De=Fe.voiceId?.trim()||(l===dt?Or:Cn),ft=g.speakingRate??ur,$e=Math.max(Hr,Math.min($r,ft)),rt={user_query:A,ttsEngineId:l,speakingRate:$e,tenant:"aiTwin"};ln.has(l)&&(rt.voice_id=De);const dr=Nr(g.language);dr&&(rt.language=dr),g.fullBody&&(rt.fullBody=!0);const _t=g.fullBody?g.waitForBodyIdle?.()??null:null;let bt=!1;const Kt=()=>{bt||(bt=!0,T.releaseStartHold())};_t&&(T.armStartHold(),_t.promise.then(Kt));try{const mt=await fetch(xe,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${W}`},body:JSON.stringify(rt),signal:re.signal});if(!mt.ok)throw new Error(`avatar_ttsWithPoses failed (${mt.status})`);const fr=mt.body;if(!fr)throw new Error("No response body");const qt=fr.getReader(),mr=new TextDecoder;let St="",Yt=!0;const Qt=async Xt=>{if(we!==N||re.signal.aborted||!H)return;const Oe=ss(Xt);if(Oe){if(Oe.event==="audio"){const ze=Oe.data.chunk,Xe=Oe.data.visemes??[],Bt=Oe.data.words??[],ht=Oe.data.is_new_segment??!1,Tt=Oe.data.sample_rate,Ft=Number(Oe.data.audio_offset_ms??0);if(ze){const nt=Yt;Yt=!1,await T.playAudioChunk(r,n,ze,Xe,Bt,ht,{sampleRate:Tt,newStream:nt,audioOffsetMs:Ft})}else(Xe.length>0||Bt.length>0)&&T.queueTimingsOnly(r,n,Xe,Bt,ht,{audioOffsetMs:Ft,newStream:Yt})}else if(Oe.event==="metadata"){const ze=Oe.data.mood;typeof ze=="string"&&ze.trim()&&(u=ze.trim());const Xe=Oe.data.sentence_emotions;Array.isArray(Xe)&&(a.length=0,a.push(...rn(Xe,u))),te()}else if(Oe.event==="error")throw new Error(String(Oe.data.message??"avatar_ttsWithPoses stream error"))}};for(;!(we!==N||re.signal.aborted||!H);){const{done:Xt,value:Oe}=await qt.read();Oe&&(St+=mr.decode(Oe,{stream:!0}));const ze=St.split(`
4
4
 
5
- `);_t=je.pop()??"";for(const He of je)await Ft(He);if(qt){_t.trim()&&await Ft(_t.trim()),we===U&&!ge.signal.aborted&&W&&T.markStreamComplete(r);break}}}catch(mt){if(Pt?.cancel(),g.onBodyIdleCancelled?.(),Ct(),ge.signal.aborted||!W)return;console.error("[realtimeVoice] avatar_speak failed:",mt),e("error"),re()}finally{M===ge&&(M=null)}},$=w=>{const P=so(w);if(!P){console.warn("[realtimeVoice] server message with no payload",w);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":p(P);break;case"avatar_audio_chunk":F(P);break;case"avatar_lipsync":q(P);break;case"avatar_interrupt":K(P);break;case"error":{const ge=String(P.message??"Voice session error");console.error("[realtimeVoice] server error:",ge),e("error"),re();break}case"avatar_speak":L(P);break}},k=()=>v||(E=new ro,v=new Ks.PipecatClient({transport:new wn.WebSocketTransport({mediaManager:E,serializer:new to,recorderSampleRate:Mn,playerSampleRate:Pn}),enableCam:!1,enableMic:!0,callbacks:{onBotReady:()=>{h=!0,e("idle"),re()},onDisconnected:()=>{h=!1,y()},onError:w=>{const P=typeof w=="object"&&w!==null&&"data"in w?String(w.data??w):String(w);console.error("[realtimeVoice]",P,w),e("error"),re()},onTransportStateChanged:w=>{w==="error"&&(e("error"),re())},onServerMessage:w=>{H(w)},onUserStartedSpeaking:()=>{},onBotStartedSpeaking:()=>{se(),X("bot_started")},onBotStoppedSpeaking:()=>{W&&ke()},onUserTranscript:w=>{String(w.text??""),g.onUserTranscript?.(w.text,!!w.final)},onBotOutput:w=>{g.onBotOutput?.(w.text)}}}),v);return{setDeveloperToken:w=>{},setTtsEngineId:w=>{c=w,T.setStreamTtsEngineId(w)},getTtsEngineId:()=>c,speak:async(w,P)=>{const ne=w.trim();if(ne){if(!v||!h)throw new Error("Realtime voice is not connected. Call connect() first.");oe(),await v.sendText(ne)}},speakWithReply:async(w,P)=>{throw new Error("speakWithReply is not available on the voice session; use AiTwin.speakWithReply()")},stop:()=>{M?.abort(),M=null,U+=1,se(),oe(),e("idle"),re()},connect:async w=>{w&&(g={...g,...w});const P=lt(g.ttsEngineId,g.voiceId);if(P.ttsEngineId&&(c=P.ttsEngineId,T.setStreamTtsEngineId(c)),g={...g,ttsEngineId:c,...P.voiceId?{voiceId:P.voiceId}:{}},!g.authToken?.trim())throw new Error("Voice connect requires authToken (same JWT as SSE Authorization Bearer).");e("loading");const ne=k();try{await ne.initDevices()}catch(we){throw h=!1,e("idle"),re(),rr(we)?new Error("Microphone access denied"):we instanceof Error?we:new Error("Failed to initialize microphone")}const ge=Ts({...g,ttsEngineId:c});console.info("[realtimeVoice] connecting (avatar_audio_chunk RTVI):",ge);try{await ne.connect({wsUrl:ge})}catch(we){if(h=!1,e("error"),re(),rr(we))throw e("idle"),new Error("Microphone access denied");const ve=we instanceof Error?we.message:"Realtime voice connect failed (WebSocket 101 only means upgrade OK — check authToken/origin/RTVI handshake)";throw new Error(`${ve} — ${ge}`)}h=!0,e("idle"),re()},disconnect:async()=>{if(Ae(),J=!1,Q=!1,S.length=0,x=!1,M?.abort(),M=null,U+=1,se(),v)try{await v.disconnect()}catch(w){console.error("[realtimeVoice] disconnect failed:",w)}h=!1,y()},isConnected:()=>h,unlockAudio:async()=>{await T.primeAudioContext()},getVisemeQueue:()=>r,getWordQueue:()=>n,getFullVisemeQueue:()=>i,getFullWordQueue:()=>s,getSentenceEmotions:()=>a,getStreamMood:()=>l,getPlaybackElapsedMs:j,isSpeaking:()=>T.isSpeaking(),isWarmingUp:()=>T.isWarmingUp(),releaseWarmupHold:()=>T.releaseWarmupHold(),releasePlaybackHold:()=>T.releaseStartHold(),setLipsyncWarmupHold:(w,P)=>{P&&(Ke=P),T.setLipsyncWarmupHoldEnabled(w)},getVoiceStream:()=>T.getVoiceStream(),setMuted:w=>{T.setMuted(w)},isMuted:()=>T.isMuted(),setPlaybackSpeed:w=>{T.setPlaybackSpeed(w)},getPlaybackSpeed:()=>T.getPlaybackSpeed(),subscribe:w=>(B.add(w),()=>B.delete(w))}}function Es(e,t,r){return{width:e.crop?.source_width??t,height:e.crop?.source_height??r}}function xs(e,t){const r=e.crop;return{x:t?.source_x??r?.x??0,y:t?.source_y??r?.y??0,width:t?.source_w??r?.width??e.frame_width??0,height:t?.source_h??r?.height??e.frame_height??0}}function Is(e){return e?(e.w??0)>0&&(e.h??0)>0:!1}function Vt(e,t){return`${e}/${t}_minus_sil.png`}const As=5;function Wr(e){const t=e?.composite_threshold;if(typeof t=="number"&&t>0)return t;const r=e?.crop?.content_threshold;return typeof r=="number"&&r>0?r:As}const oo=["aa","E","I","O","U","PP","FF","DD","SS","TH","CH","RR","kk","nn"],mn=["t01_0.25","t02_0.50","t03_0.75"],co=mn.length,ci=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 li(e,t){return`${e}__${t}`}function ui(e,t){return`pairs/${e}/${t}_minus_sil.png`}function jt(e){return`${e}_minus_sil.png`}function Cn(e,t){if(t.has(e))return e;const r=/^pairs\/([^/]+)\//.exec(e);if(!r)return null;const n=r[1].split("__")[1];if(!n||n==="sil")return null;const i=jt(n);return t.has(i)?i:null}function Rs(e,t){return e.filter(r=>t.has(r))}function lo(e,t,r){const n=Fn(e,t);return Rs(n,r).length>0}function Fn(e,t){if(e===t)return[];const r=[],n=li(e,t);if(ci.has(n)){for(const s of mn)r.push(ui(n,s));return r}const i=li(t,e);if(ci.has(i)){for(let s=co-1;s>=0;s--)r.push(ui(i,mn[s]));return r}return[]}function uo(e){return e<16?[1]:e<24?[1]:e<35?[0,1,2]:[0,1,2]}function fo(e,t){return uo(t).map(n=>e[n]).filter(n=>n!=null)}function mo(e,t,r,n){if(n<=0)return 0;const s=Math.max(1,r-t)/n,o=e-t,a=Math.floor(o/s);return Math.min(n-1,Math.max(0,a))}function Ms(e,t,r){if(!r)return`${e}/${t}`;const n=t.split("/").pop()??t,i=n.includes(".")?n.slice(0,n.lastIndexOf(".")):n;return`${e}/${i}.bin`}const ho=[.32,.24,.16,.08,0],po=ho.map(e=>`eyes_${e.toFixed(2)}`),go=["eyes_0.32","eyes_0.16","eyes_0.00"],wo=["eyes_0.32","eyes_0.16","eyes_0.08","eyes_0.00"],Xe=2,yo=-20,Ir=16,Ps={fear:-20,anger:-20,sad:-10,neutral:0,love:0,happy:0,disgust:10};function nr(e){return`brow_${e}`}function At(e){return Ps[e]}function rt(e){return Math.max(yo,Math.min(Ir,e))}function vo(e,t){if(e===t)return[];const r=e<t,n=r?Xe:-Xe,i=[];let s=e;if(s%Xe!==0){const o=r?Math.ceil(s/Xe)*Xe:Math.floor(s/Xe)*Xe,a=rt(o);if(r?a>=t:a<=t)return[t];s=a,i.push(s)}for(;;){const o=s+n;if(r?o>=t:o<=t){t!==s&&i.push(t);break}s=o,i.push(s)}return i}function di(e){const t=rt(e);if(t%Xe===0)return[t];const r=Math.floor(t/Xe)*Xe,n=Math.min(Ir,r+Xe),i=rt(r);return t-i<=n-t?i===n?[i]:[i,n]:i===n?[n]:[n,i]}const _o=["fear","anger","sad","neutral","love","happy","disgust"],bo={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 ct(e,t="neutral"){const r=String(e??"").trim().toLowerCase();return r?bo[r]??t:t}function Cs(e){return e===0?null:Vt(nr(e),"eyes_standard")}function Fs(e){return Cs(At(e))}const So={[-20]:"anger",[-10]:"sad",0:"neutral",10:"disgust"};function Bn(e,t){if(!e)return null;if(t(e))return e;const r=e.match(/^brow_(-?\d+)\/(eyes_[^/]+)_minus_sil\.png$/);if(r){const i=Number(r[1]),s=r[2];for(const a of di(i)){if(a===i)continue;const f=Vt(nr(a),s);if(t(f))return f}const o=So[i];if(o){const a=Vt(o,s);if(t(a))return a}return null}const n=e.match(/^(fear|anger|sad|neutral|love|happy|disgust)\/(eyes_[^/]+)_minus_sil\.png$/);if(n){const i=n[1],s=n[2],o=At(i);for(const a of[o,...di(o)]){const f=Vt(nr(a),s);if(t(f))return f}}return null}function fi(e,t){const r=nr(At(e));return!t||t==="eyes_standard"?Fs(e):e==="neutral"&&t==="eyes_standard"?null:Vt(r,t)}function To(e,t){const r=[];for(const n of t)r.push(fi(e,n));for(let n=t.length-2;n>=0;n--)r.push(fi(e,t[n]));return r.push(Fs(e)),r}function ko(e){return Vt(nr(e),"eyes_standard")}function Eo(e,t){return vo(e,t).map(ko)}const xo=6;function Io(e,t){for(const r of e)if(t>=r.wtime&&t<r.wtime+r.wduration)return r;return null}function Ao(e){const t=rt(e);return t>=Ir?Ir:rt(t+xo)}function Ro(e,t,r){const n=rt(r);return Io(t,e)?.emphasis?Ao(n):n}function mi(e){if(!e)return 0;const t=e.match(/^brow_(-?\d+)\//);if(!t?.[1])return null;const r=Number.parseInt(t[1],10);return Number.isFinite(r)?rt(r):null}function tt(e,t){return e+Math.random()*(t-e)}function hi(){return tt(14,32)}function Mo(e){if(e)return{holdMinMs:10,holdMaxMs:18,closedExtraMs:0};const t=Math.random();return t<.18?{holdMinMs:38,holdMaxMs:62,closedExtraMs:tt(40,90)}:t<.42?{holdMinMs:26,holdMaxMs:44,closedExtraMs:tt(12,36)}:t<.82?{holdMinMs:14,holdMaxMs:28,closedExtraMs:Math.random()<.35?tt(8,22):0}:{holdMinMs:10,holdMaxMs:18,closedExtraMs:0}}function pi(e,t){const r=tt(e.holdMinMs,e.holdMaxMs);return t?r+e.closedExtraMs:r}function Po(e={}){const{initialDelayMs:t=800+Math.random()*1200,intervalMinMs:r=2200,intervalMaxMs:n=5800,doubleBlinkChance:i=.18,doubleBlinkGapMinMs:s=120,doubleBlinkGapMaxMs:o=220,fullBlinkChance:a=.75,postEmotionChangeDelayMs:f=380,minDwellMs:m=550}=e;let l="neutral",c="neutral",h=0,v=0,E=0,g={kind:"idle",nextBlinkAt:performance.now()+t},R=null,V="__eyes_open__|neutral|brow:0";function B(M=l){V=`${R??"__eyes_open__"}|${M}|brow:${v}`}function S(M,U=l){R=M;const J=mi(M);J!=null?v=J:M==null&&(v=0),B(U)}function x(M){return Cs(M)}function O(M,U,J){const Q=rt(U),ue=rt(J);if(h=ue,Q===ue){S(x(ue));return}const ae=[...Eo(Q,ue),x(ue)];g={kind:"browBlend",paths:ae,index:0,holdUntil:M+hi(),targetBrow:ue},S(ae[0]??null)}function W(M,U){g={kind:"idle",nextBlinkAt:M+tt(r,n)},c=U,S(x(h),U)}function G(M,U,J){const Q=J?go:Math.random()<a?po:wo,ue=Mo(J),ae=Q.length-1;g={kind:"playing",paths:To(U,Q),index:0,holdUntil:M+pi(ue,ae===0),after:"idle",blinkEmotion:U,pace:ue,closedFrameIndex:ae},c=U,S(g.paths[0]??null,U)}function ie(M){if(g.kind==="browBlend"){for(;M>=g.holdUntil&&g.index<g.paths.length-1;)g.index+=1,g.holdUntil=M+hi();const U=g.paths[g.index]??null;S(U),M>=g.holdUntil&&g.index>=g.paths.length-1&&(v=g.targetBrow,h=g.targetBrow,S(x(g.targetBrow)),g={kind:"idle",nextBlinkAt:M+f});return}if(g.kind==="idle"){S(x(h),c),M>=g.nextBlinkAt&&G(M,c,!1);return}if(g.kind==="doublePause"){S(x(h),g.blinkEmotion),M>=g.resumeAt&&G(M,g.blinkEmotion,!0);return}if(g.kind==="playing"){for(;M>=g.holdUntil&&g.index<g.paths.length-1;)g.index+=1,g.holdUntil=M+pi(g.pace,g.index===g.closedFrameIndex);if(S(g.paths[g.index]??null,g.blinkEmotion),M>=g.holdUntil&&g.index>=g.paths.length-1){if(g.after==="resumeIdle"){W(M+f,l);return}if(g.after==="doublePause"){g={kind:"doublePause",resumeAt:M+tt(s,o),blinkEmotion:g.blinkEmotion},S(x(h),g.blinkEmotion);return}if(g.after==="idle"&&Math.random()<i){g={kind:"doublePause",resumeAt:M+tt(s,o),blinkEmotion:g.blinkEmotion},S(x(h),g.blinkEmotion);return}W(M,g.blinkEmotion)}}}return{advance:ie,setTargetEmotion(M,U){const J=ct(M,l);if(J===l)return;const Q=performance.now();!U?.force&&m>0&&!(l==="neutral"&&J!=="neutral")&&Q-E<m||(l=J,c=J,E=Q)},setTargetEyebrow(M){const U=rt(M);if(U===h)return;const J=performance.now(),Q=g.kind==="browBlend"?mi(R)??v:v;h=U,!(U===Q&&g.kind!=="browBlend")&&(g.kind==="playing"||g.kind==="doublePause"||O(J,Q,U))},snapToEmotion(M){const U=ct(M),J=At(U);l=U,c=U,h=J,v=J,E=performance.now(),g={kind:"idle",nextBlinkAt:performance.now()+tt(4e3,7e3)},S(x(J),U)},getTargetEmotion:()=>l,getTargetEyebrow:()=>h,getExpressionPath:()=>R,getDrawKey:()=>V,reset(){l="neutral",c="neutral",h=0,v=0,E=0,W(performance.now()+tt(r,n),"neutral")}}}function Co(){const e=document.createElement("video");e.muted=!0,e.playsInline=!0,e.preload="auto",e.setAttribute("playsinline",""),e.loop=!0;let t=!1,r=null,n="";const i=()=>{r&&(URL.revokeObjectURL(r),r=null)};return{async load(s){t&&n===s||(i(),t=!1,n=s,s.startsWith("blob:")&&(r=s),await new Promise((o,a)=>{const f=()=>{const m=e.duration;if(!Number.isFinite(m)||m<=0){a(new Error(`Idle video has invalid duration: ${s}`));return}t=!0,e.currentTime=0,o()};e.addEventListener("loadeddata",f,{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())},setLooping(s){e.loop=s},restart(){t&&(e.currentTime=0)},dispose(){e.pause(),e.removeAttribute("src"),e.load(),i(),t=!1,n=""}}}const Fo=50,Bs=400;function Bo(e,t,r){return e.filter(n=>{const i=n.queueIndex??-1;return i>=t&&i<=r})}function Do(e,t){const r=[];for(const n of e){const i=Bo(t,n.start_word,n.end_word);if(i.length===0)continue;const s=i[0],o=i[i.length-1];r.push({sentence:n,startMs:Math.max(0,s.wtime-Fo),endMs:o.wtime+o.wduration+Bs})}return r.sort((n,i)=>n.startMs-i.startMs)}function Lo(e,t,r,n="neutral"){const i=ct(n);if(t.length===0)return i;if(r.length===0||e<r[0].wtime)return ct(t[0]?.emotion,i);const s=Do(t,r);let o=null;for(const m of s)e>=m.startMs&&e<=m.endMs&&(o=m);if(o)return ct(o.sentence.emotion,i);const a=r[r.length-1],f=a.wtime+a.wduration;return e>f+Bs?ct(t[t.length-1]?.emotion,i):i}function Dn(e,t,r,n,i=As){const s=new OffscreenCanvas(r,n),o=s.getContext("2d",{willReadFrequently:!0});o.drawImage(e,0,0,r,n);const a=o.getImageData(0,0,r,n),f=o.createImageData(r,n);f.data.set(a.data);const l=new OffscreenCanvas(r,n).getContext("2d",{willReadFrequently:!0});for(const c of t){l.clearRect(0,0,r,n),l.drawImage(c,0,0,r,n);const h=l.getImageData(0,0,r,n);for(let v=0;v<f.data.length;v+=4){const E=h.data[v],g=h.data[v+1],R=h.data[v+2];h.data[v+3]>0&&Math.max(E,g,R)>i&&(f.data[v]=E,f.data[v+1]=g,f.data[v+2]=R,f.data[v+3]=255)}}return o.putImageData(f,0,0),s}let Et=null,Ht=null;const Ar=new Map;function Oo(){Et=null,Ht=null,Ar.clear()}ji(Oo);function No(e){return e??Ht??void 0}function Ln(e){return new Promise((t,r)=>{const n=new Image;n.decoding="async",n.onload=()=>t(n),n.onerror=()=>r(new Error(`Failed to load image: ${e}`)),n.src=e})}async function Uo(e){return zt()?Ki(await yt(tr(),e??"")):Ln(tr())}async function gi(e,t,r,n){const i=r?await Gi(e,n):await fetch(e).then(m=>{if(!m.ok)throw new Error(`Failed to load ${e}`);return m.json()}),s=i.sheets?.[0];if(!s?.path)throw new Error(`${e} has no sheets[0].path`);const o=r?await _a(await yt(Ms(t,s.path,r),n??"")):await Ln(`${t}/${s.path}`),a=new Map;for(const m of i.cells??[])m.path&&a.set(m.path,m);const f=new Map;for(const m of i.sheets??[])f.set(m.index,m);return{atlas:o,atlasMeta:i,cellByPath:a,sheetByIndex:f,diffBase:t}}async function hn(e){const t=No(e),r=zt();if(r&&!t)throw new Error("Encrypted assets enabled but no key provided");if(Et&&(!r||Ht===(t??null))){const s=await Et;return{...$t(s),visemePaths:[...s.viseme.cellByPath.keys()]}}Ht=t??null,Ar.clear();const n=Hi();Et=(async()=>{const s=await Uo(t),o=await gi($i(),n,r,t);let a=null;try{a=await gi(zi(),n,r,t)}catch{a=null}return{sil:s,viseme:o,expression:a}})();const i=await Et;return{...$t(i),visemePaths:[...i.viseme.cellByPath.keys()]}}async function On(e){if(await hn(e),!Et)throw new Error("Assets not loaded");return Et}function $t(e){return Es(e.viseme.atlasMeta,e.sil.naturalWidth,e.sil.naturalHeight)}function Vo(e,t){const r=document.createElement("canvas");return r.width=t.w,r.height=t.h,r.getContext("2d",{willReadFrequently:!0}).drawImage(e.atlas,t.x,t.y,t.w,t.h,0,0,t.w,t.h),r}async function Rr(e,t,r){const n=`${t.diffBase}::${r}`,i=Ar.get(n);if(i)return i;const s=(async()=>{const o=t.cellByPath.get(r);if(!o)throw new Error(`No atlas cell for path: ${r}`);const a=xs(t.atlasMeta,o),f=$t(e);if(Is(o)){const c=Vo(t,o),h=document.createElement("canvas");h.width=f.width,h.height=f.height;const v=h.getContext("2d");return v.fillStyle="#000",v.fillRect(0,0,f.width,f.height),v.drawImage(c,a.x,a.y),h}const m=`${t.diffBase}/${r}`,l=await Ln(m);if(l.naturalWidth===f.width&&l.naturalHeight===f.height)return l;throw new Error(`Diff PNG wrong size for ${r}`)})();return Ar.set(n,s),s}async function en(e,t,r,n,i,s){if(i){const{width:v,height:E}=i;if(s&&!s()||t.readyState<HTMLMediaElement.HAVE_CURRENT_DATA)return;const g=document.createElement("canvas");g.width=v,g.height=E;const R=g.getContext("2d");if(R.clearRect(0,0,v,E),R.drawImage(t,0,0,v,E),s&&!s())return;(e.width!==v||e.height!==E)&&(e.width=v,e.height=E);const V=e.getContext("2d");V.clearRect(0,0,v,E),V.drawImage(g,0,0);return}const o=await On(),a=Wr(o.viseme.atlasMeta),{width:f,height:m}=$t(o);(e.width!==f||e.height!==m)&&(e.width=f,e.height=m);const l=[],c=e.getContext("2d");if(c.clearRect(0,0,f,m),t.readyState<HTMLMediaElement.HAVE_CURRENT_DATA){const v=o.sil;c.drawImage(v,0,0,f,m);return}if(l.length===0){c.drawImage(t,0,0,f,m);return}const h=Dn(t,l,f,m,a);c.drawImage(h,0,0)}async function pn(e,t,r){const n=await On(Ht??void 0),i=Wr(n.viseme.atlasMeta),{width:s,height:o}=$t(n);(e.width!==s||e.height!==o)&&(e.width=s,e.height=o);const a=[];if(t.mouthPath){const l=new Set(n.viseme.cellByPath.keys()),c=Cn(t.mouthPath,l)??(l.has(t.mouthPath)?t.mouthPath:null);c&&a.push(await Rr(n,n.viseme,c))}if(t.expressionPath&&n.expression){const l=Bn(t.expressionPath,c=>n.expression.cellByPath.has(c));l&&a.push(await Rr(n,n.expression,l))}const f=e.getContext("2d");if(f.clearRect(0,0,s,o),a.length===0){f.drawImage(n.sil,0,0,s,o);return}const m=Dn(n.sil,a,s,o,i);f.drawImage(m,0,0)}async function Wo(e,t){const r=await On(Ht??void 0),n=Wr(r.viseme.atlasMeta),{width:i,height:s}=$t(r),o=[];if(e.mouthPath){const l=new Set(r.viseme.cellByPath.keys()),c=Cn(e.mouthPath,l)??(l.has(e.mouthPath)?e.mouthPath:null);c&&o.push(await Rr(r,r.viseme,c))}if(e.expressionPath&&r.expression){const l=Bn(e.expressionPath,c=>r.expression.cellByPath.has(c));l&&o.push(await Rr(r,r.expression,l))}const a=new OffscreenCanvas(i,s),f=a.getContext("2d");if(o.length===0)return f.drawImage(r.sil,0,0,i,s),a.transferToImageBitmap();const m=Dn(r.sil,o,i,s,n);return f.drawImage(m,0,0),a.transferToImageBitmap()}async function jo(e){await pn(e,{mouthPath:null,expressionPath:null})}const br={fontFamily:"system-ui, -apple-system, sans-serif",fontSize:"clamp(0.875rem, 2.5vw, 1.125rem)",color:"rgba(255,255,255,0.85)"};function Ho(e){return e.length===0?"":e.map(t=>t.word).join(" ")}function $o(e){if(!e)return{enabled:!1,style:br};const t=e===!0?{}:e;return{enabled:!0,style:{fontFamily:t.fontFamily??br.fontFamily,fontSize:t.fontSize??br.fontSize,color:t.color??br.color}}}const zo={position:"absolute",bottom:0,left:0,right:0,display:"flex",justifyContent:"center",padding:"0.75rem 1rem",pointerEvents:"none"},Go={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"},Ko={display:"-webkit-box",WebkitLineClamp:2,WebkitBoxOrient:"vertical",overflow:"hidden",maxWidth:"100%",margin:0};function qo({text:e,style:t}){return A.jsx("div",{style:zo,"aria-live":"polite","aria-atomic":"true",children:A.jsx("div",{style:{...Go,fontFamily:t.fontFamily,fontSize:t.fontSize,color:t.color},children:A.jsx("p",{style:Ko,children:e})})})}const Yo={inset:0,overflow:"hidden",pointerEvents:"none",position:"absolute",zIndex:3},Qo={filter:"blur(22px)",height:"100%",inset:0,objectFit:"cover",objectPosition:"top",position:"absolute",transform:"scale(1.08)",width:"100%"},Xo={backdropFilter:"blur(10px)",WebkitBackdropFilter:"blur(10px)",inset:0,position:"absolute"};function Jo({thumbnailUrl:e}){const[t,r]=d.useState(!1);d.useEffect(()=>{r(!1)},[e]);const n=!!e&&t;return A.jsxs("div",{style:Yo,"aria-hidden":!0,children:[e?A.jsx("img",{src:e,alt:"",style:{...Qo,opacity:n?1:0,transition:"opacity 0.45s ease"},onLoad:()=>r(!0),onError:()=>r(!1)}):null,A.jsx("div",{style:{...Xo,background:n?"rgba(0, 0, 0, 0.28)":"rgba(10, 10, 11, 0.92)"}})]})}let Ds=null;function wi(e){Ds=e}function wt(){return Ds}function Zo(e){return`${e.from}→${e.to}@${e.fromVtime}`}function yi(){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 ec(){let e=yi();const t=new Set,r=new Set,n=new Set;let i="",s=-1,o="";const a=()=>{e=yi(),t.clear(),r.clear(),n.clear(),i="",s=-1,o=""},f=l=>{t.add(l)},m=l=>{l&&n.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 h=Zo(l);e.transitionFramesSampled+=1,h!==i&&(i=h,s=-1,o!==h&&(o=h,e.rifeFramesOmittedByGap+=l.omittedByGap)),c&&r.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 v=l.transitionMeta;f(v.fromVtime),f(v.toVtime),m(l.mouthPath);return}if(l.label.includes("→")){e.transitionFramesDisplayed+=1;return}const h=l.label.trim();if(!(!h||h==="sil")){for(const v of c)if(v.viseme===h&&l.elapsedMs>=v.vtime&&l.elapsedMs<v.vtime+v.vduration){f(v.vtime);break}}},snapshot(l,c){let h=0,v=0;for(const B of l)if(B.viseme!=="sil"){if(B.vtime>=c)break;h+=1,t.has(B.vtime)&&(v+=1)}const E=h>0?Math.round(v/h*100):100,g=e.queueSuperseded+e.workerStale+Math.max(0,e.drawsRequested-e.drawsDisplayed),R=h-v,V=e.bufferTicks>0?Math.round(e.bufferHits/e.bufferTicks*100):100;return{...e,bufferHitRate:V,renderLoss:g,visemeSlotsTotal:h,visemeSlotsCovered:v,visemeCoveragePct:E,transitionFramesUniqueSampled:r.size,transitionFramesUniquePainted:n.size,drawsDeduped:e.rafTicksDeduped,renderSkips:e.rafTicksDeduped+g,visemesShown:v,visemesSkipped:R,rifeTransitionFramesSkipped:e.transitionFramesMissed}}}}const Ls=yn,tc=500,vi=500,rc=450,tn=.05,nc=100,ic=600,Os="__sil__";function _i(e){return e.lastDrawnKey?e.lastDrawnKey.split("|")[0]===Os:!1}function Nn(){return{lastDrawnKey:""}}function Ge(e){e.lastDrawnKey="",e.transitionCache=void 0}function sc(e,t){if(t?.transitionCache&&t.transitionCache.queueLength===e.length)return t.transitionCache.transitions;const r=hs(e);return t&&(t.transitionCache={queueLength:e.length,transitions:r}),r}function ac(e,t){let r="sil";for(const n of e)n.viseme!=="sil"&&(t!=null&&n.vtime>t||(r=n.viseme));return r}function oc(e,t,r,n=120){if(r!=="sil")return r;const i=bs(e,t,n);return i!=="sil"?i:ac(e,t)}function cc(e,t){return e==="sil"?!1:t?lo(e,"sil",t):Fn(e,"sil").length>0}function lc(){return Ls+ic}function Mr(e){return e??Os}function Un(e,t,r,n,i=nc){if(e.length===0)return{diffPath:null,label:"sil"};if(t>=kt(e))return{diffPath:null,label:"sil"};const s=n?.holdPp===!0,o=sc(e,n),a=Ya(o,t,s);if(a){const l=ps(a.fromVtime,a.toVtime,a.from,a.to,s);if(t>=l.transStart&&t<l.transEnd){let c=Fn(a.from,a.to);r&&(c=Rs(c,r));const h=fo(c,l.effectiveGapMs);if(h.length>0){const v=mo(t,l.transStart,l.transEnd,h.length);return{diffPath:h[v]??h[h.length-1],label:`${a.from}→${a.to}`,transitionMeta:{from:a.from,to:a.to,fromVtime:a.fromVtime,toVtime:a.toVtime,frameIdx:v,frameCount:h.length,fullFrameCount:c.length,omittedByGap:Math.max(0,c.length-h.length)}}}return{diffPath:jt(a.to),label:a.to}}}const f=Or(e);let m=us(f,t);return m==="sil"&&(m=bs(e,t,i)),m==="sil"?{diffPath:null,label:"sil"}:{diffPath:jt(m),label:m}}function ir(e,t){const r=t??Mr(e.expressionPath);return`${Mr(e.mouthPath)}|${r}`}function bi(e,t,r,n,i,s,o,a,f,m){const l=Un(t,r,f,s),c={mouthPath:l.diffPath,expressionPath:n},h=ir(c,i),v=wt();if(l.transitionMeta&&v?.onTransitionSample(l.transitionMeta,l.diffPath),h===s.lastDrawnKey){v?.onDrawDeduped();return}v?.onDrawRequested(),a(l),s.lastDrawnKey=h,o(e,c,h,E=>{E===h&&(s.lastDrawnKey=h)})}function rn(e,t,r,n,i,s,o=null,a=null){const f={mouthPath:a,expressionPath:t},m=o!=null?`|idle@${Math.round(o*1e3)}`:"",l=ir(f,r)+m;!(o!=null)&&l===n.lastDrawnKey||(s(o!=null?t?"idle · blink":"idle":t?"blink":"sil"),i(e,f,l,h=>{h===l&&(n.lastDrawnKey=l)}))}function Ns(e,t,r,n,i=er,s){if(r<=t||e.length===0)return[];const o=s??Nn(),a=[];let f="";for(let m=t;m<r;m+=i){const l=Un(e,m,n,o),c=Mr(l.diffPath);c!==f&&(f=c,a.push({displayAtMs:m,mouthPath:l.diffPath,mouthKey:c,label:l.label}))}return a}const uc=3;function Vn(e){let t=0;const r=[];let n=!1,i=!1;const s=async()=>{if(!n){n=!0;try{for(;r.length>0;){const a=r.shift(),f=++t;await e(a.diffs,f,a)&&f===t&&a.onDisplayed?.(a.drawKey)}}finally{n=!1,r.length>0&&s()}}},o=()=>{i||(i=!0,queueMicrotask(()=>{i=!1,s()}))};return{enqueue(a,f,m){const l=r.findIndex(c=>c.drawKey===f);l>=0?r[l]={diffs:a,drawKey:f,onDisplayed:m}:(r.length>=uc&&(r.shift(),wt()?.onQueueSuperseded()),r.push({diffs:a,drawKey:f,onDisplayed:m})),o()},reset(){t+=1,r.length=0},isLatestSeq(a){return a===t},getLatestSeq(){return t}}}function dc(e,t=2){const r=[],n=new Set;let i=0,s=!1,o=0;const a=(m,l)=>`${m}|${l}`,f=async()=>{if(!s){s=!0;try{for(;i<t&&r.length>0;){const m=r.shift(),l=a(m.displayAtMs,m.drawKey);if(n.has(l))continue;n.add(l),i+=1;const c=o;try{await e(m)}finally{if(n.delete(l),i-=1,c!==o)return}}}finally{s=!1,r.length>0&&i<t&&f()}}};return{enqueue(m){const l=a(m.displayAtMs,m.drawKey);n.has(l)||r.some(c=>a(c.displayAtMs,c.drawKey)===l)||(r.push(m),f())},isQueuedOrInflight(m,l){const c=a(m,l);return n.has(c)?!0:r.some(h=>a(h.displayAtMs,h.drawKey)===c)},reset(){o+=1,r.length=0,n.clear(),i=0},pendingCount(){return r.length+i}}}function fc(){const e=new Map,t=r=>{r.bitmap.close()};return{has(r,n){return e.has(n)},markRendered(r,n,i,s,o){const a=e.get(n);a&&t(a),e.set(n,{displayAtMs:r,mouthKey:n,label:i,mouthPath:s,bitmap:o})},findForMouthKey(r){return e.get(r)??null},removeThrough(r){},pruneBefore(r){},reset(){for(const r of e.values())t(r);e.clear()},size(){return e.size}}}function mc(e,t,r,n,i,s){const o=Ns(t,r,n,i,er,s);if(o.length===0)return{ready:0,total:0};let a=0;for(const f of o)e.has(f.displayAtMs,f.mouthKey)&&(a+=1);return{ready:a,total:o.length}}function hc(e){const t=fc(),r=Nn(),n=new Set;let i="",s=null;const o=dc(async c=>{try{if(!e.supportsBufferedPlayback)return;const h=await e.compositePrefetchFrame(c.diffs,c.mouthKey);if(!h)return;t.markRendered(c.displayAtMs,c.mouthKey,c.label,c.mouthPath,h),wt()?.onBufferPrefetched()}finally{n.delete(c.mouthKey)}},na),a=c=>{for(const h of c)t.has(h.displayAtMs,h.mouthKey)||n.has(h.mouthKey)||o.isQueuedOrInflight(0,h.mouthKey)||(n.add(h.mouthKey),o.enqueue({...h,displayAtMs:0,drawKey:h.mouthKey,diffs:{mouthPath:h.mouthPath,expressionPath:null}}))},f=(c,h,v,E=Jr)=>{if(!e.supportsBufferedPlayback)return;const g=Math.max(0,h-er*4),R=Ns(c,g,h+E,v,er,r);a(R)},m=(c,h)=>{i=c,s=h},l=(c,h)=>!(i!==c||s!==h);return{reset(){t.reset(),o.reset(),n.clear(),Ge(r),i="",s=null,wt()?.onBufferReset()},setHoldPp(c){r.holdPp=c},markExternallyDisplayed(c,h){m(c.split("|")[0]??c,h)},warmupTick(c){e.supportsBufferedPlayback&&f(c.queue,0,c.availablePaths,Math.max(Jn,Jr))},isWarmupReady(c,h=Jn){if(!e.supportsBufferedPlayback)return!0;const{ready:v,total:E}=mc(t,c.queue,0,h,c.availablePaths,r);return E===0?!1:v/E>=ra},getBufferedFrameCount:()=>t.size(),tick(c){r.holdPp=c.playbackState.holdPp===!0;const h=wt();h?.onBufferTick(),f(c.queue,c.elapsedMs,c.availablePaths),t.pruneBefore(c.elapsedMs-Jr);const v=Un(c.queue,c.elapsedMs,c.availablePaths,r),E=Mr(v.diffPath),g=ir({mouthPath:v.diffPath,expressionPath:c.expressionPath},c.expressionDrawKey),R=()=>(m(E,c.expressionPath),h?.onBufferHit(),{usedBuffer:!0,underrun:!1,held:!0});if(l(E,c.expressionPath)||c.playbackState.lastDrawnKey===g)return R();const V=t.findForMouthKey(E,c.elapsedMs,er);return V&&c.expressionPath!=null?(h?.onBufferHit(),{usedBuffer:!1,underrun:!1,held:!1}):V?(e.blitBitmap(c.canvas,V.bitmap),m(V.mouthKey,c.expressionPath),c.playbackState.lastDrawnKey=g,c.onStatus({diffPath:V.mouthPath,label:V.label}),c.onDisplayed(g,V.mouthPath,V.label),h?.onBufferHit(),{usedBuffer:!0,underrun:!1,held:!1}):(h?.onBufferUnderrun(),{usedBuffer:!1,underrun:!0,held:!1})}}}const pc=`
5
+ `);St=ze.pop()??"";for(const Xe of ze)await Qt(Xe);if(Xt){St.trim()&&await Qt(St.trim()),we===N&&!re.signal.aborted&&H&&T.markStreamComplete(r);break}}}catch(mt){if(_t?.cancel(),g.onBodyIdleCancelled?.(),Kt(),re.signal.aborted||!H)return;console.error("[realtimeVoice] avatar_speak failed:",mt),e("error"),te()}finally{B===re&&(B=null)}},J=y=>{const A=co(y);if(!A){console.warn("[realtimeVoice] server message with no payload",y);return}const W=String(A.type??"unknown");switch(W!=="avatar_metadata"&&W!=="avatar_audio_chunk"&&W!=="avatar_lipsync"&&W!=="avatar_interrupt"&&W!=="error"&&console.debug("[realtimeVoice] server message",W,A),W){case"avatar_metadata":p(A);break;case"avatar_audio_chunk":C(A);break;case"avatar_lipsync":V(A);break;case"avatar_interrupt":me(A);break;case"error":{const re=String(A.message??"Voice session error");console.error("[realtimeVoice] server error:",re),e("error"),te();break}case"avatar_speak":K(A);break}},k=()=>v||(E=new so,v=new Qs.PipecatClient({transport:new _n.WebSocketTransport({mediaManager:E,serializer:new io,recorderSampleRate:Bn,playerSampleRate:Fn}),enableCam:!1,enableMic:!0,callbacks:{onBotReady:()=>{h=!0,e("idle"),te()},onDisconnected:()=>{h=!1,w()},onError:y=>{const A=typeof y=="object"&&y!==null&&"data"in y?String(y.data??y):String(y);console.error("[realtimeVoice]",A,y),e("error"),te()},onTransportStateChanged:y=>{y==="error"&&(e("error"),te())},onServerMessage:y=>{ee(y)},onUserStartedSpeaking:()=>{},onBotStartedSpeaking:()=>{Q(),U("bot_started")},onBotStoppedSpeaking:()=>{H&&be()},onUserTranscript:y=>{String(y.text??""),g.onUserTranscript?.(y.text,!!y.final)},onBotOutput:y=>{g.onBotOutput?.(y.text)}}}),v);return{setDeveloperToken:y=>{},setTtsEngineId:y=>{l=y,T.setStreamTtsEngineId(y)},getTtsEngineId:()=>l,speak:async(y,A)=>{const W=y.trim();if(W){if(!v||!h)throw new Error("Realtime voice is not connected. Call connect() first.");ie(),await v.sendText(W)}},speakWithReply:async(y,A)=>{throw new Error("speakWithReply is not available on the voice session; use AiTwin.speakWithReply()")},stop:()=>{B?.abort(),B=null,N+=1,Q(),ie(),e("idle"),te()},connect:async y=>{y&&(g={...g,...y});const A=ct(g.ttsEngineId,g.voiceId);if(A.ttsEngineId&&(l=A.ttsEngineId,T.setStreamTtsEngineId(l)),g={...g,ttsEngineId:l,...A.voiceId?{voiceId:A.voiceId}:{}},!g.authToken?.trim())throw new Error("Voice connect requires authToken (same JWT as SSE Authorization Bearer).");e("loading");const W=k();try{await W.initDevices()}catch(we){throw h=!1,e("idle"),te(),sr(we)?new Error("Microphone access denied"):we instanceof Error?we:new Error("Failed to initialize microphone")}const re=xs({...g,ttsEngineId:l});console.info("[realtimeVoice] connecting (avatar_audio_chunk RTVI):",re);try{await W.connect({wsUrl:re})}catch(we){if(h=!1,e("error"),te(),sr(we))throw e("idle"),new Error("Microphone access denied");const Re=we instanceof Error?we.message:"Realtime voice connect failed (WebSocket 101 only means upgrade OK — check authToken/origin/RTVI handshake)";throw new Error(`${Re} — ${re}`)}h=!0,e("idle"),te()},disconnect:async()=>{if(Ae(),X=!1,se=!1,S.length=0,x=!1,B?.abort(),B=null,N+=1,Q(),v)try{await v.disconnect()}catch(y){console.error("[realtimeVoice] disconnect failed:",y)}h=!1,w()},isConnected:()=>h,unlockAudio:async()=>{await T.primeAudioContext()},getVisemeQueue:()=>r,getWordQueue:()=>n,getFullVisemeQueue:()=>i,getFullWordQueue:()=>s,getSentenceEmotions:()=>a,getStreamMood:()=>u,getPlaybackElapsedMs:z,isSpeaking:()=>T.isSpeaking(),isWarmingUp:()=>T.isWarmingUp(),releaseWarmupHold:()=>T.releaseWarmupHold(),releasePlaybackHold:()=>T.releaseStartHold(),setLipsyncWarmupHold:(y,A)=>{A&&(He=A),T.setLipsyncWarmupHoldEnabled(y)},getVoiceStream:()=>T.getVoiceStream(),setMuted:y=>{T.setMuted(y)},isMuted:()=>T.isMuted(),setPlaybackSpeed:y=>{T.setPlaybackSpeed(y)},getPlaybackSpeed:()=>T.getPlaybackSpeed(),subscribe:y=>(F.add(y),()=>F.delete(y))}}function As(e,t,r){return{width:e.crop?.source_width??t,height:e.crop?.source_height??r}}function Rs(e,t){const r=e.crop;return{x:t?.source_x??r?.x??0,y:t?.source_y??r?.y??0,width:t?.source_w??r?.width??e.frame_width??0,height:t?.source_h??r?.height??e.frame_height??0}}function Ms(e){return e?(e.w??0)>0&&(e.h??0)>0:!1}function Wt(e,t){return`${e}/${t}_minus_sil.png`}const Ps=5;function zr(e){const t=e?.composite_threshold;if(typeof t=="number"&&t>0)return t;const r=e?.crop?.content_threshold;return typeof r=="number"&&r>0?r:Ps}const uo=["aa","E","I","O","U","PP","FF","DD","SS","TH","CH","RR","kk","nn"],gn=["t01_0.25","t02_0.50","t03_0.75"],fo=gn.length,di=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 fi(e,t){return`${e}__${t}`}function mi(e,t){return`pairs/${e}/${t}_minus_sil.png`}function Ht(e){return`${e}_minus_sil.png`}function Dn(e,t){if(t.has(e))return e;const r=/^pairs\/([^/]+)\//.exec(e);if(!r)return null;const n=r[1].split("__")[1];if(!n||n==="sil")return null;const i=Ht(n);return t.has(i)?i:null}function Cs(e,t){return e.filter(r=>t.has(r))}function mo(e,t,r){const n=Ln(e,t);return Cs(n,r).length>0}function Ln(e,t){if(e===t)return[];const r=[],n=fi(e,t);if(di.has(n)){for(const s of gn)r.push(mi(n,s));return r}const i=fi(t,e);if(di.has(i)){for(let s=fo-1;s>=0;s--)r.push(mi(i,gn[s]));return r}return[]}function ho(e){return e<16?[1]:e<24?[1]:e<35?[0,1,2]:[0,1,2]}function po(e,t){return ho(t).map(n=>e[n]).filter(n=>n!=null)}function go(e,t,r,n){if(n<=0)return 0;const s=Math.max(1,r-t)/n,o=e-t,a=Math.floor(o/s);return Math.min(n-1,Math.max(0,a))}function Bs(e,t,r){if(!r)return`${e}/${t}`;const n=t.split("/").pop()??t,i=n.includes(".")?n.slice(0,n.lastIndexOf(".")):n;return`${e}/${i}.bin`}const wo=[.32,.24,.16,.08,0],yo=wo.map(e=>`eyes_${e.toFixed(2)}`),vo=["eyes_0.32","eyes_0.16","eyes_0.00"],_o=["eyes_0.32","eyes_0.16","eyes_0.08","eyes_0.00"],Qe=2,bo=-20,Pr=16,Fs={fear:-20,anger:-20,sad:-10,neutral:0,love:0,happy:0,disgust:10};function ar(e){return`brow_${e}`}function Mt(e){return Fs[e]}function tt(e){return Math.max(bo,Math.min(Pr,e))}function So(e,t){if(e===t)return[];const r=e<t,n=r?Qe:-Qe,i=[];let s=e;if(s%Qe!==0){const o=r?Math.ceil(s/Qe)*Qe:Math.floor(s/Qe)*Qe,a=tt(o);if(r?a>=t:a<=t)return[t];s=a,i.push(s)}for(;;){const o=s+n;if(r?o>=t:o<=t){t!==s&&i.push(t);break}s=o,i.push(s)}return i}function hi(e){const t=tt(e);if(t%Qe===0)return[t];const r=Math.floor(t/Qe)*Qe,n=Math.min(Pr,r+Qe),i=tt(r);return t-i<=n-t?i===n?[i]:[i,n]:i===n?[n]:[n,i]}const To=["fear","anger","sad","neutral","love","happy","disgust"],ko={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 ot(e,t="neutral"){const r=String(e??"").trim().toLowerCase();return r?ko[r]??t:t}function Ds(e){return e===0?null:Wt(ar(e),"eyes_standard")}function Ls(e){return Ds(Mt(e))}const Eo={[-20]:"anger",[-10]:"sad",0:"neutral",10:"disgust"};function On(e,t){if(!e)return null;if(t(e))return e;const r=e.match(/^brow_(-?\d+)\/(eyes_[^/]+)_minus_sil\.png$/);if(r){const i=Number(r[1]),s=r[2];for(const a of hi(i)){if(a===i)continue;const f=Wt(ar(a),s);if(t(f))return f}const o=Eo[i];if(o){const a=Wt(o,s);if(t(a))return a}return null}const n=e.match(/^(fear|anger|sad|neutral|love|happy|disgust)\/(eyes_[^/]+)_minus_sil\.png$/);if(n){const i=n[1],s=n[2],o=Mt(i);for(const a of[o,...hi(o)]){const f=Wt(ar(a),s);if(t(f))return f}}return null}function pi(e,t){const r=ar(Mt(e));return!t||t==="eyes_standard"?Ls(e):e==="neutral"&&t==="eyes_standard"?null:Wt(r,t)}function xo(e,t){const r=[];for(const n of t)r.push(pi(e,n));for(let n=t.length-2;n>=0;n--)r.push(pi(e,t[n]));return r.push(Ls(e)),r}function Io(e){return Wt(ar(e),"eyes_standard")}function Ao(e,t){return So(e,t).map(Io)}const Ro=6;function Mo(e,t){for(const r of e)if(t>=r.wtime&&t<r.wtime+r.wduration)return r;return null}function Po(e){const t=tt(e);return t>=Pr?Pr:tt(t+Ro)}function Co(e,t,r){const n=tt(r);return Mo(t,e)?.emphasis?Po(n):n}function gi(e){if(!e)return 0;const t=e.match(/^brow_(-?\d+)\//);if(!t?.[1])return null;const r=Number.parseInt(t[1],10);return Number.isFinite(r)?tt(r):null}function et(e,t){return e+Math.random()*(t-e)}function wi(){return et(14,32)}function Bo(e){if(e)return{holdMinMs:10,holdMaxMs:18,closedExtraMs:0};const t=Math.random();return t<.18?{holdMinMs:38,holdMaxMs:62,closedExtraMs:et(40,90)}:t<.42?{holdMinMs:26,holdMaxMs:44,closedExtraMs:et(12,36)}:t<.82?{holdMinMs:14,holdMaxMs:28,closedExtraMs:Math.random()<.35?et(8,22):0}:{holdMinMs:10,holdMaxMs:18,closedExtraMs:0}}function yi(e,t){const r=et(e.holdMinMs,e.holdMaxMs);return t?r+e.closedExtraMs:r}function Fo(e={}){const{initialDelayMs:t=800+Math.random()*1200,intervalMinMs:r=2200,intervalMaxMs:n=5800,doubleBlinkChance:i=.18,doubleBlinkGapMinMs:s=120,doubleBlinkGapMaxMs:o=220,fullBlinkChance:a=.75,postEmotionChangeDelayMs:f=380,minDwellMs:m=550}=e;let u="neutral",l="neutral",h=0,v=0,E=0,g={kind:"idle",nextBlinkAt:performance.now()+t},P=null,j="__eyes_open__|neutral|brow:0";function F(B=u){j=`${P??"__eyes_open__"}|${B}|brow:${v}`}function S(B,N=u){P=B;const X=gi(B);X!=null?v=X:B==null&&(v=0),F(N)}function x(B){return Ds(B)}function L(B,N,X){const se=tt(N),de=tt(X);if(h=de,se===de){S(x(de));return}const ae=[...Ao(se,de),x(de)];g={kind:"browBlend",paths:ae,index:0,holdUntil:B+wi(),targetBrow:de},S(ae[0]??null)}function H(B,N){g={kind:"idle",nextBlinkAt:B+et(r,n)},l=N,S(x(h),N)}function G(B,N,X){const se=X?vo:Math.random()<a?yo:_o,de=Bo(X),ae=se.length-1;g={kind:"playing",paths:xo(N,se),index:0,holdUntil:B+yi(de,ae===0),after:"idle",blinkEmotion:N,pace:de,closedFrameIndex:ae},l=N,S(g.paths[0]??null,N)}function ne(B){if(g.kind==="browBlend"){for(;B>=g.holdUntil&&g.index<g.paths.length-1;)g.index+=1,g.holdUntil=B+wi();const N=g.paths[g.index]??null;S(N),B>=g.holdUntil&&g.index>=g.paths.length-1&&(v=g.targetBrow,h=g.targetBrow,S(x(g.targetBrow)),g={kind:"idle",nextBlinkAt:B+f});return}if(g.kind==="idle"){S(x(h),l),B>=g.nextBlinkAt&&G(B,l,!1);return}if(g.kind==="doublePause"){S(x(h),g.blinkEmotion),B>=g.resumeAt&&G(B,g.blinkEmotion,!0);return}if(g.kind==="playing"){for(;B>=g.holdUntil&&g.index<g.paths.length-1;)g.index+=1,g.holdUntil=B+yi(g.pace,g.index===g.closedFrameIndex);if(S(g.paths[g.index]??null,g.blinkEmotion),B>=g.holdUntil&&g.index>=g.paths.length-1){if(g.after==="resumeIdle"){H(B+f,u);return}if(g.after==="doublePause"){g={kind:"doublePause",resumeAt:B+et(s,o),blinkEmotion:g.blinkEmotion},S(x(h),g.blinkEmotion);return}if(g.after==="idle"&&Math.random()<i){g={kind:"doublePause",resumeAt:B+et(s,o),blinkEmotion:g.blinkEmotion},S(x(h),g.blinkEmotion);return}H(B,g.blinkEmotion)}}}return{advance:ne,setTargetEmotion(B,N){const X=ot(B,u);if(X===u)return;const se=performance.now();!N?.force&&m>0&&!(u==="neutral"&&X!=="neutral")&&se-E<m||(u=X,l=X,E=se)},setTargetEyebrow(B){const N=tt(B);if(N===h)return;const X=performance.now(),se=g.kind==="browBlend"?gi(P)??v:v;h=N,!(N===se&&g.kind!=="browBlend")&&(g.kind==="playing"||g.kind==="doublePause"||L(X,se,N))},snapToEmotion(B){const N=ot(B),X=Mt(N);u=N,l=N,h=X,v=X,E=performance.now(),g={kind:"idle",nextBlinkAt:performance.now()+et(4e3,7e3)},S(x(X),N)},getTargetEmotion:()=>u,getTargetEyebrow:()=>h,getExpressionPath:()=>P,getDrawKey:()=>j,reset(){u="neutral",l="neutral",h=0,v=0,E=0,H(performance.now()+et(r,n),"neutral")}}}function Do(){const e=document.createElement("video");e.muted=!0,e.playsInline=!0,e.preload="auto",e.setAttribute("playsinline",""),e.loop=!0;let t=!1,r=null,n="";const i=()=>{r&&(URL.revokeObjectURL(r),r=null)};return{async load(s){t&&n===s||(i(),t=!1,n=s,s.startsWith("blob:")&&(r=s),await new Promise((o,a)=>{const f=()=>{const m=e.duration;if(!Number.isFinite(m)||m<=0){a(new Error(`Idle video has invalid duration: ${s}`));return}t=!0,e.currentTime=0,o()};e.addEventListener("loadeddata",f,{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())},setLooping(s){e.loop=s},restart(){t&&(e.currentTime=0)},dispose(){e.pause(),e.removeAttribute("src"),e.load(),i(),t=!1,n=""}}}const Lo=50,Os=400;function Oo(e,t,r){return e.filter(n=>{const i=n.queueIndex??-1;return i>=t&&i<=r})}function No(e,t){const r=[];for(const n of e){const i=Oo(t,n.start_word,n.end_word);if(i.length===0)continue;const s=i[0],o=i[i.length-1];r.push({sentence:n,startMs:Math.max(0,s.wtime-Lo),endMs:o.wtime+o.wduration+Os})}return r.sort((n,i)=>n.startMs-i.startMs)}function Uo(e,t,r,n="neutral"){const i=ot(n);if(t.length===0)return i;if(r.length===0||e<r[0].wtime)return ot(t[0]?.emotion,i);const s=No(t,r);let o=null;for(const m of s)e>=m.startMs&&e<=m.endMs&&(o=m);if(o)return ot(o.sentence.emotion,i);const a=r[r.length-1],f=a.wtime+a.wduration;return e>f+Os?ot(t[t.length-1]?.emotion,i):i}function Nn(e,t,r,n,i=Ps){const s=new OffscreenCanvas(r,n),o=s.getContext("2d",{willReadFrequently:!0});o.drawImage(e,0,0,r,n);const a=o.getImageData(0,0,r,n),f=o.createImageData(r,n);f.data.set(a.data);const u=new OffscreenCanvas(r,n).getContext("2d",{willReadFrequently:!0});for(const l of t){u.clearRect(0,0,r,n),u.drawImage(l,0,0,r,n);const h=u.getImageData(0,0,r,n);for(let v=0;v<f.data.length;v+=4){const E=h.data[v],g=h.data[v+1],P=h.data[v+2];h.data[v+3]>0&&Math.max(E,g,P)>i&&(f.data[v]=E,f.data[v+1]=g,f.data[v+2]=P,f.data[v+3]=255)}}return o.putImageData(f,0,0),s}let It=null,$t=null;const Cr=new Map;function Vo(){It=null,$t=null,Cr.clear()}zi(Vo);function Wo(e){return e??$t??void 0}function Un(e){return new Promise((t,r)=>{const n=new Image;n.decoding="async",n.onload=()=>t(n),n.onerror=()=>r(new Error(`Failed to load image: ${e}`)),n.src=e})}async function jo(e){return Gt()?Qi(await vt(ir(),e??"")):Un(ir())}async function vi(e,t,r,n){const i=r?await Yi(e,n):await fetch(e).then(m=>{if(!m.ok)throw new Error(`Failed to load ${e}`);return m.json()}),s=i.sheets?.[0];if(!s?.path)throw new Error(`${e} has no sheets[0].path`);const o=r?await Ta(await vt(Bs(t,s.path,r),n??"")):await Un(`${t}/${s.path}`),a=new Map;for(const m of i.cells??[])m.path&&a.set(m.path,m);const f=new Map;for(const m of i.sheets??[])f.set(m.index,m);return{atlas:o,atlasMeta:i,cellByPath:a,sheetByIndex:f,diffBase:t}}async function wn(e){const t=Wo(e),r=Gt();if(r&&!t)throw new Error("Encrypted assets enabled but no key provided");if(It&&(!r||$t===(t??null))){const s=await It;return{...zt(s),visemePaths:[...s.viseme.cellByPath.keys()]}}$t=t??null,Cr.clear();const n=Gi();It=(async()=>{const s=await jo(t),o=await vi(Ki(),n,r,t);let a=null;try{a=await vi(qi(),n,r,t)}catch{a=null}return{sil:s,viseme:o,expression:a}})();const i=await It;return{...zt(i),visemePaths:[...i.viseme.cellByPath.keys()]}}async function Vn(e){if(await wn(e),!It)throw new Error("Assets not loaded");return It}function zt(e){return As(e.viseme.atlasMeta,e.sil.naturalWidth,e.sil.naturalHeight)}function Ho(e,t){const r=document.createElement("canvas");return r.width=t.w,r.height=t.h,r.getContext("2d",{willReadFrequently:!0}).drawImage(e.atlas,t.x,t.y,t.w,t.h,0,0,t.w,t.h),r}async function Br(e,t,r){const n=`${t.diffBase}::${r}`,i=Cr.get(n);if(i)return i;const s=(async()=>{const o=t.cellByPath.get(r);if(!o)throw new Error(`No atlas cell for path: ${r}`);const a=Rs(t.atlasMeta,o),f=zt(e);if(Ms(o)){const l=Ho(t,o),h=document.createElement("canvas");h.width=f.width,h.height=f.height;const v=h.getContext("2d");return v.fillStyle="#000",v.fillRect(0,0,f.width,f.height),v.drawImage(l,a.x,a.y),h}const m=`${t.diffBase}/${r}`,u=await Un(m);if(u.naturalWidth===f.width&&u.naturalHeight===f.height)return u;throw new Error(`Diff PNG wrong size for ${r}`)})();return Cr.set(n,s),s}async function nn(e,t,r,n,i,s){if(i){const{width:v,height:E}=i;if(s&&!s()||t.readyState<HTMLMediaElement.HAVE_CURRENT_DATA)return;const g=document.createElement("canvas");g.width=v,g.height=E;const P=g.getContext("2d");if(P.clearRect(0,0,v,E),P.drawImage(t,0,0,v,E),s&&!s())return;(e.width!==v||e.height!==E)&&(e.width=v,e.height=E);const j=e.getContext("2d");j.clearRect(0,0,v,E),j.drawImage(g,0,0);return}const o=await Vn(),a=zr(o.viseme.atlasMeta),{width:f,height:m}=zt(o);(e.width!==f||e.height!==m)&&(e.width=f,e.height=m);const u=[],l=e.getContext("2d");if(l.clearRect(0,0,f,m),t.readyState<HTMLMediaElement.HAVE_CURRENT_DATA){const v=o.sil;l.drawImage(v,0,0,f,m);return}if(u.length===0){l.drawImage(t,0,0,f,m);return}const h=Nn(t,u,f,m,a);l.drawImage(h,0,0)}async function yn(e,t,r){const n=await Vn($t??void 0),i=zr(n.viseme.atlasMeta),{width:s,height:o}=zt(n);(e.width!==s||e.height!==o)&&(e.width=s,e.height=o);const a=[];if(t.mouthPath){const u=new Set(n.viseme.cellByPath.keys()),l=Dn(t.mouthPath,u)??(u.has(t.mouthPath)?t.mouthPath:null);l&&a.push(await Br(n,n.viseme,l))}if(t.expressionPath&&n.expression){const u=On(t.expressionPath,l=>n.expression.cellByPath.has(l));u&&a.push(await Br(n,n.expression,u))}const f=e.getContext("2d");if(f.clearRect(0,0,s,o),a.length===0){f.drawImage(n.sil,0,0,s,o);return}const m=Nn(n.sil,a,s,o,i);f.drawImage(m,0,0)}async function $o(e,t){const r=await Vn($t??void 0),n=zr(r.viseme.atlasMeta),{width:i,height:s}=zt(r),o=[];if(e.mouthPath){const u=new Set(r.viseme.cellByPath.keys()),l=Dn(e.mouthPath,u)??(u.has(e.mouthPath)?e.mouthPath:null);l&&o.push(await Br(r,r.viseme,l))}if(e.expressionPath&&r.expression){const u=On(e.expressionPath,l=>r.expression.cellByPath.has(l));u&&o.push(await Br(r,r.expression,u))}const a=new OffscreenCanvas(i,s),f=a.getContext("2d");if(o.length===0)return f.drawImage(r.sil,0,0,i,s),a.transferToImageBitmap();const m=Nn(r.sil,o,i,s,n);return f.drawImage(m,0,0),a.transferToImageBitmap()}async function zo(e){await yn(e,{mouthPath:null,expressionPath:null})}const Er={fontFamily:"system-ui, -apple-system, sans-serif",fontSize:"clamp(0.875rem, 2.5vw, 1.125rem)",color:"rgba(255,255,255,0.85)"};function Go(e){return e.length===0?"":e.map(t=>t.word).join(" ")}function Ko(e){if(!e)return{enabled:!1,style:Er};const t=e===!0?{}:e;return{enabled:!0,style:{fontFamily:t.fontFamily??Er.fontFamily,fontSize:t.fontSize??Er.fontSize,color:t.color??Er.color}}}const qo={position:"absolute",bottom:0,left:0,right:0,display:"flex",justifyContent:"center",padding:"0.75rem 1rem",pointerEvents:"none"},Yo={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"},Qo={display:"-webkit-box",WebkitLineClamp:2,WebkitBoxOrient:"vertical",overflow:"hidden",maxWidth:"100%",margin:0};function Xo({text:e,style:t}){return M.jsx("div",{style:qo,"aria-live":"polite","aria-atomic":"true",children:M.jsx("div",{style:{...Yo,fontFamily:t.fontFamily,fontSize:t.fontSize,color:t.color},children:M.jsx("p",{style:Qo,children:e})})})}const Jo={inset:0,overflow:"hidden",pointerEvents:"none",position:"absolute",zIndex:3},Zo={filter:"blur(22px)",height:"100%",inset:0,objectFit:"cover",objectPosition:"top",position:"absolute",transform:"scale(1.08)",width:"100%"},ec={backdropFilter:"blur(10px)",WebkitBackdropFilter:"blur(10px)",inset:0,position:"absolute"};function tc({thumbnailUrl:e}){const[t,r]=d.useState(!1);d.useEffect(()=>{r(!1)},[e]);const n=!!e&&t;return M.jsxs("div",{style:Jo,"aria-hidden":!0,children:[e?M.jsx("img",{src:e,alt:"",style:{...Zo,opacity:n?1:0,transition:"opacity 0.45s ease"},onLoad:()=>r(!0),onError:()=>r(!1)}):null,M.jsx("div",{style:{...ec,background:n?"rgba(0, 0, 0, 0.28)":"rgba(10, 10, 11, 0.92)"}})]})}let Ns=null;function _i(e){Ns=e}function yt(){return Ns}function rc(e){return`${e.from}→${e.to}@${e.fromVtime}`}function bi(){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 nc(){let e=bi();const t=new Set,r=new Set,n=new Set;let i="",s=-1,o="";const a=()=>{e=bi(),t.clear(),r.clear(),n.clear(),i="",s=-1,o=""},f=u=>{t.add(u)},m=u=>{u&&n.add(u)};return{reset:a,onRafTickSpeaking(){e.rafTicksSpeaking+=1},onDrawDeduped(){e.rafTicksDeduped+=1},onDrawRequested(){e.drawsRequested+=1},onQueueSuperseded(){e.queueSuperseded+=1},onWorkerStale(){e.workerStale+=1},onTransitionSample(u,l){const h=rc(u);e.transitionFramesSampled+=1,h!==i&&(i=h,s=-1,o!==h&&(o=h,e.rifeFramesOmittedByGap+=u.omittedByGap)),l&&r.add(l),s>=0&&u.frameIdx>s+1&&(e.transitionFramesMissed+=u.frameIdx-s-1),s=u.frameIdx},onBufferTick(){e.bufferTicks+=1},onBufferHit(){e.bufferHits+=1},onBufferUnderrun(){e.bufferUnderruns+=1},onBufferPrefetched(){e.bufferPrefetched+=1},onBufferReset(){},onDrawDisplayed(u,l){if(e.drawsDisplayed+=1,u.transitionMeta){e.transitionFramesDisplayed+=1;const v=u.transitionMeta;f(v.fromVtime),f(v.toVtime),m(u.mouthPath);return}if(u.label.includes("→")){e.transitionFramesDisplayed+=1;return}const h=u.label.trim();if(!(!h||h==="sil")){for(const v of l)if(v.viseme===h&&u.elapsedMs>=v.vtime&&u.elapsedMs<v.vtime+v.vduration){f(v.vtime);break}}},snapshot(u,l){let h=0,v=0;for(const F of u)if(F.viseme!=="sil"){if(F.vtime>=l)break;h+=1,t.has(F.vtime)&&(v+=1)}const E=h>0?Math.round(v/h*100):100,g=e.queueSuperseded+e.workerStale+Math.max(0,e.drawsRequested-e.drawsDisplayed),P=h-v,j=e.bufferTicks>0?Math.round(e.bufferHits/e.bufferTicks*100):100;return{...e,bufferHitRate:j,renderLoss:g,visemeSlotsTotal:h,visemeSlotsCovered:v,visemeCoveragePct:E,transitionFramesUniqueSampled:r.size,transitionFramesUniquePainted:n.size,drawsDeduped:e.rafTicksDeduped,renderSkips:e.rafTicksDeduped+g,visemesShown:v,visemesSkipped:P,rifeTransitionFramesSkipped:e.transitionFramesMissed}}}}const Us=bn,ic=500,Si=500,sc=450,sn=.05,ac=100,oc=600,Vs="__sil__";function Ti(e){return e.lastDrawnKey?e.lastDrawnKey.split("|")[0]===Vs:!1}function Wn(){return{lastDrawnKey:""}}function je(e){e.lastDrawnKey="",e.transitionCache=void 0}function cc(e,t){if(t?.transitionCache&&t.transitionCache.queueLength===e.length)return t.transitionCache.transitions;const r=ws(e);return t&&(t.transitionCache={queueLength:e.length,transitions:r}),r}function lc(e,t){let r="sil";for(const n of e)n.viseme!=="sil"&&(t!=null&&n.vtime>t||(r=n.viseme));return r}function uc(e,t,r,n=120){if(r!=="sil")return r;const i=ks(e,t,n);return i!=="sil"?i:lc(e,t)}function dc(e,t){return e==="sil"?!1:t?mo(e,"sil",t):Ln(e,"sil").length>0}function fc(){return Us+oc}function Fr(e){return e??Vs}function jn(e,t,r,n,i=ac){if(e.length===0)return{diffPath:null,label:"sil"};if(t>=xt(e))return{diffPath:null,label:"sil"};const s=n?.holdPp===!0,o=cc(e,n),a=Ja(o,t,s);if(a){const u=ys(a.fromVtime,a.toVtime,a.from,a.to,s);if(t>=u.transStart&&t<u.transEnd){let l=Ln(a.from,a.to);r&&(l=Cs(l,r));const h=po(l,u.effectiveGapMs);if(h.length>0){const v=go(t,u.transStart,u.transEnd,h.length);return{diffPath:h[v]??h[h.length-1],label:`${a.from}→${a.to}`,transitionMeta:{from:a.from,to:a.to,fromVtime:a.fromVtime,toVtime:a.toVtime,frameIdx:v,frameCount:h.length,fullFrameCount:l.length,omittedByGap:Math.max(0,l.length-h.length)}}}return{diffPath:Ht(a.to),label:a.to}}}const f=Wr(e);let m=ms(f,t);return m==="sil"&&(m=ks(e,t,i)),m==="sil"?{diffPath:null,label:"sil"}:{diffPath:Ht(m),label:m}}function or(e,t){const r=t??Fr(e.expressionPath);return`${Fr(e.mouthPath)}|${r}`}function ki(e,t,r,n,i,s,o,a,f,m){const u=jn(t,r,f,s),l={mouthPath:u.diffPath,expressionPath:n},h=or(l,i),v=yt();if(u.transitionMeta&&v?.onTransitionSample(u.transitionMeta,u.diffPath),h===s.lastDrawnKey){v?.onDrawDeduped();return}v?.onDrawRequested(),a(u),s.lastDrawnKey=h,o(e,l,h,E=>{E===h&&(s.lastDrawnKey=h)})}function an(e,t,r,n,i,s,o=null,a=null){const f={mouthPath:a,expressionPath:t},m=o!=null?`|idle@${Math.round(o*1e3)}`:"",u=or(f,r)+m;!(o!=null)&&u===n.lastDrawnKey||(s(o!=null?t?"idle · blink":"idle":t?"blink":"sil"),i(e,f,u,h=>{h===u&&(n.lastDrawnKey=u)}))}function Ws(e,t,r,n,i=nr,s){if(r<=t||e.length===0)return[];const o=s??Wn(),a=[];let f="";for(let m=t;m<r;m+=i){const u=jn(e,m,n,o),l=Fr(u.diffPath);l!==f&&(f=l,a.push({displayAtMs:m,mouthPath:u.diffPath,mouthKey:l,label:u.label}))}return a}const mc=3;function Hn(e){let t=0;const r=[];let n=!1,i=!1;const s=async()=>{if(!n){n=!0;try{for(;r.length>0;){const a=r.shift(),f=++t;await e(a.diffs,f,a)&&f===t&&a.onDisplayed?.(a.drawKey)}}finally{n=!1,r.length>0&&s()}}},o=()=>{i||(i=!0,queueMicrotask(()=>{i=!1,s()}))};return{enqueue(a,f,m){const u=r.findIndex(l=>l.drawKey===f);u>=0?r[u]={diffs:a,drawKey:f,onDisplayed:m}:(r.length>=mc&&(r.shift(),yt()?.onQueueSuperseded()),r.push({diffs:a,drawKey:f,onDisplayed:m})),o()},reset(){t+=1,r.length=0},isLatestSeq(a){return a===t},getLatestSeq(){return t}}}function hc(e,t=2){const r=[],n=new Set;let i=0,s=!1,o=0;const a=(m,u)=>`${m}|${u}`,f=async()=>{if(!s){s=!0;try{for(;i<t&&r.length>0;){const m=r.shift(),u=a(m.displayAtMs,m.drawKey);if(n.has(u))continue;n.add(u),i+=1;const l=o;try{await e(m)}finally{if(n.delete(u),i-=1,l!==o)return}}}finally{s=!1,r.length>0&&i<t&&f()}}};return{enqueue(m){const u=a(m.displayAtMs,m.drawKey);n.has(u)||r.some(l=>a(l.displayAtMs,l.drawKey)===u)||(r.push(m),f())},isQueuedOrInflight(m,u){const l=a(m,u);return n.has(l)?!0:r.some(h=>a(h.displayAtMs,h.drawKey)===l)},reset(){o+=1,r.length=0,n.clear(),i=0},pendingCount(){return r.length+i}}}function pc(){const e=new Map,t=r=>{r.bitmap.close()};return{has(r,n){return e.has(n)},markRendered(r,n,i,s,o){const a=e.get(n);a&&t(a),e.set(n,{displayAtMs:r,mouthKey:n,label:i,mouthPath:s,bitmap:o})},findForMouthKey(r){return e.get(r)??null},removeThrough(r){},pruneBefore(r){},reset(){for(const r of e.values())t(r);e.clear()},size(){return e.size}}}function gc(e,t,r,n,i,s){const o=Ws(t,r,n,i,nr,s);if(o.length===0)return{ready:0,total:0};let a=0;for(const f of o)e.has(f.displayAtMs,f.mouthKey)&&(a+=1);return{ready:a,total:o.length}}function wc(e){const t=pc(),r=Wn(),n=new Set;let i="",s=null;const o=hc(async l=>{try{if(!e.supportsBufferedPlayback)return;const h=await e.compositePrefetchFrame(l.diffs,l.mouthKey);if(!h)return;t.markRendered(l.displayAtMs,l.mouthKey,l.label,l.mouthPath,h),yt()?.onBufferPrefetched()}finally{n.delete(l.mouthKey)}},aa),a=l=>{for(const h of l)t.has(h.displayAtMs,h.mouthKey)||n.has(h.mouthKey)||o.isQueuedOrInflight(0,h.mouthKey)||(n.add(h.mouthKey),o.enqueue({...h,displayAtMs:0,drawKey:h.mouthKey,diffs:{mouthPath:h.mouthPath,expressionPath:null}}))},f=(l,h,v,E=tn)=>{if(!e.supportsBufferedPlayback)return;const g=Math.max(0,h-nr*4),P=Ws(l,g,h+E,v,nr,r);a(P)},m=(l,h)=>{i=l,s=h},u=(l,h)=>!(i!==l||s!==h);return{reset(){t.reset(),o.reset(),n.clear(),je(r),i="",s=null,yt()?.onBufferReset()},setHoldPp(l){r.holdPp=l},markExternallyDisplayed(l,h){m(l.split("|")[0]??l,h)},warmupTick(l){e.supportsBufferedPlayback&&f(l.queue,0,l.availablePaths,Math.max(ti,tn))},isWarmupReady(l,h=ti){if(!e.supportsBufferedPlayback)return!0;const{ready:v,total:E}=gc(t,l.queue,0,h,l.availablePaths,r);return E===0?!1:v/E>=sa},getBufferedFrameCount:()=>t.size(),tick(l){r.holdPp=l.playbackState.holdPp===!0;const h=yt();h?.onBufferTick(),f(l.queue,l.elapsedMs,l.availablePaths),t.pruneBefore(l.elapsedMs-tn);const v=jn(l.queue,l.elapsedMs,l.availablePaths,r),E=Fr(v.diffPath),g=or({mouthPath:v.diffPath,expressionPath:l.expressionPath},l.expressionDrawKey),P=()=>(m(E,l.expressionPath),h?.onBufferHit(),{usedBuffer:!0,underrun:!1,held:!0});if(u(E,l.expressionPath)||l.playbackState.lastDrawnKey===g)return P();const j=t.findForMouthKey(E,l.elapsedMs,nr);return j&&l.expressionPath!=null?(h?.onBufferHit(),{usedBuffer:!1,underrun:!1,held:!1}):j?(e.blitBitmap(l.canvas,j.bitmap),m(j.mouthKey,l.expressionPath),l.playbackState.lastDrawnKey=g,l.onStatus({diffPath:j.mouthPath,label:j.label}),l.onDisplayed(g,j.mouthPath,j.label),h?.onBufferHit(),{usedBuffer:!0,underrun:!1,held:!1}):(h?.onBufferUnderrun(),{usedBuffer:!1,underrun:!0,held:!1})}}}const yc=`
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
- `,gc=`
33
+ `,vc=`
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) * color.a;
45
45
  finalColor = vec4(color.rgb, keep);
46
46
  }
47
- `;function Si(e=5){const t=new Te.Filter({glProgram:Te.GlProgram.from({vertex:pc,fragment:gc,name:"threshold-key-filter"}),resources:{thresholdUniforms:{uThreshold:{value:e/255,type:"f32"}}}});return t.setThreshold=r=>{t.resources.thresholdUniforms.uniforms.uThreshold=r/255},t.getThreshold=()=>Math.round(t.resources.thresholdUniforms.uniforms.uThreshold*255),t}function wc(e,t,r){return e>r||t>r}function yc(e){return e?e.getParameter(e.MAX_TEXTURE_SIZE):4096}function vc(e,t){return t!=null&&t>0?Math.floor(t):yc(e)}function _c(e,t){const r=document.createElement("canvas");r.width=t.w,r.height=t.h;const n=r.getContext("2d");if(!n)throw new Error("Failed to acquire 2d context for atlas cell crop");return n.drawImage(e,t.x,t.y,t.w,t.h,0,0,t.w,t.h),r}function Us(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 Ti(e,t,r,n,i){const s=r?await Gi(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,f=async(c,h)=>{const v=Ms(t,h,r),E=r?await va(await yt(v,i??"")):await Us(v);if(wc(E.width,E.height,n))return console.info(`[PixiVisemeCompositor] Sheet ${h} (${E.width}x${E.height}) exceeds MAX_TEXTURE_SIZE=${n}; using per-cell crops.`),{mode:"cells",bitmap:E};const g=Te.Texture.from(E);return g.source.scaleMode="nearest",{mode:"full",texture:g}};a.set(o.index,await f(o.index,o.path));for(const c of s.sheets??[])c.index!==o.index&&c.path&&a.set(c.index,await f(c.index,c.path));const m=new Map;for(const c of s.cells??[])c.path&&m.set(c.path,c);const l=new Map;for(const c of s.sheets??[])l.set(c.index,c);return{atlasMeta:s,cellByPath:m,sheetByIndex:l,diffBase:t,sheets:a}}async function bc(e,t={}){const r=new Te.Application;try{await r.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(y){throw r.destroy({removeView:!1}),y}if(r.renderer.type!==Te.RendererType.WEBGL)throw r.destroy({removeView:!1}),new Error("Pixi did not initialize a WebGL renderer");const n=vc(r.renderer.gl,t.maxTextureSize);let i=!1,s=!1,o=!1;const a=r.canvas,f=()=>{i=!0,!s&&!o&&(s=!0,t.onWebGlContextLost?.())};a.addEventListener("webglcontextlost",f);const m=new Te.Sprite(Te.Texture.EMPTY),l=new Te.Sprite(Te.Texture.EMPTY);l.visible=!1,l.alpha=0;const c=new Te.Sprite(Te.Texture.EMPTY),h=new Te.Sprite(Te.Texture.EMPTY),v=new Te.Sprite(Te.Texture.EMPTY);v.visible=!1;const E=Si(5),g=Si(5);c.filters=[E],h.filters=[g],r.stage.addChild(m),r.stage.addChild(l),r.stage.addChild(c),r.stage.addChild(h),r.stage.addChild(v);let R=null,V=null,B=null,S=null,x=null,O=null,W=null,G=842,ie=1264,M=null,U=5;const J=new Map;let Q=null,ue=null,ae=null;const Ae=ji(()=>{J.clear(),O=null,W=null,R=null,M=null}),ke=(y,u)=>{G=y,ie=u,r.renderer.resize(y,u),(e.width!==y||e.height!==u)&&(e.width=y,e.height=u)},re=()=>{c.visible=!1,h.visible=!1,c.texture=Te.Texture.EMPTY,h.texture=Te.Texture.EMPTY,Q=null,ue=null},Ke=()=>{x=null,l.visible=!1,l.alpha=0},T=()=>{m.visible=!0,m.width=G,m.height=ie,m.x=0,m.y=0},Z=()=>{l.width=G,l.height=ie,l.x=0,l.y=0},H=()=>{v.visible=!1,Ke(),R&&(m.texture=R,T())},j=()=>{x&&H()},de=y=>{if(o||i||!R){H();return}const u=Math.max(0,y);if(!V||u<=0){H();return}re(),v.visible=!1,m.texture=R,T(),l.texture=V,Z(),l.alpha=1,l.visible=!0,x={startMs:performance.now(),durationMs:u},oe()},X=(y=performance.now())=>{if(!x)return!1;if(o||i)return j(),!1;const u=(y-x.startMs)/Math.max(1,x.durationMs);if(u>=1)return H(),oe(),!1;const p=Math.min(1,Math.max(0,u)),b=p*p*(3-2*p);return l.alpha=1-b,l.visible=!0,oe(),!0},se=()=>{if(B){try{B.resource=null}catch{}B.destroy(),B=null}V&&(V.destroy(!1),V=null),S=null},fe=(y,u)=>{const p=y.cellByPath.get(u);if(!p||!Is(p))return null;const b=`${y.diffBase}::${u}`;let C=J.get(b);if(!C){const F=p.sheet??0,q=y.sheets.get(F);if(!q)return null;let L,$=!1;if(q.mode==="full")L=new Te.Texture({source:q.texture.source,frame:new Te.Rectangle(p.x,p.y,p.w,p.h)});else{const k=_c(q.bitmap,p);L=Te.Texture.from(k),L.source.scaleMode="nearest",$=!0}C={texture:L,ownsSource:$},J.set(b,C)}return{texture:C.texture,cell:p}},me=(y,u,p,b)=>{if(!b||!p)return y.visible=!1,y.texture=Te.Texture.EMPTY,!1;const C=fe(p,b);if(!C)return y.visible=!1,y.texture=Te.Texture.EMPTY,!1;const F=xs(p.atlasMeta,C.cell);return u.setThreshold(U),y.texture=C.texture,y.x=F.x,y.y=F.y,y.width=C.cell.w,y.height=C.cell.h,y.visible=!0,!0},K=y=>{if(!y||!O)return null;const u=M??new Set(O.cellByPath.keys());return Cn(y,u)??(u.has(y)?y:null)},te=y=>{v.visible=!1,H();const u=K(y.mouthPath),p=y.expressionPath&&W?Bn(y.expressionPath,b=>W.cellByPath.has(b)):null;u!==Q?(me(c,E,O,u),Q=u):u?c.visible=!0:c.visible=!1,p!==ue?(me(h,g,W,p),ue=p):p?h.visible=!0:h.visible=!1},oe=()=>{if(!(o||i||document.hidden))try{r.render()}catch{}};return{async loadAssets(y){if(o)return{width:G,height:ie,visemePaths:[]};const u=zt();if(u&&!y)throw new Error("Encrypted assets enabled but no key provided");const p=u?await ba(await yt(tr(),y??"")):await Us(tr());R&&R.destroy(!0),R=Te.Texture.from(p),R.source.scaleMode="linear";const b=Hi();O=await Ti($i(),b,u,n,y);try{W=await Ti(zi(),b,u,n,y)}catch(F){console.warn("[PixiVisemeCompositor] expression atlas unavailable:",F),W=null}const C=Es(O.atlasMeta,p.width,p.height);return ke(C.width,C.height),U=Wr(O.atlasMeta),E.setThreshold(U),g.setThreshold(U),M=new Set(O.cellByPath.keys()),J.clear(),H(),re(),oe(),{width:C.width,height:C.height,visemePaths:[...O.cellByPath.keys()]}},getVisemeAtlasPaths(){return M},drawLiveFrame(y){o||i||!R||(j(),te(y),oe())},drawIdleVideo(y,u){o||i||document.hidden||u&&!u()||y.readyState<HTMLMediaElement.HAVE_CURRENT_DATA||(x=null,re(),v.visible=!1,R&&(m.texture=R,T()),!V||S!==y?(se(),B=new Te.VideoSource({resource:y,autoPlay:!1,updateFPS:0}),B.autoUpdate=!1,V=new Te.Texture({source:B}),S=y):V.source.update(),l.texture=V,Z(),l.alpha=1,l.visible=!0,oe())},beginIdleToSilCrossfade:de,tickIdleToSilCrossfade:X,finishIdleToSilCrossfade:j,isIdleToSilCrossfading(){return x!=null},renderSilOnly(){o||i||!R||(re(),H(),oe())},blitBitmap(y){o||i||(j(),re(),ae&&(ae.destroy(!0),ae=null),ae=Te.Texture.from(y),v.texture=ae,v.visible=!0,v.x=0,v.y=0,v.width=G,v.height=ie,m.visible=!1,oe())},async compositePrefetchFrame(y){return null},renderFrame:oe,isContextLost(){return i},dispose(){if(o)return;o=!0,a.removeEventListener("webglcontextlost",f),Ae(),se(),ae&&(ae.destroy(!0),ae=null);for(const{texture:u,ownsSource:p}of J.values())u.destroy(p);J.clear(),R&&(R.destroy(!0),R=null);const y=u=>{u.mode==="full"?u.texture.destroy(!0):u.bitmap.close()};if(O)for(const u of O.sheets.values())y(u);if(W)for(const u of W.sheets.values())y(u);E.destroy(!0),g.destroy(!0),r.destroy({removeView:!1},{children:!0,texture:!0})}}}const ki=-1,Sr=1e5,Ei=new Map;async function Sc(e){let t=Ei.get(e);if(!t){const r=await fetch(e);if(!r.ok)throw new Error(`Failed to fetch worker script (${r.status}): ${e}`);const n=await r.blob();t=URL.createObjectURL(n),Ei.set(e,t)}return new Worker(t,{name:"visemeDiffPreview"})}function Tc(){return typeof Worker<"u"&&typeof OffscreenCanvas<"u"}function gn(e,t){(e.width!==t.width||e.height!==t.height)&&(e.width=t.width,e.height=t.height);const r=e.getContext("2d");r&&r.drawImage(t,0,0)}function xi(e,t){let r=0,n=null;const i=Vn(async(s,o)=>(await hn(),await pn(e,s),i.isLatestSeq(o)));return{usesWorker:!1,usesPixi:!1,async loadAssets(s){const o=await hn(s);return n=o.visemePaths?new Set(o.visemePaths):null,o},getVisemeAtlasPaths(){return n},async renderSilOnly(){r+=1,i.reset(),await jo(e)},drawLiveFrame(s,o,a,f){i.enqueue(o,a,f)},async compositePrefetchFrame(s,o){try{return await Wo(s)}catch{return null}},blitBitmap(s,o){gn(s,o)},drawIdleVideo(){},beginIdleToSilCrossfade(){},tickIdleToSilCrossfade(){return!1},finishIdleToSilCrossfade(){},isIdleToSilCrossfading(){return!1},supportsBufferedPlayback:!0,async renderViseme(s,o){r+=1;const a=r;t.onStatus?.(o),await pn(s,{mouthPath:jt(o),expressionPath:null})},dispose(){r+=1,i.reset()}}}function kc(e,t,r){let n=null,i=1,s=0,o=!1,a=!1,f=null;const m=new Map,l=new Map;let c=Sr;const h=Vn(async(B,S,x)=>(m.set(S,{drawKey:x.drawKey,onDisplayed:x.onDisplayed}),await R({type:"drawFrame",diffPath:B.mouthPath,expressionDiffPath:B.expressionPath,liveSeq:S},void 0,!0),!1)),v=B=>{if(B===ki){let O=-1,W;for(const[G,ie]of m)G>=O&&(O=G,W=ie);O>=0&&m.delete(O),W?.onDisplayed?.(W.drawKey);return}const S=-B,x=m.get(S);m.delete(S),x?.onDisplayed?.(x.drawKey)},E=new Map,g=(B,S)=>{a||!n||n.postMessage(B,[])},R=(B,S,x=!1)=>{if(a)return Promise.resolve();const O=i++;return new Promise((W,G)=>{E.set(O,{resolve:ie=>W(ie),reject:G,generation:typeof B.generation=="number"?B.generation:void 0,expectRenderDone:x}),g({...B,requestId:O})})},V=(async()=>{n=await Sc(r),n.onmessage=B=>{if(a)return;const S=B.data;if(S.type==="status"){t.onStatus?.(S.label);return}if(S.type==="frame"){if(S.generation<=-Sr){const W=-S.generation,G=l.get(W);l.delete(W),G?.resolve(S.bitmap);return}const O=S.generation<0;if(!O&&S.generation!==s){S.bitmap.close();return}if(O&&!(S.generation===ki)){const G=-S.generation;if(!h.isLatestSeq(G)){wt()?.onWorkerStale(),S.bitmap.close();return}}if(O&&t.shouldAcceptLiveFrame&&!t.shouldAcceptLiveFrame()){wt()?.onWorkerStale(),S.bitmap.close();return}gn(e,S.bitmap),S.bitmap.close(),O&&v(S.generation);return}const x=E.get(S.requestId);if(x)switch(S.type){case"ready":E.delete(S.requestId),x.resolve();break;case"loadAssetsDone":E.delete(S.requestId),f=S.visemePaths?.length?new Set(S.visemePaths):null,x.resolve({width:S.width,height:S.height,visemePaths:S.visemePaths});break;case"renderDone":if(x.expectRenderDone&&x.generation!=null&&S.generation!==x.generation)return;E.delete(S.requestId),x.resolve();break;case"renderAborted":E.delete(S.requestId),x.resolve();break;case"error":E.delete(S.requestId),t.onError?.(S.message),x.reject(new Error(S.message));break}},n.onerror=B=>{if(a)return;const S=B.message||"Worker error";t.onError?.(S);for(const[,x]of E)x.reject(new Error(S));E.clear()},await R({type:"init"}),o=!0})();return{usesWorker:!0,usesPixi:!1,async loadAssets(B){if(a)return{width:842,height:1264};if(await V,a)return{width:842,height:1264};if(!o)throw new Error("Worker init failed");return await R({type:"loadAssets",keyHex:B,urls:wa(Mt())})??{width:842,height:1264}},getVisemeAtlasPaths(){return f},async renderSilOnly(){if(a||(await V,a))return;s+=1,h.reset(),m.clear(),l.forEach(({resolve:S})=>S(null)),l.clear(),c=Sr;const B=s;await R({type:"cancelLiveDraws"}),await R({type:"renderSil",generation:B},void 0,!0)},drawLiveFrame(B,S,x,O){a||V.then(()=>{a||h.enqueue(S,x,O)})},compositePrefetchFrame(B,S){return a?Promise.resolve(null):V.then(()=>{if(a)return null;const x=++c;return new Promise(O=>{l.set(x,{resolve:O}),R({type:"drawFrame",diffPath:B.mouthPath,expressionDiffPath:B.expressionPath,liveSeq:x},void 0,!0).catch(()=>{l.delete(x),O(null)})})})},blitBitmap(B,S){gn(B,S)},drawIdleVideo(){},beginIdleToSilCrossfade(){},tickIdleToSilCrossfade(){return!1},finishIdleToSilCrossfade(){},isIdleToSilCrossfading(){return!1},supportsBufferedPlayback:!0,async renderViseme(B,S,x={}){if(a||(await V,a))return;s+=1,h.reset(),m.clear();const O=s;try{await R({type:"cancelLiveDraws"}),await R({type:"renderViseme",generation:O,to:S,from:x.from,transitionDurationMs:x.transitionDurationMs,gapMs:x.gapMs,threshold:x.threshold},void 0,!0)}catch(W){if(W?.name==="AbortError")return;throw W}},dispose(){if(!a){a=!0,s+=1,h.reset(),m.clear(),l.forEach(({resolve:B})=>B(null)),l.clear(),c=Sr;for(const[,B]of E)B.resolve();E.clear(),n?.terminate(),n=null}}}}async function Ec(e,t){const r=await bc(e,{onWebGlContextLost:t.onWebGlContextLost,maxTextureSize:t.pixiMaxTextureSize});let n=0,i=null,s=!1;const o=Vn(async(a,f)=>s?!1:t.shouldAcceptLiveFrame&&!t.shouldAcceptLiveFrame()?(wt()?.onWorkerStale(),!1):(r.drawLiveFrame(a),o.isLatestSeq(f)));return{usesWorker:!1,usesPixi:!0,async loadAssets(a){if(s)return{width:842,height:1264};const f=await r.loadAssets(a);return i=f.visemePaths?.length?new Set(f.visemePaths):null,f},getVisemeAtlasPaths(){return i},async renderSilOnly(){s||(n+=1,o.reset(),r.renderSilOnly())},drawLiveFrame(a,f,m,l){s||o.enqueue(f,m,l)},async compositePrefetchFrame(a,f){if(s)return null;try{return await r.compositePrefetchFrame(a)}catch{return null}},blitBitmap(a,f){s||t.shouldAcceptLiveFrame&&!t.shouldAcceptLiveFrame()||r.blitBitmap(f)},drawIdleVideo(a,f){s||r.drawIdleVideo(a,f)},beginIdleToSilCrossfade(a){s||r.beginIdleToSilCrossfade(a)},tickIdleToSilCrossfade(a){return s?!1:r.tickIdleToSilCrossfade(a)},finishIdleToSilCrossfade(){s||r.finishIdleToSilCrossfade()},isIdleToSilCrossfading(){return s?!1:r.isIdleToSilCrossfading()},supportsBufferedPlayback:!1,async renderViseme(a,f){if(s)return;n+=1;const m=n;o.reset(),t.onStatus?.(f),r.drawLiveFrame({mouthPath:jt(f),expressionPath:null})},dispose(){s||(s=!0,n+=1,o.reset(),r.dispose())}}}function Ii(e,t){if(!Tc())return xi(e,t);const r=Zs(t.workerScriptUrl);try{return kc(e,t,r)}catch{return xi(e,t)}}function xc(e,t={}){if(t.preferLegacyRenderer)return Ii(e,t);let r=null,n=!1,i=null,s=!1;const o=()=>r?Promise.resolve(r):(i||(i=(async()=>{try{const a=await Ec(e,t);if(s)throw a.dispose(),new Error("Renderer disposed during Pixi init");return n=!0,r=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),r=Ii(e,t),n=!1,r}})()),i);return{get usesWorker(){return r?.usesWorker??!1},get usesPixi(){return n},async loadAssets(a){return(await o()).loadAssets(a)},getVisemeAtlasPaths(){return r?.getVisemeAtlasPaths()??null},async renderSilOnly(){return(await o()).renderSilOnly()},drawLiveFrame(a,f,m,l){o().then(c=>{s||c.drawLiveFrame(a,f,m,l)})},async compositePrefetchFrame(a,f){return(await o()).compositePrefetchFrame(a,f)},blitBitmap(a,f){r&&r.blitBitmap(a,f)},drawIdleVideo(a,f){r?.usesPixi&&r.drawIdleVideo(a,f)},beginIdleToSilCrossfade(a){r?.beginIdleToSilCrossfade(a)},tickIdleToSilCrossfade(a){return r?.tickIdleToSilCrossfade(a)??!1},finishIdleToSilCrossfade(){r?.finishIdleToSilCrossfade()},isIdleToSilCrossfading(){return r?.isIdleToSilCrossfading()??!1},get supportsBufferedPlayback(){return r?.supportsBufferedPlayback??!1},async renderViseme(a,f,m){return(await o()).renderViseme(a,f,m)},dispose(){s=!0,i=null,r?.dispose(),r=null}}}class Ic extends Error{constructor(t,r){super(`${t} timed out after ${Math.round(r/1e3)}s`),this.name="LoadTimeoutError"}}function nn(e,t,r){return new Promise((n,i)=>{const s=globalThis.setTimeout(()=>{i(new Ic(r,t))},t);e.then(o=>{globalThis.clearTimeout(s),n(o)},o=>{globalThis.clearTimeout(s),i(o)})})}const Ac={overflow:"hidden",position:"relative",display:"inline-block",lineHeight:0},Rc={display:"block",maxWidth:"100%",height:"auto"},Mc={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 sn(e){return Li(e)?Rn:Oi(e)?Fr:An}function ot(e,t){return t?.isSpeaking()||t?.isWarmingUp()?t:e.isSpeaking()||e.isWarmingUp()?e:t?.isConnected()?t:e}const Vs=d.forwardRef(function({id:t,avatarId:r,faceId:n,assets:i,authToken:s,apiBase:o,ttsEngineId:a,voiceId:f,language:m,speakingRate:l=or,className:c,style:h,canvasStyle:v,onStatusChange:E,onDisplayStatus:g,onError:R,onReady:V,showErrorOverlay:B=!0,loadingThumbnailUrl:S,onUserTranscript:x,onBotOutput:O,onRealtimeLipsyncDebug:W,onFrameRenderStats:G,lipsyncBufferedPlayback:ie=!0,lipsyncPlaybackWarmupMs:M=1500,idleHandoffHoldMs:U=tc,disableIdleVideo:J=!1,fullBody:Q=!1,pixiMaxTextureSize:ue,captions:ae,userName:Ae,userEmail:ke,userContext:re},Ke){const T=d.useRef(null),Z=J||Q,H=d.useRef(null),j=d.useRef(null),de=d.useRef(ie);de.current=ie;const X=d.useRef(M);X.current=M;const se=d.useRef(U);se.current=U;const fe=d.useRef(Z);fe.current=Z;const me=d.useRef(0),K=d.useRef(Nn()),te=d.useRef(Po()),oe=d.useRef(!1),y=d.useRef(null),u=d.useRef(null),p=d.useRef(0),b=d.useRef(0),C=d.useRef(0),F=d.useRef(null),q=d.useRef(null),L=d.useRef(!1),$=d.useRef(!1),k=d.useRef(!1),ee=d.useRef(!1),pe=d.useRef(!1),Re=d.useRef("sil"),Me=d.useRef(0),_e=d.useRef(!1),ye=d.useRef(null),w=d.useRef(!1),[P,ne]=d.useState("idle"),[ge,we]=d.useState(null),[ve,Pe]=d.useState(!1),[Ue,Ve]=d.useState(!1),[vt,We]=d.useState(!1),[nt,Gt]=d.useState(),[Pt,cr]=d.useState({width:842,height:1264}),[Ct,mt]=d.useState(null),[lr,jr]=d.useState(0),[ur,_t]=d.useState(null),[Kt,Ft]=d.useState(null),[qt,Le]=d.useState(!1),je=d.useRef(null),He=d.useRef(null),bt=d.useRef(!1),Je=d.useRef(s??null),it=o?.trim()||ut,St=d.useRef(null),Be=d.useRef(null),{ttsEngineId:qe,voiceId:Bt}=d.useMemo(()=>{const _=lt(a,f),I=_.ttsEngineId??xt;return{ttsEngineId:I,voiceId:_.voiceId??sn(I)}},[a,f]),st=d.useCallback(_=>{const I=Li(_);K.current.holdPp=I,j.current?.setHoldPp(I)},[]),ht=d.useRef(!1),dr=d.useRef({width:842,height:1264}),Dt=d.useRef(null),Wn=d.useRef("sil"),Yt=d.useRef(""),pt=d.useMemo(()=>$o(ae),[ae]),Ze=d.useCallback(()=>{Yt.current="",mt(null)},[]);d.useEffect(()=>{pt.enabled||Ze()},[pt.enabled,Ze]);const Hr=d.useCallback(_=>{if(!pt.enabled)return;const I=_.isSpeaking(),N=_.isWarmingUp();if(!I||N){Yt.current&&Ze();return}const D=Ho(_.getWordQueue());if(!D){Yt.current&&Ze();return}D!==Yt.current&&(Yt.current=D,mt(D))},[pt.enabled,Ze]),fr=d.useRef(void 0),$r=d.useRef(new Map),jn=d.useRef(V),Hn=d.useRef(E),Fe=d.useRef(g),$n=d.useRef(R),zn=d.useRef(x),zr=d.useRef(O),mr=d.useRef(W),Gn=d.useRef(G),Lt=d.useRef(ec());jn.current=V,Hn.current=E,Fe.current=g,$n.current=R,zn.current=x,zr.current=O,mr.current=W,Gn.current=G,d.useEffect(()=>{const _=Lt.current;return wi(_),()=>wi(null)},[]);const Gr=d.useCallback(_=>{const I=lt(_?.ttsEngineId??a,_?.voiceId??f),N=I.ttsEngineId??Be.current?.ttsEngineId??xt,D=I.voiceId??Be.current?.voiceId??sn(N);return{ttsEngineId:N,voiceId:D}},[a,f]),at=d.useCallback(_=>{we(_),We(!0),$n.current?.(_)},[]),Qt=d.useCallback(_=>{ne(_),Hn.current?.(_)},[]),le=d.useRef(fn(Qt,it,{onLipsyncDebug:_=>mr.current?.(_),fullBody:Q})),be=d.useRef(null),hr=d.useRef(!1),Kn=d.useRef(()=>{});d.useEffect(()=>(le.current=fn(Qt,it,{onLipsyncDebug:_=>mr.current?.(_),fullBody:Q}),s&&le.current.setDeveloperToken(s),le.current.setTtsEngineId(qe),le.current.setMuted(hr.current),()=>{le.current.stop();const _=be.current;_&&(_.disconnect(),be.current=null)}),[Qt,it,Q]),d.useEffect(()=>{if(!Q||P!=="speaking"){Le(!1);return}const _=Ut(ii(le.current.getWordQueue(),le.current.getPlaybackElapsedMs(),I=>Ut(I)!=null));He.current=_,Ft(_),Le(!0)},[Q,P]);const qn=d.useCallback(()=>(be.current||(be.current=ks(Qt,{speakingRate:l,language:m,fullBody:Q,waitForBodyIdle:()=>je.current?.waitForIdleCycleEnd()??null,onBodyIdleCancelled:()=>je.current?.resumeIdleLoop(),onUserTranscript:(_,I)=>zn.current?.(_,I),onBotOutput:_=>zr.current?.(_),onLipsyncDebug:_=>mr.current?.(_)}),be.current.setTtsEngineId(qe),be.current.setMuted(hr.current),Kn.current(!0)),be.current),[Qt,l,m,qe,Q]),$e=d.useCallback(()=>{F.current!=null&&(clearTimeout(F.current),F.current=null)},[]),Ne=d.useCallback(()=>{q.current!=null&&(clearTimeout(q.current),q.current=null),k.current=!1},[]),Kr=d.useCallback(()=>{pe.current=!0,Ne(),ye.current?.setLooping(!1)},[Ne]),Qe=d.useCallback(()=>{pe.current=!1,ye.current?.setLooping(!0)},[]),Xt=d.useCallback(()=>{if(ee.current)return;const _=H.current;if(ee.current=!0,pe.current=!0,Ne(),L.current=!1,$.current=!1,!w.current||!ye.current){_?.renderSilOnly();return}const I=ye.current;I.setLooping(!1),I.setActive(!1);const N=I.getVideo();if(N.ended||Number.isFinite(N.currentTime)&&N.currentTime<=tn){try{(N.ended||N.currentTime>tn)&&(N.currentTime=0)}catch{}_?.renderSilOnly(),_?.finishIdleToSilCrossfade();return}if(_?.usesPixi){_.drawIdleVideo(N),_.beginIdleToSilCrossfade(vi);return}(async()=>{const Y=T.current;Y&&await en(Y,N,null,void 0,dr.current).catch(()=>{}),await new Promise(Ee=>setTimeout(Ee,vi)),ee.current&&await _?.renderSilOnly()})()},[Ne]),Yn=d.useCallback(()=>{if(!(!w.current||!ye.current)){if(ee.current=!1,H.current?.finishIdleToSilCrossfade(),H.current?.renderSilOnly(),Ne(),pe.current){k.current=!1;return}k.current=!0,q.current=setTimeout(()=>{if(q.current=null,ot(le.current,be.current).isSpeaking()){k.current=!1;return}if(L.current){k.current=!1;return}if(pe.current){k.current=!1;return}const _=ye.current;if(!_){k.current=!1;return}Qe(),_.setLooping(!0),_.restart(),_.setActive(!0);const I=_.getVideo();let N=!1;const D=()=>{N||(N=!0,I.removeEventListener("playing",Y),k.current=!1)},Y=()=>{D()};if(I.addEventListener("playing",Y,{once:!0}),I.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA&&!I.paused){D();return}setTimeout(D,300)},se.current)}},[Ne,Qe]),Ot=d.useCallback(()=>{if($e(),Fe.current?.("sil"),L.current=!1,ee.current=!1,!w.current||!ye.current){k.current=!1,Qe();return}Yn()},[$e,Yn,Qe]),qr=d.useCallback(async _=>{const I=b.current,N=H.current,D=T.current,Y=()=>{_?.fallbackOnly||(L.current=!1)};if(!N||!D||!ve){Y();return}if(ot(le.current,be.current).isSpeaking()){Y();return}if(_?.fallbackOnly){if(!L.current||(Ge(K.current),await N.renderSilOnly(),I!==b.current)||ot(le.current,be.current).isSpeaking())return;Ot();return}if(_i(K.current)){Ge(K.current),Ot();return}if(de.current&&N.supportsBufferedPlayback&&!_?.fallbackOnly){if(Ge(K.current),j.current?.reset(),await N.renderSilOnly(),I!==b.current||ot(le.current,be.current).isSpeaking())return;Ot();return}const Se=oc(ot(le.current,be.current).getVisemeQueue(),Me.current,Re.current),Ce=cc(Se,Dt.current);if(Ge(K.current),!Ce){if(await N.renderSilOnly(),I!==b.current||ot(le.current,be.current).isSpeaking())return;Ot();return}try{await N.renderViseme(D,"sil",{from:Se,transitionDurationMs:Ls})}catch(xe){if(xe?.name!=="AbortError")throw xe}if(I!==b.current){Y();return}if(ot(le.current,be.current).isSpeaking()){Y();return}Ot()},[ve,Ot]),Tt=d.useCallback(()=>{if($.current||L.current)return;$.current=!0,L.current=!0,$e();const _=b.current;qr().finally(()=>{$.current=!1}),F.current=setTimeout(()=>{F.current=null,_===b.current&&qr({fallbackOnly:!0})},lc())},[$e,qr]),Qn=d.useCallback(async()=>{const _=Math.floor(Date.now()/1e3);if(St.current&&_<St.current.expiresAt-60)return St.current.key;const I=Je.current??await Tr();Je.current=I,le.current.setDeveloperToken(I);const N=await ma(I,it);return St.current={key:N.value,expiresAt:N.expiresAt},N.value},[it]);d.useEffect(()=>{s&&(Je.current=s,le.current.setDeveloperToken(s))},[s]),d.useEffect(()=>{le.current.setTtsEngineId(qe),be.current?.setTtsEngineId(qe),Be.current&&(Be.current.ttsEngineId=qe),st(qe)},[qe,st]),d.useEffect(()=>{Be.current&&(Be.current.voiceId=Bt)},[Bt]);const Ye=d.useMemo(()=>Vi(r,n),[r,n]),$s=d.useMemo(()=>i?JSON.stringify(i):Ye?`face:${Ye}`:`id:${t??""}`,[i,Ye,t]),zs=d.useMemo(()=>{const _=S?.trim();return _||(Zn(Ye)??Zn(nt)??oa(i))},[S,Ye,nt,i]);return d.useEffect(()=>{if(!t&&!i&&!Ye){at("AiTwin requires `assets`, `avatarId`/`faceId`, or `id`");return}let _=!1;ht.current=!1,Pe(!1),Ve(!1),We(!1),Gt(Ye),we(null),Be.current=null,ye.current=null,w.current=!1;const I=T.current;if(!I)return;let N=null;return(async()=>{try{let D,Y,Ee,Se,Ce;if(i)D=i,Y=qe,Ee=Bt;else if(Ye)Fe.current?.("loadFace"),D=un(Ye),Y=qe,Ee=Bt;else{Fe.current?.("getAiTwin");const z=await nn(Ni(t),3e4,"getAiTwin");if(_)return;if(!z.faceId?.trim())throw new Error("getAiTwin returned no faceId");Gt(z.faceId.trim());const Ie=lt(a,f);Y=Ie.ttsEngineId??z.ttsEngineId,Ee=Ie.voiceId??z.voiceId??sn(Y),Se=bn(z),Ce=Sn(z),D=un(z.faceId)}Be.current={ttsEngineId:Y,voiceId:Ee,brainId:Se,brainUrl:Ce},Wi(D),ye.current=Co();const xe=!!(i&&!Rt(i));N=xc(I,{preferLegacyRenderer:xe,pixiMaxTextureSize:ue,onStatus:z=>{_||Fe.current?.(z)},onError:z=>{_||at(z)},shouldAcceptLiveFrame:()=>{if(oe.current)return!0;if(L.current)return!1;const z=ot(le.current,be.current);return z.isSpeaking()||z.isWarmingUp()},onWebGlContextLost:()=>{_||bt.current||(bt.current=!0,queueMicrotask(()=>{_||jr(z=>z+1)}))}}),H.current=N,j.current=hc(N),st(Y),bt.current=!1;const Oe=z=>{const Ie=()=>{if(!z||X.current<=0)return!1;const De=H.current;return De?de.current&&De.supportsBufferedPlayback?!0:De.usesPixi:!1};le.current.setLipsyncWarmupHold(z,Ie),be.current?.setLipsyncWarmupHold(z,Ie)};Kn.current=Oe,Oe(!0),Fe.current?.("auth");const et=Je.current??s??await nn(Tr(),3e4,"getAuthToken");if(_)return;Je.current=et,le.current.setDeveloperToken(et),le.current.setTtsEngineId(Y);const ce=zt()?await Qn():void 0;if(_)return;ce&&_t(ce),Fe.current?.("loadAssets");const he=await nn(N.loadAssets(ce),Q?18e4:24e4,"load face assets");if(!_&&he.width>0&&he.height>0&&(dr.current=he,cr(he)),_)return;Dt.current=N.getVisemeAtlasPaths(),ht.current=!0,Pe(!0),jn.current?.(),N.renderSilOnly().then(()=>{_||Fe.current?.("sil")}),(async()=>{try{if(fe.current){w.current=!1,Ve(!1),await N.renderSilOnly();return}const z=await Sa(ce);if(await ye.current.load(z),_||(w.current=!0,Ve(!0),Ge(K.current),await N.renderSilOnly(),_)||(await new Promise(De=>setTimeout(De,se.current)),_))return;ye.current.setActive(!0);const Ie=ye.current.getVideo();N.usesPixi?N.drawIdleVideo(Ie):await en(I,Ie,null,void 0,dr.current)}catch(z){if(_)return;w.current=!1,Ve(!1),console.warn("[AiTwin] Idle video unavailable:",z)}finally{_||(We(!0),Fe.current?.("idle"))}})()}catch(D){if(_)return;if(D instanceof kr){at(D.message);return}at(D instanceof Error?D.message:"Failed to load AI twin")}})(),()=>{_=!0,ye.current?.dispose(),N?.dispose(),H.current=null}},[$s,i,Ye,t,qe,Bt,a,f,s,ue,Z,Qn,at,lr,st]),d.useEffect(()=>{const _={current:!1},I=()=>{const N=T.current,D=H.current,Y=ot(le.current,be.current);if(!N||!D||!ve){p.current=requestAnimationFrame(I);return}if(document.hidden){ye.current?.setActive(!1),p.current=requestAnimationFrame(I);return}const Ee=Y.isSpeaking(),Se=Y.isWarmingUp(),Ce=Ee&&!_e.current,xe=_e.current&&!Ee;Ce&&($e(),Ne(),L.current=!1,$.current=!1,Ge(K.current),j.current?.reset(),Lt.current.reset(),fr.current=void 0,C.current=0,Re.current="sil",Me.current=0,Xt()),xe&&(te.current.reset(),ye.current?.setActive(!1),j.current?.reset(),D.finishIdleToSilCrossfade(),Ze(),He.current!==null&&(He.current=null,Ft(null)),pe.current=!1,Tt());const Oe=xe||L.current||k.current||ee.current,et=ie&&D.supportsBufferedPlayback;if(pe.current&&!Ee&&!Se&&!xe&&!L.current&&!k.current){if(ee.current){D.usesPixi&&D.isIdleToSilCrossfading()&&D.tickIdleToSilCrossfade(performance.now()),_e.current=Ee,p.current=requestAnimationFrame(I);return}if(w.current&&ye.current){const ce=ye.current.getVideo();if(ce.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA){const he=ce.duration,z=ce.currentTime,Ie=ce.ended||Number.isFinite(z)&&z<=tn,De=Number.isFinite(he)&&he>0&&Number.isFinite(z)?Math.max(0,(he-z)*1e3):Number.POSITIVE_INFINITY;if(Ie||De<=rc){Xt(),D.usesPixi&&D.isIdleToSilCrossfading()&&D.tickIdleToSilCrossfade(performance.now()),_e.current=Ee,p.current=requestAnimationFrame(I);return}}}}if(Se){if(Xt(),w.current&&ye.current?.setActive(!1),D.usesPixi&&D.isIdleToSilCrossfading()){D.tickIdleToSilCrossfade(performance.now()),Y.getVisemeQueue().length>0&&me.current===0&&(me.current=performance.now()),_e.current=Y.isSpeaking(),p.current=requestAnimationFrame(I);return}const ce=Y.getVisemeQueue();ce.length>0&&me.current===0&&(me.current=performance.now()),te.current.advance(performance.now());const he=te.current.getExpressionPath(),z=te.current.getDrawKey(),Ie={queue:ce,elapsedMs:0,expressionPath:he,expressionDrawKey:z,availablePaths:Dt.current};let De=!1;et&&j.current?(j.current.warmupTick(Ie),De=j.current.isWarmupReady(Ie,X.current)):D.usesPixi&&bi(N,ce,0,he,z,K.current,(Nt,pr,Yr,gr)=>{D.drawLiveFrame(Nt,pr,Yr,ze=>{gr?.(ze),Y.isWarmingUp()&&ze!==""&&!_i({lastDrawnKey:ze})&&(me.current=0,Y.releaseWarmupHold())})},Nt=>{Fe.current?.(Nt.label)},Dt.current);const gt=me.current>0&&performance.now()-me.current>ta;Fe.current?.(De?"buffer ready":"buffering lipsync…"),(De||gt)&&(me.current=0,Y.releaseWarmupHold()),Hr(Y),_e.current=Y.isSpeaking(),p.current=requestAnimationFrame(I);return}if(Ee){Xt(),w.current&&ye.current?.setActive(!1),D.usesPixi&&D.isIdleToSilCrossfading()&&D.finishIdleToSilCrossfade();const ce=Y.getVisemeQueue(),he=Y.getPlaybackElapsedMs();Za(ce,he),Me.current=he;const z=ce.length>0?ar(ce,he):"sil";z!=="sil"&&(Re.current=z);const Ie=Lo(he,Y.getSentenceEmotions(),Y.getWordQueue(),Y.getStreamMood());if(Q){const ze=Ut(ii(Y.getWordQueue(),he,Jt=>Ut(Jt)!=null));ze!==He.current&&(He.current=ze,Ft(ze))}te.current.setTargetEmotion(Ie),te.current.setTargetEyebrow(Ro(he,Y.getWordQueue(),At(Ie))),te.current.advance(performance.now());const De=te.current.getExpressionPath(),gt=te.current.getDrawKey(),Nt=(ze,Jt,Zt,Qr)=>{const Xn={label:Wn.current,elapsedMs:he,mouthPath:Jt.mouthPath,transitionMeta:fr.current};$r.current.set(Zt,Xn),j.current?.markExternallyDisplayed(Zt,De),D.drawLiveFrame(ze,Jt,Zt,wr=>{const Gs=$r.current.get(wr)??Xn;$r.current.delete(wr),Lt.current.onDrawDisplayed(Gs,ce),j.current?.markExternallyDisplayed(wr,De),Qr?.(wr)})},pr=ze=>{Wn.current=ze.label,fr.current=ze.transitionMeta,Fe.current?.(ze.label)},Yr=ie&&D.supportsBufferedPlayback;let gr=!1;Yr&&j.current&&(gr=j.current.tick({canvas:N,queue:ce,elapsedMs:he,expressionPath:De,expressionDrawKey:gt,playbackState:K.current,availablePaths:Dt.current,onStatus:pr,onDisplayed:(Jt,Zt,Qr)=>{Lt.current.onDrawDisplayed({label:Qr,elapsedMs:he,mouthPath:Zt,transitionMeta:fr.current},ce)}}).usedBuffer),gr||bi(N,ce,he,De,gt,K.current,Nt,pr,Dt.current),Lt.current.onRafTickSpeaking(),Gn.current?.(Lt.current.snapshot(ce,he))}else if(!Oe&&oe.current){ye.current?.setActive(!1),te.current.advance(performance.now());const ce=te.current.getExpressionPath(),he=te.current.getDrawKey();rn(N,ce,he,K.current,(z,Ie,De,gt)=>D.drawLiveFrame(z,Ie,De,gt),z=>{if(u.current){Fe.current?.(u.current);return}const Ie=te.current.getTargetEmotion();Fe.current?.(z==="sil"||z==="blink"?`${Ie}${z==="blink"?" · blink":""}`:z)},null,y.current)}else if(!Oe&&w.current&&ye.current){const ce=ye.current,he=ce.getVideo();if(he.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA){ce.setActive(!0);const z=()=>!Y.isSpeaking()&&!L.current&&!k.current&&!oe.current;D.usesPixi?(D.drawIdleVideo(he,z),z()&&Fe.current?.("idle")):_.current||(_.current=!0,en(N,he,null,void 0,dr.current,z).then(()=>Fe.current?.("idle")).finally(()=>{_.current=!1}))}else rn(N,null,"__sil__",K.current,(z,Ie,De,gt)=>D.drawLiveFrame(z,Ie,De,gt),z=>Fe.current?.(z))}else Oe||rn(N,null,"__sil__",K.current,(ce,he,z,Ie)=>D.drawLiveFrame(ce,he,z,Ie),ce=>Fe.current?.(ce));pt.enabled&&Hr(Y),_e.current=Ee,p.current=requestAnimationFrame(I)};return p.current=requestAnimationFrame(I),()=>{cancelAnimationFrame(p.current),$e(),Ne(),le.current.stop(),be.current?.stop()}},[ve,Ue,Tt,$e,Ne,Xt,Hr,Ze,pt.enabled,Q]),d.useImperativeHandle(Ke,()=>({speakText:async(_,I)=>{const N=_.trim();if(!N)return;const D=H.current;if(!D||!ht.current&&!ve)throw new Error("AI twin is not ready");const{ttsEngineId:Y,voiceId:Ee}=Gr(I);we(null),Ze(),b.current+=1,$e(),Ne(),L.current=!1,$.current=!1,Re.current="sil",Me.current=0,Ge(K.current),st(Y),oe.current=!1,y.current=null,u.current=null,te.current.reset(),_e.current=!1,Kr(),ee.current=!1,D.finishIdleToSilCrossfade();try{const Se=I?.fullBody??Q,Ce=je.current,xe=!!(Se&&Ce),Oe=xe?Ce.waitForIdleCycleEnd():null,et=le.current.speak(N,{voiceId:Ee,speakingRate:I?.speakingRate??l,ttsEngineId:Y,language:I?.language??m,fullBody:Se,delayPlayback:xe});if(Oe){try{await Promise.race([Oe.promise,et.then(()=>new Promise(()=>{}))])}catch(ce){throw Oe.cancel(),le.current.releasePlaybackHold(),Ce.resumeIdleLoop(),ce}le.current.releasePlaybackHold()}await et}catch(Se){throw Qe(),ee.current=!1,D.finishIdleToSilCrossfade(),Tt(),at(Se instanceof Error?Se.message:"TTS failed"),Se}},speakWithReply:async(_,I)=>{const N=_.trim();if(!N)return{displayText:"",spokenText:""};const D=H.current;if(!D||!ht.current&&!ve)throw new Error("AI twin is not ready");const{ttsEngineId:Y,voiceId:Ee}=Gr(I);we(null),Ze(),b.current+=1,$e(),Ne(),L.current=!1,$.current=!1,Re.current="sil",Me.current=0,Ge(K.current),st(Y),oe.current=!1,y.current=null,u.current=null,te.current.reset(),_e.current=!1,Kr(),ee.current=!1,D.finishIdleToSilCrossfade();const Se=I?.brainId?.trim()||Be.current?.brainId?.trim()||void 0,Ce=I?.brainUrl?.trim()||Be.current?.brainUrl?.trim()||void 0;try{const xe=I?.fullBody??Q,Oe=je.current,et=!!(xe&&Oe),ce=et?Oe.waitForIdleCycleEnd():null,he=le.current.speakWithReply(N,{...I,voiceId:Ee,speakingRate:I?.speakingRate??l,ttsEngineId:Y,language:I?.language??m,fullBody:xe,delayPlayback:et,brainId:Se,brainUrl:Ce,userName:I?.userName?.trim()||Ae?.trim()||void 0,userEmail:I?.userEmail?.trim()||ke?.trim()||void 0,userContext:I?.userContext?.trim()||re?.trim()||void 0,onDisplayText:z=>{I?.onDisplayText?.(z),zr.current?.(z)}});if(ce){try{await Promise.race([ce.promise,he.then(()=>new Promise(()=>{}))])}catch(z){throw ce.cancel(),le.current.releasePlaybackHold(),Oe.resumeIdleLoop(),z}le.current.releasePlaybackHold()}return await he}catch(xe){throw Qe(),ee.current=!1,D.finishIdleToSilCrossfade(),Tt(),at(xe instanceof Error?xe.message:"speakWithReply failed"),xe}},stop:()=>{b.current+=1,$e(),Ne(),L.current=!1,$.current=!1,ee.current=!1,Qe(),H.current?.finishIdleToSilCrossfade(),le.current.stop(),be.current?.stop(),Ge(K.current),j.current?.reset(),me.current=0,_e.current=!1,Ze(),Tt()},setTtsEngineId:_=>{le.current.setTtsEngineId(_),be.current?.setTtsEngineId(_),Be.current&&(Be.current.ttsEngineId=_),st(_)},renderViseme:async(_,I)=>{const N=H.current,D=T.current;if(!N||!D||!ht.current)throw new Error("AI twin is not ready");await N.renderViseme(D,_,{from:I?.from,transitionDurationMs:I?.transitionDurationMs,gapMs:I?.gapMs,onStatus:Y=>Fe.current?.(Y)})},setEmotion:_=>{if(!ht.current)throw new Error("AI twin is not ready");const I=H.current,N=T.current;if(!I||!N)throw new Error("AI twin is not ready");b.current+=1,$e(),Ne(),L.current=!1,$.current=!1,k.current=!1,ee.current=!1,Qe(),le.current.stop(),be.current?.stop(),Ge(K.current),j.current?.reset(),me.current=0,_e.current=!1,I.finishIdleToSilCrossfade(),ye.current?.setActive(!1);const D=ct(_);oe.current=!0,y.current=null,u.current=null,te.current.snapToEmotion(D);const Y=te.current.getExpressionPath(),Ee=te.current.getDrawKey(),Se={mouthPath:null,expressionPath:Y},Ce=ir(Se,Ee);K.current.lastDrawnKey="",I.drawLiveFrame(N,Se,Ce,Oe=>{Oe===Ce&&(K.current.lastDrawnKey=Ce)});const xe=At(D);Fe.current?.(Y?`${D} · brow ${xe>0?"+":""}${xe}`:`${D} · brow 0 (sil base)`)},getEmotion:()=>oe.current?te.current.getTargetEmotion():null,clearEmotionPreview:()=>{oe.current=!1,y.current=null,u.current=null,te.current.reset(),Ge(K.current),Fe.current?.("idle")},setViseme:_=>{if(!ht.current)throw new Error("AI twin is not ready");const I=H.current,N=T.current;if(!I||!N)throw new Error("AI twin is not ready");b.current+=1,$e(),Ne(),L.current=!1,$.current=!1,k.current=!1,ee.current=!1,Qe(),le.current.stop(),be.current?.stop(),Ge(K.current),j.current?.reset(),me.current=0,_e.current=!1,I.finishIdleToSilCrossfade(),ye.current?.setActive(!1);const D=Dr(_);oe.current=!0,u.current=D,y.current=D==="sil"?null:jt(D),te.current.snapToEmotion("neutral");const Y=te.current.getExpressionPath(),Ee=te.current.getDrawKey(),Ce={mouthPath:y.current,expressionPath:Y},xe=ir(Ce,Ee);K.current.lastDrawnKey="",I.drawLiveFrame(N,Ce,xe,Oe=>{Oe===xe&&(K.current.lastDrawnKey=xe)}),Fe.current?.(D)},getViseme:()=>oe.current?u.current:null,isReady:()=>ht.current,getStatus:()=>P,getWordQueue:()=>le.current.getWordQueue(),connect:async(_={})=>{we(null);try{let I=_.authToken?.trim();I||(I=Je.current??s??await Tr(),Je.current=I);const N=lt(_.ttsEngineId??a,_.voiceId??f),D=N.voiceId??Be.current?.voiceId,Y=_.brainId?.trim()||_.personaId?.trim()||Be.current?.brainId,Ee=_.brainUrl?.trim()||Be.current?.brainUrl,Se=N.ttsEngineId??Be.current?.ttsEngineId??qe,Ce=qn();Se&&Ce.setTtsEngineId(Se),Se&&st(Se),await Ce.unlockAudio(),await Ce.connect({..._,apiBase:_.apiBase?.trim()||it,authToken:I,voiceId:D,brainId:Y,brainUrl:Ee,ttsEngineId:Se,speakingRate:_.speakingRate??l,language:_.language??m,fullBody:_.fullBody??Q,userName:_.userName?.trim()||Ae?.trim()||void 0,userEmail:_.userEmail?.trim()||ke?.trim()||void 0,userContext:_.userContext?.trim()||re?.trim()||void 0})}catch(I){throw rr(I)||at(I instanceof Error?I.message:"Voice connect failed"),I}},disconnect:async()=>{const _=be.current;_&&(b.current+=1,$e(),Ne(),L.current=!1,$.current=!1,ee.current=!1,Qe(),H.current?.finishIdleToSilCrossfade(),Ge(K.current),j.current?.reset(),me.current=0,_e.current=!1,await _.disconnect(),Tt())},isConnected:()=>be.current?.isConnected()??!1,getVoiceStream:()=>be.current?.getVoiceStream()??le.current?.getVoiceStream()??null,setMuted:_=>{hr.current=_,le.current?.setMuted(_),be.current?.setMuted(_)},isMuted:()=>hr.current,getBrainId:()=>Be.current?.brainId?.trim()||null,getPersonaId:()=>Be.current?.brainId?.trim()||null,getBrainUrl:()=>Be.current?.brainUrl?.trim()||null}),[ve,l,m,s,Ae,ke,re,qe,Bt,$e,Ne,Tt,Kr,Qe,at,Gr,qn,st,P,it]),A.jsxs("div",{className:c,style:{...Ac,...h},children:[A.jsx("canvas",{ref:T,width:Pt.width,height:Pt.height,style:{...Rc,...v},"aria-label":t?`AI twin ${t}`:"AI twin face"}),Q&&ve&&ur&&(nt||Ye)?A.jsx(Aa,{ref:je,poseSynced:qt,gesturesBase:Xi(nt||Ye),keyHex:ur,status:P,activePose:Kt}):null,!vt&&!ge?A.jsx(Jo,{thumbnailUrl:zs}):null,B&&ge?A.jsx("div",{style:Mc,children:ge}):null,pt.enabled&&Ct?A.jsx(qo,{text:Ct,style:pt.style},Ct):null]})});function Pc({muted:e}){return e?A.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none","aria-hidden":!0,children:[A.jsx("path",{d:"M11 5 6.5 9H3v6h3.5L11 19V5Z",fill:"currentColor"}),A.jsx("path",{d:"m16 9.5 5 5m0-5-5 5",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round"})]}):A.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none","aria-hidden":!0,children:[A.jsx("path",{d:"M11 5 6.5 9H3v6h3.5L11 19V5Z",fill:"currentColor"}),A.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 Cc(){return A.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":!0,children:A.jsx("path",{d:"M8 5.5v13l11-6.5L8 5.5Z"})})}function Fc(){return A.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":!0,children:A.jsx("rect",{x:"6",y:"6",width:"12",height:"12",rx:"1.5"})})}function Bc(){return A.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none","aria-hidden":!0,children:A.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 Dc(){return A.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none","aria-hidden":!0,children:A.jsx("path",{d:"M15 6 9 12l6 6",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}function Lc(){return A.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none","aria-hidden":!0,children:A.jsx("path",{d:"M12 19V5m0 0-6 6m6-6 6 6",stroke:"currentColor",strokeWidth:"2.25",strokeLinecap:"round",strokeLinejoin:"round"})})}function Oc(){return A.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":!0,children:A.jsx("rect",{x:"6",y:"6",width:"12",height:"12",rx:"2"})})}function Ai({className:e}){return A.jsx("span",{className:e??"aitwin-widget__spinner","aria-hidden":!0,children:A.jsx("svg",{viewBox:"0 0 24 24",fill:"none",children:A.jsx("circle",{cx:"12",cy:"12",r:"9",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeDasharray:"40 20"})})})}function Nc({muted:e,onToggle:t}){return A.jsx("button",{type:"button",className:"aitwin-widget__mute",onClick:t,"aria-label":e?"Unmute":"Mute","aria-pressed":e,children:A.jsx(Pc,{muted:e})})}function Uc(e){const t=e.status==="speaking",r=e.connecting||e.textSending||e.status==="loading"||t,n=e.connected?"End":"Talk",i=["aitwin-widget__action","aitwin-widget__action--primary",e.connecting?"aitwin-widget__action--connecting":""].filter(Boolean).join(" ");return A.jsxs("div",{className:e.textMode?"aitwin-widget__controls aitwin-widget__controls--text":"aitwin-widget__controls",children:[e.textMode?A.jsxs("form",{className:"aitwin-widget__composer",onSubmit:s=>{if(s.preventDefault(),t){e.onStopSpeech();return}e.onSendText()},children:[A.jsx("button",{type:"button",className:"aitwin-widget__composer-back",onClick:e.onTextMode,disabled:e.textSending&&!t,"aria-label":"Back",children:A.jsx(Dc,{})}),A.jsx("input",{type:"text",className:"aitwin-widget__composer-input",value:e.textDraft,onChange:s=>e.onTextDraftChange(s.target.value),placeholder:t?"Speaking…":e.textSending?"Getting reply...":"Type a message...",autoComplete:"off",disabled:!e.ready||r&&!t,autoFocus:!0}),t?A.jsx("button",{type:"button",className:"aitwin-widget__composer-send aitwin-widget__composer-send--stop",onClick:e.onStopSpeech,"aria-label":"Stop",children:A.jsx(Oc,{})}):A.jsx("button",{type:"submit",className:"aitwin-widget__composer-send",disabled:!e.ready||r||!e.textDraft.trim()&&!e.textSending,"aria-label":"Send","aria-busy":e.textSending,children:e.textSending?A.jsx(Ai,{className:"aitwin-widget__spinner aitwin-widget__spinner--on-accent"}):A.jsx(Lc,{})})]}):A.jsxs("div",{className:"aitwin-widget__actions",children:[A.jsxs("button",{type:"button",className:i,onClick:e.onTalk,disabled:!e.ready||e.connecting||e.textSending,"aria-busy":e.connecting,"aria-label":e.connecting?"Connecting":n,children:[e.connecting?A.jsx(Ai,{className:"aitwin-widget__spinner aitwin-widget__spinner--on-accent"}):e.connected?A.jsx(Fc,{}):A.jsx(Cc,{}),A.jsx("span",{children:n})]}),A.jsxs("button",{type:"button",className:"aitwin-widget__action",onClick:e.onTextMode,disabled:!e.ready||e.connecting||e.textSending,"aria-pressed":!1,children:[A.jsx(Bc,{}),A.jsx("span",{children:"Text"})]})]}),e.error?A.jsx("p",{className:"aitwin-widget__controls-error",role:"alert",children:e.error}):null]})}const Ri=97,Vc=3500;function Wc(e,t){const r=Math.max(0,e),n=1-Math.exp(-r/Vc);return Math.min(Ri,Math.round(n*Ri))}function jc(e){const[t,r]=d.useState(null),[n,i]=d.useState(()=>Date.now());return d.useEffect(()=>{if(!e){r(null);return}const s=Date.now();r(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:Wc(n-t):100}const Hc="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 $c({className:e="aitwin-widget__logo",strokeWidth:t=15,durationMs:r=2600,delayMs:n=0,loop:i=!1}){return A.jsx("svg",{viewBox:"0 0 1080 1080",className:e,role:"img","aria-label":"AITWIN logo",children:A.jsx("path",{className:i?"aitwin-widget__logo-draw aitwin-widget__logo-draw--loop":"aitwin-widget__logo-draw",d:Hc,fill:"none",stroke:"currentColor",strokeWidth:t,strokeMiterlimit:10,pathLength:1,style:{animationDuration:`${r}ms`,animationDelay:`${n}ms`}})})}function zc({progress:e}){const t=Math.max(0,Math.min(100,Math.round(e)));return A.jsx("div",{className:"aitwin-widget__face-loading","aria-live":"polite","aria-label":`Loading ${t} percent`,children:A.jsxs("div",{className:"aitwin-widget__face-loading-content",children:[A.jsx($c,{className:"aitwin-widget__logo",loop:!0,durationMs:2600}),A.jsxs("div",{className:"aitwin-widget__face-loading-bar-wrap",children:[A.jsx("div",{role:"progressbar","aria-valuenow":t,"aria-valuemin":0,"aria-valuemax":100,className:"aitwin-widget__face-loading-track",children:A.jsx("div",{className:"aitwin-widget__face-loading-fill",style:{width:`${t}%`}})}),A.jsxs("p",{className:"aitwin-widget__face-loading-pct",children:[t,"%"]})]})]})})}function Mi(e){const t=e.id?.trim()||void 0,r=e.faceId?.trim()||e.avatarId?.trim()||void 0;return{id:r?void 0:t,faceId:r,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 Gc(e){return[e.id??"",e.faceId??"",e.authToken?.slice(0,16)??"",e.voiceId??"",e.apiBase??"",String(e.speakingRate??"")].join("|")}const Pi={display:"flex",alignItems:"center",justifyContent:"center",width:"100%",height:"100%",lineHeight:0},Kc={display:"block",height:"100%",width:"100%",objectFit:"cover",objectPosition:"top"},qc=d.forwardRef(function({options:t},r){const n=d.useRef(null),i=d.useRef(t);i.current={...i.current,onReady:t.onReady,onStatusChange:t.onStatusChange,onError:t.onError,onUserTranscript:t.onUserTranscript,onBotOutput:t.onBotOutput};const[s,o]=d.useState(!!t.showControls),[a,f]=d.useState(()=>Mi(t)),[m,l]=d.useState(!1),[c,h]=d.useState(!1),[v,E]=d.useState(!1),[g,R]=d.useState(!1),[V,B]=d.useState("idle"),[S,x]=d.useState(null),[O,W]=d.useState(!1),[G,ie]=d.useState(!1),[M,U]=d.useState(""),[J,Q]=d.useState(!1),[ue,ae]=d.useState([]),[Ae,ke]=d.useState(t.brainId?.trim()||t.personaId?.trim()||void 0),[re,Ke]=d.useState(t.brainUrl?.trim()||void 0),T=d.useCallback(k=>{i.current={...i.current,...k},k.showControls!==void 0&&o(!!k.showControls),(k.brainId!==void 0||k.personaId!==void 0)&&ke((k.brainId??k.personaId)?.trim()||void 0),k.brainUrl!==void 0&&Ke(k.brainUrl.trim()||void 0),f(ee=>Mi({id:k.id??ee.id,faceId:k.faceId??k.avatarId??ee.faceId,authToken:k.authToken??ee.authToken,apiBase:k.apiBase??ee.apiBase,voiceId:k.voiceId??ee.voiceId,speakingRate:k.speakingRate??ee.speakingRate,language:k.language??ee.language}))},[]);d.useImperativeHandle(r,()=>({getTwin:()=>n.current,applyOptions:T}),[T]),d.useEffect(()=>{T(t)},[T,t.id,t.faceId,t.avatarId,t.authToken,t.apiBase,t.voiceId,t.speakingRate,t.showControls,t.brainId,t.personaId,t.brainUrl]);const Z=d.useCallback(()=>{l(!0),x(null)},[]),H=d.useCallback(k=>{k==="idle"&&h(!0)},[]),j=d.useCallback(k=>{B(k),i.current.onStatusChange?.(k)},[]),de=d.useRef(!1);de.current=m&&c;const X=d.useCallback(k=>{if(R(!1),rr(k)){ie(!0),x(null);return}x(k),de.current||(l(!1),h(!1)),i.current.onError?.(k)},[]),se=d.useCallback((k,ee)=>{i.current.onUserTranscript?.(k,ee)},[]),fe=d.useCallback(k=>{i.current.onBotOutput?.(k)},[]);d.useEffect(()=>{if(!s)return;const k=window.setInterval(()=>{E(!!n.current?.isConnected())},400);return()=>window.clearInterval(k)},[s,a]);const me=Gc(a),K=!!(a.id||a.faceId),te=m&&c,oe=K&&!te&&!S,y=jc(oe),u=d.useRef(me);d.useEffect(()=>{te&&i.current.onReady?.()},[te]),d.useEffect(()=>{te&&n.current?.setMuted(O)},[te,O,a]),d.useEffect(()=>{ae([])},[a.id,a.faceId]),d.useEffect(()=>{u.current!==me&&(u.current=me,l(!1),h(!1),x(null),R(!1),E(!1),B("idle"))},[me]);const p=d.useCallback(()=>{ie(!0),x(null),R(!1),E(!1)},[]),b=()=>{const k=n.current;if(!k?.isReady())return;if(x(null),k.isConnected()){R(!1),ie(!1),k.disconnect().finally(()=>{E(!1)});return}R(!0);const ee={authToken:a.authToken,voiceId:a.voiceId,speakingRate:a.speakingRate,language:a.language,apiBase:a.apiBase,...Ae?{brainId:Ae}:{},...re?{brainUrl:re}:{}};(async()=>{if(await eo()){p();return}ie(!1);try{await k.connect(ee),E(!!k.isConnected())}catch(pe){if(rr(pe)){p();return}const Re=pe instanceof Error?pe.message:"Failed to connect voice.";x(Re),i.current.onError?.(Re)}finally{R(!1)}})()},C=()=>{ie(k=>!k),x(null)},F=d.useRef(0),q=()=>{const k=M.trim(),ee=n.current;if(!k||!ee?.isReady()||J)return;x(null),U(""),Q(!0);const pe=++F.current;i.current.onUserTranscript?.(k,!0),(async()=>{try{const Re=Ae||ee.getBrainId()?.trim()||void 0,Me=re||ee.getBrainUrl()?.trim()||void 0,_e=await ee.speakWithReply(k,{brainId:Re,brainUrl:Me,history:ue,voiceId:a.voiceId,speakingRate:a.speakingRate,language:a.language});if(pe!==F.current)return;_e.displayText&&ae(ye=>[...ye,{role:"user",content:k},{role:"assistant",content:_e.displayText}])}catch(Re){if(pe!==F.current)return;const Me=Re instanceof Error?Re.message:"Failed to get reply.";x(Me),i.current.onError?.(Me)}finally{pe===F.current&&Q(!1)}})()},L=()=>{F.current+=1,n.current?.stop(),Q(!1)},$=()=>{const k=!O;W(k),n.current?.setMuted(k)};return A.jsxs("div",{className:"aitwin-widget__layout",children:[A.jsxs("div",{className:"aitwin-widget__stage",children:[K?A.jsx("div",{style:Pi,children:A.jsx(Vs,{ref:n,id:a.id,faceId:a.faceId,authToken:a.authToken,apiBase:a.apiBase,voiceId:a.voiceId,speakingRate:a.speakingRate,language:a.language,fullBody:t.fullBody,style:Pi,canvasStyle:Kc,onReady:Z,onDisplayStatus:H,onStatusChange:j,onError:X,onUserTranscript:se,onBotOutput:fe,loadingThumbnailUrl:t.loadingThumbnailUrl},me)}):A.jsx("p",{className:"aitwin-widget__hint",style:{padding:16},children:"Pass id or faceId to load a twin."}),oe?A.jsx(zc,{progress:y}):null,s?A.jsx(Nc,{muted:O,onToggle:$}):null]}),s?A.jsx(Uc,{ready:te,connected:v,connecting:g,status:V,textMode:G,textDraft:M,textSending:J,error:S,onTalk:b,onTextMode:C,onTextDraftChange:U,onSendText:q,onStopSpeech:L}):null]})}),Yc=".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-composer-width: calc(340px * var(--aitwin-size));--aitwin-composer-height: calc(40px * var(--aitwin-size));--aitwin-action-height: calc(32px * 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));--aitwin-float-inset: 20px;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{align-items:flex-end;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__controls--text{max-width:calc(100vw - (2 * var(--aitwin-float-inset)));width:var(--aitwin-composer-width)}.aitwin-widget__actions{align-items:center;display:flex;gap:var(--aitwin-action-gap);width:100%}.aitwin-widget__action{align-items:center;appearance:none;background:transparent;border:1.5px solid var(--aitwin-accent);border-radius:999px;box-sizing:border-box;color:var(--aitwin-accent);cursor:pointer;display:inline-flex;flex:1 1 0;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;line-height:1;margin:0;min-height:var(--aitwin-action-height);min-width:0;overflow:hidden;padding:0 calc(10px * var(--aitwin-size))}.aitwin-widget__action span{display:inline-flex;line-height:1}.aitwin-widget__action svg{display:block;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:var(--aitwin-accent);color:#fff}.aitwin-widget__action--primary:hover:not(:disabled){background:var(--aitwin-accent-hover);border-color:var(--aitwin-accent-hover)}.aitwin-widget__action--connecting:disabled{cursor:progress;opacity:1}.aitwin-widget__spinner{display:inline-flex;flex-shrink:0;height:calc(12px * var(--aitwin-size));width:calc(12px * var(--aitwin-size))}.aitwin-widget__spinner svg{animation:aitwin-widget-spin .8s linear infinite;display:block;height:100%;width:100%}.aitwin-widget__spinner--on-accent,.aitwin-widget__action .aitwin-widget__spinner{color:#fff}@keyframes aitwin-widget-spin{to{transform:rotate(360deg)}}.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{align-items:center;background:#fff;border:1.5px solid var(--aitwin-accent);border-radius:999px;display:flex;gap:calc(4px * var(--aitwin-size));height:var(--aitwin-composer-height);padding:calc(4px * var(--aitwin-size));width:100%}.aitwin-widget__composer-back{align-items:center;background:transparent;border:none;border-radius:999px;color:#9ca3af;cursor:pointer;display:inline-flex;flex-shrink:0;height:calc(30px * var(--aitwin-size));justify-content:center;padding:0;width:calc(30px * var(--aitwin-size))}.aitwin-widget__composer-back:hover:not(:disabled){color:#4b5563}.aitwin-widget__composer-back:disabled{cursor:not-allowed;opacity:.45}.aitwin-widget__composer-back svg{display:block;height:calc(16px * var(--aitwin-size));width:calc(16px * var(--aitwin-size))}.aitwin-widget__composer-input{background:transparent;border:none;color:#111827;flex:1;font-family:inherit;font-size:calc(14px * var(--aitwin-size));min-width:0;outline:none;padding:0 calc(4px * var(--aitwin-size))}.aitwin-widget__composer-input::placeholder{color:#9ca3af}.aitwin-widget__composer-input:disabled{opacity:.7}.aitwin-widget__composer-send{align-items:center;background:var(--aitwin-accent);border:none;border-radius:999px;color:#fff;cursor:pointer;display:inline-flex;flex-shrink:0;height:calc(30px * var(--aitwin-size));justify-content:center;padding:0;width:calc(30px * var(--aitwin-size))}.aitwin-widget__composer-send:hover:not(:disabled){background:var(--aitwin-accent-hover)}.aitwin-widget__composer-send:disabled{cursor:not-allowed;opacity:.45}.aitwin-widget__composer-send--stop{opacity:1}.aitwin-widget__composer-send svg{display:block;height:calc(14px * var(--aitwin-size));width:calc(14px * var(--aitwin-size))}.aitwin-widget__controls-error{color:#fecaca;font-size:calc(11px * var(--aitwin-size));margin:0}.aitwin-widget--float{bottom:var(--aitwin-float-inset);filter:drop-shadow(0 12px 32px rgba(0,0,0,.45));height:fit-content;margin:0;max-width:calc(100vw - (2 * var(--aitwin-float-inset)));position:fixed;right:var(--aitwin-float-inset);width:fit-content;z-index:2147483000}@media(max-width:640px){.aitwin-widget{--aitwin-composer-width: calc(100vw - (2 * var(--aitwin-float-inset)));--aitwin-composer-height: calc(44px * var(--aitwin-size))}.aitwin-widget__controls--text{width:var(--aitwin-composer-width)}.aitwin-widget__composer-input{font-size:calc(15px * var(--aitwin-size))}}",Ci="data-aitwin-widget-style";function Ws(){if(typeof document>"u")return;const e=Yc.trim();if(!e){console.warn("[AiTwinWidget] styles.css?inline resolved empty — chrome will be unstyled");return}const t=document.querySelector(`style[${Ci}]`);if(t){if((t.textContent??"").trim().length>0)return;t.textContent=e;return}const r=document.createElement("style");r.setAttribute(Ci,"1"),r.textContent=e,(document.head??document.documentElement).appendChild(r)}typeof document<"u"&&Ws();const Qc=d.forwardRef(function(t,r){Ws();const n=d.useRef(null);d.useImperativeHandle(r,()=>({speakText:async(s,o)=>{const a=n.current?.getTwin();if(!a)throw new Error("AiTwinWidget: twin is not mounted");return a.speakText(s,o)},speakWithReply:async(s,o)=>{const a=n.current?.getTwin();if(!a)throw new Error("AiTwinWidget: twin is not mounted");return a.speakWithReply(s,o)},connect:async s=>{const o=n.current?.getTwin();if(!o)throw new Error("AiTwinWidget: twin is not mounted");return o.connect(s)},disconnect:async()=>{const s=n.current?.getTwin();if(s)return s.disconnect()},stop:()=>{n.current?.getTwin()?.stop()},isReady:()=>!!n.current?.getTwin()?.isReady(),isConnected:()=>!!n.current?.getTwin()?.isConnected(),getTwin:()=>n.current?.getTwin()??null}),[]);const i=!!t.float;return A.jsx("div",{className:i?"aitwin-widget aitwin-widget--float":"aitwin-widget",children:A.jsx(qc,{ref:n,options:t})})}),Xc=new Set([".png",".jpg",".jpeg",".webp"]);function js(e=".png"){const t=e.toLowerCase();return Xc.has(t)?`source${t}`:"source.png"}function Jc(e,t=Pr,r=".png"){const n=e.trim();if(!n)throw new Error("faceId is required");return`${t.replace(/\/$/,"")}/${n}/${js(r)}`}function Hs(e,t){if(e&&typeof e=="object"&&"detail"in e){const r=e.detail;if(typeof r=="string"&&r.trim())return r}return t}async function Zc(e){const t=new FormData;t.append("image",e.image),e.name?.trim()&&t.append("name",e.name.trim()),e.fullBody&&t.append("fullBody","true");const r=(e.apiBase??ut).replace(/\/$/,""),n=await fetch(`${r}/createAiTwinFace`,{method:"POST",headers:{Authorization:`Bearer ${e.authToken}`},body:t}),i=await n.json().catch(()=>null);if(!n.ok)throw new Error(Hs(i,`createAiTwinFace failed (${n.status})`));return i}async function el(e,t){const r=(t.apiBase??ut).replace(/\/$/,""),n=new URL(`${r}/getAiTwinFaceStatus`);n.searchParams.set("avatarId",e.trim());const i=await fetch(n.toString(),{headers:{Authorization:`Bearer ${t.authToken}`}}),s=await i.json().catch(()=>null);if(!i.ok)throw new Error(Hs(s,`getAiTwinFaceStatus failed (${i.status})`));return s}async function tl(e=ut){const t=e.replace(/\/$/,"");try{const r=await fetch(`${t}/getAiTwinGestureCatalog`);if(r.ok)return await r.json()}catch{}return{success:!0,fullBody:!0,poses:[xr.idle,...sr.map(r=>xr[r])].filter(r=>!!r),encrypted:!0,pathTemplate:"custom-faces/{avatarId}/ges/{code}.bin",cropMetaPath:"custom-faces/{avatarId}/ges/m.json"}}async function rl(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 nl(e){const t=e.message.trim();if(!t)throw new Error("Message is required");const r=e.authToken.trim();if(!r)throw new Error("Auth token is required");const n=(e.apiBase?.trim()||ut).replace(/\/$/,""),i=await fetch(`${n}/avatarReply`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${r}`,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 rl(i));if(!i.body)throw new Error("avatarReply response body is empty");const s=i.body.getReader(),o=new TextDecoder;let a="",f="",m="",l="";for(;;){const{done:c,value:h}=await s.read();if(c)break;a+=o.decode(h,{stream:!0});const v=a.split(`
48
- `);a=v.pop()||"";for(const E of v){if(E.startsWith("event: ")){l=E.slice(7).trim();continue}if(!E.startsWith("data: "))continue;const g=E.slice(6).trim();if(!g)continue;let R;try{R=JSON.parse(g)}catch{continue}if(l==="spokenText")f=R.text||"",e.onSpokenText?.(f);else if(l==="displayText")m=R.text||"";else if(l==="error")throw new Error(R.error||"avatarReply stream error")}}if(!f.trim()||!m.trim())throw new Error("avatarReply stream missing displayText or spokenText");return{displayText:m.trim(),spokenText:f.trim()}}exports.AI_TWIN_THUMBNAIL_FILENAME=Tn;exports.AiTwin=Vs;exports.AiTwinNotFoundError=kr;exports.AiTwinWidget=Qc;exports.CONSONANT_SKIP_GROUP=os;exports.DEFAULT_TTS_ENGINE_ID=xt;exports.DEFAULT_TTS_LANGUAGE=Ca;exports.EMOTION_TO_EYEBROW=Ps;exports.EXPRESSION_ATLAS_EMOTIONS=_o;exports.FULLBODY_GESTURE_POSES=sr;exports.MIC_SAMPLE_RATE=Mn;exports.OCULUS_VISEME_IDS=ns;exports.PLAYBACK_SAMPLE_RATE=Pn;exports.SPEAKING_RATE_MAX=Vr;exports.SPEAKING_RATE_MIN=Ur;exports.TTS_ENGINE_CARTESIA=dt;exports.TTS_ENGINE_GOOGLE=vn;exports.TTS_ENGINE_INWORLD=Cr;exports.TTS_ENGINE_VISEMETTS=ft;exports.TTS_LANGUAGE_CATALOG=It;exports.TTS_LANGUAGE_CODES=es;exports.VISEME_IDS=oo;exports.VISEME_SKIP_GAP_MS=dn;exports.VISEME_TEST_CARTESIA_VOICE_ID=Rn;exports.VISEME_TEST_SPEAKING_RATE=or;exports.VISEME_TEST_VISEMETTS_VOICE_ID=Fr;exports.VISEME_TEST_VOICE_ID=An;exports.VISEME_VTIME_GRID_MS=kn;exports.VOWEL_SKIP_GROUP=as;exports.aiTwinSourceFilename=js;exports.buildPlaybackTransitions=hs;exports.buildPlaybackVisemeSeries=Or;exports.buildRawVisemeTransitions=ms;exports.buildVoiceWebSocketUrl=Ts;exports.compactSkippableVisemes=xn;exports.createAiTwinFace=Zc;exports.createAvatarTtsLipsyncController=fn;exports.createRealtimeVoiceLipsyncController=ks;exports.emotionToEyebrow=At;exports.faceAssetUrls=un;exports.fetchAiTwin=Ni;exports.fetchAvatarReply=nl;exports.fetchDevAuthToken=Tr;exports.gesturesBaseForFace=Xi;exports.getAiTwinFaceStatus=el;exports.getAiTwinGestureCatalog=tl;exports.getAiTwinSourceUrl=Jc;exports.getAiTwinThumbnailUrl=Ui;exports.getFullBodyCropMetaUrl=Ji;exports.getFullBodyGestureBinUrl=Zi;exports.isFullBodyGesturePose=Ea;exports.isTtsLanguageCode=ts;exports.isTtsLanguageSupported=Ba;exports.listSkippedVisemeEntries=Nr;exports.listSkippedVisemes=za;exports.normalizeFullBodyGesturePose=Ut;exports.normalizeOculusViseme=Dr;exports.normalizeStreamEmotion=ct;exports.normalizeTtsLanguage=Br;exports.parsePackedVoiceId=Bi;exports.parseTwinBrainUrl=aa;exports.resolveDirectFaceId=Vi;exports.resolveTwinBrainId=bn;exports.resolveTwinBrainUrl=Sn;exports.resolveVisemeAtTime=ar;exports.resolveVisemeFromPlaybackSeries=us;exports.resolveWordAtTime=Ss;exports.setActiveTwinAssets=Wi;exports.snapVisemeQueueToGrid=En;exports.snapVisemeVtimeToGrid=cs;exports.splitVoiceIdSpec=lt;exports.ttsLanguagesForEngine=Fa;
47
+ `;function Ei(e=5){const t=new _e.Filter({glProgram:_e.GlProgram.from({vertex:yc,fragment:vc,name:"threshold-key-filter"}),resources:{thresholdUniforms:{uThreshold:{value:e/255,type:"f32"}}}});return t.setThreshold=r=>{t.resources.thresholdUniforms.uniforms.uThreshold=r/255},t.getThreshold=()=>Math.round(t.resources.thresholdUniforms.uniforms.uThreshold*255),t}function _c(e,t,r){return e>r||t>r}function bc(e){return e?e.getParameter(e.MAX_TEXTURE_SIZE):4096}function Sc(e,t){return t!=null&&t>0?Math.floor(t):bc(e)}function Tc(e,t){const r=document.createElement("canvas");r.width=t.w,r.height=t.h;const n=r.getContext("2d");if(!n)throw new Error("Failed to acquire 2d context for atlas cell crop");return n.drawImage(e,t.x,t.y,t.w,t.h,0,0,t.w,t.h),r}function js(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 xi(e,t,r,n,i){const s=r?await Yi(e,i):await fetch(e).then(l=>{if(!l.ok)throw new Error(`Failed to load ${e}`);return l.json()}),o=s.sheets?.[0];if(!o?.path)throw new Error(`${e} has no sheets[0].path`);const a=new Map,f=async(l,h)=>{const v=Bs(t,h,r),E=r?await Sa(await vt(v,i??"")):await js(v);if(_c(E.width,E.height,n))return console.info(`[PixiVisemeCompositor] Sheet ${h} (${E.width}x${E.height}) exceeds MAX_TEXTURE_SIZE=${n}; using per-cell crops.`),{mode:"cells",bitmap:E};const g=_e.Texture.from(E);return g.source.scaleMode="nearest",{mode:"full",texture:g}};a.set(o.index,await f(o.index,o.path));for(const l of s.sheets??[])l.index!==o.index&&l.path&&a.set(l.index,await f(l.index,l.path));const m=new Map;for(const l of s.cells??[])l.path&&m.set(l.path,l);const u=new Map;for(const l of s.sheets??[])u.set(l.index,l);return{atlasMeta:s,cellByPath:m,sheetByIndex:u,diffBase:t,sheets:a}}async function kc(e,t={}){const r=new _e.Application;try{await r.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(w){throw r.destroy({removeView:!1}),w}if(r.renderer.type!==_e.RendererType.WEBGL)throw r.destroy({removeView:!1}),new Error("Pixi did not initialize a WebGL renderer");const n=Sc(r.renderer.gl,t.maxTextureSize);let i=!1,s=!1,o=!1;const a=r.canvas,f=()=>{i=!0,!s&&!o&&(s=!0,t.onWebGlContextLost?.())};a.addEventListener("webglcontextlost",f);const m=new _e.Sprite(_e.Texture.EMPTY),u=new _e.Sprite(_e.Texture.EMPTY);u.visible=!1,u.alpha=0;const l=new _e.Sprite(_e.Texture.EMPTY),h=new _e.Sprite(_e.Texture.EMPTY),v=new _e.Sprite(_e.Texture.EMPTY);v.visible=!1;const E=Ei(5),g=Ei(5);l.filters=[E],h.filters=[g],r.stage.addChild(m),r.stage.addChild(u),r.stage.addChild(l),r.stage.addChild(h),r.stage.addChild(v);let P=null,j=null,F=null,S=null,x=null,L=null,H=null,G=842,ne=1264,B=null,N=5;const X=new Map;let se=null,de=null,ae=null;const Ae=zi(()=>{X.clear(),L=null,H=null,P=null,B=null}),be=(w,c)=>{G=w,ne=c,r.renderer.resize(w,c),(e.width!==w||e.height!==c)&&(e.width=w,e.height=c)},te=()=>{l.visible=!1,h.visible=!1,l.texture=_e.Texture.EMPTY,h.texture=_e.Texture.EMPTY,se=null,de=null},He=()=>{x=null,u.visible=!1,u.alpha=0},T=()=>{m.visible=!0,m.width=G,m.height=ne,m.x=0,m.y=0},Z=()=>{u.width=G,u.height=ne,u.x=0,u.y=0},ee=()=>{v.visible=!1,He(),P&&(m.texture=P,T())},z=()=>{x&&ee()},fe=w=>{if(o||i||!P){ee();return}const c=Math.max(0,w);if(!j||c<=0){ee();return}te(),v.visible=!1,m.texture=P,T(),u.texture=j,Z(),u.alpha=1,u.visible=!0,x={startMs:performance.now(),durationMs:c},ie()},U=(w=performance.now())=>{if(!x)return!1;if(o||i)return z(),!1;const c=(w-x.startMs)/Math.max(1,x.durationMs);if(c>=1)return ee(),ie(),!1;const p=Math.min(1,Math.max(0,c)),b=p*p*(3-2*p);return u.alpha=1-b,u.visible=!0,ie(),!0},Q=()=>{if(F){try{F.resource=null}catch{}F.destroy(),F=null}j&&(j.destroy(!1),j=null),S=null},ce=(w,c)=>{const p=w.cellByPath.get(c);if(!p||!Ms(p))return null;const b=`${w.diffBase}::${c}`;let R=X.get(b);if(!R){const C=p.sheet??0,V=w.sheets.get(C);if(!V)return null;let K,J=!1;if(V.mode==="full")K=new _e.Texture({source:V.texture.source,frame:new _e.Rectangle(p.x,p.y,p.w,p.h)});else{const k=Tc(V.bitmap,p);K=_e.Texture.from(k),K.source.scaleMode="nearest",J=!0}R={texture:K,ownsSource:J},X.set(b,R)}return{texture:R.texture,cell:p}},Se=(w,c,p,b)=>{if(!b||!p)return w.visible=!1,w.texture=_e.Texture.EMPTY,!1;const R=ce(p,b);if(!R)return w.visible=!1,w.texture=_e.Texture.EMPTY,!1;const C=Rs(p.atlasMeta,R.cell);return c.setThreshold(N),w.texture=R.texture,w.x=C.x,w.y=C.y,w.width=R.cell.w,w.height=R.cell.h,w.visible=!0,!0},me=w=>{if(!w||!L)return null;const c=B??new Set(L.cellByPath.keys());return Dn(w,c)??(c.has(w)?w:null)},Te=w=>{v.visible=!1,ee();const c=me(w.mouthPath),p=w.expressionPath&&H?On(w.expressionPath,b=>H.cellByPath.has(b)):null;c!==se?(Se(l,E,L,c),se=c):c?l.visible=!0:l.visible=!1,p!==de?(Se(h,g,H,p),de=p):p?h.visible=!0:h.visible=!1},ie=()=>{if(!(o||i||document.hidden))try{r.render()}catch{}};return{async loadAssets(w){if(o)return{width:G,height:ne,visemePaths:[]};const c=Gt();if(c&&!w)throw new Error("Encrypted assets enabled but no key provided");const p=c?await ka(await vt(ir(),w??"")):await js(ir());P&&P.destroy(!0),P=_e.Texture.from(p),P.source.scaleMode="linear";const b=Gi();L=await xi(Ki(),b,c,n,w);try{H=await xi(qi(),b,c,n,w)}catch(C){console.warn("[PixiVisemeCompositor] expression atlas unavailable:",C),H=null}const R=As(L.atlasMeta,p.width,p.height);return be(R.width,R.height),N=zr(L.atlasMeta),E.setThreshold(N),g.setThreshold(N),B=new Set(L.cellByPath.keys()),X.clear(),ee(),te(),ie(),{width:R.width,height:R.height,visemePaths:[...L.cellByPath.keys()]}},getVisemeAtlasPaths(){return B},drawLiveFrame(w){o||i||!P||(z(),Te(w),ie())},drawIdleVideo(w,c){o||i||document.hidden||c&&!c()||w.readyState<HTMLMediaElement.HAVE_CURRENT_DATA||(x=null,te(),v.visible=!1,P&&(m.texture=P,T()),!j||S!==w?(Q(),F=new _e.VideoSource({resource:w,autoPlay:!1,updateFPS:0}),F.autoUpdate=!1,j=new _e.Texture({source:F}),S=w):j.source.update(),u.texture=j,Z(),u.alpha=1,u.visible=!0,ie())},beginIdleToSilCrossfade:fe,tickIdleToSilCrossfade:U,finishIdleToSilCrossfade:z,isIdleToSilCrossfading(){return x!=null},renderSilOnly(){o||i||!P||(te(),ee(),ie())},blitBitmap(w){o||i||(z(),te(),ae&&(ae.destroy(!0),ae=null),ae=_e.Texture.from(w),v.texture=ae,v.visible=!0,v.x=0,v.y=0,v.width=G,v.height=ne,m.visible=!1,ie())},async compositePrefetchFrame(w){return null},renderFrame:ie,isContextLost(){return i},dispose(){if(o)return;o=!0,a.removeEventListener("webglcontextlost",f),Ae(),Q(),ae&&(ae.destroy(!0),ae=null);for(const{texture:c,ownsSource:p}of X.values())c.destroy(p);X.clear(),P&&(P.destroy(!0),P=null);const w=c=>{c.mode==="full"?c.texture.destroy(!0):c.bitmap.close()};if(L)for(const c of L.sheets.values())w(c);if(H)for(const c of H.sheets.values())w(c);E.destroy(!0),g.destroy(!0),r.destroy({removeView:!1},{children:!0,texture:!0})}}}const Ii=-1,xr=1e5,Ai=new Map;async function Ec(e){let t=Ai.get(e);if(!t){const r=await fetch(e);if(!r.ok)throw new Error(`Failed to fetch worker script (${r.status}): ${e}`);const n=await r.blob();t=URL.createObjectURL(n),Ai.set(e,t)}return new Worker(t,{name:"visemeDiffPreview"})}function xc(){return typeof Worker<"u"&&typeof OffscreenCanvas<"u"}function vn(e,t){(e.width!==t.width||e.height!==t.height)&&(e.width=t.width,e.height=t.height);const r=e.getContext("2d");r&&r.drawImage(t,0,0)}function Ri(e,t){let r=0,n=null;const i=Hn(async(s,o)=>(await wn(),await yn(e,s),i.isLatestSeq(o)));return{usesWorker:!1,usesPixi:!1,async loadAssets(s){const o=await wn(s);return n=o.visemePaths?new Set(o.visemePaths):null,o},getVisemeAtlasPaths(){return n},async renderSilOnly(){r+=1,i.reset(),await zo(e)},drawLiveFrame(s,o,a,f){i.enqueue(o,a,f)},async compositePrefetchFrame(s,o){try{return await $o(s)}catch{return null}},blitBitmap(s,o){vn(s,o)},drawIdleVideo(){},beginIdleToSilCrossfade(){},tickIdleToSilCrossfade(){return!1},finishIdleToSilCrossfade(){},isIdleToSilCrossfading(){return!1},supportsBufferedPlayback:!0,async renderViseme(s,o){r+=1;const a=r;t.onStatus?.(o),await yn(s,{mouthPath:Ht(o),expressionPath:null})},dispose(){r+=1,i.reset()}}}function Ic(e,t,r){let n=null,i=1,s=0,o=!1,a=!1,f=null;const m=new Map,u=new Map;let l=xr;const h=Hn(async(F,S,x)=>(m.set(S,{drawKey:x.drawKey,onDisplayed:x.onDisplayed}),await P({type:"drawFrame",diffPath:F.mouthPath,expressionDiffPath:F.expressionPath,liveSeq:S},void 0,!0),!1)),v=F=>{if(F===Ii){let L=-1,H;for(const[G,ne]of m)G>=L&&(L=G,H=ne);L>=0&&m.delete(L),H?.onDisplayed?.(H.drawKey);return}const S=-F,x=m.get(S);m.delete(S),x?.onDisplayed?.(x.drawKey)},E=new Map,g=(F,S)=>{a||!n||n.postMessage(F,[])},P=(F,S,x=!1)=>{if(a)return Promise.resolve();const L=i++;return new Promise((H,G)=>{E.set(L,{resolve:ne=>H(ne),reject:G,generation:typeof F.generation=="number"?F.generation:void 0,expectRenderDone:x}),g({...F,requestId:L})})},j=(async()=>{n=await Ec(r),n.onmessage=F=>{if(a)return;const S=F.data;if(S.type==="status"){t.onStatus?.(S.label);return}if(S.type==="frame"){if(S.generation<=-xr){const H=-S.generation,G=u.get(H);u.delete(H),G?.resolve(S.bitmap);return}const L=S.generation<0;if(!L&&S.generation!==s){S.bitmap.close();return}if(L&&!(S.generation===Ii)){const G=-S.generation;if(!h.isLatestSeq(G)){yt()?.onWorkerStale(),S.bitmap.close();return}}if(L&&t.shouldAcceptLiveFrame&&!t.shouldAcceptLiveFrame()){yt()?.onWorkerStale(),S.bitmap.close();return}vn(e,S.bitmap),S.bitmap.close(),L&&v(S.generation);return}const x=E.get(S.requestId);if(x)switch(S.type){case"ready":E.delete(S.requestId),x.resolve();break;case"loadAssetsDone":E.delete(S.requestId),f=S.visemePaths?.length?new Set(S.visemePaths):null,x.resolve({width:S.width,height:S.height,visemePaths:S.visemePaths});break;case"renderDone":if(x.expectRenderDone&&x.generation!=null&&S.generation!==x.generation)return;E.delete(S.requestId),x.resolve();break;case"renderAborted":E.delete(S.requestId),x.resolve();break;case"error":E.delete(S.requestId),t.onError?.(S.message),x.reject(new Error(S.message));break}},n.onerror=F=>{if(a)return;const S=F.message||"Worker error";t.onError?.(S);for(const[,x]of E)x.reject(new Error(S));E.clear()},await P({type:"init"}),o=!0})();return{usesWorker:!0,usesPixi:!1,async loadAssets(F){if(a)return{width:842,height:1264};if(await j,a)return{width:842,height:1264};if(!o)throw new Error("Worker init failed");return await P({type:"loadAssets",keyHex:F,urls:_a(Ct())})??{width:842,height:1264}},getVisemeAtlasPaths(){return f},async renderSilOnly(){if(a||(await j,a))return;s+=1,h.reset(),m.clear(),u.forEach(({resolve:S})=>S(null)),u.clear(),l=xr;const F=s;await P({type:"cancelLiveDraws"}),await P({type:"renderSil",generation:F},void 0,!0)},drawLiveFrame(F,S,x,L){a||j.then(()=>{a||h.enqueue(S,x,L)})},compositePrefetchFrame(F,S){return a?Promise.resolve(null):j.then(()=>{if(a)return null;const x=++l;return new Promise(L=>{u.set(x,{resolve:L}),P({type:"drawFrame",diffPath:F.mouthPath,expressionDiffPath:F.expressionPath,liveSeq:x},void 0,!0).catch(()=>{u.delete(x),L(null)})})})},blitBitmap(F,S){vn(F,S)},drawIdleVideo(){},beginIdleToSilCrossfade(){},tickIdleToSilCrossfade(){return!1},finishIdleToSilCrossfade(){},isIdleToSilCrossfading(){return!1},supportsBufferedPlayback:!0,async renderViseme(F,S,x={}){if(a||(await j,a))return;s+=1,h.reset(),m.clear();const L=s;try{await P({type:"cancelLiveDraws"}),await P({type:"renderViseme",generation:L,to:S,from:x.from,transitionDurationMs:x.transitionDurationMs,gapMs:x.gapMs,threshold:x.threshold},void 0,!0)}catch(H){if(H?.name==="AbortError")return;throw H}},dispose(){if(!a){a=!0,s+=1,h.reset(),m.clear(),u.forEach(({resolve:F})=>F(null)),u.clear(),l=xr;for(const[,F]of E)F.resolve();E.clear(),n?.terminate(),n=null}}}}async function Ac(e,t){const r=await kc(e,{onWebGlContextLost:t.onWebGlContextLost,maxTextureSize:t.pixiMaxTextureSize});let n=0,i=null,s=!1;const o=Hn(async(a,f)=>s?!1:t.shouldAcceptLiveFrame&&!t.shouldAcceptLiveFrame()?(yt()?.onWorkerStale(),!1):(r.drawLiveFrame(a),o.isLatestSeq(f)));return{usesWorker:!1,usesPixi:!0,async loadAssets(a){if(s)return{width:842,height:1264};const f=await r.loadAssets(a);return i=f.visemePaths?.length?new Set(f.visemePaths):null,f},getVisemeAtlasPaths(){return i},async renderSilOnly(){s||(n+=1,o.reset(),r.renderSilOnly())},drawLiveFrame(a,f,m,u){s||o.enqueue(f,m,u)},async compositePrefetchFrame(a,f){if(s)return null;try{return await r.compositePrefetchFrame(a)}catch{return null}},blitBitmap(a,f){s||t.shouldAcceptLiveFrame&&!t.shouldAcceptLiveFrame()||r.blitBitmap(f)},drawIdleVideo(a,f){s||r.drawIdleVideo(a,f)},beginIdleToSilCrossfade(a){s||r.beginIdleToSilCrossfade(a)},tickIdleToSilCrossfade(a){return s?!1:r.tickIdleToSilCrossfade(a)},finishIdleToSilCrossfade(){s||r.finishIdleToSilCrossfade()},isIdleToSilCrossfading(){return s?!1:r.isIdleToSilCrossfading()},supportsBufferedPlayback:!1,async renderViseme(a,f){if(s)return;n+=1;const m=n;o.reset(),t.onStatus?.(f),r.drawLiveFrame({mouthPath:Ht(f),expressionPath:null})},dispose(){s||(s=!0,n+=1,o.reset(),r.dispose())}}}function Mi(e,t){if(!xc())return Ri(e,t);const r=ra(t.workerScriptUrl);try{return Ic(e,t,r)}catch{return Ri(e,t)}}function Rc(e,t={}){if(t.preferLegacyRenderer)return Mi(e,t);let r=null,n=!1,i=null,s=!1;const o=()=>r?Promise.resolve(r):(i||(i=(async()=>{try{const a=await Ac(e,t);if(s)throw a.dispose(),new Error("Renderer disposed during Pixi init");return n=!0,r=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),r=Mi(e,t),n=!1,r}})()),i);return{get usesWorker(){return r?.usesWorker??!1},get usesPixi(){return n},async loadAssets(a){return(await o()).loadAssets(a)},getVisemeAtlasPaths(){return r?.getVisemeAtlasPaths()??null},async renderSilOnly(){return(await o()).renderSilOnly()},drawLiveFrame(a,f,m,u){o().then(l=>{s||l.drawLiveFrame(a,f,m,u)})},async compositePrefetchFrame(a,f){return(await o()).compositePrefetchFrame(a,f)},blitBitmap(a,f){r&&r.blitBitmap(a,f)},drawIdleVideo(a,f){r?.usesPixi&&r.drawIdleVideo(a,f)},beginIdleToSilCrossfade(a){r?.beginIdleToSilCrossfade(a)},tickIdleToSilCrossfade(a){return r?.tickIdleToSilCrossfade(a)??!1},finishIdleToSilCrossfade(){r?.finishIdleToSilCrossfade()},isIdleToSilCrossfading(){return r?.isIdleToSilCrossfading()??!1},get supportsBufferedPlayback(){return r?.supportsBufferedPlayback??!1},async renderViseme(a,f,m){return(await o()).renderViseme(a,f,m)},dispose(){s=!0,i=null,r?.dispose(),r=null}}}class Mc extends Error{constructor(t,r){super(`${t} timed out after ${Math.round(r/1e3)}s`),this.name="LoadTimeoutError"}}function on(e,t,r){return new Promise((n,i)=>{const s=globalThis.setTimeout(()=>{i(new Mc(r,t))},t);e.then(o=>{globalThis.clearTimeout(s),n(o)},o=>{globalThis.clearTimeout(s),i(o)})})}const Pc={overflow:"hidden",position:"relative",display:"inline-block",lineHeight:0},Cc={display:"block",maxWidth:"100%",height:"auto"},Bc={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 Ui(e)?Cn:Vi(e)?Or:Pn}function at(e,t){return t?.isSpeaking()||t?.isWarmingUp()?t:e.isSpeaking()||e.isWarmingUp()?e:t?.isConnected()?t:e}const Hs=d.forwardRef(function({id:t,avatarId:r,faceId:n,assets:i,authToken:s,apiBase:o,ttsEngineId:a,voiceId:f,language:m,speakingRate:u=ur,className:l,style:h,canvasStyle:v,onStatusChange:E,onDisplayStatus:g,onError:P,onReady:j,showErrorOverlay:F=!0,loadingThumbnailUrl:S,onUserTranscript:x,onBotOutput:L,onRealtimeLipsyncDebug:H,onFrameRenderStats:G,lipsyncBufferedPlayback:ne=!0,lipsyncPlaybackWarmupMs:B=1500,idleHandoffHoldMs:N=ic,disableIdleVideo:X=!1,fullBody:se=!1,pixiMaxTextureSize:de,captions:ae,userName:Ae,userEmail:be,userContext:te},He){const T=d.useRef(null),[Z,ee]=d.useState(!1),z=se||Z,fe=X||z,U=d.useRef(null),Q=d.useRef(null),ce=d.useRef(ne);ce.current=ne;const Se=d.useRef(B);Se.current=B;const me=d.useRef(N);me.current=N;const Te=d.useRef(fe);Te.current=fe;const ie=d.useRef(0),w=d.useRef(Wn()),c=d.useRef(Fo()),p=d.useRef(!1),b=d.useRef(null),R=d.useRef(null),C=d.useRef(0),V=d.useRef(0),K=d.useRef(0),J=d.useRef(null),k=d.useRef(null),q=d.useRef(!1),le=d.useRef(!1),ge=d.useRef(!1),pe=d.useRef(!1),Pe=d.useRef(!1),qe=d.useRef("sil"),y=d.useRef(0),A=d.useRef(!1),W=d.useRef(null),re=d.useRef(!1),[we,Re]=d.useState("idle"),[xe,Fe]=d.useState(null),[De,ft]=d.useState(!1),[$e,rt]=d.useState(!1),[dr,_t]=d.useState(!1),[bt,Kt]=d.useState(),[mt,fr]=d.useState({width:842,height:1264}),[qt,mr]=d.useState(null),[St,Yt]=d.useState(0),[Qt,Xt]=d.useState(null),[Oe,ze]=d.useState(null),[Xe,Bt]=d.useState(!1),ht=d.useRef(null),Tt=d.useRef(null),Ft=d.useRef(!1),nt=d.useRef(s??null),kt=o?.trim()||lt,hr=d.useRef(null),Le=d.useRef(null),{ttsEngineId:Ge,voiceId:Dt}=d.useMemo(()=>{const _=ct(a,f),I=_.ttsEngineId??At;return{ttsEngineId:I,voiceId:_.voiceId??cn(I)}},[a,f]),it=d.useCallback(_=>{const I=Ui(_);w.current.holdPp=I,Q.current?.setHoldPp(I)},[]),pt=d.useRef(!1),pr=d.useRef({width:842,height:1264}),Lt=d.useRef(null),$n=d.useRef("sil"),Jt=d.useRef(""),gt=d.useMemo(()=>Ko(ae),[ae]),Je=d.useCallback(()=>{Jt.current="",mr(null)},[]);d.useEffect(()=>{gt.enabled||Je()},[gt.enabled,Je]);const Gr=d.useCallback(_=>{if(!gt.enabled)return;const I=_.isSpeaking(),O=_.isWarmingUp();if(!I||O){Jt.current&&Je();return}const D=Go(_.getWordQueue());if(!D){Jt.current&&Je();return}D!==Jt.current&&(Jt.current=D,mr(D))},[gt.enabled,Je]),gr=d.useRef(void 0),Kr=d.useRef(new Map),zn=d.useRef(j),Gn=d.useRef(E),Ce=d.useRef(g),Kn=d.useRef(P),qn=d.useRef(x),qr=d.useRef(L),wr=d.useRef(H),Yn=d.useRef(G),Ot=d.useRef(nc());zn.current=j,Gn.current=E,Ce.current=g,Kn.current=P,qn.current=x,qr.current=L,wr.current=H,Yn.current=G,d.useEffect(()=>{const _=Ot.current;return _i(_),()=>_i(null)},[]);const Yr=d.useCallback(_=>{const I=ct(_?.ttsEngineId??a,_?.voiceId??f),O=I.ttsEngineId??Le.current?.ttsEngineId??At,D=I.voiceId??Le.current?.voiceId??cn(O);return{ttsEngineId:O,voiceId:D}},[a,f]),st=d.useCallback(_=>{Fe(_),_t(!0),Kn.current?.(_)},[]),Zt=d.useCallback(_=>{Re(_),Gn.current?.(_)},[]),ue=d.useRef(pn(Zt,kt,{onLipsyncDebug:_=>wr.current?.(_),fullBody:z})),ye=d.useRef(null),yr=d.useRef(!1),Qn=d.useRef(()=>{});d.useEffect(()=>(ue.current=pn(Zt,kt,{onLipsyncDebug:_=>wr.current?.(_),fullBody:z}),s&&ue.current.setDeveloperToken(s),ue.current.setTtsEngineId(Ge),ue.current.setMuted(yr.current),()=>{ue.current.stop();const _=ye.current;_&&(_.disconnect(),ye.current=null)}),[Zt,kt,z]),d.useEffect(()=>{if(!z||we!=="speaking"){Bt(!1);return}const _=Vt(oi(ue.current.getWordQueue(),ue.current.getPlaybackElapsedMs(),I=>Vt(I)!=null));Tt.current=_,ze(_),Bt(!0)},[z,we]);const Xn=d.useCallback(()=>(ye.current||(ye.current=Is(Zt,{speakingRate:u,language:m,fullBody:z,waitForBodyIdle:()=>ht.current?.waitForIdleCycleEnd()??null,onBodyIdleCancelled:()=>ht.current?.resumeIdleLoop(),onUserTranscript:(_,I)=>qn.current?.(_,I),onBotOutput:_=>qr.current?.(_),onLipsyncDebug:_=>wr.current?.(_)}),ye.current.setTtsEngineId(Ge),ye.current.setMuted(yr.current),Qn.current(!0)),ye.current),[Zt,u,m,Ge,z]),Ve=d.useCallback(()=>{J.current!=null&&(clearTimeout(J.current),J.current=null)},[]),Ue=d.useCallback(()=>{k.current!=null&&(clearTimeout(k.current),k.current=null),ge.current=!1},[]),Qr=d.useCallback(()=>{Pe.current=!0,Ue(),W.current?.setLooping(!1)},[Ue]),Ye=d.useCallback(()=>{Pe.current=!1,W.current?.setLooping(!0)},[]),er=d.useCallback(()=>{if(pe.current)return;const _=U.current;if(pe.current=!0,Pe.current=!0,Ue(),q.current=!1,le.current=!1,!re.current||!W.current){_?.renderSilOnly();return}const I=W.current;I.setLooping(!1),I.setActive(!1);const O=I.getVideo();if(O.ended||Number.isFinite(O.currentTime)&&O.currentTime<=sn){try{(O.ended||O.currentTime>sn)&&(O.currentTime=0)}catch{}_?.renderSilOnly(),_?.finishIdleToSilCrossfade();return}if(_?.usesPixi){_.drawIdleVideo(O),_.beginIdleToSilCrossfade(Si);return}(async()=>{const Y=T.current;Y&&await nn(Y,O,null,void 0,pr.current).catch(()=>{}),await new Promise(ke=>setTimeout(ke,Si)),pe.current&&await _?.renderSilOnly()})()},[Ue]),Jn=d.useCallback(()=>{if(!(!re.current||!W.current)){if(pe.current=!1,U.current?.finishIdleToSilCrossfade(),U.current?.renderSilOnly(),Ue(),Pe.current){ge.current=!1;return}ge.current=!0,k.current=setTimeout(()=>{if(k.current=null,at(ue.current,ye.current).isSpeaking()){ge.current=!1;return}if(q.current){ge.current=!1;return}if(Pe.current){ge.current=!1;return}const _=W.current;if(!_){ge.current=!1;return}Ye(),_.setLooping(!0),_.restart(),_.setActive(!0);const I=_.getVideo();let O=!1;const D=()=>{O||(O=!0,I.removeEventListener("playing",Y),ge.current=!1)},Y=()=>{D()};if(I.addEventListener("playing",Y,{once:!0}),I.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA&&!I.paused){D();return}setTimeout(D,300)},me.current)}},[Ue,Ye]),Nt=d.useCallback(()=>{if(Ve(),Ce.current?.("sil"),q.current=!1,pe.current=!1,!re.current||!W.current){ge.current=!1,Ye();return}Jn()},[Ve,Jn,Ye]),Xr=d.useCallback(async _=>{const I=V.current,O=U.current,D=T.current,Y=()=>{_?.fallbackOnly||(q.current=!1)};if(!O||!D||!De){Y();return}if(at(ue.current,ye.current).isSpeaking()){Y();return}if(_?.fallbackOnly){if(!q.current||(je(w.current),await O.renderSilOnly(),I!==V.current)||at(ue.current,ye.current).isSpeaking())return;Nt();return}if(Ti(w.current)){je(w.current),Nt();return}if(ce.current&&O.supportsBufferedPlayback&&!_?.fallbackOnly){if(je(w.current),Q.current?.reset(),await O.renderSilOnly(),I!==V.current||at(ue.current,ye.current).isSpeaking())return;Nt();return}const ve=uc(at(ue.current,ye.current).getVisemeQueue(),y.current,qe.current),Me=dc(ve,Lt.current);if(je(w.current),!Me){if(await O.renderSilOnly(),I!==V.current||at(ue.current,ye.current).isSpeaking())return;Nt();return}try{await O.renderViseme(D,"sil",{from:ve,transitionDurationMs:Us})}catch(Ee){if(Ee?.name!=="AbortError")throw Ee}if(I!==V.current){Y();return}if(at(ue.current,ye.current).isSpeaking()){Y();return}Nt()},[De,Nt]),Et=d.useCallback(()=>{if(le.current||q.current)return;le.current=!0,q.current=!0,Ve();const _=V.current;Xr().finally(()=>{le.current=!1}),J.current=setTimeout(()=>{J.current=null,_===V.current&&Xr({fallbackOnly:!0})},fc())},[Ve,Xr]),Zn=d.useCallback(async()=>{const _=Math.floor(Date.now()/1e3);if(hr.current&&_<hr.current.expiresAt-60)return hr.current.key;const I=nt.current??await Ir();nt.current=I,ue.current.setDeveloperToken(I);const O=await ga(I,kt);return hr.current={key:O.value,expiresAt:O.expiresAt},O.value},[kt]);d.useEffect(()=>{s&&(nt.current=s,ue.current.setDeveloperToken(s))},[s]),d.useEffect(()=>{ue.current.setTtsEngineId(Ge),ye.current?.setTtsEngineId(Ge),Le.current&&(Le.current.ttsEngineId=Ge),it(Ge)},[Ge,it]),d.useEffect(()=>{Le.current&&(Le.current.voiceId=Dt)},[Dt]);const Ke=d.useMemo(()=>Hi(r,n),[r,n]);d.useEffect(()=>{ee(!1)},[t,Ke]);const Ks=d.useMemo(()=>i?JSON.stringify(i):Ke?`face:${Ke}`:`id:${t??""}`,[i,Ke,t]),qs=d.useMemo(()=>{const _=S?.trim();return _||(ri(Ke)??ri(bt)??ua(i))},[S,Ke,bt,i]);return d.useEffect(()=>{if(!t&&!i&&!Ke){st("AiTwin requires `assets`, `avatarId`/`faceId`, or `id`");return}let _=!1;pt.current=!1,ft(!1),rt(!1),_t(!1),Kt(Ke),Fe(null),Le.current=null,W.current=null,re.current=!1;const I=T.current;if(!I)return;let O=null;return(async()=>{try{let D,Y,ke,ve,Me;if(i)D=i,Y=Ge,ke=Dt;else if(Ke)Ce.current?.("loadFace"),D=mn(Ke),Y=Ge,ke=Dt;else{Ce.current?.("getAiTwin");const $=await on(Wi(t),3e4,"getAiTwin");if(_)return;if(!$.faceId?.trim())throw new Error("getAiTwin returned no faceId");$.fullBody&&ee(!0),Kt($.faceId.trim());const Ie=ct(a,f);Y=Ie.ttsEngineId??$.ttsEngineId,ke=Ie.voiceId??$.voiceId??cn(Y),ve=kn($),Me=En($),D=mn($.faceId)}Le.current={ttsEngineId:Y,voiceId:ke,brainId:ve,brainUrl:Me},$i(D),W.current=Do();const Ee=!!(i&&!Pt(i));O=Rc(I,{preferLegacyRenderer:Ee,pixiMaxTextureSize:de,onStatus:$=>{_||Ce.current?.($)},onError:$=>{_||st($)},shouldAcceptLiveFrame:()=>{if(p.current)return!0;if(q.current)return!1;const $=at(ue.current,ye.current);return $.isSpeaking()||$.isWarmingUp()},onWebGlContextLost:()=>{_||Ft.current||(Ft.current=!0,queueMicrotask(()=>{_||Yt($=>$+1)}))}}),U.current=O,Q.current=wc(O),it(Y),Ft.current=!1;const Ne=$=>{const Ie=()=>{if(!$||Se.current<=0)return!1;const Be=U.current;return Be?ce.current&&Be.supportsBufferedPlayback?!0:Be.usesPixi:!1};ue.current.setLipsyncWarmupHold($,Ie),ye.current?.setLipsyncWarmupHold($,Ie)};Qn.current=Ne,Ne(!0),Ce.current?.("auth");const Ze=nt.current??s??await on(Ir(),3e4,"getAuthToken");if(_)return;nt.current=Ze,ue.current.setDeveloperToken(Ze),ue.current.setTtsEngineId(Y);const oe=Gt()?await Zn():void 0;if(_)return;oe&&Xt(oe),Ce.current?.("loadAssets");const he=await on(O.loadAssets(oe),z?18e4:24e4,"load face assets");if(!_&&he.width>0&&he.height>0&&(pr.current=he,fr(he)),_)return;Lt.current=O.getVisemeAtlasPaths(),pt.current=!0,ft(!0),zn.current?.(),O.renderSilOnly().then(()=>{_||Ce.current?.("sil")}),(async()=>{try{if(Te.current){re.current=!1,rt(!1),await O.renderSilOnly();return}const $=await Ea(oe);if(await W.current.load($),_||(re.current=!0,rt(!0),je(w.current),await O.renderSilOnly(),_)||(await new Promise(Be=>setTimeout(Be,me.current)),_))return;W.current.setActive(!0);const Ie=W.current.getVideo();O.usesPixi?O.drawIdleVideo(Ie):await nn(I,Ie,null,void 0,pr.current)}catch($){if(_)return;re.current=!1,rt(!1),console.warn("[AiTwin] Idle video unavailable:",$)}finally{_||(_t(!0),Ce.current?.("idle"))}})()}catch(D){if(_)return;if(D instanceof Ar){st(D.message);return}st(D instanceof Error?D.message:"Failed to load AI twin")}})(),()=>{_=!0,W.current?.dispose(),O?.dispose(),U.current=null}},[Ks,i,Ke,t,Ge,Dt,a,f,s,de,fe,Zn,st,St,it]),d.useEffect(()=>{const _={current:!1},I=()=>{const O=T.current,D=U.current,Y=at(ue.current,ye.current);if(!O||!D||!De){C.current=requestAnimationFrame(I);return}if(document.hidden){W.current?.setActive(!1),C.current=requestAnimationFrame(I);return}const ke=Y.isSpeaking(),ve=Y.isWarmingUp(),Me=ke&&!A.current,Ee=A.current&&!ke;Me&&(Ve(),Ue(),q.current=!1,le.current=!1,je(w.current),Q.current?.reset(),Ot.current.reset(),gr.current=void 0,K.current=0,qe.current="sil",y.current=0,er()),Ee&&(c.current.reset(),W.current?.setActive(!1),Q.current?.reset(),D.finishIdleToSilCrossfade(),Je(),Tt.current!==null&&(Tt.current=null,ze(null)),Pe.current=!1,Et());const Ne=Ee||q.current||ge.current||pe.current,Ze=ne&&D.supportsBufferedPlayback;if(Pe.current&&!ke&&!ve&&!Ee&&!q.current&&!ge.current){if(pe.current){D.usesPixi&&D.isIdleToSilCrossfading()&&D.tickIdleToSilCrossfade(performance.now()),A.current=ke,C.current=requestAnimationFrame(I);return}if(re.current&&W.current){const oe=W.current.getVideo();if(oe.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA){const he=oe.duration,$=oe.currentTime,Ie=oe.ended||Number.isFinite($)&&$<=sn,Be=Number.isFinite(he)&&he>0&&Number.isFinite($)?Math.max(0,(he-$)*1e3):Number.POSITIVE_INFINITY;if(Ie||Be<=sc){er(),D.usesPixi&&D.isIdleToSilCrossfading()&&D.tickIdleToSilCrossfade(performance.now()),A.current=ke,C.current=requestAnimationFrame(I);return}}}}if(ve){if(er(),re.current&&W.current?.setActive(!1),D.usesPixi&&D.isIdleToSilCrossfading()){D.tickIdleToSilCrossfade(performance.now()),Y.getVisemeQueue().length>0&&ie.current===0&&(ie.current=performance.now()),A.current=Y.isSpeaking(),C.current=requestAnimationFrame(I);return}const oe=Y.getVisemeQueue();oe.length>0&&ie.current===0&&(ie.current=performance.now()),c.current.advance(performance.now());const he=c.current.getExpressionPath(),$=c.current.getDrawKey(),Ie={queue:oe,elapsedMs:0,expressionPath:he,expressionDrawKey:$,availablePaths:Lt.current};let Be=!1;Ze&&Q.current?(Q.current.warmupTick(Ie),Be=Q.current.isWarmupReady(Ie,Se.current)):D.usesPixi&&ki(O,oe,0,he,$,w.current,(Ut,vr,Jr,_r)=>{D.drawLiveFrame(Ut,vr,Jr,We=>{_r?.(We),Y.isWarmingUp()&&We!==""&&!Ti({lastDrawnKey:We})&&(ie.current=0,Y.releaseWarmupHold())})},Ut=>{Ce.current?.(Ut.label)},Lt.current);const wt=ie.current>0&&performance.now()-ie.current>ia;Ce.current?.(Be?"buffer ready":"buffering lipsync…"),(Be||wt)&&(ie.current=0,Y.releaseWarmupHold()),Gr(Y),A.current=Y.isSpeaking(),C.current=requestAnimationFrame(I);return}if(ke){er(),re.current&&W.current?.setActive(!1),D.usesPixi&&D.isIdleToSilCrossfading()&&D.finishIdleToSilCrossfade();const oe=Y.getVisemeQueue(),he=Y.getPlaybackElapsedMs();ro(oe,he),y.current=he;const $=oe.length>0?lr(oe,he):"sil";$!=="sil"&&(qe.current=$);const Ie=Uo(he,Y.getSentenceEmotions(),Y.getWordQueue(),Y.getStreamMood());if(z){const We=Vt(oi(Y.getWordQueue(),he,tr=>Vt(tr)!=null));We!==Tt.current&&(Tt.current=We,ze(We))}c.current.setTargetEmotion(Ie),c.current.setTargetEyebrow(Co(he,Y.getWordQueue(),Mt(Ie))),c.current.advance(performance.now());const Be=c.current.getExpressionPath(),wt=c.current.getDrawKey(),Ut=(We,tr,rr,Zr)=>{const ei={label:$n.current,elapsedMs:he,mouthPath:tr.mouthPath,transitionMeta:gr.current};Kr.current.set(rr,ei),Q.current?.markExternallyDisplayed(rr,Be),D.drawLiveFrame(We,tr,rr,br=>{const Ys=Kr.current.get(br)??ei;Kr.current.delete(br),Ot.current.onDrawDisplayed(Ys,oe),Q.current?.markExternallyDisplayed(br,Be),Zr?.(br)})},vr=We=>{$n.current=We.label,gr.current=We.transitionMeta,Ce.current?.(We.label)},Jr=ne&&D.supportsBufferedPlayback;let _r=!1;Jr&&Q.current&&(_r=Q.current.tick({canvas:O,queue:oe,elapsedMs:he,expressionPath:Be,expressionDrawKey:wt,playbackState:w.current,availablePaths:Lt.current,onStatus:vr,onDisplayed:(tr,rr,Zr)=>{Ot.current.onDrawDisplayed({label:Zr,elapsedMs:he,mouthPath:rr,transitionMeta:gr.current},oe)}}).usedBuffer),_r||ki(O,oe,he,Be,wt,w.current,Ut,vr,Lt.current),Ot.current.onRafTickSpeaking(),Yn.current?.(Ot.current.snapshot(oe,he))}else if(!Ne&&p.current){W.current?.setActive(!1),c.current.advance(performance.now());const oe=c.current.getExpressionPath(),he=c.current.getDrawKey();an(O,oe,he,w.current,($,Ie,Be,wt)=>D.drawLiveFrame($,Ie,Be,wt),$=>{if(R.current){Ce.current?.(R.current);return}const Ie=c.current.getTargetEmotion();Ce.current?.($==="sil"||$==="blink"?`${Ie}${$==="blink"?" · blink":""}`:$)},null,b.current)}else if(!Ne&&re.current&&W.current){const oe=W.current,he=oe.getVideo();if(he.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA){oe.setActive(!0);const $=()=>!Y.isSpeaking()&&!q.current&&!ge.current&&!p.current;D.usesPixi?(D.drawIdleVideo(he,$),$()&&Ce.current?.("idle")):_.current||(_.current=!0,nn(O,he,null,void 0,pr.current,$).then(()=>Ce.current?.("idle")).finally(()=>{_.current=!1}))}else an(O,null,"__sil__",w.current,($,Ie,Be,wt)=>D.drawLiveFrame($,Ie,Be,wt),$=>Ce.current?.($))}else Ne||an(O,null,"__sil__",w.current,(oe,he,$,Ie)=>D.drawLiveFrame(oe,he,$,Ie),oe=>Ce.current?.(oe));gt.enabled&&Gr(Y),A.current=ke,C.current=requestAnimationFrame(I)};return C.current=requestAnimationFrame(I),()=>{cancelAnimationFrame(C.current),Ve(),Ue(),ue.current.stop(),ye.current?.stop()}},[De,$e,Et,Ve,Ue,er,Gr,Je,gt.enabled,z]),d.useImperativeHandle(He,()=>({speakText:async(_,I)=>{const O=_.trim();if(!O)return;const D=U.current;if(!D||!pt.current&&!De)throw new Error("AI twin is not ready");const{ttsEngineId:Y,voiceId:ke}=Yr(I);Fe(null),Je(),V.current+=1,Ve(),Ue(),q.current=!1,le.current=!1,qe.current="sil",y.current=0,je(w.current),it(Y),p.current=!1,b.current=null,R.current=null,c.current.reset(),A.current=!1,Qr(),pe.current=!1,D.finishIdleToSilCrossfade();try{const ve=I?.fullBody??z,Me=ht.current,Ee=!!(ve&&Me),Ne=Ee?Me.waitForIdleCycleEnd():null,Ze=ue.current.speak(O,{voiceId:ke,speakingRate:I?.speakingRate??u,ttsEngineId:Y,language:I?.language??m,fullBody:ve,delayPlayback:Ee});if(Ne){try{await Promise.race([Ne.promise,Ze.then(()=>new Promise(()=>{}))])}catch(oe){throw Ne.cancel(),ue.current.releasePlaybackHold(),Me.resumeIdleLoop(),oe}ue.current.releasePlaybackHold()}await Ze}catch(ve){throw Ye(),pe.current=!1,D.finishIdleToSilCrossfade(),Et(),st(ve instanceof Error?ve.message:"TTS failed"),ve}},speakWithReply:async(_,I)=>{const O=_.trim();if(!O)return{displayText:"",spokenText:""};const D=U.current;if(!D||!pt.current&&!De)throw new Error("AI twin is not ready");const{ttsEngineId:Y,voiceId:ke}=Yr(I);Fe(null),Je(),V.current+=1,Ve(),Ue(),q.current=!1,le.current=!1,qe.current="sil",y.current=0,je(w.current),it(Y),p.current=!1,b.current=null,R.current=null,c.current.reset(),A.current=!1,Qr(),pe.current=!1,D.finishIdleToSilCrossfade();const ve=I?.brainId?.trim()||Le.current?.brainId?.trim()||void 0,Me=I?.brainUrl?.trim()||Le.current?.brainUrl?.trim()||void 0;try{const Ee=I?.fullBody??z,Ne=ht.current,Ze=!!(Ee&&Ne),oe=Ze?Ne.waitForIdleCycleEnd():null,he=ue.current.speakWithReply(O,{...I,voiceId:ke,speakingRate:I?.speakingRate??u,ttsEngineId:Y,language:I?.language??m,fullBody:Ee,delayPlayback:Ze,brainId:ve,brainUrl:Me,userName:I?.userName?.trim()||Ae?.trim()||void 0,userEmail:I?.userEmail?.trim()||be?.trim()||void 0,userContext:I?.userContext?.trim()||te?.trim()||void 0,onDisplayText:$=>{I?.onDisplayText?.($),qr.current?.($)}});if(oe){try{await Promise.race([oe.promise,he.then(()=>new Promise(()=>{}))])}catch($){throw oe.cancel(),ue.current.releasePlaybackHold(),Ne.resumeIdleLoop(),$}ue.current.releasePlaybackHold()}return await he}catch(Ee){throw Ye(),pe.current=!1,D.finishIdleToSilCrossfade(),Et(),st(Ee instanceof Error?Ee.message:"speakWithReply failed"),Ee}},stop:()=>{V.current+=1,Ve(),Ue(),q.current=!1,le.current=!1,pe.current=!1,Ye(),U.current?.finishIdleToSilCrossfade(),ue.current.stop(),ye.current?.stop(),je(w.current),Q.current?.reset(),ie.current=0,A.current=!1,Je(),Et()},setTtsEngineId:_=>{ue.current.setTtsEngineId(_),ye.current?.setTtsEngineId(_),Le.current&&(Le.current.ttsEngineId=_),it(_)},renderViseme:async(_,I)=>{const O=U.current,D=T.current;if(!O||!D||!pt.current)throw new Error("AI twin is not ready");await O.renderViseme(D,_,{from:I?.from,transitionDurationMs:I?.transitionDurationMs,gapMs:I?.gapMs,onStatus:Y=>Ce.current?.(Y)})},setEmotion:_=>{if(!pt.current)throw new Error("AI twin is not ready");const I=U.current,O=T.current;if(!I||!O)throw new Error("AI twin is not ready");V.current+=1,Ve(),Ue(),q.current=!1,le.current=!1,ge.current=!1,pe.current=!1,Ye(),ue.current.stop(),ye.current?.stop(),je(w.current),Q.current?.reset(),ie.current=0,A.current=!1,I.finishIdleToSilCrossfade(),W.current?.setActive(!1);const D=ot(_);p.current=!0,b.current=null,R.current=null,c.current.snapToEmotion(D);const Y=c.current.getExpressionPath(),ke=c.current.getDrawKey(),ve={mouthPath:null,expressionPath:Y},Me=or(ve,ke);w.current.lastDrawnKey="",I.drawLiveFrame(O,ve,Me,Ne=>{Ne===Me&&(w.current.lastDrawnKey=Me)});const Ee=Mt(D);Ce.current?.(Y?`${D} · brow ${Ee>0?"+":""}${Ee}`:`${D} · brow 0 (sil base)`)},getEmotion:()=>p.current?c.current.getTargetEmotion():null,clearEmotionPreview:()=>{p.current=!1,b.current=null,R.current=null,c.current.reset(),je(w.current),Ce.current?.("idle")},setViseme:_=>{if(!pt.current)throw new Error("AI twin is not ready");const I=U.current,O=T.current;if(!I||!O)throw new Error("AI twin is not ready");V.current+=1,Ve(),Ue(),q.current=!1,le.current=!1,ge.current=!1,pe.current=!1,Ye(),ue.current.stop(),ye.current?.stop(),je(w.current),Q.current?.reset(),ie.current=0,A.current=!1,I.finishIdleToSilCrossfade(),W.current?.setActive(!1);const D=Ur(_);p.current=!0,R.current=D,b.current=D==="sil"?null:Ht(D),c.current.snapToEmotion("neutral");const Y=c.current.getExpressionPath(),ke=c.current.getDrawKey(),Me={mouthPath:b.current,expressionPath:Y},Ee=or(Me,ke);w.current.lastDrawnKey="",I.drawLiveFrame(O,Me,Ee,Ne=>{Ne===Ee&&(w.current.lastDrawnKey=Ee)}),Ce.current?.(D)},getViseme:()=>p.current?R.current:null,isReady:()=>pt.current,getStatus:()=>we,getWordQueue:()=>ue.current.getWordQueue(),connect:async(_={})=>{Fe(null);try{let I=_.authToken?.trim();I||(I=nt.current??s??await Ir(),nt.current=I);const O=ct(_.ttsEngineId??a,_.voiceId??f),D=O.voiceId??Le.current?.voiceId,Y=_.brainId?.trim()||_.personaId?.trim()||Le.current?.brainId,ke=_.brainUrl?.trim()||Le.current?.brainUrl,ve=O.ttsEngineId??Le.current?.ttsEngineId??Ge,Me=Xn();ve&&Me.setTtsEngineId(ve),ve&&it(ve),await Me.unlockAudio(),await Me.connect({..._,apiBase:_.apiBase?.trim()||kt,authToken:I,voiceId:D,brainId:Y,brainUrl:ke,ttsEngineId:ve,speakingRate:_.speakingRate??u,language:_.language??m,fullBody:_.fullBody??z,userName:_.userName?.trim()||Ae?.trim()||void 0,userEmail:_.userEmail?.trim()||be?.trim()||void 0,userContext:_.userContext?.trim()||te?.trim()||void 0})}catch(I){throw sr(I)||st(I instanceof Error?I.message:"Voice connect failed"),I}},disconnect:async()=>{const _=ye.current;_&&(V.current+=1,Ve(),Ue(),q.current=!1,le.current=!1,pe.current=!1,Ye(),U.current?.finishIdleToSilCrossfade(),je(w.current),Q.current?.reset(),ie.current=0,A.current=!1,await _.disconnect(),Et())},isConnected:()=>ye.current?.isConnected()??!1,getVoiceStream:()=>ye.current?.getVoiceStream()??ue.current?.getVoiceStream()??null,setMuted:_=>{yr.current=_,ue.current?.setMuted(_),ye.current?.setMuted(_)},isMuted:()=>yr.current,getBrainId:()=>Le.current?.brainId?.trim()||null,getPersonaId:()=>Le.current?.brainId?.trim()||null,getBrainUrl:()=>Le.current?.brainUrl?.trim()||null}),[De,u,m,s,Ae,be,te,Ge,Dt,Ve,Ue,Et,Qr,Ye,st,Yr,Xn,it,we,kt]),M.jsxs("div",{className:l,style:{...Pc,...h},children:[M.jsx("canvas",{ref:T,width:mt.width,height:mt.height,style:{...Cc,...v},"aria-label":t?`AI twin ${t}`:"AI twin face"}),z&&De&&Qt&&(bt||Ke)?M.jsx(Pa,{ref:ht,poseSynced:Xe,gesturesBase:es(bt||Ke),keyHex:Qt,status:we,activePose:Oe}):null,!dr&&!xe?M.jsx(tc,{thumbnailUrl:qs}):null,F&&xe?M.jsx("div",{style:Bc,children:xe}):null,gt.enabled&&qt?M.jsx(Xo,{text:qt,style:gt.style},qt):null]})});function Fc({muted:e}){return e?M.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none","aria-hidden":!0,children:[M.jsx("path",{d:"M11 5 6.5 9H3v6h3.5L11 19V5Z",fill:"currentColor"}),M.jsx("path",{d:"m16 9.5 5 5m0-5-5 5",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round"})]}):M.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none","aria-hidden":!0,children:[M.jsx("path",{d:"M11 5 6.5 9H3v6h3.5L11 19V5Z",fill:"currentColor"}),M.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 Dc(){return M.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":!0,children:M.jsx("path",{d:"M8 5.5v13l11-6.5L8 5.5Z"})})}function Lc(){return M.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":!0,children:M.jsx("rect",{x:"6",y:"6",width:"12",height:"12",rx:"1.5"})})}function Oc(){return M.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none","aria-hidden":!0,children:M.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 Nc(){return M.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none","aria-hidden":!0,children:M.jsx("path",{d:"M15 6 9 12l6 6",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}function Uc(){return M.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none","aria-hidden":!0,children:M.jsx("path",{d:"M12 19V5m0 0-6 6m6-6 6 6",stroke:"currentColor",strokeWidth:"2.25",strokeLinecap:"round",strokeLinejoin:"round"})})}function Vc(){return M.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":!0,children:M.jsx("rect",{x:"6",y:"6",width:"12",height:"12",rx:"2"})})}function Pi({className:e}){return M.jsx("span",{className:e??"aitwin-widget__spinner","aria-hidden":!0,children:M.jsx("svg",{viewBox:"0 0 24 24",fill:"none",children:M.jsx("circle",{cx:"12",cy:"12",r:"9",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeDasharray:"40 20"})})})}function Wc({muted:e,onToggle:t}){return M.jsx("button",{type:"button",className:"aitwin-widget__mute",onClick:t,"aria-label":e?"Unmute":"Mute","aria-pressed":e,children:M.jsx(Fc,{muted:e})})}function jc(e){const t=e.status==="speaking",r=e.connecting||e.textSending||e.status==="loading"||t,n=e.connected?"End":"Talk",i=["aitwin-widget__action","aitwin-widget__action--primary",e.connecting?"aitwin-widget__action--connecting":""].filter(Boolean).join(" ");return M.jsxs("div",{className:e.textMode?"aitwin-widget__controls aitwin-widget__controls--text":"aitwin-widget__controls",children:[e.textMode?M.jsxs("form",{className:"aitwin-widget__composer",onSubmit:s=>{if(s.preventDefault(),t){e.onStopSpeech();return}e.onSendText()},children:[M.jsx("button",{type:"button",className:"aitwin-widget__composer-back",onClick:e.onTextMode,disabled:e.textSending&&!t,"aria-label":"Back",children:M.jsx(Nc,{})}),M.jsx("input",{type:"text",className:"aitwin-widget__composer-input",value:e.textDraft,onChange:s=>e.onTextDraftChange(s.target.value),placeholder:t?"Speaking…":e.textSending?"Getting reply...":"Type a message...",autoComplete:"off",disabled:!e.ready||r&&!t,autoFocus:!0}),t?M.jsx("button",{type:"button",className:"aitwin-widget__composer-send aitwin-widget__composer-send--stop",onClick:e.onStopSpeech,"aria-label":"Stop",children:M.jsx(Vc,{})}):M.jsx("button",{type:"submit",className:"aitwin-widget__composer-send",disabled:!e.ready||r||!e.textDraft.trim()&&!e.textSending,"aria-label":"Send","aria-busy":e.textSending,children:e.textSending?M.jsx(Pi,{className:"aitwin-widget__spinner aitwin-widget__spinner--on-accent"}):M.jsx(Uc,{})})]}):M.jsxs("div",{className:"aitwin-widget__actions",children:[M.jsxs("button",{type:"button",className:i,onClick:e.onTalk,disabled:!e.ready||e.connecting||e.textSending,"aria-busy":e.connecting,"aria-label":e.connecting?"Connecting":n,children:[e.connecting?M.jsx(Pi,{className:"aitwin-widget__spinner aitwin-widget__spinner--on-accent"}):e.connected?M.jsx(Lc,{}):M.jsx(Dc,{}),M.jsx("span",{children:n})]}),M.jsxs("button",{type:"button",className:"aitwin-widget__action",onClick:e.onTextMode,disabled:!e.ready||e.connecting||e.textSending,"aria-pressed":!1,children:[M.jsx(Oc,{}),M.jsx("span",{children:"Text"})]})]}),e.error?M.jsx("p",{className:"aitwin-widget__controls-error",role:"alert",children:e.error}):null]})}const Ci=97,Hc=3500;function $c(e,t){const r=Math.max(0,e),n=1-Math.exp(-r/Hc);return Math.min(Ci,Math.round(n*Ci))}function zc(e){const[t,r]=d.useState(null),[n,i]=d.useState(()=>Date.now());return d.useEffect(()=>{if(!e){r(null);return}const s=Date.now();r(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:$c(n-t):100}const Gc="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 Kc({className:e="aitwin-widget__logo",strokeWidth:t=15,durationMs:r=2600,delayMs:n=0,loop:i=!1}){return M.jsx("svg",{viewBox:"0 0 1080 1080",className:e,role:"img","aria-label":"AITWIN logo",children:M.jsx("path",{className:i?"aitwin-widget__logo-draw aitwin-widget__logo-draw--loop":"aitwin-widget__logo-draw",d:Gc,fill:"none",stroke:"currentColor",strokeWidth:t,strokeMiterlimit:10,pathLength:1,style:{animationDuration:`${r}ms`,animationDelay:`${n}ms`}})})}function qc({progress:e}){const t=Math.max(0,Math.min(100,Math.round(e)));return M.jsx("div",{className:"aitwin-widget__face-loading","aria-live":"polite","aria-label":`Loading ${t} percent`,children:M.jsxs("div",{className:"aitwin-widget__face-loading-content",children:[M.jsx(Kc,{className:"aitwin-widget__logo",loop:!0,durationMs:2600}),M.jsxs("div",{className:"aitwin-widget__face-loading-bar-wrap",children:[M.jsx("div",{role:"progressbar","aria-valuenow":t,"aria-valuemin":0,"aria-valuemax":100,className:"aitwin-widget__face-loading-track",children:M.jsx("div",{className:"aitwin-widget__face-loading-fill",style:{width:`${t}%`}})}),M.jsxs("p",{className:"aitwin-widget__face-loading-pct",children:[t,"%"]})]})]})})}function Bi(e){const t=e.id?.trim()||void 0,r=e.faceId?.trim()||e.avatarId?.trim()||void 0;return{id:r?void 0:t,faceId:r,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 Yc(e){return[e.id??"",e.faceId??"",e.authToken?.slice(0,16)??"",e.voiceId??"",e.apiBase??"",String(e.speakingRate??"")].join("|")}const Fi={display:"flex",alignItems:"center",justifyContent:"center",width:"100%",height:"100%",lineHeight:0},Qc={display:"block",height:"100%",width:"100%",objectFit:"cover",objectPosition:"top"},Xc=d.forwardRef(function({options:t},r){const n=d.useRef(null),i=d.useRef(t);i.current={...i.current,onReady:t.onReady,onStatusChange:t.onStatusChange,onError:t.onError,onUserTranscript:t.onUserTranscript,onBotOutput:t.onBotOutput};const[s,o]=d.useState(!!t.showControls),[a,f]=d.useState(()=>Bi(t)),[m,u]=d.useState(!1),[l,h]=d.useState(!1),[v,E]=d.useState(!1),[g,P]=d.useState(!1),[j,F]=d.useState("idle"),[S,x]=d.useState(null),[L,H]=d.useState(!1),[G,ne]=d.useState(!1),[B,N]=d.useState(""),[X,se]=d.useState(!1),[de,ae]=d.useState([]),[Ae,be]=d.useState(t.brainId?.trim()||t.personaId?.trim()||void 0),[te,He]=d.useState(t.brainUrl?.trim()||void 0),T=d.useCallback(k=>{i.current={...i.current,...k},k.showControls!==void 0&&o(!!k.showControls),(k.brainId!==void 0||k.personaId!==void 0)&&be((k.brainId??k.personaId)?.trim()||void 0),k.brainUrl!==void 0&&He(k.brainUrl.trim()||void 0),f(q=>Bi({id:k.id??q.id,faceId:k.faceId??k.avatarId??q.faceId,authToken:k.authToken??q.authToken,apiBase:k.apiBase??q.apiBase,voiceId:k.voiceId??q.voiceId,speakingRate:k.speakingRate??q.speakingRate,language:k.language??q.language}))},[]);d.useImperativeHandle(r,()=>({getTwin:()=>n.current,applyOptions:T}),[T]),d.useEffect(()=>{T(t)},[T,t.id,t.faceId,t.avatarId,t.authToken,t.apiBase,t.voiceId,t.speakingRate,t.showControls,t.brainId,t.personaId,t.brainUrl]);const Z=d.useCallback(()=>{u(!0),x(null)},[]),ee=d.useCallback(k=>{k==="idle"&&h(!0)},[]),z=d.useCallback(k=>{F(k),i.current.onStatusChange?.(k)},[]),fe=d.useRef(!1);fe.current=m&&l;const U=d.useCallback(k=>{if(P(!1),sr(k)){ne(!0),x(null);return}x(k),fe.current||(u(!1),h(!1)),i.current.onError?.(k)},[]),Q=d.useCallback((k,q)=>{i.current.onUserTranscript?.(k,q)},[]),ce=d.useCallback(k=>{i.current.onBotOutput?.(k)},[]);d.useEffect(()=>{if(!s)return;const k=window.setInterval(()=>{E(!!n.current?.isConnected())},400);return()=>window.clearInterval(k)},[s,a]);const Se=Yc(a),me=!!(a.id||a.faceId),Te=m&&l,ie=me&&!Te&&!S,w=zc(ie),c=d.useRef(Se);d.useEffect(()=>{Te&&i.current.onReady?.()},[Te]),d.useEffect(()=>{Te&&n.current?.setMuted(L)},[Te,L,a]),d.useEffect(()=>{ae([])},[a.id,a.faceId]),d.useEffect(()=>{c.current!==Se&&(c.current=Se,u(!1),h(!1),x(null),P(!1),E(!1),F("idle"))},[Se]);const p=d.useCallback(()=>{ne(!0),x(null),P(!1),E(!1)},[]),b=()=>{const k=n.current;if(!k?.isReady())return;if(x(null),k.isConnected()){P(!1),ne(!1),k.disconnect().finally(()=>{E(!1)});return}P(!0);const q={authToken:a.authToken,voiceId:a.voiceId,speakingRate:a.speakingRate,language:a.language,apiBase:a.apiBase,...Ae?{brainId:Ae}:{},...te?{brainUrl:te}:{}};(async()=>{if(await no()){p();return}ne(!1);try{await k.connect(q),E(!!k.isConnected())}catch(le){if(sr(le)){p();return}const ge=le instanceof Error?le.message:"Failed to connect voice.";x(ge),i.current.onError?.(ge)}finally{P(!1)}})()},R=()=>{ne(k=>!k),x(null)},C=d.useRef(0),V=()=>{const k=B.trim(),q=n.current;if(!k||!q?.isReady()||X)return;x(null),N(""),se(!0);const le=++C.current;i.current.onUserTranscript?.(k,!0),(async()=>{try{const ge=Ae||q.getBrainId()?.trim()||void 0,pe=te||q.getBrainUrl()?.trim()||void 0,Pe=await q.speakWithReply(k,{brainId:ge,brainUrl:pe,history:de,voiceId:a.voiceId,speakingRate:a.speakingRate,language:a.language});if(le!==C.current)return;Pe.displayText&&ae(qe=>[...qe,{role:"user",content:k},{role:"assistant",content:Pe.displayText}])}catch(ge){if(le!==C.current)return;const pe=ge instanceof Error?ge.message:"Failed to get reply.";x(pe),i.current.onError?.(pe)}finally{le===C.current&&se(!1)}})()},K=()=>{C.current+=1,n.current?.stop(),se(!1)},J=()=>{const k=!L;H(k),n.current?.setMuted(k)};return M.jsxs("div",{className:"aitwin-widget__layout",children:[M.jsxs("div",{className:"aitwin-widget__stage",children:[me?M.jsx("div",{style:Fi,children:M.jsx(Hs,{ref:n,id:a.id,faceId:a.faceId,authToken:a.authToken,apiBase:a.apiBase,voiceId:a.voiceId,speakingRate:a.speakingRate,language:a.language,fullBody:t.fullBody,style:Fi,canvasStyle:Qc,onReady:Z,onDisplayStatus:ee,onStatusChange:z,onError:U,onUserTranscript:Q,onBotOutput:ce,loadingThumbnailUrl:t.loadingThumbnailUrl},Se)}):M.jsx("p",{className:"aitwin-widget__hint",style:{padding:16},children:"Pass id or faceId to load a twin."}),ie?M.jsx(qc,{progress:w}):null,s?M.jsx(Wc,{muted:L,onToggle:J}):null]}),s?M.jsx(jc,{ready:Te,connected:v,connecting:g,status:j,textMode:G,textDraft:B,textSending:X,error:S,onTalk:b,onTextMode:R,onTextDraftChange:N,onSendText:V,onStopSpeech:K}):null]})}),Jc=".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-composer-width: calc(340px * var(--aitwin-size));--aitwin-composer-height: calc(40px * var(--aitwin-size));--aitwin-action-height: calc(32px * 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));--aitwin-float-inset: 20px;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{align-items:flex-end;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__controls--text{max-width:calc(100vw - (2 * var(--aitwin-float-inset)));width:var(--aitwin-composer-width)}.aitwin-widget__actions{align-items:center;display:flex;gap:var(--aitwin-action-gap);width:100%}.aitwin-widget__action{align-items:center;appearance:none;background:transparent;border:1.5px solid var(--aitwin-accent);border-radius:999px;box-sizing:border-box;color:var(--aitwin-accent);cursor:pointer;display:inline-flex;flex:1 1 0;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;line-height:1;margin:0;min-height:var(--aitwin-action-height);min-width:0;overflow:hidden;padding:0 calc(10px * var(--aitwin-size))}.aitwin-widget__action span{display:inline-flex;line-height:1}.aitwin-widget__action svg{display:block;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:var(--aitwin-accent);color:#fff}.aitwin-widget__action--primary:hover:not(:disabled){background:var(--aitwin-accent-hover);border-color:var(--aitwin-accent-hover)}.aitwin-widget__action--connecting:disabled{cursor:progress;opacity:1}.aitwin-widget__spinner{display:inline-flex;flex-shrink:0;height:calc(12px * var(--aitwin-size));width:calc(12px * var(--aitwin-size))}.aitwin-widget__spinner svg{animation:aitwin-widget-spin .8s linear infinite;display:block;height:100%;width:100%}.aitwin-widget__spinner--on-accent,.aitwin-widget__action .aitwin-widget__spinner{color:#fff}@keyframes aitwin-widget-spin{to{transform:rotate(360deg)}}.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{align-items:center;background:#fff;border:1.5px solid var(--aitwin-accent);border-radius:999px;display:flex;gap:calc(4px * var(--aitwin-size));height:var(--aitwin-composer-height);padding:calc(4px * var(--aitwin-size));width:100%}.aitwin-widget__composer-back{align-items:center;background:transparent;border:none;border-radius:999px;color:#9ca3af;cursor:pointer;display:inline-flex;flex-shrink:0;height:calc(30px * var(--aitwin-size));justify-content:center;padding:0;width:calc(30px * var(--aitwin-size))}.aitwin-widget__composer-back:hover:not(:disabled){color:#4b5563}.aitwin-widget__composer-back:disabled{cursor:not-allowed;opacity:.45}.aitwin-widget__composer-back svg{display:block;height:calc(16px * var(--aitwin-size));width:calc(16px * var(--aitwin-size))}.aitwin-widget__composer-input{background:transparent;border:none;color:#111827;flex:1;font-family:inherit;font-size:calc(14px * var(--aitwin-size));min-width:0;outline:none;padding:0 calc(4px * var(--aitwin-size))}.aitwin-widget__composer-input::placeholder{color:#9ca3af}.aitwin-widget__composer-input:disabled{opacity:.7}.aitwin-widget__composer-send{align-items:center;background:var(--aitwin-accent);border:none;border-radius:999px;color:#fff;cursor:pointer;display:inline-flex;flex-shrink:0;height:calc(30px * var(--aitwin-size));justify-content:center;padding:0;width:calc(30px * var(--aitwin-size))}.aitwin-widget__composer-send:hover:not(:disabled){background:var(--aitwin-accent-hover)}.aitwin-widget__composer-send:disabled{cursor:not-allowed;opacity:.45}.aitwin-widget__composer-send--stop{opacity:1}.aitwin-widget__composer-send svg{display:block;height:calc(14px * var(--aitwin-size));width:calc(14px * var(--aitwin-size))}.aitwin-widget__controls-error{color:#fecaca;font-size:calc(11px * var(--aitwin-size));margin:0}.aitwin-widget--float{bottom:var(--aitwin-float-inset);filter:drop-shadow(0 12px 32px rgba(0,0,0,.45));height:fit-content;margin:0;max-width:calc(100vw - (2 * var(--aitwin-float-inset)));position:fixed;right:var(--aitwin-float-inset);width:fit-content;z-index:2147483000}@media(max-width:640px){.aitwin-widget{--aitwin-composer-width: calc(100vw - (2 * var(--aitwin-float-inset)));--aitwin-composer-height: calc(44px * var(--aitwin-size))}.aitwin-widget__controls--text{width:var(--aitwin-composer-width)}.aitwin-widget__composer-input{font-size:calc(15px * var(--aitwin-size))}}",Di="data-aitwin-widget-style";function $s(){if(typeof document>"u")return;const e=Jc.trim();if(!e){console.warn("[AiTwinWidget] styles.css?inline resolved empty — chrome will be unstyled");return}const t=document.querySelector(`style[${Di}]`);if(t){if((t.textContent??"").trim().length>0)return;t.textContent=e;return}const r=document.createElement("style");r.setAttribute(Di,"1"),r.textContent=e,(document.head??document.documentElement).appendChild(r)}typeof document<"u"&&$s();const Zc=d.forwardRef(function(t,r){$s();const n=d.useRef(null);d.useImperativeHandle(r,()=>({speakText:async(s,o)=>{const a=n.current?.getTwin();if(!a)throw new Error("AiTwinWidget: twin is not mounted");return a.speakText(s,o)},speakWithReply:async(s,o)=>{const a=n.current?.getTwin();if(!a)throw new Error("AiTwinWidget: twin is not mounted");return a.speakWithReply(s,o)},connect:async s=>{const o=n.current?.getTwin();if(!o)throw new Error("AiTwinWidget: twin is not mounted");return o.connect(s)},disconnect:async()=>{const s=n.current?.getTwin();if(s)return s.disconnect()},stop:()=>{n.current?.getTwin()?.stop()},isReady:()=>!!n.current?.getTwin()?.isReady(),isConnected:()=>!!n.current?.getTwin()?.isConnected(),getTwin:()=>n.current?.getTwin()??null}),[]);const i=!!t.float;return M.jsx("div",{className:i?"aitwin-widget aitwin-widget--float":"aitwin-widget",children:M.jsx(Xc,{ref:n,options:t})})}),el=new Set([".png",".jpg",".jpeg",".webp"]);function zs(e=".png"){const t=e.toLowerCase();return el.has(t)?`source${t}`:"source.png"}function tl(e,t=Dr,r=".png"){const n=e.trim();if(!n)throw new Error("faceId is required");return`${t.replace(/\/$/,"")}/${n}/${zs(r)}`}function Gs(e,t){if(e&&typeof e=="object"&&"detail"in e){const r=e.detail;if(typeof r=="string"&&r.trim())return r}return t}async function rl(e){const t=new FormData;t.append("image",e.image),e.name?.trim()&&t.append("name",e.name.trim()),e.fullBody&&t.append("fullBody","true");const r=(e.apiBase??lt).replace(/\/$/,""),n=await fetch(`${r}/createAiTwinFace`,{method:"POST",headers:{Authorization:`Bearer ${e.authToken}`},body:t}),i=await n.json().catch(()=>null);if(!n.ok)throw new Error(Gs(i,`createAiTwinFace failed (${n.status})`));return i}async function nl(e,t){const r=(t.apiBase??lt).replace(/\/$/,""),n=new URL(`${r}/getAiTwinFaceStatus`);n.searchParams.set("avatarId",e.trim());const i=await fetch(n.toString(),{headers:{Authorization:`Bearer ${t.authToken}`}}),s=await i.json().catch(()=>null);if(!i.ok)throw new Error(Gs(s,`getAiTwinFaceStatus failed (${i.status})`));return s}async function il(e=lt){const t=e.replace(/\/$/,"");try{const r=await fetch(`${t}/getAiTwinGestureCatalog`);if(r.ok)return await r.json()}catch{}return{success:!0,fullBody:!0,poses:[Mr.idle,...cr.map(r=>Mr[r])].filter(r=>!!r),encrypted:!0,pathTemplate:"custom-faces/{avatarId}/ges/{code}.bin",cropMetaPath:"custom-faces/{avatarId}/ges/m.json"}}async function sl(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 al(e){const t=e.message.trim();if(!t)throw new Error("Message is required");const r=e.authToken.trim();if(!r)throw new Error("Auth token is required");const n=(e.apiBase?.trim()||lt).replace(/\/$/,""),i=await fetch(`${n}/avatarReply`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${r}`,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 sl(i));if(!i.body)throw new Error("avatarReply response body is empty");const s=i.body.getReader(),o=new TextDecoder;let a="",f="",m="",u="";for(;;){const{done:l,value:h}=await s.read();if(l)break;a+=o.decode(h,{stream:!0});const v=a.split(`
48
+ `);a=v.pop()||"";for(const E of v){if(E.startsWith("event: ")){u=E.slice(7).trim();continue}if(!E.startsWith("data: "))continue;const g=E.slice(6).trim();if(!g)continue;let P;try{P=JSON.parse(g)}catch{continue}if(u==="spokenText")f=P.text||"",e.onSpokenText?.(f);else if(u==="displayText")m=P.text||"";else if(u==="error")throw new Error(P.error||"avatarReply stream error")}}if(!f.trim()||!m.trim())throw new Error("avatarReply stream missing displayText or spokenText");return{displayText:m.trim(),spokenText:f.trim()}}exports.AI_TWIN_THUMBNAIL_FILENAME=xn;exports.AiTwin=Hs;exports.AiTwinNotFoundError=Ar;exports.AiTwinWidget=Zc;exports.CONSONANT_SKIP_GROUP=us;exports.DEFAULT_TTS_ENGINE_ID=At;exports.DEFAULT_TTS_LANGUAGE=Da;exports.EMOTION_TO_EYEBROW=Fs;exports.EXPRESSION_ATLAS_EMOTIONS=To;exports.FULLBODY_GESTURE_POSES=cr;exports.MIC_SAMPLE_RATE=Bn;exports.OCULUS_VISEME_IDS=as;exports.PLAYBACK_SAMPLE_RATE=Fn;exports.SPEAKING_RATE_MAX=$r;exports.SPEAKING_RATE_MIN=Hr;exports.TTS_ENGINE_CARTESIA=ut;exports.TTS_ENGINE_GOOGLE=Sn;exports.TTS_ENGINE_INWORLD=Lr;exports.TTS_ENGINE_VISEMETTS=dt;exports.TTS_LANGUAGE_CATALOG=Rt;exports.TTS_LANGUAGE_CODES=ns;exports.VISEME_IDS=uo;exports.VISEME_SKIP_GAP_MS=hn;exports.VISEME_TEST_CARTESIA_VOICE_ID=Cn;exports.VISEME_TEST_SPEAKING_RATE=ur;exports.VISEME_TEST_VISEMETTS_VOICE_ID=Or;exports.VISEME_TEST_VOICE_ID=Pn;exports.VISEME_VTIME_GRID_MS=In;exports.VOWEL_SKIP_GROUP=ls;exports.aiTwinSourceFilename=zs;exports.buildPlaybackTransitions=ws;exports.buildPlaybackVisemeSeries=Wr;exports.buildRawVisemeTransitions=gs;exports.buildVoiceWebSocketUrl=xs;exports.compactSkippableVisemes=Rn;exports.createAiTwinFace=rl;exports.createAvatarTtsLipsyncController=pn;exports.createRealtimeVoiceLipsyncController=Is;exports.emotionToEyebrow=Mt;exports.faceAssetUrls=mn;exports.fetchAiTwin=Wi;exports.fetchAvatarReply=al;exports.fetchDevAuthToken=Ir;exports.gesturesBaseForFace=es;exports.getAiTwinFaceStatus=nl;exports.getAiTwinGestureCatalog=il;exports.getAiTwinSourceUrl=tl;exports.getAiTwinThumbnailUrl=ji;exports.getFullBodyCropMetaUrl=ts;exports.getFullBodyGestureBinUrl=rs;exports.isFullBodyGesturePose=Aa;exports.isTtsLanguageCode=is;exports.isTtsLanguageSupported=Oa;exports.listSkippedVisemeEntries=jr;exports.listSkippedVisemes=qa;exports.normalizeFullBodyGesturePose=Vt;exports.normalizeOculusViseme=Ur;exports.normalizeStreamEmotion=ot;exports.normalizeTtsLanguage=Nr;exports.parsePackedVoiceId=Oi;exports.parseTwinBrainUrl=la;exports.resolveDirectFaceId=Hi;exports.resolveTwinBrainId=kn;exports.resolveTwinBrainUrl=En;exports.resolveVisemeAtTime=lr;exports.resolveVisemeFromPlaybackSeries=ms;exports.resolveWordAtTime=Es;exports.setActiveTwinAssets=$i;exports.snapVisemeQueueToGrid=An;exports.snapVisemeVtimeToGrid=ds;exports.splitVoiceIdSpec=ct;exports.ttsLanguagesForEngine=La;