'+ae+"");const vt=D?Q(ae):ae;if(hn===Vt)try{we=new p().parseFromString(vt,Un)}catch{}if(!we||!we.documentElement){we=ne.createDocument(hn,"template",null);try{we.documentElement.innerHTML=bn?P:vt}catch{}}const Rt=we.body||we.documentElement;return ae&&ht&&Rt.insertBefore(n.createTextNode(ht),Rt.childNodes[0]||null),hn===Vt?_.call(we,be?"html":"body")[0]:be?we.documentElement:Rt},et=function(ae){const we=z?z(ae):ae.ownerDocument;return Y.call(we||ae,ae,m.SHOW_ELEMENT|m.SHOW_COMMENT|m.SHOW_TEXT|m.SHOW_PROCESSING_INSTRUCTION|m.SHOW_CDATA_SECTION,null)},Ye=function(ae){return ae=gd(ae,Je," "),ae=gd(ae,xe," "),ae=gd(ae,ee," "),ae},$e=function(ae){var we;ae.normalize();const ht=z?z(ae):ae.ownerDocument,vt=Y.call(ht||ae,ae,m.SHOW_TEXT|m.SHOW_COMMENT|m.SHOW_CDATA_SECTION|m.SHOW_PROCESSING_INSTRUCTION,null);let Rt=vt.nextNode();for(;Rt;)Rt.data=Ye(Rt.data),Rt=vt.nextNode();const Wt=(we=ae.querySelectorAll)===null||we===void 0?void 0:we.call(ae,"template");Wt&&$o(Wt,an=>{Et(an.content)&&$e(an.content)})},Qe=function(ae){const we=I?I(ae):null;return typeof we!="string"||Rn(we)!=="form"?!1:typeof ae.nodeName!="string"||typeof ae.textContent!="string"||typeof ae.removeChild!="function"||ae.attributes!==R(ae)||typeof ae.removeAttribute!="function"||typeof ae.removeAttributeNode!="function"||typeof ae.getAttributeNode!="function"||typeof ae.setAttribute!="function"||typeof ae.namespaceURI!="string"||typeof ae.insertBefore!="function"||typeof ae.hasChildNodes!="function"||ae.nodeType!==N(ae)||ae.childNodes!==E(ae)},Et=function(ae){if(!N||typeof ae!="object"||ae===null)return!1;try{return N(ae)===Li.documentFragment}catch{return!1}},zt=function(ae){if(!N||typeof ae!="object"||ae===null)return!1;try{return typeof N(ae)=="number"}catch{return!1}};function It(gt,ae,we){gt.length!==0&&$o(gt,ht=>{ht.call(e,ae,we,Mi)})}const Sn=function(ae,we){return!!(Ne&&ae.hasChildNodes()&&!zt(ae.firstElementChild)&&Ba(mM,ae.textContent)&&Ba(mM,ae.innerHTML)||Ne&&ae.namespaceURI===Vt&&B8[we]&&(zt(ae.firstElementChild)||typeof ae.textContent=="string"&&Ba(H8[we],ae.textContent))||ae.nodeType===Li.processingInstruction||Ne&&ae.nodeType===Li.comment&&Ba(gM,ae.data))},Lt=function(ae,we){if(ae instanceof RegExp)return Ba(ae,we);if(ae instanceof Function){for(var ht=arguments.length,vt=new Array(ht>2?ht-2:0),Rt=2;Rt=0;--an){const Bn=ae===ht?x(Rt[an],!0):Rt[an];vt.insertBefore(Bn,w(ae))}}}return St(ae),!0},mn=function(ae,we,ht,vt){return ae.length===0?we:we===ht||we===vt?Ii(we):we},Gt=function(ae,we){return ae===we||A(ae)!==null?!1:(Fe&&Ht(ae),!0)},An=function(ae,we){if(It(je.beforeSanitizeElements,ae,null),Gt(ae,we))return!0;if(Qe(ae))return St(ae),!0;const ht=Rn(L(ae));if(Pe=mn(je.uponSanitizeElement,Pe,mt,Ve),It(je.uponSanitizeElement,ae,{tagName:ht,allowedTags:Pe}),Gt(ae,we))return!0;if(Sn(ae,ht))return St(ae),!0;if(We[ht]||!(ft.tagCheck instanceof Function&&ft.tagCheck(ht))&&!Pe[ht]){const vt=nn(ae,ht,we);return vt===!1&&(It(je.afterSanitizeElements,ae,null),Gt(ae,we))?!0:vt}if(j(ae)===Li.element&&!bt(ae)||(ht==="noscript"||ht==="noembed"||ht==="noframes")&&Ba(U8,ae.innerHTML))return St(ae),!0;if(Ae&&ae.nodeType===Li.text){const vt=Ye(ae.textContent);ae.textContent!==vt&&(md(e.removed,{element:ae.cloneNode()}),ae.textContent=vt)}return It(je.afterSanitizeElements,ae,null),Gt(ae,we)},oi=function(ae,we,ht){if(ue[we]||ge(we,ae)||tt&&(we==="id"||we==="name")&&(ht in n||ht in qs))return!1;const vt=it[we]||ft.attributeCheck instanceof Function&&ft.attributeCheck(we,ae);return K&&Ba(Ce,we)||Re&&Ba(Ze,we)?!0:vt?G[we]||Ba(se,gd(ht,qe,""))||(we==="src"||we==="xlink:href"||we==="href")&&ae!=="script"&&oM(ht,"data:")===0&&U[ae]||B&&!Ba(le,gd(ht,qe,""))?!0:!ht:Fn(ae)&&Lt(Be.tagNameCheck,ae)&&Lt(Be.attributeNameCheck,we,ae)||we==="is"&&Be.allowCustomizedBuiltInElements&&Lt(Be.tagNameCheck,ht)},Ft=fn({},["annotation-xml","color-profile","font-face","font-face-format","font-face-name","font-face-src","font-face-uri","missing-glyph"]),Fn=function(ae){return!Ft[Od(ae)]&&Ba(xt,ae)},Mo=function(ae,we,ht,vt){if(D&&typeof y=="object"&&typeof y.getAttributeType=="function"&&!ht)switch(y.getAttributeType(ae,we)){case"TrustedHTML":return Q(vt);case"TrustedScriptURL":return V(vt)}return vt},zl=function(ae,we,ht,vt){try{return ht?ae.setAttributeNS(ht,we,vt):ae.setAttribute(we,vt),Qe(ae)?(St(ae),!1):!0}catch{return Nt(we,ae),!1}},Ws=function(ae,we){if(It(je.beforeSanitizeAttributes,ae,null),Gt(ae,we))return;const ht=ae.attributes;if(!ht||Qe(ae))return;it=mn(je.uponSanitizeAttribute,it,at,ut);const vt={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:it,forceKeepAttr:void 0};let Rt=ht.length;const Wt=Rn(ae.nodeName);for(;Rt--;){const an=ht[Rt],Bn=an.name,Va=an.namespaceURI,pa=an.value,Pa=Rn(Bn),Co=pa;let $n=Bn==="value"?Co:b8(Co),cs=!1;if(vt.attrName=Pa,vt.attrValue=$n,vt.keepAttr=!0,vt.forceKeepAttr=void 0,It(je.uponSanitizeAttribute,ae,vt),$n=vt.attrValue,ct&&(Pa==="id"||Pa==="name")&&oM($n,fe)!==0&&(Nt(Bn,ae,an),$n=fe+$n,cs=!0),Ne&&Ba(/((--!?|])>)|<\/(style|script|title|xmp|textarea|noscript|iframe|noembed|noframes)/i,$n)){Nt(Bn,ae,an);continue}if(Pa==="attributename"&&rM($n,"href")){Nt(Bn,ae,an);continue}if(!vt.forceKeepAttr){if(!vt.keepAttr){Nt(Bn,ae,an);continue}if(!pe&&Ba(F8,$n)){Nt(Bn,ae,an);continue}if(Ae&&($n=Ye($n)),!oi(Wt,Pa,$n)){Nt(Bn,ae,an);continue}$n=Mo(Wt,Pa,Va,$n),$n!==Co&&zl(ae,Bn,Va,$n)&&cs&&sM(e.removed)}}It(je.afterSanitizeAttributes,ae,null),Gt(ae,we)},kr=function(ae){let we=null;const ht=et(ae);for(It(je.beforeSanitizeShadowDOM,ae,null);we=ht.nextNode();)if(It(je.uponSanitizeShadowNode,we,null),An(we,ae),Ws(we,ae),Et(we.content)&&kr(we.content),j(we)===Li.element){const vt=k(we);Et(vt)&&(wu(vt),kr(vt))}It(je.afterSanitizeShadowDOM,ae,null)},wu=function(ae){const we=[{node:ae,shadow:null}];for(;we.length>0;){const ht=we.pop();if(ht.shadow){kr(ht.shadow);continue}const vt=ht.node,Rt=j(vt)===Li.element,Wt=E(vt);if(Wt)for(let an=Wt.length-1;an>=0;--an)we.push({node:Wt[an],shadow:null});if(Rt){const an=I?I(vt):null;if(typeof an=="string"&&Rn(an)==="template"){const Bn=vt.content;Et(Bn)&&we.push({node:Bn,shadow:null})}}if(Rt){const an=k(vt);Et(an)&&we.push({node:null,shadow:an},{node:an,shadow:null})}}};return e.sanitize=function(gt){let ae=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},we=null,ht=null,vt=null,Rt=null;if(bn=!gt,bn&&(gt="\x3C!-->"),typeof gt!="string"&&!zt(gt)&&(gt=M8(gt),typeof gt!="string"))throw $r("dirty is not a string, aborting");if(!e.isSupported)return gt;ot?(Pe=Ve,it=ut):Z(ae),(je.uponSanitizeElement.length>0||je.uponSanitizeAttribute.length>0)&&(Pe=Ii(Pe)),je.uponSanitizeAttribute.length>0&&(it=Ii(it)),e.removed=[];const Wt=Fe&&typeof gt!="string"&&zt(gt);if(Wt){Te(gt);const Va=L(gt);if(typeof Va=="string"){const pa=Rn(Va);if(!Pe[pa]||We[pa])throw Tt(gt),$r("root node is forbidden and cannot be sanitized in-place")}if(Qe(gt))throw Tt(gt),$r("root node is clobbered and cannot be sanitized in-place");try{wu(gt)}catch(pa){throw Tt(gt),pa}}else if(zt(gt))we=Le("\x3C!---->"),ht=we.ownerDocument.importNode(gt,!0),ht.nodeType===Li.element&&ht.nodeName==="BODY"||ht.nodeName==="HTML"?we=ht:we.appendChild(ht),wu(we);else{if(!Se&&!Ae&&!be&>.indexOf("<")===-1)return D&<?Q(gt):gt;if(we=Le(gt),!we)return Se?null:lt?P:""}we&&re&&St(we.firstChild);const an=Wt?gt:we;try{const Va=et(an);for(;vt=Va.nextNode();)An(vt,an),Ws(vt,an),Et(vt.content)&&kr(vt.content)}catch(Va){throw Wt&&(Tt(gt),$o(e.removed,pa=>{pa.element&&Ht(pa.element)})),Va}if(Wt){let Va=!1;if($o(e.removed,pa=>{pa.element&&(pa.element===gt&&(Va=!0),Ht(pa.element))}),Va)throw $r("a node selected for removal could not be safely returned; refusing to sanitize in place");return Ae&&$e(gt),gt}if(Se){if(Ae&&$e(we),He)for(Rt=T.call(we.ownerDocument);we.firstChild;)Rt.appendChild(we.firstChild);else Rt=we;return(it.shadowroot||it.shadowrootmode)&&(Rt=ve.call(s,Rt,!0)),Rt}let Bn=be?we.outerHTML:we.innerHTML;return be&&Pe["!doctype"]&&we.ownerDocument&&we.ownerDocument.doctype&&we.ownerDocument.doctype.name&&Ba(P8,we.ownerDocument.doctype.name)&&(Bn=" `+Bn),Ae&&(Bn=Ye(Bn)),D&<?Q(Bn):Bn},e.setConfig=function(){let gt=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};Z(gt),ot=!0,Ve=Pe,ut=it},e.clearConfig=function(){Mi=null,ot=!1,Ve=null,ut=null,D=F,P=""},e.isValidAttribute=function(gt,ae,we){Mi||Z({});const ht=Rn(gt),vt=Rn(ae);return oi(ht,vt,we)},e.addHook=function(gt,ae){typeof ae=="function"&&mi(je,gt)&&md(je[gt],ae)},e.removeHook=function(gt,ae){if(mi(je,gt)){if(ae!==void 0){const we=x8(je[gt],ae);return we===-1?void 0:y8(je[gt],we,1)[0]}return sM(je[gt])}},e.removeHooks=function(gt){mi(je,gt)&&(je[gt]=[])},e.removeAllHooks=function(){je=vM()},e}var q8=Tk();function on({title:a,description:e,open:n,onClose:s,children:o,wide:l=!1}){return t.jsx(Tm,{open:n,onOpenChange:d=>{d||s()},children:t.jsxs(jm,{children:[t.jsx(Rm,{className:"modal-overlay"}),t.jsxs(km,{className:`modal-content pro-modal ${l?"wide":""}`,children:[t.jsx("button",{className:"modal-close","aria-label":u("Close dialog"),onClick:s,children:t.jsx(da,{size:20})}),t.jsx(Nm,{children:u(a)}),t.jsx(Dm,{children:u(e||"Manage your workspace.")}),u(o)]})]})})}function _t({children:a,tone:e="neutral"}){return t.jsxs("span",{className:`pro-pill tone-${e}`,children:[t.jsx("i",{}),u(a)]})}function So({text:a,breaks:e=!1}){const n=q8.sanitize(Tn.parse(a,{async:!1,gfm:!0,breaks:e}),{FORBID_TAGS:["img","iframe","video","audio","style","script","svg"],FORBID_ATTR:["style"]});return t.jsx("div",{className:"pro-markdown",dangerouslySetInnerHTML:{__html:n}})}function Ot({children:a,error:e=!1}){return t.jsxs("div",{className:`pro-notice ${e?"error":""}`,role:e?"alert":"status",children:[u(e?t.jsx(hl,{size:17}):t.jsx($a,{size:17})),t.jsx("span",{children:u(a)})]})}function j0(a,e,n="text/markdown"){const s=new Blob([e],{type:n}),o=URL.createObjectURL(s),l=document.createElement("a");l.href=o,l.download=a,l.click(),setTimeout(()=>URL.revokeObjectURL(o),1e3)}const Yn=a=>new Date(a).toLocaleString(Hn(),Kd({day:"numeric",month:"short",hour:"2-digit",minute:"2-digit"}));function Hd(a){return!a||window.confirm(u("You have unsaved changes. Leave without saving?"))}const Vm=a=>`${Math.floor(a/60)}:${String(Math.floor(a%60)).padStart(2,"0")}`;function R0(a){const[,e]=C.useState(0);C.useEffect(()=>{if(!a)return;const n=setInterval(()=>e(s=>s+1),1e3);return()=>clearInterval(n)},[a])}function Fi(a){const e=C.useRef(null);return a&&e.current==null&&(e.current=Date.now()),a||(e.current=null),R0(a),e.current}const vh=(a,e=0)=>e+(a?Math.max(0,Math.floor((Date.now()-a)/1e3)):0),xh=(a,e)=>Math.max(4,Math.min(95,Math.round(100*(1-Math.exp(-a/Math.max(1,e))))));function vi({since:a,base:e=0}){const n=C.useRef(Date.now());return R0(!0),t.jsx("span",{className:"wait-clock",children:Vm(vh(a??n.current,e))})}function Xn({busy:a,label:e,children:n}){const s=Fi(a);return a?t.jsxs(t.Fragment,{children:[t.jsx(Jt,{className:"spin",size:15}),u(e),t.jsx(vi,{since:s})]}):t.jsx(t.Fragment,{children:n})}function Ma({label:a,since:e,base:n=0,expect:s=30,progress:o,note:l,className:d=""}){R0(!0);const h=C.useRef(Date.now()),m=vh(e??h.current,n),p=o!=null?Math.max(3,Math.min(100,o)):xh(m,s);return t.jsxs("div",{className:`wait-line ${d}`,role:"status","aria-live":"polite",children:[t.jsxs("div",{className:"wait-line-head",children:[t.jsx(Jt,{className:"spin",size:16}),t.jsx("span",{children:u(a)}),t.jsx("span",{className:"wait-clock",children:Vm(m)})]}),t.jsx("div",{className:"wait-bar",role:"progressbar","aria-label":u(a),"aria-valuemin":0,"aria-valuemax":100,"aria-valuenow":p,children:t.jsx("i",{style:{width:`${p}%`}})}),l&&t.jsx("small",{children:u(l)})]})}function Py({title:a,note:e,steps:n,current:s,elapsed:o,progress:l,expect:d=45}){const h=l!=null?Math.max(3,Math.min(100,l)):xh(o,d);return t.jsxs("div",{className:"tailnet-working",role:"status","aria-live":"polite",children:[t.jsxs("div",{className:"tailnet-working-head",children:[t.jsx(Jt,{className:"spin",size:18}),t.jsx("strong",{children:u(a)}),t.jsx("span",{children:Vm(o)})]}),t.jsx("div",{className:"pro-progress",role:"progressbar","aria-label":u(a),"aria-valuemin":0,"aria-valuemax":100,"aria-valuenow":h,children:t.jsx("i",{style:{width:`${h}%`}})}),t.jsx("ol",{children:n.map((m,p)=>t.jsxs("li",{className:pa==="Delivered"?"green":a==="Running"?"lime":a==="Awaiting approval"||a==="In review"?"amber":a==="Failed"?"red":"neutral";function W8({agents:a,onChat:e,onDoc:n}){const[s,o]=C.useState("");C.useEffect(()=>{if(!s)return;const T=setTimeout(()=>o(""),6e3);return()=>clearTimeout(T)},[s]);const l=Bi(),[d,h]=C.useState(""),[m,p]=C.useState("All missions"),[y,v]=C.useState("Plan"),[x,S]=C.useState(!1),[M,w]=C.useState("orchestrator"),[E,A]=C.useState([]),[k,R]=C.useState(""),[N,I]=C.useState(!1),[z,j]=C.useState(null),[L,D]=C.useState(""),P=Tl();C.useEffect(()=>{P.view==="Missions"&&P.id&&(h(P.id),v("Plan"))},[P.stamp]);const F=l.missions.find(T=>T.id===d),q=l.missions.filter(T=>T.status==="Running").length,J=l.missions.filter(T=>["Awaiting approval","In review"].includes(T.status)).length,ie=l.missions.filter(T=>T.status==="Delivered"&&new Date(T.deliveredAt||T.created).getMonth()===new Date().getMonth()&&new Date(T.deliveredAt||T.created).getFullYear()===new Date().getFullYear()).length,Q=l.missions.filter(T=>["Delivered","Failed"].includes(T.status));async function V(T,_=""){if(F){try{await wt("/api/missions/act",{id:F.id,action:T,note:_}),await Za()}catch(ve){o(ve.message)}I(!1),j(null)}}async function $(T){T.preventDefault();const _=new FormData(T.currentTarget);if(!(M==="manual"&&!E.length))try{const ve=await wt("/api/missions/launch",{name:String(_.get("name")).trim(),goal:String(_.get("goal")).trim(),selection:M==="manual"?"manual":"orchestrator",team:M==="manual"?E:[],timeLimit:Number(_.get("minutes")),maxSteps:Number(_.get("steps")),needsReview:_.get("review")==="on"});await Za(),S(!1),h(ve.mission.id),v("Plan")}catch(ve){o(ve.message)}}const te=l.missions.filter(T=>(m==="All missions"||m==="Waiting on you"&&["Awaiting approval","In review"].includes(T.status)||T.status===m)&&`${T.name} ${T.goal}`.toLowerCase().includes(L.toLowerCase())),ne=T=>a.find(_=>_.id===T)||l.archived.find(_=>_.id===T),Y=T=>{const _=ne(T);return t.jsxs("span",{className:"pro-person",children:[u(_&&t.jsx(qt,{agent:_,small:!0})),u(_?.name||"Archived agent")]})};return F?t.jsxs("div",{className:"pro-mission-detail",children:[s&&t.jsx(Ot,{error:!0,children:u(s)}),t.jsxs("button",{className:"text-btn pro-back",onClick:()=>h(""),children:[t.jsx(eu,{size:16}),u("All missions")]}),t.jsxs("section",{className:"panel pro-mission-hero",children:[t.jsxs("div",{children:[t.jsxs("span",{className:"panel-kicker",children:[u("MISSION / "),u(F.id.slice(0,8).toUpperCase())]}),t.jsx("h2",{children:F.name}),t.jsx("p",{children:u(F.goal)})]}),t.jsx(_t,{tone:xM(F.status),children:u(F.status)}),t.jsxs("div",{className:"pro-mission-meta",children:[t.jsxs("span",{children:[t.jsx(ts,{size:16}),u(F.timeLimit),u(" min limit")]}),t.jsxs("span",{children:[t.jsx(Em,{size:16}),u(F.steps.length),u(" steps · max "),u(F.maxSteps)]}),t.jsxs("span",{children:[t.jsx(hh,{size:16}),u(F.team.length),u(" specialists")]}),t.jsxs("span",{children:[t.jsx($a,{size:16}),u(F.needsReview?"Owner review required":"Deliver automatically")]})]})]}),["Awaiting approval","In review"].includes(F.status)&&t.jsxs("div",{className:"pro-owner-banner",children:[t.jsx("span",{className:"pro-owner-icon",children:t.jsx(Ns,{size:22})}),t.jsxs("div",{children:[t.jsx("strong",{children:u(F.status==="Awaiting approval"?"This plan needs your go-ahead.":"Your result is ready to review.")}),t.jsx("p",{children:u(F.status==="Awaiting approval"?"Review the steps and team before work starts.":"Accept the delivery or send it back with a note.")})]}),t.jsx("div",{className:"pro-actions",children:F.status==="Awaiting approval"?t.jsxs("button",{className:"primary-btn",onClick:()=>V("approve"),children:[t.jsx(gi,{size:16}),u("Approve plan")]}):t.jsxs(t.Fragment,{children:[t.jsxs("button",{className:"secondary-btn",onClick:()=>{R(""),I(!0)},children:[t.jsx(ss,{size:16}),u("Send back")]}),t.jsxs("button",{className:"primary-btn",onClick:()=>V("accept"),children:[t.jsx(Kt,{size:16}),u("Accept result")]})]})})]}),t.jsxs("div",{className:"pro-actions pro-mission-tools",children:[!["Delivered","Stopped"].includes(F.status)&&t.jsxs("button",{className:"secondary-btn",onClick:()=>j(F.status==="Running"?"stop":"cancel"),children:[t.jsx($b,{size:14}),u(F.status==="Running"?"Stop":"Cancel")]}),F.status!=="Delivered"&&t.jsxs("button",{className:"secondary-btn",onClick:()=>V("replan"),children:[t.jsx(ss,{size:15}),u("Replan")]}),l.docs.find(T=>T.missionId===F.id)&&t.jsxs("button",{className:"secondary-btn",onClick:()=>n(l.docs.find(T=>T.missionId===F.id).id),children:[t.jsx(Si,{size:15}),u("Open result in Docs")]}),t.jsxs("span",{className:"pro-small",children:[u("Launched "),u(Yn(F.created))]})]}),t.jsxs("div",{className:"pro-detail-layout",children:[t.jsxs("section",{className:"panel pro-detail-panel",children:[t.jsx("div",{className:"pro-tabs",children:["Plan","Between the agents","Timeline"].map(T=>t.jsxs("button",{className:y===T?"selected":"",onClick:()=>v(T),children:[u(T==="Plan"?t.jsx(Op,{size:16}):T==="Timeline"?t.jsx(ts,{size:16}):t.jsx(yi,{size:16}))," ",u(T),T==="Between the agents"&&t.jsx("span",{children:u(F.handoffs.length)})]},T))}),y==="Plan"&&t.jsxs("div",{className:"pro-plan",children:[F.status==="Planning"&&t.jsx(Ma,{label:"The Orchestrator is planning the mission: the steps, and who takes each one",since:F.planningSince?F.planningSince*1e3:null,expect:60,note:"Usually under two minutes. The plan appears here for you to approve."}),F.steps.map((T,_)=>t.jsxs("article",{className:"pro-plan-step",children:[t.jsx("span",{className:`pro-step-number ${T.status.toLowerCase()}`,children:u(T.status==="Done"?t.jsx(Kt,{size:17}):_+1)}),t.jsxs("div",{children:[t.jsxs("div",{className:"pro-step-heading",children:[t.jsx("h3",{children:T.title}),t.jsx(_t,{tone:T.status==="Done"?"green":T.status==="Working"?"lime":"neutral",children:u(T.status)})]}),u(Y(T.agentId)),t.jsxs("span",{className:"pro-dependency",children:[t.jsx(Op,{size:14}),u(T.dependsOn.length?`After ${T.dependsOn.map(ve=>`step ${F.steps.findIndex(je=>je.id===ve)+1}`).join(", ")}`:"No dependencies")]}),T.result?t.jsxs("details",{children:[t.jsxs("summary",{children:[u("View result "),t.jsx(nm,{size:14})]}),t.jsx(So,{text:T.result})]}):T.status==="Working"?t.jsx(Ma,{className:"compact",label:"Working on this step now",since:T.startedAt?T.startedAt*1e3:null,expect:90}):t.jsx("p",{className:"pro-small",children:u("Result will appear when this step finishes.")})]})]},T.id))]}),y==="Between the agents"&&t.jsx("div",{className:"pro-handoffs",children:F.handoffs.length?F.handoffs.map((T,_)=>t.jsxs("article",{className:"pro-handoff",children:[t.jsxs("header",{children:[t.jsxs("span",{children:[u("HANDOFF "),u(String(_+1).padStart(2,"0"))]}),t.jsx("time",{children:u(Yn(T.time))})]}),t.jsxs("div",{className:"pro-handoff-route",children:[u(Y(T.from)),t.jsx(Kn,{size:20}),u(Y(T.to))]}),t.jsx("h4",{children:u("The brief")}),t.jsx("p",{children:u(T.brief)}),t.jsxs("details",{children:[t.jsxs("summary",{children:[t.jsx(Si,{size:15}),u("Work handed in from earlier steps"),t.jsx(nm,{size:15})]}),t.jsx(So,{text:T.input})]}),t.jsxs("div",{className:"pro-handoff-reply",children:[t.jsxs("span",{children:[t.jsx($a,{size:15}),u("Reply")]}),t.jsx("p",{children:u(T.reply)})]})]},T.id)):t.jsxs("div",{className:"pro-empty",children:[t.jsx(yl,{size:32}),t.jsx("h3",{children:u("Handoffs will appear here.")}),t.jsx("p",{children:u("Follow every brief and reply as the team works through the plan.")})]})}),y==="Timeline"&&t.jsx("div",{className:"pro-timeline",children:F.timeline.slice().reverse().map((T,_)=>t.jsxs("div",{children:[t.jsx("span",{className:_===0?"current":"",children:t.jsx(Kt,{size:13})}),t.jsxs("div",{children:[t.jsx("p",{children:T.text}),t.jsx("time",{children:u(Yn(T.time))})]})]},T.id))})]}),t.jsxs("aside",{className:"panel pro-mission-team",children:[t.jsx("span",{className:"panel-kicker",children:u("THE RIGHT EXPERTISE")}),t.jsx("h3",{children:u("Mission team")}),t.jsx("p",{children:u(F.selection==="orchestrator"?"Chosen by the Orchestrator":"Chosen by you")}),F.team.map(T=>{const _=ne(T);return _?t.jsxs("button",{onClick:()=>e(T),children:[t.jsx(qt,{agent:_}),t.jsxs("span",{children:[t.jsx("strong",{children:_.name}),t.jsx("small",{children:u(_.role)})]}),t.jsx(yi,{size:15})]},T):null}),F.ownerNote&&t.jsxs(Ot,{children:[u("Owner feedback: "),u(F.ownerNote)]}),t.jsxs("div",{className:"pro-team-note",children:[t.jsx(Ns,{size:18}),t.jsx("p",{children:u("You stay in control of the plan, the work, and the delivery.")})]})]})]}),t.jsxs(on,{title:u("Send the result back"),description:"Tell the team what needs to change.",open:N,onClose:()=>I(!1),children:[t.jsxs("label",{children:[u("Your note"),t.jsx("textarea",{rows:5,value:k,onChange:T=>R(T.target.value),placeholder:u("What would make this result ready?")})]}),t.jsxs("button",{className:"primary-btn",disabled:!k.trim(),onClick:()=>V("sendBack",k),children:[t.jsx(yl,{size:16}),u("Send feedback")]})]}),t.jsx(on,{title:u(z==="stop"?"Stop this mission?":"Cancel this mission?"),description:"Completed work and the timeline will be preserved.",open:!!z,onClose:()=>j(null),children:t.jsxs("div",{className:"pro-actions right",children:[t.jsx("button",{className:"secondary-btn",onClick:()=>j(null),children:u("Keep mission")}),t.jsx("button",{className:"pro-danger",onClick:()=>V(z),children:u(z==="stop"?"Stop mission":"Cancel mission")})]})})]}):t.jsxs(t.Fragment,{children:[s&&t.jsx(Ot,{error:!0,children:u(s)}),t.jsxs("div",{className:"pro-page-top",children:[t.jsxs("div",{children:[t.jsx(_t,{tone:"lime",children:u("PRO MISSIONS")}),t.jsx("p",{children:u("A clear goal. The right team. Work that arrives.")})]}),t.jsxs("button",{className:"primary-btn",onClick:()=>{w("orchestrator"),A([]),S(!0)},children:[t.jsx(jn,{size:17}),u("Launch a mission")]})]}),t.jsx("div",{className:"pro-metrics",children:[{label:"Running now",value:q,icon:gi},{label:"Waiting on you",value:J,icon:Ns},{label:"Delivered this month",value:ie,icon:$a},{label:"Success rate",value:Q.length?`${Math.round(l.missions.filter(T=>T.status==="Delivered").length/Q.length*100)}%`:"N/A",icon:Op}].map((T,_)=>t.jsxs("button",{className:`panel pro-metric ${_===1?"attention":""}`,onClick:()=>p(_===0?"Running":_===1?"Waiting on you":_===2?"Delivered":"All missions"),children:[t.jsxs("span",{children:[u(T.label),t.jsx(T.icon,{size:18})]}),t.jsx("strong",{children:u(T.value)}),t.jsx("small",{children:u(_===1?"A decision moves the work forward":_===3?"Delivered / completed missions":"Your workspace at a glance")})]},T.label))}),t.jsxs("div",{className:"pro-library-toolbar",children:[t.jsx("div",{className:"filter-tabs",children:["All missions","Waiting on you","Running","Delivered"].map(T=>t.jsxs("button",{className:m===T?"selected":"",onClick:()=>p(T),children:[u(T),T==="Waiting on you"&&t.jsx("span",{children:u(J)})]},T))}),t.jsxs("div",{className:"pro-actions",children:[t.jsx("input",{className:"pro-search",placeholder:u("Search missions"),"aria-label":u("Search missions"),value:L,onChange:T=>D(T.target.value)}),t.jsxs("select",{"aria-label":u("Mission state"),value:m,onChange:T=>p(T.target.value),children:[t.jsx("option",{value:"All missions",children:u("All missions")}),t.jsx("option",{value:"Waiting on you",children:u("Waiting on you")}),$5.map(T=>t.jsx("option",{value:T,children:u(T)},T))]})]})]}),t.jsx("div",{className:"pro-mission-grid",children:te.map(T=>t.jsxs("button",{className:`panel pro-mission-card ${["Awaiting approval","In review"].includes(T.status)?"needs-owner":""}`,onClick:()=>{h(T.id),v("Plan")},children:[t.jsxs("div",{className:"pro-card-top",children:[t.jsx("span",{className:"pro-mission-symbol",children:t.jsx(Ns,{size:21})}),t.jsx(_t,{tone:xM(T.status),children:u(T.status)})]}),t.jsx("h3",{children:T.name}),t.jsx("p",{children:u(T.goal)}),t.jsxs("div",{className:"pro-mission-progress",children:[t.jsxs("div",{children:[t.jsx("span",{children:T.steps.length?t.jsxs(t.Fragment,{children:[u(T.steps.filter(_=>_.status==="Done").length),u(" of "),u(T.steps.length),u(" steps")]}):u(T.status==="Planning"?"Planning the steps…":"No steps yet")}),t.jsxs("strong",{children:[u(Math.round(T.steps.filter(_=>_.status==="Done").length/Math.max(1,T.steps.length)*100)),u("%")]})]}),t.jsx("i",{children:t.jsx("b",{style:{width:`${T.steps.filter(_=>_.status==="Done").length/Math.max(1,T.steps.length)*100}%`}})})]}),t.jsxs("footer",{children:[t.jsx("div",{className:"mini-avatar-stack",children:u(T.team.map(_=>{const ve=ne(_);return ve?t.jsx(qt,{agent:ve,small:!0},_):null}))}),t.jsx("span",{children:["Awaiting approval","In review"].includes(T.status)?t.jsxs(t.Fragment,{children:[t.jsx(Ns,{size:14}),u("Needs your decision")]}):t.jsxs(t.Fragment,{children:[t.jsx(ts,{size:14}),u(T.timeLimit),u(" min limit")]})}),t.jsx(Kn,{size:17})]})]},T.id))}),!te.length&&t.jsxs("div",{className:"panel pro-empty",children:[t.jsx(Ns,{size:32}),t.jsx("h3",{children:u("No missions here yet.")}),t.jsx("p",{children:u("Try another filter or launch a new mission.")})]}),t.jsx(on,{title:u("Launch a mission"),description:"Give your team a destination and room to do useful work.",open:x,onClose:()=>S(!1),wide:!0,children:t.jsxs("form",{onSubmit:$,children:[t.jsxs("label",{children:[u("Mission name"),t.jsx("input",{name:"name",required:!0,maxLength:120,placeholder:u("What are we working towards?")})]}),t.jsxs("label",{children:[u("Goal"),t.jsx("textarea",{name:"goal",rows:3,required:!0,maxLength:3e3,placeholder:u("Describe the outcome and what a good result looks like.")})]}),t.jsxs("label",{children:[u("Who picks the team?"),t.jsxs("select",{value:M,onChange:T=>w(T.target.value),children:[t.jsx("option",{value:"orchestrator",children:u("The Orchestrator")}),t.jsx("option",{value:"manual",children:u("I choose")})]})]}),M==="manual"&&t.jsxs("fieldset",{className:"pro-agent-picker",children:[t.jsx("legend",{children:u("Choose specialists")}),u(a.map(T=>t.jsxs("label",{children:[t.jsx("input",{type:"checkbox",checked:E.includes(T.id),onChange:_=>A(ve=>_.target.checked?[...ve,T.id]:ve.filter(je=>je!==T.id))}),t.jsx(qt,{agent:T,small:!0}),t.jsx("span",{children:T.name})]},T.id)))]}),t.jsxs("div",{className:"pro-form-grid",children:[t.jsxs("label",{children:[u("Time limit (minutes)"),t.jsx("input",{name:"minutes",type:"number",defaultValue:60,min:1,max:1440,required:!0})]}),t.jsxs("label",{children:[u("Maximum steps"),t.jsx("input",{name:"steps",type:"number",defaultValue:8,min:1,max:50,required:!0})]})]}),t.jsxs("label",{className:"pro-check-label",children:[t.jsx("input",{name:"review",type:"checkbox",defaultChecked:!0}),t.jsxs("span",{children:[t.jsx("strong",{children:u("I review the result before delivery")}),t.jsx("small",{children:u("The mission stays In review until you accept it.")})]})]}),t.jsx(Ot,{children:u("You will approve the plan before the team starts.")}),t.jsx("div",{className:"pro-actions right",children:t.jsxs("button",{className:"primary-btn",disabled:!a.length||M==="manual"&&!E.length,children:[t.jsx(Ns,{size:16}),u("Launch mission")]})})]})})]})}function jk(a){const[e,n]=C.useState(null);return C.useEffect(()=>{const s=l=>{a&&(l.preventDefault(),l.returnValue="")},o=l=>{if(!a)return;l.preventDefault();const d=l.detail?.proceed;d&&n(()=>d)};return window.addEventListener("beforeunload",s),window.addEventListener("laboratorio:before-navigate",o),()=>{window.removeEventListener("beforeunload",s),window.removeEventListener("laboratorio:before-navigate",o)}},[a]),t.jsx(on,{title:u("You have unsaved changes"),description:"Save your work before leaving, or leave without saving.",open:!!e,onClose:()=>n(null),children:t.jsxs("div",{className:"pro-actions right",children:[t.jsx("button",{className:"secondary-btn",onClick:()=>n(null),children:u("Keep editing")}),t.jsx("button",{className:"pro-danger",onClick:()=>{const s=e;n(null),s?.()},children:u("Leave without saving")})]})})}function Y8({agents:a,initialId:e="",onInitialOpened:n}){const s=Bi(),[o,l]=C.useState(e),[d,h]=C.useState("All documents"),[m,p]=C.useState(""),[y,v]=C.useState("all"),[x,S]=C.useState(!1),[M,w]=C.useState(""),[E,A]=C.useState(""),[k,R]=C.useState(!1),[N,I]=C.useState(""),z=s.docs.find(ie=>ie.id===o),j=x&&!!z&&(E!==z.title||M!==z.body),L=jk(j);C.useEffect(()=>{e&&(l(e),n())},[e]);function D(){z&&(A(z.title),w(z.body),S(!0),I(""))}async function P(){if(!(!z||!E.trim()))try{await wt("/api/docs/save",{id:z.id,title:E.trim(),body:M}),await Za(),S(!1),I("Document saved")}catch(ie){I(ie.message)}}async function F(){let ie="";try{ie=await tB({title:"Untitled document",body:`# Untitled document Start with a clear idea.`,authorId:"you",kind:"Written by you",status:"Draft"})}catch(Q){I(Q.message);return}l(ie),A("Untitled document"),w(`# Untitled document Start with a clear idea.`),S(!0)}const q=s.docs.filter(ie=>(d==="All documents"||d==="Mission results"&&ie.kind==="Mission result"||d==="In review"&&ie.status==="In review"||d==="Written by you"&&ie.authorId==="you")&&(y==="all"||ie.authorId===y)&&`${ie.title} ${ie.body}`.toLowerCase().includes(m.toLowerCase())),J=ie=>a.find(Q=>Q.id===ie.authorId)||s.archived.find(Q=>Q.id===ie.authorId);return z?t.jsxs("section",{className:"panel pro-doc-reader",children:[u(L),t.jsxs("div",{className:"pro-doc-top",children:[t.jsxs("button",{className:"text-btn",onClick:()=>{Hd(j)&&(l(""),S(!1),I(""))},children:[t.jsx(eu,{size:16}),u("Document library")]}),t.jsx("div",{className:"pro-actions",children:x?t.jsxs(t.Fragment,{children:[t.jsx("button",{className:"secondary-btn",onClick:()=>{Hd(j)&&S(!1)},children:u("Cancel")}),t.jsxs("button",{className:"primary-btn",onClick:P,disabled:!E.trim(),children:[t.jsx(u2,{size:16}),u("Save document")]})]}):t.jsxs(t.Fragment,{children:[t.jsxs("button",{className:"secondary-btn",onClick:D,children:[t.jsx(Mr,{size:16}),u("Edit")]}),t.jsx("button",{className:"icon-btn","aria-label":u("Download document"),title:u("Download Markdown"),onClick:()=>j0(z.title.replace(/[^a-z0-9]+/gi,"-").toLowerCase()+".md",z.body),children:t.jsx(Eo,{size:18})}),t.jsx("button",{className:"icon-btn","aria-label":u("Print document"),onClick:()=>window.print(),children:t.jsx(OU,{size:18})}),t.jsx("button",{className:"icon-btn pro-delete-icon","aria-label":u("Delete document"),onClick:()=>R(!0),children:t.jsx(ti,{size:18})})]})})]}),t.jsxs("div",{className:"pro-doc-content",children:[t.jsxs("div",{className:"pro-doc-meta",children:[t.jsx(_t,{tone:z.status==="In review"?"amber":"neutral",children:u(z.status)}),t.jsx("span",{children:u(z.kind)}),t.jsxs("span",{children:[t.jsx(ts,{size:13}),u(Yn(z.updated))]})]}),x?t.jsxs(t.Fragment,{children:[t.jsxs("label",{children:[u("Document title"),t.jsx("input",{value:E,onChange:ie=>A(ie.target.value),maxLength:160})]}),t.jsxs("div",{className:"pro-doc-edit",children:[t.jsxs("div",{children:[t.jsx("span",{className:"panel-kicker",children:u("MARKDOWN")}),t.jsx("textarea",{rows:22,"aria-label":u("Document Markdown"),className:"pro-code-input",value:M,onChange:ie=>w(ie.target.value)})]}),t.jsxs("div",{children:[t.jsx("span",{className:"panel-kicker",children:u("LIVE PREVIEW")}),t.jsx(So,{text:M})]})]}),t.jsx("span",{className:"pro-small",children:u(j?"Unsaved changes":"No changes yet")})]}):t.jsxs(t.Fragment,{children:[t.jsx("h2",{children:z.title}),t.jsx("div",{className:"pro-doc-author",children:J(z)?t.jsxs(t.Fragment,{children:[t.jsx(qt,{agent:J(z),small:!0}),t.jsxs("span",{children:[u("Written by "),J(z).name]})]}):t.jsxs(t.Fragment,{children:[t.jsx("span",{className:"message-user-avatar","aria-hidden":"true",children:t.jsx(rw,{size:16})}),t.jsx("span",{children:u("Written by you")})]})}),t.jsx(So,{text:z.body})]}),N&&t.jsx(Ot,{children:u(N)})]}),t.jsxs(on,{title:u("Delete this document?"),description:"The file moves to a deleted folder on your server, so it can be recovered.",open:k,onClose:()=>R(!1),children:[t.jsx("p",{children:z.title}),t.jsxs("div",{className:"pro-actions right",children:[t.jsx("button",{className:"secondary-btn",onClick:()=>R(!1),children:u("Keep document")}),t.jsx("button",{className:"pro-danger",onClick:async()=>{try{await wt("/api/docs/delete",{id:z.id}),await Za(),l(""),R(!1)}catch(ie){I(ie.message)}},children:u("Delete document")})]})]})]}):t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"pro-page-top",children:[t.jsxs("div",{children:[t.jsx(_t,{tone:"lime",children:u("YOUR KNOWLEDGE, TOGETHER")}),t.jsx("p",{children:u("Useful work deserves a place to live.")})]}),t.jsxs("button",{className:"primary-btn",onClick:F,children:[t.jsx(jn,{size:17}),u("New document")]})]}),t.jsxs("div",{className:"pro-library-toolbar",children:[t.jsx("div",{className:"filter-tabs",children:["All documents","Mission results","In review","Written by you"].map(ie=>t.jsx("button",{className:d===ie?"selected":"",onClick:()=>h(ie),children:u(ie)},ie))}),t.jsxs("div",{className:"pro-doc-filters",children:[t.jsxs("label",{className:"pro-doc-author-filter",children:[t.jsx("span",{children:u("Written by")}),t.jsxs("select",{"aria-label":u("Filter documents by agent"),value:y,onChange:ie=>v(ie.target.value),children:[t.jsx("option",{value:"all",children:u("All authors")}),t.jsx("option",{value:"you",children:u("You")}),t.jsx("optgroup",{label:u("Your agents"),children:u(a.map(ie=>t.jsx("option",{value:ie.id,children:ie.name},ie.id)))}),s.archived.length>0&&t.jsx("optgroup",{label:u("Archived agents"),children:s.archived.map(ie=>t.jsxs("option",{value:ie.id,children:[ie.name,u(" · archived")]},ie.id))})]})]}),t.jsxs("label",{className:"search-input",children:[t.jsx(vo,{size:17}),t.jsx("input",{value:m,onChange:ie=>p(ie.target.value),"aria-label":u("Search documents"),placeholder:u("Search the library...")})]})]})]}),t.jsx("div",{className:"pro-doc-grid",children:q.map(ie=>t.jsxs("button",{className:"panel pro-doc-card",onClick:()=>{l(ie.id),S(!1),I("")},children:[t.jsxs("div",{className:"pro-card-top",children:[t.jsx("span",{className:`pro-doc-symbol ${ie.kind==="Mission result"?"result":""}`,children:t.jsx(Si,{size:24})}),t.jsx(_t,{tone:ie.status==="In review"?"amber":"neutral",children:u(ie.status)})]}),t.jsx("span",{className:"panel-kicker",children:u(ie.kind.toUpperCase())}),t.jsx("h3",{children:ie.title}),t.jsx("p",{children:u(ie.body.replace(/[#*>`\[\]]/g,"").split(` `).filter(Boolean).slice(ie.body.startsWith("#")?1:0,3).join(" ").slice(0,160))}),t.jsxs("footer",{children:[t.jsxs("div",{children:[J(ie)?t.jsx(qt,{agent:J(ie),small:!0}):t.jsx("span",{className:"message-user-avatar","aria-hidden":"true",children:t.jsx(rw,{size:16})}),t.jsx("span",{children:u(J(ie)?.name||"You")})]}),t.jsx("span",{children:u(Yn(ie.updated))})]})]},ie.id))}),!q.length&&(s.docs.length?t.jsxs("div",{className:"panel pro-empty",children:[t.jsx(_1,{size:34}),t.jsx("h3",{children:u("No matching documents.")}),t.jsx("p",{children:u("Try another agent, search, or document type.")}),t.jsx("button",{className:"secondary-btn",onClick:()=>{v("all"),p(""),h("All documents")},children:u("Clear filters")})]}):t.jsxs("div",{className:"panel pro-empty",children:[t.jsx(_1,{size:34}),t.jsx("h3",{children:u("No documents yet.")}),t.jsx("p",{children:u("Mission results, your agents' reports and anything you write with New document will be kept here.")})]})),t.jsxs("p",{className:"pro-library-foot",children:[t.jsx(Si,{size:15}),u(q.length),u(" of "),u(s.docs.length),u(" documents · Mission results, agent work, and saved conversations")]})]})}function X8({agents:a}){const e=Bi(),[n,s]=C.useState(a[0]?.id||""),[o,l]=C.useState(""),[d,h]=C.useState(""),[m,p]=C.useState(null),[y,v]=C.useState(!1),[x,S]=C.useState(""),[M,w]=C.useState(""),[E,A]=C.useState(""),k=C.useRef(null);C.useEffect(()=>{a.length&&![...a,...e.archived].some(F=>F.id===n)&&s(a[0].id)},[a,n,e.archived]);const R=[...a,...e.archived],N=R.find(F=>F.id===n),I=e.files.find(F=>F.id===o),z=!!I&&I.content!==d,j=jk(z);C.useEffect(()=>void 0,[R.map(F=>F.id).join("|")]);function L(F,q=!1){if(Hd(z)){if(F.sensitive&&!q){p(F);return}l(F.id),h(F.content),w(""),p(null)}}const D=I?.backups.find(F=>F.id===x);async function P(){if(I)try{await wt("/api/files/save",{id:I.id,content:d,updated:I.updated}),await Za(),w(`Backup created. ${I.name} saved at ${Yn(new Date().toISOString())}.`)}catch(F){w(F.message)}}return t.jsxs(t.Fragment,{children:[u(j),t.jsxs("div",{className:"pro-page-top",children:[t.jsxs("div",{children:[t.jsx(_t,{tone:"lime",children:u("AGENT WORKSPACE FILES")}),t.jsx("p",{children:u("Identity, memory, and settings. Carefully kept.")})]}),t.jsxs("span",{className:"resource-pill",children:[t.jsx(za,{size:16}),u("A backup before every save")]})]}),t.jsxs("section",{className:"panel pro-files-layout",children:[t.jsxs("aside",{className:"pro-file-rail",children:[t.jsxs("label",{className:"pro-label",children:[u("AGENT"),t.jsx("select",{"aria-label":u("File agent"),value:n,onChange:F=>{Hd(z)&&(s(F.target.value),l(""),w(""))},children:R.map(F=>t.jsxs("option",{value:F.id,children:[F.name,u(e.archived.some(q=>q.id===F.id)?" · archived":"")]},F.id))})]}),N&&t.jsxs("div",{className:"pro-file-agent",children:[t.jsx(qt,{agent:N}),t.jsxs("span",{children:[t.jsx("strong",{children:N.name}),t.jsx("small",{children:u("Private workspace")})]})]}),t.jsxs("label",{className:"search-input",children:[t.jsx(vo,{size:15}),t.jsx("input",{value:E,onChange:F=>A(F.target.value),placeholder:u("Find a file"),"aria-label":u("Search agent files")})]}),["Identity","Memory","Settings"].map(F=>t.jsxs("div",{className:"pro-file-group",children:[t.jsxs("h3",{children:[t.jsx(dy,{size:14}),u(F)]}),e.files.filter(q=>q.agentId===n&&q.group===F&&q.name.toLowerCase().includes(E.toLowerCase())).map(q=>t.jsxs("button",{className:q.id===o?"selected":"",onClick:()=>L(q),children:[u(q.sensitive?t.jsx(am,{size:15}):t.jsx(Si,{size:15})),t.jsx("span",{children:q.name}),t.jsx(nm,{size:14})]},q.id))]},F)),t.jsx("p",{className:"pro-small",children:u("These are the agents' real files. Archived agents keep theirs.")})]}),t.jsx("div",{className:"pro-file-main",children:I?t.jsxs(t.Fragment,{children:[t.jsxs("header",{className:"pro-file-header",children:[t.jsxs("div",{children:[t.jsx(Si,{size:18}),t.jsx("strong",{children:I.name}),z&&t.jsx(_t,{tone:"amber",children:u("Unsaved")}),I.sensitive&&t.jsx(_t,{tone:"amber",children:u("Sensitive")})]}),t.jsxs("div",{className:"pro-actions",children:[t.jsxs("button",{className:"secondary-btn",onClick:()=>{S(I.backups[0]?.id||""),v(!0)},children:[t.jsx(fl,{size:16}),u(I.backups.length),u(" backups")]}),t.jsx("button",{className:"icon-btn","aria-label":u("Revert file changes"),disabled:!z,onClick:()=>{window.confirm("Revert to the last saved version?")&&(h(I.content),w("Changes reverted"))},children:t.jsx(ss,{size:17})}),t.jsxs("button",{className:"primary-btn",disabled:!z,onClick:P,children:[t.jsx(u2,{size:16}),u("Save")]})]})]}),t.jsxs("div",{className:"pro-code-editor",children:[t.jsx("div",{ref:k,className:"pro-gutter","aria-hidden":"true",children:d.split(` `).map((F,q)=>t.jsx("div",{children:u(q+1)},q))}),t.jsx("textarea",{spellCheck:!1,wrap:"off","aria-label":u(`${I.name} editor`),value:d,onChange:F=>h(F.target.value),onScroll:F=>{k.current&&(k.current.scrollTop=F.currentTarget.scrollTop)},onKeyDown:F=>{if(F.key==="Tab"){F.preventDefault();const q=F.currentTarget,J=q.selectionStart,ie=q.selectionEnd;h(d.slice(0,J)+" "+d.slice(ie)),setTimeout(()=>{q.selectionStart=q.selectionEnd=J+2},0)}}})]}),t.jsxs("div",{className:"pro-editor-foot",children:[t.jsxs("span",{children:[u(d.split(` `).length),u(" lines · "),u(d.length),u(" characters")]}),t.jsx("span",{children:u(z?"Unsaved changes":`Saved ${Yn(I.updated)}`)})]}),t.jsx("div",{className:"pro-file-notes",children:t.jsx(Ot,{children:u(M||"Saving creates a backup of the previous version before replacing the file.")})})]}):t.jsxs("div",{className:"pro-empty pro-file-empty",children:[t.jsx("span",{className:"pro-large-icon",children:t.jsx(dy,{size:35})}),t.jsx("h3",{children:u("Every agent has a workspace.")}),t.jsx("p",{children:u("Choose a file to read or edit it. Identity shapes the agent, memory keeps context, and settings guide its tools.")}),t.jsxs("div",{children:[t.jsx(_t,{children:u("Identity")}),t.jsx(_t,{children:u("Memory")}),t.jsx(_t,{children:u("Settings")})]})]})})]}),t.jsxs(on,{title:u("Open a sensitive file?"),description:"This file can contain credentials or private configuration.",open:!!m,onClose:()=>p(null),children:[t.jsx(Ot,{children:u("Preview values are placeholders. A connected backend should check access and redact secret values.")}),t.jsx("p",{className:"pro-code-input",children:m?.name}),t.jsxs("div",{className:"pro-actions right",children:[t.jsx("button",{className:"secondary-btn",onClick:()=>p(null),children:u("Cancel")}),t.jsxs("button",{className:"primary-btn",onClick:()=>m&&L(m,!0),children:[t.jsx(am,{size:15}),u("Open file")]})]})]}),t.jsx(on,{title:u(`Backups · ${I?.name||"File"}`),description:"The previous file content is preserved before each save.",open:y,onClose:()=>v(!1),wide:!0,children:I?.backups.length?t.jsxs("div",{className:"pro-backup-layout",children:[t.jsx("div",{children:I.backups.map((F,q)=>t.jsxs("button",{className:x===F.id?"selected":"",onClick:()=>S(F.id),children:[t.jsx(fl,{size:16}),t.jsxs("span",{children:[t.jsxs("strong",{children:[u("Backup "),u(I.backups.length-q)]}),t.jsx("small",{children:u(Yn(F.time))})]})]},F.id))}),t.jsx("div",{children:D&&t.jsxs(t.Fragment,{children:[t.jsx("pre",{className:"pro-backup-code",children:D.content}),t.jsxs("div",{className:"pro-actions",children:[t.jsxs("button",{className:"secondary-btn",onClick:()=>j0(`${I.name}.backup`,D.content,"text/plain"),children:[t.jsx(Eo,{size:15}),u("Download")]}),t.jsxs("button",{className:"primary-btn",onClick:()=>{Hd(z)&&(h(D.content),v(!1),w("Backup loaded into the editor. Save to restore it."))},children:[t.jsx(ss,{size:15}),u("Restore in editor")]})]})]})})]}):t.jsxs("div",{className:"pro-empty",children:[t.jsx(fl,{size:34}),t.jsx("h3",{children:u("No backups yet.")}),t.jsx("p",{children:u("Your first save will preserve the previous version here.")})]})})]})}const yM=a=>a<6,Iy="laboratorio-terminal-token",K8=()=>{try{return sessionStorage.getItem(Iy)||""}catch{return""}},Vf=a=>{try{a?sessionStorage.setItem(Iy,a):sessionStorage.removeItem(Iy)}catch{}};class Uy extends Error{}async function Wo(a,e){const n=await fetch(a,{method:e===void 0?"GET":"POST",cache:"no-store",headers:{"Content-Type":"application/json","X-Terminal-Token":K8()},body:e===void 0?void 0:JSON.stringify(e)}),s=await n.json().catch(()=>({error:"The Laboratorio server is not answering yet."}));if(n.status===401)throw new Uy(s.error);if(!n.ok)throw new Error(s.error||"The request failed.");return s}function J8({agents:a}){const[e,n]=C.useState(!0),[s,o]=C.useState(!1),[l,d]=C.useState(""),[h,m]=C.useState(""),[p,y]=C.useState(""),[v,x]=C.useState(!1),[S,M]=C.useState([]),[w,E]=C.useState([]),[A,k]=C.useState(""),[R,N]=C.useState(""),[I,z]=C.useState(!1),[j,L]=C.useState(""),D=C.useRef(null),P=C.useRef(null),F=S.find(T=>T.id===A)||S[0],q=!e;function J(T){M(T.sessions),E(T.commands)}async function ie(){try{J(await Wo("/api/terminal/sessions")),o(!0)}catch(T){T instanceof Uy&&(o(!1),Vf(""))}}C.useEffect(()=>{Wo("/api/terminal/status").then(T=>{n(T.configured),T.unlocked&&ie()}).catch(()=>{})},[]),C.useEffect(()=>{if(!s)return;const T=setInterval(()=>{document.hidden||ie()},S.some(_=>_.running)?700:2500);return()=>clearInterval(T)},[s,S.some(T=>T.running)]),C.useEffect(()=>{P.current?.scrollIntoView({block:"nearest"})},[F?.lines.length]);async function Q(T,_){y("");try{J(await Wo(T,_))}catch(ve){ve instanceof Uy&&(o(!1),Vf("")),y(ve.message)}}async function V(){yM(S.length)&&(await Q("/api/terminal/open",{name:`Session ${S.length+1}`}),k(""))}async function $(T){if(T.preventDefault(),y(""),q&&(l.length<8||l!==h)){y(l.length<8?"Use at least 8 characters.":"The passwords do not match.");return}x(!0);try{const _=await Wo(q?"/api/terminal/setup":"/api/terminal/unlock",{password:l});Vf(_.token),n(!0),d(""),m("");const ve=await Wo("/api/terminal/sessions");J(ve),o(!0),ve.sessions.length||J(await Wo("/api/terminal/open",{name:"Session 1"}))}catch(_){y(_.message)}x(!1)}async function te(){try{await Wo("/api/terminal/lock",{})}catch{}Vf(""),o(!1),M([])}function ne(T){!F||F.running||!T.trim()||(N(""),Q("/api/terminal/run",{id:F.id,command:T.trim()}).then(()=>D.current?.focus()))}function Y(){F&&Q("/api/terminal/stop",{id:F.id})}return s?t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"pro-page-top",children:[t.jsxs("div",{children:[t.jsx(_t,{tone:"lime",children:u("SERVER CONSOLE")}),t.jsx("p",{children:u("One place for commands. Space for every session.")})]}),t.jsxs("div",{className:"pro-actions",children:[t.jsxs("span",{className:"pro-small",children:[u(S.length),u(" / 6 sessions")]}),t.jsxs("button",{className:"secondary-btn",onClick:te,children:[t.jsx(am,{size:16}),u("Lock terminal")]}),t.jsxs("button",{className:"primary-btn",disabled:!yM(S.length),onClick:V,children:[t.jsx(jn,{size:16}),u("New session")]})]})]}),t.jsxs("section",{className:"pro-terminal-shell",children:[t.jsx("header",{className:"pro-terminal-tabs",children:S.map(T=>t.jsxs("div",{className:F?.id===T.id?"selected":"",children:[t.jsxs("button",{onClick:()=>k(T.id),children:[t.jsx("span",{className:T.running?"running":""}),t.jsx(w2,{size:14}),T.name]}),t.jsx("button",{"aria-label":u(`Close ${T.name}`),onClick:()=>L(T.id),children:t.jsx(da,{size:13})})]},T.id))}),t.jsxs("div",{className:"pro-terminal-info",children:[t.jsxs("span",{children:[t.jsx("i",{}),u(F?.running?"Process running":"Ready for commands")]}),t.jsx("span",{children:u(F?`${F.cwd}`:"No session")})]}),t.jsxs("div",{className:"pro-terminal-output",role:"log","aria-label":u("Terminal output"),children:[u(F?.lines.map((T,_)=>t.jsx("pre",{className:T.kind,children:T.text},_))),!F&&t.jsx("p",{children:u("Create a session to get started.")}),t.jsx("div",{ref:P})]}),t.jsxs("form",{className:"pro-terminal-input",onSubmit:T=>{T.preventDefault(),ne(R)},children:[t.jsxs("span",{children:[u(F?`${F.cwd.split("/").pop()||"/"} `:""),t.jsx("b",{children:u("❯")})]}),t.jsx("input",{ref:D,value:R,onChange:T=>N(T.target.value),disabled:!F||F.running,"aria-label":u("Terminal command"),placeholder:u(F?.running?"Process running. Stop it to enter another command.":"Enter a command..."),autoComplete:"off",spellCheck:!1,onKeyDown:T=>{T.ctrlKey&&T.key==="c"&&(T.preventDefault(),Y())}}),F?.running?t.jsx("button",{type:"button",onClick:Y,"aria-label":u("Stop process"),children:t.jsx($b,{size:16})}):t.jsx("button",{"aria-label":u("Run command"),disabled:!R.trim()||!F,children:t.jsx(Kn,{size:18})})]})]}),t.jsxs("section",{className:"panel pro-quick-commands",children:[t.jsxs("div",{className:"panel-title",children:[t.jsxs("div",{children:[t.jsx("h2",{children:u("Quick commands")}),t.jsx("p",{children:u("A shorter path to the checks you run often.")})]}),t.jsxs("button",{className:"secondary-btn",onClick:()=>z(!0),children:[t.jsx(jn,{size:16}),u("Add command")]})]}),t.jsx("div",{children:w.map(T=>t.jsxs("article",{children:[t.jsxs("button",{disabled:!F||F.running,onClick:()=>ne(T.command),children:[t.jsx(gi,{size:16}),t.jsxs("span",{children:[t.jsx("strong",{children:T.name}),t.jsx("code",{children:T.command})]})]}),t.jsx("button",{className:"icon-btn","aria-label":u(`Remove ${T.name} command`),onClick:()=>Q("/api/terminal/commands",{commands:w.filter(_=>_.id!==T.id)}),children:t.jsx(ti,{size:14})})]},T.id))})]}),t.jsx(on,{title:u("Add a quick command"),description:"Give a frequent command a useful name.",open:I,onClose:()=>z(!1),children:t.jsxs("form",{onSubmit:T=>{T.preventDefault();const _=new FormData(T.currentTarget);Q("/api/terminal/commands",{commands:[...w,{id:crypto.randomUUID(),name:String(_.get("name")).trim(),command:String(_.get("command")).trim()}]}),z(!1)},children:[t.jsxs("label",{children:[u("Name"),t.jsx("input",{name:"name",required:!0,maxLength:60})]}),t.jsxs("label",{children:[u("Command"),t.jsx("input",{name:"command",required:!0,maxLength:500,className:"pro-code-input"})]}),t.jsxs("button",{className:"primary-btn",children:[t.jsx(jn,{size:16}),u("Add command")]})]})}),t.jsx(on,{title:u("Close this session?"),description:"Anything running in it stops. Other sessions keep running.",open:!!j,onClose:()=>L(""),children:t.jsxs("div",{className:"pro-actions right",children:[t.jsx("button",{className:"secondary-btn",onClick:()=>L(""),children:u("Keep session")}),t.jsx("button",{className:"pro-danger",onClick:()=>{Q("/api/terminal/close",{id:j}),k(""),L("")},children:u("Close session")})]})})]}):t.jsxs("section",{className:"panel pro-terminal-lock",children:[t.jsxs("div",{className:"pro-lock-art",children:[t.jsx("span",{children:t.jsx(am,{size:34})}),t.jsx("i",{}),t.jsx("i",{}),t.jsx("i",{})]}),t.jsx(_t,{tone:"lime",children:u("PRIVATE CONSOLE")}),t.jsx("h2",{children:u(q?"Your terminal. Your access.":"Unlock your terminal.")}),t.jsx("p",{children:u(q?"Set a password before opening the server console.":"Your sessions are still here. Enter your password to continue.")}),t.jsxs("form",{onSubmit:$,children:[t.jsxs("label",{children:[u(q?"Create password":"Password"),t.jsx("input",{type:"password",autoComplete:q?"new-password":"current-password",value:l,onChange:T=>d(T.target.value),required:!0,minLength:q?8:1})]}),q&&t.jsxs("label",{children:[u("Confirm password"),t.jsx("input",{type:"password",autoComplete:"new-password",value:h,onChange:T=>m(T.target.value),required:!0})]}),t.jsxs("button",{className:"primary-btn",disabled:v,children:[t.jsx(wU,{size:17}),u(v?"Checking...":q?"Set password & open":"Unlock console"),t.jsx(Kn,{size:16})]}),p&&t.jsx(Ot,{error:!0,children:u(p)})]}),t.jsxs("div",{className:"pro-lock-note",children:[t.jsx(za,{size:16}),t.jsx("p",{children:u("This password protects the terminal on the server. Each browser tab unlocks on its own.")})]})]})}const k0="180",Zc={ROTATE:0,DOLLY:1,PAN:2},qc={ROTATE:0,PAN:1,DOLLY_PAN:2,DOLLY_ROTATE:3},Z8=0,bM=1,Q8=2,Rk=1,kk=2,fr=3,Ao=0,ai=1,mr=2,Ja=0,Qc=1,SM=2,AM=3,EM=4,Nk=5,gr=100,_8=101,$8=102,eH=103,tH=104,Fy=200,nH=201,aH=202,iH=203,By=204,Hy=205,Dk=206,sH=207,zk=208,rH=209,oH=210,lH=211,cH=212,uH=213,dH=214,Gy=0,Vy=1,qy=2,au=3,Wy=4,Yy=5,Xy=6,Ky=7,N0=0,hH=1,fH=2,mo=0,Lk=1,Ok=2,Pk=3,D0=4,Ik=5,Uk=6,Fk=7,Bk=300,iu=301,su=302,Jy=303,Zy=304,qm=306,th=1e3,ll=1001,Qy=1002,ii=1003,pH=1004,qf=1005,Is=1006,yx=1007,cl=1008,Gs=1009,Hk=1010,Gk=1011,nh=1012,z0=1013,wl=1014,bs=1015,Er=1016,L0=1017,O0=1018,ru=1020,Vk=35902,qk=35899,Wk=1021,Yk=1022,Ss=1023,ah=1026,ou=1027,Wm=1028,P0=1029,Xk=1030,I0=1031,U0=1033,Fp=33776,Bp=33777,Hp=33778,Gp=33779,_y=35840,$y=35841,eb=35842,tb=35843,nb=36196,ab=37492,ib=37496,sb=37808,rb=37809,ob=37810,lb=37811,cb=37812,ub=37813,db=37814,hb=37815,fb=37816,pb=37817,mb=37818,gb=37819,vb=37820,xb=37821,yb=36492,bb=36494,Sb=36495,Ab=36283,Eb=36284,wb=36285,Mb=36286,mH=3200,gH=3201,Ym=0,vH=1,co="",Xa="srgb",lu="srgb-linear",hm="linear",Mn="srgb",fc=7680,wM=519,xH=512,yH=513,bH=514,Kk=515,SH=516,AH=517,EH=518,wH=519,Cb=35044,MM="300 es",Us=2e3,fm=2001;class Rl{addEventListener(e,n){this._listeners===void 0&&(this._listeners={});const s=this._listeners;s[e]===void 0&&(s[e]=[]),s[e].indexOf(n)===-1&&s[e].push(n)}hasEventListener(e,n){const s=this._listeners;return s===void 0?!1:s[e]!==void 0&&s[e].indexOf(n)!==-1}removeEventListener(e,n){const s=this._listeners;if(s===void 0)return;const o=s[e];if(o!==void 0){const l=o.indexOf(n);l!==-1&&o.splice(l,1)}}dispatchEvent(e){const n=this._listeners;if(n===void 0)return;const s=n[e.type];if(s!==void 0){e.target=this;const o=s.slice(0);for(let l=0,d=o.length;l>8&255]+Ua[a>>16&255]+Ua[a>>24&255]+"-"+Ua[e&255]+Ua[e>>8&255]+"-"+Ua[e>>16&15|64]+Ua[e>>24&255]+"-"+Ua[n&63|128]+Ua[n>>8&255]+"-"+Ua[n>>16&255]+Ua[n>>24&255]+Ua[s&255]+Ua[s>>8&255]+Ua[s>>16&255]+Ua[s>>24&255]).toLowerCase()}function en(a,e,n){return Math.max(e,Math.min(n,a))}function F0(a,e){return(a%e+e)%e}function MH(a,e,n,s,o){return s+(a-e)*(o-s)/(n-e)}function CH(a,e,n){return a!==e?(n-a)/(e-a):0}function Vd(a,e,n){return(1-n)*a+n*e}function TH(a,e,n,s){return Vd(a,e,1-Math.exp(-n*s))}function jH(a,e=1){return e-Math.abs(F0(a,e*2)-e)}function RH(a,e,n){return a<=e?0:a>=n?1:(a=(a-e)/(n-e),a*a*(3-2*a))}function kH(a,e,n){return a<=e?0:a>=n?1:(a=(a-e)/(n-e),a*a*a*(a*(a*6-15)+10))}function NH(a,e){return a+Math.floor(Math.random()*(e-a+1))}function DH(a,e){return a+Math.random()*(e-a)}function zH(a){return a*(.5-Math.random())}function LH(a){a!==void 0&&(CM=a);let e=CM+=1831565813;return e=Math.imul(e^e>>>15,e|1),e^=e+Math.imul(e^e>>>7,e|61),((e^e>>>14)>>>0)/4294967296}function OH(a){return a*Gd}function PH(a){return a*ih}function IH(a){return(a&a-1)===0&&a!==0}function UH(a){return Math.pow(2,Math.ceil(Math.log(a)/Math.LN2))}function FH(a){return Math.pow(2,Math.floor(Math.log(a)/Math.LN2))}function BH(a,e,n,s,o){const l=Math.cos,d=Math.sin,h=l(n/2),m=d(n/2),p=l((e+s)/2),y=d((e+s)/2),v=l((e-s)/2),x=d((e-s)/2),S=l((s-e)/2),M=d((s-e)/2);switch(o){case"XYX":a.set(h*y,m*v,m*x,h*p);break;case"YZY":a.set(m*x,h*y,m*v,h*p);break;case"ZXZ":a.set(m*v,m*x,h*y,h*p);break;case"XZX":a.set(h*y,m*M,m*S,h*p);break;case"YXY":a.set(m*S,h*y,m*M,h*p);break;case"ZYZ":a.set(m*M,m*S,h*y,h*p);break;default:console.warn("THREE.MathUtils: .setQuaternionFromProperEuler() encountered an unknown order: "+o)}}function xs(a,e){switch(e.constructor){case Float32Array:return a;case Uint32Array:return a/4294967295;case Uint16Array:return a/65535;case Uint8Array:return a/255;case Int32Array:return Math.max(a/2147483647,-1);case Int16Array:return Math.max(a/32767,-1);case Int8Array:return Math.max(a/127,-1);default:throw new Error("Invalid component type.")}}function Cn(a,e){switch(e.constructor){case Float32Array:return a;case Uint32Array:return Math.round(a*4294967295);case Uint16Array:return Math.round(a*65535);case Uint8Array:return Math.round(a*255);case Int32Array:return Math.round(a*2147483647);case Int16Array:return Math.round(a*32767);case Int8Array:return Math.round(a*127);default:throw new Error("Invalid component type.")}}const Jk={DEG2RAD:Gd,RAD2DEG:ih,generateUUID:yr,clamp:en,euclideanModulo:F0,mapLinear:MH,inverseLerp:CH,lerp:Vd,damp:TH,pingpong:jH,smoothstep:RH,smootherstep:kH,randInt:NH,randFloat:DH,randFloatSpread:zH,seededRandom:LH,degToRad:OH,radToDeg:PH,isPowerOfTwo:IH,ceilPowerOfTwo:UH,floorPowerOfTwo:FH,setQuaternionFromProperEuler:BH,normalize:Cn,denormalize:xs};class jt{constructor(e=0,n=0){jt.prototype.isVector2=!0,this.x=e,this.y=n}get width(){return this.x}set width(e){this.x=e}get height(){return this.y}set height(e){this.y=e}set(e,n){return this.x=e,this.y=n,this}setScalar(e){return this.x=e,this.y=e,this}setX(e){return this.x=e,this}setY(e){return this.y=e,this}setComponent(e,n){switch(e){case 0:this.x=n;break;case 1:this.y=n;break;default:throw new Error("index is out of range: "+e)}return this}getComponent(e){switch(e){case 0:return this.x;case 1:return this.y;default:throw new Error("index is out of range: "+e)}}clone(){return new this.constructor(this.x,this.y)}copy(e){return this.x=e.x,this.y=e.y,this}add(e){return this.x+=e.x,this.y+=e.y,this}addScalar(e){return this.x+=e,this.y+=e,this}addVectors(e,n){return this.x=e.x+n.x,this.y=e.y+n.y,this}addScaledVector(e,n){return this.x+=e.x*n,this.y+=e.y*n,this}sub(e){return this.x-=e.x,this.y-=e.y,this}subScalar(e){return this.x-=e,this.y-=e,this}subVectors(e,n){return this.x=e.x-n.x,this.y=e.y-n.y,this}multiply(e){return this.x*=e.x,this.y*=e.y,this}multiplyScalar(e){return this.x*=e,this.y*=e,this}divide(e){return this.x/=e.x,this.y/=e.y,this}divideScalar(e){return this.multiplyScalar(1/e)}applyMatrix3(e){const n=this.x,s=this.y,o=e.elements;return this.x=o[0]*n+o[3]*s+o[6],this.y=o[1]*n+o[4]*s+o[7],this}min(e){return this.x=Math.min(this.x,e.x),this.y=Math.min(this.y,e.y),this}max(e){return this.x=Math.max(this.x,e.x),this.y=Math.max(this.y,e.y),this}clamp(e,n){return this.x=en(this.x,e.x,n.x),this.y=en(this.y,e.y,n.y),this}clampScalar(e,n){return this.x=en(this.x,e,n),this.y=en(this.y,e,n),this}clampLength(e,n){const s=this.length();return this.divideScalar(s||1).multiplyScalar(en(s,e,n))}floor(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this}ceil(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this}round(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this}roundToZero(){return this.x=Math.trunc(this.x),this.y=Math.trunc(this.y),this}negate(){return this.x=-this.x,this.y=-this.y,this}dot(e){return this.x*e.x+this.y*e.y}cross(e){return this.x*e.y-this.y*e.x}lengthSq(){return this.x*this.x+this.y*this.y}length(){return Math.sqrt(this.x*this.x+this.y*this.y)}manhattanLength(){return Math.abs(this.x)+Math.abs(this.y)}normalize(){return this.divideScalar(this.length()||1)}angle(){return Math.atan2(-this.y,-this.x)+Math.PI}angleTo(e){const n=Math.sqrt(this.lengthSq()*e.lengthSq());if(n===0)return Math.PI/2;const s=this.dot(e)/n;return Math.acos(en(s,-1,1))}distanceTo(e){return Math.sqrt(this.distanceToSquared(e))}distanceToSquared(e){const n=this.x-e.x,s=this.y-e.y;return n*n+s*s}manhattanDistanceTo(e){return Math.abs(this.x-e.x)+Math.abs(this.y-e.y)}setLength(e){return this.normalize().multiplyScalar(e)}lerp(e,n){return this.x+=(e.x-this.x)*n,this.y+=(e.y-this.y)*n,this}lerpVectors(e,n,s){return this.x=e.x+(n.x-e.x)*s,this.y=e.y+(n.y-e.y)*s,this}equals(e){return e.x===this.x&&e.y===this.y}fromArray(e,n=0){return this.x=e[n],this.y=e[n+1],this}toArray(e=[],n=0){return e[n]=this.x,e[n+1]=this.y,e}fromBufferAttribute(e,n){return this.x=e.getX(n),this.y=e.getY(n),this}rotateAround(e,n){const s=Math.cos(n),o=Math.sin(n),l=this.x-e.x,d=this.y-e.y;return this.x=l*s-d*o+e.x,this.y=l*o+d*s+e.y,this}random(){return this.x=Math.random(),this.y=Math.random(),this}*[Symbol.iterator](){yield this.x,yield this.y}}class Ml{constructor(e=0,n=0,s=0,o=1){this.isQuaternion=!0,this._x=e,this._y=n,this._z=s,this._w=o}static slerpFlat(e,n,s,o,l,d,h){let m=s[o+0],p=s[o+1],y=s[o+2],v=s[o+3];const x=l[d+0],S=l[d+1],M=l[d+2],w=l[d+3];if(h===0){e[n+0]=m,e[n+1]=p,e[n+2]=y,e[n+3]=v;return}if(h===1){e[n+0]=x,e[n+1]=S,e[n+2]=M,e[n+3]=w;return}if(v!==w||m!==x||p!==S||y!==M){let E=1-h;const A=m*x+p*S+y*M+v*w,k=A>=0?1:-1,R=1-A*A;if(R>Number.EPSILON){const I=Math.sqrt(R),z=Math.atan2(I,A*k);E=Math.sin(E*z)/I,h=Math.sin(h*z)/I}const N=h*k;if(m=m*E+x*N,p=p*E+S*N,y=y*E+M*N,v=v*E+w*N,E===1-h){const I=1/Math.sqrt(m*m+p*p+y*y+v*v);m*=I,p*=I,y*=I,v*=I}}e[n]=m,e[n+1]=p,e[n+2]=y,e[n+3]=v}static multiplyQuaternionsFlat(e,n,s,o,l,d){const h=s[o],m=s[o+1],p=s[o+2],y=s[o+3],v=l[d],x=l[d+1],S=l[d+2],M=l[d+3];return e[n]=h*M+y*v+m*S-p*x,e[n+1]=m*M+y*x+p*v-h*S,e[n+2]=p*M+y*S+h*x-m*v,e[n+3]=y*M-h*v-m*x-p*S,e}get x(){return this._x}set x(e){this._x=e,this._onChangeCallback()}get y(){return this._y}set y(e){this._y=e,this._onChangeCallback()}get z(){return this._z}set z(e){this._z=e,this._onChangeCallback()}get w(){return this._w}set w(e){this._w=e,this._onChangeCallback()}set(e,n,s,o){return this._x=e,this._y=n,this._z=s,this._w=o,this._onChangeCallback(),this}clone(){return new this.constructor(this._x,this._y,this._z,this._w)}copy(e){return this._x=e.x,this._y=e.y,this._z=e.z,this._w=e.w,this._onChangeCallback(),this}setFromEuler(e,n=!0){const s=e._x,o=e._y,l=e._z,d=e._order,h=Math.cos,m=Math.sin,p=h(s/2),y=h(o/2),v=h(l/2),x=m(s/2),S=m(o/2),M=m(l/2);switch(d){case"XYZ":this._x=x*y*v+p*S*M,this._y=p*S*v-x*y*M,this._z=p*y*M+x*S*v,this._w=p*y*v-x*S*M;break;case"YXZ":this._x=x*y*v+p*S*M,this._y=p*S*v-x*y*M,this._z=p*y*M-x*S*v,this._w=p*y*v+x*S*M;break;case"ZXY":this._x=x*y*v-p*S*M,this._y=p*S*v+x*y*M,this._z=p*y*M+x*S*v,this._w=p*y*v-x*S*M;break;case"ZYX":this._x=x*y*v-p*S*M,this._y=p*S*v+x*y*M,this._z=p*y*M-x*S*v,this._w=p*y*v+x*S*M;break;case"YZX":this._x=x*y*v+p*S*M,this._y=p*S*v+x*y*M,this._z=p*y*M-x*S*v,this._w=p*y*v-x*S*M;break;case"XZY":this._x=x*y*v-p*S*M,this._y=p*S*v-x*y*M,this._z=p*y*M+x*S*v,this._w=p*y*v+x*S*M;break;default:console.warn("THREE.Quaternion: .setFromEuler() encountered an unknown order: "+d)}return n===!0&&this._onChangeCallback(),this}setFromAxisAngle(e,n){const s=n/2,o=Math.sin(s);return this._x=e.x*o,this._y=e.y*o,this._z=e.z*o,this._w=Math.cos(s),this._onChangeCallback(),this}setFromRotationMatrix(e){const n=e.elements,s=n[0],o=n[4],l=n[8],d=n[1],h=n[5],m=n[9],p=n[2],y=n[6],v=n[10],x=s+h+v;if(x>0){const S=.5/Math.sqrt(x+1);this._w=.25/S,this._x=(y-m)*S,this._y=(l-p)*S,this._z=(d-o)*S}else if(s>h&&s>v){const S=2*Math.sqrt(1+s-h-v);this._w=(y-m)/S,this._x=.25*S,this._y=(o+d)/S,this._z=(l+p)/S}else if(h>v){const S=2*Math.sqrt(1+h-s-v);this._w=(l-p)/S,this._x=(o+d)/S,this._y=.25*S,this._z=(m+y)/S}else{const S=2*Math.sqrt(1+v-s-h);this._w=(d-o)/S,this._x=(l+p)/S,this._y=(m+y)/S,this._z=.25*S}return this._onChangeCallback(),this}setFromUnitVectors(e,n){let s=e.dot(n)+1;return s<1e-8?(s=0,Math.abs(e.x)>Math.abs(e.z)?(this._x=-e.y,this._y=e.x,this._z=0,this._w=s):(this._x=0,this._y=-e.z,this._z=e.y,this._w=s)):(this._x=e.y*n.z-e.z*n.y,this._y=e.z*n.x-e.x*n.z,this._z=e.x*n.y-e.y*n.x,this._w=s),this.normalize()}angleTo(e){return 2*Math.acos(Math.abs(en(this.dot(e),-1,1)))}rotateTowards(e,n){const s=this.angleTo(e);if(s===0)return this;const o=Math.min(1,n/s);return this.slerp(e,o),this}identity(){return this.set(0,0,0,1)}invert(){return this.conjugate()}conjugate(){return this._x*=-1,this._y*=-1,this._z*=-1,this._onChangeCallback(),this}dot(e){return this._x*e._x+this._y*e._y+this._z*e._z+this._w*e._w}lengthSq(){return this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w}length(){return Math.sqrt(this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w)}normalize(){let e=this.length();return e===0?(this._x=0,this._y=0,this._z=0,this._w=1):(e=1/e,this._x=this._x*e,this._y=this._y*e,this._z=this._z*e,this._w=this._w*e),this._onChangeCallback(),this}multiply(e){return this.multiplyQuaternions(this,e)}premultiply(e){return this.multiplyQuaternions(e,this)}multiplyQuaternions(e,n){const s=e._x,o=e._y,l=e._z,d=e._w,h=n._x,m=n._y,p=n._z,y=n._w;return this._x=s*y+d*h+o*p-l*m,this._y=o*y+d*m+l*h-s*p,this._z=l*y+d*p+s*m-o*h,this._w=d*y-s*h-o*m-l*p,this._onChangeCallback(),this}slerp(e,n){if(n===0)return this;if(n===1)return this.copy(e);const s=this._x,o=this._y,l=this._z,d=this._w;let h=d*e._w+s*e._x+o*e._y+l*e._z;if(h<0?(this._w=-e._w,this._x=-e._x,this._y=-e._y,this._z=-e._z,h=-h):this.copy(e),h>=1)return this._w=d,this._x=s,this._y=o,this._z=l,this;const m=1-h*h;if(m<=Number.EPSILON){const S=1-n;return this._w=S*d+n*this._w,this._x=S*s+n*this._x,this._y=S*o+n*this._y,this._z=S*l+n*this._z,this.normalize(),this}const p=Math.sqrt(m),y=Math.atan2(p,h),v=Math.sin((1-n)*y)/p,x=Math.sin(n*y)/p;return this._w=d*v+this._w*x,this._x=s*v+this._x*x,this._y=o*v+this._y*x,this._z=l*v+this._z*x,this._onChangeCallback(),this}slerpQuaternions(e,n,s){return this.copy(e).slerp(n,s)}random(){const e=2*Math.PI*Math.random(),n=2*Math.PI*Math.random(),s=Math.random(),o=Math.sqrt(1-s),l=Math.sqrt(s);return this.set(o*Math.sin(e),o*Math.cos(e),l*Math.sin(n),l*Math.cos(n))}equals(e){return e._x===this._x&&e._y===this._y&&e._z===this._z&&e._w===this._w}fromArray(e,n=0){return this._x=e[n],this._y=e[n+1],this._z=e[n+2],this._w=e[n+3],this._onChangeCallback(),this}toArray(e=[],n=0){return e[n]=this._x,e[n+1]=this._y,e[n+2]=this._z,e[n+3]=this._w,e}fromBufferAttribute(e,n){return this._x=e.getX(n),this._y=e.getY(n),this._z=e.getZ(n),this._w=e.getW(n),this._onChangeCallback(),this}toJSON(){return this.toArray()}_onChange(e){return this._onChangeCallback=e,this}_onChangeCallback(){}*[Symbol.iterator](){yield this._x,yield this._y,yield this._z,yield this._w}}class he{constructor(e=0,n=0,s=0){he.prototype.isVector3=!0,this.x=e,this.y=n,this.z=s}set(e,n,s){return s===void 0&&(s=this.z),this.x=e,this.y=n,this.z=s,this}setScalar(e){return this.x=e,this.y=e,this.z=e,this}setX(e){return this.x=e,this}setY(e){return this.y=e,this}setZ(e){return this.z=e,this}setComponent(e,n){switch(e){case 0:this.x=n;break;case 1:this.y=n;break;case 2:this.z=n;break;default:throw new Error("index is out of range: "+e)}return this}getComponent(e){switch(e){case 0:return this.x;case 1:return this.y;case 2:return this.z;default:throw new Error("index is out of range: "+e)}}clone(){return new this.constructor(this.x,this.y,this.z)}copy(e){return this.x=e.x,this.y=e.y,this.z=e.z,this}add(e){return this.x+=e.x,this.y+=e.y,this.z+=e.z,this}addScalar(e){return this.x+=e,this.y+=e,this.z+=e,this}addVectors(e,n){return this.x=e.x+n.x,this.y=e.y+n.y,this.z=e.z+n.z,this}addScaledVector(e,n){return this.x+=e.x*n,this.y+=e.y*n,this.z+=e.z*n,this}sub(e){return this.x-=e.x,this.y-=e.y,this.z-=e.z,this}subScalar(e){return this.x-=e,this.y-=e,this.z-=e,this}subVectors(e,n){return this.x=e.x-n.x,this.y=e.y-n.y,this.z=e.z-n.z,this}multiply(e){return this.x*=e.x,this.y*=e.y,this.z*=e.z,this}multiplyScalar(e){return this.x*=e,this.y*=e,this.z*=e,this}multiplyVectors(e,n){return this.x=e.x*n.x,this.y=e.y*n.y,this.z=e.z*n.z,this}applyEuler(e){return this.applyQuaternion(TM.setFromEuler(e))}applyAxisAngle(e,n){return this.applyQuaternion(TM.setFromAxisAngle(e,n))}applyMatrix3(e){const n=this.x,s=this.y,o=this.z,l=e.elements;return this.x=l[0]*n+l[3]*s+l[6]*o,this.y=l[1]*n+l[4]*s+l[7]*o,this.z=l[2]*n+l[5]*s+l[8]*o,this}applyNormalMatrix(e){return this.applyMatrix3(e).normalize()}applyMatrix4(e){const n=this.x,s=this.y,o=this.z,l=e.elements,d=1/(l[3]*n+l[7]*s+l[11]*o+l[15]);return this.x=(l[0]*n+l[4]*s+l[8]*o+l[12])*d,this.y=(l[1]*n+l[5]*s+l[9]*o+l[13])*d,this.z=(l[2]*n+l[6]*s+l[10]*o+l[14])*d,this}applyQuaternion(e){const n=this.x,s=this.y,o=this.z,l=e.x,d=e.y,h=e.z,m=e.w,p=2*(d*o-h*s),y=2*(h*n-l*o),v=2*(l*s-d*n);return this.x=n+m*p+d*v-h*y,this.y=s+m*y+h*p-l*v,this.z=o+m*v+l*y-d*p,this}project(e){return this.applyMatrix4(e.matrixWorldInverse).applyMatrix4(e.projectionMatrix)}unproject(e){return this.applyMatrix4(e.projectionMatrixInverse).applyMatrix4(e.matrixWorld)}transformDirection(e){const n=this.x,s=this.y,o=this.z,l=e.elements;return this.x=l[0]*n+l[4]*s+l[8]*o,this.y=l[1]*n+l[5]*s+l[9]*o,this.z=l[2]*n+l[6]*s+l[10]*o,this.normalize()}divide(e){return this.x/=e.x,this.y/=e.y,this.z/=e.z,this}divideScalar(e){return this.multiplyScalar(1/e)}min(e){return this.x=Math.min(this.x,e.x),this.y=Math.min(this.y,e.y),this.z=Math.min(this.z,e.z),this}max(e){return this.x=Math.max(this.x,e.x),this.y=Math.max(this.y,e.y),this.z=Math.max(this.z,e.z),this}clamp(e,n){return this.x=en(this.x,e.x,n.x),this.y=en(this.y,e.y,n.y),this.z=en(this.z,e.z,n.z),this}clampScalar(e,n){return this.x=en(this.x,e,n),this.y=en(this.y,e,n),this.z=en(this.z,e,n),this}clampLength(e,n){const s=this.length();return this.divideScalar(s||1).multiplyScalar(en(s,e,n))}floor(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this.z=Math.floor(this.z),this}ceil(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this.z=Math.ceil(this.z),this}round(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this.z=Math.round(this.z),this}roundToZero(){return this.x=Math.trunc(this.x),this.y=Math.trunc(this.y),this.z=Math.trunc(this.z),this}negate(){return this.x=-this.x,this.y=-this.y,this.z=-this.z,this}dot(e){return this.x*e.x+this.y*e.y+this.z*e.z}lengthSq(){return this.x*this.x+this.y*this.y+this.z*this.z}length(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)}manhattanLength(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)}normalize(){return this.divideScalar(this.length()||1)}setLength(e){return this.normalize().multiplyScalar(e)}lerp(e,n){return this.x+=(e.x-this.x)*n,this.y+=(e.y-this.y)*n,this.z+=(e.z-this.z)*n,this}lerpVectors(e,n,s){return this.x=e.x+(n.x-e.x)*s,this.y=e.y+(n.y-e.y)*s,this.z=e.z+(n.z-e.z)*s,this}cross(e){return this.crossVectors(this,e)}crossVectors(e,n){const s=e.x,o=e.y,l=e.z,d=n.x,h=n.y,m=n.z;return this.x=o*m-l*h,this.y=l*d-s*m,this.z=s*h-o*d,this}projectOnVector(e){const n=e.lengthSq();if(n===0)return this.set(0,0,0);const s=e.dot(this)/n;return this.copy(e).multiplyScalar(s)}projectOnPlane(e){return bx.copy(this).projectOnVector(e),this.sub(bx)}reflect(e){return this.sub(bx.copy(e).multiplyScalar(2*this.dot(e)))}angleTo(e){const n=Math.sqrt(this.lengthSq()*e.lengthSq());if(n===0)return Math.PI/2;const s=this.dot(e)/n;return Math.acos(en(s,-1,1))}distanceTo(e){return Math.sqrt(this.distanceToSquared(e))}distanceToSquared(e){const n=this.x-e.x,s=this.y-e.y,o=this.z-e.z;return n*n+s*s+o*o}manhattanDistanceTo(e){return Math.abs(this.x-e.x)+Math.abs(this.y-e.y)+Math.abs(this.z-e.z)}setFromSpherical(e){return this.setFromSphericalCoords(e.radius,e.phi,e.theta)}setFromSphericalCoords(e,n,s){const o=Math.sin(n)*e;return this.x=o*Math.sin(s),this.y=Math.cos(n)*e,this.z=o*Math.cos(s),this}setFromCylindrical(e){return this.setFromCylindricalCoords(e.radius,e.theta,e.y)}setFromCylindricalCoords(e,n,s){return this.x=e*Math.sin(n),this.y=s,this.z=e*Math.cos(n),this}setFromMatrixPosition(e){const n=e.elements;return this.x=n[12],this.y=n[13],this.z=n[14],this}setFromMatrixScale(e){const n=this.setFromMatrixColumn(e,0).length(),s=this.setFromMatrixColumn(e,1).length(),o=this.setFromMatrixColumn(e,2).length();return this.x=n,this.y=s,this.z=o,this}setFromMatrixColumn(e,n){return this.fromArray(e.elements,n*4)}setFromMatrix3Column(e,n){return this.fromArray(e.elements,n*3)}setFromEuler(e){return this.x=e._x,this.y=e._y,this.z=e._z,this}setFromColor(e){return this.x=e.r,this.y=e.g,this.z=e.b,this}equals(e){return e.x===this.x&&e.y===this.y&&e.z===this.z}fromArray(e,n=0){return this.x=e[n],this.y=e[n+1],this.z=e[n+2],this}toArray(e=[],n=0){return e[n]=this.x,e[n+1]=this.y,e[n+2]=this.z,e}fromBufferAttribute(e,n){return this.x=e.getX(n),this.y=e.getY(n),this.z=e.getZ(n),this}random(){return this.x=Math.random(),this.y=Math.random(),this.z=Math.random(),this}randomDirection(){const e=Math.random()*Math.PI*2,n=Math.random()*2-1,s=Math.sqrt(1-n*n);return this.x=s*Math.cos(e),this.y=n,this.z=s*Math.sin(e),this}*[Symbol.iterator](){yield this.x,yield this.y,yield this.z}}const bx=new he,TM=new Ml;class Qt{constructor(e,n,s,o,l,d,h,m,p){Qt.prototype.isMatrix3=!0,this.elements=[1,0,0,0,1,0,0,0,1],e!==void 0&&this.set(e,n,s,o,l,d,h,m,p)}set(e,n,s,o,l,d,h,m,p){const y=this.elements;return y[0]=e,y[1]=o,y[2]=h,y[3]=n,y[4]=l,y[5]=m,y[6]=s,y[7]=d,y[8]=p,this}identity(){return this.set(1,0,0,0,1,0,0,0,1),this}copy(e){const n=this.elements,s=e.elements;return n[0]=s[0],n[1]=s[1],n[2]=s[2],n[3]=s[3],n[4]=s[4],n[5]=s[5],n[6]=s[6],n[7]=s[7],n[8]=s[8],this}extractBasis(e,n,s){return e.setFromMatrix3Column(this,0),n.setFromMatrix3Column(this,1),s.setFromMatrix3Column(this,2),this}setFromMatrix4(e){const n=e.elements;return this.set(n[0],n[4],n[8],n[1],n[5],n[9],n[2],n[6],n[10]),this}multiply(e){return this.multiplyMatrices(this,e)}premultiply(e){return this.multiplyMatrices(e,this)}multiplyMatrices(e,n){const s=e.elements,o=n.elements,l=this.elements,d=s[0],h=s[3],m=s[6],p=s[1],y=s[4],v=s[7],x=s[2],S=s[5],M=s[8],w=o[0],E=o[3],A=o[6],k=o[1],R=o[4],N=o[7],I=o[2],z=o[5],j=o[8];return l[0]=d*w+h*k+m*I,l[3]=d*E+h*R+m*z,l[6]=d*A+h*N+m*j,l[1]=p*w+y*k+v*I,l[4]=p*E+y*R+v*z,l[7]=p*A+y*N+v*j,l[2]=x*w+S*k+M*I,l[5]=x*E+S*R+M*z,l[8]=x*A+S*N+M*j,this}multiplyScalar(e){const n=this.elements;return n[0]*=e,n[3]*=e,n[6]*=e,n[1]*=e,n[4]*=e,n[7]*=e,n[2]*=e,n[5]*=e,n[8]*=e,this}determinant(){const e=this.elements,n=e[0],s=e[1],o=e[2],l=e[3],d=e[4],h=e[5],m=e[6],p=e[7],y=e[8];return n*d*y-n*h*p-s*l*y+s*h*m+o*l*p-o*d*m}invert(){const e=this.elements,n=e[0],s=e[1],o=e[2],l=e[3],d=e[4],h=e[5],m=e[6],p=e[7],y=e[8],v=y*d-h*p,x=h*m-y*l,S=p*l-d*m,M=n*v+s*x+o*S;if(M===0)return this.set(0,0,0,0,0,0,0,0,0);const w=1/M;return e[0]=v*w,e[1]=(o*p-y*s)*w,e[2]=(h*s-o*d)*w,e[3]=x*w,e[4]=(y*n-o*m)*w,e[5]=(o*l-h*n)*w,e[6]=S*w,e[7]=(s*m-p*n)*w,e[8]=(d*n-s*l)*w,this}transpose(){let e;const n=this.elements;return e=n[1],n[1]=n[3],n[3]=e,e=n[2],n[2]=n[6],n[6]=e,e=n[5],n[5]=n[7],n[7]=e,this}getNormalMatrix(e){return this.setFromMatrix4(e).invert().transpose()}transposeIntoArray(e){const n=this.elements;return e[0]=n[0],e[1]=n[3],e[2]=n[6],e[3]=n[1],e[4]=n[4],e[5]=n[7],e[6]=n[2],e[7]=n[5],e[8]=n[8],this}setUvTransform(e,n,s,o,l,d,h){const m=Math.cos(l),p=Math.sin(l);return this.set(s*m,s*p,-s*(m*d+p*h)+d+e,-o*p,o*m,-o*(-p*d+m*h)+h+n,0,0,1),this}scale(e,n){return this.premultiply(Sx.makeScale(e,n)),this}rotate(e){return this.premultiply(Sx.makeRotation(-e)),this}translate(e,n){return this.premultiply(Sx.makeTranslation(e,n)),this}makeTranslation(e,n){return e.isVector2?this.set(1,0,e.x,0,1,e.y,0,0,1):this.set(1,0,e,0,1,n,0,0,1),this}makeRotation(e){const n=Math.cos(e),s=Math.sin(e);return this.set(n,-s,0,s,n,0,0,0,1),this}makeScale(e,n){return this.set(e,0,0,0,n,0,0,0,1),this}equals(e){const n=this.elements,s=e.elements;for(let o=0;o<9;o++)if(n[o]!==s[o])return!1;return!0}fromArray(e,n=0){for(let s=0;s<9;s++)this.elements[s]=e[s+n];return this}toArray(e=[],n=0){const s=this.elements;return e[n]=s[0],e[n+1]=s[1],e[n+2]=s[2],e[n+3]=s[3],e[n+4]=s[4],e[n+5]=s[5],e[n+6]=s[6],e[n+7]=s[7],e[n+8]=s[8],e}clone(){return new this.constructor().fromArray(this.elements)}}const Sx=new Qt;function Zk(a){for(let e=a.length-1;e>=0;--e)if(a[e]>=65535)return!0;return!1}function pm(a){return document.createElementNS("http://www.w3.org/1999/xhtml",a)}function HH(){const a=pm("canvas");return a.style.display="block",a}const jM={};function sh(a){a in jM||(jM[a]=!0,console.warn(a))}function GH(a,e,n){return new Promise(function(s,o){function l(){switch(a.clientWaitSync(e,a.SYNC_FLUSH_COMMANDS_BIT,0)){case a.WAIT_FAILED:o();break;case a.TIMEOUT_EXPIRED:setTimeout(l,n);break;default:s()}}setTimeout(l,n)})}const RM=new Qt().set(.4123908,.3575843,.1804808,.212639,.7151687,.0721923,.0193308,.1191948,.9505322),kM=new Qt().set(3.2409699,-1.5373832,-.4986108,-.9692436,1.8759675,.0415551,.0556301,-.203977,1.0569715);function VH(){const a={enabled:!0,workingColorSpace:lu,spaces:{},convert:function(o,l,d){return this.enabled===!1||l===d||!l||!d||(this.spaces[l].transfer===Mn&&(o.r=br(o.r),o.g=br(o.g),o.b=br(o.b)),this.spaces[l].primaries!==this.spaces[d].primaries&&(o.applyMatrix3(this.spaces[l].toXYZ),o.applyMatrix3(this.spaces[d].fromXYZ)),this.spaces[d].transfer===Mn&&(o.r=_c(o.r),o.g=_c(o.g),o.b=_c(o.b))),o},workingToColorSpace:function(o,l){return this.convert(o,this.workingColorSpace,l)},colorSpaceToWorking:function(o,l){return this.convert(o,l,this.workingColorSpace)},getPrimaries:function(o){return this.spaces[o].primaries},getTransfer:function(o){return o===co?hm:this.spaces[o].transfer},getToneMappingMode:function(o){return this.spaces[o].outputColorSpaceConfig.toneMappingMode||"standard"},getLuminanceCoefficients:function(o,l=this.workingColorSpace){return o.fromArray(this.spaces[l].luminanceCoefficients)},define:function(o){Object.assign(this.spaces,o)},_getMatrix:function(o,l,d){return o.copy(this.spaces[l].toXYZ).multiply(this.spaces[d].fromXYZ)},_getDrawingBufferColorSpace:function(o){return this.spaces[o].outputColorSpaceConfig.drawingBufferColorSpace},_getUnpackColorSpace:function(o=this.workingColorSpace){return this.spaces[o].workingColorSpaceConfig.unpackColorSpace},fromWorkingColorSpace:function(o,l){return sh("THREE.ColorManagement: .fromWorkingColorSpace() has been renamed to .workingToColorSpace()."),a.workingToColorSpace(o,l)},toWorkingColorSpace:function(o,l){return sh("THREE.ColorManagement: .toWorkingColorSpace() has been renamed to .colorSpaceToWorking()."),a.colorSpaceToWorking(o,l)}},e=[.64,.33,.3,.6,.15,.06],n=[.2126,.7152,.0722],s=[.3127,.329];return a.define({[lu]:{primaries:e,whitePoint:s,transfer:hm,toXYZ:RM,fromXYZ:kM,luminanceCoefficients:n,workingColorSpaceConfig:{unpackColorSpace:Xa},outputColorSpaceConfig:{drawingBufferColorSpace:Xa}},[Xa]:{primaries:e,whitePoint:s,transfer:Mn,toXYZ:RM,fromXYZ:kM,luminanceCoefficients:n,outputColorSpaceConfig:{drawingBufferColorSpace:Xa}}}),a}const pn=VH();function br(a){return a<.04045?a*.0773993808:Math.pow(a*.9478672986+.0521327014,2.4)}function _c(a){return a<.0031308?a*12.92:1.055*Math.pow(a,.41666)-.055}let pc;class qH{static getDataURL(e,n="image/png"){if(/^data:/i.test(e.src)||typeof HTMLCanvasElement>"u")return e.src;let s;if(e instanceof HTMLCanvasElement)s=e;else{pc===void 0&&(pc=pm("canvas")),pc.width=e.width,pc.height=e.height;const o=pc.getContext("2d");e instanceof ImageData?o.putImageData(e,0,0):o.drawImage(e,0,0,e.width,e.height),s=pc}return s.toDataURL(n)}static sRGBToLinear(e){if(typeof HTMLImageElement<"u"&&e instanceof HTMLImageElement||typeof HTMLCanvasElement<"u"&&e instanceof HTMLCanvasElement||typeof ImageBitmap<"u"&&e instanceof ImageBitmap){const n=pm("canvas");n.width=e.width,n.height=e.height;const s=n.getContext("2d");s.drawImage(e,0,0,e.width,e.height);const o=s.getImageData(0,0,e.width,e.height),l=o.data;for(let d=0;d1),this.pmremVersion=0}get width(){return this.source.getSize(Ex).x}get height(){return this.source.getSize(Ex).y}get depth(){return this.source.getSize(Ex).z}get image(){return this.source.data}set image(e=null){this.source.data=e}updateMatrix(){this.matrix.setUvTransform(this.offset.x,this.offset.y,this.repeat.x,this.repeat.y,this.rotation,this.center.x,this.center.y)}addUpdateRange(e,n){this.updateRanges.push({start:e,count:n})}clearUpdateRanges(){this.updateRanges.length=0}clone(){return new this.constructor().copy(this)}copy(e){return this.name=e.name,this.source=e.source,this.mipmaps=e.mipmaps.slice(0),this.mapping=e.mapping,this.channel=e.channel,this.wrapS=e.wrapS,this.wrapT=e.wrapT,this.magFilter=e.magFilter,this.minFilter=e.minFilter,this.anisotropy=e.anisotropy,this.format=e.format,this.internalFormat=e.internalFormat,this.type=e.type,this.offset.copy(e.offset),this.repeat.copy(e.repeat),this.center.copy(e.center),this.rotation=e.rotation,this.matrixAutoUpdate=e.matrixAutoUpdate,this.matrix.copy(e.matrix),this.generateMipmaps=e.generateMipmaps,this.premultiplyAlpha=e.premultiplyAlpha,this.flipY=e.flipY,this.unpackAlignment=e.unpackAlignment,this.colorSpace=e.colorSpace,this.renderTarget=e.renderTarget,this.isRenderTargetTexture=e.isRenderTargetTexture,this.isArrayTexture=e.isArrayTexture,this.userData=JSON.parse(JSON.stringify(e.userData)),this.needsUpdate=!0,this}setValues(e){for(const n in e){const s=e[n];if(s===void 0){console.warn(`THREE.Texture.setValues(): parameter '${n}' has value of undefined.`);continue}const o=this[n];if(o===void 0){console.warn(`THREE.Texture.setValues(): property '${n}' does not exist.`);continue}o&&s&&o.isVector2&&s.isVector2||o&&s&&o.isVector3&&s.isVector3||o&&s&&o.isMatrix3&&s.isMatrix3?o.copy(s):this[n]=s}}toJSON(e){const n=e===void 0||typeof e=="string";if(!n&&e.textures[this.uuid]!==void 0)return e.textures[this.uuid];const s={metadata:{version:4.7,type:"Texture",generator:"Texture.toJSON"},uuid:this.uuid,name:this.name,image:this.source.toJSON(e).uuid,mapping:this.mapping,channel:this.channel,repeat:[this.repeat.x,this.repeat.y],offset:[this.offset.x,this.offset.y],center:[this.center.x,this.center.y],rotation:this.rotation,wrap:[this.wrapS,this.wrapT],format:this.format,internalFormat:this.internalFormat,type:this.type,colorSpace:this.colorSpace,minFilter:this.minFilter,magFilter:this.magFilter,anisotropy:this.anisotropy,flipY:this.flipY,generateMipmaps:this.generateMipmaps,premultiplyAlpha:this.premultiplyAlpha,unpackAlignment:this.unpackAlignment};return Object.keys(this.userData).length>0&&(s.userData=this.userData),n||(e.textures[this.uuid]=s),s}dispose(){this.dispatchEvent({type:"dispose"})}transformUv(e){if(this.mapping!==Bk)return e;if(e.applyMatrix3(this.matrix),e.x<0||e.x>1)switch(this.wrapS){case th:e.x=e.x-Math.floor(e.x);break;case ll:e.x=e.x<0?0:1;break;case Qy:Math.abs(Math.floor(e.x)%2)===1?e.x=Math.ceil(e.x)-e.x:e.x=e.x-Math.floor(e.x);break}if(e.y<0||e.y>1)switch(this.wrapT){case th:e.y=e.y-Math.floor(e.y);break;case ll:e.y=e.y<0?0:1;break;case Qy:Math.abs(Math.floor(e.y)%2)===1?e.y=Math.ceil(e.y)-e.y:e.y=e.y-Math.floor(e.y);break}return this.flipY&&(e.y=1-e.y),e}set needsUpdate(e){e===!0&&(this.version++,this.source.needsUpdate=!0)}set needsPMREMUpdate(e){e===!0&&this.pmremVersion++}}Ga.DEFAULT_IMAGE=null;Ga.DEFAULT_MAPPING=Bk;Ga.DEFAULT_ANISOTROPY=1;class On{constructor(e=0,n=0,s=0,o=1){On.prototype.isVector4=!0,this.x=e,this.y=n,this.z=s,this.w=o}get width(){return this.z}set width(e){this.z=e}get height(){return this.w}set height(e){this.w=e}set(e,n,s,o){return this.x=e,this.y=n,this.z=s,this.w=o,this}setScalar(e){return this.x=e,this.y=e,this.z=e,this.w=e,this}setX(e){return this.x=e,this}setY(e){return this.y=e,this}setZ(e){return this.z=e,this}setW(e){return this.w=e,this}setComponent(e,n){switch(e){case 0:this.x=n;break;case 1:this.y=n;break;case 2:this.z=n;break;case 3:this.w=n;break;default:throw new Error("index is out of range: "+e)}return this}getComponent(e){switch(e){case 0:return this.x;case 1:return this.y;case 2:return this.z;case 3:return this.w;default:throw new Error("index is out of range: "+e)}}clone(){return new this.constructor(this.x,this.y,this.z,this.w)}copy(e){return this.x=e.x,this.y=e.y,this.z=e.z,this.w=e.w!==void 0?e.w:1,this}add(e){return this.x+=e.x,this.y+=e.y,this.z+=e.z,this.w+=e.w,this}addScalar(e){return this.x+=e,this.y+=e,this.z+=e,this.w+=e,this}addVectors(e,n){return this.x=e.x+n.x,this.y=e.y+n.y,this.z=e.z+n.z,this.w=e.w+n.w,this}addScaledVector(e,n){return this.x+=e.x*n,this.y+=e.y*n,this.z+=e.z*n,this.w+=e.w*n,this}sub(e){return this.x-=e.x,this.y-=e.y,this.z-=e.z,this.w-=e.w,this}subScalar(e){return this.x-=e,this.y-=e,this.z-=e,this.w-=e,this}subVectors(e,n){return this.x=e.x-n.x,this.y=e.y-n.y,this.z=e.z-n.z,this.w=e.w-n.w,this}multiply(e){return this.x*=e.x,this.y*=e.y,this.z*=e.z,this.w*=e.w,this}multiplyScalar(e){return this.x*=e,this.y*=e,this.z*=e,this.w*=e,this}applyMatrix4(e){const n=this.x,s=this.y,o=this.z,l=this.w,d=e.elements;return this.x=d[0]*n+d[4]*s+d[8]*o+d[12]*l,this.y=d[1]*n+d[5]*s+d[9]*o+d[13]*l,this.z=d[2]*n+d[6]*s+d[10]*o+d[14]*l,this.w=d[3]*n+d[7]*s+d[11]*o+d[15]*l,this}divide(e){return this.x/=e.x,this.y/=e.y,this.z/=e.z,this.w/=e.w,this}divideScalar(e){return this.multiplyScalar(1/e)}setAxisAngleFromQuaternion(e){this.w=2*Math.acos(e.w);const n=Math.sqrt(1-e.w*e.w);return n<1e-4?(this.x=1,this.y=0,this.z=0):(this.x=e.x/n,this.y=e.y/n,this.z=e.z/n),this}setAxisAngleFromRotationMatrix(e){let n,s,o,l;const m=e.elements,p=m[0],y=m[4],v=m[8],x=m[1],S=m[5],M=m[9],w=m[2],E=m[6],A=m[10];if(Math.abs(y-x)<.01&&Math.abs(v-w)<.01&&Math.abs(M-E)<.01){if(Math.abs(y+x)<.1&&Math.abs(v+w)<.1&&Math.abs(M+E)<.1&&Math.abs(p+S+A-3)<.1)return this.set(1,0,0,0),this;n=Math.PI;const R=(p+1)/2,N=(S+1)/2,I=(A+1)/2,z=(y+x)/4,j=(v+w)/4,L=(M+E)/4;return R>N&&R>I?R<.01?(s=0,o=.707106781,l=.707106781):(s=Math.sqrt(R),o=z/s,l=j/s):N>I?N<.01?(s=.707106781,o=0,l=.707106781):(o=Math.sqrt(N),s=z/o,l=L/o):I<.01?(s=.707106781,o=.707106781,l=0):(l=Math.sqrt(I),s=j/l,o=L/l),this.set(s,o,l,n),this}let k=Math.sqrt((E-M)*(E-M)+(v-w)*(v-w)+(x-y)*(x-y));return Math.abs(k)<.001&&(k=1),this.x=(E-M)/k,this.y=(v-w)/k,this.z=(x-y)/k,this.w=Math.acos((p+S+A-1)/2),this}setFromMatrixPosition(e){const n=e.elements;return this.x=n[12],this.y=n[13],this.z=n[14],this.w=n[15],this}min(e){return this.x=Math.min(this.x,e.x),this.y=Math.min(this.y,e.y),this.z=Math.min(this.z,e.z),this.w=Math.min(this.w,e.w),this}max(e){return this.x=Math.max(this.x,e.x),this.y=Math.max(this.y,e.y),this.z=Math.max(this.z,e.z),this.w=Math.max(this.w,e.w),this}clamp(e,n){return this.x=en(this.x,e.x,n.x),this.y=en(this.y,e.y,n.y),this.z=en(this.z,e.z,n.z),this.w=en(this.w,e.w,n.w),this}clampScalar(e,n){return this.x=en(this.x,e,n),this.y=en(this.y,e,n),this.z=en(this.z,e,n),this.w=en(this.w,e,n),this}clampLength(e,n){const s=this.length();return this.divideScalar(s||1).multiplyScalar(en(s,e,n))}floor(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this.z=Math.floor(this.z),this.w=Math.floor(this.w),this}ceil(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this.z=Math.ceil(this.z),this.w=Math.ceil(this.w),this}round(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this.z=Math.round(this.z),this.w=Math.round(this.w),this}roundToZero(){return this.x=Math.trunc(this.x),this.y=Math.trunc(this.y),this.z=Math.trunc(this.z),this.w=Math.trunc(this.w),this}negate(){return this.x=-this.x,this.y=-this.y,this.z=-this.z,this.w=-this.w,this}dot(e){return this.x*e.x+this.y*e.y+this.z*e.z+this.w*e.w}lengthSq(){return this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w}length(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)}manhattanLength(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)+Math.abs(this.w)}normalize(){return this.divideScalar(this.length()||1)}setLength(e){return this.normalize().multiplyScalar(e)}lerp(e,n){return this.x+=(e.x-this.x)*n,this.y+=(e.y-this.y)*n,this.z+=(e.z-this.z)*n,this.w+=(e.w-this.w)*n,this}lerpVectors(e,n,s){return this.x=e.x+(n.x-e.x)*s,this.y=e.y+(n.y-e.y)*s,this.z=e.z+(n.z-e.z)*s,this.w=e.w+(n.w-e.w)*s,this}equals(e){return e.x===this.x&&e.y===this.y&&e.z===this.z&&e.w===this.w}fromArray(e,n=0){return this.x=e[n],this.y=e[n+1],this.z=e[n+2],this.w=e[n+3],this}toArray(e=[],n=0){return e[n]=this.x,e[n+1]=this.y,e[n+2]=this.z,e[n+3]=this.w,e}fromBufferAttribute(e,n){return this.x=e.getX(n),this.y=e.getY(n),this.z=e.getZ(n),this.w=e.getW(n),this}random(){return this.x=Math.random(),this.y=Math.random(),this.z=Math.random(),this.w=Math.random(),this}*[Symbol.iterator](){yield this.x,yield this.y,yield this.z,yield this.w}}class XH extends Rl{constructor(e=1,n=1,s={}){super(),s=Object.assign({generateMipmaps:!1,internalFormat:null,minFilter:Is,depthBuffer:!0,stencilBuffer:!1,resolveDepthBuffer:!0,resolveStencilBuffer:!0,depthTexture:null,samples:0,count:1,depth:1,multiview:!1},s),this.isRenderTarget=!0,this.width=e,this.height=n,this.depth=s.depth,this.scissor=new On(0,0,e,n),this.scissorTest=!1,this.viewport=new On(0,0,e,n);const o={width:e,height:n,depth:s.depth},l=new Ga(o);this.textures=[];const d=s.count;for(let h=0;h1;this.dispose()}this.viewport.set(0,0,e,n),this.scissor.set(0,0,e,n)}clone(){return new this.constructor().copy(this)}copy(e){this.width=e.width,this.height=e.height,this.depth=e.depth,this.scissor.copy(e.scissor),this.scissorTest=e.scissorTest,this.viewport.copy(e.viewport),this.textures.length=0;for(let n=0,s=e.textures.length;n=this.min.x&&e.x<=this.max.x&&e.y>=this.min.y&&e.y<=this.max.y&&e.z>=this.min.z&&e.z<=this.max.z}containsBox(e){return this.min.x<=e.min.x&&e.max.x<=this.max.x&&this.min.y<=e.min.y&&e.max.y<=this.max.y&&this.min.z<=e.min.z&&e.max.z<=this.max.z}getParameter(e,n){return n.set((e.x-this.min.x)/(this.max.x-this.min.x),(e.y-this.min.y)/(this.max.y-this.min.y),(e.z-this.min.z)/(this.max.z-this.min.z))}intersectsBox(e){return e.max.x>=this.min.x&&e.min.x<=this.max.x&&e.max.y>=this.min.y&&e.min.y<=this.max.y&&e.max.z>=this.min.z&&e.min.z<=this.max.z}intersectsSphere(e){return this.clampPoint(e.center,fs),fs.distanceToSquared(e.center)<=e.radius*e.radius}intersectsPlane(e){let n,s;return e.normal.x>0?(n=e.normal.x*this.min.x,s=e.normal.x*this.max.x):(n=e.normal.x*this.max.x,s=e.normal.x*this.min.x),e.normal.y>0?(n+=e.normal.y*this.min.y,s+=e.normal.y*this.max.y):(n+=e.normal.y*this.max.y,s+=e.normal.y*this.min.y),e.normal.z>0?(n+=e.normal.z*this.min.z,s+=e.normal.z*this.max.z):(n+=e.normal.z*this.max.z,s+=e.normal.z*this.min.z),n<=-e.constant&&s>=-e.constant}intersectsTriangle(e){if(this.isEmpty())return!1;this.getCenter(xd),Yf.subVectors(this.max,xd),mc.subVectors(e.a,xd),gc.subVectors(e.b,xd),vc.subVectors(e.c,xd),to.subVectors(gc,mc),no.subVectors(vc,gc),Yo.subVectors(mc,vc);let n=[0,-to.z,to.y,0,-no.z,no.y,0,-Yo.z,Yo.y,to.z,0,-to.x,no.z,0,-no.x,Yo.z,0,-Yo.x,-to.y,to.x,0,-no.y,no.x,0,-Yo.y,Yo.x,0];return!wx(n,mc,gc,vc,Yf)||(n=[1,0,0,0,1,0,0,0,1],!wx(n,mc,gc,vc,Yf))?!1:(Xf.crossVectors(to,no),n=[Xf.x,Xf.y,Xf.z],wx(n,mc,gc,vc,Yf))}clampPoint(e,n){return n.copy(e).clamp(this.min,this.max)}distanceToPoint(e){return this.clampPoint(e,fs).distanceTo(e)}getBoundingSphere(e){return this.isEmpty()?e.makeEmpty():(this.getCenter(e.center),e.radius=this.getSize(fs).length()*.5),e}intersect(e){return this.min.max(e.min),this.max.min(e.max),this.isEmpty()&&this.makeEmpty(),this}union(e){return this.min.min(e.min),this.max.max(e.max),this}applyMatrix4(e){return this.isEmpty()?this:(or[0].set(this.min.x,this.min.y,this.min.z).applyMatrix4(e),or[1].set(this.min.x,this.min.y,this.max.z).applyMatrix4(e),or[2].set(this.min.x,this.max.y,this.min.z).applyMatrix4(e),or[3].set(this.min.x,this.max.y,this.max.z).applyMatrix4(e),or[4].set(this.max.x,this.min.y,this.min.z).applyMatrix4(e),or[5].set(this.max.x,this.min.y,this.max.z).applyMatrix4(e),or[6].set(this.max.x,this.max.y,this.min.z).applyMatrix4(e),or[7].set(this.max.x,this.max.y,this.max.z).applyMatrix4(e),this.setFromPoints(or),this)}translate(e){return this.min.add(e),this.max.add(e),this}equals(e){return e.min.equals(this.min)&&e.max.equals(this.max)}toJSON(){return{min:this.min.toArray(),max:this.max.toArray()}}fromJSON(e){return this.min.fromArray(e.min),this.max.fromArray(e.max),this}}const or=[new he,new he,new he,new he,new he,new he,new he,new he],fs=new he,Wf=new kl,mc=new he,gc=new he,vc=new he,to=new he,no=new he,Yo=new he,xd=new he,Yf=new he,Xf=new he,Xo=new he;function wx(a,e,n,s,o){for(let l=0,d=a.length-3;l<=d;l+=3){Xo.fromArray(a,l);const h=o.x*Math.abs(Xo.x)+o.y*Math.abs(Xo.y)+o.z*Math.abs(Xo.z),m=e.dot(Xo),p=n.dot(Xo),y=s.dot(Xo);if(Math.max(-Math.max(m,p,y),Math.min(m,p,y))>h)return!1}return!0}const JH=new kl,yd=new he,Mx=new he;class yu{constructor(e=new he,n=-1){this.isSphere=!0,this.center=e,this.radius=n}set(e,n){return this.center.copy(e),this.radius=n,this}setFromPoints(e,n){const s=this.center;n!==void 0?s.copy(n):JH.setFromPoints(e).getCenter(s);let o=0;for(let l=0,d=e.length;lthis.radius*this.radius&&(n.sub(this.center).normalize(),n.multiplyScalar(this.radius).add(this.center)),n}getBoundingBox(e){return this.isEmpty()?(e.makeEmpty(),e):(e.set(this.center,this.center),e.expandByScalar(this.radius),e)}applyMatrix4(e){return this.center.applyMatrix4(e),this.radius=this.radius*e.getMaxScaleOnAxis(),this}translate(e){return this.center.add(e),this}expandByPoint(e){if(this.isEmpty())return this.center.copy(e),this.radius=0,this;yd.subVectors(e,this.center);const n=yd.lengthSq();if(n>this.radius*this.radius){const s=Math.sqrt(n),o=(s-this.radius)*.5;this.center.addScaledVector(yd,o/s),this.radius+=o}return this}union(e){return e.isEmpty()?this:this.isEmpty()?(this.copy(e),this):(this.center.equals(e.center)===!0?this.radius=Math.max(this.radius,e.radius):(Mx.subVectors(e.center,this.center).setLength(e.radius),this.expandByPoint(yd.copy(e.center).add(Mx)),this.expandByPoint(yd.copy(e.center).sub(Mx))),this)}equals(e){return e.center.equals(this.center)&&e.radius===this.radius}clone(){return new this.constructor().copy(this)}toJSON(){return{radius:this.radius,center:this.center.toArray()}}fromJSON(e){return this.radius=e.radius,this.center.fromArray(e.center),this}}const lr=new he,Cx=new he,Kf=new he,ao=new he,Tx=new he,Jf=new he,jx=new he;class Xm{constructor(e=new he,n=new he(0,0,-1)){this.origin=e,this.direction=n}set(e,n){return this.origin.copy(e),this.direction.copy(n),this}copy(e){return this.origin.copy(e.origin),this.direction.copy(e.direction),this}at(e,n){return n.copy(this.origin).addScaledVector(this.direction,e)}lookAt(e){return this.direction.copy(e).sub(this.origin).normalize(),this}recast(e){return this.origin.copy(this.at(e,lr)),this}closestPointToPoint(e,n){n.subVectors(e,this.origin);const s=n.dot(this.direction);return s<0?n.copy(this.origin):n.copy(this.origin).addScaledVector(this.direction,s)}distanceToPoint(e){return Math.sqrt(this.distanceSqToPoint(e))}distanceSqToPoint(e){const n=lr.subVectors(e,this.origin).dot(this.direction);return n<0?this.origin.distanceToSquared(e):(lr.copy(this.origin).addScaledVector(this.direction,n),lr.distanceToSquared(e))}distanceSqToSegment(e,n,s,o){Cx.copy(e).add(n).multiplyScalar(.5),Kf.copy(n).sub(e).normalize(),ao.copy(this.origin).sub(Cx);const l=e.distanceTo(n)*.5,d=-this.direction.dot(Kf),h=ao.dot(this.direction),m=-ao.dot(Kf),p=ao.lengthSq(),y=Math.abs(1-d*d);let v,x,S,M;if(y>0)if(v=d*m-h,x=d*h-m,M=l*y,v>=0)if(x>=-M)if(x<=M){const w=1/y;v*=w,x*=w,S=v*(v+d*x+2*h)+x*(d*v+x+2*m)+p}else x=l,v=Math.max(0,-(d*x+h)),S=-v*v+x*(x+2*m)+p;else x=-l,v=Math.max(0,-(d*x+h)),S=-v*v+x*(x+2*m)+p;else x<=-M?(v=Math.max(0,-(-d*l+h)),x=v>0?-l:Math.min(Math.max(-l,-m),l),S=-v*v+x*(x+2*m)+p):x<=M?(v=0,x=Math.min(Math.max(-l,-m),l),S=x*(x+2*m)+p):(v=Math.max(0,-(d*l+h)),x=v>0?l:Math.min(Math.max(-l,-m),l),S=-v*v+x*(x+2*m)+p);else x=d>0?-l:l,v=Math.max(0,-(d*x+h)),S=-v*v+x*(x+2*m)+p;return s&&s.copy(this.origin).addScaledVector(this.direction,v),o&&o.copy(Cx).addScaledVector(Kf,x),S}intersectSphere(e,n){lr.subVectors(e.center,this.origin);const s=lr.dot(this.direction),o=lr.dot(lr)-s*s,l=e.radius*e.radius;if(o>l)return null;const d=Math.sqrt(l-o),h=s-d,m=s+d;return m<0?null:h<0?this.at(m,n):this.at(h,n)}intersectsSphere(e){return e.radius<0?!1:this.distanceSqToPoint(e.center)<=e.radius*e.radius}distanceToPlane(e){const n=e.normal.dot(this.direction);if(n===0)return e.distanceToPoint(this.origin)===0?0:null;const s=-(this.origin.dot(e.normal)+e.constant)/n;return s>=0?s:null}intersectPlane(e,n){const s=this.distanceToPlane(e);return s===null?null:this.at(s,n)}intersectsPlane(e){const n=e.distanceToPoint(this.origin);return n===0||e.normal.dot(this.direction)*n<0}intersectBox(e,n){let s,o,l,d,h,m;const p=1/this.direction.x,y=1/this.direction.y,v=1/this.direction.z,x=this.origin;return p>=0?(s=(e.min.x-x.x)*p,o=(e.max.x-x.x)*p):(s=(e.max.x-x.x)*p,o=(e.min.x-x.x)*p),y>=0?(l=(e.min.y-x.y)*y,d=(e.max.y-x.y)*y):(l=(e.max.y-x.y)*y,d=(e.min.y-x.y)*y),s>d||l>o||((l>s||isNaN(s))&&(s=l),(d=0?(h=(e.min.z-x.z)*v,m=(e.max.z-x.z)*v):(h=(e.max.z-x.z)*v,m=(e.min.z-x.z)*v),s>m||h>o)||((h>s||s!==s)&&(s=h),(m=0?s:o,n)}intersectsBox(e){return this.intersectBox(e,lr)!==null}intersectTriangle(e,n,s,o,l){Tx.subVectors(n,e),Jf.subVectors(s,e),jx.crossVectors(Tx,Jf);let d=this.direction.dot(jx),h;if(d>0){if(o)return null;h=1}else if(d<0)h=-1,d=-d;else return null;ao.subVectors(this.origin,e);const m=h*this.direction.dot(Jf.crossVectors(ao,Jf));if(m<0)return null;const p=h*this.direction.dot(Tx.cross(ao));if(p<0||m+p>d)return null;const y=-h*ao.dot(jx);return y<0?null:this.at(y/d,l)}applyMatrix4(e){return this.origin.applyMatrix4(e),this.direction.transformDirection(e),this}equals(e){return e.origin.equals(this.origin)&&e.direction.equals(this.direction)}clone(){return new this.constructor().copy(this)}}class dn{constructor(e,n,s,o,l,d,h,m,p,y,v,x,S,M,w,E){dn.prototype.isMatrix4=!0,this.elements=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],e!==void 0&&this.set(e,n,s,o,l,d,h,m,p,y,v,x,S,M,w,E)}set(e,n,s,o,l,d,h,m,p,y,v,x,S,M,w,E){const A=this.elements;return A[0]=e,A[4]=n,A[8]=s,A[12]=o,A[1]=l,A[5]=d,A[9]=h,A[13]=m,A[2]=p,A[6]=y,A[10]=v,A[14]=x,A[3]=S,A[7]=M,A[11]=w,A[15]=E,this}identity(){return this.set(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1),this}clone(){return new dn().fromArray(this.elements)}copy(e){const n=this.elements,s=e.elements;return n[0]=s[0],n[1]=s[1],n[2]=s[2],n[3]=s[3],n[4]=s[4],n[5]=s[5],n[6]=s[6],n[7]=s[7],n[8]=s[8],n[9]=s[9],n[10]=s[10],n[11]=s[11],n[12]=s[12],n[13]=s[13],n[14]=s[14],n[15]=s[15],this}copyPosition(e){const n=this.elements,s=e.elements;return n[12]=s[12],n[13]=s[13],n[14]=s[14],this}setFromMatrix3(e){const n=e.elements;return this.set(n[0],n[3],n[6],0,n[1],n[4],n[7],0,n[2],n[5],n[8],0,0,0,0,1),this}extractBasis(e,n,s){return e.setFromMatrixColumn(this,0),n.setFromMatrixColumn(this,1),s.setFromMatrixColumn(this,2),this}makeBasis(e,n,s){return this.set(e.x,n.x,s.x,0,e.y,n.y,s.y,0,e.z,n.z,s.z,0,0,0,0,1),this}extractRotation(e){const n=this.elements,s=e.elements,o=1/xc.setFromMatrixColumn(e,0).length(),l=1/xc.setFromMatrixColumn(e,1).length(),d=1/xc.setFromMatrixColumn(e,2).length();return n[0]=s[0]*o,n[1]=s[1]*o,n[2]=s[2]*o,n[3]=0,n[4]=s[4]*l,n[5]=s[5]*l,n[6]=s[6]*l,n[7]=0,n[8]=s[8]*d,n[9]=s[9]*d,n[10]=s[10]*d,n[11]=0,n[12]=0,n[13]=0,n[14]=0,n[15]=1,this}makeRotationFromEuler(e){const n=this.elements,s=e.x,o=e.y,l=e.z,d=Math.cos(s),h=Math.sin(s),m=Math.cos(o),p=Math.sin(o),y=Math.cos(l),v=Math.sin(l);if(e.order==="XYZ"){const x=d*y,S=d*v,M=h*y,w=h*v;n[0]=m*y,n[4]=-m*v,n[8]=p,n[1]=S+M*p,n[5]=x-w*p,n[9]=-h*m,n[2]=w-x*p,n[6]=M+S*p,n[10]=d*m}else if(e.order==="YXZ"){const x=m*y,S=m*v,M=p*y,w=p*v;n[0]=x+w*h,n[4]=M*h-S,n[8]=d*p,n[1]=d*v,n[5]=d*y,n[9]=-h,n[2]=S*h-M,n[6]=w+x*h,n[10]=d*m}else if(e.order==="ZXY"){const x=m*y,S=m*v,M=p*y,w=p*v;n[0]=x-w*h,n[4]=-d*v,n[8]=M+S*h,n[1]=S+M*h,n[5]=d*y,n[9]=w-x*h,n[2]=-d*p,n[6]=h,n[10]=d*m}else if(e.order==="ZYX"){const x=d*y,S=d*v,M=h*y,w=h*v;n[0]=m*y,n[4]=M*p-S,n[8]=x*p+w,n[1]=m*v,n[5]=w*p+x,n[9]=S*p-M,n[2]=-p,n[6]=h*m,n[10]=d*m}else if(e.order==="YZX"){const x=d*m,S=d*p,M=h*m,w=h*p;n[0]=m*y,n[4]=w-x*v,n[8]=M*v+S,n[1]=v,n[5]=d*y,n[9]=-h*y,n[2]=-p*y,n[6]=S*v+M,n[10]=x-w*v}else if(e.order==="XZY"){const x=d*m,S=d*p,M=h*m,w=h*p;n[0]=m*y,n[4]=-v,n[8]=p*y,n[1]=x*v+w,n[5]=d*y,n[9]=S*v-M,n[2]=M*v-S,n[6]=h*y,n[10]=w*v+x}return n[3]=0,n[7]=0,n[11]=0,n[12]=0,n[13]=0,n[14]=0,n[15]=1,this}makeRotationFromQuaternion(e){return this.compose(ZH,e,QH)}lookAt(e,n,s){const o=this.elements;return Oi.subVectors(e,n),Oi.lengthSq()===0&&(Oi.z=1),Oi.normalize(),io.crossVectors(s,Oi),io.lengthSq()===0&&(Math.abs(s.z)===1?Oi.x+=1e-4:Oi.z+=1e-4,Oi.normalize(),io.crossVectors(s,Oi)),io.normalize(),Zf.crossVectors(Oi,io),o[0]=io.x,o[4]=Zf.x,o[8]=Oi.x,o[1]=io.y,o[5]=Zf.y,o[9]=Oi.y,o[2]=io.z,o[6]=Zf.z,o[10]=Oi.z,this}multiply(e){return this.multiplyMatrices(this,e)}premultiply(e){return this.multiplyMatrices(e,this)}multiplyMatrices(e,n){const s=e.elements,o=n.elements,l=this.elements,d=s[0],h=s[4],m=s[8],p=s[12],y=s[1],v=s[5],x=s[9],S=s[13],M=s[2],w=s[6],E=s[10],A=s[14],k=s[3],R=s[7],N=s[11],I=s[15],z=o[0],j=o[4],L=o[8],D=o[12],P=o[1],F=o[5],q=o[9],J=o[13],ie=o[2],Q=o[6],V=o[10],$=o[14],te=o[3],ne=o[7],Y=o[11],T=o[15];return l[0]=d*z+h*P+m*ie+p*te,l[4]=d*j+h*F+m*Q+p*ne,l[8]=d*L+h*q+m*V+p*Y,l[12]=d*D+h*J+m*$+p*T,l[1]=y*z+v*P+x*ie+S*te,l[5]=y*j+v*F+x*Q+S*ne,l[9]=y*L+v*q+x*V+S*Y,l[13]=y*D+v*J+x*$+S*T,l[2]=M*z+w*P+E*ie+A*te,l[6]=M*j+w*F+E*Q+A*ne,l[10]=M*L+w*q+E*V+A*Y,l[14]=M*D+w*J+E*$+A*T,l[3]=k*z+R*P+N*ie+I*te,l[7]=k*j+R*F+N*Q+I*ne,l[11]=k*L+R*q+N*V+I*Y,l[15]=k*D+R*J+N*$+I*T,this}multiplyScalar(e){const n=this.elements;return n[0]*=e,n[4]*=e,n[8]*=e,n[12]*=e,n[1]*=e,n[5]*=e,n[9]*=e,n[13]*=e,n[2]*=e,n[6]*=e,n[10]*=e,n[14]*=e,n[3]*=e,n[7]*=e,n[11]*=e,n[15]*=e,this}determinant(){const e=this.elements,n=e[0],s=e[4],o=e[8],l=e[12],d=e[1],h=e[5],m=e[9],p=e[13],y=e[2],v=e[6],x=e[10],S=e[14],M=e[3],w=e[7],E=e[11],A=e[15];return M*(+l*m*v-o*p*v-l*h*x+s*p*x+o*h*S-s*m*S)+w*(+n*m*S-n*p*x+l*d*x-o*d*S+o*p*y-l*m*y)+E*(+n*p*v-n*h*S-l*d*v+s*d*S+l*h*y-s*p*y)+A*(-o*h*y-n*m*v+n*h*x+o*d*v-s*d*x+s*m*y)}transpose(){const e=this.elements;let n;return n=e[1],e[1]=e[4],e[4]=n,n=e[2],e[2]=e[8],e[8]=n,n=e[6],e[6]=e[9],e[9]=n,n=e[3],e[3]=e[12],e[12]=n,n=e[7],e[7]=e[13],e[13]=n,n=e[11],e[11]=e[14],e[14]=n,this}setPosition(e,n,s){const o=this.elements;return e.isVector3?(o[12]=e.x,o[13]=e.y,o[14]=e.z):(o[12]=e,o[13]=n,o[14]=s),this}invert(){const e=this.elements,n=e[0],s=e[1],o=e[2],l=e[3],d=e[4],h=e[5],m=e[6],p=e[7],y=e[8],v=e[9],x=e[10],S=e[11],M=e[12],w=e[13],E=e[14],A=e[15],k=v*E*p-w*x*p+w*m*S-h*E*S-v*m*A+h*x*A,R=M*x*p-y*E*p-M*m*S+d*E*S+y*m*A-d*x*A,N=y*w*p-M*v*p+M*h*S-d*w*S-y*h*A+d*v*A,I=M*v*m-y*w*m-M*h*x+d*w*x+y*h*E-d*v*E,z=n*k+s*R+o*N+l*I;if(z===0)return this.set(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);const j=1/z;return e[0]=k*j,e[1]=(w*x*l-v*E*l-w*o*S+s*E*S+v*o*A-s*x*A)*j,e[2]=(h*E*l-w*m*l+w*o*p-s*E*p-h*o*A+s*m*A)*j,e[3]=(v*m*l-h*x*l-v*o*p+s*x*p+h*o*S-s*m*S)*j,e[4]=R*j,e[5]=(y*E*l-M*x*l+M*o*S-n*E*S-y*o*A+n*x*A)*j,e[6]=(M*m*l-d*E*l-M*o*p+n*E*p+d*o*A-n*m*A)*j,e[7]=(d*x*l-y*m*l+y*o*p-n*x*p-d*o*S+n*m*S)*j,e[8]=N*j,e[9]=(M*v*l-y*w*l-M*s*S+n*w*S+y*s*A-n*v*A)*j,e[10]=(d*w*l-M*h*l+M*s*p-n*w*p-d*s*A+n*h*A)*j,e[11]=(y*h*l-d*v*l-y*s*p+n*v*p+d*s*S-n*h*S)*j,e[12]=I*j,e[13]=(y*w*o-M*v*o+M*s*x-n*w*x-y*s*E+n*v*E)*j,e[14]=(M*h*o-d*w*o-M*s*m+n*w*m+d*s*E-n*h*E)*j,e[15]=(d*v*o-y*h*o+y*s*m-n*v*m-d*s*x+n*h*x)*j,this}scale(e){const n=this.elements,s=e.x,o=e.y,l=e.z;return n[0]*=s,n[4]*=o,n[8]*=l,n[1]*=s,n[5]*=o,n[9]*=l,n[2]*=s,n[6]*=o,n[10]*=l,n[3]*=s,n[7]*=o,n[11]*=l,this}getMaxScaleOnAxis(){const e=this.elements,n=e[0]*e[0]+e[1]*e[1]+e[2]*e[2],s=e[4]*e[4]+e[5]*e[5]+e[6]*e[6],o=e[8]*e[8]+e[9]*e[9]+e[10]*e[10];return Math.sqrt(Math.max(n,s,o))}makeTranslation(e,n,s){return e.isVector3?this.set(1,0,0,e.x,0,1,0,e.y,0,0,1,e.z,0,0,0,1):this.set(1,0,0,e,0,1,0,n,0,0,1,s,0,0,0,1),this}makeRotationX(e){const n=Math.cos(e),s=Math.sin(e);return this.set(1,0,0,0,0,n,-s,0,0,s,n,0,0,0,0,1),this}makeRotationY(e){const n=Math.cos(e),s=Math.sin(e);return this.set(n,0,s,0,0,1,0,0,-s,0,n,0,0,0,0,1),this}makeRotationZ(e){const n=Math.cos(e),s=Math.sin(e);return this.set(n,-s,0,0,s,n,0,0,0,0,1,0,0,0,0,1),this}makeRotationAxis(e,n){const s=Math.cos(n),o=Math.sin(n),l=1-s,d=e.x,h=e.y,m=e.z,p=l*d,y=l*h;return this.set(p*d+s,p*h-o*m,p*m+o*h,0,p*h+o*m,y*h+s,y*m-o*d,0,p*m-o*h,y*m+o*d,l*m*m+s,0,0,0,0,1),this}makeScale(e,n,s){return this.set(e,0,0,0,0,n,0,0,0,0,s,0,0,0,0,1),this}makeShear(e,n,s,o,l,d){return this.set(1,s,l,0,e,1,d,0,n,o,1,0,0,0,0,1),this}compose(e,n,s){const o=this.elements,l=n._x,d=n._y,h=n._z,m=n._w,p=l+l,y=d+d,v=h+h,x=l*p,S=l*y,M=l*v,w=d*y,E=d*v,A=h*v,k=m*p,R=m*y,N=m*v,I=s.x,z=s.y,j=s.z;return o[0]=(1-(w+A))*I,o[1]=(S+N)*I,o[2]=(M-R)*I,o[3]=0,o[4]=(S-N)*z,o[5]=(1-(x+A))*z,o[6]=(E+k)*z,o[7]=0,o[8]=(M+R)*j,o[9]=(E-k)*j,o[10]=(1-(x+w))*j,o[11]=0,o[12]=e.x,o[13]=e.y,o[14]=e.z,o[15]=1,this}decompose(e,n,s){const o=this.elements;let l=xc.set(o[0],o[1],o[2]).length();const d=xc.set(o[4],o[5],o[6]).length(),h=xc.set(o[8],o[9],o[10]).length();this.determinant()<0&&(l=-l),e.x=o[12],e.y=o[13],e.z=o[14],ps.copy(this);const p=1/l,y=1/d,v=1/h;return ps.elements[0]*=p,ps.elements[1]*=p,ps.elements[2]*=p,ps.elements[4]*=y,ps.elements[5]*=y,ps.elements[6]*=y,ps.elements[8]*=v,ps.elements[9]*=v,ps.elements[10]*=v,n.setFromRotationMatrix(ps),s.x=l,s.y=d,s.z=h,this}makePerspective(e,n,s,o,l,d,h=Us,m=!1){const p=this.elements,y=2*l/(n-e),v=2*l/(s-o),x=(n+e)/(n-e),S=(s+o)/(s-o);let M,w;if(m)M=l/(d-l),w=d*l/(d-l);else if(h===Us)M=-(d+l)/(d-l),w=-2*d*l/(d-l);else if(h===fm)M=-d/(d-l),w=-d*l/(d-l);else throw new Error("THREE.Matrix4.makePerspective(): Invalid coordinate system: "+h);return p[0]=y,p[4]=0,p[8]=x,p[12]=0,p[1]=0,p[5]=v,p[9]=S,p[13]=0,p[2]=0,p[6]=0,p[10]=M,p[14]=w,p[3]=0,p[7]=0,p[11]=-1,p[15]=0,this}makeOrthographic(e,n,s,o,l,d,h=Us,m=!1){const p=this.elements,y=2/(n-e),v=2/(s-o),x=-(n+e)/(n-e),S=-(s+o)/(s-o);let M,w;if(m)M=1/(d-l),w=d/(d-l);else if(h===Us)M=-2/(d-l),w=-(d+l)/(d-l);else if(h===fm)M=-1/(d-l),w=-l/(d-l);else throw new Error("THREE.Matrix4.makeOrthographic(): Invalid coordinate system: "+h);return p[0]=y,p[4]=0,p[8]=0,p[12]=x,p[1]=0,p[5]=v,p[9]=0,p[13]=S,p[2]=0,p[6]=0,p[10]=M,p[14]=w,p[3]=0,p[7]=0,p[11]=0,p[15]=1,this}equals(e){const n=this.elements,s=e.elements;for(let o=0;o<16;o++)if(n[o]!==s[o])return!1;return!0}fromArray(e,n=0){for(let s=0;s<16;s++)this.elements[s]=e[s+n];return this}toArray(e=[],n=0){const s=this.elements;return e[n]=s[0],e[n+1]=s[1],e[n+2]=s[2],e[n+3]=s[3],e[n+4]=s[4],e[n+5]=s[5],e[n+6]=s[6],e[n+7]=s[7],e[n+8]=s[8],e[n+9]=s[9],e[n+10]=s[10],e[n+11]=s[11],e[n+12]=s[12],e[n+13]=s[13],e[n+14]=s[14],e[n+15]=s[15],e}}const xc=new he,ps=new dn,ZH=new he(0,0,0),QH=new he(1,1,1),io=new he,Zf=new he,Oi=new he,NM=new dn,DM=new Ml;class Es{constructor(e=0,n=0,s=0,o=Es.DEFAULT_ORDER){this.isEuler=!0,this._x=e,this._y=n,this._z=s,this._order=o}get x(){return this._x}set x(e){this._x=e,this._onChangeCallback()}get y(){return this._y}set y(e){this._y=e,this._onChangeCallback()}get z(){return this._z}set z(e){this._z=e,this._onChangeCallback()}get order(){return this._order}set order(e){this._order=e,this._onChangeCallback()}set(e,n,s,o=this._order){return this._x=e,this._y=n,this._z=s,this._order=o,this._onChangeCallback(),this}clone(){return new this.constructor(this._x,this._y,this._z,this._order)}copy(e){return this._x=e._x,this._y=e._y,this._z=e._z,this._order=e._order,this._onChangeCallback(),this}setFromRotationMatrix(e,n=this._order,s=!0){const o=e.elements,l=o[0],d=o[4],h=o[8],m=o[1],p=o[5],y=o[9],v=o[2],x=o[6],S=o[10];switch(n){case"XYZ":this._y=Math.asin(en(h,-1,1)),Math.abs(h)<.9999999?(this._x=Math.atan2(-y,S),this._z=Math.atan2(-d,l)):(this._x=Math.atan2(x,p),this._z=0);break;case"YXZ":this._x=Math.asin(-en(y,-1,1)),Math.abs(y)<.9999999?(this._y=Math.atan2(h,S),this._z=Math.atan2(m,p)):(this._y=Math.atan2(-v,l),this._z=0);break;case"ZXY":this._x=Math.asin(en(x,-1,1)),Math.abs(x)<.9999999?(this._y=Math.atan2(-v,S),this._z=Math.atan2(-d,p)):(this._y=0,this._z=Math.atan2(m,l));break;case"ZYX":this._y=Math.asin(-en(v,-1,1)),Math.abs(v)<.9999999?(this._x=Math.atan2(x,S),this._z=Math.atan2(m,l)):(this._x=0,this._z=Math.atan2(-d,p));break;case"YZX":this._z=Math.asin(en(m,-1,1)),Math.abs(m)<.9999999?(this._x=Math.atan2(-y,p),this._y=Math.atan2(-v,l)):(this._x=0,this._y=Math.atan2(h,S));break;case"XZY":this._z=Math.asin(-en(d,-1,1)),Math.abs(d)<.9999999?(this._x=Math.atan2(x,p),this._y=Math.atan2(h,l)):(this._x=Math.atan2(-y,S),this._y=0);break;default:console.warn("THREE.Euler: .setFromRotationMatrix() encountered an unknown order: "+n)}return this._order=n,s===!0&&this._onChangeCallback(),this}setFromQuaternion(e,n,s){return NM.makeRotationFromQuaternion(e),this.setFromRotationMatrix(NM,n,s)}setFromVector3(e,n=this._order){return this.set(e.x,e.y,e.z,n)}reorder(e){return DM.setFromEuler(this),this.setFromQuaternion(DM,e)}equals(e){return e._x===this._x&&e._y===this._y&&e._z===this._z&&e._order===this._order}fromArray(e){return this._x=e[0],this._y=e[1],this._z=e[2],e[3]!==void 0&&(this._order=e[3]),this._onChangeCallback(),this}toArray(e=[],n=0){return e[n]=this._x,e[n+1]=this._y,e[n+2]=this._z,e[n+3]=this._order,e}_onChange(e){return this._onChangeCallback=e,this}_onChangeCallback(){}*[Symbol.iterator](){yield this._x,yield this._y,yield this._z,yield this._order}}Es.DEFAULT_ORDER="XYZ";class H0{constructor(){this.mask=1}set(e){this.mask=(1<>>0}enable(e){this.mask|=1<1){for(let n=0;n1){for(let s=0;s0&&(o.userData=this.userData),o.layers=this.layers.mask,o.matrix=this.matrix.toArray(),o.up=this.up.toArray(),this.matrixAutoUpdate===!1&&(o.matrixAutoUpdate=!1),this.isInstancedMesh&&(o.type="InstancedMesh",o.count=this.count,o.instanceMatrix=this.instanceMatrix.toJSON(),this.instanceColor!==null&&(o.instanceColor=this.instanceColor.toJSON())),this.isBatchedMesh&&(o.type="BatchedMesh",o.perObjectFrustumCulled=this.perObjectFrustumCulled,o.sortObjects=this.sortObjects,o.drawRanges=this._drawRanges,o.reservedRanges=this._reservedRanges,o.geometryInfo=this._geometryInfo.map(h=>({...h,boundingBox:h.boundingBox?h.boundingBox.toJSON():void 0,boundingSphere:h.boundingSphere?h.boundingSphere.toJSON():void 0})),o.instanceInfo=this._instanceInfo.map(h=>({...h})),o.availableInstanceIds=this._availableInstanceIds.slice(),o.availableGeometryIds=this._availableGeometryIds.slice(),o.nextIndexStart=this._nextIndexStart,o.nextVertexStart=this._nextVertexStart,o.geometryCount=this._geometryCount,o.maxInstanceCount=this._maxInstanceCount,o.maxVertexCount=this._maxVertexCount,o.maxIndexCount=this._maxIndexCount,o.geometryInitialized=this._geometryInitialized,o.matricesTexture=this._matricesTexture.toJSON(e),o.indirectTexture=this._indirectTexture.toJSON(e),this._colorsTexture!==null&&(o.colorsTexture=this._colorsTexture.toJSON(e)),this.boundingSphere!==null&&(o.boundingSphere=this.boundingSphere.toJSON()),this.boundingBox!==null&&(o.boundingBox=this.boundingBox.toJSON()));function l(h,m){return h[m.uuid]===void 0&&(h[m.uuid]=m.toJSON(e)),m.uuid}if(this.isScene)this.background&&(this.background.isColor?o.background=this.background.toJSON():this.background.isTexture&&(o.background=this.background.toJSON(e).uuid)),this.environment&&this.environment.isTexture&&this.environment.isRenderTargetTexture!==!0&&(o.environment=this.environment.toJSON(e).uuid);else if(this.isMesh||this.isLine||this.isPoints){o.geometry=l(e.geometries,this.geometry);const h=this.geometry.parameters;if(h!==void 0&&h.shapes!==void 0){const m=h.shapes;if(Array.isArray(m))for(let p=0,y=m.length;p0){o.children=[];for(let h=0;h0){o.animations=[];for(let h=0;h0&&(s.geometries=h),m.length>0&&(s.materials=m),p.length>0&&(s.textures=p),y.length>0&&(s.images=y),v.length>0&&(s.shapes=v),x.length>0&&(s.skeletons=x),S.length>0&&(s.animations=S),M.length>0&&(s.nodes=M)}return s.object=o,s;function d(h){const m=[];for(const p in h){const y=h[p];delete y.metadata,m.push(y)}return m}}clone(e){return new this.constructor().copy(this,e)}copy(e,n=!0){if(this.name=e.name,this.up.copy(e.up),this.position.copy(e.position),this.rotation.order=e.rotation.order,this.quaternion.copy(e.quaternion),this.scale.copy(e.scale),this.matrix.copy(e.matrix),this.matrixWorld.copy(e.matrixWorld),this.matrixAutoUpdate=e.matrixAutoUpdate,this.matrixWorldAutoUpdate=e.matrixWorldAutoUpdate,this.matrixWorldNeedsUpdate=e.matrixWorldNeedsUpdate,this.layers.mask=e.layers.mask,this.visible=e.visible,this.castShadow=e.castShadow,this.receiveShadow=e.receiveShadow,this.frustumCulled=e.frustumCulled,this.renderOrder=e.renderOrder,this.animations=e.animations.slice(),this.userData=JSON.parse(JSON.stringify(e.userData)),n===!0)for(let s=0;s0?o.multiplyScalar(1/Math.sqrt(l)):o.set(0,0,0)}static getBarycoord(e,n,s,o,l){ms.subVectors(o,n),ur.subVectors(s,n),kx.subVectors(e,n);const d=ms.dot(ms),h=ms.dot(ur),m=ms.dot(kx),p=ur.dot(ur),y=ur.dot(kx),v=d*p-h*h;if(v===0)return l.set(0,0,0),null;const x=1/v,S=(p*m-h*y)*x,M=(d*y-h*m)*x;return l.set(1-S-M,M,S)}static containsPoint(e,n,s,o){return this.getBarycoord(e,n,s,o,dr)===null?!1:dr.x>=0&&dr.y>=0&&dr.x+dr.y<=1}static getInterpolation(e,n,s,o,l,d,h,m){return this.getBarycoord(e,n,s,o,dr)===null?(m.x=0,m.y=0,"z"in m&&(m.z=0),"w"in m&&(m.w=0),null):(m.setScalar(0),m.addScaledVector(l,dr.x),m.addScaledVector(d,dr.y),m.addScaledVector(h,dr.z),m)}static getInterpolatedAttribute(e,n,s,o,l,d){return Lx.setScalar(0),Ox.setScalar(0),Px.setScalar(0),Lx.fromBufferAttribute(e,n),Ox.fromBufferAttribute(e,s),Px.fromBufferAttribute(e,o),d.setScalar(0),d.addScaledVector(Lx,l.x),d.addScaledVector(Ox,l.y),d.addScaledVector(Px,l.z),d}static isFrontFacing(e,n,s,o){return ms.subVectors(s,n),ur.subVectors(e,n),ms.cross(ur).dot(o)<0}set(e,n,s){return this.a.copy(e),this.b.copy(n),this.c.copy(s),this}setFromPointsAndIndices(e,n,s,o){return this.a.copy(e[n]),this.b.copy(e[s]),this.c.copy(e[o]),this}setFromAttributeAndIndices(e,n,s,o){return this.a.fromBufferAttribute(e,n),this.b.fromBufferAttribute(e,s),this.c.fromBufferAttribute(e,o),this}clone(){return new this.constructor().copy(this)}copy(e){return this.a.copy(e.a),this.b.copy(e.b),this.c.copy(e.c),this}getArea(){return ms.subVectors(this.c,this.b),ur.subVectors(this.a,this.b),ms.cross(ur).length()*.5}getMidpoint(e){return e.addVectors(this.a,this.b).add(this.c).multiplyScalar(1/3)}getNormal(e){return es.getNormal(this.a,this.b,this.c,e)}getPlane(e){return e.setFromCoplanarPoints(this.a,this.b,this.c)}getBarycoord(e,n){return es.getBarycoord(e,this.a,this.b,this.c,n)}getInterpolation(e,n,s,o,l){return es.getInterpolation(e,this.a,this.b,this.c,n,s,o,l)}containsPoint(e){return es.containsPoint(e,this.a,this.b,this.c)}isFrontFacing(e){return es.isFrontFacing(this.a,this.b,this.c,e)}intersectsBox(e){return e.intersectsTriangle(this)}closestPointToPoint(e,n){const s=this.a,o=this.b,l=this.c;let d,h;Sc.subVectors(o,s),Ac.subVectors(l,s),Nx.subVectors(e,s);const m=Sc.dot(Nx),p=Ac.dot(Nx);if(m<=0&&p<=0)return n.copy(s);Dx.subVectors(e,o);const y=Sc.dot(Dx),v=Ac.dot(Dx);if(y>=0&&v<=y)return n.copy(o);const x=m*v-y*p;if(x<=0&&m>=0&&y<=0)return d=m/(m-y),n.copy(s).addScaledVector(Sc,d);zx.subVectors(e,l);const S=Sc.dot(zx),M=Ac.dot(zx);if(M>=0&&S<=M)return n.copy(l);const w=S*p-m*M;if(w<=0&&p>=0&&M<=0)return h=p/(p-M),n.copy(s).addScaledVector(Ac,h);const E=y*M-S*v;if(E<=0&&v-y>=0&&S-M>=0)return UM.subVectors(l,o),h=(v-y)/(v-y+(S-M)),n.copy(o).addScaledVector(UM,h);const A=1/(E+w+x);return d=w*A,h=x*A,n.copy(s).addScaledVector(Sc,d).addScaledVector(Ac,h)}equals(e){return e.a.equals(this.a)&&e.b.equals(this.b)&&e.c.equals(this.c)}}const _k={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074},so={h:0,s:0,l:0},_f={h:0,s:0,l:0};function Ix(a,e,n){return n<0&&(n+=1),n>1&&(n-=1),n<1/6?a+(e-a)*6*n:n<1/2?e:n<2/3?a+(e-a)*6*(2/3-n):a}class tn{constructor(e,n,s){return this.isColor=!0,this.r=1,this.g=1,this.b=1,this.set(e,n,s)}set(e,n,s){if(n===void 0&&s===void 0){const o=e;o&&o.isColor?this.copy(o):typeof o=="number"?this.setHex(o):typeof o=="string"&&this.setStyle(o)}else this.setRGB(e,n,s);return this}setScalar(e){return this.r=e,this.g=e,this.b=e,this}setHex(e,n=Xa){return e=Math.floor(e),this.r=(e>>16&255)/255,this.g=(e>>8&255)/255,this.b=(e&255)/255,pn.colorSpaceToWorking(this,n),this}setRGB(e,n,s,o=pn.workingColorSpace){return this.r=e,this.g=n,this.b=s,pn.colorSpaceToWorking(this,o),this}setHSL(e,n,s,o=pn.workingColorSpace){if(e=F0(e,1),n=en(n,0,1),s=en(s,0,1),n===0)this.r=this.g=this.b=s;else{const l=s<=.5?s*(1+n):s+n-s*n,d=2*s-l;this.r=Ix(d,l,e+1/3),this.g=Ix(d,l,e),this.b=Ix(d,l,e-1/3)}return pn.colorSpaceToWorking(this,o),this}setStyle(e,n=Xa){function s(l){l!==void 0&&parseFloat(l)<1&&console.warn("THREE.Color: Alpha component of "+e+" will be ignored.")}let o;if(o=/^(\w+)\(([^\)]*)\)/.exec(e)){let l;const d=o[1],h=o[2];switch(d){case"rgb":case"rgba":if(l=/^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(h))return s(l[4]),this.setRGB(Math.min(255,parseInt(l[1],10))/255,Math.min(255,parseInt(l[2],10))/255,Math.min(255,parseInt(l[3],10))/255,n);if(l=/^\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(h))return s(l[4]),this.setRGB(Math.min(100,parseInt(l[1],10))/100,Math.min(100,parseInt(l[2],10))/100,Math.min(100,parseInt(l[3],10))/100,n);break;case"hsl":case"hsla":if(l=/^\s*(\d*\.?\d+)\s*,\s*(\d*\.?\d+)\%\s*,\s*(\d*\.?\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(h))return s(l[4]),this.setHSL(parseFloat(l[1])/360,parseFloat(l[2])/100,parseFloat(l[3])/100,n);break;default:console.warn("THREE.Color: Unknown color model "+e)}}else if(o=/^\#([A-Fa-f\d]+)$/.exec(e)){const l=o[1],d=l.length;if(d===3)return this.setRGB(parseInt(l.charAt(0),16)/15,parseInt(l.charAt(1),16)/15,parseInt(l.charAt(2),16)/15,n);if(d===6)return this.setHex(parseInt(l,16),n);console.warn("THREE.Color: Invalid hex color "+e)}else if(e&&e.length>0)return this.setColorName(e,n);return this}setColorName(e,n=Xa){const s=_k[e.toLowerCase()];return s!==void 0?this.setHex(s,n):console.warn("THREE.Color: Unknown color "+e),this}clone(){return new this.constructor(this.r,this.g,this.b)}copy(e){return this.r=e.r,this.g=e.g,this.b=e.b,this}copySRGBToLinear(e){return this.r=br(e.r),this.g=br(e.g),this.b=br(e.b),this}copyLinearToSRGB(e){return this.r=_c(e.r),this.g=_c(e.g),this.b=_c(e.b),this}convertSRGBToLinear(){return this.copySRGBToLinear(this),this}convertLinearToSRGB(){return this.copyLinearToSRGB(this),this}getHex(e=Xa){return pn.workingToColorSpace(Fa.copy(this),e),Math.round(en(Fa.r*255,0,255))*65536+Math.round(en(Fa.g*255,0,255))*256+Math.round(en(Fa.b*255,0,255))}getHexString(e=Xa){return("000000"+this.getHex(e).toString(16)).slice(-6)}getHSL(e,n=pn.workingColorSpace){pn.workingToColorSpace(Fa.copy(this),n);const s=Fa.r,o=Fa.g,l=Fa.b,d=Math.max(s,o,l),h=Math.min(s,o,l);let m,p;const y=(h+d)/2;if(h===d)m=0,p=0;else{const v=d-h;switch(p=y<=.5?v/(d+h):v/(2-d-h),d){case s:m=(o-l)/v+(o0!=e>0&&this.version++,this._alphaTest=e}onBeforeRender(){}onBeforeCompile(){}customProgramCacheKey(){return this.onBeforeCompile.toString()}setValues(e){if(e!==void 0)for(const n in e){const s=e[n];if(s===void 0){console.warn(`THREE.Material: parameter '${n}' has value of undefined.`);continue}const o=this[n];if(o===void 0){console.warn(`THREE.Material: '${n}' is not a property of THREE.${this.type}.`);continue}o&&o.isColor?o.set(s):o&&o.isVector3&&s&&s.isVector3?o.copy(s):this[n]=s}}toJSON(e){const n=e===void 0||typeof e=="string";n&&(e={textures:{},images:{}});const s={metadata:{version:4.7,type:"Material",generator:"Material.toJSON"}};s.uuid=this.uuid,s.type=this.type,this.name!==""&&(s.name=this.name),this.color&&this.color.isColor&&(s.color=this.color.getHex()),this.roughness!==void 0&&(s.roughness=this.roughness),this.metalness!==void 0&&(s.metalness=this.metalness),this.sheen!==void 0&&(s.sheen=this.sheen),this.sheenColor&&this.sheenColor.isColor&&(s.sheenColor=this.sheenColor.getHex()),this.sheenRoughness!==void 0&&(s.sheenRoughness=this.sheenRoughness),this.emissive&&this.emissive.isColor&&(s.emissive=this.emissive.getHex()),this.emissiveIntensity!==void 0&&this.emissiveIntensity!==1&&(s.emissiveIntensity=this.emissiveIntensity),this.specular&&this.specular.isColor&&(s.specular=this.specular.getHex()),this.specularIntensity!==void 0&&(s.specularIntensity=this.specularIntensity),this.specularColor&&this.specularColor.isColor&&(s.specularColor=this.specularColor.getHex()),this.shininess!==void 0&&(s.shininess=this.shininess),this.clearcoat!==void 0&&(s.clearcoat=this.clearcoat),this.clearcoatRoughness!==void 0&&(s.clearcoatRoughness=this.clearcoatRoughness),this.clearcoatMap&&this.clearcoatMap.isTexture&&(s.clearcoatMap=this.clearcoatMap.toJSON(e).uuid),this.clearcoatRoughnessMap&&this.clearcoatRoughnessMap.isTexture&&(s.clearcoatRoughnessMap=this.clearcoatRoughnessMap.toJSON(e).uuid),this.clearcoatNormalMap&&this.clearcoatNormalMap.isTexture&&(s.clearcoatNormalMap=this.clearcoatNormalMap.toJSON(e).uuid,s.clearcoatNormalScale=this.clearcoatNormalScale.toArray()),this.sheenColorMap&&this.sheenColorMap.isTexture&&(s.sheenColorMap=this.sheenColorMap.toJSON(e).uuid),this.sheenRoughnessMap&&this.sheenRoughnessMap.isTexture&&(s.sheenRoughnessMap=this.sheenRoughnessMap.toJSON(e).uuid),this.dispersion!==void 0&&(s.dispersion=this.dispersion),this.iridescence!==void 0&&(s.iridescence=this.iridescence),this.iridescenceIOR!==void 0&&(s.iridescenceIOR=this.iridescenceIOR),this.iridescenceThicknessRange!==void 0&&(s.iridescenceThicknessRange=this.iridescenceThicknessRange),this.iridescenceMap&&this.iridescenceMap.isTexture&&(s.iridescenceMap=this.iridescenceMap.toJSON(e).uuid),this.iridescenceThicknessMap&&this.iridescenceThicknessMap.isTexture&&(s.iridescenceThicknessMap=this.iridescenceThicknessMap.toJSON(e).uuid),this.anisotropy!==void 0&&(s.anisotropy=this.anisotropy),this.anisotropyRotation!==void 0&&(s.anisotropyRotation=this.anisotropyRotation),this.anisotropyMap&&this.anisotropyMap.isTexture&&(s.anisotropyMap=this.anisotropyMap.toJSON(e).uuid),this.map&&this.map.isTexture&&(s.map=this.map.toJSON(e).uuid),this.matcap&&this.matcap.isTexture&&(s.matcap=this.matcap.toJSON(e).uuid),this.alphaMap&&this.alphaMap.isTexture&&(s.alphaMap=this.alphaMap.toJSON(e).uuid),this.lightMap&&this.lightMap.isTexture&&(s.lightMap=this.lightMap.toJSON(e).uuid,s.lightMapIntensity=this.lightMapIntensity),this.aoMap&&this.aoMap.isTexture&&(s.aoMap=this.aoMap.toJSON(e).uuid,s.aoMapIntensity=this.aoMapIntensity),this.bumpMap&&this.bumpMap.isTexture&&(s.bumpMap=this.bumpMap.toJSON(e).uuid,s.bumpScale=this.bumpScale),this.normalMap&&this.normalMap.isTexture&&(s.normalMap=this.normalMap.toJSON(e).uuid,s.normalMapType=this.normalMapType,s.normalScale=this.normalScale.toArray()),this.displacementMap&&this.displacementMap.isTexture&&(s.displacementMap=this.displacementMap.toJSON(e).uuid,s.displacementScale=this.displacementScale,s.displacementBias=this.displacementBias),this.roughnessMap&&this.roughnessMap.isTexture&&(s.roughnessMap=this.roughnessMap.toJSON(e).uuid),this.metalnessMap&&this.metalnessMap.isTexture&&(s.metalnessMap=this.metalnessMap.toJSON(e).uuid),this.emissiveMap&&this.emissiveMap.isTexture&&(s.emissiveMap=this.emissiveMap.toJSON(e).uuid),this.specularMap&&this.specularMap.isTexture&&(s.specularMap=this.specularMap.toJSON(e).uuid),this.specularIntensityMap&&this.specularIntensityMap.isTexture&&(s.specularIntensityMap=this.specularIntensityMap.toJSON(e).uuid),this.specularColorMap&&this.specularColorMap.isTexture&&(s.specularColorMap=this.specularColorMap.toJSON(e).uuid),this.envMap&&this.envMap.isTexture&&(s.envMap=this.envMap.toJSON(e).uuid,this.combine!==void 0&&(s.combine=this.combine)),this.envMapRotation!==void 0&&(s.envMapRotation=this.envMapRotation.toArray()),this.envMapIntensity!==void 0&&(s.envMapIntensity=this.envMapIntensity),this.reflectivity!==void 0&&(s.reflectivity=this.reflectivity),this.refractionRatio!==void 0&&(s.refractionRatio=this.refractionRatio),this.gradientMap&&this.gradientMap.isTexture&&(s.gradientMap=this.gradientMap.toJSON(e).uuid),this.transmission!==void 0&&(s.transmission=this.transmission),this.transmissionMap&&this.transmissionMap.isTexture&&(s.transmissionMap=this.transmissionMap.toJSON(e).uuid),this.thickness!==void 0&&(s.thickness=this.thickness),this.thicknessMap&&this.thicknessMap.isTexture&&(s.thicknessMap=this.thicknessMap.toJSON(e).uuid),this.attenuationDistance!==void 0&&this.attenuationDistance!==1/0&&(s.attenuationDistance=this.attenuationDistance),this.attenuationColor!==void 0&&(s.attenuationColor=this.attenuationColor.getHex()),this.size!==void 0&&(s.size=this.size),this.shadowSide!==null&&(s.shadowSide=this.shadowSide),this.sizeAttenuation!==void 0&&(s.sizeAttenuation=this.sizeAttenuation),this.blending!==Qc&&(s.blending=this.blending),this.side!==Ao&&(s.side=this.side),this.vertexColors===!0&&(s.vertexColors=!0),this.opacity<1&&(s.opacity=this.opacity),this.transparent===!0&&(s.transparent=!0),this.blendSrc!==By&&(s.blendSrc=this.blendSrc),this.blendDst!==Hy&&(s.blendDst=this.blendDst),this.blendEquation!==gr&&(s.blendEquation=this.blendEquation),this.blendSrcAlpha!==null&&(s.blendSrcAlpha=this.blendSrcAlpha),this.blendDstAlpha!==null&&(s.blendDstAlpha=this.blendDstAlpha),this.blendEquationAlpha!==null&&(s.blendEquationAlpha=this.blendEquationAlpha),this.blendColor&&this.blendColor.isColor&&(s.blendColor=this.blendColor.getHex()),this.blendAlpha!==0&&(s.blendAlpha=this.blendAlpha),this.depthFunc!==au&&(s.depthFunc=this.depthFunc),this.depthTest===!1&&(s.depthTest=this.depthTest),this.depthWrite===!1&&(s.depthWrite=this.depthWrite),this.colorWrite===!1&&(s.colorWrite=this.colorWrite),this.stencilWriteMask!==255&&(s.stencilWriteMask=this.stencilWriteMask),this.stencilFunc!==wM&&(s.stencilFunc=this.stencilFunc),this.stencilRef!==0&&(s.stencilRef=this.stencilRef),this.stencilFuncMask!==255&&(s.stencilFuncMask=this.stencilFuncMask),this.stencilFail!==fc&&(s.stencilFail=this.stencilFail),this.stencilZFail!==fc&&(s.stencilZFail=this.stencilZFail),this.stencilZPass!==fc&&(s.stencilZPass=this.stencilZPass),this.stencilWrite===!0&&(s.stencilWrite=this.stencilWrite),this.rotation!==void 0&&this.rotation!==0&&(s.rotation=this.rotation),this.polygonOffset===!0&&(s.polygonOffset=!0),this.polygonOffsetFactor!==0&&(s.polygonOffsetFactor=this.polygonOffsetFactor),this.polygonOffsetUnits!==0&&(s.polygonOffsetUnits=this.polygonOffsetUnits),this.linewidth!==void 0&&this.linewidth!==1&&(s.linewidth=this.linewidth),this.dashSize!==void 0&&(s.dashSize=this.dashSize),this.gapSize!==void 0&&(s.gapSize=this.gapSize),this.scale!==void 0&&(s.scale=this.scale),this.dithering===!0&&(s.dithering=!0),this.alphaTest>0&&(s.alphaTest=this.alphaTest),this.alphaHash===!0&&(s.alphaHash=!0),this.alphaToCoverage===!0&&(s.alphaToCoverage=!0),this.premultipliedAlpha===!0&&(s.premultipliedAlpha=!0),this.forceSinglePass===!0&&(s.forceSinglePass=!0),this.wireframe===!0&&(s.wireframe=!0),this.wireframeLinewidth>1&&(s.wireframeLinewidth=this.wireframeLinewidth),this.wireframeLinecap!=="round"&&(s.wireframeLinecap=this.wireframeLinecap),this.wireframeLinejoin!=="round"&&(s.wireframeLinejoin=this.wireframeLinejoin),this.flatShading===!0&&(s.flatShading=!0),this.visible===!1&&(s.visible=!1),this.toneMapped===!1&&(s.toneMapped=!1),this.fog===!1&&(s.fog=!1),Object.keys(this.userData).length>0&&(s.userData=this.userData);function o(l){const d=[];for(const h in l){const m=l[h];delete m.metadata,d.push(m)}return d}if(n){const l=o(e.textures),d=o(e.images);l.length>0&&(s.textures=l),d.length>0&&(s.images=d)}return s}clone(){return new this.constructor().copy(this)}copy(e){this.name=e.name,this.blending=e.blending,this.side=e.side,this.vertexColors=e.vertexColors,this.opacity=e.opacity,this.transparent=e.transparent,this.blendSrc=e.blendSrc,this.blendDst=e.blendDst,this.blendEquation=e.blendEquation,this.blendSrcAlpha=e.blendSrcAlpha,this.blendDstAlpha=e.blendDstAlpha,this.blendEquationAlpha=e.blendEquationAlpha,this.blendColor.copy(e.blendColor),this.blendAlpha=e.blendAlpha,this.depthFunc=e.depthFunc,this.depthTest=e.depthTest,this.depthWrite=e.depthWrite,this.stencilWriteMask=e.stencilWriteMask,this.stencilFunc=e.stencilFunc,this.stencilRef=e.stencilRef,this.stencilFuncMask=e.stencilFuncMask,this.stencilFail=e.stencilFail,this.stencilZFail=e.stencilZFail,this.stencilZPass=e.stencilZPass,this.stencilWrite=e.stencilWrite;const n=e.clippingPlanes;let s=null;if(n!==null){const o=n.length;s=new Array(o);for(let l=0;l!==o;++l)s[l]=n[l].clone()}return this.clippingPlanes=s,this.clipIntersection=e.clipIntersection,this.clipShadows=e.clipShadows,this.shadowSide=e.shadowSide,this.colorWrite=e.colorWrite,this.precision=e.precision,this.polygonOffset=e.polygonOffset,this.polygonOffsetFactor=e.polygonOffsetFactor,this.polygonOffsetUnits=e.polygonOffsetUnits,this.dithering=e.dithering,this.alphaTest=e.alphaTest,this.alphaHash=e.alphaHash,this.alphaToCoverage=e.alphaToCoverage,this.premultipliedAlpha=e.premultipliedAlpha,this.forceSinglePass=e.forceSinglePass,this.visible=e.visible,this.toneMapped=e.toneMapped,this.userData=JSON.parse(JSON.stringify(e.userData)),this}dispose(){this.dispatchEvent({type:"dispose"})}set needsUpdate(e){e===!0&&this.version++}}class qd extends Rr{constructor(e){super(),this.isMeshBasicMaterial=!0,this.type="MeshBasicMaterial",this.color=new tn(16777215),this.map=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.specularMap=null,this.alphaMap=null,this.envMap=null,this.envMapRotation=new Es,this.combine=N0,this.reflectivity=1,this.refractionRatio=.98,this.wireframe=!1,this.wireframeLinewidth=1,this.wireframeLinecap="round",this.wireframeLinejoin="round",this.fog=!0,this.setValues(e)}copy(e){return super.copy(e),this.color.copy(e.color),this.map=e.map,this.lightMap=e.lightMap,this.lightMapIntensity=e.lightMapIntensity,this.aoMap=e.aoMap,this.aoMapIntensity=e.aoMapIntensity,this.specularMap=e.specularMap,this.alphaMap=e.alphaMap,this.envMap=e.envMap,this.envMapRotation.copy(e.envMapRotation),this.combine=e.combine,this.reflectivity=e.reflectivity,this.refractionRatio=e.refractionRatio,this.wireframe=e.wireframe,this.wireframeLinewidth=e.wireframeLinewidth,this.wireframeLinecap=e.wireframeLinecap,this.wireframeLinejoin=e.wireframeLinejoin,this.fog=e.fog,this}}const la=new he,$f=new jt;let a6=0;class as{constructor(e,n,s=!1){if(Array.isArray(e))throw new TypeError("THREE.BufferAttribute: array should be a Typed Array.");this.isBufferAttribute=!0,Object.defineProperty(this,"id",{value:a6++}),this.name="",this.array=e,this.itemSize=n,this.count=e!==void 0?e.length/n:0,this.normalized=s,this.usage=Cb,this.updateRanges=[],this.gpuType=bs,this.version=0}onUploadCallback(){}set needsUpdate(e){e===!0&&this.version++}setUsage(e){return this.usage=e,this}addUpdateRange(e,n){this.updateRanges.push({start:e,count:n})}clearUpdateRanges(){this.updateRanges.length=0}copy(e){return this.name=e.name,this.array=new e.array.constructor(e.array),this.itemSize=e.itemSize,this.count=e.count,this.normalized=e.normalized,this.usage=e.usage,this.gpuType=e.gpuType,this}copyAt(e,n,s){e*=this.itemSize,s*=n.itemSize;for(let o=0,l=this.itemSize;on.count&&console.warn("THREE.BufferGeometry: Buffer size too small for points data. Use .dispose() and create a new geometry."),n.needsUpdate=!0}return this}computeBoundingBox(){this.boundingBox===null&&(this.boundingBox=new kl);const e=this.attributes.position,n=this.morphAttributes.position;if(e&&e.isGLBufferAttribute){console.error("THREE.BufferGeometry.computeBoundingBox(): GLBufferAttribute requires a manual bounding box.",this),this.boundingBox.set(new he(-1/0,-1/0,-1/0),new he(1/0,1/0,1/0));return}if(e!==void 0){if(this.boundingBox.setFromBufferAttribute(e),n)for(let s=0,o=n.length;s0&&(e.userData=this.userData),this.parameters!==void 0){const m=this.parameters;for(const p in m)m[p]!==void 0&&(e[p]=m[p]);return e}e.data={attributes:{}};const n=this.index;n!==null&&(e.data.index={type:n.array.constructor.name,array:Array.prototype.slice.call(n.array)});const s=this.attributes;for(const m in s){const p=s[m];e.data.attributes[m]=p.toJSON(e.data)}const o={};let l=!1;for(const m in this.morphAttributes){const p=this.morphAttributes[m],y=[];for(let v=0,x=p.length;v0&&(o[m]=y,l=!0)}l&&(e.data.morphAttributes=o,e.data.morphTargetsRelative=this.morphTargetsRelative);const d=this.groups;d.length>0&&(e.data.groups=JSON.parse(JSON.stringify(d)));const h=this.boundingSphere;return h!==null&&(e.data.boundingSphere=h.toJSON()),e}clone(){return new this.constructor().copy(this)}copy(e){this.index=null,this.attributes={},this.morphAttributes={},this.groups=[],this.boundingBox=null,this.boundingSphere=null;const n={};this.name=e.name;const s=e.index;s!==null&&this.setIndex(s.clone());const o=e.attributes;for(const p in o){const y=o[p];this.setAttribute(p,y.clone(n))}const l=e.morphAttributes;for(const p in l){const y=[],v=l[p];for(let x=0,S=v.length;x0){const o=n[s[0]];if(o!==void 0){this.morphTargetInfluences=[],this.morphTargetDictionary={};for(let l=0,d=o.length;l(e.far-e.near)**2))&&(FM.copy(l).invert(),Ko.copy(e.ray).applyMatrix4(FM),!(s.boundingBox!==null&&Ko.intersectsBox(s.boundingBox)===!1)&&this._computeIntersections(e,n,Ko)))}_computeIntersections(e,n,s){let o;const l=this.geometry,d=this.material,h=l.index,m=l.attributes.position,p=l.attributes.uv,y=l.attributes.uv1,v=l.attributes.normal,x=l.groups,S=l.drawRange;if(h!==null)if(Array.isArray(d))for(let M=0,w=x.length;Mn.far?null:{distance:p,point:sp.clone(),object:a}}function rp(a,e,n,s,o,l,d,h,m,p){a.getVertexPosition(h,tp),a.getVertexPosition(m,np),a.getVertexPosition(p,ap);const y=s6(a,e,n,s,tp,np,ap,HM);if(y){const v=new he;es.getBarycoord(HM,tp,np,ap,v),o&&(y.uv=es.getInterpolatedAttribute(o,h,m,p,v,new jt)),l&&(y.uv1=es.getInterpolatedAttribute(l,h,m,p,v,new jt)),d&&(y.normal=es.getInterpolatedAttribute(d,h,m,p,v,new he),y.normal.dot(s.direction)>0&&y.normal.multiplyScalar(-1));const x={a:h,b:m,c:p,normal:new he,materialIndex:0};es.getNormal(tp,np,ap,x.normal),y.face=x,y.barycoord=v}return y}class wr extends Oa{constructor(e=1,n=1,s=1,o=1,l=1,d=1){super(),this.type="BoxGeometry",this.parameters={width:e,height:n,depth:s,widthSegments:o,heightSegments:l,depthSegments:d};const h=this;o=Math.floor(o),l=Math.floor(l),d=Math.floor(d);const m=[],p=[],y=[],v=[];let x=0,S=0;M("z","y","x",-1,-1,s,n,e,d,l,0),M("z","y","x",1,-1,s,n,-e,d,l,1),M("x","z","y",1,1,e,s,n,o,d,2),M("x","z","y",1,-1,e,s,-n,o,d,3),M("x","y","z",1,-1,e,n,s,o,l,4),M("x","y","z",-1,-1,e,n,-s,o,l,5),this.setIndex(m),this.setAttribute("position",new qn(p,3)),this.setAttribute("normal",new qn(y,3)),this.setAttribute("uv",new qn(v,2));function M(w,E,A,k,R,N,I,z,j,L,D){const P=N/j,F=I/L,q=N/2,J=I/2,ie=z/2,Q=j+1,V=L+1;let $=0,te=0;const ne=new he;for(let Y=0;Y0?1:-1,y.push(ne.x,ne.y,ne.z),v.push(_/j),v.push(1-Y/L),$+=1}}for(let Y=0;Y0&&(n.defines=this.defines),n.vertexShader=this.vertexShader,n.fragmentShader=this.fragmentShader,n.lights=this.lights,n.clipping=this.clipping;const s={};for(const o in this.extensions)this.extensions[o]===!0&&(s[o]=!0);return Object.keys(s).length>0&&(n.extensions=s),n}}class nN extends aa{constructor(){super(),this.isCamera=!0,this.type="Camera",this.matrixWorldInverse=new dn,this.projectionMatrix=new dn,this.projectionMatrixInverse=new dn,this.coordinateSystem=Us,this._reversedDepth=!1}get reversedDepth(){return this._reversedDepth}copy(e,n){return super.copy(e,n),this.matrixWorldInverse.copy(e.matrixWorldInverse),this.projectionMatrix.copy(e.projectionMatrix),this.projectionMatrixInverse.copy(e.projectionMatrixInverse),this.coordinateSystem=e.coordinateSystem,this}getWorldDirection(e){return super.getWorldDirection(e).negate()}updateMatrixWorld(e){super.updateMatrixWorld(e),this.matrixWorldInverse.copy(this.matrixWorld).invert()}updateWorldMatrix(e,n){super.updateWorldMatrix(e,n),this.matrixWorldInverse.copy(this.matrixWorld).invert()}clone(){return new this.constructor().copy(this)}}const ro=new he,GM=new jt,VM=new jt;class Ui extends nN{constructor(e=50,n=1,s=.1,o=2e3){super(),this.isPerspectiveCamera=!0,this.type="PerspectiveCamera",this.fov=e,this.zoom=1,this.near=s,this.far=o,this.focus=10,this.aspect=n,this.view=null,this.filmGauge=35,this.filmOffset=0,this.updateProjectionMatrix()}copy(e,n){return super.copy(e,n),this.fov=e.fov,this.zoom=e.zoom,this.near=e.near,this.far=e.far,this.focus=e.focus,this.aspect=e.aspect,this.view=e.view===null?null:Object.assign({},e.view),this.filmGauge=e.filmGauge,this.filmOffset=e.filmOffset,this}setFocalLength(e){const n=.5*this.getFilmHeight()/e;this.fov=ih*2*Math.atan(n),this.updateProjectionMatrix()}getFocalLength(){const e=Math.tan(Gd*.5*this.fov);return .5*this.getFilmHeight()/e}getEffectiveFOV(){return ih*2*Math.atan(Math.tan(Gd*.5*this.fov)/this.zoom)}getFilmWidth(){return this.filmGauge*Math.min(this.aspect,1)}getFilmHeight(){return this.filmGauge/Math.max(this.aspect,1)}getViewBounds(e,n,s){ro.set(-1,-1,.5).applyMatrix4(this.projectionMatrixInverse),n.set(ro.x,ro.y).multiplyScalar(-e/ro.z),ro.set(1,1,.5).applyMatrix4(this.projectionMatrixInverse),s.set(ro.x,ro.y).multiplyScalar(-e/ro.z)}getViewSize(e,n){return this.getViewBounds(e,GM,VM),n.subVectors(VM,GM)}setViewOffset(e,n,s,o,l,d){this.aspect=e/n,this.view===null&&(this.view={enabled:!0,fullWidth:1,fullHeight:1,offsetX:0,offsetY:0,width:1,height:1}),this.view.enabled=!0,this.view.fullWidth=e,this.view.fullHeight=n,this.view.offsetX=s,this.view.offsetY=o,this.view.width=l,this.view.height=d,this.updateProjectionMatrix()}clearViewOffset(){this.view!==null&&(this.view.enabled=!1),this.updateProjectionMatrix()}updateProjectionMatrix(){const e=this.near;let n=e*Math.tan(Gd*.5*this.fov)/this.zoom,s=2*n,o=this.aspect*s,l=-.5*o;const d=this.view;if(this.view!==null&&this.view.enabled){const m=d.fullWidth,p=d.fullHeight;l+=d.offsetX*o/m,n-=d.offsetY*s/p,o*=d.width/m,s*=d.height/p}const h=this.filmOffset;h!==0&&(l+=e*h/this.getFilmWidth()),this.projectionMatrix.makePerspective(l,l+o,n,n-s,e,this.far,this.coordinateSystem,this.reversedDepth),this.projectionMatrixInverse.copy(this.projectionMatrix).invert()}toJSON(e){const n=super.toJSON(e);return n.object.fov=this.fov,n.object.zoom=this.zoom,n.object.near=this.near,n.object.far=this.far,n.object.focus=this.focus,n.object.aspect=this.aspect,this.view!==null&&(n.object.view=Object.assign({},this.view)),n.object.filmGauge=this.filmGauge,n.object.filmOffset=this.filmOffset,n}}const wc=-90,Mc=1;class c6 extends aa{constructor(e,n,s){super(),this.type="CubeCamera",this.renderTarget=s,this.coordinateSystem=null,this.activeMipmapLevel=0;const o=new Ui(wc,Mc,e,n);o.layers=this.layers,this.add(o);const l=new Ui(wc,Mc,e,n);l.layers=this.layers,this.add(l);const d=new Ui(wc,Mc,e,n);d.layers=this.layers,this.add(d);const h=new Ui(wc,Mc,e,n);h.layers=this.layers,this.add(h);const m=new Ui(wc,Mc,e,n);m.layers=this.layers,this.add(m);const p=new Ui(wc,Mc,e,n);p.layers=this.layers,this.add(p)}updateCoordinateSystem(){const e=this.coordinateSystem,n=this.children.concat(),[s,o,l,d,h,m]=n;for(const p of n)this.remove(p);if(e===Us)s.up.set(0,1,0),s.lookAt(1,0,0),o.up.set(0,1,0),o.lookAt(-1,0,0),l.up.set(0,0,-1),l.lookAt(0,1,0),d.up.set(0,0,1),d.lookAt(0,-1,0),h.up.set(0,1,0),h.lookAt(0,0,1),m.up.set(0,1,0),m.lookAt(0,0,-1);else if(e===fm)s.up.set(0,-1,0),s.lookAt(-1,0,0),o.up.set(0,-1,0),o.lookAt(1,0,0),l.up.set(0,0,1),l.lookAt(0,1,0),d.up.set(0,0,-1),d.lookAt(0,-1,0),h.up.set(0,-1,0),h.lookAt(0,0,1),m.up.set(0,-1,0),m.lookAt(0,0,-1);else throw new Error("THREE.CubeCamera.updateCoordinateSystem(): Invalid coordinate system: "+e);for(const p of n)this.add(p),p.updateMatrixWorld()}update(e,n){this.parent===null&&this.updateMatrixWorld();const{renderTarget:s,activeMipmapLevel:o}=this;this.coordinateSystem!==e.coordinateSystem&&(this.coordinateSystem=e.coordinateSystem,this.updateCoordinateSystem());const[l,d,h,m,p,y]=this.children,v=e.getRenderTarget(),x=e.getActiveCubeFace(),S=e.getActiveMipmapLevel(),M=e.xr.enabled;e.xr.enabled=!1;const w=s.texture.generateMipmaps;s.texture.generateMipmaps=!1,e.setRenderTarget(s,0,o),e.render(n,l),e.setRenderTarget(s,1,o),e.render(n,d),e.setRenderTarget(s,2,o),e.render(n,h),e.setRenderTarget(s,3,o),e.render(n,m),e.setRenderTarget(s,4,o),e.render(n,p),s.texture.generateMipmaps=w,e.setRenderTarget(s,5,o),e.render(n,y),e.setRenderTarget(v,x,S),e.xr.enabled=M,s.texture.needsPMREMUpdate=!0}}class aN extends Ga{constructor(e=[],n=iu,s,o,l,d,h,m,p,y){super(e,n,s,o,l,d,h,m,p,y),this.isCubeTexture=!0,this.flipY=!1}get images(){return this.image}set images(e){this.image=e}}class u6 extends As{constructor(e=1,n={}){super(e,e,n),this.isWebGLCubeRenderTarget=!0;const s={width:e,height:e,depth:1},o=[s,s,s,s,s,s];this.texture=new aN(o),this._setTextureOptions(n),this.texture.isRenderTargetTexture=!0}fromEquirectangularTexture(e,n){this.texture.type=n.type,this.texture.colorSpace=n.colorSpace,this.texture.generateMipmaps=n.generateMipmaps,this.texture.minFilter=n.minFilter,this.texture.magFilter=n.magFilter;const s={uniforms:{tEquirect:{value:null}},vertexShader:` varying vec3 vWorldDirection; vec3 transformDirection( in vec3 dir, in mat4 matrix ) { return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz ); } void main() { vWorldDirection = transformDirection( position, modelMatrix ); #include #include } `,fragmentShader:` uniform sampler2D tEquirect; varying vec3 vWorldDirection; #include void main() { vec3 direction = normalize( vWorldDirection ); vec2 sampleUV = equirectUv( direction ); gl_FragColor = texture2D( tEquirect, sampleUV ); } `},o=new wr(5,5,5),l=new _a({name:"CubemapFromEquirect",uniforms:cu(s.uniforms),vertexShader:s.vertexShader,fragmentShader:s.fragmentShader,side:ai,blending:Ja});l.uniforms.tEquirect.value=n;const d=new zn(o,l),h=n.minFilter;return n.minFilter===cl&&(n.minFilter=Is),new c6(1,10,this).update(e,d),n.minFilter=h,d.geometry.dispose(),d.material.dispose(),this}clear(e,n=!0,s=!0,o=!0){const l=e.getRenderTarget();for(let d=0;d<6;d++)e.setRenderTarget(this,d),e.clear(n,s,o);e.setRenderTarget(l)}}class Pd extends aa{constructor(){super(),this.isGroup=!0,this.type="Group"}}const d6={type:"move"};class Bx{constructor(){this._targetRay=null,this._grip=null,this._hand=null}getHandSpace(){return this._hand===null&&(this._hand=new Pd,this._hand.matrixAutoUpdate=!1,this._hand.visible=!1,this._hand.joints={},this._hand.inputState={pinching:!1}),this._hand}getTargetRaySpace(){return this._targetRay===null&&(this._targetRay=new Pd,this._targetRay.matrixAutoUpdate=!1,this._targetRay.visible=!1,this._targetRay.hasLinearVelocity=!1,this._targetRay.linearVelocity=new he,this._targetRay.hasAngularVelocity=!1,this._targetRay.angularVelocity=new he),this._targetRay}getGripSpace(){return this._grip===null&&(this._grip=new Pd,this._grip.matrixAutoUpdate=!1,this._grip.visible=!1,this._grip.hasLinearVelocity=!1,this._grip.linearVelocity=new he,this._grip.hasAngularVelocity=!1,this._grip.angularVelocity=new he),this._grip}dispatchEvent(e){return this._targetRay!==null&&this._targetRay.dispatchEvent(e),this._grip!==null&&this._grip.dispatchEvent(e),this._hand!==null&&this._hand.dispatchEvent(e),this}connect(e){if(e&&e.hand){const n=this._hand;if(n)for(const s of e.hand.values())this._getHandJoint(n,s)}return this.dispatchEvent({type:"connected",data:e}),this}disconnect(e){return this.dispatchEvent({type:"disconnected",data:e}),this._targetRay!==null&&(this._targetRay.visible=!1),this._grip!==null&&(this._grip.visible=!1),this._hand!==null&&(this._hand.visible=!1),this}update(e,n,s){let o=null,l=null,d=null;const h=this._targetRay,m=this._grip,p=this._hand;if(e&&n.session.visibilityState!=="visible-blurred"){if(p&&e.hand){d=!0;for(const w of e.hand.values()){const E=n.getJointPose(w,s),A=this._getHandJoint(p,w);E!==null&&(A.matrix.fromArray(E.transform.matrix),A.matrix.decompose(A.position,A.rotation,A.scale),A.matrixWorldNeedsUpdate=!0,A.jointRadius=E.radius),A.visible=E!==null}const y=p.joints["index-finger-tip"],v=p.joints["thumb-tip"],x=y.position.distanceTo(v.position),S=.02,M=.005;p.inputState.pinching&&x>S+M?(p.inputState.pinching=!1,this.dispatchEvent({type:"pinchend",handedness:e.handedness,target:this})):!p.inputState.pinching&&x<=S-M&&(p.inputState.pinching=!0,this.dispatchEvent({type:"pinchstart",handedness:e.handedness,target:this}))}else m!==null&&e.gripSpace&&(l=n.getPose(e.gripSpace,s),l!==null&&(m.matrix.fromArray(l.transform.matrix),m.matrix.decompose(m.position,m.rotation,m.scale),m.matrixWorldNeedsUpdate=!0,l.linearVelocity?(m.hasLinearVelocity=!0,m.linearVelocity.copy(l.linearVelocity)):m.hasLinearVelocity=!1,l.angularVelocity?(m.hasAngularVelocity=!0,m.angularVelocity.copy(l.angularVelocity)):m.hasAngularVelocity=!1));h!==null&&(o=n.getPose(e.targetRaySpace,s),o===null&&l!==null&&(o=l),o!==null&&(h.matrix.fromArray(o.transform.matrix),h.matrix.decompose(h.position,h.rotation,h.scale),h.matrixWorldNeedsUpdate=!0,o.linearVelocity?(h.hasLinearVelocity=!0,h.linearVelocity.copy(o.linearVelocity)):h.hasLinearVelocity=!1,o.angularVelocity?(h.hasAngularVelocity=!0,h.angularVelocity.copy(o.angularVelocity)):h.hasAngularVelocity=!1,this.dispatchEvent(d6)))}return h!==null&&(h.visible=o!==null),m!==null&&(m.visible=l!==null),p!==null&&(p.visible=d!==null),this}_getHandJoint(e,n){if(e.joints[n.jointName]===void 0){const s=new Pd;s.matrixAutoUpdate=!1,s.visible=!1,e.joints[n.jointName]=s,e.add(s)}return e.joints[n.jointName]}}class G0{constructor(e,n=1,s=1e3){this.isFog=!0,this.name="",this.color=new tn(e),this.near=n,this.far=s}clone(){return new G0(this.color,this.near,this.far)}toJSON(){return{type:"Fog",name:this.name,color:this.color.getHex(),near:this.near,far:this.far}}}class iN extends aa{constructor(){super(),this.isScene=!0,this.type="Scene",this.background=null,this.environment=null,this.fog=null,this.backgroundBlurriness=0,this.backgroundIntensity=1,this.backgroundRotation=new Es,this.environmentIntensity=1,this.environmentRotation=new Es,this.overrideMaterial=null,typeof __THREE_DEVTOOLS__<"u"&&__THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("observe",{detail:this}))}copy(e,n){return super.copy(e,n),e.background!==null&&(this.background=e.background.clone()),e.environment!==null&&(this.environment=e.environment.clone()),e.fog!==null&&(this.fog=e.fog.clone()),this.backgroundBlurriness=e.backgroundBlurriness,this.backgroundIntensity=e.backgroundIntensity,this.backgroundRotation.copy(e.backgroundRotation),this.environmentIntensity=e.environmentIntensity,this.environmentRotation.copy(e.environmentRotation),e.overrideMaterial!==null&&(this.overrideMaterial=e.overrideMaterial.clone()),this.matrixAutoUpdate=e.matrixAutoUpdate,this}toJSON(e){const n=super.toJSON(e);return this.fog!==null&&(n.object.fog=this.fog.toJSON()),this.backgroundBlurriness>0&&(n.object.backgroundBlurriness=this.backgroundBlurriness),this.backgroundIntensity!==1&&(n.object.backgroundIntensity=this.backgroundIntensity),n.object.backgroundRotation=this.backgroundRotation.toArray(),this.environmentIntensity!==1&&(n.object.environmentIntensity=this.environmentIntensity),n.object.environmentRotation=this.environmentRotation.toArray(),n}}class h6{constructor(e,n){this.isInterleavedBuffer=!0,this.array=e,this.stride=n,this.count=e!==void 0?e.length/n:0,this.usage=Cb,this.updateRanges=[],this.version=0,this.uuid=yr()}onUploadCallback(){}set needsUpdate(e){e===!0&&this.version++}setUsage(e){return this.usage=e,this}addUpdateRange(e,n){this.updateRanges.push({start:e,count:n})}clearUpdateRanges(){this.updateRanges.length=0}copy(e){return this.array=new e.array.constructor(e.array),this.count=e.count,this.stride=e.stride,this.usage=e.usage,this}copyAt(e,n,s){e*=this.stride,s*=n.stride;for(let o=0,l=this.stride;oe.far||n.push({distance:m,point:Ad.clone(),uv:es.getInterpolation(Ad,op,wd,lp,qM,Hx,WM,new jt),face:null,object:this})}copy(e,n){return super.copy(e,n),e.center!==void 0&&this.center.copy(e.center),this.material=e.material,this}}function cp(a,e,n,s,o,l){Rc.subVectors(a,n).addScalar(.5).multiply(s),o!==void 0?(Ed.x=l*Rc.x-o*Rc.y,Ed.y=o*Rc.x+l*Rc.y):Ed.copy(Rc),a.copy(e),a.x+=Ed.x,a.y+=Ed.y,a.applyMatrix4(rN)}class oN extends Ga{constructor(e=null,n=1,s=1,o,l,d,h,m,p=ii,y=ii,v,x){super(null,d,h,m,p,y,o,l,v,x),this.isDataTexture=!0,this.image={data:e,width:n,height:s},this.generateMipmaps=!1,this.flipY=!1,this.unpackAlignment=1}}class YM extends as{constructor(e,n,s,o=1){super(e,n,s),this.isInstancedBufferAttribute=!0,this.meshPerAttribute=o}copy(e){return super.copy(e),this.meshPerAttribute=e.meshPerAttribute,this}toJSON(){const e=super.toJSON();return e.meshPerAttribute=this.meshPerAttribute,e.isInstancedBufferAttribute=!0,e}}const kc=new dn,XM=new dn,up=[],KM=new kl,p6=new dn,Md=new zn,Cd=new yu;class lN extends zn{constructor(e,n,s){super(e,n),this.isInstancedMesh=!0,this.instanceMatrix=new YM(new Float32Array(s*16),16),this.instanceColor=null,this.morphTexture=null,this.count=s,this.boundingBox=null,this.boundingSphere=null;for(let o=0;o1?null:n.copy(e.start).addScaledVector(s,l)}intersectsLine(e){const n=this.distanceToPoint(e.start),s=this.distanceToPoint(e.end);return n<0&&s>0||s<0&&n>0}intersectsBox(e){return e.intersectsPlane(this)}intersectsSphere(e){return e.intersectsPlane(this)}coplanarPoint(e){return e.copy(this.normal).multiplyScalar(-this.constant)}applyMatrix4(e,n){const s=n||g6.getNormalMatrix(e),o=this.coplanarPoint(Gx).applyMatrix4(e),l=this.normal.applyMatrix3(s).normalize();return this.constant=-o.dot(l),this}translate(e){return this.constant-=e.dot(this.normal),this}equals(e){return e.normal.equals(this.normal)&&e.constant===this.constant}clone(){return new this.constructor().copy(this)}}const Jo=new yu,v6=new jt(.5,.5),dp=new he;class V0{constructor(e=new oo,n=new oo,s=new oo,o=new oo,l=new oo,d=new oo){this.planes=[e,n,s,o,l,d]}set(e,n,s,o,l,d){const h=this.planes;return h[0].copy(e),h[1].copy(n),h[2].copy(s),h[3].copy(o),h[4].copy(l),h[5].copy(d),this}copy(e){const n=this.planes;for(let s=0;s<6;s++)n[s].copy(e.planes[s]);return this}setFromProjectionMatrix(e,n=Us,s=!1){const o=this.planes,l=e.elements,d=l[0],h=l[1],m=l[2],p=l[3],y=l[4],v=l[5],x=l[6],S=l[7],M=l[8],w=l[9],E=l[10],A=l[11],k=l[12],R=l[13],N=l[14],I=l[15];if(o[0].setComponents(p-d,S-y,A-M,I-k).normalize(),o[1].setComponents(p+d,S+y,A+M,I+k).normalize(),o[2].setComponents(p+h,S+v,A+w,I+R).normalize(),o[3].setComponents(p-h,S-v,A-w,I-R).normalize(),s)o[4].setComponents(m,x,E,N).normalize(),o[5].setComponents(p-m,S-x,A-E,I-N).normalize();else if(o[4].setComponents(p-m,S-x,A-E,I-N).normalize(),n===Us)o[5].setComponents(p+m,S+x,A+E,I+N).normalize();else if(n===fm)o[5].setComponents(m,x,E,N).normalize();else throw new Error("THREE.Frustum.setFromProjectionMatrix(): Invalid coordinate system: "+n);return this}intersectsObject(e){if(e.boundingSphere!==void 0)e.boundingSphere===null&&e.computeBoundingSphere(),Jo.copy(e.boundingSphere).applyMatrix4(e.matrixWorld);else{const n=e.geometry;n.boundingSphere===null&&n.computeBoundingSphere(),Jo.copy(n.boundingSphere).applyMatrix4(e.matrixWorld)}return this.intersectsSphere(Jo)}intersectsSprite(e){Jo.center.set(0,0,0);const n=v6.distanceTo(e.center);return Jo.radius=.7071067811865476+n,Jo.applyMatrix4(e.matrixWorld),this.intersectsSphere(Jo)}intersectsSphere(e){const n=this.planes,s=e.center,o=-e.radius;for(let l=0;l<6;l++)if(n[l].distanceToPoint(s)0?e.max.x:e.min.x,dp.y=o.normal.y>0?e.max.y:e.min.y,dp.z=o.normal.z>0?e.max.z:e.min.z,o.distanceToPoint(dp)<0)return!1}return!0}containsPoint(e){const n=this.planes;for(let s=0;s<6;s++)if(n[s].distanceToPoint(e)<0)return!1;return!0}clone(){return new this.constructor().copy(this)}}class cN extends Rr{constructor(e){super(),this.isLineBasicMaterial=!0,this.type="LineBasicMaterial",this.color=new tn(16777215),this.map=null,this.linewidth=1,this.linecap="round",this.linejoin="round",this.fog=!0,this.setValues(e)}copy(e){return super.copy(e),this.color.copy(e.color),this.map=e.map,this.linewidth=e.linewidth,this.linecap=e.linecap,this.linejoin=e.linejoin,this.fog=e.fog,this}}const gm=new he,vm=new he,JM=new dn,Td=new Xm,hp=new yu,Vx=new he,ZM=new he;class x6 extends aa{constructor(e=new Oa,n=new cN){super(),this.isLine=!0,this.type="Line",this.geometry=e,this.material=n,this.morphTargetDictionary=void 0,this.morphTargetInfluences=void 0,this.updateMorphTargets()}copy(e,n){return super.copy(e,n),this.material=Array.isArray(e.material)?e.material.slice():e.material,this.geometry=e.geometry,this}computeLineDistances(){const e=this.geometry;if(e.index===null){const n=e.attributes.position,s=[0];for(let o=1,l=n.count;o0){const o=n[s[0]];if(o!==void 0){this.morphTargetInfluences=[],this.morphTargetDictionary={};for(let l=0,d=o.length;ls)return;Vx.applyMatrix4(a.matrixWorld);const p=e.ray.origin.distanceTo(Vx);if(!(pe.far))return{distance:p,point:ZM.clone().applyMatrix4(a.matrixWorld),index:d,face:null,faceIndex:null,barycoord:null,object:a}}class QM extends Ga{constructor(e,n,s,o,l,d,h,m,p){super(e,n,s,o,l,d,h,m,p),this.isCanvasTexture=!0,this.needsUpdate=!0}}class q0 extends Ga{constructor(e,n,s=wl,o,l,d,h=ii,m=ii,p,y=ah,v=1){if(y!==ah&&y!==ou)throw new Error("DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat");const x={width:e,height:n,depth:v};super(x,o,l,d,h,m,y,s,p),this.isDepthTexture=!0,this.flipY=!1,this.generateMipmaps=!1,this.compareFunction=null}copy(e){return super.copy(e),this.source=new B0(Object.assign({},e.image)),this.compareFunction=e.compareFunction,this}toJSON(e){const n=super.toJSON(e);return this.compareFunction!==null&&(n.compareFunction=this.compareFunction),n}}class uN extends Ga{constructor(e=null){super(),this.sourceTexture=e,this.isExternalTexture=!0}copy(e){return super.copy(e),this.sourceTexture=e.sourceTexture,this}}class Wd extends Oa{constructor(e=1,n=1,s=1,o=32,l=1,d=!1,h=0,m=Math.PI*2){super(),this.type="CylinderGeometry",this.parameters={radiusTop:e,radiusBottom:n,height:s,radialSegments:o,heightSegments:l,openEnded:d,thetaStart:h,thetaLength:m};const p=this;o=Math.floor(o),l=Math.floor(l);const y=[],v=[],x=[],S=[];let M=0;const w=[],E=s/2;let A=0;k(),d===!1&&(e>0&&R(!0),n>0&&R(!1)),this.setIndex(y),this.setAttribute("position",new qn(v,3)),this.setAttribute("normal",new qn(x,3)),this.setAttribute("uv",new qn(S,2));function k(){const N=new he,I=new he;let z=0;const j=(n-e)/s;for(let L=0;L<=l;L++){const D=[],P=L/l,F=P*(n-e)+e;for(let q=0;q<=o;q++){const J=q/o,ie=J*m+h,Q=Math.sin(ie),V=Math.cos(ie);I.x=F*Q,I.y=-P*s+E,I.z=F*V,v.push(I.x,I.y,I.z),N.set(Q,j,V).normalize(),x.push(N.x,N.y,N.z),S.push(J,1-P),D.push(M++)}w.push(D)}for(let L=0;L0||D!==0)&&(y.push(P,F,J),z+=3),(n>0||D!==l-1)&&(y.push(F,q,J),z+=3)}p.addGroup(A,z,0),A+=z}function R(N){const I=M,z=new jt,j=new he;let L=0;const D=N===!0?e:n,P=N===!0?1:-1;for(let q=1;q<=o;q++)v.push(0,E*P,0),x.push(0,P,0),S.push(.5,.5),M++;const F=M;for(let q=0;q<=o;q++){const ie=q/o*m+h,Q=Math.cos(ie),V=Math.sin(ie);j.x=D*V,j.y=E*P,j.z=D*Q,v.push(j.x,j.y,j.z),x.push(0,P,0),z.x=Q*.5+.5,z.y=V*.5*P+.5,S.push(z.x,z.y),M++}for(let q=0;q.9&&j<.1&&(R<.2&&(d[k+0]+=1),N<.2&&(d[k+2]+=1),I<.2&&(d[k+4]+=1))}}function x(k){l.push(k.x,k.y,k.z)}function S(k,R){const N=k*3;R.x=e[N+0],R.y=e[N+1],R.z=e[N+2]}function M(){const k=new he,R=new he,N=new he,I=new he,z=new jt,j=new jt,L=new jt;for(let D=0,P=0;D0)m=o-1;else{m=o;break}if(o=m,s[o]===d)return o/(l-1);const y=s[o],x=s[o+1]-y,S=(d-y)/x;return(o+S)/(l-1)}getTangent(e,n){let o=e-1e-4,l=e+1e-4;o<0&&(o=0),l>1&&(l=1);const d=this.getPoint(o),h=this.getPoint(l),m=n||(d.isVector2?new jt:new he);return m.copy(h).sub(d).normalize(),m}getTangentAt(e,n){const s=this.getUtoTmapping(e);return this.getTangent(s,n)}computeFrenetFrames(e,n=!1){const s=new he,o=[],l=[],d=[],h=new he,m=new dn;for(let S=0;S<=e;S++){const M=S/e;o[S]=this.getTangentAt(M,new he)}l[0]=new he,d[0]=new he;let p=Number.MAX_VALUE;const y=Math.abs(o[0].x),v=Math.abs(o[0].y),x=Math.abs(o[0].z);y<=p&&(p=y,s.set(1,0,0)),v<=p&&(p=v,s.set(0,1,0)),x<=p&&s.set(0,0,1),h.crossVectors(o[0],s).normalize(),l[0].crossVectors(o[0],h),d[0].crossVectors(o[0],l[0]);for(let S=1;S<=e;S++){if(l[S]=l[S-1].clone(),d[S]=d[S-1].clone(),h.crossVectors(o[S-1],o[S]),h.length()>Number.EPSILON){h.normalize();const M=Math.acos(en(o[S-1].dot(o[S]),-1,1));l[S].applyMatrix4(m.makeRotationAxis(h,M))}d[S].crossVectors(o[S],l[S])}if(n===!0){let S=Math.acos(en(l[0].dot(l[e]),-1,1));S/=e,o[0].dot(h.crossVectors(l[0],l[e]))>0&&(S=-S);for(let M=1;M<=e;M++)l[M].applyMatrix4(m.makeRotationAxis(o[M],S*M)),d[M].crossVectors(o[M],l[M])}return{tangents:o,normals:l,binormals:d}}clone(){return new this.constructor().copy(this)}copy(e){return this.arcLengthDivisions=e.arcLengthDivisions,this}toJSON(){const e={metadata:{version:4.7,type:"Curve",generator:"Curve.toJSON"}};return e.arcLengthDivisions=this.arcLengthDivisions,e.type=this.type,e}fromJSON(e){return this.arcLengthDivisions=e.arcLengthDivisions,this}}function b6(a,e){const n=1-a;return n*n*e}function S6(a,e){return 2*(1-a)*a*e}function A6(a,e){return a*a*e}function qx(a,e,n,s){return b6(a,e)+S6(a,n)+A6(a,s)}class E6 extends y6{constructor(e=new he,n=new he,s=new he){super(),this.isQuadraticBezierCurve3=!0,this.type="QuadraticBezierCurve3",this.v0=e,this.v1=n,this.v2=s}getPoint(e,n=new he){const s=n,o=this.v0,l=this.v1,d=this.v2;return s.set(qx(e,o.x,l.x,d.x),qx(e,o.y,l.y,d.y),qx(e,o.z,l.z,d.z)),s}copy(e){return super.copy(e),this.v0.copy(e.v0),this.v1.copy(e.v1),this.v2.copy(e.v2),this}toJSON(){const e=super.toJSON();return e.v0=this.v0.toArray(),e.v1=this.v1.toArray(),e.v2=this.v2.toArray(),e}fromJSON(e){return super.fromJSON(e),this.v0.fromArray(e.v0),this.v1.fromArray(e.v1),this.v2.fromArray(e.v2),this}}class Y0 extends W0{constructor(e=1,n=0){const s=(1+Math.sqrt(5))/2,o=[-1,s,0,1,s,0,-1,-s,0,1,-s,0,0,-1,s,0,1,s,0,-1,-s,0,1,-s,s,0,-1,s,0,1,-s,0,-1,-s,0,1],l=[0,11,5,0,5,1,0,1,7,0,7,10,0,10,11,1,5,9,5,11,4,11,10,2,10,7,6,7,1,8,3,9,4,3,4,2,3,2,6,3,6,8,3,8,9,4,9,5,2,4,11,6,2,10,8,6,7,9,8,1];super(o,l,e,n),this.type="IcosahedronGeometry",this.parameters={radius:e,detail:n}}static fromJSON(e){return new Y0(e.radius,e.detail)}}class uu extends Oa{constructor(e=1,n=1,s=1,o=1){super(),this.type="PlaneGeometry",this.parameters={width:e,height:n,widthSegments:s,heightSegments:o};const l=e/2,d=n/2,h=Math.floor(s),m=Math.floor(o),p=h+1,y=m+1,v=e/h,x=n/m,S=[],M=[],w=[],E=[];for(let A=0;A0)&&S.push(R,N,z),(A!==s-1||mS.start-M.start);let x=0;for(let S=1;S 0 vec4 plane; #ifdef ALPHA_TO_COVERAGE float distanceToPlane, distanceGradient; float clipOpacity = 1.0; #pragma unroll_loop_start for ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) { plane = clippingPlanes[ i ]; distanceToPlane = - dot( vClipPosition, plane.xyz ) + plane.w; distanceGradient = fwidth( distanceToPlane ) / 2.0; clipOpacity *= smoothstep( - distanceGradient, distanceGradient, distanceToPlane ); if ( clipOpacity == 0.0 ) discard; } #pragma unroll_loop_end #if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES float unionClipOpacity = 1.0; #pragma unroll_loop_start for ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) { plane = clippingPlanes[ i ]; distanceToPlane = - dot( vClipPosition, plane.xyz ) + plane.w; distanceGradient = fwidth( distanceToPlane ) / 2.0; unionClipOpacity *= 1.0 - smoothstep( - distanceGradient, distanceGradient, distanceToPlane ); } #pragma unroll_loop_end clipOpacity *= 1.0 - unionClipOpacity; #endif diffuseColor.a *= clipOpacity; if ( diffuseColor.a == 0.0 ) discard; #else #pragma unroll_loop_start for ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) { plane = clippingPlanes[ i ]; if ( dot( vClipPosition, plane.xyz ) > plane.w ) discard; } #pragma unroll_loop_end #if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES bool clipped = true; #pragma unroll_loop_start for ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) { plane = clippingPlanes[ i ]; clipped = ( dot( vClipPosition, plane.xyz ) > plane.w ) && clipped; } #pragma unroll_loop_end if ( clipped ) discard; #endif #endif #endif`,t9=`#if NUM_CLIPPING_PLANES > 0 varying vec3 vClipPosition; uniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ]; #endif`,n9=`#if NUM_CLIPPING_PLANES > 0 varying vec3 vClipPosition; #endif`,a9=`#if NUM_CLIPPING_PLANES > 0 vClipPosition = - mvPosition.xyz; #endif`,i9=`#if defined( USE_COLOR_ALPHA ) diffuseColor *= vColor; #elif defined( USE_COLOR ) diffuseColor.rgb *= vColor; #endif`,s9=`#if defined( USE_COLOR_ALPHA ) varying vec4 vColor; #elif defined( USE_COLOR ) varying vec3 vColor; #endif`,r9=`#if defined( USE_COLOR_ALPHA ) varying vec4 vColor; #elif defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR ) || defined( USE_BATCHING_COLOR ) varying vec3 vColor; #endif`,o9=`#if defined( USE_COLOR_ALPHA ) vColor = vec4( 1.0 ); #elif defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR ) || defined( USE_BATCHING_COLOR ) vColor = vec3( 1.0 ); #endif #ifdef USE_COLOR vColor *= color; #endif #ifdef USE_INSTANCING_COLOR vColor.xyz *= instanceColor.xyz; #endif #ifdef USE_BATCHING_COLOR vec3 batchingColor = getBatchingColor( getIndirectIndex( gl_DrawID ) ); vColor.xyz *= batchingColor.xyz; #endif`,l9=`#define PI 3.141592653589793 #define PI2 6.283185307179586 #define PI_HALF 1.5707963267948966 #define RECIPROCAL_PI 0.3183098861837907 #define RECIPROCAL_PI2 0.15915494309189535 #define EPSILON 1e-6 #ifndef saturate #define saturate( a ) clamp( a, 0.0, 1.0 ) #endif #define whiteComplement( a ) ( 1.0 - saturate( a ) ) float pow2( const in float x ) { return x*x; } vec3 pow2( const in vec3 x ) { return x*x; } float pow3( const in float x ) { return x*x*x; } float pow4( const in float x ) { float x2 = x*x; return x2*x2; } float max3( const in vec3 v ) { return max( max( v.x, v.y ), v.z ); } float average( const in vec3 v ) { return dot( v, vec3( 0.3333333 ) ); } highp float rand( const in vec2 uv ) { const highp float a = 12.9898, b = 78.233, c = 43758.5453; highp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI ); return fract( sin( sn ) * c ); } #ifdef HIGH_PRECISION float precisionSafeLength( vec3 v ) { return length( v ); } #else float precisionSafeLength( vec3 v ) { float maxComponent = max3( abs( v ) ); return length( v / maxComponent ) * maxComponent; } #endif struct IncidentLight { vec3 color; vec3 direction; bool visible; }; struct ReflectedLight { vec3 directDiffuse; vec3 directSpecular; vec3 indirectDiffuse; vec3 indirectSpecular; }; #ifdef USE_ALPHAHASH varying vec3 vPosition; #endif vec3 transformDirection( in vec3 dir, in mat4 matrix ) { return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz ); } vec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) { return normalize( ( vec4( dir, 0.0 ) * matrix ).xyz ); } mat3 transposeMat3( const in mat3 m ) { mat3 tmp; tmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x ); tmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y ); tmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z ); return tmp; } bool isPerspectiveMatrix( mat4 m ) { return m[ 2 ][ 3 ] == - 1.0; } vec2 equirectUv( in vec3 dir ) { float u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5; float v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5; return vec2( u, v ); } vec3 BRDF_Lambert( const in vec3 diffuseColor ) { return RECIPROCAL_PI * diffuseColor; } vec3 F_Schlick( const in vec3 f0, const in float f90, const in float dotVH ) { float fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH ); return f0 * ( 1.0 - fresnel ) + ( f90 * fresnel ); } float F_Schlick( const in float f0, const in float f90, const in float dotVH ) { float fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH ); return f0 * ( 1.0 - fresnel ) + ( f90 * fresnel ); } // validated`,c9=`#ifdef ENVMAP_TYPE_CUBE_UV #define cubeUV_minMipLevel 4.0 #define cubeUV_minTileSize 16.0 float getFace( vec3 direction ) { vec3 absDirection = abs( direction ); float face = - 1.0; if ( absDirection.x > absDirection.z ) { if ( absDirection.x > absDirection.y ) face = direction.x > 0.0 ? 0.0 : 3.0; else face = direction.y > 0.0 ? 1.0 : 4.0; } else { if ( absDirection.z > absDirection.y ) face = direction.z > 0.0 ? 2.0 : 5.0; else face = direction.y > 0.0 ? 1.0 : 4.0; } return face; } vec2 getUV( vec3 direction, float face ) { vec2 uv; if ( face == 0.0 ) { uv = vec2( direction.z, direction.y ) / abs( direction.x ); } else if ( face == 1.0 ) { uv = vec2( - direction.x, - direction.z ) / abs( direction.y ); } else if ( face == 2.0 ) { uv = vec2( - direction.x, direction.y ) / abs( direction.z ); } else if ( face == 3.0 ) { uv = vec2( - direction.z, direction.y ) / abs( direction.x ); } else if ( face == 4.0 ) { uv = vec2( - direction.x, direction.z ) / abs( direction.y ); } else { uv = vec2( direction.x, direction.y ) / abs( direction.z ); } return 0.5 * ( uv + 1.0 ); } vec3 bilinearCubeUV( sampler2D envMap, vec3 direction, float mipInt ) { float face = getFace( direction ); float filterInt = max( cubeUV_minMipLevel - mipInt, 0.0 ); mipInt = max( mipInt, cubeUV_minMipLevel ); float faceSize = exp2( mipInt ); highp vec2 uv = getUV( direction, face ) * ( faceSize - 2.0 ) + 1.0; if ( face > 2.0 ) { uv.y += faceSize; face -= 3.0; } uv.x += face * faceSize; uv.x += filterInt * 3.0 * cubeUV_minTileSize; uv.y += 4.0 * ( exp2( CUBEUV_MAX_MIP ) - faceSize ); uv.x *= CUBEUV_TEXEL_WIDTH; uv.y *= CUBEUV_TEXEL_HEIGHT; #ifdef texture2DGradEXT return texture2DGradEXT( envMap, uv, vec2( 0.0 ), vec2( 0.0 ) ).rgb; #else return texture2D( envMap, uv ).rgb; #endif } #define cubeUV_r0 1.0 #define cubeUV_m0 - 2.0 #define cubeUV_r1 0.8 #define cubeUV_m1 - 1.0 #define cubeUV_r4 0.4 #define cubeUV_m4 2.0 #define cubeUV_r5 0.305 #define cubeUV_m5 3.0 #define cubeUV_r6 0.21 #define cubeUV_m6 4.0 float roughnessToMip( float roughness ) { float mip = 0.0; if ( roughness >= cubeUV_r1 ) { mip = ( cubeUV_r0 - roughness ) * ( cubeUV_m1 - cubeUV_m0 ) / ( cubeUV_r0 - cubeUV_r1 ) + cubeUV_m0; } else if ( roughness >= cubeUV_r4 ) { mip = ( cubeUV_r1 - roughness ) * ( cubeUV_m4 - cubeUV_m1 ) / ( cubeUV_r1 - cubeUV_r4 ) + cubeUV_m1; } else if ( roughness >= cubeUV_r5 ) { mip = ( cubeUV_r4 - roughness ) * ( cubeUV_m5 - cubeUV_m4 ) / ( cubeUV_r4 - cubeUV_r5 ) + cubeUV_m4; } else if ( roughness >= cubeUV_r6 ) { mip = ( cubeUV_r5 - roughness ) * ( cubeUV_m6 - cubeUV_m5 ) / ( cubeUV_r5 - cubeUV_r6 ) + cubeUV_m5; } else { mip = - 2.0 * log2( 1.16 * roughness ); } return mip; } vec4 textureCubeUV( sampler2D envMap, vec3 sampleDir, float roughness ) { float mip = clamp( roughnessToMip( roughness ), cubeUV_m0, CUBEUV_MAX_MIP ); float mipF = fract( mip ); float mipInt = floor( mip ); vec3 color0 = bilinearCubeUV( envMap, sampleDir, mipInt ); if ( mipF == 0.0 ) { return vec4( color0, 1.0 ); } else { vec3 color1 = bilinearCubeUV( envMap, sampleDir, mipInt + 1.0 ); return vec4( mix( color0, color1, mipF ), 1.0 ); } } #endif`,u9=`vec3 transformedNormal = objectNormal; #ifdef USE_TANGENT vec3 transformedTangent = objectTangent; #endif #ifdef USE_BATCHING mat3 bm = mat3( batchingMatrix ); transformedNormal /= vec3( dot( bm[ 0 ], bm[ 0 ] ), dot( bm[ 1 ], bm[ 1 ] ), dot( bm[ 2 ], bm[ 2 ] ) ); transformedNormal = bm * transformedNormal; #ifdef USE_TANGENT transformedTangent = bm * transformedTangent; #endif #endif #ifdef USE_INSTANCING mat3 im = mat3( instanceMatrix ); transformedNormal /= vec3( dot( im[ 0 ], im[ 0 ] ), dot( im[ 1 ], im[ 1 ] ), dot( im[ 2 ], im[ 2 ] ) ); transformedNormal = im * transformedNormal; #ifdef USE_TANGENT transformedTangent = im * transformedTangent; #endif #endif transformedNormal = normalMatrix * transformedNormal; #ifdef FLIP_SIDED transformedNormal = - transformedNormal; #endif #ifdef USE_TANGENT transformedTangent = ( modelViewMatrix * vec4( transformedTangent, 0.0 ) ).xyz; #ifdef FLIP_SIDED transformedTangent = - transformedTangent; #endif #endif`,d9=`#ifdef USE_DISPLACEMENTMAP uniform sampler2D displacementMap; uniform float displacementScale; uniform float displacementBias; #endif`,h9=`#ifdef USE_DISPLACEMENTMAP transformed += normalize( objectNormal ) * ( texture2D( displacementMap, vDisplacementMapUv ).x * displacementScale + displacementBias ); #endif`,f9=`#ifdef USE_EMISSIVEMAP vec4 emissiveColor = texture2D( emissiveMap, vEmissiveMapUv ); #ifdef DECODE_VIDEO_TEXTURE_EMISSIVE emissiveColor = sRGBTransferEOTF( emissiveColor ); #endif totalEmissiveRadiance *= emissiveColor.rgb; #endif`,p9=`#ifdef USE_EMISSIVEMAP uniform sampler2D emissiveMap; #endif`,m9="gl_FragColor = linearToOutputTexel( gl_FragColor );",g9=`vec4 LinearTransferOETF( in vec4 value ) { return value; } vec4 sRGBTransferEOTF( in vec4 value ) { return vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a ); } vec4 sRGBTransferOETF( in vec4 value ) { return vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a ); }`,v9=`#ifdef USE_ENVMAP #ifdef ENV_WORLDPOS vec3 cameraToFrag; if ( isOrthographic ) { cameraToFrag = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) ); } else { cameraToFrag = normalize( vWorldPosition - cameraPosition ); } vec3 worldNormal = inverseTransformDirection( normal, viewMatrix ); #ifdef ENVMAP_MODE_REFLECTION vec3 reflectVec = reflect( cameraToFrag, worldNormal ); #else vec3 reflectVec = refract( cameraToFrag, worldNormal, refractionRatio ); #endif #else vec3 reflectVec = vReflect; #endif #ifdef ENVMAP_TYPE_CUBE vec4 envColor = textureCube( envMap, envMapRotation * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) ); #else vec4 envColor = vec4( 0.0 ); #endif #ifdef ENVMAP_BLENDING_MULTIPLY outgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity ); #elif defined( ENVMAP_BLENDING_MIX ) outgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity ); #elif defined( ENVMAP_BLENDING_ADD ) outgoingLight += envColor.xyz * specularStrength * reflectivity; #endif #endif`,x9=`#ifdef USE_ENVMAP uniform float envMapIntensity; uniform float flipEnvMap; uniform mat3 envMapRotation; #ifdef ENVMAP_TYPE_CUBE uniform samplerCube envMap; #else uniform sampler2D envMap; #endif #endif`,y9=`#ifdef USE_ENVMAP uniform float reflectivity; #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( LAMBERT ) #define ENV_WORLDPOS #endif #ifdef ENV_WORLDPOS varying vec3 vWorldPosition; uniform float refractionRatio; #else varying vec3 vReflect; #endif #endif`,b9=`#ifdef USE_ENVMAP #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( LAMBERT ) #define ENV_WORLDPOS #endif #ifdef ENV_WORLDPOS varying vec3 vWorldPosition; #else varying vec3 vReflect; uniform float refractionRatio; #endif #endif`,S9=`#ifdef USE_ENVMAP #ifdef ENV_WORLDPOS vWorldPosition = worldPosition.xyz; #else vec3 cameraToVertex; if ( isOrthographic ) { cameraToVertex = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) ); } else { cameraToVertex = normalize( worldPosition.xyz - cameraPosition ); } vec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix ); #ifdef ENVMAP_MODE_REFLECTION vReflect = reflect( cameraToVertex, worldNormal ); #else vReflect = refract( cameraToVertex, worldNormal, refractionRatio ); #endif #endif #endif`,A9=`#ifdef USE_FOG vFogDepth = - mvPosition.z; #endif`,E9=`#ifdef USE_FOG varying float vFogDepth; #endif`,w9=`#ifdef USE_FOG #ifdef FOG_EXP2 float fogFactor = 1.0 - exp( - fogDensity * fogDensity * vFogDepth * vFogDepth ); #else float fogFactor = smoothstep( fogNear, fogFar, vFogDepth ); #endif gl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor ); #endif`,M9=`#ifdef USE_FOG uniform vec3 fogColor; varying float vFogDepth; #ifdef FOG_EXP2 uniform float fogDensity; #else uniform float fogNear; uniform float fogFar; #endif #endif`,C9=`#ifdef USE_GRADIENTMAP uniform sampler2D gradientMap; #endif vec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) { float dotNL = dot( normal, lightDirection ); vec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 ); #ifdef USE_GRADIENTMAP return vec3( texture2D( gradientMap, coord ).r ); #else vec2 fw = fwidth( coord ) * 0.5; return mix( vec3( 0.7 ), vec3( 1.0 ), smoothstep( 0.7 - fw.x, 0.7 + fw.x, coord.x ) ); #endif }`,T9=`#ifdef USE_LIGHTMAP uniform sampler2D lightMap; uniform float lightMapIntensity; #endif`,j9=`LambertMaterial material; material.diffuseColor = diffuseColor.rgb; material.specularStrength = specularStrength;`,R9=`varying vec3 vViewPosition; struct LambertMaterial { vec3 diffuseColor; float specularStrength; }; void RE_Direct_Lambert( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in LambertMaterial material, inout ReflectedLight reflectedLight ) { float dotNL = saturate( dot( geometryNormal, directLight.direction ) ); vec3 irradiance = dotNL * directLight.color; reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor ); } void RE_IndirectDiffuse_Lambert( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in LambertMaterial material, inout ReflectedLight reflectedLight ) { reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor ); } #define RE_Direct RE_Direct_Lambert #define RE_IndirectDiffuse RE_IndirectDiffuse_Lambert`,k9=`uniform bool receiveShadow; uniform vec3 ambientLightColor; #if defined( USE_LIGHT_PROBES ) uniform vec3 lightProbe[ 9 ]; #endif vec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) { float x = normal.x, y = normal.y, z = normal.z; vec3 result = shCoefficients[ 0 ] * 0.886227; result += shCoefficients[ 1 ] * 2.0 * 0.511664 * y; result += shCoefficients[ 2 ] * 2.0 * 0.511664 * z; result += shCoefficients[ 3 ] * 2.0 * 0.511664 * x; result += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y; result += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z; result += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 ); result += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z; result += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y ); return result; } vec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in vec3 normal ) { vec3 worldNormal = inverseTransformDirection( normal, viewMatrix ); vec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe ); return irradiance; } vec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) { vec3 irradiance = ambientLightColor; return irradiance; } float getDistanceAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) { float distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 ); if ( cutoffDistance > 0.0 ) { distanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) ); } return distanceFalloff; } float getSpotAttenuation( const in float coneCosine, const in float penumbraCosine, const in float angleCosine ) { return smoothstep( coneCosine, penumbraCosine, angleCosine ); } #if NUM_DIR_LIGHTS > 0 struct DirectionalLight { vec3 direction; vec3 color; }; uniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ]; void getDirectionalLightInfo( const in DirectionalLight directionalLight, out IncidentLight light ) { light.color = directionalLight.color; light.direction = directionalLight.direction; light.visible = true; } #endif #if NUM_POINT_LIGHTS > 0 struct PointLight { vec3 position; vec3 color; float distance; float decay; }; uniform PointLight pointLights[ NUM_POINT_LIGHTS ]; void getPointLightInfo( const in PointLight pointLight, const in vec3 geometryPosition, out IncidentLight light ) { vec3 lVector = pointLight.position - geometryPosition; light.direction = normalize( lVector ); float lightDistance = length( lVector ); light.color = pointLight.color; light.color *= getDistanceAttenuation( lightDistance, pointLight.distance, pointLight.decay ); light.visible = ( light.color != vec3( 0.0 ) ); } #endif #if NUM_SPOT_LIGHTS > 0 struct SpotLight { vec3 position; vec3 direction; vec3 color; float distance; float decay; float coneCos; float penumbraCos; }; uniform SpotLight spotLights[ NUM_SPOT_LIGHTS ]; void getSpotLightInfo( const in SpotLight spotLight, const in vec3 geometryPosition, out IncidentLight light ) { vec3 lVector = spotLight.position - geometryPosition; light.direction = normalize( lVector ); float angleCos = dot( light.direction, spotLight.direction ); float spotAttenuation = getSpotAttenuation( spotLight.coneCos, spotLight.penumbraCos, angleCos ); if ( spotAttenuation > 0.0 ) { float lightDistance = length( lVector ); light.color = spotLight.color * spotAttenuation; light.color *= getDistanceAttenuation( lightDistance, spotLight.distance, spotLight.decay ); light.visible = ( light.color != vec3( 0.0 ) ); } else { light.color = vec3( 0.0 ); light.visible = false; } } #endif #if NUM_RECT_AREA_LIGHTS > 0 struct RectAreaLight { vec3 color; vec3 position; vec3 halfWidth; vec3 halfHeight; }; uniform sampler2D ltc_1; uniform sampler2D ltc_2; uniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ]; #endif #if NUM_HEMI_LIGHTS > 0 struct HemisphereLight { vec3 direction; vec3 skyColor; vec3 groundColor; }; uniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ]; vec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in vec3 normal ) { float dotNL = dot( normal, hemiLight.direction ); float hemiDiffuseWeight = 0.5 * dotNL + 0.5; vec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight ); return irradiance; } #endif`,N9=`#ifdef USE_ENVMAP vec3 getIBLIrradiance( const in vec3 normal ) { #ifdef ENVMAP_TYPE_CUBE_UV vec3 worldNormal = inverseTransformDirection( normal, viewMatrix ); vec4 envMapColor = textureCubeUV( envMap, envMapRotation * worldNormal, 1.0 ); return PI * envMapColor.rgb * envMapIntensity; #else return vec3( 0.0 ); #endif } vec3 getIBLRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness ) { #ifdef ENVMAP_TYPE_CUBE_UV vec3 reflectVec = reflect( - viewDir, normal ); reflectVec = normalize( mix( reflectVec, normal, roughness * roughness) ); reflectVec = inverseTransformDirection( reflectVec, viewMatrix ); vec4 envMapColor = textureCubeUV( envMap, envMapRotation * reflectVec, roughness ); return envMapColor.rgb * envMapIntensity; #else return vec3( 0.0 ); #endif } #ifdef USE_ANISOTROPY vec3 getIBLAnisotropyRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness, const in vec3 bitangent, const in float anisotropy ) { #ifdef ENVMAP_TYPE_CUBE_UV vec3 bentNormal = cross( bitangent, viewDir ); bentNormal = normalize( cross( bentNormal, bitangent ) ); bentNormal = normalize( mix( bentNormal, normal, pow2( pow2( 1.0 - anisotropy * ( 1.0 - roughness ) ) ) ) ); return getIBLRadiance( viewDir, bentNormal, roughness ); #else return vec3( 0.0 ); #endif } #endif #endif`,D9=`ToonMaterial material; material.diffuseColor = diffuseColor.rgb;`,z9=`varying vec3 vViewPosition; struct ToonMaterial { vec3 diffuseColor; }; void RE_Direct_Toon( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in ToonMaterial material, inout ReflectedLight reflectedLight ) { vec3 irradiance = getGradientIrradiance( geometryNormal, directLight.direction ) * directLight.color; reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor ); } void RE_IndirectDiffuse_Toon( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in ToonMaterial material, inout ReflectedLight reflectedLight ) { reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor ); } #define RE_Direct RE_Direct_Toon #define RE_IndirectDiffuse RE_IndirectDiffuse_Toon`,L9=`BlinnPhongMaterial material; material.diffuseColor = diffuseColor.rgb; material.specularColor = specular; material.specularShininess = shininess; material.specularStrength = specularStrength;`,O9=`varying vec3 vViewPosition; struct BlinnPhongMaterial { vec3 diffuseColor; vec3 specularColor; float specularShininess; float specularStrength; }; void RE_Direct_BlinnPhong( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) { float dotNL = saturate( dot( geometryNormal, directLight.direction ) ); vec3 irradiance = dotNL * directLight.color; reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor ); reflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometryViewDir, geometryNormal, material.specularColor, material.specularShininess ) * material.specularStrength; } void RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) { reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor ); } #define RE_Direct RE_Direct_BlinnPhong #define RE_IndirectDiffuse RE_IndirectDiffuse_BlinnPhong`,P9=`PhysicalMaterial material; material.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor ); vec3 dxy = max( abs( dFdx( nonPerturbedNormal ) ), abs( dFdy( nonPerturbedNormal ) ) ); float geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z ); material.roughness = max( roughnessFactor, 0.0525 );material.roughness += geometryRoughness; material.roughness = min( material.roughness, 1.0 ); #ifdef IOR material.ior = ior; #ifdef USE_SPECULAR float specularIntensityFactor = specularIntensity; vec3 specularColorFactor = specularColor; #ifdef USE_SPECULAR_COLORMAP specularColorFactor *= texture2D( specularColorMap, vSpecularColorMapUv ).rgb; #endif #ifdef USE_SPECULAR_INTENSITYMAP specularIntensityFactor *= texture2D( specularIntensityMap, vSpecularIntensityMapUv ).a; #endif material.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor ); #else float specularIntensityFactor = 1.0; vec3 specularColorFactor = vec3( 1.0 ); material.specularF90 = 1.0; #endif material.specularColor = mix( min( pow2( ( material.ior - 1.0 ) / ( material.ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor, diffuseColor.rgb, metalnessFactor ); #else material.specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor ); material.specularF90 = 1.0; #endif #ifdef USE_CLEARCOAT material.clearcoat = clearcoat; material.clearcoatRoughness = clearcoatRoughness; material.clearcoatF0 = vec3( 0.04 ); material.clearcoatF90 = 1.0; #ifdef USE_CLEARCOATMAP material.clearcoat *= texture2D( clearcoatMap, vClearcoatMapUv ).x; #endif #ifdef USE_CLEARCOAT_ROUGHNESSMAP material.clearcoatRoughness *= texture2D( clearcoatRoughnessMap, vClearcoatRoughnessMapUv ).y; #endif material.clearcoat = saturate( material.clearcoat ); material.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 ); material.clearcoatRoughness += geometryRoughness; material.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 ); #endif #ifdef USE_DISPERSION material.dispersion = dispersion; #endif #ifdef USE_IRIDESCENCE material.iridescence = iridescence; material.iridescenceIOR = iridescenceIOR; #ifdef USE_IRIDESCENCEMAP material.iridescence *= texture2D( iridescenceMap, vIridescenceMapUv ).r; #endif #ifdef USE_IRIDESCENCE_THICKNESSMAP material.iridescenceThickness = (iridescenceThicknessMaximum - iridescenceThicknessMinimum) * texture2D( iridescenceThicknessMap, vIridescenceThicknessMapUv ).g + iridescenceThicknessMinimum; #else material.iridescenceThickness = iridescenceThicknessMaximum; #endif #endif #ifdef USE_SHEEN material.sheenColor = sheenColor; #ifdef USE_SHEEN_COLORMAP material.sheenColor *= texture2D( sheenColorMap, vSheenColorMapUv ).rgb; #endif material.sheenRoughness = clamp( sheenRoughness, 0.07, 1.0 ); #ifdef USE_SHEEN_ROUGHNESSMAP material.sheenRoughness *= texture2D( sheenRoughnessMap, vSheenRoughnessMapUv ).a; #endif #endif #ifdef USE_ANISOTROPY #ifdef USE_ANISOTROPYMAP mat2 anisotropyMat = mat2( anisotropyVector.x, anisotropyVector.y, - anisotropyVector.y, anisotropyVector.x ); vec3 anisotropyPolar = texture2D( anisotropyMap, vAnisotropyMapUv ).rgb; vec2 anisotropyV = anisotropyMat * normalize( 2.0 * anisotropyPolar.rg - vec2( 1.0 ) ) * anisotropyPolar.b; #else vec2 anisotropyV = anisotropyVector; #endif material.anisotropy = length( anisotropyV ); if( material.anisotropy == 0.0 ) { anisotropyV = vec2( 1.0, 0.0 ); } else { anisotropyV /= material.anisotropy; material.anisotropy = saturate( material.anisotropy ); } material.alphaT = mix( pow2( material.roughness ), 1.0, pow2( material.anisotropy ) ); material.anisotropyT = tbn[ 0 ] * anisotropyV.x + tbn[ 1 ] * anisotropyV.y; material.anisotropyB = tbn[ 1 ] * anisotropyV.x - tbn[ 0 ] * anisotropyV.y; #endif`,I9=`struct PhysicalMaterial { vec3 diffuseColor; float roughness; vec3 specularColor; float specularF90; float dispersion; #ifdef USE_CLEARCOAT float clearcoat; float clearcoatRoughness; vec3 clearcoatF0; float clearcoatF90; #endif #ifdef USE_IRIDESCENCE float iridescence; float iridescenceIOR; float iridescenceThickness; vec3 iridescenceFresnel; vec3 iridescenceF0; #endif #ifdef USE_SHEEN vec3 sheenColor; float sheenRoughness; #endif #ifdef IOR float ior; #endif #ifdef USE_TRANSMISSION float transmission; float transmissionAlpha; float thickness; float attenuationDistance; vec3 attenuationColor; #endif #ifdef USE_ANISOTROPY float anisotropy; float alphaT; vec3 anisotropyT; vec3 anisotropyB; #endif }; vec3 clearcoatSpecularDirect = vec3( 0.0 ); vec3 clearcoatSpecularIndirect = vec3( 0.0 ); vec3 sheenSpecularDirect = vec3( 0.0 ); vec3 sheenSpecularIndirect = vec3(0.0 ); vec3 Schlick_to_F0( const in vec3 f, const in float f90, const in float dotVH ) { float x = clamp( 1.0 - dotVH, 0.0, 1.0 ); float x2 = x * x; float x5 = clamp( x * x2 * x2, 0.0, 0.9999 ); return ( f - vec3( f90 ) * x5 ) / ( 1.0 - x5 ); } float V_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) { float a2 = pow2( alpha ); float gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) ); float gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) ); return 0.5 / max( gv + gl, EPSILON ); } float D_GGX( const in float alpha, const in float dotNH ) { float a2 = pow2( alpha ); float denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0; return RECIPROCAL_PI * a2 / pow2( denom ); } #ifdef USE_ANISOTROPY float V_GGX_SmithCorrelated_Anisotropic( const in float alphaT, const in float alphaB, const in float dotTV, const in float dotBV, const in float dotTL, const in float dotBL, const in float dotNV, const in float dotNL ) { float gv = dotNL * length( vec3( alphaT * dotTV, alphaB * dotBV, dotNV ) ); float gl = dotNV * length( vec3( alphaT * dotTL, alphaB * dotBL, dotNL ) ); float v = 0.5 / ( gv + gl ); return saturate(v); } float D_GGX_Anisotropic( const in float alphaT, const in float alphaB, const in float dotNH, const in float dotTH, const in float dotBH ) { float a2 = alphaT * alphaB; highp vec3 v = vec3( alphaB * dotTH, alphaT * dotBH, a2 * dotNH ); highp float v2 = dot( v, v ); float w2 = a2 / v2; return RECIPROCAL_PI * a2 * pow2 ( w2 ); } #endif #ifdef USE_CLEARCOAT vec3 BRDF_GGX_Clearcoat( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material) { vec3 f0 = material.clearcoatF0; float f90 = material.clearcoatF90; float roughness = material.clearcoatRoughness; float alpha = pow2( roughness ); vec3 halfDir = normalize( lightDir + viewDir ); float dotNL = saturate( dot( normal, lightDir ) ); float dotNV = saturate( dot( normal, viewDir ) ); float dotNH = saturate( dot( normal, halfDir ) ); float dotVH = saturate( dot( viewDir, halfDir ) ); vec3 F = F_Schlick( f0, f90, dotVH ); float V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV ); float D = D_GGX( alpha, dotNH ); return F * ( V * D ); } #endif vec3 BRDF_GGX( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material ) { vec3 f0 = material.specularColor; float f90 = material.specularF90; float roughness = material.roughness; float alpha = pow2( roughness ); vec3 halfDir = normalize( lightDir + viewDir ); float dotNL = saturate( dot( normal, lightDir ) ); float dotNV = saturate( dot( normal, viewDir ) ); float dotNH = saturate( dot( normal, halfDir ) ); float dotVH = saturate( dot( viewDir, halfDir ) ); vec3 F = F_Schlick( f0, f90, dotVH ); #ifdef USE_IRIDESCENCE F = mix( F, material.iridescenceFresnel, material.iridescence ); #endif #ifdef USE_ANISOTROPY float dotTL = dot( material.anisotropyT, lightDir ); float dotTV = dot( material.anisotropyT, viewDir ); float dotTH = dot( material.anisotropyT, halfDir ); float dotBL = dot( material.anisotropyB, lightDir ); float dotBV = dot( material.anisotropyB, viewDir ); float dotBH = dot( material.anisotropyB, halfDir ); float V = V_GGX_SmithCorrelated_Anisotropic( material.alphaT, alpha, dotTV, dotBV, dotTL, dotBL, dotNV, dotNL ); float D = D_GGX_Anisotropic( material.alphaT, alpha, dotNH, dotTH, dotBH ); #else float V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV ); float D = D_GGX( alpha, dotNH ); #endif return F * ( V * D ); } vec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) { const float LUT_SIZE = 64.0; const float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE; const float LUT_BIAS = 0.5 / LUT_SIZE; float dotNV = saturate( dot( N, V ) ); vec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) ); uv = uv * LUT_SCALE + LUT_BIAS; return uv; } float LTC_ClippedSphereFormFactor( const in vec3 f ) { float l = length( f ); return max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 ); } vec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) { float x = dot( v1, v2 ); float y = abs( x ); float a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y; float b = 3.4175940 + ( 4.1616724 + y ) * y; float v = a / b; float theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v; return cross( v1, v2 ) * theta_sintheta; } vec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) { vec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ]; vec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ]; vec3 lightNormal = cross( v1, v2 ); if( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 ); vec3 T1, T2; T1 = normalize( V - N * dot( V, N ) ); T2 = - cross( N, T1 ); mat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) ); vec3 coords[ 4 ]; coords[ 0 ] = mat * ( rectCoords[ 0 ] - P ); coords[ 1 ] = mat * ( rectCoords[ 1 ] - P ); coords[ 2 ] = mat * ( rectCoords[ 2 ] - P ); coords[ 3 ] = mat * ( rectCoords[ 3 ] - P ); coords[ 0 ] = normalize( coords[ 0 ] ); coords[ 1 ] = normalize( coords[ 1 ] ); coords[ 2 ] = normalize( coords[ 2 ] ); coords[ 3 ] = normalize( coords[ 3 ] ); vec3 vectorFormFactor = vec3( 0.0 ); vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] ); vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] ); vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] ); vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] ); float result = LTC_ClippedSphereFormFactor( vectorFormFactor ); return vec3( result ); } #if defined( USE_SHEEN ) float D_Charlie( float roughness, float dotNH ) { float alpha = pow2( roughness ); float invAlpha = 1.0 / alpha; float cos2h = dotNH * dotNH; float sin2h = max( 1.0 - cos2h, 0.0078125 ); return ( 2.0 + invAlpha ) * pow( sin2h, invAlpha * 0.5 ) / ( 2.0 * PI ); } float V_Neubelt( float dotNV, float dotNL ) { return saturate( 1.0 / ( 4.0 * ( dotNL + dotNV - dotNL * dotNV ) ) ); } vec3 BRDF_Sheen( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, vec3 sheenColor, const in float sheenRoughness ) { vec3 halfDir = normalize( lightDir + viewDir ); float dotNL = saturate( dot( normal, lightDir ) ); float dotNV = saturate( dot( normal, viewDir ) ); float dotNH = saturate( dot( normal, halfDir ) ); float D = D_Charlie( sheenRoughness, dotNH ); float V = V_Neubelt( dotNV, dotNL ); return sheenColor * ( D * V ); } #endif float IBLSheenBRDF( const in vec3 normal, const in vec3 viewDir, const in float roughness ) { float dotNV = saturate( dot( normal, viewDir ) ); float r2 = roughness * roughness; float a = roughness < 0.25 ? -339.2 * r2 + 161.4 * roughness - 25.9 : -8.48 * r2 + 14.3 * roughness - 9.95; float b = roughness < 0.25 ? 44.0 * r2 - 23.7 * roughness + 3.26 : 1.97 * r2 - 3.27 * roughness + 0.72; float DG = exp( a * dotNV + b ) + ( roughness < 0.25 ? 0.0 : 0.1 * ( roughness - 0.25 ) ); return saturate( DG * RECIPROCAL_PI ); } vec2 DFGApprox( const in vec3 normal, const in vec3 viewDir, const in float roughness ) { float dotNV = saturate( dot( normal, viewDir ) ); const vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 ); const vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 ); vec4 r = roughness * c0 + c1; float a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y; vec2 fab = vec2( - 1.04, 1.04 ) * a004 + r.zw; return fab; } vec3 EnvironmentBRDF( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness ) { vec2 fab = DFGApprox( normal, viewDir, roughness ); return specularColor * fab.x + specularF90 * fab.y; } #ifdef USE_IRIDESCENCE void computeMultiscatteringIridescence( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float iridescence, const in vec3 iridescenceF0, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) { #else void computeMultiscattering( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) { #endif vec2 fab = DFGApprox( normal, viewDir, roughness ); #ifdef USE_IRIDESCENCE vec3 Fr = mix( specularColor, iridescenceF0, iridescence ); #else vec3 Fr = specularColor; #endif vec3 FssEss = Fr * fab.x + specularF90 * fab.y; float Ess = fab.x + fab.y; float Ems = 1.0 - Ess; vec3 Favg = Fr + ( 1.0 - Fr ) * 0.047619; vec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg ); singleScatter += FssEss; multiScatter += Fms * Ems; } #if NUM_RECT_AREA_LIGHTS > 0 void RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) { vec3 normal = geometryNormal; vec3 viewDir = geometryViewDir; vec3 position = geometryPosition; vec3 lightPos = rectAreaLight.position; vec3 halfWidth = rectAreaLight.halfWidth; vec3 halfHeight = rectAreaLight.halfHeight; vec3 lightColor = rectAreaLight.color; float roughness = material.roughness; vec3 rectCoords[ 4 ]; rectCoords[ 0 ] = lightPos + halfWidth - halfHeight; rectCoords[ 1 ] = lightPos - halfWidth - halfHeight; rectCoords[ 2 ] = lightPos - halfWidth + halfHeight; rectCoords[ 3 ] = lightPos + halfWidth + halfHeight; vec2 uv = LTC_Uv( normal, viewDir, roughness ); vec4 t1 = texture2D( ltc_1, uv ); vec4 t2 = texture2D( ltc_2, uv ); mat3 mInv = mat3( vec3( t1.x, 0, t1.y ), vec3( 0, 1, 0 ), vec3( t1.z, 0, t1.w ) ); vec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y ); reflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords ); reflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords ); } #endif void RE_Direct_Physical( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) { float dotNL = saturate( dot( geometryNormal, directLight.direction ) ); vec3 irradiance = dotNL * directLight.color; #ifdef USE_CLEARCOAT float dotNLcc = saturate( dot( geometryClearcoatNormal, directLight.direction ) ); vec3 ccIrradiance = dotNLcc * directLight.color; clearcoatSpecularDirect += ccIrradiance * BRDF_GGX_Clearcoat( directLight.direction, geometryViewDir, geometryClearcoatNormal, material ); #endif #ifdef USE_SHEEN sheenSpecularDirect += irradiance * BRDF_Sheen( directLight.direction, geometryViewDir, geometryNormal, material.sheenColor, material.sheenRoughness ); #endif reflectedLight.directSpecular += irradiance * BRDF_GGX( directLight.direction, geometryViewDir, geometryNormal, material ); reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor ); } void RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) { reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor ); } void RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) { #ifdef USE_CLEARCOAT clearcoatSpecularIndirect += clearcoatRadiance * EnvironmentBRDF( geometryClearcoatNormal, geometryViewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness ); #endif #ifdef USE_SHEEN sheenSpecularIndirect += irradiance * material.sheenColor * IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness ); #endif vec3 singleScattering = vec3( 0.0 ); vec3 multiScattering = vec3( 0.0 ); vec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI; #ifdef USE_IRIDESCENCE computeMultiscatteringIridescence( geometryNormal, geometryViewDir, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness, singleScattering, multiScattering ); #else computeMultiscattering( geometryNormal, geometryViewDir, material.specularColor, material.specularF90, material.roughness, singleScattering, multiScattering ); #endif vec3 totalScattering = singleScattering + multiScattering; vec3 diffuse = material.diffuseColor * ( 1.0 - max( max( totalScattering.r, totalScattering.g ), totalScattering.b ) ); reflectedLight.indirectSpecular += radiance * singleScattering; reflectedLight.indirectSpecular += multiScattering * cosineWeightedIrradiance; reflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance; } #define RE_Direct RE_Direct_Physical #define RE_Direct_RectArea RE_Direct_RectArea_Physical #define RE_IndirectDiffuse RE_IndirectDiffuse_Physical #define RE_IndirectSpecular RE_IndirectSpecular_Physical float computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) { return saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion ); }`,U9=` vec3 geometryPosition = - vViewPosition; vec3 geometryNormal = normal; vec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition ); vec3 geometryClearcoatNormal = vec3( 0.0 ); #ifdef USE_CLEARCOAT geometryClearcoatNormal = clearcoatNormal; #endif #ifdef USE_IRIDESCENCE float dotNVi = saturate( dot( normal, geometryViewDir ) ); if ( material.iridescenceThickness == 0.0 ) { material.iridescence = 0.0; } else { material.iridescence = saturate( material.iridescence ); } if ( material.iridescence > 0.0 ) { material.iridescenceFresnel = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor ); material.iridescenceF0 = Schlick_to_F0( material.iridescenceFresnel, 1.0, dotNVi ); } #endif IncidentLight directLight; #if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct ) PointLight pointLight; #if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0 PointLightShadow pointLightShadow; #endif #pragma unroll_loop_start for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) { pointLight = pointLights[ i ]; getPointLightInfo( pointLight, geometryPosition, directLight ); #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS ) pointLightShadow = pointLightShadows[ i ]; directLight.color *= ( directLight.visible && receiveShadow ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowIntensity, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0; #endif RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight ); } #pragma unroll_loop_end #endif #if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct ) SpotLight spotLight; vec4 spotColor; vec3 spotLightCoord; bool inSpotLightMap; #if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0 SpotLightShadow spotLightShadow; #endif #pragma unroll_loop_start for ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) { spotLight = spotLights[ i ]; getSpotLightInfo( spotLight, geometryPosition, directLight ); #if ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS ) #define SPOT_LIGHT_MAP_INDEX UNROLLED_LOOP_INDEX #elif ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS ) #define SPOT_LIGHT_MAP_INDEX NUM_SPOT_LIGHT_MAPS #else #define SPOT_LIGHT_MAP_INDEX ( UNROLLED_LOOP_INDEX - NUM_SPOT_LIGHT_SHADOWS + NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS ) #endif #if ( SPOT_LIGHT_MAP_INDEX < NUM_SPOT_LIGHT_MAPS ) spotLightCoord = vSpotLightCoord[ i ].xyz / vSpotLightCoord[ i ].w; inSpotLightMap = all( lessThan( abs( spotLightCoord * 2. - 1. ), vec3( 1.0 ) ) ); spotColor = texture2D( spotLightMap[ SPOT_LIGHT_MAP_INDEX ], spotLightCoord.xy ); directLight.color = inSpotLightMap ? directLight.color * spotColor.rgb : directLight.color; #endif #undef SPOT_LIGHT_MAP_INDEX #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS ) spotLightShadow = spotLightShadows[ i ]; directLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowIntensity, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotLightCoord[ i ] ) : 1.0; #endif RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight ); } #pragma unroll_loop_end #endif #if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct ) DirectionalLight directionalLight; #if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0 DirectionalLightShadow directionalLightShadow; #endif #pragma unroll_loop_start for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) { directionalLight = directionalLights[ i ]; getDirectionalLightInfo( directionalLight, directLight ); #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS ) directionalLightShadow = directionalLightShadows[ i ]; directLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowIntensity, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0; #endif RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight ); } #pragma unroll_loop_end #endif #if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea ) RectAreaLight rectAreaLight; #pragma unroll_loop_start for ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) { rectAreaLight = rectAreaLights[ i ]; RE_Direct_RectArea( rectAreaLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight ); } #pragma unroll_loop_end #endif #if defined( RE_IndirectDiffuse ) vec3 iblIrradiance = vec3( 0.0 ); vec3 irradiance = getAmbientLightIrradiance( ambientLightColor ); #if defined( USE_LIGHT_PROBES ) irradiance += getLightProbeIrradiance( lightProbe, geometryNormal ); #endif #if ( NUM_HEMI_LIGHTS > 0 ) #pragma unroll_loop_start for ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) { irradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometryNormal ); } #pragma unroll_loop_end #endif #endif #if defined( RE_IndirectSpecular ) vec3 radiance = vec3( 0.0 ); vec3 clearcoatRadiance = vec3( 0.0 ); #endif`,F9=`#if defined( RE_IndirectDiffuse ) #ifdef USE_LIGHTMAP vec4 lightMapTexel = texture2D( lightMap, vLightMapUv ); vec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity; irradiance += lightMapIrradiance; #endif #if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV ) iblIrradiance += getIBLIrradiance( geometryNormal ); #endif #endif #if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular ) #ifdef USE_ANISOTROPY radiance += getIBLAnisotropyRadiance( geometryViewDir, geometryNormal, material.roughness, material.anisotropyB, material.anisotropy ); #else radiance += getIBLRadiance( geometryViewDir, geometryNormal, material.roughness ); #endif #ifdef USE_CLEARCOAT clearcoatRadiance += getIBLRadiance( geometryViewDir, geometryClearcoatNormal, material.clearcoatRoughness ); #endif #endif`,B9=`#if defined( RE_IndirectDiffuse ) RE_IndirectDiffuse( irradiance, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight ); #endif #if defined( RE_IndirectSpecular ) RE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight ); #endif`,H9=`#if defined( USE_LOGARITHMIC_DEPTH_BUFFER ) gl_FragDepth = vIsPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5; #endif`,G9=`#if defined( USE_LOGARITHMIC_DEPTH_BUFFER ) uniform float logDepthBufFC; varying float vFragDepth; varying float vIsPerspective; #endif`,V9=`#ifdef USE_LOGARITHMIC_DEPTH_BUFFER varying float vFragDepth; varying float vIsPerspective; #endif`,q9=`#ifdef USE_LOGARITHMIC_DEPTH_BUFFER vFragDepth = 1.0 + gl_Position.w; vIsPerspective = float( isPerspectiveMatrix( projectionMatrix ) ); #endif`,W9=`#ifdef USE_MAP vec4 sampledDiffuseColor = texture2D( map, vMapUv ); #ifdef DECODE_VIDEO_TEXTURE sampledDiffuseColor = sRGBTransferEOTF( sampledDiffuseColor ); #endif diffuseColor *= sampledDiffuseColor; #endif`,Y9=`#ifdef USE_MAP uniform sampler2D map; #endif`,X9=`#if defined( USE_MAP ) || defined( USE_ALPHAMAP ) #if defined( USE_POINTS_UV ) vec2 uv = vUv; #else vec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy; #endif #endif #ifdef USE_MAP diffuseColor *= texture2D( map, uv ); #endif #ifdef USE_ALPHAMAP diffuseColor.a *= texture2D( alphaMap, uv ).g; #endif`,K9=`#if defined( USE_POINTS_UV ) varying vec2 vUv; #else #if defined( USE_MAP ) || defined( USE_ALPHAMAP ) uniform mat3 uvTransform; #endif #endif #ifdef USE_MAP uniform sampler2D map; #endif #ifdef USE_ALPHAMAP uniform sampler2D alphaMap; #endif`,J9=`float metalnessFactor = metalness; #ifdef USE_METALNESSMAP vec4 texelMetalness = texture2D( metalnessMap, vMetalnessMapUv ); metalnessFactor *= texelMetalness.b; #endif`,Z9=`#ifdef USE_METALNESSMAP uniform sampler2D metalnessMap; #endif`,Q9=`#ifdef USE_INSTANCING_MORPH float morphTargetInfluences[ MORPHTARGETS_COUNT ]; float morphTargetBaseInfluence = texelFetch( morphTexture, ivec2( 0, gl_InstanceID ), 0 ).r; for ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) { morphTargetInfluences[i] = texelFetch( morphTexture, ivec2( i + 1, gl_InstanceID ), 0 ).r; } #endif`,_9=`#if defined( USE_MORPHCOLORS ) vColor *= morphTargetBaseInfluence; for ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) { #if defined( USE_COLOR_ALPHA ) if ( morphTargetInfluences[ i ] != 0.0 ) vColor += getMorph( gl_VertexID, i, 2 ) * morphTargetInfluences[ i ]; #elif defined( USE_COLOR ) if ( morphTargetInfluences[ i ] != 0.0 ) vColor += getMorph( gl_VertexID, i, 2 ).rgb * morphTargetInfluences[ i ]; #endif } #endif`,$9=`#ifdef USE_MORPHNORMALS objectNormal *= morphTargetBaseInfluence; for ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) { if ( morphTargetInfluences[ i ] != 0.0 ) objectNormal += getMorph( gl_VertexID, i, 1 ).xyz * morphTargetInfluences[ i ]; } #endif`,eG=`#ifdef USE_MORPHTARGETS #ifndef USE_INSTANCING_MORPH uniform float morphTargetBaseInfluence; uniform float morphTargetInfluences[ MORPHTARGETS_COUNT ]; #endif uniform sampler2DArray morphTargetsTexture; uniform ivec2 morphTargetsTextureSize; vec4 getMorph( const in int vertexIndex, const in int morphTargetIndex, const in int offset ) { int texelIndex = vertexIndex * MORPHTARGETS_TEXTURE_STRIDE + offset; int y = texelIndex / morphTargetsTextureSize.x; int x = texelIndex - y * morphTargetsTextureSize.x; ivec3 morphUV = ivec3( x, y, morphTargetIndex ); return texelFetch( morphTargetsTexture, morphUV, 0 ); } #endif`,tG=`#ifdef USE_MORPHTARGETS transformed *= morphTargetBaseInfluence; for ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) { if ( morphTargetInfluences[ i ] != 0.0 ) transformed += getMorph( gl_VertexID, i, 0 ).xyz * morphTargetInfluences[ i ]; } #endif`,nG=`float faceDirection = gl_FrontFacing ? 1.0 : - 1.0; #ifdef FLAT_SHADED vec3 fdx = dFdx( vViewPosition ); vec3 fdy = dFdy( vViewPosition ); vec3 normal = normalize( cross( fdx, fdy ) ); #else vec3 normal = normalize( vNormal ); #ifdef DOUBLE_SIDED normal *= faceDirection; #endif #endif #if defined( USE_NORMALMAP_TANGENTSPACE ) || defined( USE_CLEARCOAT_NORMALMAP ) || defined( USE_ANISOTROPY ) #ifdef USE_TANGENT mat3 tbn = mat3( normalize( vTangent ), normalize( vBitangent ), normal ); #else mat3 tbn = getTangentFrame( - vViewPosition, normal, #if defined( USE_NORMALMAP ) vNormalMapUv #elif defined( USE_CLEARCOAT_NORMALMAP ) vClearcoatNormalMapUv #else vUv #endif ); #endif #if defined( DOUBLE_SIDED ) && ! defined( FLAT_SHADED ) tbn[0] *= faceDirection; tbn[1] *= faceDirection; #endif #endif #ifdef USE_CLEARCOAT_NORMALMAP #ifdef USE_TANGENT mat3 tbn2 = mat3( normalize( vTangent ), normalize( vBitangent ), normal ); #else mat3 tbn2 = getTangentFrame( - vViewPosition, normal, vClearcoatNormalMapUv ); #endif #if defined( DOUBLE_SIDED ) && ! defined( FLAT_SHADED ) tbn2[0] *= faceDirection; tbn2[1] *= faceDirection; #endif #endif vec3 nonPerturbedNormal = normal;`,aG=`#ifdef USE_NORMALMAP_OBJECTSPACE normal = texture2D( normalMap, vNormalMapUv ).xyz * 2.0 - 1.0; #ifdef FLIP_SIDED normal = - normal; #endif #ifdef DOUBLE_SIDED normal = normal * faceDirection; #endif normal = normalize( normalMatrix * normal ); #elif defined( USE_NORMALMAP_TANGENTSPACE ) vec3 mapN = texture2D( normalMap, vNormalMapUv ).xyz * 2.0 - 1.0; mapN.xy *= normalScale; normal = normalize( tbn * mapN ); #elif defined( USE_BUMPMAP ) normal = perturbNormalArb( - vViewPosition, normal, dHdxy_fwd(), faceDirection ); #endif`,iG=`#ifndef FLAT_SHADED varying vec3 vNormal; #ifdef USE_TANGENT varying vec3 vTangent; varying vec3 vBitangent; #endif #endif`,sG=`#ifndef FLAT_SHADED varying vec3 vNormal; #ifdef USE_TANGENT varying vec3 vTangent; varying vec3 vBitangent; #endif #endif`,rG=`#ifndef FLAT_SHADED vNormal = normalize( transformedNormal ); #ifdef USE_TANGENT vTangent = normalize( transformedTangent ); vBitangent = normalize( cross( vNormal, vTangent ) * tangent.w ); #endif #endif`,oG=`#ifdef USE_NORMALMAP uniform sampler2D normalMap; uniform vec2 normalScale; #endif #ifdef USE_NORMALMAP_OBJECTSPACE uniform mat3 normalMatrix; #endif #if ! defined ( USE_TANGENT ) && ( defined ( USE_NORMALMAP_TANGENTSPACE ) || defined ( USE_CLEARCOAT_NORMALMAP ) || defined( USE_ANISOTROPY ) ) mat3 getTangentFrame( vec3 eye_pos, vec3 surf_norm, vec2 uv ) { vec3 q0 = dFdx( eye_pos.xyz ); vec3 q1 = dFdy( eye_pos.xyz ); vec2 st0 = dFdx( uv.st ); vec2 st1 = dFdy( uv.st ); vec3 N = surf_norm; vec3 q1perp = cross( q1, N ); vec3 q0perp = cross( N, q0 ); vec3 T = q1perp * st0.x + q0perp * st1.x; vec3 B = q1perp * st0.y + q0perp * st1.y; float det = max( dot( T, T ), dot( B, B ) ); float scale = ( det == 0.0 ) ? 0.0 : inversesqrt( det ); return mat3( T * scale, B * scale, N ); } #endif`,lG=`#ifdef USE_CLEARCOAT vec3 clearcoatNormal = nonPerturbedNormal; #endif`,cG=`#ifdef USE_CLEARCOAT_NORMALMAP vec3 clearcoatMapN = texture2D( clearcoatNormalMap, vClearcoatNormalMapUv ).xyz * 2.0 - 1.0; clearcoatMapN.xy *= clearcoatNormalScale; clearcoatNormal = normalize( tbn2 * clearcoatMapN ); #endif`,uG=`#ifdef USE_CLEARCOATMAP uniform sampler2D clearcoatMap; #endif #ifdef USE_CLEARCOAT_NORMALMAP uniform sampler2D clearcoatNormalMap; uniform vec2 clearcoatNormalScale; #endif #ifdef USE_CLEARCOAT_ROUGHNESSMAP uniform sampler2D clearcoatRoughnessMap; #endif`,dG=`#ifdef USE_IRIDESCENCEMAP uniform sampler2D iridescenceMap; #endif #ifdef USE_IRIDESCENCE_THICKNESSMAP uniform sampler2D iridescenceThicknessMap; #endif`,hG=`#ifdef OPAQUE diffuseColor.a = 1.0; #endif #ifdef USE_TRANSMISSION diffuseColor.a *= material.transmissionAlpha; #endif gl_FragColor = vec4( outgoingLight, diffuseColor.a );`,fG=`vec3 packNormalToRGB( const in vec3 normal ) { return normalize( normal ) * 0.5 + 0.5; } vec3 unpackRGBToNormal( const in vec3 rgb ) { return 2.0 * rgb.xyz - 1.0; } const float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;const float ShiftRight8 = 1. / 256.; const float Inv255 = 1. / 255.; const vec4 PackFactors = vec4( 1.0, 256.0, 256.0 * 256.0, 256.0 * 256.0 * 256.0 ); const vec2 UnpackFactors2 = vec2( UnpackDownscale, 1.0 / PackFactors.g ); const vec3 UnpackFactors3 = vec3( UnpackDownscale / PackFactors.rg, 1.0 / PackFactors.b ); const vec4 UnpackFactors4 = vec4( UnpackDownscale / PackFactors.rgb, 1.0 / PackFactors.a ); vec4 packDepthToRGBA( const in float v ) { if( v <= 0.0 ) return vec4( 0., 0., 0., 0. ); if( v >= 1.0 ) return vec4( 1., 1., 1., 1. ); float vuf; float af = modf( v * PackFactors.a, vuf ); float bf = modf( vuf * ShiftRight8, vuf ); float gf = modf( vuf * ShiftRight8, vuf ); return vec4( vuf * Inv255, gf * PackUpscale, bf * PackUpscale, af ); } vec3 packDepthToRGB( const in float v ) { if( v <= 0.0 ) return vec3( 0., 0., 0. ); if( v >= 1.0 ) return vec3( 1., 1., 1. ); float vuf; float bf = modf( v * PackFactors.b, vuf ); float gf = modf( vuf * ShiftRight8, vuf ); return vec3( vuf * Inv255, gf * PackUpscale, bf ); } vec2 packDepthToRG( const in float v ) { if( v <= 0.0 ) return vec2( 0., 0. ); if( v >= 1.0 ) return vec2( 1., 1. ); float vuf; float gf = modf( v * 256., vuf ); return vec2( vuf * Inv255, gf ); } float unpackRGBAToDepth( const in vec4 v ) { return dot( v, UnpackFactors4 ); } float unpackRGBToDepth( const in vec3 v ) { return dot( v, UnpackFactors3 ); } float unpackRGToDepth( const in vec2 v ) { return v.r * UnpackFactors2.r + v.g * UnpackFactors2.g; } vec4 pack2HalfToRGBA( const in vec2 v ) { vec4 r = vec4( v.x, fract( v.x * 255.0 ), v.y, fract( v.y * 255.0 ) ); return vec4( r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w ); } vec2 unpackRGBATo2Half( const in vec4 v ) { return vec2( v.x + ( v.y / 255.0 ), v.z + ( v.w / 255.0 ) ); } float viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) { return ( viewZ + near ) / ( near - far ); } float orthographicDepthToViewZ( const in float depth, const in float near, const in float far ) { return depth * ( near - far ) - near; } float viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) { return ( ( near + viewZ ) * far ) / ( ( far - near ) * viewZ ); } float perspectiveDepthToViewZ( const in float depth, const in float near, const in float far ) { return ( near * far ) / ( ( far - near ) * depth - far ); }`,pG=`#ifdef PREMULTIPLIED_ALPHA gl_FragColor.rgb *= gl_FragColor.a; #endif`,mG=`vec4 mvPosition = vec4( transformed, 1.0 ); #ifdef USE_BATCHING mvPosition = batchingMatrix * mvPosition; #endif #ifdef USE_INSTANCING mvPosition = instanceMatrix * mvPosition; #endif mvPosition = modelViewMatrix * mvPosition; gl_Position = projectionMatrix * mvPosition;`,gG=`#ifdef DITHERING gl_FragColor.rgb = dithering( gl_FragColor.rgb ); #endif`,vG=`#ifdef DITHERING vec3 dithering( vec3 color ) { float grid_position = rand( gl_FragCoord.xy ); vec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 ); dither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position ); return color + dither_shift_RGB; } #endif`,xG=`float roughnessFactor = roughness; #ifdef USE_ROUGHNESSMAP vec4 texelRoughness = texture2D( roughnessMap, vRoughnessMapUv ); roughnessFactor *= texelRoughness.g; #endif`,yG=`#ifdef USE_ROUGHNESSMAP uniform sampler2D roughnessMap; #endif`,bG=`#if NUM_SPOT_LIGHT_COORDS > 0 varying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ]; #endif #if NUM_SPOT_LIGHT_MAPS > 0 uniform sampler2D spotLightMap[ NUM_SPOT_LIGHT_MAPS ]; #endif #ifdef USE_SHADOWMAP #if NUM_DIR_LIGHT_SHADOWS > 0 uniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ]; varying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ]; struct DirectionalLightShadow { float shadowIntensity; float shadowBias; float shadowNormalBias; float shadowRadius; vec2 shadowMapSize; }; uniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ]; #endif #if NUM_SPOT_LIGHT_SHADOWS > 0 uniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ]; struct SpotLightShadow { float shadowIntensity; float shadowBias; float shadowNormalBias; float shadowRadius; vec2 shadowMapSize; }; uniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ]; #endif #if NUM_POINT_LIGHT_SHADOWS > 0 uniform sampler2D pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ]; varying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ]; struct PointLightShadow { float shadowIntensity; float shadowBias; float shadowNormalBias; float shadowRadius; vec2 shadowMapSize; float shadowCameraNear; float shadowCameraFar; }; uniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ]; #endif float texture2DCompare( sampler2D depths, vec2 uv, float compare ) { float depth = unpackRGBAToDepth( texture2D( depths, uv ) ); #ifdef USE_REVERSED_DEPTH_BUFFER return step( depth, compare ); #else return step( compare, depth ); #endif } vec2 texture2DDistribution( sampler2D shadow, vec2 uv ) { return unpackRGBATo2Half( texture2D( shadow, uv ) ); } float VSMShadow( sampler2D shadow, vec2 uv, float compare ) { float occlusion = 1.0; vec2 distribution = texture2DDistribution( shadow, uv ); #ifdef USE_REVERSED_DEPTH_BUFFER float hard_shadow = step( distribution.x, compare ); #else float hard_shadow = step( compare, distribution.x ); #endif if ( hard_shadow != 1.0 ) { float distance = compare - distribution.x; float variance = max( 0.00000, distribution.y * distribution.y ); float softness_probability = variance / (variance + distance * distance ); softness_probability = clamp( ( softness_probability - 0.3 ) / ( 0.95 - 0.3 ), 0.0, 1.0 ); occlusion = clamp( max( hard_shadow, softness_probability ), 0.0, 1.0 ); } return occlusion; } float getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord ) { float shadow = 1.0; shadowCoord.xyz /= shadowCoord.w; shadowCoord.z += shadowBias; bool inFrustum = shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0; bool frustumTest = inFrustum && shadowCoord.z <= 1.0; if ( frustumTest ) { #if defined( SHADOWMAP_TYPE_PCF ) vec2 texelSize = vec2( 1.0 ) / shadowMapSize; float dx0 = - texelSize.x * shadowRadius; float dy0 = - texelSize.y * shadowRadius; float dx1 = + texelSize.x * shadowRadius; float dy1 = + texelSize.y * shadowRadius; float dx2 = dx0 / 2.0; float dy2 = dy0 / 2.0; float dx3 = dx1 / 2.0; float dy3 = dy1 / 2.0; shadow = ( texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) + texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) + texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) + texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) + texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) + texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) + texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) + texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) + texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) + texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) + texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) + texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) + texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) + texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) + texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) + texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) + texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z ) ) * ( 1.0 / 17.0 ); #elif defined( SHADOWMAP_TYPE_PCF_SOFT ) vec2 texelSize = vec2( 1.0 ) / shadowMapSize; float dx = texelSize.x; float dy = texelSize.y; vec2 uv = shadowCoord.xy; vec2 f = fract( uv * shadowMapSize + 0.5 ); uv -= f * texelSize; shadow = ( texture2DCompare( shadowMap, uv, shadowCoord.z ) + texture2DCompare( shadowMap, uv + vec2( dx, 0.0 ), shadowCoord.z ) + texture2DCompare( shadowMap, uv + vec2( 0.0, dy ), shadowCoord.z ) + texture2DCompare( shadowMap, uv + texelSize, shadowCoord.z ) + mix( texture2DCompare( shadowMap, uv + vec2( -dx, 0.0 ), shadowCoord.z ), texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 0.0 ), shadowCoord.z ), f.x ) + mix( texture2DCompare( shadowMap, uv + vec2( -dx, dy ), shadowCoord.z ), texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, dy ), shadowCoord.z ), f.x ) + mix( texture2DCompare( shadowMap, uv + vec2( 0.0, -dy ), shadowCoord.z ), texture2DCompare( shadowMap, uv + vec2( 0.0, 2.0 * dy ), shadowCoord.z ), f.y ) + mix( texture2DCompare( shadowMap, uv + vec2( dx, -dy ), shadowCoord.z ), texture2DCompare( shadowMap, uv + vec2( dx, 2.0 * dy ), shadowCoord.z ), f.y ) + mix( mix( texture2DCompare( shadowMap, uv + vec2( -dx, -dy ), shadowCoord.z ), texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, -dy ), shadowCoord.z ), f.x ), mix( texture2DCompare( shadowMap, uv + vec2( -dx, 2.0 * dy ), shadowCoord.z ), texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 2.0 * dy ), shadowCoord.z ), f.x ), f.y ) ) * ( 1.0 / 9.0 ); #elif defined( SHADOWMAP_TYPE_VSM ) shadow = VSMShadow( shadowMap, shadowCoord.xy, shadowCoord.z ); #else shadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ); #endif } return mix( 1.0, shadow, shadowIntensity ); } vec2 cubeToUV( vec3 v, float texelSizeY ) { vec3 absV = abs( v ); float scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) ); absV *= scaleToCube; v *= scaleToCube * ( 1.0 - 2.0 * texelSizeY ); vec2 planar = v.xy; float almostATexel = 1.5 * texelSizeY; float almostOne = 1.0 - almostATexel; if ( absV.z >= almostOne ) { if ( v.z > 0.0 ) planar.x = 4.0 - v.x; } else if ( absV.x >= almostOne ) { float signX = sign( v.x ); planar.x = v.z * signX + 2.0 * signX; } else if ( absV.y >= almostOne ) { float signY = sign( v.y ); planar.x = v.x + 2.0 * signY + 2.0; planar.y = v.z * signY - 2.0; } return vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 ); } float getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) { float shadow = 1.0; vec3 lightToPosition = shadowCoord.xyz; float lightToPositionLength = length( lightToPosition ); if ( lightToPositionLength - shadowCameraFar <= 0.0 && lightToPositionLength - shadowCameraNear >= 0.0 ) { float dp = ( lightToPositionLength - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear ); dp += shadowBias; vec3 bd3D = normalize( lightToPosition ); vec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) ); #if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT ) || defined( SHADOWMAP_TYPE_VSM ) vec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y; shadow = ( texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) + texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) + texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) + texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) + texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) + texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) + texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) + texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) + texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp ) ) * ( 1.0 / 9.0 ); #else shadow = texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ); #endif } return mix( 1.0, shadow, shadowIntensity ); } #endif`,SG=`#if NUM_SPOT_LIGHT_COORDS > 0 uniform mat4 spotLightMatrix[ NUM_SPOT_LIGHT_COORDS ]; varying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ]; #endif #ifdef USE_SHADOWMAP #if NUM_DIR_LIGHT_SHADOWS > 0 uniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ]; varying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ]; struct DirectionalLightShadow { float shadowIntensity; float shadowBias; float shadowNormalBias; float shadowRadius; vec2 shadowMapSize; }; uniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ]; #endif #if NUM_SPOT_LIGHT_SHADOWS > 0 struct SpotLightShadow { float shadowIntensity; float shadowBias; float shadowNormalBias; float shadowRadius; vec2 shadowMapSize; }; uniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ]; #endif #if NUM_POINT_LIGHT_SHADOWS > 0 uniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ]; varying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ]; struct PointLightShadow { float shadowIntensity; float shadowBias; float shadowNormalBias; float shadowRadius; vec2 shadowMapSize; float shadowCameraNear; float shadowCameraFar; }; uniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ]; #endif #endif`,AG=`#if ( defined( USE_SHADOWMAP ) && ( NUM_DIR_LIGHT_SHADOWS > 0 || NUM_POINT_LIGHT_SHADOWS > 0 ) ) || ( NUM_SPOT_LIGHT_COORDS > 0 ) vec3 shadowWorldNormal = inverseTransformDirection( transformedNormal, viewMatrix ); vec4 shadowWorldPosition; #endif #if defined( USE_SHADOWMAP ) #if NUM_DIR_LIGHT_SHADOWS > 0 #pragma unroll_loop_start for ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) { shadowWorldPosition = worldPosition + vec4( shadowWorldNormal * directionalLightShadows[ i ].shadowNormalBias, 0 ); vDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * shadowWorldPosition; } #pragma unroll_loop_end #endif #if NUM_POINT_LIGHT_SHADOWS > 0 #pragma unroll_loop_start for ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) { shadowWorldPosition = worldPosition + vec4( shadowWorldNormal * pointLightShadows[ i ].shadowNormalBias, 0 ); vPointShadowCoord[ i ] = pointShadowMatrix[ i ] * shadowWorldPosition; } #pragma unroll_loop_end #endif #endif #if NUM_SPOT_LIGHT_COORDS > 0 #pragma unroll_loop_start for ( int i = 0; i < NUM_SPOT_LIGHT_COORDS; i ++ ) { shadowWorldPosition = worldPosition; #if ( defined( USE_SHADOWMAP ) && UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS ) shadowWorldPosition.xyz += shadowWorldNormal * spotLightShadows[ i ].shadowNormalBias; #endif vSpotLightCoord[ i ] = spotLightMatrix[ i ] * shadowWorldPosition; } #pragma unroll_loop_end #endif`,EG=`float getShadowMask() { float shadow = 1.0; #ifdef USE_SHADOWMAP #if NUM_DIR_LIGHT_SHADOWS > 0 DirectionalLightShadow directionalLight; #pragma unroll_loop_start for ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) { directionalLight = directionalLightShadows[ i ]; shadow *= receiveShadow ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowIntensity, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0; } #pragma unroll_loop_end #endif #if NUM_SPOT_LIGHT_SHADOWS > 0 SpotLightShadow spotLight; #pragma unroll_loop_start for ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) { spotLight = spotLightShadows[ i ]; shadow *= receiveShadow ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowIntensity, spotLight.shadowBias, spotLight.shadowRadius, vSpotLightCoord[ i ] ) : 1.0; } #pragma unroll_loop_end #endif #if NUM_POINT_LIGHT_SHADOWS > 0 PointLightShadow pointLight; #pragma unroll_loop_start for ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) { pointLight = pointLightShadows[ i ]; shadow *= receiveShadow ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowIntensity, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0; } #pragma unroll_loop_end #endif #endif return shadow; }`,wG=`#ifdef USE_SKINNING mat4 boneMatX = getBoneMatrix( skinIndex.x ); mat4 boneMatY = getBoneMatrix( skinIndex.y ); mat4 boneMatZ = getBoneMatrix( skinIndex.z ); mat4 boneMatW = getBoneMatrix( skinIndex.w ); #endif`,MG=`#ifdef USE_SKINNING uniform mat4 bindMatrix; uniform mat4 bindMatrixInverse; uniform highp sampler2D boneTexture; mat4 getBoneMatrix( const in float i ) { int size = textureSize( boneTexture, 0 ).x; int j = int( i ) * 4; int x = j % size; int y = j / size; vec4 v1 = texelFetch( boneTexture, ivec2( x, y ), 0 ); vec4 v2 = texelFetch( boneTexture, ivec2( x + 1, y ), 0 ); vec4 v3 = texelFetch( boneTexture, ivec2( x + 2, y ), 0 ); vec4 v4 = texelFetch( boneTexture, ivec2( x + 3, y ), 0 ); return mat4( v1, v2, v3, v4 ); } #endif`,CG=`#ifdef USE_SKINNING vec4 skinVertex = bindMatrix * vec4( transformed, 1.0 ); vec4 skinned = vec4( 0.0 ); skinned += boneMatX * skinVertex * skinWeight.x; skinned += boneMatY * skinVertex * skinWeight.y; skinned += boneMatZ * skinVertex * skinWeight.z; skinned += boneMatW * skinVertex * skinWeight.w; transformed = ( bindMatrixInverse * skinned ).xyz; #endif`,TG=`#ifdef USE_SKINNING mat4 skinMatrix = mat4( 0.0 ); skinMatrix += skinWeight.x * boneMatX; skinMatrix += skinWeight.y * boneMatY; skinMatrix += skinWeight.z * boneMatZ; skinMatrix += skinWeight.w * boneMatW; skinMatrix = bindMatrixInverse * skinMatrix * bindMatrix; objectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz; #ifdef USE_TANGENT objectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz; #endif #endif`,jG=`float specularStrength; #ifdef USE_SPECULARMAP vec4 texelSpecular = texture2D( specularMap, vSpecularMapUv ); specularStrength = texelSpecular.r; #else specularStrength = 1.0; #endif`,RG=`#ifdef USE_SPECULARMAP uniform sampler2D specularMap; #endif`,kG=`#if defined( TONE_MAPPING ) gl_FragColor.rgb = toneMapping( gl_FragColor.rgb ); #endif`,NG=`#ifndef saturate #define saturate( a ) clamp( a, 0.0, 1.0 ) #endif uniform float toneMappingExposure; vec3 LinearToneMapping( vec3 color ) { return saturate( toneMappingExposure * color ); } vec3 ReinhardToneMapping( vec3 color ) { color *= toneMappingExposure; return saturate( color / ( vec3( 1.0 ) + color ) ); } vec3 CineonToneMapping( vec3 color ) { color *= toneMappingExposure; color = max( vec3( 0.0 ), color - 0.004 ); return pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) ); } vec3 RRTAndODTFit( vec3 v ) { vec3 a = v * ( v + 0.0245786 ) - 0.000090537; vec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081; return a / b; } vec3 ACESFilmicToneMapping( vec3 color ) { const mat3 ACESInputMat = mat3( vec3( 0.59719, 0.07600, 0.02840 ), vec3( 0.35458, 0.90834, 0.13383 ), vec3( 0.04823, 0.01566, 0.83777 ) ); const mat3 ACESOutputMat = mat3( vec3( 1.60475, -0.10208, -0.00327 ), vec3( -0.53108, 1.10813, -0.07276 ), vec3( -0.07367, -0.00605, 1.07602 ) ); color *= toneMappingExposure / 0.6; color = ACESInputMat * color; color = RRTAndODTFit( color ); color = ACESOutputMat * color; return saturate( color ); } const mat3 LINEAR_REC2020_TO_LINEAR_SRGB = mat3( vec3( 1.6605, - 0.1246, - 0.0182 ), vec3( - 0.5876, 1.1329, - 0.1006 ), vec3( - 0.0728, - 0.0083, 1.1187 ) ); const mat3 LINEAR_SRGB_TO_LINEAR_REC2020 = mat3( vec3( 0.6274, 0.0691, 0.0164 ), vec3( 0.3293, 0.9195, 0.0880 ), vec3( 0.0433, 0.0113, 0.8956 ) ); vec3 agxDefaultContrastApprox( vec3 x ) { vec3 x2 = x * x; vec3 x4 = x2 * x2; return + 15.5 * x4 * x2 - 40.14 * x4 * x + 31.96 * x4 - 6.868 * x2 * x + 0.4298 * x2 + 0.1191 * x - 0.00232; } vec3 AgXToneMapping( vec3 color ) { const mat3 AgXInsetMatrix = mat3( vec3( 0.856627153315983, 0.137318972929847, 0.11189821299995 ), vec3( 0.0951212405381588, 0.761241990602591, 0.0767994186031903 ), vec3( 0.0482516061458583, 0.101439036467562, 0.811302368396859 ) ); const mat3 AgXOutsetMatrix = mat3( vec3( 1.1271005818144368, - 0.1413297634984383, - 0.14132976349843826 ), vec3( - 0.11060664309660323, 1.157823702216272, - 0.11060664309660294 ), vec3( - 0.016493938717834573, - 0.016493938717834257, 1.2519364065950405 ) ); const float AgxMinEv = - 12.47393; const float AgxMaxEv = 4.026069; color *= toneMappingExposure; color = LINEAR_SRGB_TO_LINEAR_REC2020 * color; color = AgXInsetMatrix * color; color = max( color, 1e-10 ); color = log2( color ); color = ( color - AgxMinEv ) / ( AgxMaxEv - AgxMinEv ); color = clamp( color, 0.0, 1.0 ); color = agxDefaultContrastApprox( color ); color = AgXOutsetMatrix * color; color = pow( max( vec3( 0.0 ), color ), vec3( 2.2 ) ); color = LINEAR_REC2020_TO_LINEAR_SRGB * color; color = clamp( color, 0.0, 1.0 ); return color; } vec3 NeutralToneMapping( vec3 color ) { const float StartCompression = 0.8 - 0.04; const float Desaturation = 0.15; color *= toneMappingExposure; float x = min( color.r, min( color.g, color.b ) ); float offset = x < 0.08 ? x - 6.25 * x * x : 0.04; color -= offset; float peak = max( color.r, max( color.g, color.b ) ); if ( peak < StartCompression ) return color; float d = 1. - StartCompression; float newPeak = 1. - d * d / ( peak + d - StartCompression ); color *= newPeak / peak; float g = 1. - 1. / ( Desaturation * ( peak - newPeak ) + 1. ); return mix( color, vec3( newPeak ), g ); } vec3 CustomToneMapping( vec3 color ) { return color; }`,DG=`#ifdef USE_TRANSMISSION material.transmission = transmission; material.transmissionAlpha = 1.0; material.thickness = thickness; material.attenuationDistance = attenuationDistance; material.attenuationColor = attenuationColor; #ifdef USE_TRANSMISSIONMAP material.transmission *= texture2D( transmissionMap, vTransmissionMapUv ).r; #endif #ifdef USE_THICKNESSMAP material.thickness *= texture2D( thicknessMap, vThicknessMapUv ).g; #endif vec3 pos = vWorldPosition; vec3 v = normalize( cameraPosition - pos ); vec3 n = inverseTransformDirection( normal, viewMatrix ); vec4 transmitted = getIBLVolumeRefraction( n, v, material.roughness, material.diffuseColor, material.specularColor, material.specularF90, pos, modelMatrix, viewMatrix, projectionMatrix, material.dispersion, material.ior, material.thickness, material.attenuationColor, material.attenuationDistance ); material.transmissionAlpha = mix( material.transmissionAlpha, transmitted.a, material.transmission ); totalDiffuse = mix( totalDiffuse, transmitted.rgb, material.transmission ); #endif`,zG=`#ifdef USE_TRANSMISSION uniform float transmission; uniform float thickness; uniform float attenuationDistance; uniform vec3 attenuationColor; #ifdef USE_TRANSMISSIONMAP uniform sampler2D transmissionMap; #endif #ifdef USE_THICKNESSMAP uniform sampler2D thicknessMap; #endif uniform vec2 transmissionSamplerSize; uniform sampler2D transmissionSamplerMap; uniform mat4 modelMatrix; uniform mat4 projectionMatrix; varying vec3 vWorldPosition; float w0( float a ) { return ( 1.0 / 6.0 ) * ( a * ( a * ( - a + 3.0 ) - 3.0 ) + 1.0 ); } float w1( float a ) { return ( 1.0 / 6.0 ) * ( a * a * ( 3.0 * a - 6.0 ) + 4.0 ); } float w2( float a ){ return ( 1.0 / 6.0 ) * ( a * ( a * ( - 3.0 * a + 3.0 ) + 3.0 ) + 1.0 ); } float w3( float a ) { return ( 1.0 / 6.0 ) * ( a * a * a ); } float g0( float a ) { return w0( a ) + w1( a ); } float g1( float a ) { return w2( a ) + w3( a ); } float h0( float a ) { return - 1.0 + w1( a ) / ( w0( a ) + w1( a ) ); } float h1( float a ) { return 1.0 + w3( a ) / ( w2( a ) + w3( a ) ); } vec4 bicubic( sampler2D tex, vec2 uv, vec4 texelSize, float lod ) { uv = uv * texelSize.zw + 0.5; vec2 iuv = floor( uv ); vec2 fuv = fract( uv ); float g0x = g0( fuv.x ); float g1x = g1( fuv.x ); float h0x = h0( fuv.x ); float h1x = h1( fuv.x ); float h0y = h0( fuv.y ); float h1y = h1( fuv.y ); vec2 p0 = ( vec2( iuv.x + h0x, iuv.y + h0y ) - 0.5 ) * texelSize.xy; vec2 p1 = ( vec2( iuv.x + h1x, iuv.y + h0y ) - 0.5 ) * texelSize.xy; vec2 p2 = ( vec2( iuv.x + h0x, iuv.y + h1y ) - 0.5 ) * texelSize.xy; vec2 p3 = ( vec2( iuv.x + h1x, iuv.y + h1y ) - 0.5 ) * texelSize.xy; return g0( fuv.y ) * ( g0x * textureLod( tex, p0, lod ) + g1x * textureLod( tex, p1, lod ) ) + g1( fuv.y ) * ( g0x * textureLod( tex, p2, lod ) + g1x * textureLod( tex, p3, lod ) ); } vec4 textureBicubic( sampler2D sampler, vec2 uv, float lod ) { vec2 fLodSize = vec2( textureSize( sampler, int( lod ) ) ); vec2 cLodSize = vec2( textureSize( sampler, int( lod + 1.0 ) ) ); vec2 fLodSizeInv = 1.0 / fLodSize; vec2 cLodSizeInv = 1.0 / cLodSize; vec4 fSample = bicubic( sampler, uv, vec4( fLodSizeInv, fLodSize ), floor( lod ) ); vec4 cSample = bicubic( sampler, uv, vec4( cLodSizeInv, cLodSize ), ceil( lod ) ); return mix( fSample, cSample, fract( lod ) ); } vec3 getVolumeTransmissionRay( const in vec3 n, const in vec3 v, const in float thickness, const in float ior, const in mat4 modelMatrix ) { vec3 refractionVector = refract( - v, normalize( n ), 1.0 / ior ); vec3 modelScale; modelScale.x = length( vec3( modelMatrix[ 0 ].xyz ) ); modelScale.y = length( vec3( modelMatrix[ 1 ].xyz ) ); modelScale.z = length( vec3( modelMatrix[ 2 ].xyz ) ); return normalize( refractionVector ) * thickness * modelScale; } float applyIorToRoughness( const in float roughness, const in float ior ) { return roughness * clamp( ior * 2.0 - 2.0, 0.0, 1.0 ); } vec4 getTransmissionSample( const in vec2 fragCoord, const in float roughness, const in float ior ) { float lod = log2( transmissionSamplerSize.x ) * applyIorToRoughness( roughness, ior ); return textureBicubic( transmissionSamplerMap, fragCoord.xy, lod ); } vec3 volumeAttenuation( const in float transmissionDistance, const in vec3 attenuationColor, const in float attenuationDistance ) { if ( isinf( attenuationDistance ) ) { return vec3( 1.0 ); } else { vec3 attenuationCoefficient = -log( attenuationColor ) / attenuationDistance; vec3 transmittance = exp( - attenuationCoefficient * transmissionDistance ); return transmittance; } } vec4 getIBLVolumeRefraction( const in vec3 n, const in vec3 v, const in float roughness, const in vec3 diffuseColor, const in vec3 specularColor, const in float specularF90, const in vec3 position, const in mat4 modelMatrix, const in mat4 viewMatrix, const in mat4 projMatrix, const in float dispersion, const in float ior, const in float thickness, const in vec3 attenuationColor, const in float attenuationDistance ) { vec4 transmittedLight; vec3 transmittance; #ifdef USE_DISPERSION float halfSpread = ( ior - 1.0 ) * 0.025 * dispersion; vec3 iors = vec3( ior - halfSpread, ior, ior + halfSpread ); for ( int i = 0; i < 3; i ++ ) { vec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, iors[ i ], modelMatrix ); vec3 refractedRayExit = position + transmissionRay; vec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 ); vec2 refractionCoords = ndcPos.xy / ndcPos.w; refractionCoords += 1.0; refractionCoords /= 2.0; vec4 transmissionSample = getTransmissionSample( refractionCoords, roughness, iors[ i ] ); transmittedLight[ i ] = transmissionSample[ i ]; transmittedLight.a += transmissionSample.a; transmittance[ i ] = diffuseColor[ i ] * volumeAttenuation( length( transmissionRay ), attenuationColor, attenuationDistance )[ i ]; } transmittedLight.a /= 3.0; #else vec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, ior, modelMatrix ); vec3 refractedRayExit = position + transmissionRay; vec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 ); vec2 refractionCoords = ndcPos.xy / ndcPos.w; refractionCoords += 1.0; refractionCoords /= 2.0; transmittedLight = getTransmissionSample( refractionCoords, roughness, ior ); transmittance = diffuseColor * volumeAttenuation( length( transmissionRay ), attenuationColor, attenuationDistance ); #endif vec3 attenuatedColor = transmittance * transmittedLight.rgb; vec3 F = EnvironmentBRDF( n, v, specularColor, specularF90, roughness ); float transmittanceFactor = ( transmittance.r + transmittance.g + transmittance.b ) / 3.0; return vec4( ( 1.0 - F ) * attenuatedColor, 1.0 - ( 1.0 - transmittedLight.a ) * transmittanceFactor ); } #endif`,LG=`#if defined( USE_UV ) || defined( USE_ANISOTROPY ) varying vec2 vUv; #endif #ifdef USE_MAP varying vec2 vMapUv; #endif #ifdef USE_ALPHAMAP varying vec2 vAlphaMapUv; #endif #ifdef USE_LIGHTMAP varying vec2 vLightMapUv; #endif #ifdef USE_AOMAP varying vec2 vAoMapUv; #endif #ifdef USE_BUMPMAP varying vec2 vBumpMapUv; #endif #ifdef USE_NORMALMAP varying vec2 vNormalMapUv; #endif #ifdef USE_EMISSIVEMAP varying vec2 vEmissiveMapUv; #endif #ifdef USE_METALNESSMAP varying vec2 vMetalnessMapUv; #endif #ifdef USE_ROUGHNESSMAP varying vec2 vRoughnessMapUv; #endif #ifdef USE_ANISOTROPYMAP varying vec2 vAnisotropyMapUv; #endif #ifdef USE_CLEARCOATMAP varying vec2 vClearcoatMapUv; #endif #ifdef USE_CLEARCOAT_NORMALMAP varying vec2 vClearcoatNormalMapUv; #endif #ifdef USE_CLEARCOAT_ROUGHNESSMAP varying vec2 vClearcoatRoughnessMapUv; #endif #ifdef USE_IRIDESCENCEMAP varying vec2 vIridescenceMapUv; #endif #ifdef USE_IRIDESCENCE_THICKNESSMAP varying vec2 vIridescenceThicknessMapUv; #endif #ifdef USE_SHEEN_COLORMAP varying vec2 vSheenColorMapUv; #endif #ifdef USE_SHEEN_ROUGHNESSMAP varying vec2 vSheenRoughnessMapUv; #endif #ifdef USE_SPECULARMAP varying vec2 vSpecularMapUv; #endif #ifdef USE_SPECULAR_COLORMAP varying vec2 vSpecularColorMapUv; #endif #ifdef USE_SPECULAR_INTENSITYMAP varying vec2 vSpecularIntensityMapUv; #endif #ifdef USE_TRANSMISSIONMAP uniform mat3 transmissionMapTransform; varying vec2 vTransmissionMapUv; #endif #ifdef USE_THICKNESSMAP uniform mat3 thicknessMapTransform; varying vec2 vThicknessMapUv; #endif`,OG=`#if defined( USE_UV ) || defined( USE_ANISOTROPY ) varying vec2 vUv; #endif #ifdef USE_MAP uniform mat3 mapTransform; varying vec2 vMapUv; #endif #ifdef USE_ALPHAMAP uniform mat3 alphaMapTransform; varying vec2 vAlphaMapUv; #endif #ifdef USE_LIGHTMAP uniform mat3 lightMapTransform; varying vec2 vLightMapUv; #endif #ifdef USE_AOMAP uniform mat3 aoMapTransform; varying vec2 vAoMapUv; #endif #ifdef USE_BUMPMAP uniform mat3 bumpMapTransform; varying vec2 vBumpMapUv; #endif #ifdef USE_NORMALMAP uniform mat3 normalMapTransform; varying vec2 vNormalMapUv; #endif #ifdef USE_DISPLACEMENTMAP uniform mat3 displacementMapTransform; varying vec2 vDisplacementMapUv; #endif #ifdef USE_EMISSIVEMAP uniform mat3 emissiveMapTransform; varying vec2 vEmissiveMapUv; #endif #ifdef USE_METALNESSMAP uniform mat3 metalnessMapTransform; varying vec2 vMetalnessMapUv; #endif #ifdef USE_ROUGHNESSMAP uniform mat3 roughnessMapTransform; varying vec2 vRoughnessMapUv; #endif #ifdef USE_ANISOTROPYMAP uniform mat3 anisotropyMapTransform; varying vec2 vAnisotropyMapUv; #endif #ifdef USE_CLEARCOATMAP uniform mat3 clearcoatMapTransform; varying vec2 vClearcoatMapUv; #endif #ifdef USE_CLEARCOAT_NORMALMAP uniform mat3 clearcoatNormalMapTransform; varying vec2 vClearcoatNormalMapUv; #endif #ifdef USE_CLEARCOAT_ROUGHNESSMAP uniform mat3 clearcoatRoughnessMapTransform; varying vec2 vClearcoatRoughnessMapUv; #endif #ifdef USE_SHEEN_COLORMAP uniform mat3 sheenColorMapTransform; varying vec2 vSheenColorMapUv; #endif #ifdef USE_SHEEN_ROUGHNESSMAP uniform mat3 sheenRoughnessMapTransform; varying vec2 vSheenRoughnessMapUv; #endif #ifdef USE_IRIDESCENCEMAP uniform mat3 iridescenceMapTransform; varying vec2 vIridescenceMapUv; #endif #ifdef USE_IRIDESCENCE_THICKNESSMAP uniform mat3 iridescenceThicknessMapTransform; varying vec2 vIridescenceThicknessMapUv; #endif #ifdef USE_SPECULARMAP uniform mat3 specularMapTransform; varying vec2 vSpecularMapUv; #endif #ifdef USE_SPECULAR_COLORMAP uniform mat3 specularColorMapTransform; varying vec2 vSpecularColorMapUv; #endif #ifdef USE_SPECULAR_INTENSITYMAP uniform mat3 specularIntensityMapTransform; varying vec2 vSpecularIntensityMapUv; #endif #ifdef USE_TRANSMISSIONMAP uniform mat3 transmissionMapTransform; varying vec2 vTransmissionMapUv; #endif #ifdef USE_THICKNESSMAP uniform mat3 thicknessMapTransform; varying vec2 vThicknessMapUv; #endif`,PG=`#if defined( USE_UV ) || defined( USE_ANISOTROPY ) vUv = vec3( uv, 1 ).xy; #endif #ifdef USE_MAP vMapUv = ( mapTransform * vec3( MAP_UV, 1 ) ).xy; #endif #ifdef USE_ALPHAMAP vAlphaMapUv = ( alphaMapTransform * vec3( ALPHAMAP_UV, 1 ) ).xy; #endif #ifdef USE_LIGHTMAP vLightMapUv = ( lightMapTransform * vec3( LIGHTMAP_UV, 1 ) ).xy; #endif #ifdef USE_AOMAP vAoMapUv = ( aoMapTransform * vec3( AOMAP_UV, 1 ) ).xy; #endif #ifdef USE_BUMPMAP vBumpMapUv = ( bumpMapTransform * vec3( BUMPMAP_UV, 1 ) ).xy; #endif #ifdef USE_NORMALMAP vNormalMapUv = ( normalMapTransform * vec3( NORMALMAP_UV, 1 ) ).xy; #endif #ifdef USE_DISPLACEMENTMAP vDisplacementMapUv = ( displacementMapTransform * vec3( DISPLACEMENTMAP_UV, 1 ) ).xy; #endif #ifdef USE_EMISSIVEMAP vEmissiveMapUv = ( emissiveMapTransform * vec3( EMISSIVEMAP_UV, 1 ) ).xy; #endif #ifdef USE_METALNESSMAP vMetalnessMapUv = ( metalnessMapTransform * vec3( METALNESSMAP_UV, 1 ) ).xy; #endif #ifdef USE_ROUGHNESSMAP vRoughnessMapUv = ( roughnessMapTransform * vec3( ROUGHNESSMAP_UV, 1 ) ).xy; #endif #ifdef USE_ANISOTROPYMAP vAnisotropyMapUv = ( anisotropyMapTransform * vec3( ANISOTROPYMAP_UV, 1 ) ).xy; #endif #ifdef USE_CLEARCOATMAP vClearcoatMapUv = ( clearcoatMapTransform * vec3( CLEARCOATMAP_UV, 1 ) ).xy; #endif #ifdef USE_CLEARCOAT_NORMALMAP vClearcoatNormalMapUv = ( clearcoatNormalMapTransform * vec3( CLEARCOAT_NORMALMAP_UV, 1 ) ).xy; #endif #ifdef USE_CLEARCOAT_ROUGHNESSMAP vClearcoatRoughnessMapUv = ( clearcoatRoughnessMapTransform * vec3( CLEARCOAT_ROUGHNESSMAP_UV, 1 ) ).xy; #endif #ifdef USE_IRIDESCENCEMAP vIridescenceMapUv = ( iridescenceMapTransform * vec3( IRIDESCENCEMAP_UV, 1 ) ).xy; #endif #ifdef USE_IRIDESCENCE_THICKNESSMAP vIridescenceThicknessMapUv = ( iridescenceThicknessMapTransform * vec3( IRIDESCENCE_THICKNESSMAP_UV, 1 ) ).xy; #endif #ifdef USE_SHEEN_COLORMAP vSheenColorMapUv = ( sheenColorMapTransform * vec3( SHEEN_COLORMAP_UV, 1 ) ).xy; #endif #ifdef USE_SHEEN_ROUGHNESSMAP vSheenRoughnessMapUv = ( sheenRoughnessMapTransform * vec3( SHEEN_ROUGHNESSMAP_UV, 1 ) ).xy; #endif #ifdef USE_SPECULARMAP vSpecularMapUv = ( specularMapTransform * vec3( SPECULARMAP_UV, 1 ) ).xy; #endif #ifdef USE_SPECULAR_COLORMAP vSpecularColorMapUv = ( specularColorMapTransform * vec3( SPECULAR_COLORMAP_UV, 1 ) ).xy; #endif #ifdef USE_SPECULAR_INTENSITYMAP vSpecularIntensityMapUv = ( specularIntensityMapTransform * vec3( SPECULAR_INTENSITYMAP_UV, 1 ) ).xy; #endif #ifdef USE_TRANSMISSIONMAP vTransmissionMapUv = ( transmissionMapTransform * vec3( TRANSMISSIONMAP_UV, 1 ) ).xy; #endif #ifdef USE_THICKNESSMAP vThicknessMapUv = ( thicknessMapTransform * vec3( THICKNESSMAP_UV, 1 ) ).xy; #endif`,IG=`#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP ) || defined ( USE_TRANSMISSION ) || NUM_SPOT_LIGHT_COORDS > 0 vec4 worldPosition = vec4( transformed, 1.0 ); #ifdef USE_BATCHING worldPosition = batchingMatrix * worldPosition; #endif #ifdef USE_INSTANCING worldPosition = instanceMatrix * worldPosition; #endif worldPosition = modelMatrix * worldPosition; #endif`;const UG=`varying vec2 vUv; uniform mat3 uvTransform; void main() { vUv = ( uvTransform * vec3( uv, 1 ) ).xy; gl_Position = vec4( position.xy, 1.0, 1.0 ); }`,FG=`uniform sampler2D t2D; uniform float backgroundIntensity; varying vec2 vUv; void main() { vec4 texColor = texture2D( t2D, vUv ); #ifdef DECODE_VIDEO_TEXTURE texColor = vec4( mix( pow( texColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), texColor.rgb * 0.0773993808, vec3( lessThanEqual( texColor.rgb, vec3( 0.04045 ) ) ) ), texColor.w ); #endif texColor.rgb *= backgroundIntensity; gl_FragColor = texColor; #include #include }`,BG=`varying vec3 vWorldDirection; #include void main() { vWorldDirection = transformDirection( position, modelMatrix ); #include #include gl_Position.z = gl_Position.w; }`,HG=`#ifdef ENVMAP_TYPE_CUBE uniform samplerCube envMap; #elif defined( ENVMAP_TYPE_CUBE_UV ) uniform sampler2D envMap; #endif uniform float flipEnvMap; uniform float backgroundBlurriness; uniform float backgroundIntensity; uniform mat3 backgroundRotation; varying vec3 vWorldDirection; #include void main() { #ifdef ENVMAP_TYPE_CUBE vec4 texColor = textureCube( envMap, backgroundRotation * vec3( flipEnvMap * vWorldDirection.x, vWorldDirection.yz ) ); #elif defined( ENVMAP_TYPE_CUBE_UV ) vec4 texColor = textureCubeUV( envMap, backgroundRotation * vWorldDirection, backgroundBlurriness ); #else vec4 texColor = vec4( 0.0, 0.0, 0.0, 1.0 ); #endif texColor.rgb *= backgroundIntensity; gl_FragColor = texColor; #include #include }`,GG=`varying vec3 vWorldDirection; #include void main() { vWorldDirection = transformDirection( position, modelMatrix ); #include #include gl_Position.z = gl_Position.w; }`,VG=`uniform samplerCube tCube; uniform float tFlip; uniform float opacity; varying vec3 vWorldDirection; void main() { vec4 texColor = textureCube( tCube, vec3( tFlip * vWorldDirection.x, vWorldDirection.yz ) ); gl_FragColor = texColor; gl_FragColor.a *= opacity; #include #include }`,qG=`#include #include #include #include #include #include #include #include varying vec2 vHighPrecisionZW; void main() { #include #include #include #include #ifdef USE_DISPLACEMENTMAP #include #include #include #endif #include #include #include #include #include #include #include vHighPrecisionZW = gl_Position.zw; }`,WG=`#if DEPTH_PACKING == 3200 uniform float opacity; #endif #include #include #include #include #include #include #include #include #include varying vec2 vHighPrecisionZW; void main() { vec4 diffuseColor = vec4( 1.0 ); #include #if DEPTH_PACKING == 3200 diffuseColor.a = opacity; #endif #include #include #include #include #include #ifdef USE_REVERSED_DEPTH_BUFFER float fragCoordZ = vHighPrecisionZW[ 0 ] / vHighPrecisionZW[ 1 ]; #else float fragCoordZ = 0.5 * vHighPrecisionZW[ 0 ] / vHighPrecisionZW[ 1 ] + 0.5; #endif #if DEPTH_PACKING == 3200 gl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), opacity ); #elif DEPTH_PACKING == 3201 gl_FragColor = packDepthToRGBA( fragCoordZ ); #elif DEPTH_PACKING == 3202 gl_FragColor = vec4( packDepthToRGB( fragCoordZ ), 1.0 ); #elif DEPTH_PACKING == 3203 gl_FragColor = vec4( packDepthToRG( fragCoordZ ), 0.0, 1.0 ); #endif }`,YG=`#define DISTANCE varying vec3 vWorldPosition; #include #include #include #include #include #include #include void main() { #include #include #include #include #ifdef USE_DISPLACEMENTMAP #include #include #include #endif #include #include #include #include #include #include #include vWorldPosition = worldPosition.xyz; }`,XG=`#define DISTANCE uniform vec3 referencePosition; uniform float nearDistance; uniform float farDistance; varying vec3 vWorldPosition; #include #include #include #include #include #include #include #include void main () { vec4 diffuseColor = vec4( 1.0 ); #include #include #include #include #include float dist = length( vWorldPosition - referencePosition ); dist = ( dist - nearDistance ) / ( farDistance - nearDistance ); dist = saturate( dist ); gl_FragColor = packDepthToRGBA( dist ); }`,KG=`varying vec3 vWorldDirection; #include void main() { vWorldDirection = transformDirection( position, modelMatrix ); #include #include }`,JG=`uniform sampler2D tEquirect; varying vec3 vWorldDirection; #include void main() { vec3 direction = normalize( vWorldDirection ); vec2 sampleUV = equirectUv( direction ); gl_FragColor = texture2D( tEquirect, sampleUV ); #include #include }`,ZG=`uniform float scale; attribute float lineDistance; varying float vLineDistance; #include #include #include #include #include #include #include void main() { vLineDistance = scale * lineDistance; #include #include #include #include #include #include #include #include #include #include }`,QG=`uniform vec3 diffuse; uniform float opacity; uniform float dashSize; uniform float totalSize; varying float vLineDistance; #include #include #include #include #include #include #include void main() { vec4 diffuseColor = vec4( diffuse, opacity ); #include if ( mod( vLineDistance, totalSize ) > dashSize ) { discard; } vec3 outgoingLight = vec3( 0.0 ); #include #include #include outgoingLight = diffuseColor.rgb; #include #include #include #include #include }`,_G=`#include #include #include #include #include #include #include #include #include #include void main() { #include #include #include #include #include #if defined ( USE_ENVMAP ) || defined ( USE_SKINNING ) #include #include #include #include #include #endif #include #include #include #include #include #include #include #include #include }`,$G=`uniform vec3 diffuse; uniform float opacity; #ifndef FLAT_SHADED varying vec3 vNormal; #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include void main() { vec4 diffuseColor = vec4( diffuse, opacity ); #include #include #include #include #include #include #include #include ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) ); #ifdef USE_LIGHTMAP vec4 lightMapTexel = texture2D( lightMap, vLightMapUv ); reflectedLight.indirectDiffuse += lightMapTexel.rgb * lightMapIntensity * RECIPROCAL_PI; #else reflectedLight.indirectDiffuse += vec3( 1.0 ); #endif #include reflectedLight.indirectDiffuse *= diffuseColor.rgb; vec3 outgoingLight = reflectedLight.indirectDiffuse; #include #include #include #include #include #include #include }`,eV=`#define LAMBERT varying vec3 vViewPosition; #include #include #include #include #include #include #include #include #include #include #include #include #include void main() { #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include vViewPosition = - mvPosition.xyz; #include #include #include #include }`,tV=`#define LAMBERT uniform vec3 diffuse; uniform vec3 emissive; uniform float opacity; #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include void main() { vec4 diffuseColor = vec4( diffuse, opacity ); #include ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) ); vec3 totalEmissiveRadiance = emissive; #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance; #include #include #include #include #include #include #include }`,nV=`#define MATCAP varying vec3 vViewPosition; #include #include #include #include #include #include #include #include #include #include #include void main() { #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include vViewPosition = - mvPosition.xyz; }`,aV=`#define MATCAP uniform vec3 diffuse; uniform float opacity; uniform sampler2D matcap; varying vec3 vViewPosition; #include #include #include #include #include #include #include #include #include #include #include #include #include #include void main() { vec4 diffuseColor = vec4( diffuse, opacity ); #include #include #include #include #include #include #include #include #include vec3 viewDir = normalize( vViewPosition ); vec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) ); vec3 y = cross( viewDir, x ); vec2 uv = vec2( dot( x, normal ), dot( y, normal ) ) * 0.495 + 0.5; #ifdef USE_MATCAP vec4 matcapColor = texture2D( matcap, uv ); #else vec4 matcapColor = vec4( vec3( mix( 0.2, 0.8, uv.y ) ), 1.0 ); #endif vec3 outgoingLight = diffuseColor.rgb * matcapColor.rgb; #include #include #include #include #include #include }`,iV=`#define NORMAL #if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE ) varying vec3 vViewPosition; #endif #include #include #include #include #include #include #include #include #include void main() { #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE ) vViewPosition = - mvPosition.xyz; #endif }`,sV=`#define NORMAL uniform float opacity; #if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE ) varying vec3 vViewPosition; #endif #include #include #include #include #include #include #include void main() { vec4 diffuseColor = vec4( 0.0, 0.0, 0.0, opacity ); #include #include #include #include gl_FragColor = vec4( packNormalToRGB( normal ), diffuseColor.a ); #ifdef OPAQUE gl_FragColor.a = 1.0; #endif }`,rV=`#define PHONG varying vec3 vViewPosition; #include #include #include #include #include #include #include #include #include #include #include #include #include void main() { #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include vViewPosition = - mvPosition.xyz; #include #include #include #include }`,oV=`#define PHONG uniform vec3 diffuse; uniform vec3 emissive; uniform vec3 specular; uniform float shininess; uniform float opacity; #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include void main() { vec4 diffuseColor = vec4( diffuse, opacity ); #include ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) ); vec3 totalEmissiveRadiance = emissive; #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance; #include #include #include #include #include #include #include }`,lV=`#define STANDARD varying vec3 vViewPosition; #ifdef USE_TRANSMISSION varying vec3 vWorldPosition; #endif #include #include #include #include #include #include #include #include #include #include #include #include void main() { #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include vViewPosition = - mvPosition.xyz; #include #include #include #ifdef USE_TRANSMISSION vWorldPosition = worldPosition.xyz; #endif }`,cV=`#define STANDARD #ifdef PHYSICAL #define IOR #define USE_SPECULAR #endif uniform vec3 diffuse; uniform vec3 emissive; uniform float roughness; uniform float metalness; uniform float opacity; #ifdef IOR uniform float ior; #endif #ifdef USE_SPECULAR uniform float specularIntensity; uniform vec3 specularColor; #ifdef USE_SPECULAR_COLORMAP uniform sampler2D specularColorMap; #endif #ifdef USE_SPECULAR_INTENSITYMAP uniform sampler2D specularIntensityMap; #endif #endif #ifdef USE_CLEARCOAT uniform float clearcoat; uniform float clearcoatRoughness; #endif #ifdef USE_DISPERSION uniform float dispersion; #endif #ifdef USE_IRIDESCENCE uniform float iridescence; uniform float iridescenceIOR; uniform float iridescenceThicknessMinimum; uniform float iridescenceThicknessMaximum; #endif #ifdef USE_SHEEN uniform vec3 sheenColor; uniform float sheenRoughness; #ifdef USE_SHEEN_COLORMAP uniform sampler2D sheenColorMap; #endif #ifdef USE_SHEEN_ROUGHNESSMAP uniform sampler2D sheenRoughnessMap; #endif #endif #ifdef USE_ANISOTROPY uniform vec2 anisotropyVector; #ifdef USE_ANISOTROPYMAP uniform sampler2D anisotropyMap; #endif #endif varying vec3 vViewPosition; #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include void main() { vec4 diffuseColor = vec4( diffuse, opacity ); #include ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) ); vec3 totalEmissiveRadiance = emissive; #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include vec3 totalDiffuse = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse; vec3 totalSpecular = reflectedLight.directSpecular + reflectedLight.indirectSpecular; #include vec3 outgoingLight = totalDiffuse + totalSpecular + totalEmissiveRadiance; #ifdef USE_SHEEN float sheenEnergyComp = 1.0 - 0.157 * max3( material.sheenColor ); outgoingLight = outgoingLight * sheenEnergyComp + sheenSpecularDirect + sheenSpecularIndirect; #endif #ifdef USE_CLEARCOAT float dotNVcc = saturate( dot( geometryClearcoatNormal, geometryViewDir ) ); vec3 Fcc = F_Schlick( material.clearcoatF0, material.clearcoatF90, dotNVcc ); outgoingLight = outgoingLight * ( 1.0 - material.clearcoat * Fcc ) + ( clearcoatSpecularDirect + clearcoatSpecularIndirect ) * material.clearcoat; #endif #include #include #include #include #include #include }`,uV=`#define TOON varying vec3 vViewPosition; #include #include #include #include #include #include #include #include #include #include #include #include void main() { #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include vViewPosition = - mvPosition.xyz; #include #include #include }`,dV=`#define TOON uniform vec3 diffuse; uniform vec3 emissive; uniform float opacity; #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include void main() { vec4 diffuseColor = vec4( diffuse, opacity ); #include ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) ); vec3 totalEmissiveRadiance = emissive; #include #include #include #include #include #include #include #include #include #include #include #include #include #include vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance; #include #include #include #include #include #include }`,hV=`uniform float size; uniform float scale; #include #include #include #include #include #include #ifdef USE_POINTS_UV varying vec2 vUv; uniform mat3 uvTransform; #endif void main() { #ifdef USE_POINTS_UV vUv = ( uvTransform * vec3( uv, 1 ) ).xy; #endif #include #include #include #include #include #include gl_PointSize = size; #ifdef USE_SIZEATTENUATION bool isPerspective = isPerspectiveMatrix( projectionMatrix ); if ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z ); #endif #include #include #include #include }`,fV=`uniform vec3 diffuse; uniform float opacity; #include #include #include #include #include #include #include #include void main() { vec4 diffuseColor = vec4( diffuse, opacity ); #include vec3 outgoingLight = vec3( 0.0 ); #include #include #include #include #include outgoingLight = diffuseColor.rgb; #include #include #include #include #include }`,pV=`#include #include #include #include #include #include #include void main() { #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include }`,mV=`uniform vec3 color; uniform float opacity; #include #include #include #include #include #include #include #include void main() { #include gl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) ); #include #include #include }`,gV=`uniform float rotation; uniform vec2 center; #include #include #include #include #include void main() { #include vec4 mvPosition = modelViewMatrix[ 3 ]; vec2 scale = vec2( length( modelMatrix[ 0 ].xyz ), length( modelMatrix[ 1 ].xyz ) ); #ifndef USE_SIZEATTENUATION bool isPerspective = isPerspectiveMatrix( projectionMatrix ); if ( isPerspective ) scale *= - mvPosition.z; #endif vec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale; vec2 rotatedPosition; rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y; rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y; mvPosition.xy += rotatedPosition; gl_Position = projectionMatrix * mvPosition; #include #include #include }`,vV=`uniform vec3 diffuse; uniform float opacity; #include #include #include #include #include #include #include #include #include void main() { vec4 diffuseColor = vec4( diffuse, opacity ); #include vec3 outgoingLight = vec3( 0.0 ); #include #include #include #include #include outgoingLight = diffuseColor.rgb; #include #include #include #include }`,$t={alphahash_fragment:F6,alphahash_pars_fragment:B6,alphamap_fragment:H6,alphamap_pars_fragment:G6,alphatest_fragment:V6,alphatest_pars_fragment:q6,aomap_fragment:W6,aomap_pars_fragment:Y6,batching_pars_vertex:X6,batching_vertex:K6,begin_vertex:J6,beginnormal_vertex:Z6,bsdfs:Q6,iridescence_fragment:_6,bumpmap_pars_fragment:$6,clipping_planes_fragment:e9,clipping_planes_pars_fragment:t9,clipping_planes_pars_vertex:n9,clipping_planes_vertex:a9,color_fragment:i9,color_pars_fragment:s9,color_pars_vertex:r9,color_vertex:o9,common:l9,cube_uv_reflection_fragment:c9,defaultnormal_vertex:u9,displacementmap_pars_vertex:d9,displacementmap_vertex:h9,emissivemap_fragment:f9,emissivemap_pars_fragment:p9,colorspace_fragment:m9,colorspace_pars_fragment:g9,envmap_fragment:v9,envmap_common_pars_fragment:x9,envmap_pars_fragment:y9,envmap_pars_vertex:b9,envmap_physical_pars_fragment:N9,envmap_vertex:S9,fog_vertex:A9,fog_pars_vertex:E9,fog_fragment:w9,fog_pars_fragment:M9,gradientmap_pars_fragment:C9,lightmap_pars_fragment:T9,lights_lambert_fragment:j9,lights_lambert_pars_fragment:R9,lights_pars_begin:k9,lights_toon_fragment:D9,lights_toon_pars_fragment:z9,lights_phong_fragment:L9,lights_phong_pars_fragment:O9,lights_physical_fragment:P9,lights_physical_pars_fragment:I9,lights_fragment_begin:U9,lights_fragment_maps:F9,lights_fragment_end:B9,logdepthbuf_fragment:H9,logdepthbuf_pars_fragment:G9,logdepthbuf_pars_vertex:V9,logdepthbuf_vertex:q9,map_fragment:W9,map_pars_fragment:Y9,map_particle_fragment:X9,map_particle_pars_fragment:K9,metalnessmap_fragment:J9,metalnessmap_pars_fragment:Z9,morphinstance_vertex:Q9,morphcolor_vertex:_9,morphnormal_vertex:$9,morphtarget_pars_vertex:eG,morphtarget_vertex:tG,normal_fragment_begin:nG,normal_fragment_maps:aG,normal_pars_fragment:iG,normal_pars_vertex:sG,normal_vertex:rG,normalmap_pars_fragment:oG,clearcoat_normal_fragment_begin:lG,clearcoat_normal_fragment_maps:cG,clearcoat_pars_fragment:uG,iridescence_pars_fragment:dG,opaque_fragment:hG,packing:fG,premultiplied_alpha_fragment:pG,project_vertex:mG,dithering_fragment:gG,dithering_pars_fragment:vG,roughnessmap_fragment:xG,roughnessmap_pars_fragment:yG,shadowmap_pars_fragment:bG,shadowmap_pars_vertex:SG,shadowmap_vertex:AG,shadowmask_pars_fragment:EG,skinbase_vertex:wG,skinning_pars_vertex:MG,skinning_vertex:CG,skinnormal_vertex:TG,specularmap_fragment:jG,specularmap_pars_fragment:RG,tonemapping_fragment:kG,tonemapping_pars_fragment:NG,transmission_fragment:DG,transmission_pars_fragment:zG,uv_pars_fragment:LG,uv_pars_vertex:OG,uv_vertex:PG,worldpos_vertex:IG,background_vert:UG,background_frag:FG,backgroundCube_vert:BG,backgroundCube_frag:HG,cube_vert:GG,cube_frag:VG,depth_vert:qG,depth_frag:WG,distanceRGBA_vert:YG,distanceRGBA_frag:XG,equirect_vert:KG,equirect_frag:JG,linedashed_vert:ZG,linedashed_frag:QG,meshbasic_vert:_G,meshbasic_frag:$G,meshlambert_vert:eV,meshlambert_frag:tV,meshmatcap_vert:nV,meshmatcap_frag:aV,meshnormal_vert:iV,meshnormal_frag:sV,meshphong_vert:rV,meshphong_frag:oV,meshphysical_vert:lV,meshphysical_frag:cV,meshtoon_vert:uV,meshtoon_frag:dV,points_vert:hV,points_frag:fV,shadow_vert:pV,shadow_frag:mV,sprite_vert:gV,sprite_frag:vV},At={common:{diffuse:{value:new tn(16777215)},opacity:{value:1},map:{value:null},mapTransform:{value:new Qt},alphaMap:{value:null},alphaMapTransform:{value:new Qt},alphaTest:{value:0}},specularmap:{specularMap:{value:null},specularMapTransform:{value:new Qt}},envmap:{envMap:{value:null},envMapRotation:{value:new Qt},flipEnvMap:{value:-1},reflectivity:{value:1},ior:{value:1.5},refractionRatio:{value:.98}},aomap:{aoMap:{value:null},aoMapIntensity:{value:1},aoMapTransform:{value:new Qt}},lightmap:{lightMap:{value:null},lightMapIntensity:{value:1},lightMapTransform:{value:new Qt}},bumpmap:{bumpMap:{value:null},bumpMapTransform:{value:new Qt},bumpScale:{value:1}},normalmap:{normalMap:{value:null},normalMapTransform:{value:new Qt},normalScale:{value:new jt(1,1)}},displacementmap:{displacementMap:{value:null},displacementMapTransform:{value:new Qt},displacementScale:{value:1},displacementBias:{value:0}},emissivemap:{emissiveMap:{value:null},emissiveMapTransform:{value:new Qt}},metalnessmap:{metalnessMap:{value:null},metalnessMapTransform:{value:new Qt}},roughnessmap:{roughnessMap:{value:null},roughnessMapTransform:{value:new Qt}},gradientmap:{gradientMap:{value:null}},fog:{fogDensity:{value:25e-5},fogNear:{value:1},fogFar:{value:2e3},fogColor:{value:new tn(16777215)}},lights:{ambientLightColor:{value:[]},lightProbe:{value:[]},directionalLights:{value:[],properties:{direction:{},color:{}}},directionalLightShadows:{value:[],properties:{shadowIntensity:1,shadowBias:{},shadowNormalBias:{},shadowRadius:{},shadowMapSize:{}}},directionalShadowMap:{value:[]},directionalShadowMatrix:{value:[]},spotLights:{value:[],properties:{color:{},position:{},direction:{},distance:{},coneCos:{},penumbraCos:{},decay:{}}},spotLightShadows:{value:[],properties:{shadowIntensity:1,shadowBias:{},shadowNormalBias:{},shadowRadius:{},shadowMapSize:{}}},spotLightMap:{value:[]},spotShadowMap:{value:[]},spotLightMatrix:{value:[]},pointLights:{value:[],properties:{color:{},position:{},decay:{},distance:{}}},pointLightShadows:{value:[],properties:{shadowIntensity:1,shadowBias:{},shadowNormalBias:{},shadowRadius:{},shadowMapSize:{},shadowCameraNear:{},shadowCameraFar:{}}},pointShadowMap:{value:[]},pointShadowMatrix:{value:[]},hemisphereLights:{value:[],properties:{direction:{},skyColor:{},groundColor:{}}},rectAreaLights:{value:[],properties:{color:{},position:{},width:{},height:{}}},ltc_1:{value:null},ltc_2:{value:null}},points:{diffuse:{value:new tn(16777215)},opacity:{value:1},size:{value:1},scale:{value:1},map:{value:null},alphaMap:{value:null},alphaMapTransform:{value:new Qt},alphaTest:{value:0},uvTransform:{value:new Qt}},sprite:{diffuse:{value:new tn(16777215)},opacity:{value:1},center:{value:new jt(.5,.5)},rotation:{value:0},map:{value:null},mapTransform:{value:new Qt},alphaMap:{value:null},alphaMapTransform:{value:new Qt},alphaTest:{value:0}}},zs={basic:{uniforms:Ya([At.common,At.specularmap,At.envmap,At.aomap,At.lightmap,At.fog]),vertexShader:$t.meshbasic_vert,fragmentShader:$t.meshbasic_frag},lambert:{uniforms:Ya([At.common,At.specularmap,At.envmap,At.aomap,At.lightmap,At.emissivemap,At.bumpmap,At.normalmap,At.displacementmap,At.fog,At.lights,{emissive:{value:new tn(0)}}]),vertexShader:$t.meshlambert_vert,fragmentShader:$t.meshlambert_frag},phong:{uniforms:Ya([At.common,At.specularmap,At.envmap,At.aomap,At.lightmap,At.emissivemap,At.bumpmap,At.normalmap,At.displacementmap,At.fog,At.lights,{emissive:{value:new tn(0)},specular:{value:new tn(1118481)},shininess:{value:30}}]),vertexShader:$t.meshphong_vert,fragmentShader:$t.meshphong_frag},standard:{uniforms:Ya([At.common,At.envmap,At.aomap,At.lightmap,At.emissivemap,At.bumpmap,At.normalmap,At.displacementmap,At.roughnessmap,At.metalnessmap,At.fog,At.lights,{emissive:{value:new tn(0)},roughness:{value:1},metalness:{value:0},envMapIntensity:{value:1}}]),vertexShader:$t.meshphysical_vert,fragmentShader:$t.meshphysical_frag},toon:{uniforms:Ya([At.common,At.aomap,At.lightmap,At.emissivemap,At.bumpmap,At.normalmap,At.displacementmap,At.gradientmap,At.fog,At.lights,{emissive:{value:new tn(0)}}]),vertexShader:$t.meshtoon_vert,fragmentShader:$t.meshtoon_frag},matcap:{uniforms:Ya([At.common,At.bumpmap,At.normalmap,At.displacementmap,At.fog,{matcap:{value:null}}]),vertexShader:$t.meshmatcap_vert,fragmentShader:$t.meshmatcap_frag},points:{uniforms:Ya([At.points,At.fog]),vertexShader:$t.points_vert,fragmentShader:$t.points_frag},dashed:{uniforms:Ya([At.common,At.fog,{scale:{value:1},dashSize:{value:1},totalSize:{value:2}}]),vertexShader:$t.linedashed_vert,fragmentShader:$t.linedashed_frag},depth:{uniforms:Ya([At.common,At.displacementmap]),vertexShader:$t.depth_vert,fragmentShader:$t.depth_frag},normal:{uniforms:Ya([At.common,At.bumpmap,At.normalmap,At.displacementmap,{opacity:{value:1}}]),vertexShader:$t.meshnormal_vert,fragmentShader:$t.meshnormal_frag},sprite:{uniforms:Ya([At.sprite,At.fog]),vertexShader:$t.sprite_vert,fragmentShader:$t.sprite_frag},background:{uniforms:{uvTransform:{value:new Qt},t2D:{value:null},backgroundIntensity:{value:1}},vertexShader:$t.background_vert,fragmentShader:$t.background_frag},backgroundCube:{uniforms:{envMap:{value:null},flipEnvMap:{value:-1},backgroundBlurriness:{value:0},backgroundIntensity:{value:1},backgroundRotation:{value:new Qt}},vertexShader:$t.backgroundCube_vert,fragmentShader:$t.backgroundCube_frag},cube:{uniforms:{tCube:{value:null},tFlip:{value:-1},opacity:{value:1}},vertexShader:$t.cube_vert,fragmentShader:$t.cube_frag},equirect:{uniforms:{tEquirect:{value:null}},vertexShader:$t.equirect_vert,fragmentShader:$t.equirect_frag},distanceRGBA:{uniforms:Ya([At.common,At.displacementmap,{referencePosition:{value:new he},nearDistance:{value:1},farDistance:{value:1e3}}]),vertexShader:$t.distanceRGBA_vert,fragmentShader:$t.distanceRGBA_frag},shadow:{uniforms:Ya([At.lights,At.fog,{color:{value:new tn(0)},opacity:{value:1}}]),vertexShader:$t.shadow_vert,fragmentShader:$t.shadow_frag}};zs.physical={uniforms:Ya([zs.standard.uniforms,{clearcoat:{value:0},clearcoatMap:{value:null},clearcoatMapTransform:{value:new Qt},clearcoatNormalMap:{value:null},clearcoatNormalMapTransform:{value:new Qt},clearcoatNormalScale:{value:new jt(1,1)},clearcoatRoughness:{value:0},clearcoatRoughnessMap:{value:null},clearcoatRoughnessMapTransform:{value:new Qt},dispersion:{value:0},iridescence:{value:0},iridescenceMap:{value:null},iridescenceMapTransform:{value:new Qt},iridescenceIOR:{value:1.3},iridescenceThicknessMinimum:{value:100},iridescenceThicknessMaximum:{value:400},iridescenceThicknessMap:{value:null},iridescenceThicknessMapTransform:{value:new Qt},sheen:{value:0},sheenColor:{value:new tn(0)},sheenColorMap:{value:null},sheenColorMapTransform:{value:new Qt},sheenRoughness:{value:1},sheenRoughnessMap:{value:null},sheenRoughnessMapTransform:{value:new Qt},transmission:{value:0},transmissionMap:{value:null},transmissionMapTransform:{value:new Qt},transmissionSamplerSize:{value:new jt},transmissionSamplerMap:{value:null},thickness:{value:0},thicknessMap:{value:null},thicknessMapTransform:{value:new Qt},attenuationDistance:{value:0},attenuationColor:{value:new tn(0)},specularColor:{value:new tn(1,1,1)},specularColorMap:{value:null},specularColorMapTransform:{value:new Qt},specularIntensity:{value:1},specularIntensityMap:{value:null},specularIntensityMapTransform:{value:new Qt},anisotropyVector:{value:new jt},anisotropyMap:{value:null},anisotropyMapTransform:{value:new Qt}}]),vertexShader:$t.meshphysical_vert,fragmentShader:$t.meshphysical_frag};const pp={r:0,b:0,g:0},Zo=new Es,xV=new dn;function yV(a,e,n,s,o,l,d){const h=new tn(0);let m=l===!0?0:1,p,y,v=null,x=0,S=null;function M(R){let N=R.isScene===!0?R.background:null;return N&&N.isTexture&&(N=(R.backgroundBlurriness>0?n:e).get(N)),N}function w(R){let N=!1;const I=M(R);I===null?A(h,m):I&&I.isColor&&(A(I,1),N=!0);const z=a.xr.getEnvironmentBlendMode();z==="additive"?s.buffers.color.setClear(0,0,0,1,d):z==="alpha-blend"&&s.buffers.color.setClear(0,0,0,0,d),(a.autoClear||N)&&(s.buffers.depth.setTest(!0),s.buffers.depth.setMask(!0),s.buffers.color.setMask(!0),a.clear(a.autoClearColor,a.autoClearDepth,a.autoClearStencil))}function E(R,N){const I=M(N);I&&(I.isCubeTexture||I.mapping===qm)?(y===void 0&&(y=new zn(new wr(1,1,1),new _a({name:"BackgroundCubeMaterial",uniforms:cu(zs.backgroundCube.uniforms),vertexShader:zs.backgroundCube.vertexShader,fragmentShader:zs.backgroundCube.fragmentShader,side:ai,depthTest:!1,depthWrite:!1,fog:!1,allowOverride:!1})),y.geometry.deleteAttribute("normal"),y.geometry.deleteAttribute("uv"),y.onBeforeRender=function(z,j,L){this.matrixWorld.copyPosition(L.matrixWorld)},Object.defineProperty(y.material,"envMap",{get:function(){return this.uniforms.envMap.value}}),o.update(y)),Zo.copy(N.backgroundRotation),Zo.x*=-1,Zo.y*=-1,Zo.z*=-1,I.isCubeTexture&&I.isRenderTargetTexture===!1&&(Zo.y*=-1,Zo.z*=-1),y.material.uniforms.envMap.value=I,y.material.uniforms.flipEnvMap.value=I.isCubeTexture&&I.isRenderTargetTexture===!1?-1:1,y.material.uniforms.backgroundBlurriness.value=N.backgroundBlurriness,y.material.uniforms.backgroundIntensity.value=N.backgroundIntensity,y.material.uniforms.backgroundRotation.value.setFromMatrix4(xV.makeRotationFromEuler(Zo)),y.material.toneMapped=pn.getTransfer(I.colorSpace)!==Mn,(v!==I||x!==I.version||S!==a.toneMapping)&&(y.material.needsUpdate=!0,v=I,x=I.version,S=a.toneMapping),y.layers.enableAll(),R.unshift(y,y.geometry,y.material,0,0,null)):I&&I.isTexture&&(p===void 0&&(p=new zn(new uu(2,2),new _a({name:"BackgroundMaterial",uniforms:cu(zs.background.uniforms),vertexShader:zs.background.vertexShader,fragmentShader:zs.background.fragmentShader,side:Ao,depthTest:!1,depthWrite:!1,fog:!1,allowOverride:!1})),p.geometry.deleteAttribute("normal"),Object.defineProperty(p.material,"map",{get:function(){return this.uniforms.t2D.value}}),o.update(p)),p.material.uniforms.t2D.value=I,p.material.uniforms.backgroundIntensity.value=N.backgroundIntensity,p.material.toneMapped=pn.getTransfer(I.colorSpace)!==Mn,I.matrixAutoUpdate===!0&&I.updateMatrix(),p.material.uniforms.uvTransform.value.copy(I.matrix),(v!==I||x!==I.version||S!==a.toneMapping)&&(p.material.needsUpdate=!0,v=I,x=I.version,S=a.toneMapping),p.layers.enableAll(),R.unshift(p,p.geometry,p.material,0,0,null))}function A(R,N){R.getRGB(pp,tN(a)),s.buffers.color.setClear(pp.r,pp.g,pp.b,N,d)}function k(){y!==void 0&&(y.geometry.dispose(),y.material.dispose(),y=void 0),p!==void 0&&(p.geometry.dispose(),p.material.dispose(),p=void 0)}return{getClearColor:function(){return h},setClearColor:function(R,N=1){h.set(R),m=N,A(h,m)},getClearAlpha:function(){return m},setClearAlpha:function(R){m=R,A(h,m)},render:w,addToRenderList:E,dispose:k}}function bV(a,e){const n=a.getParameter(a.MAX_VERTEX_ATTRIBS),s={},o=x(null);let l=o,d=!1;function h(P,F,q,J,ie){let Q=!1;const V=v(J,q,F);l!==V&&(l=V,p(l.object)),Q=S(P,J,q,ie),Q&&M(P,J,q,ie),ie!==null&&e.update(ie,a.ELEMENT_ARRAY_BUFFER),(Q||d)&&(d=!1,N(P,F,q,J),ie!==null&&a.bindBuffer(a.ELEMENT_ARRAY_BUFFER,e.get(ie).buffer))}function m(){return a.createVertexArray()}function p(P){return a.bindVertexArray(P)}function y(P){return a.deleteVertexArray(P)}function v(P,F,q){const J=q.wireframe===!0;let ie=s[P.id];ie===void 0&&(ie={},s[P.id]=ie);let Q=ie[F.id];Q===void 0&&(Q={},ie[F.id]=Q);let V=Q[J];return V===void 0&&(V=x(m()),Q[J]=V),V}function x(P){const F=[],q=[],J=[];for(let ie=0;ie=0){const Y=ie[te];let T=Q[te];if(T===void 0&&(te==="instanceMatrix"&&P.instanceMatrix&&(T=P.instanceMatrix),te==="instanceColor"&&P.instanceColor&&(T=P.instanceColor)),Y===void 0||Y.attribute!==T||T&&Y.data!==T.data)return!0;V++}return l.attributesNum!==V||l.index!==J}function M(P,F,q,J){const ie={},Q=F.attributes;let V=0;const $=q.getAttributes();for(const te in $)if($[te].location>=0){let Y=Q[te];Y===void 0&&(te==="instanceMatrix"&&P.instanceMatrix&&(Y=P.instanceMatrix),te==="instanceColor"&&P.instanceColor&&(Y=P.instanceColor));const T={};T.attribute=Y,Y&&Y.data&&(T.data=Y.data),ie[te]=T,V++}l.attributes=ie,l.attributesNum=V,l.index=J}function w(){const P=l.newAttributes;for(let F=0,q=P.length;F=0){let ne=ie[$];if(ne===void 0&&($==="instanceMatrix"&&P.instanceMatrix&&(ne=P.instanceMatrix),$==="instanceColor"&&P.instanceColor&&(ne=P.instanceColor)),ne!==void 0){const Y=ne.normalized,T=ne.itemSize,_=e.get(ne);if(_===void 0)continue;const ve=_.buffer,je=_.type,Je=_.bytesPerElement,xe=je===a.INT||je===a.UNSIGNED_INT||ne.gpuType===z0;if(ne.isInterleavedBufferAttribute){const ee=ne.data,Ce=ee.stride,Ze=ne.offset;if(ee.isInstancedInterleavedBuffer){for(let le=0;le0&&a.getShaderPrecisionFormat(a.FRAGMENT_SHADER,a.HIGH_FLOAT).precision>0)return"highp";j="mediump"}return j==="mediump"&&a.getShaderPrecisionFormat(a.VERTEX_SHADER,a.MEDIUM_FLOAT).precision>0&&a.getShaderPrecisionFormat(a.FRAGMENT_SHADER,a.MEDIUM_FLOAT).precision>0?"mediump":"lowp"}let p=n.precision!==void 0?n.precision:"highp";const y=m(p);y!==p&&(console.warn("THREE.WebGLRenderer:",p,"not supported, using",y,"instead."),p=y);const v=n.logarithmicDepthBuffer===!0,x=n.reversedDepthBuffer===!0&&e.has("EXT_clip_control"),S=a.getParameter(a.MAX_TEXTURE_IMAGE_UNITS),M=a.getParameter(a.MAX_VERTEX_TEXTURE_IMAGE_UNITS),w=a.getParameter(a.MAX_TEXTURE_SIZE),E=a.getParameter(a.MAX_CUBE_MAP_TEXTURE_SIZE),A=a.getParameter(a.MAX_VERTEX_ATTRIBS),k=a.getParameter(a.MAX_VERTEX_UNIFORM_VECTORS),R=a.getParameter(a.MAX_VARYING_VECTORS),N=a.getParameter(a.MAX_FRAGMENT_UNIFORM_VECTORS),I=M>0,z=a.getParameter(a.MAX_SAMPLES);return{isWebGL2:!0,getMaxAnisotropy:l,getMaxPrecision:m,textureFormatReadable:d,textureTypeReadable:h,precision:p,logarithmicDepthBuffer:v,reversedDepthBuffer:x,maxTextures:S,maxVertexTextures:M,maxTextureSize:w,maxCubemapSize:E,maxAttributes:A,maxVertexUniforms:k,maxVaryings:R,maxFragmentUniforms:N,vertexTextures:I,maxSamples:z}}function EV(a){const e=this;let n=null,s=0,o=!1,l=!1;const d=new oo,h=new Qt,m={value:null,needsUpdate:!1};this.uniform=m,this.numPlanes=0,this.numIntersection=0,this.init=function(v,x){const S=v.length!==0||x||s!==0||o;return o=x,s=v.length,S},this.beginShadows=function(){l=!0,y(null)},this.endShadows=function(){l=!1},this.setGlobalState=function(v,x){n=y(v,x,0)},this.setState=function(v,x,S){const M=v.clippingPlanes,w=v.clipIntersection,E=v.clipShadows,A=a.get(v);if(!o||M===null||M.length===0||l&&!E)l?y(null):p();else{const k=l?0:s,R=k*4;let N=A.clippingState||null;m.value=N,N=y(M,x,R,S);for(let I=0;I!==R;++I)N[I]=n[I];A.clippingState=N,this.numIntersection=w?this.numPlanes:0,this.numPlanes+=k}};function p(){m.value!==n&&(m.value=n,m.needsUpdate=s>0),e.numPlanes=s,e.numIntersection=0}function y(v,x,S,M){const w=v!==null?v.length:0;let E=null;if(w!==0){if(E=m.value,M!==!0||E===null){const A=S+w*4,k=x.matrixWorldInverse;h.getNormalMatrix(k),(E===null||E.length0){const p=new u6(m.height);return p.fromEquirectangularTexture(a,d),e.set(d,p),d.addEventListener("dispose",o),n(p.texture,d.mapping)}else return null}}return d}function o(d){const h=d.target;h.removeEventListener("dispose",o);const m=e.get(h);m!==void 0&&(e.delete(h),m.dispose())}function l(){e=new WeakMap}return{get:s,dispose:l}}const Wc=4,rC=[.125,.215,.35,.446,.526,.582],al=20,Xx=new J0,oC=new tn;let Kx=null,Jx=0,Zx=0,Qx=!1;const el=(1+Math.sqrt(5))/2,Nc=1/el,lC=[new he(-el,Nc,0),new he(el,Nc,0),new he(-Nc,0,el),new he(Nc,0,el),new he(0,el,-Nc),new he(0,el,Nc),new he(-1,1,-1),new he(1,1,-1),new he(-1,1,1),new he(1,1,1)],MV=new he;class Rb{constructor(e){this._renderer=e,this._pingPongRenderTarget=null,this._lodMax=0,this._cubeSize=0,this._lodPlanes=[],this._sizeLods=[],this._sigmas=[],this._blurMaterial=null,this._cubemapMaterial=null,this._equirectMaterial=null,this._compileMaterial(this._blurMaterial)}fromScene(e,n=0,s=.1,o=100,l={}){const{size:d=256,position:h=MV}=l;Kx=this._renderer.getRenderTarget(),Jx=this._renderer.getActiveCubeFace(),Zx=this._renderer.getActiveMipmapLevel(),Qx=this._renderer.xr.enabled,this._renderer.xr.enabled=!1,this._setSize(d);const m=this._allocateTargets();return m.depthBuffer=!0,this._sceneToCubeUV(e,s,o,m,h),n>0&&this._blur(m,0,0,n),this._applyPMREM(m),this._cleanup(m),m}fromEquirectangular(e,n=null){return this._fromTexture(e,n)}fromCubemap(e,n=null){return this._fromTexture(e,n)}compileCubemapShader(){this._cubemapMaterial===null&&(this._cubemapMaterial=dC(),this._compileMaterial(this._cubemapMaterial))}compileEquirectangularShader(){this._equirectMaterial===null&&(this._equirectMaterial=uC(),this._compileMaterial(this._equirectMaterial))}dispose(){this._dispose(),this._cubemapMaterial!==null&&this._cubemapMaterial.dispose(),this._equirectMaterial!==null&&this._equirectMaterial.dispose()}_setSize(e){this._lodMax=Math.floor(Math.log2(e)),this._cubeSize=Math.pow(2,this._lodMax)}_dispose(){this._blurMaterial!==null&&this._blurMaterial.dispose(),this._pingPongRenderTarget!==null&&this._pingPongRenderTarget.dispose();for(let e=0;e2?I:0,I,I),v.setRenderTarget(o),A&&v.render(E,m),v.render(e,m)}E.geometry.dispose(),E.material.dispose(),v.toneMapping=S,v.autoClear=x,e.background=k}_textureToCubeUV(e,n){const s=this._renderer,o=e.mapping===iu||e.mapping===su;o?(this._cubemapMaterial===null&&(this._cubemapMaterial=dC()),this._cubemapMaterial.uniforms.flipEnvMap.value=e.isRenderTargetTexture===!1?-1:1):this._equirectMaterial===null&&(this._equirectMaterial=uC());const l=o?this._cubemapMaterial:this._equirectMaterial,d=new zn(this._lodPlanes[0],l),h=l.uniforms;h.envMap.value=e;const m=this._cubeSize;mp(n,0,0,3*m,2*m),s.setRenderTarget(n),s.render(d,Xx)}_applyPMREM(e){const n=this._renderer,s=n.autoClear;n.autoClear=!1;const o=this._lodPlanes.length;for(let l=1;lal&&console.warn(`sigmaRadians, ${l}, is too large and will clip, as it requested ${E} samples when the maximum is set to ${al}`);const A=[];let k=0;for(let j=0;jR-Wc?o-R+Wc:0),z=4*(this._cubeSize-N);mp(n,I,z,3*N,2*N),m.setRenderTarget(n),m.render(v,Xx)}}function CV(a){const e=[],n=[],s=[];let o=a;const l=a-Wc+1+rC.length;for(let d=0;da-Wc?m=rC[d-a+Wc-1]:d===0&&(m=0),s.push(m);const p=1/(h-2),y=-p,v=1+p,x=[y,y,v,y,v,v,y,y,v,v,y,v],S=6,M=6,w=3,E=2,A=1,k=new Float32Array(w*M*S),R=new Float32Array(E*M*S),N=new Float32Array(A*M*S);for(let z=0;z2?0:-1,D=[j,L,0,j+2/3,L,0,j+2/3,L+1,0,j,L,0,j+2/3,L+1,0,j,L+1,0];k.set(D,w*M*z),R.set(x,E*M*z);const P=[z,z,z,z,z,z];N.set(P,A*M*z)}const I=new Oa;I.setAttribute("position",new as(k,w)),I.setAttribute("uv",new as(R,E)),I.setAttribute("faceIndex",new as(N,A)),e.push(I),o>Wc&&o--}return{lodPlanes:e,sizeLods:n,sigmas:s}}function cC(a,e,n){const s=new As(a,e,n);return s.texture.mapping=qm,s.texture.name="PMREM.cubeUv",s.scissorTest=!0,s}function mp(a,e,n,s,o){a.viewport.set(e,n,s,o),a.scissor.set(e,n,s,o)}function TV(a,e,n){const s=new Float32Array(al),o=new he(0,1,0);return new _a({name:"SphericalGaussianBlur",defines:{n:al,CUBEUV_TEXEL_WIDTH:1/e,CUBEUV_TEXEL_HEIGHT:1/n,CUBEUV_MAX_MIP:`${a}.0`},uniforms:{envMap:{value:null},samples:{value:1},weights:{value:s},latitudinal:{value:!1},dTheta:{value:0},mipInt:{value:0},poleAxis:{value:o}},vertexShader:Z0(),fragmentShader:` precision mediump float; precision mediump int; varying vec3 vOutputDirection; uniform sampler2D envMap; uniform int samples; uniform float weights[ n ]; uniform bool latitudinal; uniform float dTheta; uniform float mipInt; uniform vec3 poleAxis; #define ENVMAP_TYPE_CUBE_UV #include vec3 getSample( float theta, vec3 axis ) { float cosTheta = cos( theta ); // Rodrigues' axis-angle rotation vec3 sampleDirection = vOutputDirection * cosTheta + cross( axis, vOutputDirection ) * sin( theta ) + axis * dot( axis, vOutputDirection ) * ( 1.0 - cosTheta ); return bilinearCubeUV( envMap, sampleDirection, mipInt ); } void main() { vec3 axis = latitudinal ? poleAxis : cross( poleAxis, vOutputDirection ); if ( all( equal( axis, vec3( 0.0 ) ) ) ) { axis = vec3( vOutputDirection.z, 0.0, - vOutputDirection.x ); } axis = normalize( axis ); gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 ); gl_FragColor.rgb += weights[ 0 ] * getSample( 0.0, axis ); for ( int i = 1; i < n; i++ ) { if ( i >= samples ) { break; } float theta = dTheta * float( i ); gl_FragColor.rgb += weights[ i ] * getSample( -1.0 * theta, axis ); gl_FragColor.rgb += weights[ i ] * getSample( theta, axis ); } } `,blending:Ja,depthTest:!1,depthWrite:!1})}function uC(){return new _a({name:"EquirectangularToCubeUV",uniforms:{envMap:{value:null}},vertexShader:Z0(),fragmentShader:` precision mediump float; precision mediump int; varying vec3 vOutputDirection; uniform sampler2D envMap; #include void main() { vec3 outputDirection = normalize( vOutputDirection ); vec2 uv = equirectUv( outputDirection ); gl_FragColor = vec4( texture2D ( envMap, uv ).rgb, 1.0 ); } `,blending:Ja,depthTest:!1,depthWrite:!1})}function dC(){return new _a({name:"CubemapToCubeUV",uniforms:{envMap:{value:null},flipEnvMap:{value:-1}},vertexShader:Z0(),fragmentShader:` precision mediump float; precision mediump int; uniform float flipEnvMap; varying vec3 vOutputDirection; uniform samplerCube envMap; void main() { gl_FragColor = textureCube( envMap, vec3( flipEnvMap * vOutputDirection.x, vOutputDirection.yz ) ); } `,blending:Ja,depthTest:!1,depthWrite:!1})}function Z0(){return` precision mediump float; precision mediump int; attribute float faceIndex; varying vec3 vOutputDirection; // RH coordinate system; PMREM face-indexing convention vec3 getDirection( vec2 uv, float face ) { uv = 2.0 * uv - 1.0; vec3 direction = vec3( uv, 1.0 ); if ( face == 0.0 ) { direction = direction.zyx; // ( 1, v, u ) pos x } else if ( face == 1.0 ) { direction = direction.xzy; direction.xz *= -1.0; // ( -u, 1, -v ) pos y } else if ( face == 2.0 ) { direction.x *= -1.0; // ( -u, v, 1 ) pos z } else if ( face == 3.0 ) { direction = direction.zyx; direction.xz *= -1.0; // ( -1, v, -u ) neg x } else if ( face == 4.0 ) { direction = direction.xzy; direction.xy *= -1.0; // ( -u, -1, v ) neg y } else if ( face == 5.0 ) { direction.z *= -1.0; // ( u, v, -1 ) neg z } return direction; } void main() { vOutputDirection = getDirection( uv, faceIndex ); gl_Position = vec4( position, 1.0 ); } `}function jV(a){let e=new WeakMap,n=null;function s(h){if(h&&h.isTexture){const m=h.mapping,p=m===Jy||m===Zy,y=m===iu||m===su;if(p||y){let v=e.get(h);const x=v!==void 0?v.texture.pmremVersion:0;if(h.isRenderTargetTexture&&h.pmremVersion!==x)return n===null&&(n=new Rb(a)),v=p?n.fromEquirectangular(h,v):n.fromCubemap(h,v),v.texture.pmremVersion=h.pmremVersion,e.set(h,v),v.texture;if(v!==void 0)return v.texture;{const S=h.image;return p&&S&&S.height>0||y&&S&&o(S)?(n===null&&(n=new Rb(a)),v=p?n.fromEquirectangular(h):n.fromCubemap(h),v.texture.pmremVersion=h.pmremVersion,e.set(h,v),h.addEventListener("dispose",l),v.texture):null}}}return h}function o(h){let m=0;const p=6;for(let y=0;ye.maxTextureSize&&(z=Math.ceil(I/e.maxTextureSize),I=e.maxTextureSize);const j=new Float32Array(I*z*4*v),L=new Qk(j,I,z,v);L.type=bs,L.needsUpdate=!0;const D=N*4;for(let F=0;F0)return a;const o=e*n;let l=fC[o];if(l===void 0&&(l=new Float32Array(o),fC[o]=l),e!==0){s.toArray(l,0);for(let d=1,h=0;d!==e;++d)h+=n,a[d].toArray(l,h)}return l}function xa(a,e){if(a.length!==e.length)return!1;for(let n=0,s=a.length;n":" "} ${h}: ${n[d]}`)}return s.join(` `)}const bC=new Qt;function j7(a){pn._getMatrix(bC,pn.workingColorSpace,a);const e=`mat3( ${bC.elements.map(n=>n.toFixed(4))} )`;switch(pn.getTransfer(a)){case hm:return[e,"LinearTransferOETF"];case Mn:return[e,"sRGBTransferOETF"];default:return console.warn("THREE.WebGLProgram: Unsupported color space: ",a),[e,"LinearTransferOETF"]}}function SC(a,e,n){const s=a.getShaderParameter(e,a.COMPILE_STATUS),l=(a.getShaderInfoLog(e)||"").trim();if(s&&l==="")return"";const d=/ERROR: 0:(\d+)/.exec(l);if(d){const h=parseInt(d[1]);return n.toUpperCase()+` `+l+` `+T7(a.getShaderSource(e),h)}else return l}function R7(a,e){const n=j7(e);return[`vec4 ${a}( vec4 value ) {`,` return ${n[1]}( vec4( value.rgb * ${n[0]}, value.a ) );`,"}"].join(` `)}function k7(a,e){let n;switch(e){case Lk:n="Linear";break;case Ok:n="Reinhard";break;case Pk:n="Cineon";break;case D0:n="ACESFilmic";break;case Uk:n="AgX";break;case Fk:n="Neutral";break;case Ik:n="Custom";break;default:console.warn("THREE.WebGLProgram: Unsupported toneMapping:",e),n="Linear"}return"vec3 "+a+"( vec3 color ) { return "+n+"ToneMapping( color ); }"}const gp=new he;function N7(){pn.getLuminanceCoefficients(gp);const a=gp.x.toFixed(4),e=gp.y.toFixed(4),n=gp.z.toFixed(4);return["float luminance( const in vec3 rgb ) {",` const vec3 weights = vec3( ${a}, ${e}, ${n} );`," return dot( weights, rgb );","}"].join(` `)}function D7(a){return[a.extensionClipCullDistance?"#extension GL_ANGLE_clip_cull_distance : require":"",a.extensionMultiDraw?"#extension GL_ANGLE_multi_draw : require":""].filter(Id).join(` `)}function z7(a){const e=[];for(const n in a){const s=a[n];s!==!1&&e.push("#define "+n+" "+s)}return e.join(` `)}function L7(a,e){const n={},s=a.getProgramParameter(e,a.ACTIVE_ATTRIBUTES);for(let o=0;o/gm;function kb(a){return a.replace(O7,I7)}const P7=new Map;function I7(a,e){let n=$t[e];if(n===void 0){const s=P7.get(e);if(s!==void 0)n=$t[s],console.warn('THREE.WebGLRenderer: Shader chunk "%s" has been deprecated. Use "%s" instead.',e,s);else throw new Error("Can not resolve #include <"+e+">")}return kb(n)}const U7=/#pragma unroll_loop_start\s+for\s*\(\s*int\s+i\s*=\s*(\d+)\s*;\s*i\s*<\s*(\d+)\s*;\s*i\s*\+\+\s*\)\s*{([\s\S]+?)}\s+#pragma unroll_loop_end/g;function wC(a){return a.replace(U7,F7)}function F7(a,e,n,s){let o="";for(let l=parseInt(e);l0&&(E+=` `),A=["#define SHADER_TYPE "+n.shaderType,"#define SHADER_NAME "+n.shaderName,M].filter(Id).join(` `),A.length>0&&(A+=` `)):(E=[MC(n),"#define SHADER_TYPE "+n.shaderType,"#define SHADER_NAME "+n.shaderName,M,n.extensionClipCullDistance?"#define USE_CLIP_DISTANCE":"",n.batching?"#define USE_BATCHING":"",n.batchingColor?"#define USE_BATCHING_COLOR":"",n.instancing?"#define USE_INSTANCING":"",n.instancingColor?"#define USE_INSTANCING_COLOR":"",n.instancingMorph?"#define USE_INSTANCING_MORPH":"",n.useFog&&n.fog?"#define USE_FOG":"",n.useFog&&n.fogExp2?"#define FOG_EXP2":"",n.map?"#define USE_MAP":"",n.envMap?"#define USE_ENVMAP":"",n.envMap?"#define "+y:"",n.lightMap?"#define USE_LIGHTMAP":"",n.aoMap?"#define USE_AOMAP":"",n.bumpMap?"#define USE_BUMPMAP":"",n.normalMap?"#define USE_NORMALMAP":"",n.normalMapObjectSpace?"#define USE_NORMALMAP_OBJECTSPACE":"",n.normalMapTangentSpace?"#define USE_NORMALMAP_TANGENTSPACE":"",n.displacementMap?"#define USE_DISPLACEMENTMAP":"",n.emissiveMap?"#define USE_EMISSIVEMAP":"",n.anisotropy?"#define USE_ANISOTROPY":"",n.anisotropyMap?"#define USE_ANISOTROPYMAP":"",n.clearcoatMap?"#define USE_CLEARCOATMAP":"",n.clearcoatRoughnessMap?"#define USE_CLEARCOAT_ROUGHNESSMAP":"",n.clearcoatNormalMap?"#define USE_CLEARCOAT_NORMALMAP":"",n.iridescenceMap?"#define USE_IRIDESCENCEMAP":"",n.iridescenceThicknessMap?"#define USE_IRIDESCENCE_THICKNESSMAP":"",n.specularMap?"#define USE_SPECULARMAP":"",n.specularColorMap?"#define USE_SPECULAR_COLORMAP":"",n.specularIntensityMap?"#define USE_SPECULAR_INTENSITYMAP":"",n.roughnessMap?"#define USE_ROUGHNESSMAP":"",n.metalnessMap?"#define USE_METALNESSMAP":"",n.alphaMap?"#define USE_ALPHAMAP":"",n.alphaHash?"#define USE_ALPHAHASH":"",n.transmission?"#define USE_TRANSMISSION":"",n.transmissionMap?"#define USE_TRANSMISSIONMAP":"",n.thicknessMap?"#define USE_THICKNESSMAP":"",n.sheenColorMap?"#define USE_SHEEN_COLORMAP":"",n.sheenRoughnessMap?"#define USE_SHEEN_ROUGHNESSMAP":"",n.mapUv?"#define MAP_UV "+n.mapUv:"",n.alphaMapUv?"#define ALPHAMAP_UV "+n.alphaMapUv:"",n.lightMapUv?"#define LIGHTMAP_UV "+n.lightMapUv:"",n.aoMapUv?"#define AOMAP_UV "+n.aoMapUv:"",n.emissiveMapUv?"#define EMISSIVEMAP_UV "+n.emissiveMapUv:"",n.bumpMapUv?"#define BUMPMAP_UV "+n.bumpMapUv:"",n.normalMapUv?"#define NORMALMAP_UV "+n.normalMapUv:"",n.displacementMapUv?"#define DISPLACEMENTMAP_UV "+n.displacementMapUv:"",n.metalnessMapUv?"#define METALNESSMAP_UV "+n.metalnessMapUv:"",n.roughnessMapUv?"#define ROUGHNESSMAP_UV "+n.roughnessMapUv:"",n.anisotropyMapUv?"#define ANISOTROPYMAP_UV "+n.anisotropyMapUv:"",n.clearcoatMapUv?"#define CLEARCOATMAP_UV "+n.clearcoatMapUv:"",n.clearcoatNormalMapUv?"#define CLEARCOAT_NORMALMAP_UV "+n.clearcoatNormalMapUv:"",n.clearcoatRoughnessMapUv?"#define CLEARCOAT_ROUGHNESSMAP_UV "+n.clearcoatRoughnessMapUv:"",n.iridescenceMapUv?"#define IRIDESCENCEMAP_UV "+n.iridescenceMapUv:"",n.iridescenceThicknessMapUv?"#define IRIDESCENCE_THICKNESSMAP_UV "+n.iridescenceThicknessMapUv:"",n.sheenColorMapUv?"#define SHEEN_COLORMAP_UV "+n.sheenColorMapUv:"",n.sheenRoughnessMapUv?"#define SHEEN_ROUGHNESSMAP_UV "+n.sheenRoughnessMapUv:"",n.specularMapUv?"#define SPECULARMAP_UV "+n.specularMapUv:"",n.specularColorMapUv?"#define SPECULAR_COLORMAP_UV "+n.specularColorMapUv:"",n.specularIntensityMapUv?"#define SPECULAR_INTENSITYMAP_UV "+n.specularIntensityMapUv:"",n.transmissionMapUv?"#define TRANSMISSIONMAP_UV "+n.transmissionMapUv:"",n.thicknessMapUv?"#define THICKNESSMAP_UV "+n.thicknessMapUv:"",n.vertexTangents&&n.flatShading===!1?"#define USE_TANGENT":"",n.vertexColors?"#define USE_COLOR":"",n.vertexAlphas?"#define USE_COLOR_ALPHA":"",n.vertexUv1s?"#define USE_UV1":"",n.vertexUv2s?"#define USE_UV2":"",n.vertexUv3s?"#define USE_UV3":"",n.pointsUvs?"#define USE_POINTS_UV":"",n.flatShading?"#define FLAT_SHADED":"",n.skinning?"#define USE_SKINNING":"",n.morphTargets?"#define USE_MORPHTARGETS":"",n.morphNormals&&n.flatShading===!1?"#define USE_MORPHNORMALS":"",n.morphColors?"#define USE_MORPHCOLORS":"",n.morphTargetsCount>0?"#define MORPHTARGETS_TEXTURE_STRIDE "+n.morphTextureStride:"",n.morphTargetsCount>0?"#define MORPHTARGETS_COUNT "+n.morphTargetsCount:"",n.doubleSided?"#define DOUBLE_SIDED":"",n.flipSided?"#define FLIP_SIDED":"",n.shadowMapEnabled?"#define USE_SHADOWMAP":"",n.shadowMapEnabled?"#define "+m:"",n.sizeAttenuation?"#define USE_SIZEATTENUATION":"",n.numLightProbes>0?"#define USE_LIGHT_PROBES":"",n.logarithmicDepthBuffer?"#define USE_LOGARITHMIC_DEPTH_BUFFER":"",n.reversedDepthBuffer?"#define USE_REVERSED_DEPTH_BUFFER":"","uniform mat4 modelMatrix;","uniform mat4 modelViewMatrix;","uniform mat4 projectionMatrix;","uniform mat4 viewMatrix;","uniform mat3 normalMatrix;","uniform vec3 cameraPosition;","uniform bool isOrthographic;","#ifdef USE_INSTANCING"," attribute mat4 instanceMatrix;","#endif","#ifdef USE_INSTANCING_COLOR"," attribute vec3 instanceColor;","#endif","#ifdef USE_INSTANCING_MORPH"," uniform sampler2D morphTexture;","#endif","attribute vec3 position;","attribute vec3 normal;","attribute vec2 uv;","#ifdef USE_UV1"," attribute vec2 uv1;","#endif","#ifdef USE_UV2"," attribute vec2 uv2;","#endif","#ifdef USE_UV3"," attribute vec2 uv3;","#endif","#ifdef USE_TANGENT"," attribute vec4 tangent;","#endif","#if defined( USE_COLOR_ALPHA )"," attribute vec4 color;","#elif defined( USE_COLOR )"," attribute vec3 color;","#endif","#ifdef USE_SKINNING"," attribute vec4 skinIndex;"," attribute vec4 skinWeight;","#endif",` `].filter(Id).join(` `),A=[MC(n),"#define SHADER_TYPE "+n.shaderType,"#define SHADER_NAME "+n.shaderName,M,n.useFog&&n.fog?"#define USE_FOG":"",n.useFog&&n.fogExp2?"#define FOG_EXP2":"",n.alphaToCoverage?"#define ALPHA_TO_COVERAGE":"",n.map?"#define USE_MAP":"",n.matcap?"#define USE_MATCAP":"",n.envMap?"#define USE_ENVMAP":"",n.envMap?"#define "+p:"",n.envMap?"#define "+y:"",n.envMap?"#define "+v:"",x?"#define CUBEUV_TEXEL_WIDTH "+x.texelWidth:"",x?"#define CUBEUV_TEXEL_HEIGHT "+x.texelHeight:"",x?"#define CUBEUV_MAX_MIP "+x.maxMip+".0":"",n.lightMap?"#define USE_LIGHTMAP":"",n.aoMap?"#define USE_AOMAP":"",n.bumpMap?"#define USE_BUMPMAP":"",n.normalMap?"#define USE_NORMALMAP":"",n.normalMapObjectSpace?"#define USE_NORMALMAP_OBJECTSPACE":"",n.normalMapTangentSpace?"#define USE_NORMALMAP_TANGENTSPACE":"",n.emissiveMap?"#define USE_EMISSIVEMAP":"",n.anisotropy?"#define USE_ANISOTROPY":"",n.anisotropyMap?"#define USE_ANISOTROPYMAP":"",n.clearcoat?"#define USE_CLEARCOAT":"",n.clearcoatMap?"#define USE_CLEARCOATMAP":"",n.clearcoatRoughnessMap?"#define USE_CLEARCOAT_ROUGHNESSMAP":"",n.clearcoatNormalMap?"#define USE_CLEARCOAT_NORMALMAP":"",n.dispersion?"#define USE_DISPERSION":"",n.iridescence?"#define USE_IRIDESCENCE":"",n.iridescenceMap?"#define USE_IRIDESCENCEMAP":"",n.iridescenceThicknessMap?"#define USE_IRIDESCENCE_THICKNESSMAP":"",n.specularMap?"#define USE_SPECULARMAP":"",n.specularColorMap?"#define USE_SPECULAR_COLORMAP":"",n.specularIntensityMap?"#define USE_SPECULAR_INTENSITYMAP":"",n.roughnessMap?"#define USE_ROUGHNESSMAP":"",n.metalnessMap?"#define USE_METALNESSMAP":"",n.alphaMap?"#define USE_ALPHAMAP":"",n.alphaTest?"#define USE_ALPHATEST":"",n.alphaHash?"#define USE_ALPHAHASH":"",n.sheen?"#define USE_SHEEN":"",n.sheenColorMap?"#define USE_SHEEN_COLORMAP":"",n.sheenRoughnessMap?"#define USE_SHEEN_ROUGHNESSMAP":"",n.transmission?"#define USE_TRANSMISSION":"",n.transmissionMap?"#define USE_TRANSMISSIONMAP":"",n.thicknessMap?"#define USE_THICKNESSMAP":"",n.vertexTangents&&n.flatShading===!1?"#define USE_TANGENT":"",n.vertexColors||n.instancingColor||n.batchingColor?"#define USE_COLOR":"",n.vertexAlphas?"#define USE_COLOR_ALPHA":"",n.vertexUv1s?"#define USE_UV1":"",n.vertexUv2s?"#define USE_UV2":"",n.vertexUv3s?"#define USE_UV3":"",n.pointsUvs?"#define USE_POINTS_UV":"",n.gradientMap?"#define USE_GRADIENTMAP":"",n.flatShading?"#define FLAT_SHADED":"",n.doubleSided?"#define DOUBLE_SIDED":"",n.flipSided?"#define FLIP_SIDED":"",n.shadowMapEnabled?"#define USE_SHADOWMAP":"",n.shadowMapEnabled?"#define "+m:"",n.premultipliedAlpha?"#define PREMULTIPLIED_ALPHA":"",n.numLightProbes>0?"#define USE_LIGHT_PROBES":"",n.decodeVideoTexture?"#define DECODE_VIDEO_TEXTURE":"",n.decodeVideoTextureEmissive?"#define DECODE_VIDEO_TEXTURE_EMISSIVE":"",n.logarithmicDepthBuffer?"#define USE_LOGARITHMIC_DEPTH_BUFFER":"",n.reversedDepthBuffer?"#define USE_REVERSED_DEPTH_BUFFER":"","uniform mat4 viewMatrix;","uniform vec3 cameraPosition;","uniform bool isOrthographic;",n.toneMapping!==mo?"#define TONE_MAPPING":"",n.toneMapping!==mo?$t.tonemapping_pars_fragment:"",n.toneMapping!==mo?k7("toneMapping",n.toneMapping):"",n.dithering?"#define DITHERING":"",n.opaque?"#define OPAQUE":"",$t.colorspace_pars_fragment,R7("linearToOutputTexel",n.outputColorSpace),N7(),n.useDepthPacking?"#define DEPTH_PACKING "+n.depthPacking:"",` `].filter(Id).join(` `)),d=kb(d),d=AC(d,n),d=EC(d,n),h=kb(h),h=AC(h,n),h=EC(h,n),d=wC(d),h=wC(h),n.isRawShaderMaterial!==!0&&(k=`#version 300 es `,E=[S,"#define attribute in","#define varying out","#define texture2D texture"].join(` `)+` `+E,A=["#define varying in",n.glslVersion===MM?"":"layout(location = 0) out highp vec4 pc_fragColor;",n.glslVersion===MM?"":"#define gl_FragColor pc_fragColor","#define gl_FragDepthEXT gl_FragDepth","#define texture2D texture","#define textureCube texture","#define texture2DProj textureProj","#define texture2DLodEXT textureLod","#define texture2DProjLodEXT textureProjLod","#define textureCubeLodEXT textureLod","#define texture2DGradEXT textureGrad","#define texture2DProjGradEXT textureProjGrad","#define textureCubeGradEXT textureGrad"].join(` `)+` `+A);const R=k+E+d,N=k+A+h,I=yC(o,o.VERTEX_SHADER,R),z=yC(o,o.FRAGMENT_SHADER,N);o.attachShader(w,I),o.attachShader(w,z),n.index0AttributeName!==void 0?o.bindAttribLocation(w,0,n.index0AttributeName):n.morphTargets===!0&&o.bindAttribLocation(w,0,"position"),o.linkProgram(w);function j(F){if(a.debug.checkShaderErrors){const q=o.getProgramInfoLog(w)||"",J=o.getShaderInfoLog(I)||"",ie=o.getShaderInfoLog(z)||"",Q=q.trim(),V=J.trim(),$=ie.trim();let te=!0,ne=!0;if(o.getProgramParameter(w,o.LINK_STATUS)===!1)if(te=!1,typeof a.debug.onShaderError=="function")a.debug.onShaderError(o,w,I,z);else{const Y=SC(o,I,"vertex"),T=SC(o,z,"fragment");console.error("THREE.WebGLProgram: Shader Error "+o.getError()+" - VALIDATE_STATUS "+o.getProgramParameter(w,o.VALIDATE_STATUS)+` Material Name: `+F.name+` Material Type: `+F.type+` Program Info Log: `+Q+` `+Y+` `+T)}else Q!==""?console.warn("THREE.WebGLProgram: Program Info Log:",Q):(V===""||$==="")&&(ne=!1);ne&&(F.diagnostics={runnable:te,programLog:Q,vertexShader:{log:V,prefix:E},fragmentShader:{log:$,prefix:A}})}o.deleteShader(I),o.deleteShader(z),L=new Vp(o,w),D=L7(o,w)}let L;this.getUniforms=function(){return L===void 0&&j(this),L};let D;this.getAttributes=function(){return D===void 0&&j(this),D};let P=n.rendererExtensionParallelShaderCompile===!1;return this.isReady=function(){return P===!1&&(P=o.getProgramParameter(w,M7)),P},this.destroy=function(){s.releaseStatesOfProgram(this),o.deleteProgram(w),this.program=void 0},this.type=n.shaderType,this.name=n.shaderName,this.id=C7++,this.cacheKey=e,this.usedTimes=1,this.program=w,this.vertexShader=I,this.fragmentShader=z,this}let Y7=0;class X7{constructor(){this.shaderCache=new Map,this.materialCache=new Map}update(e){const n=e.vertexShader,s=e.fragmentShader,o=this._getShaderStage(n),l=this._getShaderStage(s),d=this._getShaderCacheForMaterial(e);return d.has(o)===!1&&(d.add(o),o.usedTimes++),d.has(l)===!1&&(d.add(l),l.usedTimes++),this}remove(e){const n=this.materialCache.get(e);for(const s of n)s.usedTimes--,s.usedTimes===0&&this.shaderCache.delete(s.code);return this.materialCache.delete(e),this}getVertexShaderID(e){return this._getShaderStage(e.vertexShader).id}getFragmentShaderID(e){return this._getShaderStage(e.fragmentShader).id}dispose(){this.shaderCache.clear(),this.materialCache.clear()}_getShaderCacheForMaterial(e){const n=this.materialCache;let s=n.get(e);return s===void 0&&(s=new Set,n.set(e,s)),s}_getShaderStage(e){const n=this.shaderCache;let s=n.get(e);return s===void 0&&(s=new K7(e),n.set(e,s)),s}}class K7{constructor(e){this.id=Y7++,this.code=e,this.usedTimes=0}}function J7(a,e,n,s,o,l,d){const h=new H0,m=new X7,p=new Set,y=[],v=o.logarithmicDepthBuffer,x=o.vertexTextures;let S=o.precision;const M={MeshDepthMaterial:"depth",MeshDistanceMaterial:"distanceRGBA",MeshNormalMaterial:"normal",MeshBasicMaterial:"basic",MeshLambertMaterial:"lambert",MeshPhongMaterial:"phong",MeshToonMaterial:"toon",MeshStandardMaterial:"physical",MeshPhysicalMaterial:"physical",MeshMatcapMaterial:"matcap",LineBasicMaterial:"basic",LineDashedMaterial:"dashed",PointsMaterial:"points",ShadowMaterial:"shadow",SpriteMaterial:"sprite"};function w(D){return p.add(D),D===0?"uv":`uv${D}`}function E(D,P,F,q,J){const ie=q.fog,Q=J.geometry,V=D.isMeshStandardMaterial?q.environment:null,$=(D.isMeshStandardMaterial?n:e).get(D.envMap||V),te=$&&$.mapping===qm?$.image.height:null,ne=M[D.type];D.precision!==null&&(S=o.getMaxPrecision(D.precision),S!==D.precision&&console.warn("THREE.WebGLProgram.getParameters:",D.precision,"not supported, using",S,"instead."));const Y=Q.morphAttributes.position||Q.morphAttributes.normal||Q.morphAttributes.color,T=Y!==void 0?Y.length:0;let _=0;Q.morphAttributes.position!==void 0&&(_=1),Q.morphAttributes.normal!==void 0&&(_=2),Q.morphAttributes.color!==void 0&&(_=3);let ve,je,Je,xe;if(ne){const pt=zs[ne];ve=pt.vertexShader,je=pt.fragmentShader}else ve=D.vertexShader,je=D.fragmentShader,m.update(D),Je=m.getVertexShaderID(D),xe=m.getFragmentShaderID(D);const ee=a.getRenderTarget(),Ce=a.state.buffers.depth.getReversed(),Ze=J.isInstancedMesh===!0,le=J.isBatchedMesh===!0,qe=!!D.map,xt=!!D.matcap,se=!!$,Pe=!!D.aoMap,mt=!!D.lightMap,it=!!D.bumpMap,at=!!D.normalMap,Be=!!D.displacementMap,We=!!D.emissiveMap,ue=!!D.metalnessMap,ft=!!D.roughnessMap,Re=D.anisotropy>0,K=D.clearcoat>0,B=D.dispersion>0,pe=D.iridescence>0,Ae=D.sheen>0,Ne=D.transmission>0,be=Re&&!!D.anisotropyMap,ot=K&&!!D.clearcoatMap,Ve=K&&!!D.clearcoatNormalMap,ut=K&&!!D.clearcoatRoughnessMap,re=pe&&!!D.iridescenceMap,Se=pe&&!!D.iridescenceThicknessMap,He=Ae&&!!D.sheenColorMap,lt=Ae&&!!D.sheenRoughnessMap,tt=!!D.specularMap,ct=!!D.specularColorMap,fe=!!D.specularIntensityMap,oe=Ne&&!!D.transmissionMap,Fe=Ne&&!!D.thicknessMap,Xe=!!D.gradientMap,dt=!!D.alphaMap,W=D.alphaTest>0,U=!!D.alphaHash,ce=!!D.extensions;let G=mo;D.toneMapped&&(ee===null||ee.isXRRenderTarget===!0)&&(G=a.toneMapping);const ke={shaderID:ne,shaderType:D.type,shaderName:D.name,vertexShader:ve,fragmentShader:je,defines:D.defines,customVertexShaderID:Je,customFragmentShaderID:xe,isRawShaderMaterial:D.isRawShaderMaterial===!0,glslVersion:D.glslVersion,precision:S,batching:le,batchingColor:le&&J._colorsTexture!==null,instancing:Ze,instancingColor:Ze&&J.instanceColor!==null,instancingMorph:Ze&&J.morphTexture!==null,supportsVertexTextures:x,outputColorSpace:ee===null?a.outputColorSpace:ee.isXRRenderTarget===!0?ee.texture.colorSpace:lu,alphaToCoverage:!!D.alphaToCoverage,map:qe,matcap:xt,envMap:se,envMapMode:se&&$.mapping,envMapCubeUVHeight:te,aoMap:Pe,lightMap:mt,bumpMap:it,normalMap:at,displacementMap:x&&Be,emissiveMap:We,normalMapObjectSpace:at&&D.normalMapType===vH,normalMapTangentSpace:at&&D.normalMapType===Ym,metalnessMap:ue,roughnessMap:ft,anisotropy:Re,anisotropyMap:be,clearcoat:K,clearcoatMap:ot,clearcoatNormalMap:Ve,clearcoatRoughnessMap:ut,dispersion:B,iridescence:pe,iridescenceMap:re,iridescenceThicknessMap:Se,sheen:Ae,sheenColorMap:He,sheenRoughnessMap:lt,specularMap:tt,specularColorMap:ct,specularIntensityMap:fe,transmission:Ne,transmissionMap:oe,thicknessMap:Fe,gradientMap:Xe,opaque:D.transparent===!1&&D.blending===Qc&&D.alphaToCoverage===!1,alphaMap:dt,alphaTest:W,alphaHash:U,combine:D.combine,mapUv:qe&&w(D.map.channel),aoMapUv:Pe&&w(D.aoMap.channel),lightMapUv:mt&&w(D.lightMap.channel),bumpMapUv:it&&w(D.bumpMap.channel),normalMapUv:at&&w(D.normalMap.channel),displacementMapUv:Be&&w(D.displacementMap.channel),emissiveMapUv:We&&w(D.emissiveMap.channel),metalnessMapUv:ue&&w(D.metalnessMap.channel),roughnessMapUv:ft&&w(D.roughnessMap.channel),anisotropyMapUv:be&&w(D.anisotropyMap.channel),clearcoatMapUv:ot&&w(D.clearcoatMap.channel),clearcoatNormalMapUv:Ve&&w(D.clearcoatNormalMap.channel),clearcoatRoughnessMapUv:ut&&w(D.clearcoatRoughnessMap.channel),iridescenceMapUv:re&&w(D.iridescenceMap.channel),iridescenceThicknessMapUv:Se&&w(D.iridescenceThicknessMap.channel),sheenColorMapUv:He&&w(D.sheenColorMap.channel),sheenRoughnessMapUv:lt&&w(D.sheenRoughnessMap.channel),specularMapUv:tt&&w(D.specularMap.channel),specularColorMapUv:ct&&w(D.specularColorMap.channel),specularIntensityMapUv:fe&&w(D.specularIntensityMap.channel),transmissionMapUv:oe&&w(D.transmissionMap.channel),thicknessMapUv:Fe&&w(D.thicknessMap.channel),alphaMapUv:dt&&w(D.alphaMap.channel),vertexTangents:!!Q.attributes.tangent&&(at||Re),vertexColors:D.vertexColors,vertexAlphas:D.vertexColors===!0&&!!Q.attributes.color&&Q.attributes.color.itemSize===4,pointsUvs:J.isPoints===!0&&!!Q.attributes.uv&&(qe||dt),fog:!!ie,useFog:D.fog===!0,fogExp2:!!ie&&ie.isFogExp2,flatShading:D.flatShading===!0&&D.wireframe===!1,sizeAttenuation:D.sizeAttenuation===!0,logarithmicDepthBuffer:v,reversedDepthBuffer:Ce,skinning:J.isSkinnedMesh===!0,morphTargets:Q.morphAttributes.position!==void 0,morphNormals:Q.morphAttributes.normal!==void 0,morphColors:Q.morphAttributes.color!==void 0,morphTargetsCount:T,morphTextureStride:_,numDirLights:P.directional.length,numPointLights:P.point.length,numSpotLights:P.spot.length,numSpotLightMaps:P.spotLightMap.length,numRectAreaLights:P.rectArea.length,numHemiLights:P.hemi.length,numDirLightShadows:P.directionalShadowMap.length,numPointLightShadows:P.pointShadowMap.length,numSpotLightShadows:P.spotShadowMap.length,numSpotLightShadowsWithMaps:P.numSpotLightShadowsWithMaps,numLightProbes:P.numLightProbes,numClippingPlanes:d.numPlanes,numClipIntersection:d.numIntersection,dithering:D.dithering,shadowMapEnabled:a.shadowMap.enabled&&F.length>0,shadowMapType:a.shadowMap.type,toneMapping:G,decodeVideoTexture:qe&&D.map.isVideoTexture===!0&&pn.getTransfer(D.map.colorSpace)===Mn,decodeVideoTextureEmissive:We&&D.emissiveMap.isVideoTexture===!0&&pn.getTransfer(D.emissiveMap.colorSpace)===Mn,premultipliedAlpha:D.premultipliedAlpha,doubleSided:D.side===mr,flipSided:D.side===ai,useDepthPacking:D.depthPacking>=0,depthPacking:D.depthPacking||0,index0AttributeName:D.index0AttributeName,extensionClipCullDistance:ce&&D.extensions.clipCullDistance===!0&&s.has("WEBGL_clip_cull_distance"),extensionMultiDraw:(ce&&D.extensions.multiDraw===!0||le)&&s.has("WEBGL_multi_draw"),rendererExtensionParallelShaderCompile:s.has("KHR_parallel_shader_compile"),customProgramCacheKey:D.customProgramCacheKey()};return ke.vertexUv1s=p.has(1),ke.vertexUv2s=p.has(2),ke.vertexUv3s=p.has(3),p.clear(),ke}function A(D){const P=[];if(D.shaderID?P.push(D.shaderID):(P.push(D.customVertexShaderID),P.push(D.customFragmentShaderID)),D.defines!==void 0)for(const F in D.defines)P.push(F),P.push(D.defines[F]);return D.isRawShaderMaterial===!1&&(k(P,D),R(P,D),P.push(a.outputColorSpace)),P.push(D.customProgramCacheKey),P.join()}function k(D,P){D.push(P.precision),D.push(P.outputColorSpace),D.push(P.envMapMode),D.push(P.envMapCubeUVHeight),D.push(P.mapUv),D.push(P.alphaMapUv),D.push(P.lightMapUv),D.push(P.aoMapUv),D.push(P.bumpMapUv),D.push(P.normalMapUv),D.push(P.displacementMapUv),D.push(P.emissiveMapUv),D.push(P.metalnessMapUv),D.push(P.roughnessMapUv),D.push(P.anisotropyMapUv),D.push(P.clearcoatMapUv),D.push(P.clearcoatNormalMapUv),D.push(P.clearcoatRoughnessMapUv),D.push(P.iridescenceMapUv),D.push(P.iridescenceThicknessMapUv),D.push(P.sheenColorMapUv),D.push(P.sheenRoughnessMapUv),D.push(P.specularMapUv),D.push(P.specularColorMapUv),D.push(P.specularIntensityMapUv),D.push(P.transmissionMapUv),D.push(P.thicknessMapUv),D.push(P.combine),D.push(P.fogExp2),D.push(P.sizeAttenuation),D.push(P.morphTargetsCount),D.push(P.morphAttributeCount),D.push(P.numDirLights),D.push(P.numPointLights),D.push(P.numSpotLights),D.push(P.numSpotLightMaps),D.push(P.numHemiLights),D.push(P.numRectAreaLights),D.push(P.numDirLightShadows),D.push(P.numPointLightShadows),D.push(P.numSpotLightShadows),D.push(P.numSpotLightShadowsWithMaps),D.push(P.numLightProbes),D.push(P.shadowMapType),D.push(P.toneMapping),D.push(P.numClippingPlanes),D.push(P.numClipIntersection),D.push(P.depthPacking)}function R(D,P){h.disableAll(),P.supportsVertexTextures&&h.enable(0),P.instancing&&h.enable(1),P.instancingColor&&h.enable(2),P.instancingMorph&&h.enable(3),P.matcap&&h.enable(4),P.envMap&&h.enable(5),P.normalMapObjectSpace&&h.enable(6),P.normalMapTangentSpace&&h.enable(7),P.clearcoat&&h.enable(8),P.iridescence&&h.enable(9),P.alphaTest&&h.enable(10),P.vertexColors&&h.enable(11),P.vertexAlphas&&h.enable(12),P.vertexUv1s&&h.enable(13),P.vertexUv2s&&h.enable(14),P.vertexUv3s&&h.enable(15),P.vertexTangents&&h.enable(16),P.anisotropy&&h.enable(17),P.alphaHash&&h.enable(18),P.batching&&h.enable(19),P.dispersion&&h.enable(20),P.batchingColor&&h.enable(21),P.gradientMap&&h.enable(22),D.push(h.mask),h.disableAll(),P.fog&&h.enable(0),P.useFog&&h.enable(1),P.flatShading&&h.enable(2),P.logarithmicDepthBuffer&&h.enable(3),P.reversedDepthBuffer&&h.enable(4),P.skinning&&h.enable(5),P.morphTargets&&h.enable(6),P.morphNormals&&h.enable(7),P.morphColors&&h.enable(8),P.premultipliedAlpha&&h.enable(9),P.shadowMapEnabled&&h.enable(10),P.doubleSided&&h.enable(11),P.flipSided&&h.enable(12),P.useDepthPacking&&h.enable(13),P.dithering&&h.enable(14),P.transmission&&h.enable(15),P.sheen&&h.enable(16),P.opaque&&h.enable(17),P.pointsUvs&&h.enable(18),P.decodeVideoTexture&&h.enable(19),P.decodeVideoTextureEmissive&&h.enable(20),P.alphaToCoverage&&h.enable(21),D.push(h.mask)}function N(D){const P=M[D.type];let F;if(P){const q=zs[P];F=ul.clone(q.uniforms)}else F=D.uniforms;return F}function I(D,P){let F;for(let q=0,J=y.length;q0?s.push(A):S.transparent===!0?o.push(A):n.push(A)}function m(v,x,S,M,w,E){const A=d(v,x,S,M,w,E);S.transmission>0?s.unshift(A):S.transparent===!0?o.unshift(A):n.unshift(A)}function p(v,x){n.length>1&&n.sort(v||Q7),s.length>1&&s.sort(x||CC),o.length>1&&o.sort(x||CC)}function y(){for(let v=e,x=a.length;v=l.length?(d=new TC,l.push(d)):d=l[o],d}function n(){a=new WeakMap}return{get:e,dispose:n}}function $7(){const a={};return{get:function(e){if(a[e.id]!==void 0)return a[e.id];let n;switch(e.type){case"DirectionalLight":n={direction:new he,color:new tn};break;case"SpotLight":n={position:new he,direction:new he,color:new tn,distance:0,coneCos:0,penumbraCos:0,decay:0};break;case"PointLight":n={position:new he,color:new tn,distance:0,decay:0};break;case"HemisphereLight":n={direction:new he,skyColor:new tn,groundColor:new tn};break;case"RectAreaLight":n={color:new tn,position:new he,halfWidth:new he,halfHeight:new he};break}return a[e.id]=n,n}}}function eq(){const a={};return{get:function(e){if(a[e.id]!==void 0)return a[e.id];let n;switch(e.type){case"DirectionalLight":n={shadowIntensity:1,shadowBias:0,shadowNormalBias:0,shadowRadius:1,shadowMapSize:new jt};break;case"SpotLight":n={shadowIntensity:1,shadowBias:0,shadowNormalBias:0,shadowRadius:1,shadowMapSize:new jt};break;case"PointLight":n={shadowIntensity:1,shadowBias:0,shadowNormalBias:0,shadowRadius:1,shadowMapSize:new jt,shadowCameraNear:1,shadowCameraFar:1e3};break}return a[e.id]=n,n}}}let tq=0;function nq(a,e){return(e.castShadow?2:0)-(a.castShadow?2:0)+(e.map?1:0)-(a.map?1:0)}function aq(a){const e=new $7,n=eq(),s={version:0,hash:{directionalLength:-1,pointLength:-1,spotLength:-1,rectAreaLength:-1,hemiLength:-1,numDirectionalShadows:-1,numPointShadows:-1,numSpotShadows:-1,numSpotMaps:-1,numLightProbes:-1},ambient:[0,0,0],probe:[],directional:[],directionalShadow:[],directionalShadowMap:[],directionalShadowMatrix:[],spot:[],spotLightMap:[],spotShadow:[],spotShadowMap:[],spotLightMatrix:[],rectArea:[],rectAreaLTC1:null,rectAreaLTC2:null,point:[],pointShadow:[],pointShadowMap:[],pointShadowMatrix:[],hemi:[],numSpotLightShadowsWithMaps:0,numLightProbes:0};for(let p=0;p<9;p++)s.probe.push(new he);const o=new he,l=new dn,d=new dn;function h(p){let y=0,v=0,x=0;for(let D=0;D<9;D++)s.probe[D].set(0,0,0);let S=0,M=0,w=0,E=0,A=0,k=0,R=0,N=0,I=0,z=0,j=0;p.sort(nq);for(let D=0,P=p.length;D0&&(a.has("OES_texture_float_linear")===!0?(s.rectAreaLTC1=At.LTC_FLOAT_1,s.rectAreaLTC2=At.LTC_FLOAT_2):(s.rectAreaLTC1=At.LTC_HALF_1,s.rectAreaLTC2=At.LTC_HALF_2)),s.ambient[0]=y,s.ambient[1]=v,s.ambient[2]=x;const L=s.hash;(L.directionalLength!==S||L.pointLength!==M||L.spotLength!==w||L.rectAreaLength!==E||L.hemiLength!==A||L.numDirectionalShadows!==k||L.numPointShadows!==R||L.numSpotShadows!==N||L.numSpotMaps!==I||L.numLightProbes!==j)&&(s.directional.length=S,s.spot.length=w,s.rectArea.length=E,s.point.length=M,s.hemi.length=A,s.directionalShadow.length=k,s.directionalShadowMap.length=k,s.pointShadow.length=R,s.pointShadowMap.length=R,s.spotShadow.length=N,s.spotShadowMap.length=N,s.directionalShadowMatrix.length=k,s.pointShadowMatrix.length=R,s.spotLightMatrix.length=N+I-z,s.spotLightMap.length=I,s.numSpotLightShadowsWithMaps=z,s.numLightProbes=j,L.directionalLength=S,L.pointLength=M,L.spotLength=w,L.rectAreaLength=E,L.hemiLength=A,L.numDirectionalShadows=k,L.numPointShadows=R,L.numSpotShadows=N,L.numSpotMaps=I,L.numLightProbes=j,s.version=tq++)}function m(p,y){let v=0,x=0,S=0,M=0,w=0;const E=y.matrixWorldInverse;for(let A=0,k=p.length;A=d.length?(h=new jC(a),d.push(h)):h=d[l],h}function s(){e=new WeakMap}return{get:n,dispose:s}}const sq=`void main() { gl_Position = vec4( position, 1.0 ); }`,rq=`uniform sampler2D shadow_pass; uniform vec2 resolution; uniform float radius; #include void main() { const float samples = float( VSM_SAMPLES ); float mean = 0.0; float squared_mean = 0.0; float uvStride = samples <= 1.0 ? 0.0 : 2.0 / ( samples - 1.0 ); float uvStart = samples <= 1.0 ? 0.0 : - 1.0; for ( float i = 0.0; i < samples; i ++ ) { float uvOffset = uvStart + i * uvStride; #ifdef HORIZONTAL_PASS vec2 distribution = unpackRGBATo2Half( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( uvOffset, 0.0 ) * radius ) / resolution ) ); mean += distribution.x; squared_mean += distribution.y * distribution.y + distribution.x * distribution.x; #else float depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( 0.0, uvOffset ) * radius ) / resolution ) ); mean += depth; squared_mean += depth * depth; #endif } mean = mean / samples; squared_mean = squared_mean / samples; float std_dev = sqrt( squared_mean - mean * mean ); gl_FragColor = pack2HalfToRGBA( vec2( mean, std_dev ) ); }`;function oq(a,e,n){let s=new V0;const o=new jt,l=new jt,d=new On,h=new T6({depthPacking:gH}),m=new j6,p={},y=n.maxTextureSize,v={[Ao]:ai,[ai]:Ao,[mr]:mr},x=new _a({defines:{VSM_SAMPLES:8},uniforms:{shadow_pass:{value:null},resolution:{value:new jt},radius:{value:4}},vertexShader:sq,fragmentShader:rq}),S=x.clone();S.defines.HORIZONTAL_PASS=1;const M=new Oa;M.setAttribute("position",new as(new Float32Array([-1,-1,.5,3,-1,.5,-1,3,.5]),3));const w=new zn(M,x),E=this;this.enabled=!1,this.autoUpdate=!0,this.needsUpdate=!1,this.type=Rk;let A=this.type;this.render=function(z,j,L){if(E.enabled===!1||E.autoUpdate===!1&&E.needsUpdate===!1||z.length===0)return;const D=a.getRenderTarget(),P=a.getActiveCubeFace(),F=a.getActiveMipmapLevel(),q=a.state;q.setBlending(Ja),q.buffers.depth.getReversed()===!0?q.buffers.color.setClear(0,0,0,0):q.buffers.color.setClear(1,1,1,1),q.buffers.depth.setTest(!0),q.setScissorTest(!1);const J=A!==fr&&this.type===fr,ie=A===fr&&this.type!==fr;for(let Q=0,V=z.length;Qy||o.y>y)&&(o.x>y&&(l.x=Math.floor(y/ne.x),o.x=l.x*ne.x,te.mapSize.x=l.x),o.y>y&&(l.y=Math.floor(y/ne.y),o.y=l.y*ne.y,te.mapSize.y=l.y)),te.map===null||J===!0||ie===!0){const T=this.type!==fr?{minFilter:ii,magFilter:ii}:{};te.map!==null&&te.map.dispose(),te.map=new As(o.x,o.y,T),te.map.texture.name=$.name+".shadowMap",te.camera.updateProjectionMatrix()}a.setRenderTarget(te.map),a.clear();const Y=te.getViewportCount();for(let T=0;T0||j.map&&j.alphaTest>0||j.alphaToCoverage===!0){const q=P.uuid,J=j.uuid;let ie=p[q];ie===void 0&&(ie={},p[q]=ie);let Q=ie[J];Q===void 0&&(Q=P.clone(),ie[J]=Q,j.addEventListener("dispose",I)),P=Q}if(P.visible=j.visible,P.wireframe=j.wireframe,D===fr?P.side=j.shadowSide!==null?j.shadowSide:j.side:P.side=j.shadowSide!==null?j.shadowSide:v[j.side],P.alphaMap=j.alphaMap,P.alphaTest=j.alphaToCoverage===!0?.5:j.alphaTest,P.map=j.map,P.clipShadows=j.clipShadows,P.clippingPlanes=j.clippingPlanes,P.clipIntersection=j.clipIntersection,P.displacementMap=j.displacementMap,P.displacementScale=j.displacementScale,P.displacementBias=j.displacementBias,P.wireframeLinewidth=j.wireframeLinewidth,P.linewidth=j.linewidth,L.isPointLight===!0&&P.isMeshDistanceMaterial===!0){const q=a.properties.get(P);q.light=L}return P}function N(z,j,L,D,P){if(z.visible===!1)return;if(z.layers.test(j.layers)&&(z.isMesh||z.isLine||z.isPoints)&&(z.castShadow||z.receiveShadow&&P===fr)&&(!z.frustumCulled||s.intersectsObject(z))){z.modelViewMatrix.multiplyMatrices(L.matrixWorldInverse,z.matrixWorld);const J=e.update(z),ie=z.material;if(Array.isArray(ie)){const Q=J.groups;for(let V=0,$=Q.length;V<$;V++){const te=Q[V],ne=ie[te.materialIndex];if(ne&&ne.visible){const Y=R(z,ne,D,P);z.onBeforeShadow(a,z,j,L,J,Y,te),a.renderBufferDirect(L,null,J,Y,z,te),z.onAfterShadow(a,z,j,L,J,Y,te)}}}else if(ie.visible){const Q=R(z,ie,D,P);z.onBeforeShadow(a,z,j,L,J,Q,null),a.renderBufferDirect(L,null,J,Q,z,null),z.onAfterShadow(a,z,j,L,J,Q,null)}}const q=z.children;for(let J=0,ie=q.length;J=1):te.indexOf("OpenGL ES")!==-1&&($=parseFloat(/^OpenGL ES (\d)/.exec(te)[1]),V=$>=2);let ne=null,Y={};const T=a.getParameter(a.SCISSOR_BOX),_=a.getParameter(a.VIEWPORT),ve=new On().fromArray(T),je=new On().fromArray(_);function Je(oe,Fe,Xe,dt){const W=new Uint8Array(4),U=a.createTexture();a.bindTexture(oe,U),a.texParameteri(oe,a.TEXTURE_MIN_FILTER,a.NEAREST),a.texParameteri(oe,a.TEXTURE_MAG_FILTER,a.NEAREST);for(let ce=0;ce"u"?!1:/OculusBrowser/g.test(navigator.userAgent),p=new jt,y=new WeakMap;let v;const x=new WeakMap;let S=!1;try{S=typeof OffscreenCanvas<"u"&&new OffscreenCanvas(1,1).getContext("2d")!==null}catch{}function M(K,B){return S?new OffscreenCanvas(K,B):pm("canvas")}function w(K,B,pe){let Ae=1;const Ne=Re(K);if((Ne.width>pe||Ne.height>pe)&&(Ae=pe/Math.max(Ne.width,Ne.height)),Ae<1)if(typeof HTMLImageElement<"u"&&K instanceof HTMLImageElement||typeof HTMLCanvasElement<"u"&&K instanceof HTMLCanvasElement||typeof ImageBitmap<"u"&&K instanceof ImageBitmap||typeof VideoFrame<"u"&&K instanceof VideoFrame){const be=Math.floor(Ae*Ne.width),ot=Math.floor(Ae*Ne.height);v===void 0&&(v=M(be,ot));const Ve=B?M(be,ot):v;return Ve.width=be,Ve.height=ot,Ve.getContext("2d").drawImage(K,0,0,be,ot),console.warn("THREE.WebGLRenderer: Texture has been resized from ("+Ne.width+"x"+Ne.height+") to ("+be+"x"+ot+")."),Ve}else return"data"in K&&console.warn("THREE.WebGLRenderer: Image in DataTexture is too big ("+Ne.width+"x"+Ne.height+")."),K;return K}function E(K){return K.generateMipmaps}function A(K){a.generateMipmap(K)}function k(K){return K.isWebGLCubeRenderTarget?a.TEXTURE_CUBE_MAP:K.isWebGL3DRenderTarget?a.TEXTURE_3D:K.isWebGLArrayRenderTarget||K.isCompressedArrayTexture?a.TEXTURE_2D_ARRAY:a.TEXTURE_2D}function R(K,B,pe,Ae,Ne=!1){if(K!==null){if(a[K]!==void 0)return a[K];console.warn("THREE.WebGLRenderer: Attempt to use non-existing WebGL internal format '"+K+"'")}let be=B;if(B===a.RED&&(pe===a.FLOAT&&(be=a.R32F),pe===a.HALF_FLOAT&&(be=a.R16F),pe===a.UNSIGNED_BYTE&&(be=a.R8)),B===a.RED_INTEGER&&(pe===a.UNSIGNED_BYTE&&(be=a.R8UI),pe===a.UNSIGNED_SHORT&&(be=a.R16UI),pe===a.UNSIGNED_INT&&(be=a.R32UI),pe===a.BYTE&&(be=a.R8I),pe===a.SHORT&&(be=a.R16I),pe===a.INT&&(be=a.R32I)),B===a.RG&&(pe===a.FLOAT&&(be=a.RG32F),pe===a.HALF_FLOAT&&(be=a.RG16F),pe===a.UNSIGNED_BYTE&&(be=a.RG8)),B===a.RG_INTEGER&&(pe===a.UNSIGNED_BYTE&&(be=a.RG8UI),pe===a.UNSIGNED_SHORT&&(be=a.RG16UI),pe===a.UNSIGNED_INT&&(be=a.RG32UI),pe===a.BYTE&&(be=a.RG8I),pe===a.SHORT&&(be=a.RG16I),pe===a.INT&&(be=a.RG32I)),B===a.RGB_INTEGER&&(pe===a.UNSIGNED_BYTE&&(be=a.RGB8UI),pe===a.UNSIGNED_SHORT&&(be=a.RGB16UI),pe===a.UNSIGNED_INT&&(be=a.RGB32UI),pe===a.BYTE&&(be=a.RGB8I),pe===a.SHORT&&(be=a.RGB16I),pe===a.INT&&(be=a.RGB32I)),B===a.RGBA_INTEGER&&(pe===a.UNSIGNED_BYTE&&(be=a.RGBA8UI),pe===a.UNSIGNED_SHORT&&(be=a.RGBA16UI),pe===a.UNSIGNED_INT&&(be=a.RGBA32UI),pe===a.BYTE&&(be=a.RGBA8I),pe===a.SHORT&&(be=a.RGBA16I),pe===a.INT&&(be=a.RGBA32I)),B===a.RGB&&(pe===a.UNSIGNED_INT_5_9_9_9_REV&&(be=a.RGB9_E5),pe===a.UNSIGNED_INT_10F_11F_11F_REV&&(be=a.R11F_G11F_B10F)),B===a.RGBA){const ot=Ne?hm:pn.getTransfer(Ae);pe===a.FLOAT&&(be=a.RGBA32F),pe===a.HALF_FLOAT&&(be=a.RGBA16F),pe===a.UNSIGNED_BYTE&&(be=ot===Mn?a.SRGB8_ALPHA8:a.RGBA8),pe===a.UNSIGNED_SHORT_4_4_4_4&&(be=a.RGBA4),pe===a.UNSIGNED_SHORT_5_5_5_1&&(be=a.RGB5_A1)}return(be===a.R16F||be===a.R32F||be===a.RG16F||be===a.RG32F||be===a.RGBA16F||be===a.RGBA32F)&&e.get("EXT_color_buffer_float"),be}function N(K,B){let pe;return K?B===null||B===wl||B===ru?pe=a.DEPTH24_STENCIL8:B===bs?pe=a.DEPTH32F_STENCIL8:B===nh&&(pe=a.DEPTH24_STENCIL8,console.warn("DepthTexture: 16 bit depth attachment is not supported with stencil. Using 24-bit attachment.")):B===null||B===wl||B===ru?pe=a.DEPTH_COMPONENT24:B===bs?pe=a.DEPTH_COMPONENT32F:B===nh&&(pe=a.DEPTH_COMPONENT16),pe}function I(K,B){return E(K)===!0||K.isFramebufferTexture&&K.minFilter!==ii&&K.minFilter!==Is?Math.log2(Math.max(B.width,B.height))+1:K.mipmaps!==void 0&&K.mipmaps.length>0?K.mipmaps.length:K.isCompressedTexture&&Array.isArray(K.image)?B.mipmaps.length:1}function z(K){const B=K.target;B.removeEventListener("dispose",z),L(B),B.isVideoTexture&&y.delete(B)}function j(K){const B=K.target;B.removeEventListener("dispose",j),P(B)}function L(K){const B=s.get(K);if(B.__webglInit===void 0)return;const pe=K.source,Ae=x.get(pe);if(Ae){const Ne=Ae[B.__cacheKey];Ne.usedTimes--,Ne.usedTimes===0&&D(K),Object.keys(Ae).length===0&&x.delete(pe)}s.remove(K)}function D(K){const B=s.get(K);a.deleteTexture(B.__webglTexture);const pe=K.source,Ae=x.get(pe);delete Ae[B.__cacheKey],d.memory.textures--}function P(K){const B=s.get(K);if(K.depthTexture&&(K.depthTexture.dispose(),s.remove(K.depthTexture)),K.isWebGLCubeRenderTarget)for(let Ae=0;Ae<6;Ae++){if(Array.isArray(B.__webglFramebuffer[Ae]))for(let Ne=0;Ne=o.maxTextures&&console.warn("THREE.WebGLTextures: Trying to use "+K+" texture units while this GPU supports only "+o.maxTextures),F+=1,K}function ie(K){const B=[];return B.push(K.wrapS),B.push(K.wrapT),B.push(K.wrapR||0),B.push(K.magFilter),B.push(K.minFilter),B.push(K.anisotropy),B.push(K.internalFormat),B.push(K.format),B.push(K.type),B.push(K.generateMipmaps),B.push(K.premultiplyAlpha),B.push(K.flipY),B.push(K.unpackAlignment),B.push(K.colorSpace),B.join()}function Q(K,B){const pe=s.get(K);if(K.isVideoTexture&&ue(K),K.isRenderTargetTexture===!1&&K.isExternalTexture!==!0&&K.version>0&&pe.__version!==K.version){const Ae=K.image;if(Ae===null)console.warn("THREE.WebGLRenderer: Texture marked for update but no image data found.");else if(Ae.complete===!1)console.warn("THREE.WebGLRenderer: Texture marked for update but image is incomplete");else{xe(pe,K,B);return}}else K.isExternalTexture&&(pe.__webglTexture=K.sourceTexture?K.sourceTexture:null);n.bindTexture(a.TEXTURE_2D,pe.__webglTexture,a.TEXTURE0+B)}function V(K,B){const pe=s.get(K);if(K.isRenderTargetTexture===!1&&K.version>0&&pe.__version!==K.version){xe(pe,K,B);return}n.bindTexture(a.TEXTURE_2D_ARRAY,pe.__webglTexture,a.TEXTURE0+B)}function $(K,B){const pe=s.get(K);if(K.isRenderTargetTexture===!1&&K.version>0&&pe.__version!==K.version){xe(pe,K,B);return}n.bindTexture(a.TEXTURE_3D,pe.__webglTexture,a.TEXTURE0+B)}function te(K,B){const pe=s.get(K);if(K.version>0&&pe.__version!==K.version){ee(pe,K,B);return}n.bindTexture(a.TEXTURE_CUBE_MAP,pe.__webglTexture,a.TEXTURE0+B)}const ne={[th]:a.REPEAT,[ll]:a.CLAMP_TO_EDGE,[Qy]:a.MIRRORED_REPEAT},Y={[ii]:a.NEAREST,[pH]:a.NEAREST_MIPMAP_NEAREST,[qf]:a.NEAREST_MIPMAP_LINEAR,[Is]:a.LINEAR,[yx]:a.LINEAR_MIPMAP_NEAREST,[cl]:a.LINEAR_MIPMAP_LINEAR},T={[xH]:a.NEVER,[wH]:a.ALWAYS,[yH]:a.LESS,[Kk]:a.LEQUAL,[bH]:a.EQUAL,[EH]:a.GEQUAL,[SH]:a.GREATER,[AH]:a.NOTEQUAL};function _(K,B){if(B.type===bs&&e.has("OES_texture_float_linear")===!1&&(B.magFilter===Is||B.magFilter===yx||B.magFilter===qf||B.magFilter===cl||B.minFilter===Is||B.minFilter===yx||B.minFilter===qf||B.minFilter===cl)&&console.warn("THREE.WebGLRenderer: Unable to use linear filtering with floating point textures. OES_texture_float_linear not supported on this device."),a.texParameteri(K,a.TEXTURE_WRAP_S,ne[B.wrapS]),a.texParameteri(K,a.TEXTURE_WRAP_T,ne[B.wrapT]),(K===a.TEXTURE_3D||K===a.TEXTURE_2D_ARRAY)&&a.texParameteri(K,a.TEXTURE_WRAP_R,ne[B.wrapR]),a.texParameteri(K,a.TEXTURE_MAG_FILTER,Y[B.magFilter]),a.texParameteri(K,a.TEXTURE_MIN_FILTER,Y[B.minFilter]),B.compareFunction&&(a.texParameteri(K,a.TEXTURE_COMPARE_MODE,a.COMPARE_REF_TO_TEXTURE),a.texParameteri(K,a.TEXTURE_COMPARE_FUNC,T[B.compareFunction])),e.has("EXT_texture_filter_anisotropic")===!0){if(B.magFilter===ii||B.minFilter!==qf&&B.minFilter!==cl||B.type===bs&&e.has("OES_texture_float_linear")===!1)return;if(B.anisotropy>1||s.get(B).__currentAnisotropy){const pe=e.get("EXT_texture_filter_anisotropic");a.texParameterf(K,pe.TEXTURE_MAX_ANISOTROPY_EXT,Math.min(B.anisotropy,o.getMaxAnisotropy())),s.get(B).__currentAnisotropy=B.anisotropy}}}function ve(K,B){let pe=!1;K.__webglInit===void 0&&(K.__webglInit=!0,B.addEventListener("dispose",z));const Ae=B.source;let Ne=x.get(Ae);Ne===void 0&&(Ne={},x.set(Ae,Ne));const be=ie(B);if(be!==K.__cacheKey){Ne[be]===void 0&&(Ne[be]={texture:a.createTexture(),usedTimes:0},d.memory.textures++,pe=!0),Ne[be].usedTimes++;const ot=Ne[K.__cacheKey];ot!==void 0&&(Ne[K.__cacheKey].usedTimes--,ot.usedTimes===0&&D(B)),K.__cacheKey=be,K.__webglTexture=Ne[be].texture}return pe}function je(K,B,pe){return Math.floor(Math.floor(K/pe)/B)}function Je(K,B,pe,Ae){const be=K.updateRanges;if(be.length===0)n.texSubImage2D(a.TEXTURE_2D,0,0,0,B.width,B.height,pe,Ae,B.data);else{be.sort((Se,He)=>Se.start-He.start);let ot=0;for(let Se=1;Se0){oe&&Fe&&n.texStorage2D(a.TEXTURE_2D,dt,tt,fe[0].width,fe[0].height);for(let W=0,U=fe.length;W0){const ce=sC(ct.width,ct.height,B.format,B.type);for(const G of B.layerUpdates){const ke=ct.data.subarray(G*ce/ct.data.BYTES_PER_ELEMENT,(G+1)*ce/ct.data.BYTES_PER_ELEMENT);n.compressedTexSubImage3D(a.TEXTURE_2D_ARRAY,W,0,0,G,ct.width,ct.height,1,He,ke)}B.clearLayerUpdates()}else n.compressedTexSubImage3D(a.TEXTURE_2D_ARRAY,W,0,0,0,ct.width,ct.height,Se.depth,He,ct.data)}else n.compressedTexImage3D(a.TEXTURE_2D_ARRAY,W,tt,ct.width,ct.height,Se.depth,0,ct.data,0,0);else console.warn("THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()");else oe?Xe&&n.texSubImage3D(a.TEXTURE_2D_ARRAY,W,0,0,0,ct.width,ct.height,Se.depth,He,lt,ct.data):n.texImage3D(a.TEXTURE_2D_ARRAY,W,tt,ct.width,ct.height,Se.depth,0,He,lt,ct.data)}else{oe&&Fe&&n.texStorage2D(a.TEXTURE_2D,dt,tt,fe[0].width,fe[0].height);for(let W=0,U=fe.length;W0){const W=sC(Se.width,Se.height,B.format,B.type);for(const U of B.layerUpdates){const ce=Se.data.subarray(U*W/Se.data.BYTES_PER_ELEMENT,(U+1)*W/Se.data.BYTES_PER_ELEMENT);n.texSubImage3D(a.TEXTURE_2D_ARRAY,0,0,0,U,Se.width,Se.height,1,He,lt,ce)}B.clearLayerUpdates()}else n.texSubImage3D(a.TEXTURE_2D_ARRAY,0,0,0,0,Se.width,Se.height,Se.depth,He,lt,Se.data)}else n.texImage3D(a.TEXTURE_2D_ARRAY,0,tt,Se.width,Se.height,Se.depth,0,He,lt,Se.data);else if(B.isData3DTexture)oe?(Fe&&n.texStorage3D(a.TEXTURE_3D,dt,tt,Se.width,Se.height,Se.depth),Xe&&n.texSubImage3D(a.TEXTURE_3D,0,0,0,0,Se.width,Se.height,Se.depth,He,lt,Se.data)):n.texImage3D(a.TEXTURE_3D,0,tt,Se.width,Se.height,Se.depth,0,He,lt,Se.data);else if(B.isFramebufferTexture){if(Fe)if(oe)n.texStorage2D(a.TEXTURE_2D,dt,tt,Se.width,Se.height);else{let W=Se.width,U=Se.height;for(let ce=0;ce>=1,U>>=1}}else if(fe.length>0){if(oe&&Fe){const W=Re(fe[0]);n.texStorage2D(a.TEXTURE_2D,dt,tt,W.width,W.height)}for(let W=0,U=fe.length;W0&&dt++;const U=Re(He[0]);n.texStorage2D(a.TEXTURE_CUBE_MAP,dt,fe,U.width,U.height)}for(let U=0;U<6;U++)if(Se){oe?Xe&&n.texSubImage2D(a.TEXTURE_CUBE_MAP_POSITIVE_X+U,0,0,0,He[U].width,He[U].height,tt,ct,He[U].data):n.texImage2D(a.TEXTURE_CUBE_MAP_POSITIVE_X+U,0,fe,He[U].width,He[U].height,0,tt,ct,He[U].data);for(let ce=0;ce>be),lt=Math.max(1,B.height>>be);Ne===a.TEXTURE_3D||Ne===a.TEXTURE_2D_ARRAY?n.texImage3D(Ne,be,ut,He,lt,B.depth,0,ot,Ve,null):n.texImage2D(Ne,be,ut,He,lt,0,ot,Ve,null)}n.bindFramebuffer(a.FRAMEBUFFER,K),We(B)?h.framebufferTexture2DMultisampleEXT(a.FRAMEBUFFER,Ae,Ne,Se.__webglTexture,0,Be(B)):(Ne===a.TEXTURE_2D||Ne>=a.TEXTURE_CUBE_MAP_POSITIVE_X&&Ne<=a.TEXTURE_CUBE_MAP_NEGATIVE_Z)&&a.framebufferTexture2D(a.FRAMEBUFFER,Ae,Ne,Se.__webglTexture,be),n.bindFramebuffer(a.FRAMEBUFFER,null)}function Ze(K,B,pe){if(a.bindRenderbuffer(a.RENDERBUFFER,K),B.depthBuffer){const Ae=B.depthTexture,Ne=Ae&&Ae.isDepthTexture?Ae.type:null,be=N(B.stencilBuffer,Ne),ot=B.stencilBuffer?a.DEPTH_STENCIL_ATTACHMENT:a.DEPTH_ATTACHMENT,Ve=Be(B);We(B)?h.renderbufferStorageMultisampleEXT(a.RENDERBUFFER,Ve,be,B.width,B.height):pe?a.renderbufferStorageMultisample(a.RENDERBUFFER,Ve,be,B.width,B.height):a.renderbufferStorage(a.RENDERBUFFER,be,B.width,B.height),a.framebufferRenderbuffer(a.FRAMEBUFFER,ot,a.RENDERBUFFER,K)}else{const Ae=B.textures;for(let Ne=0;Ne{delete B.__boundDepthTexture,delete B.__depthDisposeCallback,Ae.removeEventListener("dispose",Ne)};Ae.addEventListener("dispose",Ne),B.__depthDisposeCallback=Ne}B.__boundDepthTexture=Ae}if(K.depthTexture&&!B.__autoAllocateDepthBuffer){if(pe)throw new Error("target.depthTexture not supported in Cube render targets");const Ae=K.texture.mipmaps;Ae&&Ae.length>0?le(B.__webglFramebuffer[0],K):le(B.__webglFramebuffer,K)}else if(pe){B.__webglDepthbuffer=[];for(let Ae=0;Ae<6;Ae++)if(n.bindFramebuffer(a.FRAMEBUFFER,B.__webglFramebuffer[Ae]),B.__webglDepthbuffer[Ae]===void 0)B.__webglDepthbuffer[Ae]=a.createRenderbuffer(),Ze(B.__webglDepthbuffer[Ae],K,!1);else{const Ne=K.stencilBuffer?a.DEPTH_STENCIL_ATTACHMENT:a.DEPTH_ATTACHMENT,be=B.__webglDepthbuffer[Ae];a.bindRenderbuffer(a.RENDERBUFFER,be),a.framebufferRenderbuffer(a.FRAMEBUFFER,Ne,a.RENDERBUFFER,be)}}else{const Ae=K.texture.mipmaps;if(Ae&&Ae.length>0?n.bindFramebuffer(a.FRAMEBUFFER,B.__webglFramebuffer[0]):n.bindFramebuffer(a.FRAMEBUFFER,B.__webglFramebuffer),B.__webglDepthbuffer===void 0)B.__webglDepthbuffer=a.createRenderbuffer(),Ze(B.__webglDepthbuffer,K,!1);else{const Ne=K.stencilBuffer?a.DEPTH_STENCIL_ATTACHMENT:a.DEPTH_ATTACHMENT,be=B.__webglDepthbuffer;a.bindRenderbuffer(a.RENDERBUFFER,be),a.framebufferRenderbuffer(a.FRAMEBUFFER,Ne,a.RENDERBUFFER,be)}}n.bindFramebuffer(a.FRAMEBUFFER,null)}function xt(K,B,pe){const Ae=s.get(K);B!==void 0&&Ce(Ae.__webglFramebuffer,K,K.texture,a.COLOR_ATTACHMENT0,a.TEXTURE_2D,0),pe!==void 0&&qe(K)}function se(K){const B=K.texture,pe=s.get(K),Ae=s.get(B);K.addEventListener("dispose",j);const Ne=K.textures,be=K.isWebGLCubeRenderTarget===!0,ot=Ne.length>1;if(ot||(Ae.__webglTexture===void 0&&(Ae.__webglTexture=a.createTexture()),Ae.__version=B.version,d.memory.textures++),be){pe.__webglFramebuffer=[];for(let Ve=0;Ve<6;Ve++)if(B.mipmaps&&B.mipmaps.length>0){pe.__webglFramebuffer[Ve]=[];for(let ut=0;ut0){pe.__webglFramebuffer=[];for(let Ve=0;Ve0&&We(K)===!1){pe.__webglMultisampledFramebuffer=a.createFramebuffer(),pe.__webglColorRenderbuffer=[],n.bindFramebuffer(a.FRAMEBUFFER,pe.__webglMultisampledFramebuffer);for(let Ve=0;Ve0)for(let ut=0;ut0)for(let ut=0;ut0){if(We(K)===!1){const B=K.textures,pe=K.width,Ae=K.height;let Ne=a.COLOR_BUFFER_BIT;const be=K.stencilBuffer?a.DEPTH_STENCIL_ATTACHMENT:a.DEPTH_ATTACHMENT,ot=s.get(K),Ve=B.length>1;if(Ve)for(let re=0;re0?n.bindFramebuffer(a.DRAW_FRAMEBUFFER,ot.__webglFramebuffer[0]):n.bindFramebuffer(a.DRAW_FRAMEBUFFER,ot.__webglFramebuffer);for(let re=0;re0&&e.has("WEBGL_multisampled_render_to_texture")===!0&&B.__useRenderToTexture!==!1}function ue(K){const B=d.render.frame;y.get(K)!==B&&(y.set(K,B),K.update())}function ft(K,B){const pe=K.colorSpace,Ae=K.format,Ne=K.type;return K.isCompressedTexture===!0||K.isVideoTexture===!0||pe!==lu&&pe!==co&&(pn.getTransfer(pe)===Mn?(Ae!==Ss||Ne!==Gs)&&console.warn("THREE.WebGLTextures: sRGB encoded textures have to use RGBAFormat and UnsignedByteType."):console.error("THREE.WebGLTextures: Unsupported texture color space:",pe)),B}function Re(K){return typeof HTMLImageElement<"u"&&K instanceof HTMLImageElement?(p.width=K.naturalWidth||K.width,p.height=K.naturalHeight||K.height):typeof VideoFrame<"u"&&K instanceof VideoFrame?(p.width=K.displayWidth,p.height=K.displayHeight):(p.width=K.width,p.height=K.height),p}this.allocateTextureUnit=J,this.resetTextureUnits=q,this.setTexture2D=Q,this.setTexture2DArray=V,this.setTexture3D=$,this.setTextureCube=te,this.rebindTextures=xt,this.setupRenderTarget=se,this.updateRenderTargetMipmap=Pe,this.updateMultisampleRenderTarget=at,this.setupDepthRenderbuffer=qe,this.setupFrameBufferTexture=Ce,this.useMultisampledRTT=We}function dq(a,e){function n(s,o=co){let l;const d=pn.getTransfer(o);if(s===Gs)return a.UNSIGNED_BYTE;if(s===L0)return a.UNSIGNED_SHORT_4_4_4_4;if(s===O0)return a.UNSIGNED_SHORT_5_5_5_1;if(s===Vk)return a.UNSIGNED_INT_5_9_9_9_REV;if(s===qk)return a.UNSIGNED_INT_10F_11F_11F_REV;if(s===Hk)return a.BYTE;if(s===Gk)return a.SHORT;if(s===nh)return a.UNSIGNED_SHORT;if(s===z0)return a.INT;if(s===wl)return a.UNSIGNED_INT;if(s===bs)return a.FLOAT;if(s===Er)return a.HALF_FLOAT;if(s===Wk)return a.ALPHA;if(s===Yk)return a.RGB;if(s===Ss)return a.RGBA;if(s===ah)return a.DEPTH_COMPONENT;if(s===ou)return a.DEPTH_STENCIL;if(s===Wm)return a.RED;if(s===P0)return a.RED_INTEGER;if(s===Xk)return a.RG;if(s===I0)return a.RG_INTEGER;if(s===U0)return a.RGBA_INTEGER;if(s===Fp||s===Bp||s===Hp||s===Gp)if(d===Mn)if(l=e.get("WEBGL_compressed_texture_s3tc_srgb"),l!==null){if(s===Fp)return l.COMPRESSED_SRGB_S3TC_DXT1_EXT;if(s===Bp)return l.COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;if(s===Hp)return l.COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;if(s===Gp)return l.COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT}else return null;else if(l=e.get("WEBGL_compressed_texture_s3tc"),l!==null){if(s===Fp)return l.COMPRESSED_RGB_S3TC_DXT1_EXT;if(s===Bp)return l.COMPRESSED_RGBA_S3TC_DXT1_EXT;if(s===Hp)return l.COMPRESSED_RGBA_S3TC_DXT3_EXT;if(s===Gp)return l.COMPRESSED_RGBA_S3TC_DXT5_EXT}else return null;if(s===_y||s===$y||s===eb||s===tb)if(l=e.get("WEBGL_compressed_texture_pvrtc"),l!==null){if(s===_y)return l.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;if(s===$y)return l.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;if(s===eb)return l.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;if(s===tb)return l.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}else return null;if(s===nb||s===ab||s===ib)if(l=e.get("WEBGL_compressed_texture_etc"),l!==null){if(s===nb||s===ab)return d===Mn?l.COMPRESSED_SRGB8_ETC2:l.COMPRESSED_RGB8_ETC2;if(s===ib)return d===Mn?l.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:l.COMPRESSED_RGBA8_ETC2_EAC}else return null;if(s===sb||s===rb||s===ob||s===lb||s===cb||s===ub||s===db||s===hb||s===fb||s===pb||s===mb||s===gb||s===vb||s===xb)if(l=e.get("WEBGL_compressed_texture_astc"),l!==null){if(s===sb)return d===Mn?l.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:l.COMPRESSED_RGBA_ASTC_4x4_KHR;if(s===rb)return d===Mn?l.COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:l.COMPRESSED_RGBA_ASTC_5x4_KHR;if(s===ob)return d===Mn?l.COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:l.COMPRESSED_RGBA_ASTC_5x5_KHR;if(s===lb)return d===Mn?l.COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:l.COMPRESSED_RGBA_ASTC_6x5_KHR;if(s===cb)return d===Mn?l.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:l.COMPRESSED_RGBA_ASTC_6x6_KHR;if(s===ub)return d===Mn?l.COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:l.COMPRESSED_RGBA_ASTC_8x5_KHR;if(s===db)return d===Mn?l.COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:l.COMPRESSED_RGBA_ASTC_8x6_KHR;if(s===hb)return d===Mn?l.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:l.COMPRESSED_RGBA_ASTC_8x8_KHR;if(s===fb)return d===Mn?l.COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:l.COMPRESSED_RGBA_ASTC_10x5_KHR;if(s===pb)return d===Mn?l.COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:l.COMPRESSED_RGBA_ASTC_10x6_KHR;if(s===mb)return d===Mn?l.COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:l.COMPRESSED_RGBA_ASTC_10x8_KHR;if(s===gb)return d===Mn?l.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:l.COMPRESSED_RGBA_ASTC_10x10_KHR;if(s===vb)return d===Mn?l.COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:l.COMPRESSED_RGBA_ASTC_12x10_KHR;if(s===xb)return d===Mn?l.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:l.COMPRESSED_RGBA_ASTC_12x12_KHR}else return null;if(s===yb||s===bb||s===Sb)if(l=e.get("EXT_texture_compression_bptc"),l!==null){if(s===yb)return d===Mn?l.COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:l.COMPRESSED_RGBA_BPTC_UNORM_EXT;if(s===bb)return l.COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT;if(s===Sb)return l.COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT}else return null;if(s===Ab||s===Eb||s===wb||s===Mb)if(l=e.get("EXT_texture_compression_rgtc"),l!==null){if(s===Ab)return l.COMPRESSED_RED_RGTC1_EXT;if(s===Eb)return l.COMPRESSED_SIGNED_RED_RGTC1_EXT;if(s===wb)return l.COMPRESSED_RED_GREEN_RGTC2_EXT;if(s===Mb)return l.COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT}else return null;return s===ru?a.UNSIGNED_INT_24_8:a[s]!==void 0?a[s]:null}return{convert:n}}const hq=` void main() { gl_Position = vec4( position, 1.0 ); }`,fq=` uniform sampler2DArray depthColor; uniform float depthWidth; uniform float depthHeight; void main() { vec2 coord = vec2( gl_FragCoord.x / depthWidth, gl_FragCoord.y / depthHeight ); if ( coord.x >= 1.0 ) { gl_FragDepth = texture( depthColor, vec3( coord.x - 1.0, coord.y, 1 ) ).r; } else { gl_FragDepth = texture( depthColor, vec3( coord.x, coord.y, 0 ) ).r; } }`;class pq{constructor(){this.texture=null,this.mesh=null,this.depthNear=0,this.depthFar=0}init(e,n){if(this.texture===null){const s=new uN(e.texture);(e.depthNear!==n.depthNear||e.depthFar!==n.depthFar)&&(this.depthNear=e.depthNear,this.depthFar=e.depthFar),this.texture=s}}getMesh(e){if(this.texture!==null&&this.mesh===null){const n=e.cameras[0].viewport,s=new _a({vertexShader:hq,fragmentShader:fq,uniforms:{depthColor:{value:this.texture},depthWidth:{value:n.z},depthHeight:{value:n.w}}});this.mesh=new zn(new uu(20,20),s)}return this.mesh}reset(){this.texture=null,this.mesh=null}getDepthTexture(){return this.texture}}class mq extends Rl{constructor(e,n){super();const s=this;let o=null,l=1,d=null,h="local-floor",m=1,p=null,y=null,v=null,x=null,S=null,M=null;const w=typeof XRWebGLBinding<"u",E=new pq,A={},k=n.getContextAttributes();let R=null,N=null;const I=[],z=[],j=new jt;let L=null;const D=new Ui;D.viewport=new On;const P=new Ui;P.viewport=new On;const F=[D,P],q=new z6;let J=null,ie=null;this.cameraAutoUpdate=!0,this.enabled=!1,this.isPresenting=!1,this.getController=function(xe){let ee=I[xe];return ee===void 0&&(ee=new Bx,I[xe]=ee),ee.getTargetRaySpace()},this.getControllerGrip=function(xe){let ee=I[xe];return ee===void 0&&(ee=new Bx,I[xe]=ee),ee.getGripSpace()},this.getHand=function(xe){let ee=I[xe];return ee===void 0&&(ee=new Bx,I[xe]=ee),ee.getHandSpace()};function Q(xe){const ee=z.indexOf(xe.inputSource);if(ee===-1)return;const Ce=I[ee];Ce!==void 0&&(Ce.update(xe.inputSource,xe.frame,p||d),Ce.dispatchEvent({type:xe.type,data:xe.inputSource}))}function V(){o.removeEventListener("select",Q),o.removeEventListener("selectstart",Q),o.removeEventListener("selectend",Q),o.removeEventListener("squeeze",Q),o.removeEventListener("squeezestart",Q),o.removeEventListener("squeezeend",Q),o.removeEventListener("end",V),o.removeEventListener("inputsourceschange",$);for(let xe=0;xe=0&&(z[Ze]=null,I[Ze].disconnect(Ce))}for(let ee=0;ee=z.length){z.push(Ce),Ze=qe;break}else if(z[qe]===null){z[qe]=Ce,Ze=qe;break}if(Ze===-1)break}const le=I[Ze];le&&le.connect(Ce)}}const te=new he,ne=new he;function Y(xe,ee,Ce){te.setFromMatrixPosition(ee.matrixWorld),ne.setFromMatrixPosition(Ce.matrixWorld);const Ze=te.distanceTo(ne),le=ee.projectionMatrix.elements,qe=Ce.projectionMatrix.elements,xt=le[14]/(le[10]-1),se=le[14]/(le[10]+1),Pe=(le[9]+1)/le[5],mt=(le[9]-1)/le[5],it=(le[8]-1)/le[0],at=(qe[8]+1)/qe[0],Be=xt*it,We=xt*at,ue=Ze/(-it+at),ft=ue*-it;if(ee.matrixWorld.decompose(xe.position,xe.quaternion,xe.scale),xe.translateX(ft),xe.translateZ(ue),xe.matrixWorld.compose(xe.position,xe.quaternion,xe.scale),xe.matrixWorldInverse.copy(xe.matrixWorld).invert(),le[10]===-1)xe.projectionMatrix.copy(ee.projectionMatrix),xe.projectionMatrixInverse.copy(ee.projectionMatrixInverse);else{const Re=xt+ue,K=se+ue,B=Be-ft,pe=We+(Ze-ft),Ae=Pe*se/K*Re,Ne=mt*se/K*Re;xe.projectionMatrix.makePerspective(B,pe,Ae,Ne,Re,K),xe.projectionMatrixInverse.copy(xe.projectionMatrix).invert()}}function T(xe,ee){ee===null?xe.matrixWorld.copy(xe.matrix):xe.matrixWorld.multiplyMatrices(ee.matrixWorld,xe.matrix),xe.matrixWorldInverse.copy(xe.matrixWorld).invert()}this.updateCamera=function(xe){if(o===null)return;let ee=xe.near,Ce=xe.far;E.texture!==null&&(E.depthNear>0&&(ee=E.depthNear),E.depthFar>0&&(Ce=E.depthFar)),q.near=P.near=D.near=ee,q.far=P.far=D.far=Ce,(J!==q.near||ie!==q.far)&&(o.updateRenderState({depthNear:q.near,depthFar:q.far}),J=q.near,ie=q.far),q.layers.mask=xe.layers.mask|6,D.layers.mask=q.layers.mask&3,P.layers.mask=q.layers.mask&5;const Ze=xe.parent,le=q.cameras;T(q,Ze);for(let qe=0;qe0&&(E.alphaTest.value=A.alphaTest);const k=e.get(A),R=k.envMap,N=k.envMapRotation;R&&(E.envMap.value=R,Qo.copy(N),Qo.x*=-1,Qo.y*=-1,Qo.z*=-1,R.isCubeTexture&&R.isRenderTargetTexture===!1&&(Qo.y*=-1,Qo.z*=-1),E.envMapRotation.value.setFromMatrix4(gq.makeRotationFromEuler(Qo)),E.flipEnvMap.value=R.isCubeTexture&&R.isRenderTargetTexture===!1?-1:1,E.reflectivity.value=A.reflectivity,E.ior.value=A.ior,E.refractionRatio.value=A.refractionRatio),A.lightMap&&(E.lightMap.value=A.lightMap,E.lightMapIntensity.value=A.lightMapIntensity,n(A.lightMap,E.lightMapTransform)),A.aoMap&&(E.aoMap.value=A.aoMap,E.aoMapIntensity.value=A.aoMapIntensity,n(A.aoMap,E.aoMapTransform))}function d(E,A){E.diffuse.value.copy(A.color),E.opacity.value=A.opacity,A.map&&(E.map.value=A.map,n(A.map,E.mapTransform))}function h(E,A){E.dashSize.value=A.dashSize,E.totalSize.value=A.dashSize+A.gapSize,E.scale.value=A.scale}function m(E,A,k,R){E.diffuse.value.copy(A.color),E.opacity.value=A.opacity,E.size.value=A.size*k,E.scale.value=R*.5,A.map&&(E.map.value=A.map,n(A.map,E.uvTransform)),A.alphaMap&&(E.alphaMap.value=A.alphaMap,n(A.alphaMap,E.alphaMapTransform)),A.alphaTest>0&&(E.alphaTest.value=A.alphaTest)}function p(E,A){E.diffuse.value.copy(A.color),E.opacity.value=A.opacity,E.rotation.value=A.rotation,A.map&&(E.map.value=A.map,n(A.map,E.mapTransform)),A.alphaMap&&(E.alphaMap.value=A.alphaMap,n(A.alphaMap,E.alphaMapTransform)),A.alphaTest>0&&(E.alphaTest.value=A.alphaTest)}function y(E,A){E.specular.value.copy(A.specular),E.shininess.value=Math.max(A.shininess,1e-4)}function v(E,A){A.gradientMap&&(E.gradientMap.value=A.gradientMap)}function x(E,A){E.metalness.value=A.metalness,A.metalnessMap&&(E.metalnessMap.value=A.metalnessMap,n(A.metalnessMap,E.metalnessMapTransform)),E.roughness.value=A.roughness,A.roughnessMap&&(E.roughnessMap.value=A.roughnessMap,n(A.roughnessMap,E.roughnessMapTransform)),A.envMap&&(E.envMapIntensity.value=A.envMapIntensity)}function S(E,A,k){E.ior.value=A.ior,A.sheen>0&&(E.sheenColor.value.copy(A.sheenColor).multiplyScalar(A.sheen),E.sheenRoughness.value=A.sheenRoughness,A.sheenColorMap&&(E.sheenColorMap.value=A.sheenColorMap,n(A.sheenColorMap,E.sheenColorMapTransform)),A.sheenRoughnessMap&&(E.sheenRoughnessMap.value=A.sheenRoughnessMap,n(A.sheenRoughnessMap,E.sheenRoughnessMapTransform))),A.clearcoat>0&&(E.clearcoat.value=A.clearcoat,E.clearcoatRoughness.value=A.clearcoatRoughness,A.clearcoatMap&&(E.clearcoatMap.value=A.clearcoatMap,n(A.clearcoatMap,E.clearcoatMapTransform)),A.clearcoatRoughnessMap&&(E.clearcoatRoughnessMap.value=A.clearcoatRoughnessMap,n(A.clearcoatRoughnessMap,E.clearcoatRoughnessMapTransform)),A.clearcoatNormalMap&&(E.clearcoatNormalMap.value=A.clearcoatNormalMap,n(A.clearcoatNormalMap,E.clearcoatNormalMapTransform),E.clearcoatNormalScale.value.copy(A.clearcoatNormalScale),A.side===ai&&E.clearcoatNormalScale.value.negate())),A.dispersion>0&&(E.dispersion.value=A.dispersion),A.iridescence>0&&(E.iridescence.value=A.iridescence,E.iridescenceIOR.value=A.iridescenceIOR,E.iridescenceThicknessMinimum.value=A.iridescenceThicknessRange[0],E.iridescenceThicknessMaximum.value=A.iridescenceThicknessRange[1],A.iridescenceMap&&(E.iridescenceMap.value=A.iridescenceMap,n(A.iridescenceMap,E.iridescenceMapTransform)),A.iridescenceThicknessMap&&(E.iridescenceThicknessMap.value=A.iridescenceThicknessMap,n(A.iridescenceThicknessMap,E.iridescenceThicknessMapTransform))),A.transmission>0&&(E.transmission.value=A.transmission,E.transmissionSamplerMap.value=k.texture,E.transmissionSamplerSize.value.set(k.width,k.height),A.transmissionMap&&(E.transmissionMap.value=A.transmissionMap,n(A.transmissionMap,E.transmissionMapTransform)),E.thickness.value=A.thickness,A.thicknessMap&&(E.thicknessMap.value=A.thicknessMap,n(A.thicknessMap,E.thicknessMapTransform)),E.attenuationDistance.value=A.attenuationDistance,E.attenuationColor.value.copy(A.attenuationColor)),A.anisotropy>0&&(E.anisotropyVector.value.set(A.anisotropy*Math.cos(A.anisotropyRotation),A.anisotropy*Math.sin(A.anisotropyRotation)),A.anisotropyMap&&(E.anisotropyMap.value=A.anisotropyMap,n(A.anisotropyMap,E.anisotropyMapTransform))),E.specularIntensity.value=A.specularIntensity,E.specularColor.value.copy(A.specularColor),A.specularColorMap&&(E.specularColorMap.value=A.specularColorMap,n(A.specularColorMap,E.specularColorMapTransform)),A.specularIntensityMap&&(E.specularIntensityMap.value=A.specularIntensityMap,n(A.specularIntensityMap,E.specularIntensityMapTransform))}function M(E,A){A.matcap&&(E.matcap.value=A.matcap)}function w(E,A){const k=e.get(A).light;E.referencePosition.value.setFromMatrixPosition(k.matrixWorld),E.nearDistance.value=k.shadow.camera.near,E.farDistance.value=k.shadow.camera.far}return{refreshFogUniforms:s,refreshMaterialUniforms:o}}function xq(a,e,n,s){let o={},l={},d=[];const h=a.getParameter(a.MAX_UNIFORM_BUFFER_BINDINGS);function m(k,R){const N=R.program;s.uniformBlockBinding(k,N)}function p(k,R){let N=o[k.id];N===void 0&&(M(k),N=y(k),o[k.id]=N,k.addEventListener("dispose",E));const I=R.program;s.updateUBOMapping(k,I);const z=e.render.frame;l[k.id]!==z&&(x(k),l[k.id]=z)}function y(k){const R=v();k.__bindingPointIndex=R;const N=a.createBuffer(),I=k.__size,z=k.usage;return a.bindBuffer(a.UNIFORM_BUFFER,N),a.bufferData(a.UNIFORM_BUFFER,I,z),a.bindBuffer(a.UNIFORM_BUFFER,null),a.bindBufferBase(a.UNIFORM_BUFFER,R,N),N}function v(){for(let k=0;k0&&(N+=I-z),k.__size=N,k.__cache={},this}function w(k){const R={boundary:0,storage:0};return typeof k=="number"||typeof k=="boolean"?(R.boundary=4,R.storage=4):k.isVector2?(R.boundary=8,R.storage=8):k.isVector3||k.isColor?(R.boundary=16,R.storage=12):k.isVector4?(R.boundary=16,R.storage=16):k.isMatrix3?(R.boundary=48,R.storage=48):k.isMatrix4?(R.boundary=64,R.storage=64):k.isTexture?console.warn("THREE.WebGLRenderer: Texture samplers can not be part of an uniforms group."):console.warn("THREE.WebGLRenderer: Unsupported uniform value type.",k),R}function E(k){const R=k.target;R.removeEventListener("dispose",E);const N=d.indexOf(R.__bindingPointIndex);d.splice(N,1),a.deleteBuffer(o[R.id]),delete o[R.id],delete l[R.id]}function A(){for(const k in o)a.deleteBuffer(o[k]);d=[],o={},l={}}return{bind:m,update:p,dispose:A}}class yq{constructor(e={}){const{canvas:n=HH(),context:s=null,depth:o=!0,stencil:l=!1,alpha:d=!1,antialias:h=!1,premultipliedAlpha:m=!0,preserveDrawingBuffer:p=!1,powerPreference:y="default",failIfMajorPerformanceCaveat:v=!1,reversedDepthBuffer:x=!1}=e;this.isWebGLRenderer=!0;let S;if(s!==null){if(typeof WebGLRenderingContext<"u"&&s instanceof WebGLRenderingContext)throw new Error("THREE.WebGLRenderer: WebGL 1 is not supported since r163.");S=s.getContextAttributes().alpha}else S=d;const M=new Uint32Array(4),w=new Int32Array(4);let E=null,A=null;const k=[],R=[];this.domElement=n,this.debug={checkShaderErrors:!0,onShaderError:null},this.autoClear=!0,this.autoClearColor=!0,this.autoClearDepth=!0,this.autoClearStencil=!0,this.sortObjects=!0,this.clippingPlanes=[],this.localClippingEnabled=!1,this.toneMapping=mo,this.toneMappingExposure=1,this.transmissionResolutionScale=1;const N=this;let I=!1;this._outputColorSpace=Xa;let z=0,j=0,L=null,D=-1,P=null;const F=new On,q=new On;let J=null;const ie=new tn(0);let Q=0,V=n.width,$=n.height,te=1,ne=null,Y=null;const T=new On(0,0,V,$),_=new On(0,0,V,$);let ve=!1;const je=new V0;let Je=!1,xe=!1;const ee=new dn,Ce=new he,Ze=new On,le={background:null,fog:null,environment:null,overrideMaterial:null,isScene:!0};let qe=!1;function xt(){return L===null?te:1}let se=s;function Pe(Z,ye){return n.getContext(Z,ye)}try{const Z={alpha:!0,depth:o,stencil:l,antialias:h,premultipliedAlpha:m,preserveDrawingBuffer:p,powerPreference:y,failIfMajorPerformanceCaveat:v};if("setAttribute"in n&&n.setAttribute("data-engine",`three.js r${k0}`),n.addEventListener("webglcontextlost",Xe,!1),n.addEventListener("webglcontextrestored",dt,!1),n.addEventListener("webglcontextcreationerror",W,!1),se===null){const ye="webgl2";if(se=Pe(ye,Z),se===null)throw Pe(ye)?new Error("Error creating WebGL context with your selected attributes."):new Error("Error creating WebGL context.")}}catch(Z){throw console.error("THREE.WebGLRenderer: "+Z.message),Z}let mt,it,at,Be,We,ue,ft,Re,K,B,pe,Ae,Ne,be,ot,Ve,ut,re,Se,He,lt,tt,ct,fe;function oe(){mt=new RV(se),mt.init(),tt=new dq(se,mt),it=new AV(se,mt,e,tt),at=new cq(se,mt),it.reversedDepthBuffer&&x&&at.buffers.depth.setReversed(!0),Be=new DV(se),We=new Z7,ue=new uq(se,mt,at,We,it,tt,Be),ft=new wV(N),Re=new jV(N),K=new U6(se),ct=new bV(se,K),B=new kV(se,K,Be,ct),pe=new LV(se,B,K,Be),Se=new zV(se,it,ue),Ve=new EV(We),Ae=new J7(N,ft,Re,mt,it,ct,Ve),Ne=new vq(N,We),be=new _7,ot=new iq(mt),re=new yV(N,ft,Re,at,pe,S,m),ut=new oq(N,pe,it),fe=new xq(se,Be,it,at),He=new SV(se,mt,Be),lt=new NV(se,mt,Be),Be.programs=Ae.programs,N.capabilities=it,N.extensions=mt,N.properties=We,N.renderLists=be,N.shadowMap=ut,N.state=at,N.info=Be}oe();const Fe=new mq(N,se);this.xr=Fe,this.getContext=function(){return se},this.getContextAttributes=function(){return se.getContextAttributes()},this.forceContextLoss=function(){const Z=mt.get("WEBGL_lose_context");Z&&Z.loseContext()},this.forceContextRestore=function(){const Z=mt.get("WEBGL_lose_context");Z&&Z.restoreContext()},this.getPixelRatio=function(){return te},this.setPixelRatio=function(Z){Z!==void 0&&(te=Z,this.setSize(V,$,!1))},this.getSize=function(Z){return Z.set(V,$)},this.setSize=function(Z,ye,Oe=!0){if(Fe.isPresenting){console.warn("THREE.WebGLRenderer: Can't change size while VR device is presenting.");return}V=Z,$=ye,n.width=Math.floor(Z*te),n.height=Math.floor(ye*te),Oe===!0&&(n.style.width=Z+"px",n.style.height=ye+"px"),this.setViewport(0,0,Z,ye)},this.getDrawingBufferSize=function(Z){return Z.set(V*te,$*te).floor()},this.setDrawingBufferSize=function(Z,ye,Oe){V=Z,$=ye,te=Oe,n.width=Math.floor(Z*Oe),n.height=Math.floor(ye*Oe),this.setViewport(0,0,Z,ye)},this.getCurrentViewport=function(Z){return Z.copy(F)},this.getViewport=function(Z){return Z.copy(T)},this.setViewport=function(Z,ye,Oe,Ie){Z.isVector4?T.set(Z.x,Z.y,Z.z,Z.w):T.set(Z,ye,Oe,Ie),at.viewport(F.copy(T).multiplyScalar(te).round())},this.getScissor=function(Z){return Z.copy(_)},this.setScissor=function(Z,ye,Oe,Ie){Z.isVector4?_.set(Z.x,Z.y,Z.z,Z.w):_.set(Z,ye,Oe,Ie),at.scissor(q.copy(_).multiplyScalar(te).round())},this.getScissorTest=function(){return ve},this.setScissorTest=function(Z){at.setScissorTest(ve=Z)},this.setOpaqueSort=function(Z){ne=Z},this.setTransparentSort=function(Z){Y=Z},this.getClearColor=function(Z){return Z.copy(re.getClearColor())},this.setClearColor=function(){re.setClearColor(...arguments)},this.getClearAlpha=function(){return re.getClearAlpha()},this.setClearAlpha=function(){re.setClearAlpha(...arguments)},this.clear=function(Z=!0,ye=!0,Oe=!0){let Ie=0;if(Z){let Ee=!1;if(L!==null){const rt=L.texture.format;Ee=rt===U0||rt===I0||rt===P0}if(Ee){const rt=L.texture.type,bt=rt===Gs||rt===wl||rt===nh||rt===ru||rt===L0||rt===O0,St=re.getClearColor(),yt=re.getClearAlpha(),Tt=St.r,Nt=St.g,Dt=St.b;bt?(M[0]=Tt,M[1]=Nt,M[2]=Dt,M[3]=yt,se.clearBufferuiv(se.COLOR,0,M)):(w[0]=Tt,w[1]=Nt,w[2]=Dt,w[3]=yt,se.clearBufferiv(se.COLOR,0,w))}else Ie|=se.COLOR_BUFFER_BIT}ye&&(Ie|=se.DEPTH_BUFFER_BIT),Oe&&(Ie|=se.STENCIL_BUFFER_BIT,this.state.buffers.stencil.setMask(4294967295)),se.clear(Ie)},this.clearColor=function(){this.clear(!0,!1,!1)},this.clearDepth=function(){this.clear(!1,!0,!1)},this.clearStencil=function(){this.clear(!1,!1,!0)},this.dispose=function(){n.removeEventListener("webglcontextlost",Xe,!1),n.removeEventListener("webglcontextrestored",dt,!1),n.removeEventListener("webglcontextcreationerror",W,!1),re.dispose(),be.dispose(),ot.dispose(),We.dispose(),ft.dispose(),Re.dispose(),pe.dispose(),ct.dispose(),fe.dispose(),Ae.dispose(),Fe.dispose(),Fe.removeEventListener("sessionstart",Vt),Fe.removeEventListener("sessionend",hn),bn.stop()};function Xe(Z){Z.preventDefault(),console.log("THREE.WebGLRenderer: Context Lost."),I=!0}function dt(){console.log("THREE.WebGLRenderer: Context Restored."),I=!1;const Z=Be.autoReset,ye=ut.enabled,Oe=ut.autoUpdate,Ie=ut.needsUpdate,Ee=ut.type;oe(),Be.autoReset=Z,ut.enabled=ye,ut.autoUpdate=Oe,ut.needsUpdate=Ie,ut.type=Ee}function W(Z){console.error("THREE.WebGLRenderer: A WebGL context could not be created. Reason: ",Z.statusMessage)}function U(Z){const ye=Z.target;ye.removeEventListener("dispose",U),ce(ye)}function ce(Z){G(Z),We.remove(Z)}function G(Z){const ye=We.get(Z).programs;ye!==void 0&&(ye.forEach(function(Oe){Ae.releaseProgram(Oe)}),Z.isShaderMaterial&&Ae.releaseShaderCache(Z))}this.renderBufferDirect=function(Z,ye,Oe,Ie,Ee,rt){ye===null&&(ye=le);const bt=Ee.isMesh&&Ee.matrixWorld.determinant()<0,St=wi(Z,ye,Oe,Ie,Ee);at.setMaterial(Ie,bt);let yt=Oe.index,Tt=1;if(Ie.wireframe===!0){if(yt=B.getWireframeAttribute(Oe),yt===void 0)return;Tt=2}const Nt=Oe.drawRange,Dt=Oe.attributes.position;let Ht=Nt.start*Tt,ge=(Nt.start+Nt.count)*Tt;rt!==null&&(Ht=Math.max(Ht,rt.start*Tt),ge=Math.min(ge,(rt.start+rt.count)*Tt)),yt!==null?(Ht=Math.max(Ht,0),ge=Math.min(ge,yt.count)):Dt!=null&&(Ht=Math.max(Ht,0),ge=Math.min(ge,Dt.count));const Te=ge-Ht;if(Te<0||Te===1/0)return;ct.setup(Ee,Ie,St,Oe,yt);let Le,et=He;if(yt!==null&&(Le=K.get(yt),et=lt,et.setIndex(Le)),Ee.isMesh)Ie.wireframe===!0?(at.setLineWidth(Ie.wireframeLinewidth*xt()),et.setMode(se.LINES)):et.setMode(se.TRIANGLES);else if(Ee.isLine){let Ye=Ie.linewidth;Ye===void 0&&(Ye=1),at.setLineWidth(Ye*xt()),Ee.isLineSegments?et.setMode(se.LINES):Ee.isLineLoop?et.setMode(se.LINE_LOOP):et.setMode(se.LINE_STRIP)}else Ee.isPoints?et.setMode(se.POINTS):Ee.isSprite&&et.setMode(se.TRIANGLES);if(Ee.isBatchedMesh)if(Ee._multiDrawInstances!==null)sh("THREE.WebGLRenderer: renderMultiDrawInstances has been deprecated and will be removed in r184. Append to renderMultiDraw arguments and use indirection."),et.renderMultiDrawInstances(Ee._multiDrawStarts,Ee._multiDrawCounts,Ee._multiDrawCount,Ee._multiDrawInstances);else if(mt.get("WEBGL_multi_draw"))et.renderMultiDraw(Ee._multiDrawStarts,Ee._multiDrawCounts,Ee._multiDrawCount);else{const Ye=Ee._multiDrawStarts,$e=Ee._multiDrawCounts,Qe=Ee._multiDrawCount,Et=yt?K.get(yt).bytesPerElement:1,zt=We.get(Ie).currentProgram.getUniforms();for(let It=0;It{function rt(){if(Ie.forEach(function(bt){We.get(bt).currentProgram.isReady()&&Ie.delete(bt)}),Ie.size===0){Ee(Z);return}setTimeout(rt,10)}mt.get("KHR_parallel_shader_compile")!==null?rt():setTimeout(rt,10)})};let pt=null;function Mt(Z){pt&&pt(Z)}function Vt(){bn.stop()}function hn(){bn.start()}const bn=new hN;bn.setAnimationLoop(Mt),typeof self<"u"&&bn.setContext(self),this.setAnimationLoop=function(Z){pt=Z,Fe.setAnimationLoop(Z),Z===null?bn.stop():bn.start()},Fe.addEventListener("sessionstart",Vt),Fe.addEventListener("sessionend",hn),this.render=function(Z,ye){if(ye!==void 0&&ye.isCamera!==!0){console.error("THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.");return}if(I===!0)return;if(Z.matrixWorldAutoUpdate===!0&&Z.updateMatrixWorld(),ye.parent===null&&ye.matrixWorldAutoUpdate===!0&&ye.updateMatrixWorld(),Fe.enabled===!0&&Fe.isPresenting===!0&&(Fe.cameraAutoUpdate===!0&&Fe.updateCamera(ye),ye=Fe.getCamera()),Z.isScene===!0&&Z.onBeforeRender(N,Z,ye,L),A=ot.get(Z,R.length),A.init(ye),R.push(A),ee.multiplyMatrices(ye.projectionMatrix,ye.matrixWorldInverse),je.setFromProjectionMatrix(ee,Us,ye.reversedDepth),xe=this.localClippingEnabled,Je=Ve.init(this.clippingPlanes,xe),E=be.get(Z,k.length),E.init(),k.push(E),Fe.enabled===!0&&Fe.isPresenting===!0){const rt=N.xr.getDepthSensingMesh();rt!==null&&fa(rt,ye,-1/0,N.sortObjects)}fa(Z,ye,0,N.sortObjects),E.finish(),N.sortObjects===!0&&E.sort(ne,Y),qe=Fe.enabled===!1||Fe.isPresenting===!1||Fe.hasDepthSensing()===!1,qe&&re.addToRenderList(E,Z),this.info.render.frame++,Je===!0&&Ve.beginShadows();const Oe=A.state.shadowsArray;ut.render(Oe,Z,ye),Je===!0&&Ve.endShadows(),this.info.autoReset===!0&&this.info.reset();const Ie=E.opaque,Ee=E.transmissive;if(A.setupLights(),ye.isArrayCamera){const rt=ye.cameras;if(Ee.length>0)for(let bt=0,St=rt.length;bt0&&ba(Ie,Ee,Z,ye),qe&&re.render(Z),Ta(E,Z,ye);L!==null&&j===0&&(ue.updateMultisampleRenderTarget(L),ue.updateRenderTargetMipmap(L)),Z.isScene===!0&&Z.onAfterRender(N,Z,ye),ct.resetDefaultState(),D=-1,P=null,R.pop(),R.length>0?(A=R[R.length-1],Je===!0&&Ve.setGlobalState(N.clippingPlanes,A.state.camera)):A=null,k.pop(),k.length>0?E=k[k.length-1]:E=null};function fa(Z,ye,Oe,Ie){if(Z.visible===!1)return;if(Z.layers.test(ye.layers)){if(Z.isGroup)Oe=Z.renderOrder;else if(Z.isLOD)Z.autoUpdate===!0&&Z.update(ye);else if(Z.isLight)A.pushLight(Z),Z.castShadow&&A.pushShadow(Z);else if(Z.isSprite){if(!Z.frustumCulled||je.intersectsSprite(Z)){Ie&&Ze.setFromMatrixPosition(Z.matrixWorld).applyMatrix4(ee);const bt=pe.update(Z),St=Z.material;St.visible&&E.push(Z,bt,St,Oe,Ze.z,null)}}else if((Z.isMesh||Z.isLine||Z.isPoints)&&(!Z.frustumCulled||je.intersectsObject(Z))){const bt=pe.update(Z),St=Z.material;if(Ie&&(Z.boundingSphere!==void 0?(Z.boundingSphere===null&&Z.computeBoundingSphere(),Ze.copy(Z.boundingSphere.center)):(bt.boundingSphere===null&&bt.computeBoundingSphere(),Ze.copy(bt.boundingSphere.center)),Ze.applyMatrix4(Z.matrixWorld).applyMatrix4(ee)),Array.isArray(St)){const yt=bt.groups;for(let Tt=0,Nt=yt.length;Tt0&&Qn(Ee,ye,Oe),rt.length>0&&Qn(rt,ye,Oe),bt.length>0&&Qn(bt,ye,Oe),at.buffers.depth.setTest(!0),at.buffers.depth.setMask(!0),at.buffers.color.setMask(!0),at.setPolygonOffset(!1)}function ba(Z,ye,Oe,Ie){if((Oe.isScene===!0?Oe.overrideMaterial:null)!==null)return;A.state.transmissionRenderTarget[Ie.id]===void 0&&(A.state.transmissionRenderTarget[Ie.id]=new As(1,1,{generateMipmaps:!0,type:mt.has("EXT_color_buffer_half_float")||mt.has("EXT_color_buffer_float")?Er:Gs,minFilter:cl,samples:4,stencilBuffer:l,resolveDepthBuffer:!1,resolveStencilBuffer:!1,colorSpace:pn.workingColorSpace}));const rt=A.state.transmissionRenderTarget[Ie.id],bt=Ie.viewport||F;rt.setSize(bt.z*N.transmissionResolutionScale,bt.w*N.transmissionResolutionScale);const St=N.getRenderTarget(),yt=N.getActiveCubeFace(),Tt=N.getActiveMipmapLevel();N.setRenderTarget(rt),N.getClearColor(ie),Q=N.getClearAlpha(),Q<1&&N.setClearColor(16777215,.5),N.clear(),qe&&re.render(Oe);const Nt=N.toneMapping;N.toneMapping=mo;const Dt=Ie.viewport;if(Ie.viewport!==void 0&&(Ie.viewport=void 0),A.setupLightsView(Ie),Je===!0&&Ve.setGlobalState(N.clippingPlanes,Ie),Qn(Z,Oe,Ie),ue.updateMultisampleRenderTarget(rt),ue.updateRenderTargetMipmap(rt),mt.has("WEBGL_multisampled_render_to_texture")===!1){let Ht=!1;for(let ge=0,Te=ye.length;ge0),Dt=!!Oe.morphAttributes.position,Ht=!!Oe.morphAttributes.normal,ge=!!Oe.morphAttributes.color;let Te=mo;Ie.toneMapped&&(L===null||L.isXRRenderTarget===!0)&&(Te=N.toneMapping);const Le=Oe.morphAttributes.position||Oe.morphAttributes.normal||Oe.morphAttributes.color,et=Le!==void 0?Le.length:0,Ye=We.get(Ie),$e=A.state.lights;if(Je===!0&&(xe===!0||Z!==P)){const Gt=Z===P&&Ie.id===D;Ve.setState(Ie,Z,Gt)}let Qe=!1;Ie.version===Ye.__version?(Ye.needsLights&&Ye.lightsStateVersion!==$e.state.version||Ye.outputColorSpace!==St||Ee.isBatchedMesh&&Ye.batching===!1||!Ee.isBatchedMesh&&Ye.batching===!0||Ee.isBatchedMesh&&Ye.batchingColor===!0&&Ee.colorTexture===null||Ee.isBatchedMesh&&Ye.batchingColor===!1&&Ee.colorTexture!==null||Ee.isInstancedMesh&&Ye.instancing===!1||!Ee.isInstancedMesh&&Ye.instancing===!0||Ee.isSkinnedMesh&&Ye.skinning===!1||!Ee.isSkinnedMesh&&Ye.skinning===!0||Ee.isInstancedMesh&&Ye.instancingColor===!0&&Ee.instanceColor===null||Ee.isInstancedMesh&&Ye.instancingColor===!1&&Ee.instanceColor!==null||Ee.isInstancedMesh&&Ye.instancingMorph===!0&&Ee.morphTexture===null||Ee.isInstancedMesh&&Ye.instancingMorph===!1&&Ee.morphTexture!==null||Ye.envMap!==yt||Ie.fog===!0&&Ye.fog!==rt||Ye.numClippingPlanes!==void 0&&(Ye.numClippingPlanes!==Ve.numPlanes||Ye.numIntersection!==Ve.numIntersection)||Ye.vertexAlphas!==Tt||Ye.vertexTangents!==Nt||Ye.morphTargets!==Dt||Ye.morphNormals!==Ht||Ye.morphColors!==ge||Ye.toneMapping!==Te||Ye.morphTargetsCount!==et)&&(Qe=!0):(Qe=!0,Ye.__version=Ie.version);let Et=Ye.currentProgram;Qe===!0&&(Et=_n(Ie,ye,Ee));let zt=!1,It=!1,Sn=!1;const Lt=Et.getUniforms(),nn=Ye.uniforms;if(at.useProgram(Et.program)&&(zt=!0,It=!0,Sn=!0),Ie.id!==D&&(D=Ie.id,It=!0),zt||P!==Z){at.buffers.depth.getReversed()&&Z.reversedDepth!==!0&&(Z._reversedDepth=!0,Z.updateProjectionMatrix()),Lt.setValue(se,"projectionMatrix",Z.projectionMatrix),Lt.setValue(se,"viewMatrix",Z.matrixWorldInverse);const An=Lt.map.cameraPosition;An!==void 0&&An.setValue(se,Ce.setFromMatrixPosition(Z.matrixWorld)),it.logarithmicDepthBuffer&&Lt.setValue(se,"logDepthBufFC",2/(Math.log(Z.far+1)/Math.LN2)),(Ie.isMeshPhongMaterial||Ie.isMeshToonMaterial||Ie.isMeshLambertMaterial||Ie.isMeshBasicMaterial||Ie.isMeshStandardMaterial||Ie.isShaderMaterial)&&Lt.setValue(se,"isOrthographic",Z.isOrthographicCamera===!0),P!==Z&&(P=Z,It=!0,Sn=!0)}if(Ee.isSkinnedMesh){Lt.setOptional(se,Ee,"bindMatrix"),Lt.setOptional(se,Ee,"bindMatrixInverse");const Gt=Ee.skeleton;Gt&&(Gt.boneTexture===null&&Gt.computeBoneTexture(),Lt.setValue(se,"boneTexture",Gt.boneTexture,ue))}Ee.isBatchedMesh&&(Lt.setOptional(se,Ee,"batchingTexture"),Lt.setValue(se,"batchingTexture",Ee._matricesTexture,ue),Lt.setOptional(se,Ee,"batchingIdTexture"),Lt.setValue(se,"batchingIdTexture",Ee._indirectTexture,ue),Lt.setOptional(se,Ee,"batchingColorTexture"),Ee._colorsTexture!==null&&Lt.setValue(se,"batchingColorTexture",Ee._colorsTexture,ue));const mn=Oe.morphAttributes;if((mn.position!==void 0||mn.normal!==void 0||mn.color!==void 0)&&Se.update(Ee,Oe,Et),(It||Ye.receiveShadow!==Ee.receiveShadow)&&(Ye.receiveShadow=Ee.receiveShadow,Lt.setValue(se,"receiveShadow",Ee.receiveShadow)),Ie.isMeshGouraudMaterial&&Ie.envMap!==null&&(nn.envMap.value=yt,nn.flipEnvMap.value=yt.isCubeTexture&&yt.isRenderTargetTexture===!1?-1:1),Ie.isMeshStandardMaterial&&Ie.envMap===null&&ye.environment!==null&&(nn.envMapIntensity.value=ye.environmentIntensity),It&&(Lt.setValue(se,"toneMappingExposure",N.toneMappingExposure),Ye.needsLights&&Ms(nn,Sn),rt&&Ie.fog===!0&&Ne.refreshFogUniforms(nn,rt),Ne.refreshMaterialUniforms(nn,Ie,te,$,A.state.transmissionRenderTarget[Z.id]),Vp.upload(se,In(Ye),nn,ue)),Ie.isShaderMaterial&&Ie.uniformsNeedUpdate===!0&&(Vp.upload(se,In(Ye),nn,ue),Ie.uniformsNeedUpdate=!1),Ie.isSpriteMaterial&&Lt.setValue(se,"center",Ee.center),Lt.setValue(se,"modelViewMatrix",Ee.modelViewMatrix),Lt.setValue(se,"normalMatrix",Ee.normalMatrix),Lt.setValue(se,"modelMatrix",Ee.matrixWorld),Ie.isShaderMaterial||Ie.isRawShaderMaterial){const Gt=Ie.uniformsGroups;for(let An=0,oi=Gt.length;An0&&ue.useMultisampledRTT(Z)===!1?Ee=We.get(Z).__webglMultisampledFramebuffer:Array.isArray(Nt)?Ee=Nt[Oe]:Ee=Nt,F.copy(Z.viewport),q.copy(Z.scissor),J=Z.scissorTest}else F.copy(T).multiplyScalar(te).floor(),q.copy(_).multiplyScalar(te).floor(),J=ve;if(Oe!==0&&(Ee=Mi),at.bindFramebuffer(se.FRAMEBUFFER,Ee)&&Ie&&at.drawBuffers(Z,Ee),at.viewport(F),at.scissor(q),at.setScissorTest(J),rt){const yt=We.get(Z.texture);se.framebufferTexture2D(se.FRAMEBUFFER,se.COLOR_ATTACHMENT0,se.TEXTURE_CUBE_MAP_POSITIVE_X+ye,yt.__webglTexture,Oe)}else if(bt){const yt=ye;for(let Tt=0;Tt=0&&ye<=Z.width-Ie&&Oe>=0&&Oe<=Z.height-Ee&&(Z.textures.length>1&&se.readBuffer(se.COLOR_ATTACHMENT0+St),se.readPixels(ye,Oe,Ie,Ee,tt.convert(Nt),tt.convert(Dt),rt))}finally{const Tt=L!==null?We.get(L).__webglFramebuffer:null;at.bindFramebuffer(se.FRAMEBUFFER,Tt)}}},this.readRenderTargetPixelsAsync=async function(Z,ye,Oe,Ie,Ee,rt,bt,St=0){if(!(Z&&Z.isWebGLRenderTarget))throw new Error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");let yt=We.get(Z).__webglFramebuffer;if(Z.isWebGLCubeRenderTarget&&bt!==void 0&&(yt=yt[bt]),yt)if(ye>=0&&ye<=Z.width-Ie&&Oe>=0&&Oe<=Z.height-Ee){at.bindFramebuffer(se.FRAMEBUFFER,yt);const Tt=Z.textures[St],Nt=Tt.format,Dt=Tt.type;if(!it.textureFormatReadable(Nt))throw new Error("THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarget is not in RGBA or implementation defined format.");if(!it.textureTypeReadable(Dt))throw new Error("THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarget is not in UnsignedByteType or implementation defined type.");const Ht=se.createBuffer();se.bindBuffer(se.PIXEL_PACK_BUFFER,Ht),se.bufferData(se.PIXEL_PACK_BUFFER,rt.byteLength,se.STREAM_READ),Z.textures.length>1&&se.readBuffer(se.COLOR_ATTACHMENT0+St),se.readPixels(ye,Oe,Ie,Ee,tt.convert(Nt),tt.convert(Dt),0);const ge=L!==null?We.get(L).__webglFramebuffer:null;at.bindFramebuffer(se.FRAMEBUFFER,ge);const Te=se.fenceSync(se.SYNC_GPU_COMMANDS_COMPLETE,0);return se.flush(),await GH(se,Te,4),se.bindBuffer(se.PIXEL_PACK_BUFFER,Ht),se.getBufferSubData(se.PIXEL_PACK_BUFFER,0,rt),se.deleteBuffer(Ht),se.deleteSync(Te),rt}else throw new Error("THREE.WebGLRenderer.readRenderTargetPixelsAsync: requested read bounds are out of range.")},this.copyFramebufferToTexture=function(Z,ye=null,Oe=0){const Ie=Math.pow(2,-Oe),Ee=Math.floor(Z.image.width*Ie),rt=Math.floor(Z.image.height*Ie),bt=ye!==null?ye.x:0,St=ye!==null?ye.y:0;ue.setTexture2D(Z,0),se.copyTexSubImage2D(se.TEXTURE_2D,Oe,0,0,bt,St,Ee,rt),at.unbindTexture()};const qs=se.createFramebuffer(),Ci=se.createFramebuffer();this.copyTextureToTexture=function(Z,ye,Oe=null,Ie=null,Ee=0,rt=null){rt===null&&(Ee!==0?(sh("WebGLRenderer: copyTextureToTexture function signature has changed to support src and dst mipmap levels."),rt=Ee,Ee=0):rt=0);let bt,St,yt,Tt,Nt,Dt,Ht,ge,Te;const Le=Z.isCompressedTexture?Z.mipmaps[rt]:Z.image;if(Oe!==null)bt=Oe.max.x-Oe.min.x,St=Oe.max.y-Oe.min.y,yt=Oe.isBox3?Oe.max.z-Oe.min.z:1,Tt=Oe.min.x,Nt=Oe.min.y,Dt=Oe.isBox3?Oe.min.z:0;else{const mn=Math.pow(2,-Ee);bt=Math.floor(Le.width*mn),St=Math.floor(Le.height*mn),Z.isDataArrayTexture?yt=Le.depth:Z.isData3DTexture?yt=Math.floor(Le.depth*mn):yt=1,Tt=0,Nt=0,Dt=0}Ie!==null?(Ht=Ie.x,ge=Ie.y,Te=Ie.z):(Ht=0,ge=0,Te=0);const et=tt.convert(ye.format),Ye=tt.convert(ye.type);let $e;ye.isData3DTexture?(ue.setTexture3D(ye,0),$e=se.TEXTURE_3D):ye.isDataArrayTexture||ye.isCompressedArrayTexture?(ue.setTexture2DArray(ye,0),$e=se.TEXTURE_2D_ARRAY):(ue.setTexture2D(ye,0),$e=se.TEXTURE_2D),se.pixelStorei(se.UNPACK_FLIP_Y_WEBGL,ye.flipY),se.pixelStorei(se.UNPACK_PREMULTIPLY_ALPHA_WEBGL,ye.premultiplyAlpha),se.pixelStorei(se.UNPACK_ALIGNMENT,ye.unpackAlignment);const Qe=se.getParameter(se.UNPACK_ROW_LENGTH),Et=se.getParameter(se.UNPACK_IMAGE_HEIGHT),zt=se.getParameter(se.UNPACK_SKIP_PIXELS),It=se.getParameter(se.UNPACK_SKIP_ROWS),Sn=se.getParameter(se.UNPACK_SKIP_IMAGES);se.pixelStorei(se.UNPACK_ROW_LENGTH,Le.width),se.pixelStorei(se.UNPACK_IMAGE_HEIGHT,Le.height),se.pixelStorei(se.UNPACK_SKIP_PIXELS,Tt),se.pixelStorei(se.UNPACK_SKIP_ROWS,Nt),se.pixelStorei(se.UNPACK_SKIP_IMAGES,Dt);const Lt=Z.isDataArrayTexture||Z.isData3DTexture,nn=ye.isDataArrayTexture||ye.isData3DTexture;if(Z.isDepthTexture){const mn=We.get(Z),Gt=We.get(ye),An=We.get(mn.__renderTarget),oi=We.get(Gt.__renderTarget);at.bindFramebuffer(se.READ_FRAMEBUFFER,An.__webglFramebuffer),at.bindFramebuffer(se.DRAW_FRAMEBUFFER,oi.__webglFramebuffer);for(let Ft=0;FtMath.PI&&(s-=pi),o<-Math.PI?o+=pi:o>Math.PI&&(o-=pi),s<=o?this._spherical.theta=Math.max(s,Math.min(o,this._spherical.theta)):this._spherical.theta=this._spherical.theta>(s+o)/2?Math.max(s,this._spherical.theta):Math.min(o,this._spherical.theta)),this._spherical.phi=Math.max(this.minPolarAngle,Math.min(this.maxPolarAngle,this._spherical.phi)),this._spherical.makeSafe(),this.enableDamping===!0?this.target.addScaledVector(this._panOffset,this.dampingFactor):this.target.add(this._panOffset),this.target.sub(this.cursor),this.target.clampLength(this.minTargetRadius,this.maxTargetRadius),this.target.add(this.cursor);let l=!1;if(this.zoomToCursor&&this._performCursorZoom||this.object.isOrthographicCamera)this._spherical.radius=this._clampDistance(this._spherical.radius);else{const d=this._spherical.radius;this._spherical.radius=this._clampDistance(this._spherical.radius*this._scale),l=d!=this._spherical.radius}if(ga.setFromSpherical(this._spherical),ga.applyQuaternion(this._quatInverse),n.copy(this.target).add(ga),this.object.lookAt(this.target),this.enableDamping===!0?(this._sphericalDelta.theta*=1-this.dampingFactor,this._sphericalDelta.phi*=1-this.dampingFactor,this._panOffset.multiplyScalar(1-this.dampingFactor)):(this._sphericalDelta.set(0,0,0),this._panOffset.set(0,0,0)),this.zoomToCursor&&this._performCursorZoom){let d=null;if(this.object.isPerspectiveCamera){const h=ga.length();d=this._clampDistance(h*this._scale);const m=h-d;this.object.position.addScaledVector(this._dollyDirection,m),this.object.updateMatrixWorld(),l=!!m}else if(this.object.isOrthographicCamera){const h=new he(this._mouse.x,this._mouse.y,0);h.unproject(this.object);const m=this.object.zoom;this.object.zoom=Math.max(this.minZoom,Math.min(this.maxZoom,this.object.zoom/this._scale)),this.object.updateProjectionMatrix(),l=m!==this.object.zoom;const p=new he(this._mouse.x,this._mouse.y,0);p.unproject(this.object),this.object.position.sub(p).add(h),this.object.updateMatrixWorld(),d=ga.length()}else console.warn("WARNING: OrbitControls.js encountered an unknown camera type - zoom to cursor disabled."),this.zoomToCursor=!1;d!==null&&(this.screenSpacePanning?this.target.set(0,0,-1).transformDirection(this.object.matrix).multiplyScalar(d).add(this.object.position):(vp.origin.copy(this.object.position),vp.direction.set(0,0,-1).transformDirection(this.object.matrix),Math.abs(this.object.up.dot(vp.direction))$x||8*(1-this._lastQuaternion.dot(this.object.quaternion))>$x||this._lastTargetPosition.distanceToSquared(this.target)>$x?(this.dispatchEvent(RC),this._lastPosition.copy(this.object.position),this._lastQuaternion.copy(this.object.quaternion),this._lastTargetPosition.copy(this.target),!0):!1}_getAutoRotationAngle(e){return e!==null?pi/60*this.autoRotateSpeed*e:pi/60/60*this.autoRotateSpeed}_getZoomScale(e){const n=Math.abs(e*.01);return Math.pow(.95,this.zoomSpeed*n)}_rotateLeft(e){this._sphericalDelta.theta-=e}_rotateUp(e){this._sphericalDelta.phi-=e}_panLeft(e,n){ga.setFromMatrixColumn(n,0),ga.multiplyScalar(-e),this._panOffset.add(ga)}_panUp(e,n){this.screenSpacePanning===!0?ga.setFromMatrixColumn(n,1):(ga.setFromMatrixColumn(n,0),ga.crossVectors(this.object.up,ga)),ga.multiplyScalar(e),this._panOffset.add(ga)}_pan(e,n){const s=this.domElement;if(this.object.isPerspectiveCamera){const o=this.object.position;ga.copy(o).sub(this.target);let l=ga.length();l*=Math.tan(this.object.fov/2*Math.PI/180),this._panLeft(2*e*l/s.clientHeight,this.object.matrix),this._panUp(2*n*l/s.clientHeight,this.object.matrix)}else this.object.isOrthographicCamera?(this._panLeft(e*(this.object.right-this.object.left)/this.object.zoom/s.clientWidth,this.object.matrix),this._panUp(n*(this.object.top-this.object.bottom)/this.object.zoom/s.clientHeight,this.object.matrix)):(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled."),this.enablePan=!1)}_dollyOut(e){this.object.isPerspectiveCamera||this.object.isOrthographicCamera?this._scale/=e:(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."),this.enableZoom=!1)}_dollyIn(e){this.object.isPerspectiveCamera||this.object.isOrthographicCamera?this._scale*=e:(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."),this.enableZoom=!1)}_updateZoomParameters(e,n){if(!this.zoomToCursor)return;this._performCursorZoom=!0;const s=this.domElement.getBoundingClientRect(),o=e-s.left,l=n-s.top,d=s.width,h=s.height;this._mouse.x=o/d*2-1,this._mouse.y=-(l/h)*2+1,this._dollyDirection.set(this._mouse.x,this._mouse.y,1).unproject(this.object).sub(this.object.position).normalize()}_clampDistance(e){return Math.max(this.minDistance,Math.min(this.maxDistance,e))}_handleMouseDownRotate(e){this._rotateStart.set(e.clientX,e.clientY)}_handleMouseDownDolly(e){this._updateZoomParameters(e.clientX,e.clientX),this._dollyStart.set(e.clientX,e.clientY)}_handleMouseDownPan(e){this._panStart.set(e.clientX,e.clientY)}_handleMouseMoveRotate(e){this._rotateEnd.set(e.clientX,e.clientY),this._rotateDelta.subVectors(this._rotateEnd,this._rotateStart).multiplyScalar(this.rotateSpeed);const n=this.domElement;this._rotateLeft(pi*this._rotateDelta.x/n.clientHeight),this._rotateUp(pi*this._rotateDelta.y/n.clientHeight),this._rotateStart.copy(this._rotateEnd),this.update()}_handleMouseMoveDolly(e){this._dollyEnd.set(e.clientX,e.clientY),this._dollyDelta.subVectors(this._dollyEnd,this._dollyStart),this._dollyDelta.y>0?this._dollyOut(this._getZoomScale(this._dollyDelta.y)):this._dollyDelta.y<0&&this._dollyIn(this._getZoomScale(this._dollyDelta.y)),this._dollyStart.copy(this._dollyEnd),this.update()}_handleMouseMovePan(e){this._panEnd.set(e.clientX,e.clientY),this._panDelta.subVectors(this._panEnd,this._panStart).multiplyScalar(this.panSpeed),this._pan(this._panDelta.x,this._panDelta.y),this._panStart.copy(this._panEnd),this.update()}_handleMouseWheel(e){this._updateZoomParameters(e.clientX,e.clientY),e.deltaY<0?this._dollyIn(this._getZoomScale(e.deltaY)):e.deltaY>0&&this._dollyOut(this._getZoomScale(e.deltaY)),this.update()}_handleKeyDown(e){let n=!1;switch(e.code){case this.keys.UP:e.ctrlKey||e.metaKey||e.shiftKey?this.enableRotate&&this._rotateUp(pi*this.keyRotateSpeed/this.domElement.clientHeight):this.enablePan&&this._pan(0,this.keyPanSpeed),n=!0;break;case this.keys.BOTTOM:e.ctrlKey||e.metaKey||e.shiftKey?this.enableRotate&&this._rotateUp(-pi*this.keyRotateSpeed/this.domElement.clientHeight):this.enablePan&&this._pan(0,-this.keyPanSpeed),n=!0;break;case this.keys.LEFT:e.ctrlKey||e.metaKey||e.shiftKey?this.enableRotate&&this._rotateLeft(pi*this.keyRotateSpeed/this.domElement.clientHeight):this.enablePan&&this._pan(this.keyPanSpeed,0),n=!0;break;case this.keys.RIGHT:e.ctrlKey||e.metaKey||e.shiftKey?this.enableRotate&&this._rotateLeft(-pi*this.keyRotateSpeed/this.domElement.clientHeight):this.enablePan&&this._pan(-this.keyPanSpeed,0),n=!0;break}n&&(e.preventDefault(),this.update())}_handleTouchStartRotate(e){if(this._pointers.length===1)this._rotateStart.set(e.pageX,e.pageY);else{const n=this._getSecondPointerPosition(e),s=.5*(e.pageX+n.x),o=.5*(e.pageY+n.y);this._rotateStart.set(s,o)}}_handleTouchStartPan(e){if(this._pointers.length===1)this._panStart.set(e.pageX,e.pageY);else{const n=this._getSecondPointerPosition(e),s=.5*(e.pageX+n.x),o=.5*(e.pageY+n.y);this._panStart.set(s,o)}}_handleTouchStartDolly(e){const n=this._getSecondPointerPosition(e),s=e.pageX-n.x,o=e.pageY-n.y,l=Math.sqrt(s*s+o*o);this._dollyStart.set(0,l)}_handleTouchStartDollyPan(e){this.enableZoom&&this._handleTouchStartDolly(e),this.enablePan&&this._handleTouchStartPan(e)}_handleTouchStartDollyRotate(e){this.enableZoom&&this._handleTouchStartDolly(e),this.enableRotate&&this._handleTouchStartRotate(e)}_handleTouchMoveRotate(e){if(this._pointers.length==1)this._rotateEnd.set(e.pageX,e.pageY);else{const s=this._getSecondPointerPosition(e),o=.5*(e.pageX+s.x),l=.5*(e.pageY+s.y);this._rotateEnd.set(o,l)}this._rotateDelta.subVectors(this._rotateEnd,this._rotateStart).multiplyScalar(this.rotateSpeed);const n=this.domElement;this._rotateLeft(pi*this._rotateDelta.x/n.clientHeight),this._rotateUp(pi*this._rotateDelta.y/n.clientHeight),this._rotateStart.copy(this._rotateEnd)}_handleTouchMovePan(e){if(this._pointers.length===1)this._panEnd.set(e.pageX,e.pageY);else{const n=this._getSecondPointerPosition(e),s=.5*(e.pageX+n.x),o=.5*(e.pageY+n.y);this._panEnd.set(s,o)}this._panDelta.subVectors(this._panEnd,this._panStart).multiplyScalar(this.panSpeed),this._pan(this._panDelta.x,this._panDelta.y),this._panStart.copy(this._panEnd)}_handleTouchMoveDolly(e){const n=this._getSecondPointerPosition(e),s=e.pageX-n.x,o=e.pageY-n.y,l=Math.sqrt(s*s+o*o);this._dollyEnd.set(0,l),this._dollyDelta.set(0,Math.pow(this._dollyEnd.y/this._dollyStart.y,this.zoomSpeed)),this._dollyOut(this._dollyDelta.y),this._dollyStart.copy(this._dollyEnd);const d=(e.pageX+n.x)*.5,h=(e.pageY+n.y)*.5;this._updateZoomParameters(d,h)}_handleTouchMoveDollyPan(e){this.enableZoom&&this._handleTouchMoveDolly(e),this.enablePan&&this._handleTouchMovePan(e)}_handleTouchMoveDollyRotate(e){this.enableZoom&&this._handleTouchMoveDolly(e),this.enableRotate&&this._handleTouchMoveRotate(e)}_addPointer(e){this._pointers.push(e.pointerId)}_removePointer(e){delete this._pointerPositions[e.pointerId];for(let n=0;nw?(E=1,A=0):(E=0,A=1);const k=M-E+y,R=w-A+y,N=M-1+2*y,I=w-1+2*y,z=m&255,j=p&255,L=this.perm[z+this.perm[j]]%12,D=this.perm[z+E+this.perm[j+A]]%12,P=this.perm[z+1+this.perm[j+1]]%12;let F=.5-M*M-w*w;F<0?s=0:(F*=F,s=F*F*this._dot(this.grad3[L],M,w));let q=.5-k*k-R*R;q<0?o=0:(q*=q,o=q*q*this._dot(this.grad3[D],k,R));let J=.5-N*N-I*I;return J<0?l=0:(J*=J,l=J*J*this._dot(this.grad3[P],N,I)),70*(s+o+l)}noise3d(e,n,s){let o,l,d,h;const p=(e+n+s)*.3333333333333333,y=Math.floor(e+p),v=Math.floor(n+p),x=Math.floor(s+p),S=1/6,M=(y+v+x)*S,w=y-M,E=v-M,A=x-M,k=e-w,R=n-E,N=s-A;let I,z,j,L,D,P;k>=R?R>=N?(I=1,z=0,j=0,L=1,D=1,P=0):k>=N?(I=1,z=0,j=0,L=1,D=0,P=1):(I=0,z=0,j=1,L=1,D=0,P=1):RP?32:0,ie=D>F?16:0,Q=P>F?8:0,V=D>q?4:0,$=P>q?2:0,te=F>q?1:0,ne=J+ie+Q+V+$+te,Y=d[ne][0]>=3?1:0,T=d[ne][1]>=3?1:0,_=d[ne][2]>=3?1:0,ve=d[ne][3]>=3?1:0,je=d[ne][0]>=2?1:0,Je=d[ne][1]>=2?1:0,xe=d[ne][2]>=2?1:0,ee=d[ne][3]>=2?1:0,Ce=d[ne][0]>=1?1:0,Ze=d[ne][1]>=1?1:0,le=d[ne][2]>=1?1:0,qe=d[ne][3]>=1?1:0,xt=D-Y+p,se=P-T+p,Pe=F-_+p,mt=q-ve+p,it=D-je+2*p,at=P-Je+2*p,Be=F-xe+2*p,We=q-ee+2*p,ue=D-Ce+3*p,ft=P-Ze+3*p,Re=F-le+3*p,K=q-qe+3*p,B=D-1+4*p,pe=P-1+4*p,Ae=F-1+4*p,Ne=q-1+4*p,be=E&255,ot=A&255,Ve=k&255,ut=R&255,re=h[be+h[ot+h[Ve+h[ut]]]]%32,Se=h[be+Y+h[ot+T+h[Ve+_+h[ut+ve]]]]%32,He=h[be+je+h[ot+Je+h[Ve+xe+h[ut+ee]]]]%32,lt=h[be+Ce+h[ot+Ze+h[Ve+le+h[ut+qe]]]]%32,tt=h[be+1+h[ot+1+h[Ve+1+h[ut+1]]]]%32;let ct=.6-D*D-P*P-F*F-q*q;ct<0?y=0:(ct*=ct,y=ct*ct*this._dot4(l[re],D,P,F,q));let fe=.6-xt*xt-se*se-Pe*Pe-mt*mt;fe<0?v=0:(fe*=fe,v=fe*fe*this._dot4(l[Se],xt,se,Pe,mt));let oe=.6-it*it-at*at-Be*Be-We*We;oe<0?x=0:(oe*=oe,x=oe*oe*this._dot4(l[He],it,at,Be,We));let Fe=.6-ue*ue-ft*ft-Re*Re-K*K;Fe<0?S=0:(Fe*=Fe,S=Fe*Fe*this._dot4(l[lt],ue,ft,Re,K));let Xe=.6-B*B-pe*pe-Ae*Ae-Ne*Ne;return Xe<0?M=0:(Xe*=Xe,M=Xe*Xe*this._dot4(l[tt],B,pe,Ae,Ne)),27*(y+v+x+S+M)}_dot(e,n,s){return e[0]*n+e[1]*s}_dot3(e,n,s,o){return e[0]*n+e[1]*s+e[2]*o}_dot4(e,n,s,o,l){return e[0]*n+e[1]*s+e[2]*o+e[3]*l}}const xp={defines:{PERSPECTIVE_CAMERA:1,KERNEL_SIZE:32},uniforms:{tNormal:{value:null},tDepth:{value:null},tNoise:{value:null},kernel:{value:null},cameraNear:{value:null},cameraFar:{value:null},resolution:{value:new jt},cameraProjectionMatrix:{value:new dn},cameraInverseProjectionMatrix:{value:new dn},kernelRadius:{value:8},minDistance:{value:.005},maxDistance:{value:.05}},vertexShader:` varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`,fragmentShader:` uniform highp sampler2D tNormal; uniform highp sampler2D tDepth; uniform sampler2D tNoise; uniform vec3 kernel[ KERNEL_SIZE ]; uniform vec2 resolution; uniform float cameraNear; uniform float cameraFar; uniform mat4 cameraProjectionMatrix; uniform mat4 cameraInverseProjectionMatrix; uniform float kernelRadius; uniform float minDistance; // avoid artifacts caused by neighbour fragments with minimal depth difference uniform float maxDistance; // avoid the influence of fragments which are too far away varying vec2 vUv; #include float getDepth( const in vec2 screenPosition ) { return texture2D( tDepth, screenPosition ).x; } float getLinearDepth( const in vec2 screenPosition ) { #if PERSPECTIVE_CAMERA == 1 float fragCoordZ = texture2D( tDepth, screenPosition ).x; float viewZ = perspectiveDepthToViewZ( fragCoordZ, cameraNear, cameraFar ); return viewZToOrthographicDepth( viewZ, cameraNear, cameraFar ); #else return texture2D( tDepth, screenPosition ).x; #endif } float getViewZ( const in float depth ) { #if PERSPECTIVE_CAMERA == 1 return perspectiveDepthToViewZ( depth, cameraNear, cameraFar ); #else return orthographicDepthToViewZ( depth, cameraNear, cameraFar ); #endif } vec3 getViewPosition( const in vec2 screenPosition, const in float depth, const in float viewZ ) { float clipW = cameraProjectionMatrix[2][3] * viewZ + cameraProjectionMatrix[3][3]; vec4 clipPosition = vec4( ( vec3( screenPosition, depth ) - 0.5 ) * 2.0, 1.0 ); clipPosition *= clipW; // unprojection. return ( cameraInverseProjectionMatrix * clipPosition ).xyz; } vec3 getViewNormal( const in vec2 screenPosition ) { return unpackRGBToNormal( texture2D( tNormal, screenPosition ).xyz ); } void main() { float depth = getDepth( vUv ); if ( depth == 1.0 ) { gl_FragColor = vec4( 1.0 ); // don't influence background } else { float viewZ = getViewZ( depth ); vec3 viewPosition = getViewPosition( vUv, depth, viewZ ); vec3 viewNormal = getViewNormal( vUv ); vec2 noiseScale = vec2( resolution.x / 4.0, resolution.y / 4.0 ); vec3 random = vec3( texture2D( tNoise, vUv * noiseScale ).r ); // compute matrix used to reorient a kernel vector vec3 tangent = normalize( random - viewNormal * dot( random, viewNormal ) ); vec3 bitangent = cross( viewNormal, tangent ); mat3 kernelMatrix = mat3( tangent, bitangent, viewNormal ); float occlusion = 0.0; for ( int i = 0; i < KERNEL_SIZE; i ++ ) { vec3 sampleVector = kernelMatrix * kernel[ i ]; // reorient sample vector in view space vec3 samplePoint = viewPosition + ( sampleVector * kernelRadius ); // calculate sample point vec4 samplePointNDC = cameraProjectionMatrix * vec4( samplePoint, 1.0 ); // project point and calculate NDC samplePointNDC /= samplePointNDC.w; vec2 samplePointUv = samplePointNDC.xy * 0.5 + 0.5; // compute uv coordinates float realDepth = getLinearDepth( samplePointUv ); // get linear depth from depth texture float sampleDepth = viewZToOrthographicDepth( samplePoint.z, cameraNear, cameraFar ); // compute linear depth of the sample view Z value float delta = sampleDepth - realDepth; if ( delta > minDistance && delta < maxDistance ) { // if fragment is before sample point, increase occlusion occlusion += 1.0; } } occlusion = clamp( occlusion / float( KERNEL_SIZE ), 0.0, 1.0 ); gl_FragColor = vec4( vec3( 1.0 - occlusion ), 1.0 ); } }`},yp={defines:{PERSPECTIVE_CAMERA:1},uniforms:{tDepth:{value:null},cameraNear:{value:null},cameraFar:{value:null}},vertexShader:`varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`,fragmentShader:`uniform sampler2D tDepth; uniform float cameraNear; uniform float cameraFar; varying vec2 vUv; #include float getLinearDepth( const in vec2 screenPosition ) { #if PERSPECTIVE_CAMERA == 1 float fragCoordZ = texture2D( tDepth, screenPosition ).x; float viewZ = perspectiveDepthToViewZ( fragCoordZ, cameraNear, cameraFar ); return viewZToOrthographicDepth( viewZ, cameraNear, cameraFar ); #else return texture2D( tDepth, screenPosition ).x; #endif } void main() { float depth = getLinearDepth( vUv ); gl_FragColor = vec4( vec3( 1.0 - depth ), 1.0 ); }`},bp={uniforms:{tDiffuse:{value:null},resolution:{value:new jt}},vertexShader:`varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`,fragmentShader:`uniform sampler2D tDiffuse; uniform vec2 resolution; varying vec2 vUv; void main() { vec2 texelSize = ( 1.0 / resolution ); float result = 0.0; for ( int i = - 2; i <= 2; i ++ ) { for ( int j = - 2; j <= 2; j ++ ) { vec2 offset = ( vec2( float( i ), float( j ) ) ) * texelSize; result += texture2D( tDiffuse, vUv + offset ).r; } } gl_FragColor = vec4( vec3( result / ( 5.0 * 5.0 ) ), 1.0 ); }`};class uo extends Su{constructor(e,n,s=512,o=512,l=32){super(),this.width=s,this.height=o,this.clear=!0,this.needsSwap=!1,this.camera=n,this.scene=e,this.kernelRadius=8,this.kernel=[],this.noiseTexture=null,this.output=0,this.minDistance=.005,this.maxDistance=.1,this._visibilityCache=[],this._generateSampleKernel(l),this._generateRandomKernelRotations();const d=new q0;d.format=ou,d.type=ru,this.normalRenderTarget=new As(this.width,this.height,{minFilter:ii,magFilter:ii,type:Er,depthTexture:d}),this.ssaoRenderTarget=new As(this.width,this.height,{type:Er}),this.blurRenderTarget=this.ssaoRenderTarget.clone(),this.ssaoMaterial=new _a({defines:Object.assign({},xp.defines),uniforms:ul.clone(xp.uniforms),vertexShader:xp.vertexShader,fragmentShader:xp.fragmentShader,blending:Ja}),this.ssaoMaterial.defines.KERNEL_SIZE=l,this.ssaoMaterial.uniforms.tNormal.value=this.normalRenderTarget.texture,this.ssaoMaterial.uniforms.tDepth.value=this.normalRenderTarget.depthTexture,this.ssaoMaterial.uniforms.tNoise.value=this.noiseTexture,this.ssaoMaterial.uniforms.kernel.value=this.kernel,this.ssaoMaterial.uniforms.cameraNear.value=this.camera.near,this.ssaoMaterial.uniforms.cameraFar.value=this.camera.far,this.ssaoMaterial.uniforms.resolution.value.set(this.width,this.height),this.ssaoMaterial.uniforms.cameraProjectionMatrix.value.copy(this.camera.projectionMatrix),this.ssaoMaterial.uniforms.cameraInverseProjectionMatrix.value.copy(this.camera.projectionMatrixInverse),this.normalMaterial=new M6,this.normalMaterial.blending=Ja,this.blurMaterial=new _a({defines:Object.assign({},bp.defines),uniforms:ul.clone(bp.uniforms),vertexShader:bp.vertexShader,fragmentShader:bp.fragmentShader}),this.blurMaterial.uniforms.tDiffuse.value=this.ssaoRenderTarget.texture,this.blurMaterial.uniforms.resolution.value.set(this.width,this.height),this.depthRenderMaterial=new _a({defines:Object.assign({},yp.defines),uniforms:ul.clone(yp.uniforms),vertexShader:yp.vertexShader,fragmentShader:yp.fragmentShader,blending:Ja}),this.depthRenderMaterial.uniforms.tDepth.value=this.normalRenderTarget.depthTexture,this.depthRenderMaterial.uniforms.cameraNear.value=this.camera.near,this.depthRenderMaterial.uniforms.cameraFar.value=this.camera.far,this.copyMaterial=new _a({uniforms:ul.clone(qp.uniforms),vertexShader:qp.vertexShader,fragmentShader:qp.fragmentShader,transparent:!0,depthTest:!1,depthWrite:!1,blendSrc:zk,blendDst:Fy,blendEquation:gr,blendSrcAlpha:Dk,blendDstAlpha:Fy,blendEquationAlpha:gr}),this._fsQuad=new _0(null),this._originalClearColor=new tn}dispose(){this.normalRenderTarget.dispose(),this.ssaoRenderTarget.dispose(),this.blurRenderTarget.dispose(),this.normalMaterial.dispose(),this.blurMaterial.dispose(),this.copyMaterial.dispose(),this.depthRenderMaterial.dispose(),this._fsQuad.dispose()}render(e,n,s){switch(this._overrideVisibility(),this._renderOverride(e,this.normalMaterial,this.normalRenderTarget,7829503,1),this._restoreVisibility(),this.ssaoMaterial.uniforms.kernelRadius.value=this.kernelRadius,this.ssaoMaterial.uniforms.minDistance.value=this.minDistance,this.ssaoMaterial.uniforms.maxDistance.value=this.maxDistance,this._renderPass(e,this.ssaoMaterial,this.ssaoRenderTarget),this._renderPass(e,this.blurMaterial,this.blurRenderTarget),this.output){case uo.OUTPUT.SSAO:this.copyMaterial.uniforms.tDiffuse.value=this.ssaoRenderTarget.texture,this.copyMaterial.blending=Ja,this._renderPass(e,this.copyMaterial,this.renderToScreen?null:s);break;case uo.OUTPUT.Blur:this.copyMaterial.uniforms.tDiffuse.value=this.blurRenderTarget.texture,this.copyMaterial.blending=Ja,this._renderPass(e,this.copyMaterial,this.renderToScreen?null:s);break;case uo.OUTPUT.Depth:this._renderPass(e,this.depthRenderMaterial,this.renderToScreen?null:s);break;case uo.OUTPUT.Normal:this.copyMaterial.uniforms.tDiffuse.value=this.normalRenderTarget.texture,this.copyMaterial.blending=Ja,this._renderPass(e,this.copyMaterial,this.renderToScreen?null:s);break;case uo.OUTPUT.Default:this.copyMaterial.uniforms.tDiffuse.value=this.blurRenderTarget.texture,this.copyMaterial.blending=Nk,this._renderPass(e,this.copyMaterial,this.renderToScreen?null:s);break;default:console.warn("THREE.SSAOPass: Unknown output type.")}}setSize(e,n){this.width=e,this.height=n,this.ssaoRenderTarget.setSize(e,n),this.normalRenderTarget.setSize(e,n),this.blurRenderTarget.setSize(e,n),this.ssaoMaterial.uniforms.resolution.value.set(e,n),this.ssaoMaterial.uniforms.cameraProjectionMatrix.value.copy(this.camera.projectionMatrix),this.ssaoMaterial.uniforms.cameraInverseProjectionMatrix.value.copy(this.camera.projectionMatrixInverse),this.blurMaterial.uniforms.resolution.value.set(e,n)}_renderPass(e,n,s,o,l){e.getClearColor(this._originalClearColor);const d=e.getClearAlpha(),h=e.autoClear;e.setRenderTarget(s),e.autoClear=!1,o!=null&&(e.setClearColor(o),e.setClearAlpha(l||0),e.clear()),this._fsQuad.material=n,this._fsQuad.render(e),e.autoClear=h,e.setClearColor(this._originalClearColor),e.setClearAlpha(d)}_renderOverride(e,n,s,o,l){e.getClearColor(this._originalClearColor);const d=e.getClearAlpha(),h=e.autoClear;e.setRenderTarget(s),e.autoClear=!1,o=n.clearColor||o,l=n.clearAlpha||l,o!=null&&(e.setClearColor(o),e.setClearAlpha(l||0),e.clear()),this.scene.overrideMaterial=n,e.render(this.scene,this.camera),this.scene.overrideMaterial=null,e.autoClear=h,e.setClearColor(this._originalClearColor),e.setClearAlpha(d)}_generateSampleKernel(e){const n=this.kernel;for(let s=0;s #include varying vec2 vUv; void main() { gl_FragColor = texture2D( tDiffuse, vUv ); // tone mapping #ifdef LINEAR_TONE_MAPPING gl_FragColor.rgb = LinearToneMapping( gl_FragColor.rgb ); #elif defined( REINHARD_TONE_MAPPING ) gl_FragColor.rgb = ReinhardToneMapping( gl_FragColor.rgb ); #elif defined( CINEON_TONE_MAPPING ) gl_FragColor.rgb = CineonToneMapping( gl_FragColor.rgb ); #elif defined( ACES_FILMIC_TONE_MAPPING ) gl_FragColor.rgb = ACESFilmicToneMapping( gl_FragColor.rgb ); #elif defined( AGX_TONE_MAPPING ) gl_FragColor.rgb = AgXToneMapping( gl_FragColor.rgb ); #elif defined( NEUTRAL_TONE_MAPPING ) gl_FragColor.rgb = NeutralToneMapping( gl_FragColor.rgb ); #elif defined( CUSTOM_TONE_MAPPING ) gl_FragColor.rgb = CustomToneMapping( gl_FragColor.rgb ); #endif // color space #ifdef SRGB_TRANSFER gl_FragColor = sRGBTransferOETF( gl_FragColor ); #endif }`};class Gq extends Su{constructor(){super(),this.uniforms=ul.clone(Sp.uniforms),this.material=new w6({name:Sp.name,uniforms:this.uniforms,vertexShader:Sp.vertexShader,fragmentShader:Sp.fragmentShader}),this._fsQuad=new _0(this.material),this._outputColorSpace=null,this._toneMapping=null}render(e,n,s){this.uniforms.tDiffuse.value=s.texture,this.uniforms.toneMappingExposure.value=e.toneMappingExposure,(this._outputColorSpace!==e.outputColorSpace||this._toneMapping!==e.toneMapping)&&(this._outputColorSpace=e.outputColorSpace,this._toneMapping=e.toneMapping,this.material.defines={},pn.getTransfer(this._outputColorSpace)===Mn&&(this.material.defines.SRGB_TRANSFER=""),this._toneMapping===Lk?this.material.defines.LINEAR_TONE_MAPPING="":this._toneMapping===Ok?this.material.defines.REINHARD_TONE_MAPPING="":this._toneMapping===Pk?this.material.defines.CINEON_TONE_MAPPING="":this._toneMapping===D0?this.material.defines.ACES_FILMIC_TONE_MAPPING="":this._toneMapping===Uk?this.material.defines.AGX_TONE_MAPPING="":this._toneMapping===Fk?this.material.defines.NEUTRAL_TONE_MAPPING="":this._toneMapping===Ik&&(this.material.defines.CUSTOM_TONE_MAPPING=""),this.material.needsUpdate=!0),this.renderToScreen===!0?(e.setRenderTarget(null),this._fsQuad.render(e)):(e.setRenderTarget(n),this.clear&&e.clear(e.autoClearColor,e.autoClearDepth,e.autoClearStencil),this._fsQuad.render(e))}dispose(){this.material.dispose(),this._fsQuad.dispose()}}class Vq extends iN{constructor(){super();const e=new wr;e.deleteAttribute("uv");const n=new Tb({side:ai}),s=new Tb,o=new N6(16777215,900,28,2);o.position.set(.418,16.199,.3),this.add(o);const l=new zn(e,n);l.position.set(-.757,13.219,.717),l.scale.set(31.713,28.305,28.591),this.add(l);const d=new lN(e,s,6),h=new aa;h.position.set(-10.906,2.009,1.846),h.rotation.set(0,-.195,0),h.scale.set(2.328,7.905,4.651),h.updateMatrix(),d.setMatrixAt(0,h.matrix),h.position.set(-5.607,-.754,-.758),h.rotation.set(0,.994,0),h.scale.set(1.97,1.534,3.955),h.updateMatrix(),d.setMatrixAt(1,h.matrix),h.position.set(6.167,.857,7.803),h.rotation.set(0,.561,0),h.scale.set(3.927,6.285,3.687),h.updateMatrix(),d.setMatrixAt(2,h.matrix),h.position.set(-2.017,.018,6.124),h.rotation.set(0,.333,0),h.scale.set(2.002,4.566,2.064),h.updateMatrix(),d.setMatrixAt(3,h.matrix),h.position.set(2.291,-.756,-2.621),h.rotation.set(0,-.286,0),h.scale.set(1.546,1.552,1.496),h.updateMatrix(),d.setMatrixAt(4,h.matrix),h.position.set(-2.193,-.369,-5.547),h.rotation.set(0,.516,0),h.scale.set(3.875,3.487,2.986),h.updateMatrix(),d.setMatrixAt(5,h.matrix),this.add(d);const m=new zn(e,Dc(50));m.position.set(-16.116,14.37,8.208),m.scale.set(.1,2.428,2.739),this.add(m);const p=new zn(e,Dc(50));p.position.set(-16.109,18.021,-8.207),p.scale.set(.1,2.425,2.751),this.add(p);const y=new zn(e,Dc(17));y.position.set(14.904,12.198,-1.832),y.scale.set(.15,4.265,6.331),this.add(y);const v=new zn(e,Dc(43));v.position.set(-.462,8.89,14.52),v.scale.set(4.38,5.441,.088),this.add(v);const x=new zn(e,Dc(20));x.position.set(3.235,11.486,-12.541),x.scale.set(2.5,2,.1),this.add(x);const S=new zn(e,Dc(100));S.position.set(0,20,0),S.scale.set(1,.1,1),this.add(S)}dispose(){const e=new Set;this.traverse(n=>{n.isMesh&&(e.add(n.geometry),e.add(n.material))});for(const n of e)n.dispose()}}function Dc(a){return new C6({color:0,emissive:16777215,emissiveIntensity:a})}const Rd=new he;function Zi(a,e,n,s,o,l){const d=2*Math.PI*o/4,h=Math.max(l-2*o,0),m=Math.PI/4;Rd.copy(e),Rd[s]=0,Rd.normalize();const p=.5*d/(d+h),y=1-Rd.angleTo(a)/m;return Math.sign(Rd[n])===1?y*p:h/(d+h)+p+p*(1-y)}class Yd extends wr{constructor(e=1,n=1,s=1,o=2,l=.1){const d=o*2+1;if(l=Math.min(e/2,n/2,s/2,l),super(1,1,1,d,d,d),this.type="RoundedBoxGeometry",this.parameters={width:e,height:n,depth:s,segments:o,radius:l},d===1)return;const h=this.toNonIndexed();this.index=null,this.attributes.position=h.attributes.position,this.attributes.normal=h.attributes.normal,this.attributes.uv=h.attributes.uv;const m=new he,p=new he,y=new he(e,n,s).divideScalar(2).subScalar(l),v=this.attributes.position.array,x=this.attributes.normal.array,S=this.attributes.uv.array,M=v.length/6,w=new he,E=.5/d;for(let A=0,k=0;Anew he(.8,.86,1.1).normalize().multiplyScalar(p*3.4/Math.min(1,Math.max(.25,a.clientWidth/Math.max(1,a.clientHeight))));y.position.copy(v());const x=new Sq(y,l.domElement);x.target.set(0,5.5,0),x.enableDamping=!0,x.dampingFactor=.075,x.maxPolarAngle=Math.PI*.475,x.minPolarAngle=.14,x.minDistance=9,x.maxDistance=p*8;const S=new Vq,M=new Rb(l),w=M.fromScene(S,.025);d.environment=w.texture,d.environmentIntensity=n?.38:.4,S.dispose(),M.dispose(),d.add(new R6(n?10997487:15398143,n?2374706:12892056,n?1.05:.8));const E=new tC(n?11917055:16774101,n?2.7:3);E.position.set(-18,32,18),E.castShadow=!0,E.shadow.mapSize.set(2048,2048),E.shadow.normalBias=.045,E.shadow.bias=-15e-5,E.shadow.camera.left=-p*1.6,E.shadow.camera.right=p*1.6,E.shadow.camera.top=p*1.6,E.shadow.camera.bottom=-p*1.6,E.shadow.camera.far=100,E.shadow.camera.updateProjectionMatrix(),d.add(E);const A=new tC(n?6530722:14806261,n?1:.65);A.position.set(20,14,-12),d.add(A);const k=[],R=[],N=[],I=(ge,Te=.65,Le=0,et=0,Ye=0)=>{const $e=new Tb({color:ge,roughness:Te,metalness:Le,emissive:et,emissiveIntensity:Ye});return k.push($e),$e},z=I(n?10857633:15262162,.48),j=I(n?13026742:16117727,.48),L=I(12890259,.6),D=I(10387543,.35,.65),P=I(3166798,.42,.45),F=I(n?1852491:5406334,.21,.65),q=I(n?4550514:9614252,.19,.5),J=I(1982021,.2,.5),ie=I(n?8087126:12223080,.72),Q=I(5858147,.55,.3),V=I(16112802,.4,.1,16764804,n?1.7:.22),$=I(12772985,.45,.15,10671173,n?.6:.12),te=I(n?6321262:13684155,.85),ne=I(n?10333346:15459539,.78),Y=I(n?2111546:5793891,.92),T=I(15197902,.83),_=I(7503183,.98),ve=I(n?4614995:9149287,.95),je=I(n?1868677:5813426,.17,.4),Je=I(7889993,.95),xe=I(11240540,.85),ee=[I(4747354,.95),I(7310428,.95),I(10464108,.95)],Ce=[I(n?11371922:15052478,.93),I(n?12689318:15845841,.93),I(n?9860482:14260906,.93)],Ze=new wr(1,1,1),le=new Yd(1,1,1,2,.055),qe=new Y0(1,2);R.push(Ze,le,qe);const xt=new Map,se=new Map;let Pe=new dn,mt=null;const it=new aa;function at(ge,Te,Le,et,Ye,$e=1,Qe=1,Et=1,zt=0,It=0,Sn=0){it.position.set(Le,et,Ye),it.scale.set($e,Qe,Et),it.rotation.set(zt,It,Sn),it.updateMatrix();const Lt=ge.uuid+Te.uuid;let nn=xt.get(Lt);nn||(nn={geo:ge,material:Te,transforms:[],ids:[]},xt.set(Lt,nn)),nn.transforms.push(it.matrix.clone().premultiply(Pe)),nn.ids.push(mt)}const Be=(ge,Te,Le,et,Ye,$e,Qe,Et=0,zt=!1)=>at(zt?le:Ze,Qe,et,Ye,$e,ge,Te,Le,0,Et);function We(ge,Te,Le,et,Ye,$e,Qe,Et=32){const zt=`c${ge/Te}:${Et}`;let It=se.get(zt);It||(It=new Wd(ge/Te,1,1,Et),se.set(zt,It),R.push(It)),at(It,Qe,et,Ye,$e,Te,Le,Te)}function ue(ge,Te,Le,et,Ye,$e=1){at(qe,Ye,Te,Le,et,ge,ge*$e,ge)}function ft(ge,Te,Le,et,Ye,$e,Qe=!1){const Et=`r${ge}:${Te}`;let zt=se.get(Et);zt||(zt=new X0(ge,Te,8,80),se.set(Et,zt),R.push(zt)),at(zt,$e,Le,et,Ye,1,1,1,Qe?0:Math.PI/2)}function Re(ge,Te,Le,et){const Ye=new xm(ge-Te/2,ge+Te/2,160);R.push(Ye),at(Ye,et,0,Le,0,1,1,1,-Math.PI/2)}function K(ge,Te,Le,et){const Ye=Te.clone().sub(ge);it.position.copy(ge).add(Te).multiplyScalar(.5),it.scale.set(Le,Ye.length(),Le),it.quaternion.setFromUnitVectors(new he(0,1,0),Ye.normalize()),it.updateMatrix();const $e=Ze.uuid+et.uuid;let Qe=xt.get($e);Qe||(Qe={geo:Ze,material:et,transforms:[],ids:[]},xt.set($e,Qe)),Qe.transforms.push(it.matrix.clone().premultiply(Pe)),Qe.ids.push(mt)}function B(ge,Te,Le=1,et=!1,Ye=0){We(.045*Le,.095*Le,1.18*Le,ge,Ye+.59*Le,Te,Je,7);const $e=et?Ce:ee;for(let Qe=0;Qe<5;Qe++){const Et=Qe*2.4;K(new he(ge,Ye+.65*Le,Te),new he(ge+Math.cos(Et)*.36*Le,Ye+(1.12+Qe%2*.12)*Le,Te+Math.sin(Et)*.36*Le),.04*Le,Je)}for(let Qe=0;Qe<(et?28:16);Qe++){const Et=Qe*2.39996,zt=Math.sqrt((Qe+.5)/(et?28:16))*.52,It=Math.cos(Et)*zt,Sn=Math.sin(Et)*zt,Lt=1.25+Math.sin(Qe*3.71)*.16+(1-zt)*.32;ue((et?.2:.27)*Le,ge+It*Le,Ye+Lt*Le,Te+Sn*Le,$e[Qe%3],.9)}}function pe(ge,Te,Le,et=1.1,Ye=.5){Be(et,.24,Ye,ge,Te+.12,Le,z,0,!0),Be(et-.1,.045,Ye-.1,ge,Te+.255,Le,_);for(let $e=0;$e<3;$e++)ue(.19,ge-et*.3+$e*et*.3,Te+.36,Le,ee[$e],.75)}function Ae(ge,Te,Le){const et=Pe.clone();Pe.multiply(new dn().makeTranslation(ge,0,Te)).multiply(new dn().makeRotationY(Le));for(let Ye=0;Ye<3;Ye++)Be(1.05,.065,.095,0,.36,-.16+Ye*.12,xe),Be(1.05,.07,.065,0,.6+Ye*.08,-.23,xe);Be(.06,.36,.4,-.4,.18,0,P),Be(.06,.36,.4,.4,.18,0,P),Pe.copy(et)}function Ne(ge,Te,Le=0){We(.035,.048,1.55,ge,Le+.78,Te,P,8),Be(.32,.055,.08,ge+.12,Le+1.55,Te,P),ue(.095,ge+.25,Le+1.53,Te,V,.7),We(.12,.16,.14,ge,Le+.07,Te,ne,10)}function be(ge,Te,Le,et=0){const Ye=[P,ie,z,Q,D][Le%5];ue(.065,ge,et+.4,Te,L),Be(.14,.2,.1,ge,et+.235,Te,Ye,0,!0),Be(.045,.16,.05,ge-.045,et+.08,Te,P),Be(.045,.16,.05,ge+.045,et+.08,Te,P)}function ot(ge,Te,Le,et,Ye,$e,Qe=0){Be(ge,Te,Le,et,Ye+Te/2,$e,Qe===1?ie:z,0,!0);const Et=Math.max(2,Math.round(Te/.65)),zt=Math.max(2,Math.floor(ge/.5)),It=Math.max(2,Math.floor(Le/.5));for(let Sn=0;Sn{const{x:Le,z:et,angle:Ye}=qq(Te,e.length);Pe.makeTranslation(Le,.14,et).multiply(new dn().makeRotationY(Math.atan2(-Le,-et))),mt=ge.id;const $e=Te%8;let Qe=6;if(Be(5.15,.16,5.05,0,.04,0,te,0,!0),ut(),$e===0){Ve(2.9,6.8,2.7,0,1.34,-.2),Ve(2.15,3.5,2,0,8.2,-.2),Ve(1.45,1.55,1.4,0,11.78,-.2);for(const Ft of[-1,1])for(let Fn=0;Fn<3;Fn++)Be(.075,9.4,.075,Ft*(1.5-Fn*.25),6,1.18,D);We(.08,.13,2,0,14.25,-.2,D,12),ue(.14,0,15.3,-.2,V),Be(.85,.25,.85,0,13.55,-.2,$),pe(-1.7,1.36,1.1,.6,1.4),pe(1.7,1.36,1.1,.6,1.4),Qe=15.4}else if($e===1){ot(3.2,4.7,2.8,-.35,1.35,0,2),Ve(.9,6.9,1.6,1.55,1.35,-.5),We(1.35,1.35,.3,-.35,6.25,0,D);const Ft=new ym(1,32,20,0,Math.PI*2,0,Math.PI/2);R.push(Ft),at(Ft,j,-.35,6.4,0,1.28,1.1,1.28),Be(.12,.8,1.85,-.35,6.85,.05,D),We(.18,.35,.42,1.55,8.5,-.5,j),pe(0,1.34,1.63,2.5,.35),Qe=8.75}else if($e===2){ot(3.6,3.2,2.8,0,1.35,0,1),ot(2.75,1.85,2.25,0,4.7,-.22,0),ot(1.8,1.15,1.6,0,6.7,-.4,0);for(let Ft=0;Ft<5;Ft++)Be(.075,3.2,.08,-1.57+Ft*.78,2.98,1.46,L);pe(-1.55,4.82,.45,.45,1.2),pe(1.55,4.82,.45,.45,1.2),Be(1,.22,.7,0,8.13,-.4,D),Qe=8.25}else if($e===3)Ve(1.7,6.2,2.8,-1.05,1.35,0),Ve(1.55,4.5,2.6,1.02,1.35,0),Be(1.1,.55,1.1,0,4.2,-.3,q),Be(1.2,.1,1.2,0,4.52,-.3,z),Be(.06,1.2,.06,-1.05,8.13,0,D),pe(1.05,6,.7,1.1,.5),Qe=8.75;else if($e===4){for(let Ft=0;Ft<3;Ft++){const Fn=1.35+Ft*.93,Mo=(Ft-1)*.22;Be(3.8,.75,3.05,Mo,Fn+.37,0,J,0,!0),Be(4.35,.18,3.4,Mo,Fn+.82,0,j,0,!0);for(const zl of[-1,1])for(let Ws=0;Ws<6;Ws++)Be(.055,.75,.055,Mo-1.7+Ws*.68,Fn+.37,zl*1.55,D)}Be(2.8,.1,2.15,.22,4.29,0,ve,0,!0),B(-.6,.2,.65,!1,4.35),B(.8,-.2,.55,!1,4.35),pe(0,1.34,1.7,2.5,.45),Qe=5.55}else if($e===5){We(1.55,1.8,8,0,5.35,0,q,6);for(let Ft=0;Ft<13;Ft++)We(1.86-Ft*.025,1.86-Ft*.025,.075,0,1.42+Ft*.63,0,z,6);for(let Ft=0;Ft<6;Ft++){const Fn=Ft*Math.PI/3;K(new he(Math.sin(Fn)*1.8,1.4,Math.cos(Fn)*1.8),new he(Math.sin(Fn)*1.55,9.35,Math.cos(Fn)*1.55),.085,D)}We(1.62,1.62,.24,0,9.48,0,j,6),We(1.18,1.3,.7,0,9.94,0,J,6),We(.14,.28,.9,0,10.72,0,$,6),Qe=11.2}else if($e===6){ot(3.7,3.7,3,0,1.35,0),ot(2.85,2.1,2.2,-.2,5.2,-.3),ot(1.8,1.5,1.7,-.45,7.45,-.5);for(let Ft=0;Ft<3;Ft++)pe(-1.15+Ft*.95,5.35,1.27,.72,.3);pe(1.54,5.35,-.25,.3,1.5),Be(.14,1.05,.15,-1.1,9.6,-.5,D),Be(.14,1.05,.15,.2,9.6,-.5,D),Be(1.45,.15,.15,-.45,10.1,-.5,D),Qe=10.2}else{ot(3.7,3,3,0,1.35,.1,1);for(let Ft=0;Ft<3;Ft++){const Fn=new Wd(.77,.77,1.25,3);Fn.rotateZ(Math.PI/2),R.push(Fn),at(Fn,j,-1.25+Ft*1.25,4.85,.1,1,1,1,0,0,Math.PI/6),Be(1.05,.3,.06,-1.25+Ft*1.25,4.65,1.52,q)}ot(1.2,6.5,1.2,-1.3,4.45,-.65,0),Be(1.55,.2,1.55,-1.3,11.1,-.65,D),ft(.4,.07,-1.3,10.28,.02,V,!0),Be(.06,.32,.05,-1.3,10.33,.07,P),Be(.25,.05,.05,-1.2,10.28,.07,P),Qe=11.3}Be(.48,.12,.04,0,1.2,2.39,ge.status==="Working"?$:Q),Be(.5,.25,.65,-.7,1.48,-1.5,Q),Be(.6,.08,.75,-.7,1.65,-1.5,j),B(-2.15,-1.9,.78,Te%2===0),B(2.22,1.65,.82,Te%3===0),pe(-1.52,.12,2.03,1,.38),pe(1.52,.12,2.03,1,.38),Ne(2.3,2.35),be(.55,2.55,Te),be(-.5,2.4,Te+2),be(1.4,2.65,Te+1);const Et=document.createElement("canvas");Et.width=512,Et.height=128;const zt=Et.getContext("2d");zt.fillStyle=n?"#173c3b":"#faf7ee",zt.beginPath(),zt.roundRect(2,2,508,124,18),zt.fill(),zt.fillStyle="#749044",zt.fillRect(24,25,7,78),zt.fillStyle=n?"#edf0db":"#213f39",zt.font="600 43px system-ui",zt.textBaseline="middle",zt.fillText(ge.name,48,47,440),zt.font="600 25px system-ui",zt.fillStyle=n?"#d0dccf":"#46564b",zt.fillText(Wq[$e].toUpperCase(),48,87,440);const It=new QM(Et);It.colorSpace=Xa,N.push(It);const Sn=new f6(new sN({map:It,depthTest:!1,transparent:!0}));Sn.position.set(Le,Qe+1.05,et),Sn.scale.set(6.8,1.7,1),Sn.userData.agentId=ge.id,d.add(Sn),ct.push(Sn),lt.set(ge.id,new he(Le,Math.min(Qe*.45,5),et)),tt.set(ge.id,Qe),mt=null,Pe.identity();const Lt=new qd({color:13825411,transparent:!0,opacity:.8,depthWrite:!1});k.push(Lt);const nn=new xm(2.73,2.79,80);R.push(nn);const mn=new zn(nn,Lt);mn.rotation.x=-Math.PI/2,mn.position.set(Le,.26,et),mn.userData.agentId=ge.id,d.add(mn),fe.push(mn);const Gt=Ye+Math.PI/Math.max(1,e.length),An=Math.cos(Gt)*(m+.7),oi=Math.sin(Gt)*(m+.7);We(.82,.9,.15,An,.18,oi,z,32),We(.76,.76,.04,An,.28,oi,_,32),B(An,oi,1.35,!0,.29),B(Math.cos(Gt)*(m+3),Math.sin(Gt)*(m+3),.85),Ne(Math.cos(Gt)*(Se+1.5),Math.sin(Gt)*(Se+1.5)),Ae(Math.cos(Gt)*(m+2),Math.sin(Gt)*(m+2),-Gt);for(let Ft=0;Ft<5;Ft++)ue(.12,An+Math.cos(Ft)*.6,.3,oi+Math.sin(Ft)*.6,Ce[Ft%3],.6)});const oe=document.createElement("canvas");oe.width=1024,oe.height=128;const Fe=oe.getContext("2d");Fe.fillStyle=n?"#abc3b5":"#697b67",Fe.font="500 52px system-ui",Fe.textAlign="center",Fe.fillText("A C C O R D O / A G E N T D I S T R I C T",512,80);const Xe=new QM(oe);Xe.colorSpace=Xa,N.push(Xe);const dt=new qd({map:Xe,transparent:!0,depthWrite:!1});k.push(dt);const W=p-1,U=new uu(10.5,1.31,96,1),ce=U.attributes.position;for(let ge=0;geTe.setMatrixAt(et,Le)),Te.castShadow=!0,Te.receiveShadow=!0,Te.userData.agentIds=ge.ids,d.add(Te),ge.ids.some(Boolean)&&ke.push(Te)}const pt=[];for(let ge=0;ge<3;ge++){const Te=new Pd,Le=new zn(new Yd(.56,.27,1.08,2,.07),[j,ie,P][ge]);Le.position.y=.27,Te.add(Le);const et=new zn(new Yd(.46,.21,.65,2,.04),J);et.position.set(0,.48,-.05),Te.add(et);for(const Ye of[-1,1])for(const $e of[-.34,.34]){const Qe=new zn(new Wd(.095,.095,.05,10),Q);Qe.rotation.z=Math.PI/2,Qe.position.set(Ye*.28,.19,$e),Te.add(Qe)}for(const Ye of[-1,1]){const $e=new zn(new wr(.13,.035,.02),V);$e.position.set(Ye*.14,.3,.55),Te.add($e)}Te.traverse(Ye=>{Ye instanceof zn&&(Ye.castShadow=!0,R.push(Ye.geometry))}),d.add(Te),pt.push(Te)}const Mt=new qd({color:13038445});k.push(Mt);const Vt=new ym(.105,12,8);R.push(Vt);const hn=Array.from({length:8},()=>{const ge=new zn(Vt,Mt);return d.add(ge),ge}),bn=new cN({color:n?12966809:6850648,transparent:!0,opacity:.45});k.push(bn);const fa=Array.from({length:8},()=>{const ge=new Oa;R.push(ge);const Te=new x6(ge,bn);return d.add(Te),Te});let Ta="",ba=[],Qn=null,ri="",_n={x:0,y:0},In=0,Un=!0;const wi=new O6,Ms=new jt;function Rn(ge){const Te=l.domElement.getBoundingClientRect();Ms.set((ge.clientX-Te.left)/Te.width*2-1,-(ge.clientY-Te.top)/Te.height*2+1),wi.setFromCamera(Ms,y);for(const Le of wi.intersectObjects(ke,!1)){const et=Le.object.userData.agentIds[Le.instanceId??0];if(et)return et}return""}const Mi=()=>{ri="",l.domElement.style.cursor="grab"},qs=ge=>{_n={x:ge.clientX,y:ge.clientY}},Ci=ge=>{ge.buttons||(ri=Rn(ge),l.domElement.style.cursor=ri?"pointer":"grab")},Z=ge=>{if(Math.hypot(ge.clientX-_n.x,ge.clientY-_n.y)>7)return;const Te=Rn(ge);o(Te)};l.domElement.addEventListener("pointerleave",Mi),l.domElement.addEventListener("pointerdown",qs),l.domElement.addEventListener("pointermove",Ci),l.domElement.addEventListener("pointerup",Z),l.domElement.style.cursor="grab",x.addEventListener("start",()=>{Qn=null});const ye=new Fq(l,new As(1,1,{type:Er,samples:4})),Oe=new Bq(d,y);ye.addPass(Oe);const Ie=new uo(d,y,1,1,16);Ie.kernelRadius=.9,Ie.minDistance=5e-4,Ie.maxDistance=.025,ye.addPass(Ie);const Ee=new Gq;ye.addPass(Ee);let rt=a.clientWidth;const bt=new ResizeObserver(()=>{Math.abs(rt-a.clientWidth)>80&&(y.position.copy(v()),x.target.set(0,5.5,0),Qn=null),rt=a.clientWidth,y.aspect=a.clientWidth/Math.max(1,a.clientHeight),y.updateProjectionMatrix(),l.setSize(a.clientWidth,a.clientHeight),ye.setSize(a.clientWidth,a.clientHeight)});bt.observe(a);const St=new IntersectionObserver(ge=>{Un=ge[0]?.isIntersecting??!0});St.observe(a);const yt=new he,Tt=new he,Nt=new he;function Dt(){const ge=ct.filter($e=>$e.visible);if(!ge.length)return;const Te=l.domElement.clientWidth||1,Le=l.domElement.clientHeight||1,et=Math.min(2,Math.max(1,860/Te));for(const $e of ge)$e.scale.set(6.8*et,1.7*et,1);Nt.set(0,1,0).applyQuaternion(y.quaternion);const Ye=[];for(const $e of ge.sort((Qe,Et)=>Qe.position.distanceToSquared(y.position)-Et.position.distanceToSquared(y.position))){yt.copy($e.position).project(y),Tt.copy($e.position).addScaledVector(Nt,$e.scale.y).project(y);const Qe=Math.max(4,Math.abs(Tt.y-yt.y)*Le/2),Et=Qe*$e.scale.x/$e.scale.y,zt=(1-yt.y)*Le/2;let It=(yt.x+1)*Te/2;const Sn=Math.max(0,It+Et/2-(Te-6))-Math.max(0,6-(It-Et/2));It-=Sn;let Lt=0;const nn=mn=>Ye.some(Gt=>Math.abs(Gt.x-It)<(Gt.w+Et)/2+4&&Math.abs(Gt.y-(zt-mn*Qe*1.08))<(Gt.h+Qe)/2+2);for(;Lt<6&&nn(Lt);)Lt++;$e.center.set(.5+Sn/Et,.5-Lt*1.08),Ye.push({x:It,y:zt-Lt*Qe*1.08,w:Et,h:Qe})}}function Ht(ge){if(In=requestAnimationFrame(Ht),!Un||document.hidden)return;const Te=Da().reduceMotion,Le=s();x.enableDamping=!Te,Qn&&(y.position.lerp(Qn.position,Te?1:.055),x.target.lerp(Qn.target,Te?1:.055),y.position.distanceTo(Qn.position)<.035&&(Qn=null)),x.update(),ct.forEach($e=>{$e.visible=Le.labels||$e.userData.agentId===ri}),Dt(),fe.forEach($e=>$e.visible=$e.userData.agentId===Le.selected||$e.userData.agentId===ri),pt.forEach(($e,Qe)=>{const Et=Te?Qe*2.2:ge*35e-6+Qe*2.2,zt=Se+(Qe===1?-.44:.44);$e.position.set(Math.cos(Et)*zt,.14,Math.sin(Et)*zt),$e.rotation.y=-Et});const et=Le.routes.filter($e=>lt.has($e.from)&<.has($e.to)).slice(0,8),Ye=JSON.stringify(et);Ye!==Ta&&(Ta=Ye,ba=et.map($e=>{const Qe=lt.get($e.from).clone(),Et=lt.get($e.to).clone();Qe.y=(tt.get($e.from)||5)+.3,Et.y=(tt.get($e.to)||5)+.3;const zt=Qe.clone().lerp(Et,.5);return zt.y+=3,new E6(Qe,zt,Et)}),fa.forEach(($e,Qe)=>{$e.geometry.dispose(),$e.geometry=new Oa,ba[Qe]&&$e.geometry.setFromPoints(ba[Qe].getPoints(50))})),hn.forEach(($e,Qe)=>{$e.visible=!!ba[Qe]&&Le.handoffs,fa[Qe].visible=$e.visible,$e.visible&&$e.position.copy(ba[Qe].getPoint(Te?.5:(ge/5500+Qe*.2)%1))}),ye.render()}return In=requestAnimationFrame(Ht),{zoom:ge=>{y.position.sub(x.target).multiplyScalar(ge).add(x.target),x.update()},fly:ge=>{const Te=lt.get(ge);if(!Te)return;const Le=tt.get(ge)||7;Qn={target:Te.clone(),position:Te.clone().add(new he(Le*.7+5,Le*.6+4,Le*.8+6))},o(ge)},reset:()=>{Qn={position:v(),target:new he(0,5.5,0)}},screen:ge=>{const Te=lt.get(ge);if(!Te)return null;const Le=Te.clone();Le.y=(tt.get(ge)||7)+1.6,Le.project(y);const et=l.domElement.getBoundingClientRect();return{x:(Le.x+1)/2*et.width,y:(1-Le.y)/2*et.height,visible:Le.z<1&&Math.abs(Le.x)<=1.05&&Math.abs(Le.y)<=1.05}},destroy:()=>{cancelAnimationFrame(In),bt.disconnect(),St.disconnect(),x.dispose(),l.domElement.removeEventListener("pointerleave",Mi),l.domElement.removeEventListener("pointerdown",qs),l.domElement.removeEventListener("pointermove",Ci),l.domElement.removeEventListener("pointerup",Z),ct.forEach(ge=>ge.material.dispose()),fa.forEach(ge=>ge.geometry.dispose()),new Set(R).forEach(ge=>ge.dispose()),new Set(k).forEach(ge=>ge.dispose()),N.forEach(ge=>ge.dispose()),w.dispose(),Oe.dispose(),Ie.dispose(),Ee.dispose(),ye.dispose(),l.dispose(),l.domElement.remove()}}}function Xq({agents:a,onChat:e}){const n=C.useRef(""),s=C.useRef(e),o=C.useRef(!1),l=C.useRef(null),[d,h]=C.useState("");s.current=e,C.useEffect(()=>{if(!d)return;let L=0;const D=()=>{const P=l.current,F=y.current,q=p.current;if(P&&F&&q){const J=F.screen(d);J&&(P.style.left=`${q.offsetLeft+J.x}px`,P.style.top=`${q.offsetTop+J.y-22}px`,P.style.opacity=J.visible?"":"0")}L=requestAnimationFrame(D)};return D(),()=>cancelAnimationFrame(L)},[d]);const m=Bi(),p=C.useRef(null),y=C.useRef(null),[v,x]=C.useState(a[0]?.id||""),[S,M]=C.useState(""),[w,E]=C.useState(!1),[A,k]=C.useState(!0),[R,N]=C.useState(document.documentElement.dataset.theme),I=C.useRef({labels:!1,handoffs:!0}),z=C.useRef([]);I.current={labels:w,handoffs:A},z.current=m.missions.filter(L=>L.status==="Running").flatMap(L=>L.handoffs.map(D=>({from:D.from,to:D.to})));const j=a.find(L=>L.id===v)||a[0];return n.current=j?.id||"",C.useEffect(()=>{const L=new MutationObserver(()=>N(document.documentElement.dataset.theme));return L.observe(document.documentElement,{attributes:!0,attributeFilter:["data-theme"]}),()=>L.disconnect()},[]),C.useEffect(()=>{const L=p.current;if(L)try{const D=Yq(L,a,R==="dark",()=>({...I.current,selected:n.current,routes:z.current}),P=>{if(o.current){P&&x(P);return}if(!P){h("");return}x(P),h(P)});return y.current=D,M(""),()=>{D.destroy(),y.current=null}}catch{M("3D rendering is unavailable in this browser. Use the agent selector to open a conversation.")}},[a.map(L=>`${L.id}:${L.name}:${L.status}`).join("|"),R]),t.jsxs("section",{className:"panel pro-city-shell pro-garden pro-city-immersive",children:[t.jsxs("div",{className:"pro-city-overlay",children:[t.jsxs("div",{children:[t.jsx("h1",{children:u("The Laboratorio district")}),t.jsxs("p",{children:[u(a.length),u(" agents · "),u(m.missions.filter(L=>L.status==="Running").length),u(" missions running")]})]}),t.jsxs("div",{className:"pro-city-toggles",children:[t.jsx("select",{"aria-label":u("City buildings"),value:j?.id||"",onChange:L=>{x(L.target.value),o.current=!0;try{y.current?.fly(L.target.value)}finally{o.current=!1}},children:a.map(L=>t.jsx("option",{value:L.id,children:L.name},L.id))}),t.jsx("button",{"aria-label":u("Fly in"),title:u("Fly in"),disabled:!j,onClick:()=>{if(j){o.current=!0;try{y.current?.fly(j.id)}finally{o.current=!1}}},children:t.jsx(_i,{size:16})}),t.jsx("button",{"aria-label":u("Open chat"),title:u("Open chat"),disabled:!j,onClick:()=>j&&e(j.id),children:t.jsx(yi,{size:16})}),t.jsxs("button",{"aria-label":u("Labels"),"aria-pressed":w,className:w?"selected":"",onClick:()=>E(L=>!L),children:[t.jsx(dU,{size:15}),t.jsx("span",{children:u("Labels")})]}),t.jsxs("button",{"aria-label":u("Handoffs"),"aria-pressed":A,className:A?"selected":"",onClick:()=>k(L=>!L),children:[t.jsx(Em,{size:15}),t.jsx("span",{children:u("Handoffs")})]})]})]}),t.jsx("div",{className:"pro-city-canvas",ref:p}),d&&t.jsxs("button",{ref:l,type:"button",className:"city-chat-pop","aria-label":u(`Chat with ${a.find(L=>L.id===d)?.name||""}`),onClick:()=>{s.current(d),h("")},children:[t.jsx("i",{"aria-hidden":"true",children:"✦"}),u("Chat with")," ",a.find(L=>L.id===d)?.name]}),t.jsxs("div",{className:"pro-city-controls",children:[t.jsx("button",{"aria-label":u("Zoom in"),onClick:()=>y.current?.zoom(.8),children:t.jsx(jn,{size:19})}),t.jsx("button",{"aria-label":u("Zoom out"),onClick:()=>y.current?.zoom(1.2),children:t.jsx(Hj,{size:19})}),t.jsx("button",{"aria-label":u("Reset city view"),onClick:()=>y.current?.reset(),children:t.jsx(ss,{size:18})}),t.jsx("button",{"aria-label":u("Fullscreen city"),onClick:()=>p.current?.parentElement?.requestFullscreen?.(),children:t.jsx(CU,{size:18})})]}),t.jsxs("div",{className:"pro-city-hint",children:[t.jsx(DU,{size:14}),u("Drag to orbit · scroll or pinch to zoom · click a building")]}),S&&t.jsx("div",{className:"city-render-error",children:t.jsx(Ot,{error:!0,children:u(S)})})]})}const Fc=[{id:"composio",name:"Composio",category:"Automation",description:"One tool layer for agent actions across your favorite apps.",mark:"C",color:"#ed753e",scopes:["Discover enabled toolkits","Execute approved tool actions","Use configured triggers"],recommended:!0,hub:!0},{id:"tailscale",name:"Tailscale",category:"Access",description:"Open your dashboard from your phone or laptop, privately, with nothing opened to the internet.",mark:"∷",color:"#242424",scopes:["Reach this dashboard from your own devices"],recommended:!0,access:!0},{id:"higgsfield",name:"Higgsfield",category:"Creative",description:"Images and videos from Higgsfield’s models, made by your team. Agents check the price first and only generate when you allow it.",mark:"H",color:"#141414",scopes:["See models, styles and prices","Generate images and videos with my approval","Generate on its own (spends credits)"],recommended:!0,native:!0},{id:"gmail",name:"Gmail",category:"Communication",description:"Find important messages and prepare thoughtful email drafts.",mark:"M",color:"#d65345",scopes:["Read selected email","Create email drafts","Send email with approval"],recommended:!0},{id:"calendar",name:"Google Calendar",category:"Productivity",description:"Plan your day and coordinate the work around your schedule.",mark:"31",color:"#4285db",scopes:["Read calendar events","Create and update events","Invite guests with approval"],recommended:!0},{id:"tasks",name:"Google Tasks",category:"Productivity",description:"Keep your to-do lists in step with the work your team does.",mark:"✓",color:"#2f6fd1",scopes:["Read your task lists","Add and update tasks","Complete and delete tasks with approval"]},{id:"docs",name:"Google Docs",category:"Knowledge",description:"Read your notes and documents, and draft new ones.",mark:"≡",color:"#3b78e7",scopes:["Read your documents","Create new documents","Edit existing documents with approval"],recommended:!0},{id:"sheets",name:"Google Sheets",category:"Productivity",description:"Analyze spreadsheet data and keep reports up to date.",mark:"▤",color:"#32936b",scopes:["Read selected spreadsheets","Update spreadsheet cells","Create spreadsheets"]},{id:"drive",name:"Google Drive",category:"Knowledge",description:"Find source material and keep your team’s deliverables organized.",mark:"△",color:"#379469",scopes:["Read selected files","Create and update files","Organize folders"]},{id:"youtube",name:"YouTube",category:"Research",description:"Look up videos and channels, with their numbers, for research and content ideas.",mark:"▶",color:"#d9453b",scopes:["Search videos and read channel statistics"]},{id:"meet",name:"Google Meet",category:"Communication",description:"Read meeting recordings and transcripts, so nothing said gets lost.",mark:"◉",color:"#1f8a70",scopes:["Read meeting records and transcripts"]}],Kq=["docs","composio","gmail","calendar","drive","youtube"].map(a=>Fc.find(e=>e.id===a));function Jq(){const[a,e]=C.useState(null),n=l=>e({...l,at:Date.now()});async function s(){try{n(await wt("/api/tailnet"))}catch{}}C.useEffect(()=>{s();const l=()=>{document.visibilityState==="visible"&&s()};return window.addEventListener("focus",l),document.addEventListener("visibilitychange",l),()=>{window.removeEventListener("focus",l),document.removeEventListener("visibilitychange",l)}},[]);const o=!!a&&(a.busy||a.publishing||!!a.authUrl&&!a.signedIn);return C.useEffect(()=>{if(!o)return;const l=setInterval(s,a?.busy?1500:3e3);return()=>clearInterval(l)},[o,a?.busy]),{ts:a,setTs:n,load:s}}function Zq(a){return a?a.url?"On your tailnet":a.signedIn?"Signed in":a.authUrl?"Waiting for sign-in":null:null}function Qq({ts:a,setTs:e,load:n,onDone:s,feedback:o}){const[l,d]=C.useState(!1),[h,m]=C.useState(!1),[p,y]=C.useState(!1),[v,x]=C.useState(!1);async function S(R,N,I={}){d(!0);try{const z=await wt(R,I);e(z),N?.(z)}catch(z){o(z.message)}d(!1)}const[,M]=C.useState(0),w=!!a&&(a.busy||a.publishing||!!a.authUrl&&!a.signedIn);C.useEffect(()=>{if(!w)return;const R=setInterval(()=>M(N=>N+1),1e3);return()=>clearInterval(R)},[w]);const E=R=>R+Math.max(0,Math.floor((Date.now()-(a?.at||Date.now()))/1e3));if(!a)return t.jsx(Ot,{children:u("Checking Tailscale on this server…")});const A=a.url?3:a.signedIn?2:a.installed&&!a.busy?1:0,k=R=>window.open(R,"_blank","noopener");return t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"integration-setup-title",children:[t.jsx("span",{className:"integration-mark",style:{"--tool-color":"#242424"},"aria-hidden":"true",children:"∷"}),t.jsxs("div",{children:[t.jsx("h3",{children:u("Your dashboard, on your own devices")}),t.jsx("p",{children:u("Tailscale is a private network between your own devices. Connect this server once, and open Laboratorio from your phone or laptop anywhere, with nothing opened to the internet.")})]})]}),t.jsx("div",{className:"integration-steps","aria-label":u("Tailscale setup"),children:["Connect","Sign in","On your tailnet"].map((R,N)=>{const I=A>N||N===2&&!!a.url,z=A===N;return t.jsxs("span",{className:z&&!I?"current":I?"complete":"",children:[t.jsx("b",{children:u(I?t.jsx(Kt,{size:12}):N+1)}),u(R)]},R)})}),a.plan==="app"&&!a.installed&&t.jsxs(t.Fragment,{children:[t.jsx(Ot,{children:u("Install the Tailscale app on this computer (tailscale.com/download) and sign in to it. Then press Check again.")}),t.jsxs("div",{className:"pro-actions right",children:[t.jsxs("button",{className:"secondary-btn",onClick:()=>k("https://tailscale.com/download"),children:[t.jsx(Dd,{size:15}),u("Get Tailscale")]}),t.jsx("button",{className:"primary-btn",disabled:l,onClick:()=>{n()},children:u("Check again")})]})]}),a.plan!=="app"&&!a.signedIn&&!a.authUrl&&t.jsxs(t.Fragment,{children:[a.busy?t.jsx(Py,{title:"Setting up Tailscale on this server",steps:a.plan==="root"?["Install Tailscale","Get your sign-in link"]:["Download Tailscale","Start it","Get your sign-in link"],current:/sign-in|link/.test(a.stage)?a.plan==="root"?1:2:/start|unpack/.test(a.stage)&&a.plan!=="root"?1:0,elapsed:E(a.busyFor),progress:a.progress,note:"Usually under a minute. You can leave this window open."}):t.jsx(Ot,{error:!!a.error,children:u(a.error?`It stopped: ${a.error}`:a.plan==="own"?"Laboratorio downloads Tailscale (about 30 MB) and runs it for this dashboard only. Nothing else on this server changes.":a.plan==="root"?"Laboratorio installs Tailscale with Tailscale's own installer (about a minute).":"Tailscale is installed here. Sign it in to your account.")}),t.jsx("div",{className:"pro-actions right",children:t.jsxs("button",{className:"primary-btn",disabled:l||a.busy,onClick:()=>S("/api/tailnet/connect",R=>{R.authUrl&&k(R.authUrl)}),children:[u(a.busy||l?t.jsx(Jt,{className:"spin",size:16}):t.jsx(jn,{size:16})),u(a.busy?"Setting up…":a.error?"Try again":"Connect to Tailscale")]})})]}),!a.signedIn&&a.authUrl&&t.jsxs(t.Fragment,{children:[t.jsx(Ot,{children:u(a.signInStuck?"Approved it already and this card is still waiting? Tailscale sometimes does not pass the approval on (most often when the sign-in page was opened twice). Get a new sign-in link below and sign in once more, in one tab.":"Sign in with your Tailscale account (it is free to create one) in the tab that opens, and approve this server. Open it once: this card updates by itself.")}),t.jsxs("div",{className:"tailnet-signin",children:[a.qr&&t.jsx("img",{src:a.qr,alt:u("Scan to sign in to Tailscale from your phone"),width:132,height:132}),t.jsxs("div",{children:[t.jsx("p",{children:u(a.qr?"On your phone? Scan the code. On this computer, use the button.":"The sign-in opens on Tailscale's own page. Laboratorio never sees your password.")}),t.jsxs("button",{className:"primary-btn",disabled:v,onClick:()=>{k(a.authUrl),x(!0),setTimeout(()=>x(!1),15e3)},children:[t.jsx(Dd,{size:15}),u(v?"Opened in a new tab":"Open the Tailscale sign-in")]}),t.jsx("button",{className:"text-btn",disabled:l,onClick:()=>S("/api/tailnet/connect",void 0,{fresh:!0}),children:u(a.signInStuck?"Get a new sign-in link":"Sign-in link expired? Get a new one")})]})]}),t.jsxs("div",{className:"tailnet-waiting",role:"status","aria-live":"polite",children:[t.jsx(Jt,{className:"spin",size:16}),t.jsx("span",{children:u(v||a.signInFor>20?"Waiting for your approval in the Tailscale tab. This card moves on by itself the moment you approve.":"Waiting for you to open the sign-in.")}),t.jsx("b",{children:Vm(E(a.signInFor))})]})]}),a.signedIn&&!a.url&&t.jsxs(t.Fragment,{children:[a.publishing&&!a.enableUrl?t.jsx(Py,{title:"Putting your dashboard on your tailnet",steps:["Add the dashboard to your tailnet","Get its secure certificate from Tailscale (20 to 60 seconds)","Show your address"],current:a.publishStage==="serve"?0:a.publishStage==="certificate"?1:2,elapsed:E(a.publishFor),note:"It is working. The address appears here the moment it opens."}):t.jsx(Ot,{error:!!a.publishError,children:u(a.publishError?`Tailscale said: ${a.publishError}`:a.enableUrl?"One more click: your tailnet has never served a page before. Allow HTTPS for it on Tailscale's page, and the address appears here.":`This server is on your tailnet${a.machine?` as ${a.machine}`:""}. Put the dashboard on it, so you can open Laboratorio from any of your devices?`)}),!(a.publishing&&!a.enableUrl)&&t.jsx("div",{className:"pro-actions right",children:a.enableUrl?t.jsxs("button",{className:"primary-btn",onClick:()=>k(a.enableUrl),children:[t.jsx(Dd,{size:15}),u("Allow HTTPS on my tailnet")]}):t.jsxs(t.Fragment,{children:[t.jsx("button",{className:"secondary-btn",onClick:s,children:u("Not now")}),t.jsxs("button",{className:"primary-btn",disabled:l||a.publishing,onClick:()=>{e({...a,publishing:!0,publishStage:"serve",publishFor:0}),S("/api/tailnet/publish",R=>{R.url&&o("Your dashboard is on your tailnet. The address stays on the Tailscale card.")})},children:[u(l||a.publishing?t.jsx(Jt,{className:"spin",size:16}):t.jsx(za,{size:16})),u("Yes, put it on my tailnet")]})]})})]}),a.url&&t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"tailnet-address",children:[t.jsx("span",{className:"panel-kicker",children:u("YOUR DASHBOARD ON YOUR TAILNET")}),t.jsx("a",{href:a.link,target:"_blank",rel:"noopener",children:a.url}),t.jsxs("div",{children:[t.jsxs("button",{className:"secondary-btn",onClick:async()=>{try{await navigator.clipboard.writeText(a.link),m(!0),setTimeout(()=>m(!1),1800)}catch{o("Copy did not work in this browser. Select the address and copy it.")}},children:[u(h?t.jsx(Kt,{size:15}):t.jsx(uU,{size:15})),u(h?"Copied":"Copy link")]}),t.jsxs("button",{className:"primary-btn",onClick:()=>k(a.link),children:[t.jsx(Dd,{size:15}),u("Open")]})]})]}),a.publishWarning&&t.jsx(Ot,{error:!0,children:u(a.publishWarning)}),a.publishNote&&t.jsx(Ot,{children:u(a.publishNote)}),t.jsx(Ot,{children:u(`Open it on any device signed in to your Tailscale account${a.tailnet?` (${a.tailnet})`:""}. This address stays here on the Tailscale card.`)}),a.sharesLocalhost&&t.jsx("p",{className:"pro-small",children:u("Tailscale runs for this dashboard in user mode here, so programs on this server that listen only on this machine can also be reached from your own tailnet devices.")}),p?t.jsxs(t.Fragment,{children:[t.jsx("p",{className:"pro-small",children:u(a.mode==="own"?"Take the dashboard off your tailnet and disconnect this server from Tailscale? You can connect it again any time. Tailscale keeps this server in your device list: remove it there (login.tailscale.com/admin/machines) and a new connection gets the same address again.":"Take the dashboard off your tailnet? Your Tailscale itself stays as it is.")}),t.jsxs("div",{className:"pro-actions right",children:[t.jsx("button",{className:"secondary-btn",onClick:()=>y(!1),children:u("Keep it")}),t.jsx("button",{className:"pro-danger",disabled:l,onClick:()=>S(a.mode==="own"?"/api/tailnet/disconnect":"/api/tailnet/unpublish",()=>{y(!1),o("Your dashboard is off the tailnet.")}),children:u(a.mode==="own"?"Disconnect":"Take it off")})]})]}):t.jsxs("div",{className:"pro-actions spread",children:[t.jsxs("button",{className:"text-btn pro-delete-icon",onClick:()=>y(!0),children:[t.jsx(I2,{size:15}),u(a.mode==="own"?"Disconnect Tailscale":"Take it off the tailnet")]}),t.jsx("button",{className:"primary-btn",onClick:s,children:u("Done")})]})]})]})}function _q({hf:a,onChange:e,onChooseAgents:n,feedback:s,connected:o}){const[l,d]=C.useState(""),[h,m]=C.useState("");async function p(x,S={},M=""){d(M||x);try{const w=await wt(x,S);return e(w),w}catch(w){s(w.message)}finally{d("")}}if(!a)return t.jsx(Ot,{children:u("Checking Higgsfield on this server…")});const y=a.signedIn?2:a.installed?1:0;async function v(){const x=window.open("about:blank","_blank"),S=await p("/api/higgsfield/login",{},"signin");S?.signInUrl&&x?x.location.href=S.signInUrl:x?.close()}return t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"integration-setup-title",children:[t.jsx("span",{className:"integration-mark",style:{"--tool-color":"#141414"},"aria-hidden":"true",children:"H"}),t.jsxs("div",{children:[t.jsx("h3",{children:u("Images and videos, made by your team")}),t.jsx("p",{children:u("Your agents use your Higgsfield account through Higgsfield’s own app on your server. They check the price first, and only generate when you allow it.")})]})]}),t.jsx("div",{className:"integration-steps","aria-label":u("Higgsfield setup"),children:["Install","Sign in","Choose agents"].map((x,S)=>t.jsxs("span",{className:y===S?"current":y>S?"complete":"",children:[t.jsx("b",{children:u(y>S?"✓":S+1)}),u(x)]},x))}),!a.installed&&t.jsxs(t.Fragment,{children:[a.installing?t.jsx(Py,{title:"Installing Higgsfield on this server",steps:["Find the latest version","Download Higgsfield’s app","Check it and unpack it"],current:a.progress<15?0:a.progress<88?1:2,elapsed:a.installFor,progress:a.progress,note:"About 20 MB. Checked against Higgsfield’s published fingerprint before it is used."}):t.jsx(Ot,{error:!!a.installError,children:u(a.installError?`It stopped: ${a.installError}`:"Higgsfield’s app is not on this server yet. It is a free download, about 20 MB, straight from Higgsfield.")}),!a.installing&&t.jsx("div",{className:"pro-actions right",children:t.jsx("button",{className:"primary-btn",disabled:!!l,onClick:()=>p("/api/higgsfield/install",{},"install"),children:t.jsxs(Xn,{busy:l==="install",label:"Starting",children:[t.jsx(jn,{size:16}),u(a.installError?"Try again":"Install Higgsfield")]})})})]}),a.installed&&!a.signedIn&&!a.signInUrl&&a.workspaceChoice?.length>0&&t.jsxs(t.Fragment,{children:[t.jsx(Ot,{children:u("Signed in. Which Higgsfield workspace should your agents use? Its credits pay for what they make.")}),t.jsx("div",{className:"higgsfield-workspaces",children:a.workspaceChoice.map(x=>t.jsx("button",{className:"secondary-btn",disabled:!!l,onClick:()=>p("/api/higgsfield/workspace",{id:x.id},"ws"+x.id),children:t.jsxs(Xn,{busy:l==="ws"+x.id,label:"Choosing",children:[t.jsx("strong",{children:x.name||u("Your own workspace")}),t.jsx("span",{children:u([x.plan&&x.plan[0].toUpperCase()+x.plan.slice(1),x.credits!=null?`${x.credits} credits`:""].filter(Boolean).join(" · "))})]})},x.id))})]}),a.installed&&!a.signedIn&&!a.signInUrl&&!(a.workspaceChoice?.length>0)&&t.jsxs(t.Fragment,{children:[t.jsx(Ot,{error:!!a.signInError,children:u(a.signInError||"Sign in with your Higgsfield account. Higgsfield’s own page opens in a new tab; Laboratorio never sees your password.")}),t.jsx("div",{className:"pro-actions right",children:t.jsx("button",{className:"primary-btn",disabled:!!l,onClick:v,children:t.jsxs(Xn,{busy:l==="signin",label:"Preparing the sign-in",children:[t.jsx(za,{size:16}),u("Sign in to Higgsfield")]})})})]}),a.installed&&!a.signedIn&&a.signInUrl&&t.jsxs(t.Fragment,{children:[t.jsx(Ma,{label:"Waiting for you to approve on Higgsfield’s page",since:null,base:a.signInFor,expect:60,note:`This sign-in stays open for 5 minutes${a.signInFor<300?` (about ${Math.max(1,Math.ceil((300-a.signInFor)/60))} left)`:""}.`}),t.jsxs("ol",{className:"higgsfield-steps",children:[t.jsx("li",{children:u("Approve Laboratorio on Higgsfield’s page (it opened in a new tab).")}),t.jsx("li",{children:u("That tab then tries to open an address starting with http://localhost and shows that it cannot connect. That is expected when Laboratorio runs on a server.")}),t.jsx("li",{children:u("Copy that whole address from the tab’s address bar and paste it here.")})]}),t.jsxs("label",{className:"higgsfield-paste",children:[u("The address the tab ended on"),t.jsx("input",{"aria-label":u("The address the sign-in tab ended on"),value:h,onChange:x=>m(x.target.value),placeholder:"http://localhost:8765/callback?code=…",autoComplete:"off",spellCheck:!1})]}),t.jsxs("div",{className:"pro-actions spread",children:[t.jsxs("button",{className:"text-btn",disabled:!!l,onClick:v,children:[t.jsx(Dd,{size:15}),u("Open the sign-in again")]}),t.jsx("button",{className:"primary-btn",disabled:!h.trim()||!!l,onClick:async()=>{(await p("/api/higgsfield/finish",{url:h.trim()},"finish"))?.signedIn&&(m(""),s("Higgsfield is signed in."))},children:t.jsxs(Xn,{busy:l==="finish",label:"Finishing the sign-in",children:[u("Finish sign-in"),t.jsx(Kn,{size:15})]})})]}),t.jsx("p",{className:"pro-small",children:u("Running Laboratorio on this same computer? Then you do not need to paste anything: this card moves on by itself.")})]}),a.signedIn&&t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"higgsfield-account",children:[t.jsx("span",{className:"panel-kicker",children:u("SIGNED IN TO HIGGSFIELD")}),t.jsx("strong",{children:a.account.email||u("Your Higgsfield account")}),t.jsx("span",{children:u([a.account.plan,a.account.credits!=null?`${a.account.credits} credits left`:""].filter(Boolean).join(" · "))})]}),t.jsx(Ot,{children:u(o?"Your agents have Higgsfield. Change who can use it, and how, in the connection settings.":"Next, choose which agents may use it, and whether they generate only with your approval.")}),t.jsxs("div",{className:"pro-actions spread",children:[t.jsx("button",{className:"text-btn pro-delete-icon",disabled:!!l,onClick:async()=>{const x=await p("/api/higgsfield/logout",{},"logout");x&&!x.signedIn&&s("Signed out of Higgsfield. No agent can use it now.")},children:t.jsxs(Xn,{busy:l==="logout",label:"Signing out",children:[t.jsx(MU,{size:15}),u("Sign out")]})}),!o&&t.jsxs("button",{className:"primary-btn",onClick:n,children:[u("Choose agents"),t.jsx(Kn,{size:15})]})]})]})]})}function zc({tool:a,small:e=!1}){return t.jsx("span",{className:`integration-mark ${e?"small":""}`,style:{"--tool-color":a.color},"aria-hidden":"true",children:u(a.mark)})}function $q({agents:a}){const[e,n]=C.useState([]),[s,o]=C.useState(!1),[l,d]=C.useState({installed:!1,installing:!1,installError:null,installProgress:0,installStage:"",signedIn:!1,signingIn:!1}),[h,m]=C.useState({}),[p,y]=C.useState(""),[v,x]=C.useState(""),[S,M]=C.useState(""),[w,E]=C.useState(!1),[A,k]=C.useState(),[R,N]=C.useState({});function I(U){n(U.connections),U.higgsfield&&k(U.higgsfield),N(U.linked||{}),o(U.composio.keySet),d({...U.composio,installProgress:U.composio.installProgress||0,installStage:U.composio.installStage||""}),m(U.slugs)}async function z(){try{I(await wt("/api/integrations"))}catch(U){le(U.message)}}C.useEffect(()=>{z()},[]);const j=Jq(),L=Zq(j.ts),[D,P]=C.useState(""),[F,q]=C.useState("All tools"),[J,ie]=C.useState("All categories"),[Q,V]=C.useState(null),[$,te]=C.useState(0),[ne,Y]=C.useState("My workspace"),[T,_]=C.useState("Direct"),[ve,je]=C.useState([]),[Je,xe]=C.useState([0]),[ee,Ce]=C.useState(0),[Ze,le]=C.useState(""),[qe,xt]=C.useState(!1),[se,Pe]=C.useState(""),mt=Fi(!!se),it=Fi(l.installing),at=Fi($===3),[Be,We]=C.useState([]),[ue,ft]=C.useState(null),[Re,K]=C.useState([]),[B,pe]=C.useState([0]),[Ae,Ne]=C.useState(!1);function be(U){const ce=e.find(G=>G.toolId===U.id);ft(U),K((ce?.agentIds||[]).filter(G=>Ve.has(G))),pe(ce?.scopeIndexes?.length?ce.scopeIndexes:U.native?[0,1]:[0])}async function ot(){if(ue){Ne(!0);try{I(await wt("/api/integrations/assign",{toolId:ue.id,agentIds:Re,scopeIndexes:B,scopeLabels:B.map(U=>ue.scopes[U]).filter(Boolean)})),le(Re.length?`${ue.name}: ${Re.length} ${Re.length===1?"agent has":"agents have"} it now.`:`${ue.name}: no agent can use it now.`),ft(null)}catch(U){le(U.message)}Ne(!1)}}const Ve=new Set(a.map(U=>U.id)),ut=ve.filter(U=>Ve.has(U)),re=e.find(U=>U.toolId===Q?.id);C.useEffect(()=>{const U=()=>{document.visibilityState==="visible"&&z()};return window.addEventListener("focus",U),document.addEventListener("visibilitychange",U),()=>{window.removeEventListener("focus",U),document.removeEventListener("visibilitychange",U)}},[]),C.useEffect(()=>{if(!(l.installing||l.signingIn||A?.installing||A?.signInUrl||e.some(ce=>ce.method==="Composio"&&!ce.connected&&!ce.error)))return;const U=setInterval(z,l.installing||A?.installing?1500:3e3);return()=>clearInterval(U)},[e,l.installing,l.signingIn,A?.installing,A?.signInUrl]);function Se(U){const ce=e.find(G=>G.toolId===U.id);V(U),Y(ce?.label||"My workspace"),_(U.native?"Higgsfield":U.hub?"Direct":"Composio"),y(ce?.url||""),x(""),je(ce?.agentIds||a.slice(0,1).map(G=>G.id)),xe(ce?.scopeIndexes||(U.native?[0,1]:[0])),te(ce?4:0),Ce(0)}function He(){V(null),te(0),Ce(0)}C.useEffect(()=>{if($!==3||!Q)return;let U=!0;return Ce(1),(async()=>{try{const ce=await wt("/api/integrations/connect",{toolId:Q.id,label:ne.trim(),method:T,agentIds:ut,scopeIndexes:Je,scopeLabels:Je.map(G=>Q.scopes[G]).filter(Boolean),url:p,token:v});if(!U)return;Ce(2),I(ce),ce.redirectUrl?(window.open(ce.redirectUrl,"_blank","noopener"),le(`Finish signing in to ${Q.name} in the tab that just opened. This page updates by itself.`)):le(`${Q.name} is connected and your agents have it.`),Ce(3),te(4)}catch(ce){U&&(le(ce.message),te(2))}})(),()=>{U=!1}},[$,Q]);const lt=(re?.agentIds||[]).filter(U=>Ve.has(U)),tt=Be.length!==lt.length||Be.some(U=>!lt.includes(U));C.useEffect(()=>{$===4&&re&&We((re.agentIds||[]).filter(U=>Ve.has(U)))},[$,Q?.id,re?.updated]);async function ct(){if(Q){Pe(`Updating which agents can use ${Q.name}`);try{I(await wt("/api/integrations/act",{toolId:Q.id,action:"access",agentIds:Be})),le(Be.length?`${Q.name}: ${Be.length} ${Be.length===1?"agent has":"agents have"} access now.`:`${Q.name}: no agent can use it now.`)}catch(U){le(U.message)}Pe("")}}async function fe(){if(!re||!Q)return;const U=re.status==="ready"?"pause":"resume";Pe(U==="pause"?`Pausing ${Q.name}: taking it away from your agents`:`Resuming ${Q.name}: giving it back to your agents`);try{I(await wt("/api/integrations/act",{toolId:Q.id,action:U})),le(`${Q.name} ${U==="pause"?"paused: your agents lost access until you resume it":"resumed"}.`)}catch(ce){le(ce.message)}Pe("")}const oe=e.filter(U=>U.status==="ready"),Fe=new Set(oe.flatMap(U=>U.agentIds).filter(U=>Ve.has(U))).size,Xe=U=>e.some(ce=>ce.toolId===U.id)||!!R[U.id]||!!(U.access&&j.ts?.url)||!!(U.hub&&l.signedIn),dt=Fc.filter(Xe).length,W=Fc.filter(U=>(J==="All categories"||U.category===J)&&(F==="All tools"||F==="Connected"&&Xe(U)||F==="Recommended"&&U.recommended)&&`${U.name} ${U.description} ${U.category}`.toLowerCase().includes(D.toLowerCase()));return t.jsxs("div",{className:"integrations-page",children:[t.jsxs("section",{className:"integration-hero",children:[t.jsxs("div",{children:[t.jsxs("span",{className:"integration-kicker",children:[t.jsx(Vc,{size:14}),u(" CONNECT YOUR WORKSPACE")]}),t.jsxs("h2",{children:[u("Your tools."),t.jsx("br",{}),t.jsx("span",{children:u("Your team’s superpowers.")})]}),t.jsx("p",{children:u("Bring the apps you love into Laboratorio. Give every agent the right tools to move your work forward.")}),t.jsxs("div",{className:"integration-hero-stats",children:[t.jsxs("div",{children:[t.jsx("strong",{children:u(dt.toString().padStart(2,"0"))}),t.jsx("span",{children:u("connected tools")})]}),t.jsxs("div",{children:[t.jsx("strong",{children:u(Fe.toString().padStart(2,"0"))}),t.jsx("span",{children:u("agents with access")})]}),t.jsxs("div",{children:[t.jsx("strong",{children:u(Fc.length)}),t.jsx("span",{children:u("tools to explore")})]})]})]}),t.jsxs("div",{className:"integration-network","aria-hidden":"true",children:[t.jsx("div",{className:"integration-ring"}),t.jsx("div",{className:"integration-ring inner"}),t.jsxs("div",{className:"integration-center",children:[t.jsx(Fs,{size:32}),t.jsx("span",{children:u("LABORATORIO")})]}),u(Kq.map((U,ce)=>{const G=U.id;return t.jsxs("div",{className:`integration-node node-${ce}`,children:[t.jsx(zc,{tool:U,small:!0}),t.jsx("span",{children:U.name})]},G)})),t.jsxs("span",{className:"integration-network-caption",children:[t.jsx("span",{}),u(" A more connected team")]})]})]}),t.jsxs("div",{className:"integration-section-head",children:[t.jsxs("div",{children:[t.jsx("span",{className:"panel-kicker",children:u("THE TOOL LIBRARY")}),t.jsx("h2",{children:u("Works where you work.")})]}),t.jsx(_t,{tone:"green",children:u("Live connections")})]}),t.jsxs("div",{className:"integration-toolbar",children:[t.jsx("div",{className:"filter-tabs",children:["All tools","Connected","Recommended"].map(U=>t.jsxs("button",{"aria-pressed":F===U,className:F===U?"selected":"",onClick:()=>q(U),children:[u(U),t.jsx("span",{children:u(U==="All tools"?Fc.length:U==="Connected"?dt:Fc.filter(ce=>ce.recommended).length)})]},U))}),t.jsxs("div",{className:"integration-search",children:[t.jsx("select",{"aria-label":u("Filter integrations by category"),value:J,onChange:U=>ie(U.target.value),children:["All categories","Access","Creative","Knowledge","Communication","Productivity","Development","Automation","CRM"].map(U=>t.jsx("option",{value:U,children:u(U)},U))}),t.jsxs("label",{className:"search-input",children:[t.jsx(vo,{size:16}),t.jsx("input",{"aria-label":u("Search integrations"),placeholder:u("Find a tool…"),value:D,onChange:U=>P(U.target.value)})]})]})]}),Ze&&t.jsxs(Ot,{children:[u(Ze),t.jsx("button",{className:"text-btn",onClick:()=>le(""),"aria-label":u("Dismiss integration update"),children:u("Dismiss")})]}),t.jsx("div",{className:"integration-grid",children:W.map(U=>{const ce=e.find(ke=>ke.toolId===U.id),G=a.filter(ke=>ce?.agentIds.includes(ke.id));return t.jsxs("article",{className:`integration-card ${ce||U.access&&j.ts?.url||U.hub&&l.signedIn?"is-connected":""}`,children:[t.jsxs("div",{className:"integration-card-top",children:[t.jsx(zc,{tool:U}),t.jsx("button",{className:`integration-add ${ce?"configured":""}`,"aria-label":u(ce||U.access&&L||U.hub&&l.signedIn||U.native&&A?.signedIn?`Manage ${U.name} integration`:`Connect ${U.name}`),title:u(ce||U.access&&L||U.hub&&l.signedIn||U.native&&A?.signedIn?"Manage connection":"Add integration"),onClick:()=>Se(U),children:u(ce||U.access&&L||U.hub&&l.signedIn||U.native&&A?.signedIn?t.jsx(rs,{size:18}):t.jsx(jn,{size:21}))})]}),t.jsxs("div",{className:"integration-name",children:[t.jsx("h3",{children:U.name}),U.hub&&t.jsx("span",{children:u("TOOL LAYER")})]}),U.access&&j.ts?.url?t.jsx("p",{className:"tailnet-card-url",children:t.jsx("a",{href:j.ts.link,target:"_blank",rel:"noopener",children:j.ts.url})}):t.jsx("p",{children:u(U.description)}),t.jsxs("footer",{children:[t.jsx("span",{children:u(U.category)}),U.access?L?t.jsxs("button",{onClick:()=>Se(U),className:`integration-status ${L==="Waiting for sign-in"?"paused":"ready"}`,children:[t.jsx("i",{}),u(L)]}):t.jsxs("button",{className:"integration-connect-link",onClick:()=>Se(U),children:[u("Connect "),t.jsx(Kn,{size:14})]}):!U.hub&&(ce?.connected&&ce.status!=="paused"||!ce&&R[U.id])?t.jsxs("button",{className:"integration-assign",onClick:()=>be(U),children:[t.jsx(hh,{size:14}),u(ce?.agentIds?.filter(ke=>Ve.has(ke)).length?`${ce.agentIds.filter(ke=>Ve.has(ke)).length} ${ce.agentIds.filter(ke=>Ve.has(ke)).length===1?"agent":"agents"} · Assign`:"Assign agents")]}):ce?t.jsxs("button",{onClick:()=>Se(U),className:`integration-status ${ce.status}`,children:[t.jsx("i",{}),u(ce.status==="paused"?"Paused":ce.connected?"Connected":ce.error?"Needs attention":"Waiting for sign-in")]}):U.hub&&l.signedIn?t.jsxs("button",{onClick:()=>Se(U),className:"integration-status ready",children:[t.jsx("i",{}),u("Signed in")]}):t.jsxs("button",{className:"integration-connect-link",onClick:()=>Se(U),children:[u(U.hub&&l.installed?"Sign in ":"Connect "),t.jsx(Kn,{size:14})]})]}),ce&&t.jsxs("div",{className:"integration-card-team",children:[t.jsx("div",{children:u(G.slice(0,3).map(ke=>t.jsx(qt,{agent:ke,small:!0},ke.id)))}),t.jsxs("span",{children:[u(G.length)," ",u(G.length===1?"agent":"agents"),u(" assigned"),u(ce.method==="Composio"?" · via Composio":"")]})]})]},U.id)})}),!W.length&&t.jsxs("div",{className:"panel pro-empty",children:[t.jsx(Vc,{size:34}),t.jsx("h3",{children:u(F==="Connected"&&!dt?"Your first connection starts here.":"No tools match these filters.")}),t.jsx("p",{children:u(F==="Connected"&&!dt?"Browse the library and add a tool to your team.":"Try another search or category.")}),t.jsx("button",{className:"secondary-btn",onClick:()=>{q("All tools"),P(""),ie("All categories")},children:u("Explore all tools")})]}),t.jsxs("div",{className:"integration-foot",children:[t.jsx(za,{size:17}),t.jsx("span",{children:u(s?"Sign-ins happen on Composio's own secure pages. Each agent can only use the tools you assigned to it, and that is enforced, not just asked.":"Set up Composio on the Composio card first, then connect your Google apps.")})]}),t.jsx(on,{title:u(ue?`Who can use ${ue.name}?`:"Assign agents"),description:u("Tick the agents, choose what they may do, then save. Each agent can only use what you tick here."),open:!!ue,onClose:()=>{Ae||ft(null)},wide:!0,children:ue&&t.jsxs("div",{className:"integration-setup integration-assign-window",children:[t.jsxs("div",{className:"integration-access-grid",children:[t.jsxs("section",{children:[t.jsxs("div",{className:"integration-field-heading",children:[t.jsx("strong",{children:u("Your agents")}),t.jsx("button",{className:"text-btn",onClick:()=>K(Re.length===a.length?[]:a.map(U=>U.id)),children:u(Re.length===a.length?"Clear all":"Select all")})]}),t.jsx("div",{className:"integration-agent-list",children:a.map(U=>t.jsxs("label",{className:Re.includes(U.id)?"checked":"",children:[t.jsx("input",{type:"checkbox",checked:Re.includes(U.id),onChange:ce=>K(ce.target.checked?[...Re,U.id]:Re.filter(G=>G!==U.id))}),t.jsx(qt,{agent:U,small:!0}),t.jsxs("span",{children:[U.name,t.jsx("small",{children:u(U.role)})]})]},U.id))})]}),t.jsxs("section",{children:[t.jsxs("div",{className:"integration-field-heading",children:[t.jsx("strong",{children:u("What they may do")}),t.jsx(za,{size:16})]}),ue.scopes.map((U,ce)=>t.jsxs("label",{className:"integration-scope",children:[t.jsx("input",{type:"checkbox",checked:B.includes(ce),onChange:G=>pe(G.target.checked?[...B,ce]:B.filter(ke=>ke!==ce))}),t.jsxs("span",{children:[u(U),t.jsx("small",{children:u(ce===0?"Look things up only.":U.toLowerCase().includes("approval")?"Your yes in the Approval Inbox comes first.":"Allowed on its own.")})]})]},U))]})]}),t.jsx("p",{className:"integration-access-note",children:u(Re.length?`${Re.length} ${Re.length===1?"agent":"agents"} will be able to use ${ue.name}.`:`No agent will be able to use ${ue.name}.`)}),t.jsxs("div",{className:"pro-actions spread",children:[t.jsx("button",{className:"text-btn",onClick:()=>{const U=ue;ft(null),Se(U)},children:u("More settings")}),t.jsxs("div",{className:"pro-actions",children:[t.jsx("button",{className:"secondary-btn",disabled:Ae,onClick:()=>ft(null),children:u("Cancel")}),t.jsx("button",{className:"primary-btn",disabled:Ae||!B.length||!Re.length&&!e.some(U=>U.toolId===ue.id),onClick:ot,children:t.jsxs(Xn,{busy:Ae,label:"Saving",children:[t.jsx(Kt,{size:15}),u("Save")]})})]})]})]})}),t.jsx(on,{title:u(Q?Q.access?"Tailscale":$===5?`Disconnect ${Q.name}?`:$===4?`${Q.name} connection`:`Connect ${Q.name}`:"Connect a tool"),description:Q?.access?"Reach your dashboard from your own devices.":$===5?"Remove this connection from your agents.":$===3?"Setting up your connection.":$===4?"Manage this tool and the agents assigned to it.":"Set up the tool, choose who may use it, then connect.",open:!!Q,onClose:He,wide:!0,children:Q&&t.jsxs("div",{className:"integration-setup",children:[se&&t.jsx(Ma,{label:se,since:mt,expect:20}),Q.access&&t.jsx(Qq,{...j,onDone:He,feedback:le}),Q.native&&$===0&&t.jsx(_q,{hf:A,onChange:U=>{k(U),z()},onChooseAgents:()=>te(1),feedback:le,connected:!!re}),$<3&&!Q.hub&&!Q.access&&!(Q.native&&$===0)&&t.jsx("div",{className:"integration-steps","aria-label":u("Connection setup steps"),children:["Setup","Agent access","Review"].map((U,ce)=>t.jsxs("span",{className:$===ce?"current":$>ce?"complete":"",children:[t.jsx("b",{children:u($>ce?t.jsx(Kt,{size:12}):ce+1)}),u(U)]},U))}),$===0&&Q.hub&&t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"integration-setup-title",children:[t.jsx(zc,{tool:Q}),t.jsxs("div",{children:[t.jsx("h3",{children:u("Composio on your server")}),t.jsx("p",{children:u("Composio signs your agents in to Gmail, Slack, Notion and the other tools here. Install it once, sign in once, then connect each tool from its own card.")})]})]}),t.jsx("div",{className:"integration-steps","aria-label":u("Composio setup"),children:["Install","Sign in","Connect tools"].map((U,ce)=>{const G=ce===0?l.installed:ce===1?l.signedIn:!1,ke=ce===0?!l.installed:ce===1?l.installed&&!l.signedIn:l.signedIn;return t.jsxs("span",{className:ke?"current":G?"complete":"",children:[t.jsx("b",{children:u(G?t.jsx(Kt,{size:12}):ce+1)}),u(U)]},U)})}),!l.installed&&t.jsxs(t.Fragment,{children:[t.jsx(Ot,{error:!!l.installError,children:u(l.installing?`Installing Composio on your server: ${l.installStage||"starting"}, ${Math.round(l.installProgress||0)}%.`:l.installError?`The install stopped: ${l.installError}`:"Composio is not installed on this server yet. It is a free download (about 120 MB).")}),l.installing&&t.jsx(Ma,{label:`Installing Composio: ${l.installStage||"starting"}`,since:it,progress:l.installProgress||0,note:"A 120 MB download. Usually a minute or two."}),t.jsx("div",{className:"pro-actions right",children:t.jsxs("button",{className:"primary-btn",disabled:w||l.installing,onClick:async()=>{E(!0);try{I(await wt("/api/integrations/composio/install",{}))}catch(U){le(U.message)}E(!1)},children:[u(l.installing?t.jsx(Jt,{className:"spin",size:16}):t.jsx(jn,{size:16})),u(l.installing?"Installing…":l.installError?"Try again":"Install Composio")]})})]}),l.installed&&!l.signedIn&&t.jsxs(t.Fragment,{children:[t.jsx(Ot,{children:u(l.signingIn?"Approve the sign-in in the tab that opened. This card updates by itself.":"Sign in with your Composio account (it is free to create one). The sign-in opens in a new tab.")}),t.jsx("div",{className:"pro-actions right",children:t.jsx("button",{className:"primary-btn",disabled:w,onClick:async()=>{E(!0),Pe("Asking Composio for your sign-in link");try{const U=await wt("/api/integrations/composio/login",{});I(U),U.url&&window.open(U.url,"_blank","noopener")}catch(U){le(U.message)}Pe(""),E(!1)},children:u(l.signingIn?"Open the sign-in again":"Sign in to Composio")})})]}),l.signedIn&&t.jsxs(t.Fragment,{children:[t.jsx(Ot,{children:u("Composio is installed and signed in. Choose a tool below, pick which agents may use it, and connect it.")}),t.jsxs("div",{className:"pro-actions right",children:[t.jsx("button",{className:"text-btn",disabled:w,onClick:async()=>{E(!0),Pe("Signing out of Composio and taking its tools away from your agents");try{I(await wt("/api/integrations/key",{key:""})),le("Signed out of Composio. Composio tools were taken away from your agents.")}catch(U){le(U.message)}Pe(""),E(!1)},children:u("Sign out")}),t.jsx("button",{className:"primary-btn",onClick:He,children:u("Done")})]})]})]}),$===0&&!Q.hub&&!Q.access&&!Q.native&&t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"integration-setup-title",children:[t.jsx(zc,{tool:Q}),t.jsxs("div",{children:[t.jsxs("h3",{children:[u("Your "),Q.name,u(" workspace")]}),t.jsx("p",{children:u(Q.description)})]})]}),t.jsxs("label",{children:[u("Connection name"),t.jsx("input",{"aria-label":u("Connection name"),value:ne,onChange:U=>Y(U.target.value),maxLength:80,placeholder:u("e.g. Product team workspace")})]}),t.jsx("span",{className:"integration-field-label",children:u("Connection method")}),t.jsx("div",{className:"integration-methods",children:["Composio"].map(U=>t.jsxs("button",{"aria-pressed":T===U,className:T===U?"selected":"",onClick:()=>_(U),children:[u(U==="Direct"?t.jsx(Vc,{size:20}):t.jsx(Em,{size:20})),t.jsx("strong",{children:u(U==="Direct"?Q.hub?"Composio tool layer":"Direct connection":"Via Composio")}),t.jsx("small",{children:u(U==="Direct"?Q.hub?"Configure a shared tool layer for your team.":"A dedicated connection to this app.":"Route this tool through your integration layer.")}),u(T===U&&t.jsx($a,{size:17}))]},U))}),T==="Direct"&&!Q.hub&&t.jsxs(t.Fragment,{children:[t.jsxs("label",{children:[u("Tool server address (MCP URL)"),t.jsx("input",{"aria-label":u("MCP URL"),value:p,onChange:U=>y(U.target.value),placeholder:"https://…/mcp"})]}),t.jsxs("label",{children:[u("Access token (optional)"),t.jsx("input",{type:"password",autoComplete:"off","aria-label":u("Access token"),value:v,onChange:U=>x(U.target.value)})]})]}),t.jsx(Ot,{children:u(T==="Composio"?s?"You sign in on Composio's own page. Laboratorio never sees your password.":"Install Composio and sign in on the Composio card first.":"Find this address in the tool's own MCP settings, for example Zapier MCP or an n8n MCP trigger.")}),t.jsxs("div",{className:"pro-actions right",children:[t.jsx("button",{className:"secondary-btn",onClick:He,children:u("Cancel")}),t.jsxs("button",{className:"primary-btn",disabled:!ne.trim()||T==="Direct"&&!p.trim()||T==="Composio"&&!s,onClick:()=>te(1),children:[u("Choose agent access "),t.jsx(Kn,{size:15})]})]})]}),$===1&&t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"integration-access-head",children:[t.jsx("h3",{children:u("Give the right agents access.")}),t.jsxs("p",{children:[u("Choose who can use "),Q.name,u(" and what they can do.")]})]}),t.jsxs("div",{className:"integration-access-grid",children:[t.jsxs("section",{children:[t.jsxs("div",{className:"integration-field-heading",children:[t.jsx("strong",{children:u("Your agents")}),t.jsx("button",{className:"text-btn",onClick:()=>je(ut.length===a.length?[]:a.map(U=>U.id)),children:u(ut.length===a.length?"Clear all":"Select all")})]}),t.jsx("div",{className:"integration-agent-list",children:a.map(U=>t.jsxs("label",{className:ve.includes(U.id)?"checked":"",children:[t.jsx("input",{type:"checkbox",checked:ve.includes(U.id),onChange:ce=>je(ce.target.checked?[...ve,U.id]:ve.filter(G=>G!==U.id))}),t.jsx(qt,{agent:U,small:!0}),t.jsxs("span",{children:[U.name,t.jsx("small",{children:u(U.role)})]})]},U.id))})]}),t.jsxs("section",{children:[t.jsxs("div",{className:"integration-field-heading",children:[t.jsx("strong",{children:u("Tool access")}),t.jsx(za,{size:16})]}),Q.scopes.map((U,ce)=>t.jsxs("label",{className:"integration-scope",children:[t.jsx("input",{type:"checkbox",checked:Je.includes(ce),onChange:G=>xe(G.target.checked?[...Je,ce]:Je.filter(ke=>ke!==ce))}),t.jsxs("span",{children:[u(U),t.jsx("small",{children:u(ce===0?"Read context for the assigned agents.":U.includes("approval")?"Require owner approval before this action.":"Enable this action for assigned agents.")})]})]},U)),t.jsx("p",{className:"integration-permission-note",children:u("This is your intended access configuration. The final permissions will be confirmed during account authorization.")})]})]}),t.jsxs("div",{className:"pro-actions spread",children:[t.jsxs("button",{className:"secondary-btn",onClick:()=>te(0),children:[t.jsx(eu,{size:15}),u("Back")]}),t.jsxs("button",{className:"primary-btn",disabled:!ut.length||!Je.length,onClick:()=>te(2),children:[u("Review setup "),t.jsx(Kn,{size:15})]})]})]}),$===2&&t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"integration-review-heading",children:[t.jsx(zc,{tool:Q}),t.jsx("h3",{children:u("Ready to bring it together.")}),t.jsx("p",{children:u("Review it, then connect.")})]}),t.jsxs("dl",{className:"integration-review",children:[t.jsxs("div",{children:[t.jsx("dt",{children:u("Tool")}),t.jsx("dd",{children:Q.name})]}),t.jsxs("div",{children:[t.jsx("dt",{children:u("Workspace")}),t.jsx("dd",{children:u(ne)})]}),t.jsxs("div",{children:[t.jsx("dt",{children:u("Connection")}),t.jsxs("dd",{children:[u(T),u(Q.hub?" tool layer":"")]})]}),t.jsxs("div",{children:[t.jsx("dt",{children:u("Agent access")}),t.jsx("dd",{children:u(a.filter(U=>ut.includes(U.id)).map(U=>U.name).join(", "))})]}),t.jsxs("div",{children:[t.jsx("dt",{children:u("Permissions")}),t.jsx("dd",{children:Je.map(U=>t.jsxs("span",{children:[t.jsx(Kt,{size:13}),u(Q.scopes[U])]},U))})]})]}),t.jsxs("div",{className:"integration-build-note",children:[t.jsx(Ha,{size:18}),t.jsx("p",{children:u(T==="Higgsfield"?"The chosen agents get Higgsfield with these rules. Generating spends your credits, so keep it with your approval unless you are sure.":"The chosen agents get this tool with these rules. You can change who has it at any time from its card.")})]}),t.jsxs("div",{className:"pro-actions spread",children:[t.jsxs("button",{className:"secondary-btn",onClick:()=>te(1),children:[t.jsx(eu,{size:15}),u("Back")]}),t.jsxs("button",{className:"primary-btn",onClick:()=>{Ce(0),te(3)},children:[t.jsx(Vc,{size:16}),u("Build connection")]})]})]}),$===3&&t.jsxs("div",{className:"integration-building",role:"status","aria-live":"polite",children:[t.jsx(zc,{tool:Q}),t.jsxs("h3",{children:[u("Bringing "),Q.name,u(" to your team.")]}),t.jsx("p",{children:u("Setting up the connection")}),t.jsx("div",{children:["Prepare authorization","Configure tool access","Provision selected agents"].map((U,ce)=>t.jsxs("span",{className:ee>ce?"done":"",children:[u(ee>ce?t.jsx($a,{size:19}):ee===ce?t.jsx(Jt,{className:"spin",size:19}):t.jsx("span",{className:"integration-pending"})),u(U)]},U))}),t.jsx("div",{className:"pro-progress",children:t.jsx("i",{style:{width:`${Math.max(ee/3*100,xh(vh(at),40))}%`}})}),t.jsx(vi,{since:at}),t.jsx("small",{children:u(T==="Composio"?"Composio opens its secure sign-in in a new tab":T==="Higgsfield"?"Giving the chosen agents Higgsfield, with your rules":"Adding the tool server to your agents")})]}),$===4&&re&&t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"integration-ready",children:[t.jsx("span",{className:"integration-ready-symbol",children:t.jsx($a,{size:30})}),t.jsxs("div",{children:[t.jsx("h3",{children:u(re.status==="paused"?"Connection paused":re.connected?"Connected":re.error?"Needs attention":"Waiting for sign-in")}),t.jsxs("p",{children:[Q.name,u(" · "),u(re.label)]})]}),t.jsx(_t,{tone:re.status==="paused"||!re.connected?"amber":"green",children:u(re.status==="paused"?"Paused":re.connected?"Connected":re.error?"Needs attention":"Waiting for sign-in")})]}),t.jsxs("div",{className:"integration-connected-details",children:[t.jsxs("div",{children:[t.jsxs("div",{className:"integration-field-heading",children:[t.jsx("span",{className:"panel-kicker",children:u("WHO CAN USE IT")}),t.jsx("button",{className:"text-btn",onClick:()=>We(Be.length===a.length?[]:a.map(U=>U.id)),children:u(Be.length===a.length?"Clear all":"Select all")})]}),t.jsx("div",{className:"integration-agent-list",children:a.map(U=>t.jsxs("label",{className:Be.includes(U.id)?"checked":"",children:[t.jsx("input",{type:"checkbox",checked:Be.includes(U.id),onChange:ce=>We(ce.target.checked?[...Be,U.id]:Be.filter(G=>G!==U.id))}),t.jsx(qt,{agent:U,small:!0}),t.jsxs("span",{children:[U.name,t.jsx("small",{children:u(U.role)})]})]},U.id))}),t.jsx("p",{className:"integration-access-note",children:u(Be.length?`${Be.length} ${Be.length===1?"agent":"agents"} can use ${Q.name}.`:`No agent can use ${Q.name} until you tick one.`)}),t.jsx("div",{className:"pro-actions right",children:t.jsx("button",{className:"primary-btn",disabled:!tt||!!se,onClick:ct,children:t.jsxs(Xn,{busy:!!se&&se.startsWith("Updating"),label:"Saving",children:[t.jsx(Kt,{size:15}),u("Save access")]})})})]}),t.jsxs("div",{children:[t.jsx("span",{className:"panel-kicker",children:u("TOOL ACCESS")}),re.scopeIndexes.map(U=>t.jsxs("p",{children:[t.jsx(Kt,{size:14}),u(Q.scopes[U])]},U))]})]}),t.jsxs("div",{className:"integration-management",children:[t.jsxs("button",{className:"secondary-btn",onClick:()=>te(0),children:[t.jsx(rs,{size:15}),u("Edit setup")]}),t.jsxs("button",{className:"secondary-btn",onClick:fe,children:[u(re.status==="ready"?t.jsx(nu,{size:15}):t.jsx(gi,{size:15}))," ",u(re.status==="ready"?"Pause":"Resume")]}),t.jsxs("button",{className:"text-btn pro-delete-icon",onClick:()=>te(5),children:[t.jsx(I2,{size:15}),u("Disconnect")]})]}),t.jsx(Ot,{children:u(re.error||(re.connected?"The assigned agents can use this tool now. Ask one of them to try it in Chat.":"Finish the sign-in in the tab Composio opened; this updates by itself."))}),t.jsx("div",{className:"pro-actions right",children:t.jsx("button",{className:"primary-btn",onClick:He,children:u("Done")})})]}),$===5&&t.jsxs(t.Fragment,{children:[t.jsxs("p",{className:"pro-small",children:[u("Remove this connection and every agent's access to it? You can add "),Q.name,u(" again from the library.")]}),t.jsxs("div",{className:"pro-actions right",children:[t.jsx("button",{className:"secondary-btn",onClick:()=>te(4),children:u("Keep connection")}),t.jsx("button",{className:"pro-danger",disabled:!!se,onClick:async()=>{Pe(`Disconnecting ${Q.name} from your agents`);try{I(await wt("/api/integrations/act",{toolId:Q.id,action:"disconnect"})),le(`${Q.name} disconnected. No agent can use it now.`)}catch(U){le(U.message)}Pe(""),He()},children:t.jsx(Xn,{busy:!!se,label:"Disconnecting",children:u("Disconnect")})})]})]})]})})]})}const is=[],yN=["Rate limit","Provider unavailable","Response timeout"],eW={fallback:"",fallbackEnabled:!1,conditions:[...yN],timeout:120,retries:1,skills:{}};let du={},bN={};const Nb=["","minimal","low","medium","high","xhigh"];let SN={enabled:!1,keySet:!1,light:{},strong:{}};const bm=new Set;function yh(a){is.splice(0,is.length,...a.catalog),du={...a.options},SN=a.jev,bN={...a.agents||{}},a.efforts?.length&&Nb.splice(0,Nb.length,...a.efforts);for(const e of Object.keys(Wp))delete Wp[e];Object.assign(Wp,a.notes||{}),bm.forEach(e=>e())}const tW=a=>bN[a]?.effort||"",Wp={};async function nW(a){const e=await wt("/api/models/all",a);return yh(e),e.message||"Saved for every agent."}async function AN(a=!1){try{yh(await wt(a?"/api/models/refresh":"/api/models",a?{}:void 0))}catch{}}typeof window<"u"&&AN();const Yp=a=>is.find(e=>e.name===a)?.provider||"";function hu(a,e=""){const n=du[a];return{...eW,...n,skills:n?.skills||{}}}async function aW(a,e){yh(await wt("/api/models/agent",{id:a,...e}))}function DC(a,e){du={...du,[a]:{...hu(a),...e}},bm.forEach(n=>n()),e.skills&&wt("/api/models/skills",{id:a,skills:e.skills,names:Object.fromEntries(Ls.map(n=>[n.id,n.name]))}).then(yh).catch(()=>AN())}const EN=()=>SN;async function rh(a){yh(await wt("/api/models/jev",a))}function Au(){return C.useSyncExternalStore(a=>(bm.add(a),()=>bm.delete(a)),()=>du,()=>du)}function iW(a,e,n){return e.fallbackEnabled&&e.conditions.includes(n)&&e.fallback&&e.fallback!==a?e.fallback:a}const Ls=[{id:"web-research",name:"Web research",category:"Research",description:"Find sources and prepare a structured research summary.",icon:"Globe",approval:!1},{id:"deep-analysis",name:"Deep analysis",category:"Research",description:"Compare evidence, identify gaps, and explain conclusions.",icon:"ScanSearch",approval:!1},{id:"writing",name:"Content drafting",category:"Content",description:"Turn a brief into clear content for your audience.",icon:"PenLine",approval:!1},{id:"code-review",name:"Code review",category:"Development",description:"Review code and suggest actionable improvements.",icon:"Code2",approval:!1},{id:"spreadsheets",name:"Spreadsheet analysis",category:"Analysis",description:"Explore tables and prepare useful summaries and charts.",icon:"ChartNoAxesCombined",approval:!1},{id:"pdf",name:"PDF reading",category:"Documents",description:"Extract key points and questions from attached documents.",icon:"FileText",approval:!1},{id:"images",name:"Image understanding",category:"Analysis",description:"Review screenshots, visual references, and diagrams.",icon:"Image",approval:!1},{id:"email",name:"Email drafting",category:"Communication",description:"Prepare concise email drafts for your review.",icon:"Mail",approval:!0},{id:"translation",name:"Translation",category:"Content",description:"Translate content while preserving meaning and tone.",icon:"Languages",approval:!1},{id:"social",name:"Social content",category:"Content",description:"Adapt your message into posts for different channels.",icon:"Megaphone",approval:!0},{id:"meetings",name:"Meeting notes",category:"Documents",description:"Turn transcripts into decisions and action items.",icon:"NotebookPen",approval:!1},{id:"automation",name:"Workflow automation",category:"Automation",description:"Plan repeatable steps across connected tools.",icon:"Workflow",approval:!0}],sW={Globe:Qb,ScanSearch:UU,PenLine:Mr,Code2:VT,ChartNoAxesCombined:rU,FileText:Si,Image:hj,Mail:ei,Languages:xU,Megaphone:TU,NotebookPen:zU,Workflow:Fs};function rW({agents:a,initialAgent:e="",onModel:n}){Au();const[s,o]=C.useState(e||a[0]?.id||""),[l,d]=C.useState("All skills"),[h,m]=C.useState(""),[p,y]=C.useState(""),[v,x]=C.useState({enabled:!1,instructions:"",approval:!1}),[S,M]=C.useState("");C.useEffect(()=>{e&&a.some(j=>j.id===e)&&o(e)},[e]),C.useEffect(()=>{a.some(j=>j.id===s)||o(a[0]?.id||"")},[a.map(j=>j.id).join("|")]);const w=a.find(j=>j.id===s),E=hu(s),A=Ls.find(j=>j.id===p),k=Ls.filter(j=>E.skills[j.id]?.enabled).length,R=j=>E.skills[j]||{enabled:!1,instructions:"",approval:Ls.find(L=>L.id===j)?.approval||!1};function N(j){const L=R(j);DC(s,{skills:{...E.skills,[j]:{...L,enabled:!L.enabled}}}),M(L.enabled?"Skill disabled for this agent.":"Skill enabled for this agent.")}function I(j){y(j),x({...R(j)})}const z=Ls.filter(j=>(l==="All skills"||E.skills[j.id]?.enabled)&&`${u(j.name)} ${u(j.category)} ${u(j.description)} ${j.name}`.toLowerCase().includes(h.toLowerCase()));return t.jsxs("div",{className:"skills-page",children:[t.jsxs("section",{className:"skills-hero",children:[t.jsxs("div",{children:[t.jsxs("span",{className:"capability-kicker",children:[t.jsx(Ha,{size:15}),u("SHAPE THEIR EXPERTISE")]}),t.jsxs("h2",{children:[u("A sharper skill set."),t.jsx("br",{}),u("A more capable team.")]}),t.jsx("p",{children:u("Choose what each agent can do. Add your instructions and keep the working style consistent.")})]}),t.jsxs("div",{className:"skills-hero-badge",children:[t.jsx(Ha,{size:31}),t.jsx("strong",{children:u(Ls.length)}),t.jsx("span",{children:u("skills to explore")})]})]}),t.jsxs("div",{className:"skills-agent-bar",children:[t.jsxs("div",{children:[u(w&&t.jsx(qt,{agent:w})),t.jsxs("label",{children:[u("Manage skills for"),t.jsx("select",{"aria-label":u("Select agent for skills"),value:s,onChange:j=>{o(j.target.value),M("")},children:u(a.map(j=>t.jsx("option",{value:j.id,children:j.name},j.id)))})]})]}),t.jsxs("div",{children:[t.jsxs(_t,{tone:"green",children:[u(k),u(" enabled")]}),u(w&&t.jsxs("button",{className:"secondary-btn",onClick:()=>n(s),children:[t.jsx(dh,{size:16}),w.model]}))]})]}),t.jsxs("div",{className:"integration-toolbar",children:[t.jsx("div",{className:"filter-tabs",children:["All skills","Enabled"].map(j=>t.jsxs("button",{"aria-pressed":l===j,className:l===j?"selected":"",onClick:()=>d(j),children:[u(j),t.jsx("span",{children:u(j==="All skills"?Ls.length:k)})]},j))}),t.jsxs("label",{className:"search-input",children:[t.jsx(vo,{size:16}),t.jsx("input",{"aria-label":u("Search skills"),placeholder:u("Find a skill…"),value:h,onChange:j=>m(j.target.value)})]})]}),S&&t.jsx(Ot,{children:u(S)}),t.jsx("div",{className:"skills-grid",children:z.map(j=>{const L=sW[j.icon],D=R(j.id);return t.jsxs("article",{className:`skill-card ${D.enabled?"enabled":""}`,children:[t.jsxs("div",{className:"skill-card-top",children:[t.jsx("span",{className:"skill-symbol",children:t.jsx(L,{size:23})}),t.jsx("button",{className:"pref-switch",role:"switch","aria-label":u(`Enable ${j.name} for ${w?.name||"agent"}`),"aria-checked":D.enabled,disabled:!w,onClick:()=>N(j.id),children:t.jsx("i",{})})]}),t.jsx("span",{className:"panel-kicker",children:u(j.category)}),t.jsx("h3",{children:u(j.name)}),t.jsx("p",{children:u(j.description)}),t.jsxs("footer",{children:[t.jsx("span",{className:D.enabled?"is-enabled":"",children:u(D.enabled?"Enabled":"Disabled")}),t.jsxs("button",{className:"text-btn",disabled:!w,onClick:()=>I(j.id),children:[t.jsx(rs,{size:14}),u("Configure")]})]}),D.instructions&&t.jsx("small",{children:u("Custom instructions added")})]},j.id)})}),!z.length&&t.jsxs("div",{className:"panel pro-empty",children:[t.jsx(Ha,{size:30}),t.jsx("h3",{children:u(l==="Enabled"?"No skills enabled yet.":"No matching skills.")}),t.jsx("p",{children:u("Choose a skill from the library to get started.")}),t.jsx("button",{className:"secondary-btn",onClick:()=>{d("All skills"),m("")},children:u("Explore all skills")})]}),t.jsx("p",{className:"capability-note",children:u("Enabled skills and your instructions are written into this agent's identity file, so it follows them in every conversation. Skills marked for review always show you a draft first.")}),t.jsx(on,{title:u(A?`Configure ${A.name}`:"Configure skill"),description:"Set the instructions and review preferences for this agent.",open:!!A,onClose:()=>y(""),children:A&&t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"capability-agent",children:[u(w&&t.jsx(qt,{agent:w,small:!0})),t.jsx("span",{children:w?.name}),t.jsx(_t,{tone:v.enabled?"green":"neutral",children:u(v.enabled?"Enabled":"Disabled")})]}),t.jsxs("label",{className:"pref-toggle-row",children:[t.jsxs("span",{children:[t.jsx("strong",{children:u("Enable this skill")}),t.jsx("small",{children:u("Make this capability available to the selected agent.")})]}),t.jsx("button",{type:"button",className:"pref-switch",role:"switch","aria-label":u("Enable this skill"),"aria-checked":v.enabled,onClick:()=>x(j=>({...j,enabled:!j.enabled})),children:t.jsx("i",{})})]}),t.jsxs("label",{children:[u("Custom instructions"),t.jsx("textarea",{"aria-label":u("Skill instructions"),rows:5,maxLength:2e3,placeholder:u("How should this agent use the skill?"),value:v.instructions,onChange:j=>x(L=>({...L,instructions:j.target.value}))})]}),t.jsxs("label",{className:"pref-toggle-row",children:[t.jsxs("span",{children:[t.jsx("strong",{children:u("Owner review")}),t.jsx("small",{children:u("Require your approval before using the result in an external action.")})]}),t.jsx("button",{type:"button",className:"pref-switch",role:"switch","aria-label":u("Require owner review for skill"),"aria-checked":v.approval,onClick:()=>x(j=>({...j,approval:!j.approval})),children:t.jsx("i",{})})]}),t.jsxs("div",{className:"pro-actions right",children:[t.jsx("button",{className:"secondary-btn",onClick:()=>y(""),children:u("Cancel")}),t.jsxs("button",{className:"primary-btn",onClick:()=>{DC(s,{skills:{...E.skills,[A.id]:v}}),y(""),M("Skill configuration saved.")},children:[t.jsx(Kt,{size:16}),u("Save skill")]})]})]})})]})}function oW({agent:a,data:e,onSave:n,onClose:s}){Au();const[o,l]=C.useState(""),[d,h]=C.useState(hu("")),[m,p]=C.useState(!1),[y,v]=C.useState(""),[x,S]=C.useState(""),[M,w]=C.useState(""),[E,A]=C.useState(!1);C.useEffect(()=>{a&&(l(a.model),h(hu(a.id,a.model)),w(tW(a.id)),A(!1),v(""),S(""))},[a?.id]);function k(z){l(z),z===d.fallback&&h(j=>({...j,fallback:is.find(L=>L.name!==z)?.name||""})),v("")}async function R(){if(!(!a||m)){p(!0),S("");try{E?S(await nW({primary:o,primaryProvider:Yp(o),effort:M})):(await aW(a.id,{primary:o,primaryProvider:Yp(o),effort:M,fallback:d.fallback,fallbackProvider:Yp(d.fallback),fallbackEnabled:d.fallbackEnabled,conditions:d.conditions,timeout:d.timeout,retries:d.retries}),S(`Saved. ${a.name} now thinks with ${o}${M?` at ${M} effort`:""}.`))}catch(z){S(z.message)}finally{p(!1)}}}const N=o&&(!d.fallbackEnabled||d.fallback!==o&&d.conditions.length>0),I=[...is];return o&&!I.some(z=>z.name===o)&&I.unshift({name:o,provider:"Current model"}),t.jsx(on,{title:u("AI model & fallback"),description:"Choose the model for this agent and a backup route when it needs one.",open:!!a,onClose:s,wide:!0,children:a&&t.jsxs("div",{className:"model-settings",children:[t.jsxs("div",{className:"capability-agent",children:[t.jsx(qt,{agent:a}),t.jsxs("div",{children:[t.jsx("h3",{children:a.name}),t.jsx("p",{children:u(a.role)})]}),t.jsx(_t,{tone:"green",children:u("Live routing")})]}),t.jsxs("div",{className:"model-route-grid",children:[t.jsxs("section",{children:[t.jsxs("span",{className:"capability-kicker",children:[t.jsx(dh,{size:15}),u("PRIMARY MODEL")]}),t.jsx("h3",{children:u("The everyday choice")}),t.jsxs("label",{children:[u("Primary AI model"),t.jsx("select",{"aria-label":u("Primary AI model"),value:o,onChange:z=>k(z.target.value),children:[...new Set(I.map(z=>z.provider))].map(z=>t.jsx("optgroup",{label:u(z),children:u(I.filter(j=>j.provider===z).map(j=>t.jsx("option",{value:j.name,children:j.name},z+j.name)))},z))})]}),Object.values(Wp).map(z=>t.jsx("p",{className:"model-note",children:u(z)},z)),t.jsxs("label",{children:[u("Effort"),t.jsx("select",{"aria-label":u("Effort"),value:M,onChange:z=>w(z.target.value),children:Nb.map(z=>t.jsx("option",{value:z,children:u(z?z[0].toUpperCase()+z.slice(1):"Model default")},z||"default"))})]}),t.jsx("p",{children:u("Used for this agent’s normal conversations and work. More effort thinks longer: better on hard work, slower and costlier.")}),t.jsxs("label",{className:"model-for-all",children:[t.jsx("input",{type:"checkbox",checked:E,onChange:z=>A(z.target.checked)})," ",u("Use this model and effort for every agent")]})]}),t.jsx("span",{className:"model-route-arrow",children:t.jsx(Kn,{size:23})}),t.jsxs("section",{className:d.fallbackEnabled?"":"is-disabled",children:[t.jsxs("span",{className:"capability-kicker",children:[t.jsx(za,{size:15}),u("FALLBACK MODEL")]}),t.jsxs("div",{className:"model-fallback-title",children:[t.jsx("h3",{children:u("A second route")}),t.jsx("button",{className:"pref-switch",role:"switch","aria-label":u("Enable fallback model"),"aria-checked":d.fallbackEnabled,onClick:()=>{h(z=>({...z,fallbackEnabled:!z.fallbackEnabled})),v("")},children:t.jsx("i",{})})]}),t.jsxs("label",{children:[u("Fallback AI model"),t.jsxs("select",{"aria-label":u("Fallback AI model"),disabled:!d.fallbackEnabled,value:d.fallback,onChange:z=>{h(j=>({...j,fallback:z.target.value})),v("")},children:[!d.fallback&&t.jsx("option",{value:"",children:u("Choose a model")}),is.filter(z=>z.name!==o).map(z=>t.jsxs("option",{value:z.name,children:[z.name,u(" · "),u(z.provider)]},z.provider+z.name))]})]}),t.jsx("p",{children:u("Used only when an enabled fallback condition occurs.")})]})]}),t.jsxs("div",{className:"model-conditions",children:[t.jsx("h3",{children:u("When should the fallback take over?")}),t.jsx("div",{children:yN.map(z=>t.jsxs("label",{children:[t.jsx("input",{type:"checkbox",disabled:!d.fallbackEnabled,checked:d.conditions.includes(z),onChange:j=>{h(L=>({...L,conditions:j.target.checked?[...L.conditions,z]:L.conditions.filter(D=>D!==z)})),v("")}}),t.jsx("span",{children:u(z)})]},z))})]}),t.jsxs("div",{className:"pro-form-grid model-limits",children:[t.jsxs("label",{children:[u("Response timeout"),t.jsx("select",{value:d.timeout,onChange:z=>h(j=>({...j,timeout:Number(z.target.value)})),children:[30,60,120].map(z=>t.jsxs("option",{value:z,children:[u(z),u(" seconds")]},z))})]}),t.jsxs("label",{children:[u("Retries before fallback"),t.jsx("select",{value:d.retries,onChange:z=>h(j=>({...j,retries:Number(z.target.value)})),children:[0,1,2,3].map(z=>t.jsx("option",{value:z,children:u(z)},z))})]})]}),t.jsxs("div",{className:"model-test",children:[t.jsxs("div",{children:[t.jsx(hU,{size:20}),t.jsxs("span",{children:[t.jsx("strong",{children:u("Preview a provider interruption")}),t.jsx("small",{children:u("See which model these rules would select.")})]})]}),t.jsx("button",{className:"secondary-btn",disabled:!N,onClick:()=>{const z=d.conditions[0]||"Provider unavailable";v(iW(o,d,z))},children:u("Preview routing")})]}),y&&t.jsx(Ot,{children:t.jsxs("span",{children:[u("Selected route: "),t.jsx("strong",{children:u(y)})]})}),x&&t.jsx(Ot,{children:u(x)}),t.jsx("p",{className:"capability-note",children:u("Saved in this agent's own Hermes settings. Hermes moves to the fallback on rate limits and outages; Laboratorio also moves to it after a timeout on the turns it starts.")}),t.jsxs("div",{className:"pro-actions right",children:[t.jsx("button",{className:"secondary-btn",onClick:s,children:u("Close")}),t.jsx("button",{className:"primary-btn",disabled:!N||m,onClick:R,children:t.jsxs(Xn,{busy:m,label:"Saving the model settings",children:[t.jsx(Kt,{size:16}),u("Save model settings")]})})]})]})})}const lW=["Mission plan","Mission result","Email draft","Social post","Calendar change","Generation","Automation result","Tool sign-in"],cW=["New email","Email from a sender","Slack message","Slack mention","New calendar event","New GitHub issue","New form submission","File in a folder","Web page changes","On a schedule"],uW=["Approval Inbox","Docs","Telegram","To-do","Mission"],Lc=["Agents & memories","Documents","Missions","Schedules","Automations","Settings"];function wN(a,e=new Date,n="UTC"){if(!a.quiet)return!1;const s=new Intl.DateTimeFormat("en-GB",{timeZone:n,hour:"2-digit",minute:"2-digit",hourCycle:"h23"}).format(e),o=m=>Number(m.slice(0,2))*60+Number(m.slice(3,5)),l=o(s),d=o(a.start),h=o(a.end);return d===h||(d=d&&l=d||ln.name.trim().toLocaleLowerCase()===e.trim().toLocaleLowerCase())}function Db(){return crypto.randomUUID()}let ca={approvals:[],decisions:[],edits:{},rules:[],runs:[],notifications:{browser:!1,phone:!1,telegram:!1,telegramChat:"",quiet:!0,start:"22:00",end:"08:00"},backups:[],backupAuto:!1,backupFrequency:"Daily",backupKeep:7,installedTemplates:[],templateJob:{running:!1},pushKey:null,telegramReady:!1};const zb=new Set,Xd=()=>zb.forEach(a=>a());function LC(){return ca}async function oh(){try{ca={...await wt("/api/owner"),error:ca.error},Xd()}catch{}}let OC=0;typeof window<"u"&&(oh(),setInterval(()=>{if(document.hidden)return;OC++,(ca.templateJob?.running||ca.rules.some(e=>e.testing)||ca.decisions.some(e=>e.outcome==="Carrying it out now.")||OC%5===0)&&oh()},2e3));let Ap=null;function wa(a){const e=ca,n=structuredClone(ca);a(n),ca={...n,error:void 0},Xd(),Ap&&clearTimeout(Ap),Ap=setTimeout(async()=>{Ap=null;try{ca=await wt("/api/owner",{notifications:{...ca.notifications,timezone:Da().timezone},edits:ca.edits,rules:ca.rules,backupAuto:ca.backupAuto,backupFrequency:ca.backupFrequency,backupKeep:ca.backupKeep},"PUT"),Xd()}catch(s){ca={...e,error:s.message},Xd(),oh()}},350)}function Nl(){return C.useSyncExternalStore(a=>(zb.add(a),()=>zb.delete(a)),LC,LC)}async function $c(a,e){const n=await wt(a,e);return n&&typeof n=="object"&&"approvals"in n&&(ca={...n,error:void 0},Xd()),n}function bh(){const a=ky();return[...a.missions.filter(n=>["Awaiting approval","In review"].includes(n.status)).map(n=>({id:`${n.id}:${n.status==="In review"?"result":"plan"}`,agentId:n.status==="In review"&&n.steps.at(-1)?.agentId||n.team[0],kind:n.status==="In review"?"Mission result":"Mission plan",title:n.name,sourceId:n.id,arrived:n.timeline.at(-1)?.time||n.created,body:n.status==="In review"?a.docs.find(s=>s.missionId===n.id)?.body||n.steps.map(s=>s.result).join(` `):`Goal: ${n.goal} ${n.steps.map((s,o)=>`${o+1}. ${s.title}`).join(` `)} Time limit: ${n.timeLimit} minutes Owner review: ${n.needsReview?"Required":"Not required"}`})),...ca.approvals].map(n=>({...n,body:ca.edits[n.id]??n.body})).sort((n,s)=>s.arrived.localeCompare(n.arrived))}const dW=a=>{const e=atob((a+"=".repeat((4-a.length%4)%4)).replace(/-/g,"+").replace(/_/g,"/"));return Uint8Array.from(e,n=>n.charCodeAt(0))};async function MN(a,e){if(!("serviceWorker"in navigator)||!("PushManager"in window)||!("Notification"in window))throw new Error(a==="phone"?"This browser cannot show notifications yet. On a phone, add Laboratorio to the home screen first and open it from there.":"This browser cannot show notifications.");if(!e)throw new Error("The server could not make a notification key. Check its log.");if(await Notification.requestPermission()!=="granted")throw new Error("Notifications are blocked for this site. Allow them in the browser settings, then try again.");const n=await navigator.serviceWorker.register("/sw.js");await navigator.serviceWorker.ready;const s=await n.pushManager.getSubscription()||await n.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:dW(e)});await wt("/api/owner/push",{subscription:s.toJSON(),kind:a})}const hW=a=>{const e=a.size;return e>1024*1024?`${(e/1024/1024).toFixed(2)} MB`:`${Math.ceil(e/1024)} KB`};function fW({onRestored:a}){const e=Nl(),[n,s]=C.useState(""),[o,l]=C.useState(!1),[d,h]=C.useState(null),[m,p]=C.useState([...Lc]),[y,v]=C.useState([]),[x,S]=C.useState(!0),[M,w]=C.useState(!1),[E,A]=C.useState(""),[k,R]=C.useState(""),[N,I]=C.useState(""),[z,j]=C.useState(!1),[L,D]=C.useState(""),[P,F]=C.useState(null),q=C.useRef(null),J=Fi(z);async function ie(){D("create"),j(!0),I("");try{await $c("/api/backups/create",{name:n}),l(!1),s(""),R("Backup saved on the server with the current team, memories, and work.")}catch(T){I(T.message)}finally{j(!1)}}function Q(T){h(T),p([...Lc]),v(T.agents.map(_=>_.id)),S(!0),w(!1),A(""),I("")}const V=Tl();C.useEffect(()=>{if(V.view==="Settings"&&V.section==="backups"){if(V.id){const T=e.backups.find(_=>_.id===V.id);T&&Q(T)}requestAnimationFrame(()=>document.getElementById("team-backup")?.scrollIntoView({block:"start"}))}},[V.stamp]);async function $(T){I(""),R("");try{if(T.size>300*1024*1024)throw new Error("Backup files must be smaller than 300 MB.");D("upload"),j(!0);const _=await na("/api/backups/upload",{method:"POST",headers:{"Content-Type":"application/gzip"},body:T}),ve=await _.json();if(!_.ok)throw new Error(ve.error||"The upload failed.");await oh(),R("Backup uploaded. Review its contents before restoring.");const je=ve.backups.find(Je=>Je.id===ve.uploaded);je&&Q(je)}catch(_){I(_.message)}finally{j(!1)}q.current&&(q.current.value="")}async function te(){if(!(!d||E!=="RESTORE"||!Y.length)){D("restore"),j(!0),I("");try{const T=await $c("/api/backups/restore",{id:d.id,parts:Y,agentIds:y,everything:x,confirm:E});await a(),h(null),w(!1),R(T.message||"Restore complete.")}catch(T){I(T.message)}finally{j(!1)}}}const ne=d?d.agents:[],Y=x?[...Lc]:m;return t.jsxs("section",{className:"ow-backups",id:"team-backup",children:[t.jsxs("div",{className:"ow-section-title",children:[t.jsxs("div",{children:[t.jsx("span",{className:"panel-kicker",children:u("KEEP YOUR TEAM CLOSE")}),t.jsx("h2",{children:u("Team backup & restore")}),t.jsx("p",{children:u("A safe copy of your agents, their memories, and the work you have built together.")})]}),t.jsxs("div",{className:"pro-actions",children:[t.jsx("input",{ref:q,type:"file",accept:".gz,.tar.gz,application/gzip",hidden:!0,"aria-label":"Upload team backup",onChange:T=>T.target.files?.[0]&&$(T.target.files[0])}),t.jsx("button",{className:"secondary-btn",disabled:z,onClick:()=>q.current?.click(),children:t.jsxs(Xn,{busy:z&&L==="upload",label:"Uploading",children:[t.jsx(F2,{size:15}),u("Upload backup")]})}),t.jsxs("button",{className:"primary-btn",onClick:()=>l(!0),children:[t.jsx(jn,{size:15}),u("Back up now")]})]})]}),t.jsxs("div",{className:"panel ow-backup-policy",children:[t.jsxs("div",{children:[t.jsx(za,{size:24}),t.jsxs("span",{children:[t.jsx("h3",{children:u("A rhythm for peace of mind.")}),t.jsx("p",{children:u("Automatic backups run on this server, even while the dashboard is closed.")})]})]}),t.jsxs("label",{className:"ow-check",children:[t.jsx("input",{type:"checkbox","aria-label":"Automatic team backups",checked:e.backupAuto,onChange:T=>wa(_=>{_.backupAuto=T.target.checked})}),u("Automatic backups")]}),t.jsxs("label",{children:[u("Frequency"),t.jsxs("select",{value:e.backupFrequency,onChange:T=>wa(_=>{_.backupFrequency=T.target.value}),children:[t.jsx("option",{value:"Daily",children:u("Daily")}),t.jsx("option",{value:"Weekly",children:u("Weekly")})]})]}),t.jsxs("label",{children:[u("Keep"),t.jsx("select",{"aria-label":"Backups to keep",value:e.backupKeep,onChange:T=>wa(_=>{_.backupKeep=Number(T.target.value)}),children:[3,7,14,30].map(T=>t.jsxs("option",{value:T,children:[T," backups"]},T))})]})]}),z&&L==="upload"&&t.jsx(Ma,{label:"Uploading the backup to your server and checking what is inside",since:J,expect:20}),k&&t.jsx(Ot,{children:k}),N&&t.jsx(Ot,{error:!0,children:N}),t.jsx("div",{className:"panel ow-backup-list",children:e.backups.length?e.backups.map(T=>t.jsxs("article",{children:[t.jsx("span",{className:"ow-backup-icon",children:t.jsx(fU,{size:25})}),t.jsxs("div",{children:[t.jsx("h3",{children:T.name}),t.jsxs("p",{children:[Yn(T.created)," · ",hW(T)]}),t.jsxs("small",{children:[T.counts.agents??0," ",u("agents")," · ",T.counts.docs??0," ",u("documents")," · ",T.counts.missions??0," ",u("missions"),T.automatic?` · ${u("Automatic")}`:""]}),t.jsxs("details",{children:[t.jsx("summary",{children:u("What is inside")}),t.jsx("div",{className:"ow-backup-contents",children:Lc.map(_=>t.jsxs("span",{children:[t.jsx(Kt,{size:13}),u(_)]},_))})]})]}),t.jsxs("div",{className:"pro-actions",children:[t.jsxs("button",{className:"secondary-btn","aria-label":`Download ${T.name}`,onClick:()=>{window.location.href=`/api/backups/download?id=${T.id}`},children:[t.jsx(Eo,{size:15}),t.jsx("span",{children:u("Download")})]}),t.jsxs("button",{className:"secondary-btn",onClick:()=>Q(T),children:[t.jsx(ss,{size:15}),u("Restore")]}),t.jsx("button",{className:"ow-icon-button","aria-label":`Delete ${T.name}`,onClick:()=>F(T.id),children:t.jsx(ti,{size:16})})]})]},T.id)):t.jsxs("div",{className:"ow-empty",children:[t.jsx(tu,{size:32}),t.jsx("h3",{children:u("Your first backup starts here.")}),t.jsx("p",{children:u("Make a snapshot before changing your team.")})]})}),t.jsxs(on,{open:o,onClose:()=>l(!1),title:"Back up your team",description:"Capture the team as it is right now.",children:[t.jsxs("label",{children:[u("Backup name (optional)"),t.jsx("input",{"aria-label":"Backup name",value:n,onChange:T=>s(T.target.value),maxLength:100,placeholder:"Before the next launch"})]}),t.jsx("div",{className:"ow-backup-contents",children:Lc.map(T=>t.jsxs("span",{children:[t.jsx(Kt,{size:14}),u(T)]},T))}),t.jsx("p",{className:"pro-small",children:u("The snapshot includes agent files and memories. Sign-in credentials, API keys, and the terminal password are left out. Download it to keep a copy off this server.")}),z&&L==="create"&&t.jsx(Ma,{label:"Packing your agents, their memories and your work into the backup",since:J,expect:25}),t.jsx("button",{className:"primary-btn",disabled:z,onClick:ie,children:t.jsxs(Xn,{busy:z,label:"Creating the backup",children:[t.jsx(tu,{size:16}),u("Create backup")]})})]}),t.jsx(on,{open:!!d,onClose:()=>{z||h(null)},title:M?"Confirm what will be replaced":"Restore your team",description:d?.name,wide:!0,children:d&&t.jsxs(t.Fragment,{children:[M?t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"ow-replacement",children:[t.jsx(za,{size:25}),t.jsxs("div",{children:[t.jsx("h3",{children:u("This replaces current data.")}),t.jsx("p",{children:u(x?"The complete agent roster, memories, documents, missions, schedules, automations, tasks, and settings will be replaced by this snapshot.":"Only the chosen parts below will be replaced. Other team data stays in place.")})]})]}),t.jsx("ul",{className:"ow-replace-list",children:Y.map(T=>t.jsxs("li",{children:[u(T),T==="Agents & memories"&&!x&&`: ${ne.filter(_=>y.includes(_.id)).map(_=>_.name).join(", ")}`]},T))}),t.jsx("p",{className:"pro-small",children:u("Laboratorio backs up the current team first, so this can be undone.")}),t.jsxs("label",{children:[u("Type RESTORE to continue"),t.jsx("input",{"aria-label":"Restore confirmation",value:E,onChange:T=>A(T.target.value),placeholder:"RESTORE"})]}),z&&L==="restore"&&t.jsx(Ma,{label:"Restoring your team: unpacking the backup and putting each part back",since:J,expect:40,note:"Keep this window open. Your team is back the moment this finishes."}),t.jsxs("div",{className:"pro-actions spread",children:[t.jsx("button",{className:"secondary-btn",disabled:z,onClick:()=>w(!1),children:u("Back")}),t.jsx("button",{className:"primary-btn",disabled:E!=="RESTORE"||z,onClick:te,children:t.jsx(Xn,{busy:z,label:"Restoring",children:u("Restore selected data")})})]})]}):t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"segmented",children:[t.jsx("button",{className:x?"selected":"",onClick:()=>S(!0),children:u("Restore everything")}),t.jsx("button",{className:x?"":"selected",onClick:()=>S(!1),children:u("Choose parts")})]}),!x&&t.jsx("div",{className:"ow-restore-parts",children:Lc.map(T=>t.jsxs("label",{className:"ow-check",children:[t.jsx("input",{type:"checkbox",checked:m.includes(T),onChange:()=>p(_=>_.includes(T)?_.filter(ve=>ve!==T):[..._,T])}),u(T)]},T))}),Y.includes("Agents & memories")&&t.jsxs("section",{className:"ow-restore-agents",children:[t.jsx("h3",{children:u("Agents in this backup")}),ne.map(T=>t.jsxs("label",{className:"ow-check",children:[t.jsx("input",{type:"checkbox",disabled:x,checked:x||y.includes(T.id),onChange:()=>v(_=>_.includes(T.id)?_.filter(ve=>ve!==T.id):[..._,T.id])}),T.name,t.jsx("span",{children:T.role})]},T.id))]}),t.jsx("div",{className:"pro-actions right",children:t.jsx("button",{className:"primary-btn",disabled:!Y.length||Y.includes("Agents & memories")&&!x&&!y.length,onClick:()=>{A(""),w(!0)},children:u("Review replacement")})})]}),N&&t.jsx(Ot,{error:!0,children:N})]})}),t.jsx(on,{open:!!P,onClose:()=>F(null),title:"Remove this backup?",description:"Download a copy first if you want to keep it.",children:t.jsxs("div",{className:"pro-actions right",children:[t.jsx("button",{className:"secondary-btn",onClick:()=>F(null),children:u("Keep backup")}),t.jsx("button",{className:"ow-reject",onClick:async()=>{try{await $c("/api/backups/delete",{id:P})}catch(T){I(T.message)}F(null)},children:u("Remove backup")})]})})]})}const CN=25*1024*1024,go=[{id:"personal",name:"Personal inbox",address:"hello@laboratorio.example"},{id:"studio",name:"Studio inbox",address:"studio@laboratorio.example"}];function pW(a){go.splice(0,go.length,...a)}function mW(a){return a.split(/[,;\n]/).map(e=>e.trim()).filter(Boolean)}function ey(a){const e=mW(a);return e.length>0&&e.every(n=>/^[^\s@<>]+@[^\s@<>]+\.[^\s@<>]+$/.test(n))}function Lb(a){return a.reduce((e,n)=>e+n.size,0)}function gW(a){return!ey(a.to)||a.cc.trim()&&!ey(a.cc)||a.bcc.trim()&&!ey(a.bcc)?"Enter valid email addresses, separated by commas.":a.subject.trim()?!a.body.trim()&&a.mode!=="forward"?"Write a message before sending.":Lb(a.attachments)>CN?"Attachments exceed 25 MB in total. Remove a file to continue.":a.attachments.some(e=>e.status!=="ready")?"Wait until every attachment is ready.":"":"Add a subject before sending."}function vW(a="new",e){const n=new Set(go.map(o=>o.address.toLowerCase())),s=[e?.address,...e?.to||[],...e?.cc||[]].filter(o=>!!o&&!n.has(o.toLowerCase()));return{id:crypto.randomUUID(),mode:a,sourceId:e?.id,fromInboxId:e?.inboxId||go[0]?.id||"",to:a==="forward"||a==="new"?"":a==="replyAll"?[...new Set(s)].join(", "):e?.address||"",cc:"",bcc:"",subject:e?a==="forward"?`Fwd: ${e.subject.replace(/^Fwd: /i,"")}`:/^Re: /i.test(e.subject)?e.subject:`Re: ${e.subject}`:"",body:"",attachments:a==="forward"?(e?.attachments||[]).map(o=>({...o,progress:100,status:"ready"})):[],updated:new Date().toISOString()}}function dl(a){return a.filter(e=>!e.deleted&&!e.archived)}function $0(a){return dl(a).filter(e=>e.urgency>=8&&!e.handled)}function xW(a,e){return a.filter(n=>e==="trash"?n.deleted:!n.deleted&&(e==="archived"?n.archived:e==="starred"?n.starred:!n.archived&&(e==="all"||e==="attention"?e==="all"||n.urgency>=8&&!n.handled:n.categoryId===e)))}function PC(a,e,n,s){const o=structuredClone(a.emails.filter(h=>e.includes(h.id))),l=[];let d=0;for(const h of a.emails.filter(m=>e.includes(m.id)))if(n==="read"&&(h.unread=!1),n==="unread"&&(h.unread=!0),n==="addressed"&&(h.handled=!0),n==="unaddressed"&&(h.handled=!1),n==="star"&&(h.starred=!0),n==="unstar"&&(h.starred=!1),n==="archive"&&(h.archived=!0),n==="unarchive"&&(h.archived=!1),n==="delete"&&(h.deleted=!0),n==="move"&&s&&a.categories.some(m=>m.id===s)&&s!==h.categoryId){const m=crypto.randomUUID();a.corrections.unshift({id:m,emailId:h.id,sender:h.sender,from:a.categories.find(p=>p.id===h.categoryId)?.name||"Other",to:a.categories.find(p=>p.id===s).name,at:new Date().toISOString()}),l.push(m),d++,h.categoryId=s}return a.correctionCount+=d,{action:n,before:o,correctionIds:l,correctionCount:d}}function IC(a,e){for(const n of e.before){const s=a.emails.find(o=>o.id===n.id);if(s){const o={read:"unread",unread:"unread",addressed:"handled",unaddressed:"handled",star:"starred",unstar:"starred",archive:"archived",unarchive:"archived",delete:"deleted",move:"categoryId"}[e.action];Object.assign(s,{[o]:n[o]})}}a.corrections=a.corrections.filter(n=>!e.correctionIds.includes(n.id)),a.correctionCount=Math.max(0,a.correctionCount-e.correctionCount)}const il="other",tl=["#a5ce31","#56a6a9","#c49b62","#8d8bd0","#cc7d85","#72a887","#d6ae46"];function TN(){return[{id:"sponsorships",name:"Sponsorships",description:"Partnership proposals, paid collaborations and media requests.",examples:["Northstar Studios · Partnership idea","Haven Labs · Campaign proposal"],color:tl[0],gmailLabel:!0,autoDraft:!0,agentId:"agent-2",instructions:"Reply warmly, ask for the brief and budget, and prepare a draft for my approval.",notify:!0},{id:"support",name:"Customer support",description:"Customer questions, access issues and product problems.",examples:["Atlas Support · Export issue","Sofia Chen · Workspace invite"],color:tl[1],gmailLabel:!0,autoDraft:!1,agentId:"agent-orchestrator",instructions:"",notify:!0},{id:"membership",name:"Membership",description:"Member plans, renewals and account changes.",examples:["Leah Martins · Annual plan","David Ruiz · Team plan"],color:tl[2],gmailLabel:!1,autoDraft:!1,agentId:"agent-orchestrator",instructions:"",notify:!1},{id:"invoices",name:"Invoices",description:"Invoices, payment reminders and receipts.",examples:["Cloudline Billing · Invoice","Pine Accounting · Receipt"],color:tl[3],gmailLabel:!0,autoDraft:!1,agentId:"agent-orchestrator",instructions:"",notify:!0},{id:"newsletters",name:"Newsletters",description:"Recurring digests and reading from subscriptions.",examples:["The Product Edit · Weekly digest","Founders Notes · Monday brief"],color:tl[4],gmailLabel:!1,autoDraft:!1,agentId:"agent-orchestrator",instructions:"",notify:!1},{id:il,name:"Other",description:"Messages that do not fit another category.",examples:["Ari Patel · Lunch next week","Mosaic Events · Roundtable"],color:tl[5],gmailLabel:!1,autoDraft:!1,agentId:"agent-orchestrator",instructions:"",notify:!1}]}const ml=a=>new Set(a.map(e=>e.threadId||e.id)).size,yW=(a,e)=>a.filter(n=>Date.now()-Date.parse(n.at)<=e*864e5).length;function bW(){return{stage:"intro",demoGmail:!1,demoKey:!1,categories:[{...TN().at(-1)}],emails:[],corrections:[],correctionCount:0,draftInstructions:{},sortDays:7,lastSorted:"",sortRuns:0,costLedger:[],connected:!1,keySet:!1,periodCounts:{},job:{kind:null,done:0,total:0,error:null},perEmail:24e-6,analyzed:0,loaded:!1,drafts:[],sent:[],suggestions:{}}}let Ut=bW();const Ob=new Set,La=()=>Ob.forEach(a=>a());function UC(){return Ut}function Eu(){return C.useSyncExternalStore(a=>(Ob.add(a),()=>Ob.delete(a)),UC,UC)}const SW=a=>(a.match(/<([^>]+)>/)?.[1]||a).trim(),FC=a=>(Array.isArray(a)?a.map(String):String(a||"").split(/,(?![^<]*>)/)).map(SW).filter(Boolean),AW=(a,e)=>`/api/mail/attachment?id=${encodeURIComponent(a)}&att=${encodeURIComponent(e.attachmentId)}&name=${encodeURIComponent(e.filename||"file")}&type=${encodeURIComponent(e.mimeType||"")}`,eS=(a,e)=>(Array.isArray(e)?e:[]).map(n=>n.attachmentId?{id:n.attachmentId,name:n.filename||"file",type:n.mimeType||"application/octet-stream",size:n.size||0,progress:100,status:"ready",url:AW(a,n)}:n);function tS(a){return{...a,starred:!!a.starred,archived:!!a.archived,deleted:Jm.has(a.id),inboxId:Ut.account||"",to:FC(a.to),cc:FC(a.cc),attachments:eS(a.id,a.attachments),conversation:Array.isArray(a.conversation)?a.conversation:[],body:typeof a.body=="string"?a.body:""}}let lh=0;const Jm=new Set;function Sh(a){const e={...a};if(lh>0)delete e.emails;else if(a.emails){const n=new Map(Ut.emails.map(s=>[s.id,s]));e.emails=a.emails.map(s=>{const o=tS(s),l=n.get(o.id);return!o.body&&l?.body&&(o.body=l.body,l.conversation?.length&&!o.conversation.length&&(o.conversation=l.conversation)),o})}if(a.accounts){const n=[...a.accounts].sort((s,o)=>(o.id===a.account?1:0)-(s.id===a.account?1:0)).map(s=>({id:s.id,name:s.alias||s.email,address:s.email}));pW(n.length?n:[{id:"",name:"Gmail",address:""}])}return e}let fu=0;const jN=a=>fu&&!a.job?.kind&&Date.now()-fu<15e3?{...a,job:Ut.job,stage:Ut.stage}:a;let BC="",Ep=null;function gl(){return Ep||(Ep=EW().finally(()=>{Ep=null})),Ep}async function EW(){const a=Date.now();try{const e=await wt(`/api/mail?light=1&rev=${encodeURIComponent(lh>0?"":BC)}`);e.emails&&e.emailsRev&&lh===0&&(BC=e.emailsRev);let n=Sh(e);if(a{wp++,!document.hidden&&((Ut.job?.kind||Ut.checking?.running)&&wp%3===0||Ut.connecting&&wp%3===0||wp%30===0)&&gl()},1e3));function HC(a){fu=a.kind?Date.now():0,Ut={...Ut,job:a},La()}function wW(a){const e=tS(a);Ut={...Ut,emails:Ut.emails.map(n=>n.id===e.id?{...n,...e,unread:n.unread&&e.unread}:n)},La()}async function ch(a,e={}){const n=Sh(await wt(a,e));return n.job?.kind&&(fu=0),Ut={...Ut,...n,error:void 0},La(),Ut}function vl(a){const e=structuredClone(Ut);a(e),Ut=e,La()}let Mp=null,kd={},Cp=[];function Ka(a){const e=Ut,n=structuredClone(Ut);a(n),n.categories.some(l=>l.id===il)||n.categories.push(TN().at(-1)),Ut=n,La();const s=new Map(e.emails.map(l=>[l.id,l]));for(const l of n.emails){const d=s.get(l.id);if(!d)continue;const h={};d.unread!==l.unread&&(h.unread=l.unread),d.handled!==l.handled&&(h.handled=l.handled),d.categoryId!==l.categoryId&&(h.categoryId=l.categoryId),Object.keys(h).length&&(kd[l.id]={...kd[l.id],...h})}const o=new Set(n.corrections.map(l=>l.id));Cp.push(...e.corrections.filter(l=>!o.has(l.id)).map(l=>l.id)),!(typeof window>"u")&&(OW(e.drafts,n.drafts),!(!Object.keys(kd).length&&!Cp.length&&JSON.stringify(e.categories)===JSON.stringify(n.categories)&&e.sortDays===n.sortDays)&&(Mp&&clearTimeout(Mp),Mp=setTimeout(async()=>{Mp=null;const l=Object.entries(kd).map(([h,m])=>({id:h,...m})),d=Cp;kd={},Cp=[];try{const h=jN(Sh(await wt("/api/mail",{categories:Ut.categories,sortDays:Ut.sortDays,emails:l,removeCorrections:d},"PUT")));Ut={...Ut,...h,error:void 0},La()}catch(h){Ut={...Ut,error:h.message},La(),gl()}},400)))}async function Ah(a){const e=Sh(await wt("/api/mail",a,"PUT"));Ut={...Ut,...e,error:void 0},La()}const MW=a=>Ah({retention:a}),CW=a=>ch("/api/mail/period",{days:a}),TW=a=>Ah({interval:a}),jW=a=>Ah({markReadInGmail:a}),RW=a=>Ah({emails:[{id:a,confirm:!0}]}),kW=a=>Ah({account:a});async function GC(a,e,n){lh++;let s;try{s=await wt("/api/mail/bulk",{action:a,ids:e,categoryId:n})}finally{lh--}Ut={...Ut,...Sh(s),error:void 0},La()}const pu=new Map;function RN(a){return a.forEach(e=>{Jm.delete(e)}),fetch("/api/mail/bulk",{method:"POST",keepalive:!0,headers:{"Content-Type":"application/json"},body:JSON.stringify({action:"delete",ids:a})})}function NW(a,e){const n=a.join(",");return a.forEach(s=>Jm.add(s)),pu.set(n,setTimeout(async()=>{pu.delete(n);try{const s=await RN(a),o=await s.json().catch(()=>({}));if(!s.ok)throw new Error(o.error||"Gmail did not move them to Trash.");vl(l=>{l.emails=l.emails.filter(d=>!a.includes(d.id))})}catch(s){vl(o=>{o.emails.forEach(l=>{a.includes(l.id)&&(l.deleted=!1)})}),e(s.message)}},8e3)),n}function DW(a){const e=pu.get(a);e&&clearTimeout(e),pu.delete(a),a.split(",").forEach(n=>Jm.delete(n))}typeof window<"u"&&addEventListener("pagehide",()=>{for(const[a,e]of pu)clearTimeout(e),RN(a.split(","));pu.clear()});const ho=new Map;async function zW(){try{const a=await wt("/api/mail/drafts");Ut={...Ut,drafts:a.drafts.map(e=>({...e,attachments:(e.attachments||[]).map(n=>({...n,progress:100,status:"ready"}))}))},La()}catch{}}function kN(a){const e=ho.get(a);e&&clearTimeout(e),ho.delete(a);const n=Ut.drafts.find(s=>s.id===a);return n?wt("/api/mail/drafts/save",{draft:n}).then(()=>{}):Promise.resolve()}const LW=a=>kN(a);function OW(a,e){const n=new Map(a.map(o=>[o.id,JSON.stringify(o)]));for(const o of e){if(n.get(o.id)===JSON.stringify(o))continue;const l=ho.get(o.id);l&&clearTimeout(l),ho.set(o.id,setTimeout(()=>{kN(o.id).catch(()=>{})},800))}const s=new Set(e.map(o=>o.id));for(const o of a)if(!s.has(o.id)){const l=ho.get(o.id);l&&clearTimeout(l),ho.delete(o.id),wt("/api/mail/drafts/act",{action:"delete",id:o.id}).catch(()=>{})}}async function PW(a){const e=ho.get(a.id);e&&clearTimeout(e),ho.delete(a.id);const n=a.attachments.filter(l=>!l.url).map(({id:l,name:d,type:h,size:m})=>({id:l,name:d,type:h,size:m})),s={draftId:a.id,from:a.fromInboxId,to:a.to,cc:a.cc,bcc:a.bcc,subject:a.subject,body:a.body,html:a.html&&a.html.trim()?a.html:void 0},o=a.mode==="new"||!a.sourceId?await wt("/api/mail/send",{...s,attachments:n}):a.mode==="forward"?await wt("/api/mail/forward",{...s,id:a.sourceId}):await wt("/api/mail/reply",{...s,id:a.sourceId,attachments:n});return vl(l=>{if(l.drafts=l.drafts.filter(d=>d.id!==a.id),l.sent=[o.sent,...l.sent.filter(d=>d.id!==o.sent.id)],o.email){const d=tS(o.email),h=l.emails.findIndex(m=>m.id===d.id);h>=0&&(l.emails[h]={...l.emails[h],...d})}}),o.message}async function ty(){if(!Ut.sentLoading){Ut={...Ut,sentLoading:!0,sentError:void 0},La();try{const e=(await wt("/api/mail/sent")).sent.map(n=>({id:n.id,mode:"new",fromInboxId:"",to:n.to||"",cc:"",bcc:"",subject:n.subject,body:n.preview,attachments:[],updated:n.at,sentAt:n.at,url:n.url,full:!1}));Ut={...Ut,sent:e,sentLoading:!1},La()}catch(a){Ut={...Ut,sentLoading:!1,sentError:a.message},La()}}}async function IW(a){if(!(Ut.sent.find(e=>e.id===a)?.full||!/^[0-9a-f]{8,32}$/.test(a)))try{const e=await wt(`/api/mail/message?id=${encodeURIComponent(a)}`);vl(n=>{const s=n.sent.find(o=>o.id===a);s&&Object.assign(s,{body:e.body||s.body,to:e.to||s.to,cc:e.cc,attachments:eS(a,e.attachments),full:!0})})}catch{}}async function UW(a,e){const n=async o=>{const l=await wt(`/api/mail/thread?id=${encodeURIComponent(a)}${o?"&fresh=1":""}`);return{thread:l.thread.map(d=>({...d,attachments:eS(d.id,d.attachments)})),stale:!!l.stale}},s=await n(!1);return s.stale&&e&&n(!0).then(o=>e(o.thread)).catch(()=>{}),s.thread}async function FW(){Ut={...Ut,checking:{...Ut.checking||{at:null,new:0,removed:0,changed:0,error:null},running:!0}},La();try{await ch("/api/mail/check")}catch(a){throw Ut={...Ut,checking:{...Ut.checking,running:!1}},La(),a}}const Yc=a=>(a.needsReply??0)>=60&&!a.handled&&!a.youReplied,BW={Bold:["Gras","Negrita","Fett","Negrito","Grassetto"],Italic:["Italique","Cursiva","Kursiv","Itálico","Corsivo"],Underline:["Souligné","Subrayado","Unterstrichen","Sublinhado","Sottolineato"],Strikethrough:["Barré","Tachado","Durchgestrichen","Riscado","Barrato"],Formatting:["Mise en forme","Formato","Formatierung","Formatação","Formattazione"],"Text size":["Taille du texte","Tamaño del texto","Textgröße","Tamanho do texto","Dimensione del testo"],Size:["Taille","Tamaño","Größe","Tamanho","Dimensione"],Small:["Petit","Pequeño","Klein","Pequeno","Piccolo"],Normal:["Normal","Normal","Normal","Normal","Normale"],Large:["Grand","Grande","Groß","Grande","Grande"],Huge:["Très grand","Enorme","Sehr groß","Enorme","Enorme"],"Text colour":["Couleur du texte","Color del texto","Textfarbe","Cor do texto","Colore del testo"],Highlight:["Surligner","Resaltar","Hervorheben","Realçar","Evidenzia"],"No highlight":["Sans surlignage","Sin resaltado","Keine Hervorhebung","Sem realce","Nessuna evidenziazione"],Link:["Lien","Enlace","Link","Ligação","Link"],"Bulleted list":["Liste à puces","Lista con viñetas","Aufzählung","Lista com marcadores","Elenco puntato"],"Numbered list":["Liste numérotée","Lista numerada","Nummerierte Liste","Lista numerada","Elenco numerato"],Quote:["Citation","Cita","Zitat","Citação","Citazione"],"Clear formatting":["Effacer la mise en forme","Borrar formato","Formatierung entfernen","Limpar formatação","Cancella formattazione"],"Link address":["Adresse du lien","Dirección del enlace","Link-Adresse","Endereço da ligação","Indirizzo del link"],"Add link":["Ajouter le lien","Añadir enlace","Link hinzufügen","Adicionar ligação","Aggiungi link"],"Remove link":["Retirer le lien","Quitar enlace","Link entfernen","Remover ligação","Rimuovi link"],"Draft with an agent":["Rédiger avec un agent","Redactar con un agente","Mit einem Agenten entwerfen","Redigir com um agente","Scrivi con un agente"],"Jev was not sure":["Jev n’était pas sûr","Jev no estaba seguro","Jev war sich nicht sicher","O Jev não tinha certeza","Jev non era sicuro"],or:["ou","o","oder","ou","o"],Category:["Catégorie","Categoría","Kategorie","Categoria","Categoria"],"Why?":["Pourquoi ?","¿Por qué?","Warum?","Porquê?","Perché?"],"Add to-do":["Ajouter une tâche","Añadir tarea","Aufgabe hinzufügen","Adicionar tarefa","Aggiungi attività"],"Loading the full email from Gmail…":["Chargement de l’e-mail complet depuis Gmail…","Cargando el correo completo de Gmail…","Vollständige E-Mail wird aus Gmail geladen…","A carregar o e-mail completo do Gmail…","Caricamento dell’email completa da Gmail…"],"The full email could not be loaded from Gmail.":["L’e-mail complet n’a pas pu être chargé depuis Gmail.","No se pudo cargar el correo completo de Gmail.","Die vollständige E-Mail konnte nicht aus Gmail geladen werden.","Não foi possível carregar o e-mail completo do Gmail.","Impossibile caricare l’email completa da Gmail."],"Needs a reply":["Réponse attendue","Requiere respuesta","Antwort nötig","Precisa de resposta","Serve una risposta"],"Jev thinks someone is waiting for your answer":["Jev pense que quelqu’un attend votre réponse","Jev cree que alguien espera tu respuesta","Jev meint, dass jemand auf Ihre Antwort wartet","O Jev acha que alguém espera a sua resposta","Jev pensa che qualcuno aspetti la tua risposta"],"Check now":["Vérifier","Comprobar","Jetzt prüfen","Verificar agora","Controlla ora"],"Checking…":["Vérification…","Comprobando…","Wird geprüft…","A verificar…","Controllo…"],"Check Gmail for new mail now":["Vérifier maintenant les nouveaux e-mails dans Gmail","Buscar ahora correo nuevo en Gmail","Jetzt in Gmail nach neuen E-Mails suchen","Verificar agora novos e-mails no Gmail","Controlla ora la nuova posta in Gmail"],"Could not check Gmail":["Impossible de vérifier Gmail","No se pudo comprobar Gmail","Gmail konnte nicht geprüft werden","Não foi possível verificar o Gmail","Impossibile controllare Gmail"],"new email sorted":["nouvel e-mail trié","correo nuevo ordenado","neue E-Mail sortiert","novo e-mail organizado","nuova email ordinata"],"new emails sorted":["nouveaux e-mails triés","correos nuevos ordenados","neue E-Mails sortiert","novos e-mails organizados","nuove email ordinate"],"No new mail":["Aucun nouvel e-mail","No hay correo nuevo","Keine neuen E-Mails","Sem e-mails novos","Nessuna nuova email"],"deleted in Gmail and removed here":["supprimés dans Gmail et retirés ici","borrados en Gmail y quitados aquí","in Gmail gelöscht und hier entfernt","apagados no Gmail e removidos aqui","eliminate in Gmail e rimosse qui"],"changed in Gmail and updated here":["modifiés dans Gmail et mis à jour ici","cambiados en Gmail y actualizados aquí","in Gmail geändert und hier aktualisiert","alterados no Gmail e atualizados aqui","modificate in Gmail e aggiornate qui"],"Open unread mail":["Ouvrir les e-mails non lus","Abrir correos no leídos","Ungelesene E-Mails öffnen","Abrir e-mails não lidos","Apri le email non lette"],"Mail learned from your move.":["Mail a appris de votre déplacement.","Mail aprendió de tu cambio.","Mail hat aus Ihrer Verschiebung gelernt.","O Mail aprendeu com a sua alteração.","Mail ha imparato dal tuo spostamento."],"more emails checked":["autres e-mails vérifiés","correos más revisados","weitere E-Mails geprüft","outros e-mails verificados","altre email controllate"],"moved to":["déplacés vers","movidos a","verschoben nach","movidos para","spostate in"],"Show the quoted messages":["Afficher les messages cités","Mostrar los mensajes citados","Zitierte Nachrichten anzeigen","Mostrar as mensagens citadas","Mostra i messaggi citati"],"Hide the quoted messages":["Masquer les messages cités","Ocultar los mensajes citados","Zitierte Nachrichten ausblenden","Ocultar as mensagens citadas","Nascondi i messaggi citati"],"Earlier in this conversation":["Plus tôt dans cette conversation","Antes en esta conversación","Früher in diesem Gespräch","Antes nesta conversa","Prima in questa conversazione"],"Later in this conversation":["Plus tard dans cette conversation","Después en esta conversación","Später in diesem Gespräch","Depois nesta conversa","Dopo in questa conversazione"],"Reading the conversation from Gmail…":["Lecture de la conversation dans Gmail…","Leyendo la conversación de Gmail…","Gespräch wird aus Gmail gelesen…","A ler a conversa do Gmail…","Lettura della conversazione da Gmail…"],"You replied to this email":["Vous avez répondu à cet e-mail","Respondiste a este correo","Sie haben auf diese E-Mail geantwortet","Respondeu a este e-mail","Hai risposto a questa email"],Replied:["Répondu","Respondido","Beantwortet","Respondido","Risposto"],"This email answers something you sent":["Cet e-mail répond à un message que vous avez envoyé","Este correo responde a algo que enviaste","Diese E-Mail antwortet auf etwas, das Sie gesendet haben","Este e-mail responde a algo que enviou","Questa email risponde a qualcosa che hai inviato"],"Replies to you":["Vous répond","Te responde","Antwortet Ihnen","Responde-lhe","Ti risponde"],"8 to 10 goes to Needs attention.":["De 8 à 10, l’e-mail va dans À traiter.","De 8 a 10 pasa a Requiere atención.","8 bis 10 landet unter Braucht Aufmerksamkeit.","De 8 a 10 vai para Precisa de atenção.","Da 8 a 10 finisce in Richiede attenzione."],Read:["Lus","Leídos","Gelesen","Lidos","Letti"],"Could not send":["Envoi impossible","No se pudo enviar","Senden nicht möglich","Não foi possível enviar","Invio non riuscito"],"Saved as you write.":["Enregistré pendant la rédaction.","Se guarda mientras escribes.","Wird beim Schreiben gespeichert.","Guardado enquanto escreve.","Salvato mentre scrivi."],"Sent from your Gmail.":["Envoyé depuis votre Gmail.","Se envía desde tu Gmail.","Wird über Ihr Gmail gesendet.","Enviado pelo seu Gmail.","Inviato dal tuo Gmail."],"The original attachments go with it.":["Les pièces jointes d’origine sont incluses.","Los adjuntos originales van incluidos.","Die ursprünglichen Anhänge werden mitgesendet.","Os anexos originais seguem junto.","Gli allegati originali vengono inclusi."],"Your draft is safe.":["Votre brouillon est conservé.","Tu borrador está a salvo.","Ihr Entwurf ist sicher.","O seu rascunho está seguro.","La tua bozza è al sicuro."],"The draft stopped because Laboratorio restarted. Ask the agent again.":["Le brouillon s'est arrêté car Laboratorio a redémarré. Redemandez à l'agent.","El borrador se detuvo porque Laboratorio se reinició. Pídeselo de nuevo al agente.","Der Entwurf wurde abgebrochen, weil Laboratorio neu gestartet ist. Bitte den Agenten erneut fragen.","O rascunho parou porque o Laboratorio reiniciou. Peça novamente ao agente.","La bozza si è interrotta perché Laboratorio si è riavviato. Chiedi di nuovo all'agente."],"An agent is writing a draft…":["Un agent rédige un brouillon…","Un agente está escribiendo un borrador…","Ein Agent schreibt einen Entwurf…","Um agente está a escrever um rascunho…","Un agente sta scrivendo una bozza…"],"Could not move to Trash in Gmail":["Impossible de placer dans la corbeille Gmail","No se pudo mover a la papelera de Gmail","Konnte nicht in den Gmail-Papierkorb verschoben werden","Não foi possível mover para o lixo do Gmail","Impossibile spostare nel cestino di Gmail"],"Could not update Gmail":["Impossible de mettre à jour Gmail","No se pudo actualizar Gmail","Gmail konnte nicht aktualisiert werden","Não foi possível atualizar o Gmail","Impossibile aggiornare Gmail"],"Move back to the inbox":["Remettre dans la boîte de réception","Devolver a la bandeja de entrada","Zurück in den Posteingang","Voltar para a caixa de entrada","Riporta nella posta in arrivo"],"Moved back to the inbox.":["Remis dans la boîte de réception.","Devuelto a la bandeja de entrada.","Zurück im Posteingang.","Voltou para a caixa de entrada.","Riportato nella posta in arrivo."],"Reading your sent mail from Gmail…":["Lecture de vos e-mails envoyés dans Gmail…","Leyendo tus correos enviados de Gmail…","Gesendete E-Mails werden aus Gmail gelesen…","A ler os e-mails enviados do Gmail…","Lettura della posta inviata da Gmail…"],"Sent mail could not be read":["Impossible de lire les e-mails envoyés","No se pudieron leer los correos enviados","Gesendete E-Mails konnten nicht gelesen werden","Não foi possível ler os e-mails enviados","Impossibile leggere la posta inviata"],"Your mail is unchanged.":["Vos e-mails n’ont pas changé.","Tu correo no ha cambiado.","Ihre E-Mails sind unverändert.","Os seus e-mails não mudaram.","La tua posta è invariata."],"On a phone, add Laboratorio to the home screen and open it from there to receive alerts.":["Sur un téléphone, ajoutez Laboratorio à l’écran d’accueil et ouvrez-le depuis là pour recevoir les alertes.","En un teléfono, añade Laboratorio a la pantalla de inicio y ábrelo desde allí para recibir avisos.","Auf dem Telefon Laboratorio zum Startbildschirm hinzufügen und von dort öffnen, um Hinweise zu erhalten.","No telemóvel, adicione o Laboratorio ao ecrã inicial e abra-o a partir daí para receber alertas.","Sul telefono, aggiungi Laboratorio alla schermata Home e aprilo da lì per ricevere gli avvisi."],"Quiet hours hold browser, phone and Telegram alerts. The bell always keeps them.":["Les heures calmes retiennent les alertes du navigateur, du téléphone et de Telegram. La cloche les garde toujours.","Las horas de silencio retienen los avisos del navegador, del teléfono y de Telegram. La campana siempre los guarda.","Ruhezeiten halten Browser-, Telefon- und Telegram-Hinweise zurück. Die Glocke behält sie immer.","As horas de silêncio retêm os alertas do navegador, do telemóvel e do Telegram. O sino guarda-os sempre.","Le ore di silenzio trattengono gli avvisi del browser, del telefono e di Telegram. La campanella li conserva sempre."],"Writing a draft. Edit agent reply appears here when it is ready. Nothing is sent.":["Rédaction en cours. « Modifier la réponse de l’agent » apparaîtra ici quand elle sera prête. Rien n’est envoyé.","Escribiendo un borrador. «Editar respuesta del agente» aparecerá aquí cuando esté lista. No se envía nada.","Entwurf wird geschrieben. „Antwort des Agenten bearbeiten“ erscheint hier, sobald sie fertig ist. Nichts wird gesendet.","A escrever um rascunho. «Editar resposta do agente» aparece aqui quando estiver pronta. Nada é enviado.","Bozza in scrittura. «Modifica risposta dell’agente» comparirà qui quando sarà pronta. Non viene inviato nulla."],"Each file must be 20 MB or smaller.":["Chaque fichier doit faire 20 Mo au maximum.","Cada archivo debe ocupar 20 MB o menos.","Jede Datei darf höchstens 20 MB groß sein.","Cada ficheiro deve ter 20 MB ou menos.","Ogni file deve essere di 20 MB o meno."],"No emails in this view":["Aucun e-mail dans cette vue","No hay correos en esta vista","Keine E-Mails in dieser Ansicht","Nenhum e-mail nesta vista","Nessuna email in questa vista"],"Try another folder or clear your filters.":["Essayez un autre dossier ou effacez les filtres.","Prueba otra carpeta o borra los filtros.","Anderen Ordner wählen oder Filter entfernen.","Tente outra pasta ou limpe os filtros.","Prova un’altra cartella o cancella i filtri."],Reply:["Répondre","Responder","Antworten","Responder","Rispondi"],"Reply all":["Répondre à tous","Responder a todos","Allen antworten","Responder a todos","Rispondi a tutti"],Forward:["Transférer","Reenviar","Weiterleiten","Encaminhar","Inoltra"],"New email":["Nouvel e-mail","Nuevo correo","Neue E-Mail","Novo e-mail","Nuova email"],From:["De","De","Von","De","Da"],To:["À","Para","An","Para","A"],Subject:["Objet","Asunto","Betreff","Assunto","Oggetto"],Message:["Message","Mensaje","Nachricht","Mensagem","Messaggio"],"Sending inbox":["Boîte d’envoi","Cuenta de envío","Absenderkonto","Conta de envio","Casella di invio"],"Personal inbox":["Boîte personnelle","Correo personal","Persönliches Postfach","Caixa pessoal","Casella personale"],"Studio inbox":["Boîte du studio","Correo del estudio","Studio-Postfach","Caixa do estúdio","Casella dello studio"],"To recipients":["Destinataires","Destinatarios","Empfänger","Destinatários","Destinatari"],"Email subject":["Objet de l’e-mail","Asunto del correo","E-Mail-Betreff","Assunto do e-mail","Oggetto dell’email"],"Writing area":["Zone de rédaction","Área de escritura","Schreibbereich","Área de escrita","Area di scrittura"],"Write your message…":["Écrivez votre message…","Escribe tu mensaje…","Schreiben Sie Ihre Nachricht…","Escreva sua mensagem…","Scrivi il tuo messaggio…"],"Add a note (optional)":["Ajouter une note (facultatif)","Añadir una nota (opcional)","Notiz hinzufügen (optional)","Adicionar uma nota (opcional)","Aggiungi una nota (facoltativo)"],Send:["Envoyer","Enviar","Senden","Enviar","Invia"],"Sending…":["Envoi en cours…","Enviando…","Wird gesendet…","Enviando…","Invio in corso…"],left:["restants","restantes","übrig","restantes","rimanenti"],Sent:["Envoyé","Enviados","Gesendet","Enviados","Inviata"],"Save as draft":["Enregistrer le brouillon","Guardar como borrador","Als Entwurf speichern","Salvar como rascunho","Salva come bozza"],"Saving draft…":["Enregistrement…","Guardando borrador…","Entwurf wird gespeichert…","Salvando rascunho…","Salvataggio bozza…"],Discard:["Abandonner","Descartar","Verwerfen","Descartar","Scarta"],"Close and keep draft":["Fermer et garder le brouillon","Cerrar y conservar borrador","Schließen und Entwurf behalten","Fechar e manter rascunho","Chiudi e conserva la bozza"],"Draft discarded.":["Brouillon abandonné.","Borrador descartado.","Entwurf verworfen.","Rascunho descartado.","Bozza scartata."],"Draft restored.":["Brouillon restauré.","Borrador recuperado.","Entwurf wiederhergestellt.","Rascunho restaurado.","Bozza ripristinata."],"Draft saved. Continue it from Drafts.":["Brouillon enregistré. Retrouvez-le dans Brouillons.","Borrador guardado. Continúa desde Borradores.","Entwurf gespeichert. Unter Entwürfe fortsetzen.","Rascunho salvo. Continue em Rascunhos.","Bozza salvata. Continua da Bozze."],"Saved on this device as you write.":["Enregistré sur cet appareil pendant la rédaction.","Se guarda en este dispositivo mientras escribes.","Wird beim Schreiben auf diesem Gerät gespeichert.","Salvo neste dispositivo enquanto você escreve.","Salvata sul dispositivo mentre scrivi."],"Sample sending only. No email leaves Laboratorio.":["Envoi fictif. Aucun e-mail ne quitte Laboratorio.","Envío de prueba. Ningún correo sale de Laboratorio.","Nur Beispielversand. Keine E-Mail verlässt Laboratorio.","Envio de exemplo. Nenhum e-mail sai do Laboratorio.","Invio di esempio. Nessuna email lascia Laboratorio."],"Sent in this preview. The conversation and Sent folder are updated.":["Envoyé dans cet aperçu. La conversation et le dossier Envoyés sont à jour.","Enviado en esta vista previa. La conversación y Enviados están actualizados.","In dieser Vorschau gesendet. Verlauf und Gesendet sind aktualisiert.","Enviado nesta prévia. A conversa e Enviados foram atualizados.","Inviata in questa anteprima. Conversazione e Posta inviata aggiornate."],"Could not send: the sample Gmail connection timed out. Your draft is safe. Try again.":["Envoi impossible : délai dépassé pour la connexion Gmail fictive. Votre brouillon est conservé. Réessayez.","No se pudo enviar: la conexión de ejemplo con Gmail agotó el tiempo. Tu borrador está a salvo. Reintenta.","Senden fehlgeschlagen: Zeitüberschreitung der Gmail-Beispielverbindung. Ihr Entwurf ist sicher. Erneut versuchen.","Falha no envio: a conexão de exemplo do Gmail expirou. Seu rascunho está seguro. Tente novamente.","Invio fallito: la connessione Gmail di esempio è scaduta. La bozza è al sicuro. Riprova."],"Try again":["Réessayer","Reintentar","Erneut versuchen","Tentar novamente","Riprova"],Attachments:["Pièces jointes","Archivos adjuntos","Anhänge","Anexos","Allegati"],"Add attachments":["Ajouter des fichiers","Añadir adjuntos","Anhänge hinzufügen","Adicionar anexos","Aggiungi allegati"],"Remove attachment":["Retirer le fichier","Quitar adjunto","Anhang entfernen","Remover anexo","Rimuovi allegato"],"Save attachment":["Enregistrer le fichier","Guardar adjunto","Anhang speichern","Salvar anexo","Salva allegato"],"Drop files here or add attachments.":["Déposez des fichiers ici ou ajoutez des pièces jointes.","Suelta archivos aquí o añade adjuntos.","Dateien hier ablegen oder Anhänge hinzufügen.","Solte arquivos aqui ou adicione anexos.","Trascina i file qui o aggiungi allegati."],"Adding attachment…":["Ajout du fichier…","Añadiendo adjunto…","Anhang wird hinzugefügt…","Adicionando anexo…","Aggiunta allegato…"],"Attachment unavailable":["Fichier indisponible","Adjunto no disponible","Anhang nicht verfügbar","Anexo indisponível","Allegato non disponibile"],"Attachments exceed 25 MB in total. Remove a file to continue.":["Les fichiers dépassent 25 Mo au total. Retirez un fichier pour continuer.","Los adjuntos superan 25 MB en total. Quita un archivo para continuar.","Die Anhänge überschreiten insgesamt 25 MB. Entfernen Sie eine Datei.","Os anexos excedem 25 MB no total. Remova um arquivo para continuar.","Gli allegati superano 25 MB in totale. Rimuovi un file per continuare."],"Wait until every attachment is ready.":["Attendez que tous les fichiers soient prêts.","Espera a que todos los adjuntos estén listos.","Warten Sie, bis alle Anhänge bereit sind.","Espere todos os anexos ficarem prontos.","Attendi che tutti gli allegati siano pronti."],"Could not store this attachment on this device.":["Impossible d’enregistrer ce fichier sur cet appareil.","No se pudo guardar el adjunto en este dispositivo.","Anhang konnte auf diesem Gerät nicht gespeichert werden.","Não foi possível salvar este anexo no dispositivo.","Impossibile salvare l’allegato sul dispositivo."],"This attachment is unavailable. Remove it and add it again.":["Ce fichier est indisponible. Retirez-le et ajoutez-le à nouveau.","Este adjunto no está disponible. Quítalo y añádelo de nuevo.","Dieser Anhang ist nicht verfügbar. Entfernen und erneut hinzufügen.","Este anexo está indisponível. Remova e adicione novamente.","Allegato non disponibile. Rimuovilo e aggiungilo di nuovo."],"Could not open this attachment.":["Impossible d’ouvrir ce fichier.","No se pudo abrir el adjunto.","Anhang konnte nicht geöffnet werden.","Não foi possível abrir este anexo.","Impossibile aprire l’allegato."],"Enter valid email addresses, separated by commas.":["Saisissez des adresses valides, séparées par des virgules.","Introduce correos válidos separados por comas.","Gültige E-Mail-Adressen eingeben, durch Kommas getrennt.","Digite e-mails válidos, separados por vírgulas.","Inserisci indirizzi validi separati da virgole."],"Add a subject before sending.":["Ajoutez un objet avant l’envoi.","Añade un asunto antes de enviar.","Vor dem Senden einen Betreff hinzufügen.","Adicione um assunto antes de enviar.","Aggiungi un oggetto prima di inviare."],"Write a message before sending.":["Écrivez un message avant l’envoi.","Escribe un mensaje antes de enviar.","Vor dem Senden eine Nachricht schreiben.","Escreva uma mensagem antes de enviar.","Scrivi un messaggio prima di inviare."],Conversation:["Conversation","Conversación","Verlauf","Conversa","Conversazione"],"Conversation underneath":["Conversation ci-dessous","Conversación debajo","Verlauf darunter","Conversa abaixo","Conversazione sottostante"],"Forwarded message":["Message transféré","Mensaje reenviado","Weitergeleitete Nachricht","Mensagem encaminhada","Messaggio inoltrato"],"Edit agent reply":["Modifier la réponse de l’agent","Editar respuesta del agente","Agentenantwort bearbeiten","Editar resposta do agente","Modifica risposta dell’agente"],"Review in writing area":["Relire dans la rédaction","Revisar en el editor","Im Schreibbereich prüfen","Revisar na área de escrita","Rivedi nell’area di scrittura"],"Review the suggestion in the writing area, or keep it waiting in Approval Inbox. Nothing is sent automatically.":["Relisez la suggestion dans la rédaction ou gardez-la dans les approbations. Rien n’est envoyé automatiquement.","Revisa la propuesta en el editor o déjala en Aprobaciones. Nada se envía automáticamente.","Vorschlag im Schreibbereich prüfen oder im Freigabeeingang behalten. Nichts wird automatisch gesendet.","Revise a sugestão na área de escrita ou mantenha em Aprovações. Nada é enviado automaticamente.","Rivedi il suggerimento nell’editor o lascialo nelle Approvazioni. Nulla viene inviato automaticamente."],Hello:["Bonjour","Hola","Hallo","Olá","Ciao"],"Thank you for your message. I have read it and would be happy to help.":["Merci pour votre message. Je l’ai lu et serai ravi de vous aider.","Gracias por tu mensaje. Lo he leído y estaré encantado de ayudar.","Vielen Dank für Ihre Nachricht. Ich habe sie gelesen und helfe Ihnen gerne.","Obrigado pela mensagem. Eu a li e ficarei feliz em ajudar.","Grazie per il messaggio. L’ho letto e sarò felice di aiutarti."],"Could you share the brief, budget and dates you have in mind?":["Pourriez-vous préciser le brief, le budget et les dates envisagées ?","¿Puedes compartir el brief, el presupuesto y las fechas previstas?","Könnten Sie Briefing, Budget und geplante Termine nennen?","Você pode compartilhar o briefing, orçamento e datas previstas?","Puoi condividere il brief, il budget e le date previste?"],"Could you share the details and preferred next steps?":["Pourriez-vous préciser les détails et les prochaines étapes souhaitées ?","¿Puedes compartir los detalles y los próximos pasos deseados?","Könnten Sie Details und gewünschte nächste Schritte nennen?","Você pode compartilhar os detalhes e próximos passos desejados?","Puoi condividere i dettagli e i prossimi passi desiderati?"],"Best regards":["Cordialement","Un saludo","Mit freundlichen Grüßen","Atenciosamente","Cordiali saluti"],"Your Laboratorio team":["Votre équipe Laboratorio","Tu equipo Laboratorio","Ihr Laboratorio-Team","Sua equipe Laboratorio","Il tuo team Laboratorio"],"Reply to":["Réponse à","Respuesta a","Antwort an","Resposta a","Risposta a"],"Mark as read":["Marquer comme lu","Marcar como leído","Als gelesen markieren","Marcar como lido","Segna come letto"],"Mark as unread":["Marquer comme non lu","Marcar como no leído","Als ungelesen markieren","Marcar como não lido","Segna come non letto"],"Mark as needing attention":["Marquer comme à traiter","Marcar para atender","Als offen markieren","Marcar para atenção","Segna come da gestire"],"Marked as read.":["Marqué comme lu.","Marcado como leído.","Als gelesen markiert.","Marcado como lido.","Segnato come letto."],"Marked as unread.":["Marqué comme non lu.","Marcado como no leído.","Als ungelesen markiert.","Marcado como não lido.","Segnato come non letto."],Star:["Favori","Destacar","Markieren","Destacar","Aggiungi stella"],Unstar:["Retirer des favoris","Quitar destacado","Markierung entfernen","Remover destaque","Rimuovi stella"],Starred:["Favoris","Destacados","Markiert","Com estrela","Speciali"],"Starred.":["Ajouté aux favoris.","Destacado.","Markiert.","Destacado.","Stella aggiunta."],"Star removed.":["Retiré des favoris.","Destacado quitado.","Markierung entfernt.","Destaque removido.","Stella rimossa."],Archive:["Archiver","Archivar","Archivieren","Arquivar","Archivia"],Archived:["Archives","Archivados","Archiviert","Arquivados","Archiviata"],"Archived.":["Archivé.","Archivado.","Archiviert.","Arquivado.","Archiviata."],Trash:["Corbeille","Papelera","Papierkorb","Lixeira","Cestino"],"Moved to Trash.":["Déplacé dans la corbeille.","Movido a la papelera.","In den Papierkorb verschoben.","Movido para a lixeira.","Spostata nel cestino."],Undo:["Annuler","Deshacer","Rückgängig","Desfazer","Annulla"],"Action undone.":["Action annulée.","Acción deshecha.","Aktion rückgängig gemacht.","Ação desfeita.","Azione annullata."],"Select email":["Sélectionner l’e-mail","Seleccionar correo","E-Mail auswählen","Selecionar e-mail","Seleziona email"],"Select all in this view":["Tout sélectionner dans cette vue","Seleccionar todo en esta vista","Alle in dieser Ansicht auswählen","Selecionar tudo nesta vista","Seleziona tutto in questa vista"],"Selected mail actions":["Actions sur la sélection","Acciones de selección","Aktionen für Auswahl","Ações da seleção","Azioni sulla selezione"],"Move selection to category":["Déplacer la sélection","Mover selección a categoría","Auswahl in Kategorie verschieben","Mover seleção para categoria","Sposta selezione in categoria"],selected:["sélectionnés","seleccionados","ausgewählt","selecionados","selezionati"],"MAIL FOLDERS":["DOSSIERS DE COURRIER","CARPETAS DE CORREO","E-MAIL-ORDNER","PASTAS DE CORREIO","CARTELLE DI POSTA"],Drafts:["Brouillons","Borradores","Entwürfe","Rascunhos","Bozze"],"Delete draft":["Supprimer le brouillon","Eliminar borrador","Entwurf löschen","Excluir rascunho","Elimina bozza"],"No recipient yet":["Aucun destinataire","Sin destinatario","Noch kein Empfänger","Sem destinatário","Nessun destinatario"],"No subject yet":["Aucun objet","Sin asunto","Noch kein Betreff","Sem assunto","Nessun oggetto"],"Continue writing your message.":["Continuez votre message.","Continúa escribiendo tu mensaje.","Schreiben Sie Ihre Nachricht weiter.","Continue escrevendo sua mensagem.","Continua a scrivere il messaggio."],"No unfinished emails":["Aucun e-mail inachevé","No hay correos pendientes","Keine unfertigen E-Mails","Nenhum e-mail inacabado","Nessuna email incompleta"],"Messages you save or close while writing will wait here.":["Les messages enregistrés ou fermés pendant la rédaction vous attendront ici.","Los mensajes guardados o cerrados mientras escribes te esperan aquí.","Gespeicherte oder beim Schreiben geschlossene Nachrichten warten hier.","Mensagens salvas ou fechadas durante a escrita ficam aqui.","I messaggi salvati o chiusi durante la scrittura ti aspettano qui."],"Your next email starts here":["Votre prochain e-mail commence ici","Tu próximo correo empieza aquí","Ihre nächste E-Mail beginnt hier","Seu próximo e-mail começa aqui","La tua prossima email inizia qui"],"Messages sent from Laboratorio or Gmail will appear in Sent.":["Les messages envoyés depuis Laboratorio ou Gmail apparaîtront dans Envoyés.","Los mensajes enviados desde Laboratorio o Gmail aparecerán en Enviados.","Von Laboratorio oder Gmail gesendete Nachrichten erscheinen unter Gesendet.","Mensagens enviadas pelo Laboratorio ou Gmail aparecerão em Enviados.","I messaggi inviati da Laboratorio o Gmail appariranno nella Posta inviata."],"No starred mail":["Aucun favori","No hay correos destacados","Keine markierten E-Mails","Nenhum e-mail com estrela","Nessuna email speciale"],"Star important emails to keep them close.":["Ajoutez les e-mails importants aux favoris pour les retrouver vite.","Destaca los correos importantes para tenerlos a mano.","Wichtige E-Mails markieren, um sie griffbereit zu halten.","Destaque e-mails importantes para mantê-los por perto.","Aggiungi una stella alle email importanti per ritrovarle."],"Sent message removed from this preview.":["Message envoyé retiré de cet aperçu.","Mensaje enviado eliminado de esta vista previa.","Gesendete Nachricht aus der Vorschau entfernt.","Mensagem enviada removida desta prévia.","Messaggio inviato rimosso dall’anteprima."],"Your writing desk":["Votre espace de rédaction","Tu espacio de escritura","Ihr Schreibplatz","Seu espaço de escrita","Il tuo spazio di scrittura"],"Your draft stays safe when you close this window.":["Votre brouillon est conservé lorsque vous fermez cette fenêtre.","Tu borrador se conserva al cerrar esta ventana.","Ihr Entwurf bleibt beim Schließen dieses Fensters erhalten.","Seu rascunho fica seguro ao fechar esta janela.","La bozza rimane al sicuro quando chiudi questa finestra."],"SENT EMAIL":["E-MAIL ENVOYÉ","CORREO ENVIADO","GESENDETE E-MAIL","E-MAIL ENVIADO","EMAIL INVIATA"],"Preview states":["États de l’aperçu","Estados de prueba","Vorschauzustände","Estados da prévia","Stati dell’anteprima"],"Fail the next send":["Simuler un échec d’envoi","Simular fallo del próximo envío","Nächsten Versand fehlschlagen lassen","Simular falha no próximo envio","Simula errore al prossimo invio"],"Fail the next Gmail action":["Simuler un échec Gmail","Simular fallo de la próxima acción Gmail","Nächste Gmail-Aktion fehlschlagen lassen","Simular falha na próxima ação Gmail","Simula errore alla prossima azione Gmail"],"Sample state controls, no real mailbox is contacted.":["Contrôles fictifs, aucune boîte réelle n’est contactée.","Controles de prueba, no se contacta ninguna cuenta real.","Beispielzustände, kein echtes Postfach wird kontaktiert.","Controles de exemplo, nenhuma caixa real é acessada.","Controlli di esempio, nessuna casella reale viene contattata."],"Could not update Gmail: the sample connection expired. Your mail is unchanged. Try the action again.":["Mise à jour Gmail impossible : la connexion fictive a expiré. Vos e-mails sont intacts. Réessayez.","No se pudo actualizar Gmail: la conexión de ejemplo expiró. Tu correo no cambió. Reintenta la acción.","Gmail konnte nicht aktualisiert werden: Beispielverbindung abgelaufen. Ihre E-Mails sind unverändert. Aktion erneut versuchen.","Falha ao atualizar o Gmail: a conexão de exemplo expirou. Seus e-mails não mudaram. Tente a ação novamente.","Aggiornamento Gmail fallito: la connessione di esempio è scaduta. La posta è invariata. Riprova."],"Open Mail":["Ouvrir le courrier","Abrir Correo","E-Mail öffnen","Abrir Correio","Apri Posta"],"Preview unread mail":["Aperçu des e-mails non lus","Vista de correos no leídos","Ungelesene E-Mails ansehen","Prévia dos e-mails não lidos","Anteprima email non lette"],"Unread mail":["E-mails non lus","Correo no leído","Ungelesene E-Mails","E-mails não lidos","Email non lette"],"No unread mail":["Aucun e-mail non lu","No hay correos no leídos","Keine ungelesenen E-Mails","Nenhum e-mail não lido","Nessuna email non letta"],"Your inbox is up to date.":["Votre boîte est à jour.","Tu bandeja está al día.","Ihr Posteingang ist aktuell.","Sua caixa está em dia.","La tua casella è aggiornata."],"Close preview":["Fermer l’aperçu","Cerrar vista previa","Vorschau schließen","Fechar prévia","Chiudi anteprima"],unseen:["non vus","sin ver","ungesehen","não vistos","non viste"],"All caught up":["Tout est à jour","Todo al día","Alles erledigt","Tudo em dia","Tutto aggiornato"],"Quiet hours active":["Heures calmes actives","Horario silencioso activo","Ruhezeiten aktiv","Horário silencioso ativo","Ore silenziose attive"],"Close notifications":["Fermer les notifications","Cerrar notificaciones","Benachrichtigungen schließen","Fechar notificações","Chiudi notifiche"],"Filter notifications by kind":["Filtrer les notifications par type","Filtrar por tipo","Nach Art filtern","Filtrar notificações por tipo","Filtra notifiche per tipo"],"Mark all as seen":["Tout marquer comme vu","Marcar todo como visto","Alle als gesehen markieren","Marcar todas como vistas","Segna tutte come viste"],Seen:["Vu","Visto","Gesehen","Vista","Vista"],"Nothing new":["Rien de nouveau","Nada nuevo","Nichts Neues","Nada novo","Niente di nuovo"],"Updates from your inbox and team will appear here.":["Les nouvelles de votre boîte et de votre équipe apparaîtront ici.","Las novedades de tu correo y equipo aparecerán aquí.","Neuigkeiten aus Posteingang und Team erscheinen hier.","Novidades da caixa e equipe aparecerão aqui.","Gli aggiornamenti di posta e team appariranno qui."],"Clear seen notifications":["Effacer les notifications vues","Borrar notificaciones vistas","Gesehene Meldungen entfernen","Limpar notificações vistas","Cancella notifiche viste"],"Notification choices":["Choix des notifications","Preferencias de notificación","Benachrichtigungsoptionen","Preferências de notificação","Preferenze delle notifiche"],"Choose what reaches you, and when.":["Choisissez ce qui vous parvient et quand.","Elige qué recibes y cuándo.","Wählen Sie, was Sie erreicht und wann.","Escolha o que recebe e quando.","Scegli cosa ricevere e quando."],"Which updates notify you":["Quels événements vous alertent","Qué novedades te notifican","Welche Updates Sie benachrichtigen","Quais atualizações notificam você","Quali aggiornamenti ti notificano"],"Where alerts arrive":["Où recevoir les alertes","Dónde llegan los avisos","Wo Hinweise ankommen","Onde os alertas chegam","Dove arrivano gli avvisi"],"Email alerts also follow the choices in each Mail category. These choices affect future alerts, not your existing history.":["Les alertes de courrier suivent aussi les choix de chaque catégorie. Ces choix concernent les futures alertes, pas l’historique.","Los avisos de correo siguen cada categoría. Estas preferencias afectan avisos futuros, no el historial existente.","E-Mail-Hinweise folgen auch den Kategorien. Diese Optionen gelten für künftige Hinweise, nicht den bisherigen Verlauf.","Alertas de e-mail seguem cada categoria. As escolhas afetam alertas futuros, não o histórico atual.","Gli avvisi email seguono anche le categorie. Le preferenze valgono per avvisi futuri, non per la cronologia esistente."],"Add Laboratorio to your phone home screen to receive phone alerts after the backend is connected.":["Ajoutez Laboratorio à l’écran d’accueil du téléphone pour recevoir les alertes une fois le backend connecté.","Añade Laboratorio a la pantalla de inicio para recibir avisos al conectar el backend.","Laboratorio zum Startbildschirm hinzufügen, um nach der Backend-Anbindung Hinweise zu erhalten.","Adicione Laboratorio à tela inicial para receber alertas após conectar o backend.","Aggiungi Laboratorio alla schermata iniziale per ricevere avvisi dopo il collegamento al backend."],"Alert delivery is a frontend preview. Nothing buzzes or sends a Telegram message yet.":["Les alertes sont un aperçu. Aucune vibration ni aucun message Telegram n’est envoyé.","Los avisos son una vista previa. Aún no hay vibraciones ni mensajes de Telegram.","Hinweise sind eine Frontend-Vorschau. Noch keine Vibration oder Telegram-Nachricht.","Alertas são uma prévia. Nada vibra ou envia mensagens no Telegram ainda.","Gli avvisi sono un’anteprima. Nessuna vibrazione o messaggio Telegram viene inviato."],Email:["E-mail","Correo","E-Mail","E-mail","Email"],Approval:["Approbation","Aprobación","Freigabe","Aprovação","Approvazione"],Mission:["Mission","Misión","Mission","Missão","Missione"],Automation:["Automatisation","Automatización","Automatisierung","Automação","Automazione"],Backup:["Sauvegarde","Copia de seguridad","Sicherung","Backup","Backup"],"Agent error":["Erreur d’agent","Error del agente","Agentenfehler","Erro do agente","Errore dell’agente"],"Automation needs attention":["Automatisation à vérifier","Automatización requiere atención","Automatisierung benötigt Hilfe","Automação precisa de atenção","Automazione da controllare"],"Automation completed":["Automatisation terminée","Automatización completada","Automatisierung abgeschlossen","Automação concluída","Automazione completata"],"Scheduled job finished":["Tâche programmée terminée","Trabajo programado completado","Geplanter Job abgeschlossen","Tarefa agendada concluída","Processo pianificato completato"],"Scheduled job failed":["Échec d’une tâche programmée","Falló el trabajo programado","Geplanter Job fehlgeschlagen","Tarefa agendada falhou","Processo pianificato fallito"],"Team backup made":["Équipe sauvegardée","Copia del equipo creada","Teamsicherung erstellt","Backup da equipe criado","Backup del team creato"],"Backup needs attention":["Sauvegarde à vérifier","Copia requiere atención","Sicherung benötigt Hilfe","Backup precisa de atenção","Backup da controllare"],"An agent needs your help":["Un agent a besoin d’aide","Un agente necesita ayuda","Ein Agent braucht Ihre Hilfe","Um agente precisa de ajuda","Un agente ha bisogno di aiuto"],"Mission plan ready":["Plan de mission prêt","Plan de misión listo","Missionsplan bereit","Plano da missão pronto","Piano della missione pronto"],"Mission result ready":["Résultat de mission prêt","Resultado de misión listo","Missionsergebnis bereit","Resultado da missão pronto","Risultato della missione pronto"],"Mission needs attention":["Mission à vérifier","Misión requiere atención","Mission benötigt Hilfe","Missão precisa de atenção","Missione da controllare"],"Finish signing in":["Terminer la connexion","Completar inicio de sesión","Anmeldung abschließen","Concluir login","Completa l’accesso"],"Waiting for your approval":["En attente de votre accord","Esperando tu aprobación","Wartet auf Ihre Freigabe","Aguardando sua aprovação","In attesa della tua approvazione"],"Competitor watch could not read the watched page. Review the run and try again.":["La veille n’a pas pu lire la page. Vérifiez l’exécution et réessayez.","El monitor no pudo leer la página. Revisa la ejecución y reintenta.","Die Beobachtung konnte die Seite nicht lesen. Lauf prüfen und erneut versuchen.","O monitor não leu a página. Revise a execução e tente novamente.","Il monitoraggio non ha letto la pagina. Controlla l’esecuzione e riprova."],"The morning research brief is ready to review in the job history.":["Le brief du matin est prêt dans l’historique des tâches.","El informe de la mañana está listo en el historial.","Das Morgenbriefing ist im Jobverlauf bereit.","O resumo da manhã está pronto no histórico.","Il riepilogo mattutino è pronto nella cronologia."],"The sample data source timed out. Nothing was published.":["La source fictive n’a pas répondu à temps. Rien n’a été publié.","La fuente de prueba agotó el tiempo. Nada se publicó.","Die Beispieldatenquelle hat das Zeitlimit überschritten. Nichts veröffentlicht.","A fonte de exemplo expirou. Nada foi publicado.","La fonte di esempio è scaduta. Nulla è stato pubblicato."],"Your agents, memories and workspace were included in the sample snapshot.":["Vos agents, mémoires et espace figurent dans la sauvegarde fictive.","La copia de ejemplo incluyó agentes, memorias y espacio.","Agenten, Erinnerungen und Arbeitsbereich sind im Beispielsnapshot enthalten.","Agentes, memórias e espaço estão no backup de exemplo.","Agenti, memorie e spazio sono nel backup di esempio."],"The sample storage destination was unavailable. Your current team is intact.":["Le stockage fictif était indisponible. Votre équipe reste intacte.","El destino de prueba no estaba disponible. Tu equipo está intacto.","Beispielspeicher nicht verfügbar. Ihr Team ist unverändert.","O armazenamento de exemplo estava indisponível. Sua equipe está intacta.","Archivio di esempio non disponibile. Il team è intatto."],"Developer reached the sample model limit. Review the agent and its fallback model.":["Developer a atteint la limite du modèle fictif. Vérifiez l’agent et son modèle de secours.","Developer alcanzó el límite del modelo de prueba. Revisa el agente y su modelo alternativo.","Developer hat das Beispiellimit erreicht. Agent und Ersatzmodell prüfen.","Developer atingiu o limite do modelo de exemplo. Revise o agente e o modelo alternativo.","Developer ha raggiunto il limite del modello di esempio. Controlla l’agente e il modello alternativo."],LEGEND:["LÉGENDE","LEYENDA","LEGENDE","LEGENDA","LEGENDA"],"Dots and % show how sure Jev is of each category.":["Les points et le % montrent la certitude de Jev pour chaque catégorie.","Los puntos y el % muestran lo seguro que está Jev de cada categoría.","Punkte und % zeigen, wie sicher Jev bei jeder Kategorie ist.","Os pontos e a % mostram a certeza do Jev sobre cada categoria.","Punti e % mostrano quanto Jev è sicuro di ogni categoria."],"Jev is sure of this category":["Certitude de Jev pour cette catégorie","Seguridad de Jev sobre esta categoría","So sicher ist Jev bei dieser Kategorie","Certeza do Jev sobre esta categoria","Sicurezza di Jev su questa categoria"],"The shaded dots and the number show how sure Jev is of each email’s category.":["Les points remplis et le chiffre indiquent à quel point Jev est sûr de la catégorie de chaque e-mail.","Los puntos sombreados y el número muestran lo seguro que está Jev de la categoría de cada email.","Die gefüllten Punkte und die Zahl zeigen, wie sicher Jev bei der Kategorie jeder E-Mail ist.","Os pontos preenchidos e o número mostram o quanto o Jev tem certeza da categoria de cada e-mail.","I punti pieni e il numero mostrano quanto Jev è sicuro della categoria di ogni email."],"Worth checking":["À vérifier","Para revisar","Prüfenswert","Vale conferir","Da controllare"],"messages in this conversation":["messages dans cette conversation","mensajes en esta conversación","Nachrichten in diesem Gespräch","mensagens nesta conversa","messaggi in questa conversazione"],"Emails Jev was less than 70% sure about":["E-mails dont Jev était sûr à moins de 70 %","Emails de los que Jev estaba seguro en menos del 70 %","E-Mails, bei denen Jev zu weniger als 70 % sicher war","E-mails em que o Jev tinha menos de 70% de certeza","Email su cui Jev era sicuro meno del 70%"],"Could also be":["Pourrait aussi être","También podría ser","Könnte auch sein","Também pode ser","Potrebbe anche essere"],Keep:["Garder","Mantener","Behalten","Manter","Mantieni"],"Move to":["Déplacer vers","Mover a","Verschieben nach","Mover para","Sposta in"],"Kept. Laboratorio will learn from this.":["Conservé. Laboratorio en tiendra compte.","Mantenido. Laboratorio aprenderá de esto.","Behalten. Laboratorio lernt daraus.","Mantido. O Laboratorio vai aprender com isso.","Mantenuto. Laboratorio imparerà da questo."],"Mark as addressed":["Marquer comme traité","Marcar como atendido","Als erledigt markieren","Marcar como resolvido","Segna come gestita"],"Mark as not addressed":["Marquer comme non traité","Marcar como no atendido","Als nicht erledigt markieren","Marcar como não resolvido","Segna come non gestita"],"Marked as addressed.":["Marqué comme traité.","Marcado como atendido.","Als erledigt markiert.","Marcado como resolvido.","Segnata come gestita."],"Marked as not addressed.":["Marqué comme non traité.","Marcado como no atendido.","Als nicht erledigt markiert.","Marcado como não resolvido.","Segnata come non gestita."],Addressed:["Traité","Atendido","Erledigt","Resolvido","Gestita"],"Mark emails as read in Gmail when I open them here":["Marquer les e-mails comme lus dans Gmail quand je les ouvre ici","Marcar los emails como leídos en Gmail al abrirlos aquí","E-Mails in Gmail als gelesen markieren, wenn ich sie hier öffne","Marcar e-mails como lidos no Gmail quando eu os abrir aqui","Segna le email come lette in Gmail quando le apro qui"],"Off: Laboratorio never changes anything in Gmail apart from labels you switch on.":["Désactivé : Laboratorio ne modifie rien dans Gmail, sauf les libellés que vous activez.","Desactivado: Laboratorio no cambia nada en Gmail salvo las etiquetas que actives.","Aus: Laboratorio ändert in Gmail nichts außer den Labels, die Sie einschalten.","Desligado: o Laboratorio não muda nada no Gmail além dos marcadores que você ativar.","Disattivato: Laboratorio non cambia nulla in Gmail tranne le etichette che attivi."],"Jev sorts your email. About $0.00002 an email.":["Jev trie vos e-mails. Environ 0,00002 $ par e-mail.","Jev clasifica tus emails. Unos 0,00002 $ por email.","Jev sortiert Ihre E-Mails. Etwa 0,00002 $ pro E-Mail.","O Jev classifica seus e-mails. Cerca de US$ 0,00002 por e-mail.","Jev ordina le tue email. Circa 0,00002 $ per email."],"Staying in step with Gmail":["Rester en phase avec Gmail","Al día con Gmail","Im Einklang mit Gmail","Em sintonia com o Gmail","In sintonia con Gmail"],"Check Gmail for new mail every":["Vérifier les nouveaux e-mails Gmail toutes les","Buscar correo nuevo en Gmail cada","Gmail auf neue E-Mails prüfen alle","Verificar novos e-mails no Gmail a cada","Controlla la nuova posta Gmail ogni"],minutes:["minutes","minutos","Minuten","minutos","minuti"],"New mail is sorted on its own. Deletions and read changes made in Gmail follow every":["Le nouveau courrier est trié automatiquement. Les suppressions et changements de lecture faits dans Gmail suivent toutes les","El correo nuevo se clasifica solo. Los borrados y cambios de lectura hechos en Gmail se aplican cada","Neue E-Mails werden von selbst sortiert. Löschungen und Lesestatus-Änderungen in Gmail folgen alle","O correio novo é classificado sozinho. Exclusões e mudanças de leitura feitas no Gmail acompanham a cada","La nuova posta viene ordinata da sola. Eliminazioni e cambi di lettura fatti in Gmail seguono ogni"],"Last new mail sorted":["Dernier nouvel e-mail trié","Último correo nuevo clasificado","Zuletzt neue E-Mail sortiert","Último e-mail novo classificado","Ultima nuova email ordinata"],"Every new email, and every email from the period above, is downloaded in full with its conversation, so it opens at once. Attachments stay in Gmail until you open them. Mail older than the keep time leaves Laboratorio only: Gmail stays your real mailbox, and Laboratorio never deletes or moves anything there.":["Chaque nouvel e-mail, et chaque e-mail de la période ci-dessus, est téléchargé en entier avec sa conversation, pour s’ouvrir aussitôt. Les pièces jointes restent dans Gmail jusqu’à ce que vous les ouvriez. Le courrier plus ancien que la durée de conservation quitte seulement Laboratorio : Gmail reste votre vraie boîte, et Laboratorio n’y supprime ni ne déplace rien.","Cada correo nuevo, y cada correo del periodo anterior, se descarga completo con su conversación, para abrirse al instante. Los adjuntos se quedan en Gmail hasta que los abras. El correo más antiguo que el tiempo de conservación solo sale de Laboratorio: Gmail sigue siendo tu buzón real y Laboratorio nunca borra ni mueve nada allí.","Jede neue E-Mail und jede E-Mail aus dem Zeitraum oben wird vollständig mit ihrer Unterhaltung geladen und öffnet sich sofort. Anhänge bleiben in Gmail, bis Sie sie öffnen. Ältere E-Mails als die Aufbewahrungszeit verlassen nur Laboratorio: Gmail bleibt Ihr echtes Postfach, und Laboratorio löscht oder verschiebt dort nie etwas.","Cada novo e-mail, e cada e-mail do período acima, é baixado por inteiro com a conversa, para abrir na hora. Os anexos ficam no Gmail até você abri-los. O correio mais antigo que o tempo de guarda sai apenas do Laboratorio: o Gmail continua sendo sua caixa real, e o Laboratorio nunca apaga nem move nada lá.","Ogni nuova email, e ogni email del periodo sopra, viene scaricata per intero con la sua conversazione, così si apre subito. Gli allegati restano in Gmail finché non li apri. La posta più vecchia del tempo di conservazione lascia solo Laboratorio: Gmail resta la tua vera casella, e Laboratorio non elimina né sposta mai nulla lì."],"Keep mail for":["Conserver le courrier pendant","Conservar el correo durante","E-Mails behalten für","Guardar o correio por","Conserva la posta per"],"Download past mail from the last":["Télécharger le courrier des derniers","Descargar el correo de los últimos","Frühere E-Mails laden aus den letzten","Baixar o correio dos últimos","Scarica la posta degli ultimi"],"30 days":["30 jours","30 días","30 Tage","30 dias","30 giorni"],"90 days":["90 jours","90 días","90 Tage","90 dias","90 giorni"],"6 months":["6 mois","6 meses","6 Monate","6 meses","6 mesi"],"1 year":["1 an","1 año","1 Jahr","1 ano","1 anno"],Everything:["Tout","Todo","Alles","Tudo","Tutto"],"Last checked with Gmail":["Dernière vérification avec Gmail","Última comprobación con Gmail","Zuletzt mit Gmail abgeglichen","Última verificação com o Gmail","Ultimo controllo con Gmail"],removed:["retirés","quitados","entfernt","removidos","rimossi"],"read changes":["changements de lecture","cambios de lectura","Lesestatus-Änderungen","mudanças de leitura","cambi di lettura"],"Mail will sort":["Courrier triera","Correo clasificará","E-Mail sortiert","O Correio vai classificar","Posta ordinerà"],"You have more than one Gmail account. Which inbox should Laboratorio sort?":["Vous avez plusieurs comptes Gmail. Quelle boîte Laboratorio doit-il trier ?","Tienes más de una cuenta de Gmail. ¿Qué bandeja debe clasificar Laboratorio?","Sie haben mehr als ein Gmail-Konto. Welchen Posteingang soll Laboratorio sortieren?","Você tem mais de uma conta do Gmail. Qual caixa o Laboratorio deve classificar?","Hai più di un account Gmail. Quale casella deve ordinare Laboratorio?"],"Fast: about 45 emails a second":["Rapide : environ 45 e-mails par seconde","Rápida: unos 45 emails por segundo","Schnell: etwa 45 E-Mails pro Sekunde","Rápida: cerca de 45 e-mails por segundo","Veloce: circa 45 email al secondo"],"About 5 emails a second":["Environ 5 e-mails par seconde","Unos 5 emails por segundo","Etwa 5 E-Mails pro Sekunde","Cerca de 5 e-mails por segundo","Circa 5 email al secondo"],"Checking your Gmail accounts...":["Vérification de vos comptes Gmail...","Comprobando tus cuentas de Gmail...","Ihre Gmail-Konten werden geprüft...","Verificando suas contas do Gmail...","Verifica dei tuoi account Gmail..."],"Switch inbox":["Changer de boîte","Cambiar de bandeja","Posteingang wechseln","Trocar de caixa","Cambia casella"],"Another inbox gets its own categories and sorting. The current categories, sorted mail and corrections are cleared; nothing changes in Gmail.":["Une autre boîte a ses propres catégories et son propre tri. Les catégories, le courrier trié et les corrections actuels sont effacés ; rien ne change dans Gmail.","Otra bandeja tiene sus propias categorías y clasificación. Se borran las categorías, el correo clasificado y las correcciones actuales; nada cambia en Gmail.","Ein anderer Posteingang bekommt eigene Kategorien und Sortierung. Die aktuellen Kategorien, sortierten E-Mails und Korrekturen werden gelöscht; in Gmail ändert sich nichts.","Outra caixa tem suas próprias categorias e classificação. As categorias, o correio classificado e as correções atuais são apagados; nada muda no Gmail.","Un’altra casella ha categorie e ordinamento propri. Categorie, posta ordinata e correzioni attuali vengono cancellate; in Gmail non cambia nulla."],"Sort this inbox instead":["Trier plutôt cette boîte","Clasificar esta bandeja en su lugar","Stattdessen diesen Posteingang sortieren","Classificar esta caixa em vez disso","Ordina invece questa casella"],"Mail sorts your email with Jev, using the Jev key from Jev routing above. About $0.00002 an email.":["Courrier trie vos e-mails avec Jev, grâce à la clé Jev du routage Jev ci-dessus. Environ 0,00002 $ par e-mail.","Correo clasifica tus emails con Jev, usando la clave de Jev del enrutamiento Jev de arriba. Unos 0,00002 $ por email.","E-Mail sortiert Ihre Nachrichten mit Jev und nutzt den Jev-Schlüssel aus dem Jev-Routing oben. Etwa 0,00002 $ pro E-Mail.","O Correio classifica seus e-mails com Jev, usando a chave Jev do roteamento Jev acima. Cerca de US$ 0,00002 por e-mail.","Posta ordina le tue email con Jev, usando la chiave Jev del routing Jev qui sopra. Circa 0,00002 $ per email."],"Sender, subject and the start of each email go to Jev for sorting.":["L’expéditeur, l’objet et le début de chaque e-mail partent vers Jev pour le tri.","El remitente, el asunto y el comienzo de cada email van a Jev para clasificarlo.","Absender, Betreff und der Anfang jeder E-Mail gehen zum Sortieren an Jev.","Remetente, assunto e início de cada e-mail vão para o Jev para a classificação.","Mittente, oggetto e inizio di ogni email vanno a Jev per l’ordinamento."],"Start with the two connections your inbox needs: Gmail, and a Jev key for sorting.":["Commencez par les deux connexions dont votre boîte a besoin : Gmail et une clé Jev pour le tri.","Empieza con las dos conexiones que necesita tu bandeja: Gmail y una clave de Jev para clasificar.","Beginnen Sie mit den zwei Verbindungen, die Ihr Posteingang braucht: Gmail und ein Jev-Schlüssel zum Sortieren.","Comece pelas duas conexões de que sua caixa precisa: o Gmail e uma chave Jev para a classificação.","Inizia dai due collegamenti che servono alla tua posta: Gmail e una chiave Jev per l’ordinamento."],"Jev key is set":["La clé Jev est enregistrée","La clave de Jev está guardada","Der Jev-Schlüssel ist gespeichert","A chave Jev está definida","La chiave Jev è impostata"],"Sorting needs a Jev key":["Le tri a besoin d’une clé Jev","La clasificación necesita una clave de Jev","Zum Sortieren braucht es einen Jev-Schlüssel","A classificação precisa de uma chave Jev","L’ordinamento richiede una chiave Jev"],"Sorting runs through":["Le tri passe par","La clasificación funciona a través de","Sortiert wird über","A classificação passa por","L’ordinamento passa da"],"Paste your Jev key here, from OpenRouter or TypeSafe. Sorting costs about two cents a month.":["Collez ici votre clé Jev, d’OpenRouter ou de TypeSafe. Le tri coûte environ deux centimes par mois.","Pega aquí tu clave de Jev, de OpenRouter o de TypeSafe. Clasificar cuesta unos dos céntimos al mes.","Fügen Sie hier Ihren Jev-Schlüssel von OpenRouter oder TypeSafe ein. Das Sortieren kostet etwa zwei Cent im Monat.","Cole aqui sua chave Jev, do OpenRouter ou da TypeSafe. A classificação custa cerca de dois centavos por mês.","Incolla qui la tua chiave Jev, da OpenRouter o TypeSafe. L’ordinamento costa circa due centesimi al mese."],"Paste your Jev key":["Collez votre clé Jev","Pega tu clave de Jev","Jev-Schlüssel einfügen","Cole sua chave Jev","Incolla la tua chiave Jev"],"OpenRouter or TypeSafe key":["Clé OpenRouter ou TypeSafe","Clave de OpenRouter o TypeSafe","Schlüssel von OpenRouter oder TypeSafe","Chave do OpenRouter ou da TypeSafe","Chiave OpenRouter o TypeSafe"],"No key yet? Create one at openrouter.ai/keys or console.typesafe.ai/keys. It is also used for Jev routing in Settings.":["Pas encore de clé ? Créez-en une sur openrouter.ai/keys ou console.typesafe.ai/keys. Elle sert aussi au routage Jev dans Paramètres.","¿Aún sin clave? Crea una en openrouter.ai/keys o console.typesafe.ai/keys. También se usa para el enrutamiento Jev en Ajustes.","Noch kein Schlüssel? Erstellen Sie einen unter openrouter.ai/keys oder console.typesafe.ai/keys. Er wird auch für das Jev-Routing in den Einstellungen genutzt.","Ainda sem chave? Crie uma em openrouter.ai/keys ou console.typesafe.ai/keys. Ela também é usada no roteamento Jev em Configurações.","Nessuna chiave? Creane una su openrouter.ai/keys o console.typesafe.ai/keys. Serve anche per il routing Jev in Impostazioni."],"Sorting sends the sender, subject and start of each email to Jev, through OpenRouter or TypeSafe, whichever your key is from. Finding categories shows your Orchestrator the same for up to 250 recent emails. Attachments and whole threads never leave this computer.":["Le tri envoie l’expéditeur, l’objet et le début de chaque e-mail à Jev, via OpenRouter ou TypeSafe selon l’origine de votre clé. Pour trouver les catégories, votre Orchestrateur voit la même chose pour au plus 250 e-mails récents. Les pièces jointes et les fils entiers ne quittent jamais cet ordinateur.","La clasificación envía a Jev el remitente, el asunto y el comienzo de cada email, a través de OpenRouter o TypeSafe según de dónde sea tu clave. Para encontrar las categorías, tu Orquestador ve lo mismo de hasta 250 emails recientes. Los adjuntos y los hilos completos nunca salen de este ordenador.","Beim Sortieren gehen Absender, Betreff und der Anfang jeder E-Mail an Jev, über OpenRouter oder TypeSafe, je nachdem, woher Ihr Schlüssel stammt. Zum Finden der Kategorien sieht Ihr Orchestrator dasselbe von bis zu 250 aktuellen E-Mails. Anhänge und ganze Verläufe verlassen diesen Computer nie.","A classificação envia ao Jev o remetente, o assunto e o início de cada e-mail, pelo OpenRouter ou pela TypeSafe, conforme a origem da sua chave. Para encontrar as categorias, seu Orquestrador vê o mesmo de até 250 e-mails recentes. Anexos e conversas inteiras nunca saem deste computador.","L’ordinamento invia a Jev mittente, oggetto e inizio di ogni email, tramite OpenRouter o TypeSafe a seconda della tua chiave. Per trovare le categorie, il tuo Orchestratore vede lo stesso per al massimo 250 email recenti. Allegati e conversazioni intere non lasciano mai questo computer."],"emails read from Gmail":["e-mails lus depuis Gmail","emails leídos de Gmail","E-Mails aus Gmail gelesen","e-mails lidos do Gmail","email lette da Gmail"],"Starting...":["Démarrage...","Iniciando...","Wird gestartet...","Iniciando...","Avvio in corso..."],"What is happening":["Ce qui se passe","Qué está pasando","Was gerade passiert","O que está acontecendo","Cosa sta succedendo"],"Show what happened":["Voir ce qui s’est passé","Ver qué pasó","Anzeigen, was passiert ist","Ver o que aconteceu","Mostra cosa è successo"],"emails read. Your Orchestrator is proposing categories.":["e-mails lus. Votre Orchestrateur propose des catégories.","emails leídos. Tu Orquestador está proponiendo categorías.","E-Mails gelesen. Ihr Orchestrator schlägt Kategorien vor.","e-mails lidos. Seu Orquestrador está propondo categorias.","email lette. Il tuo Orchestratore sta proponendo le categorie."],"emails collected so far":["e-mails récupérés jusqu’ici","emails recopilados hasta ahora","E-Mails bisher abgerufen","e-mails coletados até agora","email raccolte finora"],"recent emails read":["e-mails récents lus","emails recientes leídos","aktuelle E-Mails gelesen","e-mails recentes lidos","email recenti lette"],"Laboratorio reads your mail through it and never sends anything on its own.":["Laboratorio lit votre courrier par ce biais et n’envoie jamais rien de lui-même.","Laboratorio lee tu correo a través de él y nunca envía nada por su cuenta.","Laboratorio liest darüber Ihre E-Mails und versendet nie etwas von sich aus.","O Laboratorio lê seu correio por meio dele e nunca envia nada por conta própria.","Laboratorio legge la tua posta tramite Gmail e non invia mai nulla da solo."],"Key saved. Mail can sort now.":["Clé enregistrée. Courrier peut trier maintenant.","Clave guardada. Correo ya puede clasificar.","Schlüssel gespeichert. E-Mail kann jetzt sortieren.","Chave salva. O Correio já pode classificar.","Chiave salvata. Posta ora può ordinare."],"Paste your OpenRouter key here. Sorting costs about two cents a month.":["Collez votre clé OpenRouter ici. Le tri coûte environ deux centimes par mois.","Pega aquí tu clave de OpenRouter. Clasificar cuesta unos dos céntimos al mes.","Fügen Sie hier Ihren OpenRouter-Schlüssel ein. Das Sortieren kostet etwa zwei Cent im Monat.","Cole aqui sua chave OpenRouter. A classificação custa cerca de dois centavos por mês.","Incolla qui la tua chiave OpenRouter. L’ordinamento costa circa due centesimi al mese."],"Paste your OpenRouter key":["Collez votre clé OpenRouter","Pega tu clave de OpenRouter","OpenRouter-Schlüssel einfügen","Cole sua chave OpenRouter","Incolla la tua chiave OpenRouter"],"Checking the key...":["Vérification de la clé...","Comprobando la clave...","Schlüssel wird geprüft...","Verificando a chave...","Verifica della chiave..."],"Save key":["Enregistrer la clé","Guardar clave","Schlüssel speichern","Salvar chave","Salva chiave"],"No key yet? Create one at openrouter.ai/keys. It is also used for Jev routing in Settings.":["Pas encore de clé ? Créez-en une sur openrouter.ai/keys. Elle sert aussi au routage Jev dans Paramètres.","¿Aún sin clave? Crea una en openrouter.ai/keys. También se usa para el enrutamiento Jev en Ajustes.","Noch kein Schlüssel? Erstellen Sie einen unter openrouter.ai/keys. Er wird auch für das Jev-Routing in den Einstellungen genutzt.","Ainda sem chave? Crie uma em openrouter.ai/keys. Ela também é usada no roteamento Jev em Configurações.","Nessuna chiave? Creane una su openrouter.ai/keys. Serve anche per il routing Jev in Impostazioni."],"Change key":["Changer de clé","Cambiar clave","Schlüssel ändern","Trocar chave","Cambia chiave"],"Add key":["Ajouter une clé","Añadir clave","Schlüssel hinzufügen","Adicionar chave","Aggiungi chiave"],Cancel:["Annuler","Cancelar","Abbrechen","Cancelar","Annulla"],"Mail sorting":["Tri du courrier","Clasificación del correo","E-Mail-Sortierung","Classificação do correio","Ordinamento della posta"],"Mail sorts your email with Jev, using the OpenRouter key from Jev routing above. About $0.00002 an email.":["Courrier trie vos e-mails avec Jev, grâce à la clé OpenRouter du routage Jev ci-dessus. Environ 0,00002 $ par e-mail.","Correo clasifica tus emails con Jev, usando la clave de OpenRouter del enrutamiento Jev de arriba. Unos 0,00002 $ por email.","E-Mail sortiert Ihre Nachrichten mit Jev und nutzt den OpenRouter-Schlüssel aus dem Jev-Routing oben. Etwa 0,00002 $ pro E-Mail.","O Correio classifica seus e-mails com Jev, usando a chave OpenRouter do roteamento Jev acima. Cerca de US$ 0,00002 por e-mail.","Posta ordina le tue email con Jev, usando la chiave OpenRouter del routing Jev qui sopra. Circa 0,00002 $ per email."],"Key is set":["Clé enregistrée","Clave guardada","Schlüssel gespeichert","Chave definida","Chiave impostata"],"No key yet":["Pas encore de clé","Aún sin clave","Noch kein Schlüssel","Ainda sem chave","Nessuna chiave"],"Your Orchestrator’s model sorts your email. A Jev key makes it faster and cheaper: about $0.00002 an email.":["Le modèle de votre Orchestrateur trie vos e-mails. Une clé Jev rend le tri plus rapide et moins cher : environ 0,00002 $ par e-mail.","El modelo de tu Orquestador clasifica tu correo. Una clave Jev lo hace más rápido y barato: unos 0,00002 $ por correo.","Das Modell Ihres Orchestrators sortiert Ihre E-Mails. Ein Jev-Schlüssel macht es schneller und günstiger: etwa 0,00002 $ pro E-Mail.","O modelo do seu Orquestrador classifica seus e-mails. Uma chave Jev deixa mais rápido e barato: cerca de US$ 0,00002 por e-mail.","Il modello del tuo Orchestratore ordina la tua posta. Una chiave Jev lo rende più veloce ed economico: circa 0,00002 $ per email."],"Jev key (optional)":["Clé Jev (facultative)","Clave Jev (opcional)","Jev-Schlüssel (optional)","Chave Jev (opcional)","Chiave Jev (facoltativa)"],"Using your default model":["Votre modèle par défaut","Usa tu modelo predeterminado","Ihr Standardmodell","Usando seu modelo padrão","Usa il tuo modello predefinito"],Optional:["Facultatif","Opcional","Optional","Opcional","Facoltativo"],"Without a key, your Orchestrator’s model sorts your mail. A Jev key from OpenRouter or TypeSafe makes it faster and cheaper: about two cents a month.":["Sans clé, le modèle de votre Orchestrateur trie votre courrier. Une clé Jev d’OpenRouter ou TypeSafe le rend plus rapide et moins cher : environ deux centimes par mois.","Sin clave, el modelo de tu Orquestador clasifica tu correo. Una clave Jev de OpenRouter o TypeSafe lo hace más rápido y barato: unos dos céntimos al mes.","Ohne Schlüssel sortiert das Modell Ihres Orchestrators Ihre E-Mails. Ein Jev-Schlüssel von OpenRouter oder TypeSafe macht es schneller und günstiger: etwa zwei Cent im Monat.","Sem chave, o modelo do seu Orquestrador classifica seu correio. Uma chave Jev da OpenRouter ou TypeSafe deixa mais rápido e barato: cerca de dois centavos por mês.","Senza chiave, il modello del tuo Orchestratore ordina la tua posta. Una chiave Jev di OpenRouter o TypeSafe lo rende più veloce ed economico: circa due centesimi al mese."],"Your model’s price":["Prix de votre modèle","Precio de tu modelo","Preis Ihres Modells","Preço do seu modelo","Prezzo del tuo modello"],"Sorted by your Orchestrator’s model, 40 emails a turn. A Jev key makes it faster and cheaper.":["Trié par le modèle de votre Orchestrateur, 40 e-mails par tour. Une clé Jev le rend plus rapide et moins cher.","Clasificado por el modelo de tu Orquestador, 40 correos por turno. Una clave Jev lo hace más rápido y barato.","Sortiert vom Modell Ihres Orchestrators, 40 E-Mails pro Durchgang. Ein Jev-Schlüssel macht es schneller und günstiger.","Classificado pelo modelo do seu Orquestrador, 40 e-mails por vez. Uma chave Jev deixa mais rápido e barato.","Ordinato dal modello del tuo Orchestratore, 40 email per turno. Una chiave Jev lo rende più veloce ed economico."],"Your mail is sorted.":["Votre courrier est trié.","Tu correo está clasificado.","Ihre E-Mails sind sortiert.","Seu correio foi classificado.","La tua posta è ordinata."],"Writing a draft. It will wait in Approval Inbox. Nothing is sent.":["Rédaction d’un brouillon. Il attendra dans les approbations. Rien n’est envoyé.","Escribiendo un borrador. Esperará en Aprobaciones. No se envía nada.","Entwurf wird geschrieben. Er wartet im Freigabeeingang. Nichts wird versendet.","Escrevendo um rascunho. Ele aguardará em Aprovações. Nada é enviado.","Bozza in scrittura. Attenderà nelle Approvazioni. Nulla viene inviato."],"Sorted by Jev":["Trié par Jev","Clasificado por Jev","Sortiert von Jev","Classificado pelo Jev","Ordinato da Jev"],"Start with the two connections your inbox needs: Gmail, and your OpenRouter key for sorting.":["Commencez par les deux connexions dont votre boîte a besoin : Gmail et votre clé OpenRouter pour le tri.","Empieza con las dos conexiones que necesita tu bandeja: Gmail y tu clave de OpenRouter para clasificar.","Beginnen Sie mit den zwei Verbindungen, die Ihr Posteingang braucht: Gmail und Ihr OpenRouter-Schlüssel zum Sortieren.","Comece pelas duas conexões de que sua caixa precisa: o Gmail e sua chave OpenRouter para a classificação.","Inizia dai due collegamenti che servono alla tua posta: Gmail e la tua chiave OpenRouter per l’ordinamento."],"Gmail is connected":["Gmail est connecté","Gmail está conectado","Gmail ist verbunden","O Gmail está conectado","Gmail è collegato"],"Connect Gmail in Integrations. Laboratorio reads your mail through it and never sends anything on its own.":["Connectez Gmail dans Intégrations. Laboratorio lit votre courrier par ce biais et n’envoie jamais rien de lui-même.","Conecta Gmail en Integraciones. Laboratorio lee tu correo a través de él y nunca envía nada por su cuenta.","Verbinden Sie Gmail unter Integrationen. Laboratorio liest darüber Ihre E-Mails und versendet nie etwas von sich aus.","Conecte o Gmail em Integrações. O Laboratorio lê seu correio por meio dele e nunca envia nada por conta própria.","Collega Gmail in Integrazioni. Laboratorio legge la tua posta tramite Gmail e non invia mai nulla da solo."],"OpenRouter key is set":["La clé OpenRouter est enregistrée","La clave de OpenRouter está guardada","Der OpenRouter-Schlüssel ist gespeichert","A chave OpenRouter está definida","La chiave OpenRouter è impostata"],"Add your OpenRouter key in Settings, under Jev routing. Sorting costs about two cents a month.":["Ajoutez votre clé OpenRouter dans Paramètres, sous Routage Jev. Le tri coûte environ deux centimes par mois.","Añade tu clave de OpenRouter en Ajustes, en Enrutamiento Jev. Clasificar cuesta unos dos céntimos al mes.","Fügen Sie Ihren OpenRouter-Schlüssel in den Einstellungen unter Jev-Routing hinzu. Das Sortieren kostet etwa zwei Cent im Monat.","Adicione sua chave OpenRouter em Configurações, em Roteamento Jev. A classificação custa cerca de dois centavos por mês.","Aggiungi la tua chiave OpenRouter in Impostazioni, sotto Routing Jev. L’ordinamento costa circa due centesimi al mese."],"Laboratorio reads up to 250 recent emails, then you can rename, merge or change every suggestion.":["Laboratorio lit jusqu’à 250 e-mails récents, puis vous pouvez renommer, fusionner ou modifier chaque suggestion.","Laboratorio lee hasta 250 emails recientes y después puedes renombrar, combinar o cambiar cada sugerencia.","Laboratorio liest bis zu 250 aktuelle E-Mails, danach können Sie jeden Vorschlag umbenennen, zusammenführen oder ändern.","O Laboratorio lê até 250 e-mails recentes e depois você pode renomear, mesclar ou alterar cada sugestão.","Laboratorio legge fino a 250 email recenti, poi puoi rinominare, unire o cambiare ogni proposta."],"Measured Jev price: about $0.00002 an email.":["Prix Jev mesuré : environ 0,00002 $ par e-mail.","Precio de Jev medido: unos 0,00002 $ por email.","Gemessener Jev-Preis: etwa 0,00002 $ pro E-Mail.","Preço do Jev medido: cerca de US$ 0,00002 por e-mail.","Prezzo Jev misurato: circa 0,00002 $ per email."],"Sorting sends the sender, subject and start of each email to OpenRouter. Finding categories shows your Orchestrator the same for up to 250 recent emails. Attachments and whole threads never leave this computer.":["Le tri envoie l’expéditeur, l’objet et le début de chaque e-mail à OpenRouter. Pour trouver les catégories, votre Orchestrateur voit la même chose pour au plus 250 e-mails récents. Les pièces jointes et les fils entiers ne quittent jamais cet ordinateur.","La clasificación envía a OpenRouter el remitente, el asunto y el comienzo de cada email. Para encontrar las categorías, tu Orquestador ve lo mismo de hasta 250 emails recientes. Los adjuntos y los hilos completos nunca salen de este ordenador.","Beim Sortieren gehen Absender, Betreff und der Anfang jeder E-Mail an OpenRouter. Zum Finden der Kategorien sieht Ihr Orchestrator dasselbe von bis zu 250 aktuellen E-Mails. Anhänge und ganze Verläufe verlassen diesen Computer nie.","A classificação envia ao OpenRouter o remetente, o assunto e o início de cada e-mail. Para encontrar as categorias, seu Orquestrador vê o mesmo de até 250 e-mails recentes. Anexos e conversas inteiras nunca saem deste computador.","L’ordinamento invia a OpenRouter mittente, oggetto e inizio di ogni email. Per trovare le categorie, il tuo Orchestratore vede lo stesso per al massimo 250 email recenti. Allegati e conversazioni intere non lasciano mai questo computer."],"Gmail connected":["Gmail connecté","Gmail conectado","Gmail verbunden","Gmail conectado","Gmail collegato"],"Gmail not connected":["Gmail non connecté","Gmail no conectado","Gmail nicht verbunden","Gmail não conectado","Gmail non collegato"],"Your Orchestrator reads the sender, subject and first lines of recent mail.":["Votre Orchestrateur lit l’expéditeur, l’objet et les premières lignes du courrier récent.","Tu Orquestador lee el remitente, el asunto y las primeras líneas del correo reciente.","Ihr Orchestrator liest Absender, Betreff und die ersten Zeilen der aktuellen E-Mails.","Seu Orquestrador lê o remetente, o assunto e as primeiras linhas do correio recente.","Il tuo Orchestratore legge mittente, oggetto e prime righe della posta recente."],"Sender, subject and the start of each email go to OpenRouter for sorting.":["L’expéditeur, l’objet et le début de chaque e-mail partent vers OpenRouter pour le tri.","El remitente, el asunto y el comienzo de cada email van a OpenRouter para clasificarlo.","Absender, Betreff und der Anfang jeder E-Mail gehen zum Sortieren an OpenRouter.","Remetente, assunto e início de cada e-mail vão para o OpenRouter para a classificação.","Mittente, oggetto e inizio di ogni email vanno a OpenRouter per l’ordinamento."],Mail:["Courrier","Correo","E-Mail","Correio","Posta"],"Your inbox, sorted around what matters.":["Votre boîte de réception, triée selon vos priorités.","Tu bandeja de entrada, ordenada según tus prioridades.","Ihr Posteingang, nach Ihren Prioritäten sortiert.","Sua caixa de entrada, organizada pelo que importa.","La tua posta, ordinata in base alle tue priorità."],"OpenRouter sorting preview":["Aperçu du tri OpenRouter","Vista previa de clasificación OpenRouter","OpenRouter-Sortiervorschau","Prévia da classificação OpenRouter","Anteprima ordinamento OpenRouter"],"A sample key state lets you explore Mail. No real key is entered, saved or sent.":["Un état de clé fictif permet d’explorer Courrier. Aucune vraie clé n’est saisie, enregistrée ou envoyée.","Una clave de ejemplo permite explorar Correo. No se introduce, guarda ni envía una clave real.","Mit einem Beispielschlüssel können Sie E-Mail testen. Kein echter Schlüssel wird eingegeben, gespeichert oder gesendet.","Uma chave de exemplo permite explorar o Correio. Nenhuma chave real é inserida, salva ou enviada.","Una chiave di esempio permette di esplorare Posta. Nessuna chiave reale viene inserita, salvata o inviata."],"Use sample sorting key":["Utiliser une clé de tri fictive","Usar clave de ejemplo","Beispielschlüssel verwenden","Usar chave de exemplo","Usa chiave di esempio"],"Messages moved to Other.":["Messages déplacés vers Autres.","Mensajes movidos a Otros.","Nachrichten nach Sonstiges verschoben.","Mensagens movidas para Outros.","Messaggi spostati in Altro."],"Categories merged.":["Catégories fusionnées.","Categorías combinadas.","Kategorien zusammengeführt.","Categorias mescladas.","Categorie unite."],"Category split.":["Catégorie divisée.","Categoría dividida.","Kategorie aufgeteilt.","Categoria dividida.","Categoria divisa."],"Moved. Laboratorio will learn from this correction.":["Déplacé. Laboratorio apprendra de cette correction.","Movido. Laboratorio aprenderá de esta corrección.","Verschoben. Laboratorio lernt aus dieser Korrektur.","Movido. O Laboratorio aprenderá com esta correção.","Spostato. Laboratorio imparerà da questa correzione."],"Draft sent to Approval Inbox. Nothing was sent.":["Brouillon ajouté aux approbations. Rien n’a été envoyé.","Borrador enviado a Aprobaciones. No se ha enviado nada.","Entwurf im Freigabeeingang. Nichts wurde versendet.","Rascunho enviado para Aprovações. Nada foi enviado.","Bozza inviata alle Approvazioni. Nulla è stato spedito."],"Personal to-do created.":["Tâche personnelle créée.","Tarea personal creada.","Persönliche Aufgabe erstellt.","Tarefa pessoal criada.","Attività personale creata."],"Could not create the to-do. Please try again.":["Impossible de créer la tâche. Réessayez.","No se pudo crear la tarea. Inténtalo de nuevo.","Aufgabe konnte nicht erstellt werden. Bitte erneut versuchen.","Não foi possível criar a tarefa. Tente novamente.","Impossibile creare l’attività. Riprova."],"A CALMER INBOX":["UNE BOÎTE PLUS SEREINE","UNA BANDEJA MÁS TRANQUILA","EIN RUHIGERER POSTEINGANG","UMA CAIXA MAIS TRANQUILA","UNA CASELLA PIÙ TRANQUILLA"],"Mail, with the signal turned up.":["Le courrier, avec l’essentiel en avant.","Correo, con lo importante en primer plano.","E-Mail, mit dem Wichtigen im Fokus.","Correio, com o que importa em destaque.","La posta, con ciò che conta in evidenza."],"Your messages, organized around what matters to you. The final decisions stay yours.":["Vos messages, organisés selon vos priorités. La décision finale vous appartient.","Tus mensajes, organizados según lo que te importa. La decisión final es tuya.","Ihre Nachrichten, nach Ihren Prioritäten geordnet. Sie entscheiden zuletzt.","Suas mensagens, organizadas pelo que importa. A decisão final é sua.","I tuoi messaggi, organizzati secondo le tue priorità. La decisione finale è tua."],"Gmail + OpenRouter":["Gmail + OpenRouter","Gmail + OpenRouter","Gmail + OpenRouter","Gmail + OpenRouter","Gmail + OpenRouter"],"FINDING YOUR CATEGORIES":["RECHERCHE DE VOS CATÉGORIES","BUSCANDO TUS CATEGORÍAS","KATEGORIEN WERDEN GEFUNDEN","ENCONTRANDO SUAS CATEGORIAS","RICERCA DELLE TUE CATEGORIE"],"SORTING YOUR MAIL":["TRI DE VOTRE COURRIER","CLASIFICANDO TU CORREO","E-MAILS WERDEN SORTIERT","CLASSIFICANDO SEU CORREIO","ORDINAMENTO DELLA POSTA"],"Reading the shape of your inbox.":["Analyse de votre boîte de réception.","Analizando tu bandeja de entrada.","Ihr Posteingang wird analysiert.","Analisando sua caixa de entrada.","Analisi della tua casella di posta."],"Putting every message in its place.":["Chaque message trouve sa place.","Cada mensaje encuentra su lugar.","Jede Nachricht findet ihren Platz.","Cada mensagem encontra seu lugar.","Ogni messaggio trova il suo posto."],"recent emails looked at":["e-mails récents examinés","correos recientes analizados","geprüfte aktuelle E-Mails","e-mails recentes analisados","email recenti esaminate"],"emails sorted":["e-mails triés","correos clasificados","sortierte E-Mails","e-mails classificados","email ordinate"],"Sample data only. No email or key leaves this browser.":["Données fictives uniquement. Aucun e-mail ni clé ne quitte ce navigateur.","Solo datos de ejemplo. Ningún correo ni clave sale de este navegador.","Nur Beispieldaten. Keine E-Mail und kein Schlüssel verlassen diesen Browser.","Apenas dados de exemplo. Nenhum e-mail ou chave sai deste navegador.","Solo dati di esempio. Nessuna email o chiave lascia il browser."],Discover:["Découvrir","Descubrir","Entdecken","Descobrir","Scopri"],"Shape categories":["Affiner les catégories","Ajustar categorías","Kategorien anpassen","Ajustar categorias","Definisci categorie"],Sort:["Trier","Clasificar","Sortieren","Classificar","Ordina"],"FIRST-TIME SETUP":["CONFIGURATION INITIALE","CONFIGURACIÓN INICIAL","ERSTE EINRICHTUNG","CONFIGURAÇÃO INICIAL","CONFIGURAZIONE INIZIALE"],"Make room for the important things.":["Place à ce qui compte.","Haz espacio para lo importante.","Platz für das Wichtige.","Abra espaço para o que importa.","Fai spazio alle cose importanti."],"Start with the two connections your inbox needs. This preview uses sample messages and never asks for a real key.":["Commencez par les deux accès nécessaires. Cet aperçu utilise des messages fictifs et ne demande jamais de vraie clé.","Empieza con las dos conexiones necesarias. Esta vista usa mensajes de ejemplo y nunca pide una clave real.","Beginnen Sie mit den zwei nötigen Verbindungen. Diese Vorschau nutzt Beispielnachrichten und verlangt keinen echten Schlüssel.","Comece pelas duas conexões necessárias. Esta prévia usa mensagens de exemplo e nunca pede uma chave real.","Inizia dalle due connessioni necessarie. Questa anteprima usa messaggi di esempio e non chiede mai una chiave reale."],"Ready for preview":["Prêt pour l’aperçu","Listo para la vista previa","Bereit für die Vorschau","Pronto para a prévia","Pronto per l’anteprima"],"Step 01":["Étape 01","Paso 01","Schritt 01","Etapa 01","Passaggio 01"],"Step 02":["Étape 02","Paso 02","Schritt 02","Etapa 02","Passaggio 02"],"Sample Gmail inbox is ready":["Boîte Gmail fictive prête","Bandeja Gmail de ejemplo lista","Beispiel-Gmail bereit","Caixa Gmail de exemplo pronta","Casella Gmail di esempio pronta"],"Your mail categories are ready":["Vos catégories de mail sont prêtes","Tus categorías de correo están listas","Ihre Mail-Kategorien sind fertig","Suas categorias de e-mail estão prontas","Le tue categorie di posta sono pronte"],"Your inbox is sorted":["Votre boîte de réception est triée","Tu bandeja de entrada está ordenada","Ihr Posteingang ist sortiert","Sua caixa de entrada está organizada","La tua posta in arrivo è ordinata"],"Finding your mail categories stopped":["La recherche de catégories s’est arrêtée","La búsqueda de categorías se detuvo","Die Suche nach Kategorien wurde angehalten","A busca de categorias parou","La ricerca delle categorie si è interrotta"],"Sorting your mail stopped":["Le tri de vos mails s’est arrêté","La ordenación del correo se detuvo","Das Sortieren Ihrer Mails wurde angehalten","A organização dos e-mails parou","L’ordinamento della posta si è interrotto"],"Sender, subject and the start of each email go to your Orchestrator's model for sorting, 40 at a time, so the count moves in steps.":["L’expéditeur, l’objet et le début de chaque e-mail partent vers le modèle de votre Orchestrateur pour le tri, 40 à la fois : le compteur avance par paliers.","El remitente, el asunto y el inicio de cada correo van al modelo de tu Orquestador para ordenarlos, de 40 en 40, así que el contador avanza a saltos.","Absender, Betreff und Anfang jeder E-Mail gehen zum Sortieren an das Modell Ihres Orchestrators, 40 auf einmal, daher springt der Zähler in Schritten.","O remetente, o assunto e o início de cada e-mail vão para o modelo do seu Orquestrador para a organização, 40 de cada vez, por isso a contagem avança aos saltos.","Mittente, oggetto e inizio di ogni email vanno al modello del tuo Orchestratore per l’ordinamento, 40 alla volta, quindi il conteggio avanza a scatti."],"Sure of this category":["Sûr de cette catégorie","Seguro de esta categoría","Sicher bei dieser Kategorie","Seguro desta categoria","Sicuro di questa categoria"],"Emails sorted with less than 70% certainty":["E-mails triés avec moins de 70 % de certitude","Correos ordenados con menos del 70 % de certeza","E-Mails, die mit weniger als 70 % Sicherheit sortiert wurden","E-mails organizados com menos de 70% de certeza","Email ordinate con meno del 70% di certezza"],"Dots and % show how sure the sorting is of each category.":["Les points et les % montrent la certitude du tri pour chaque catégorie.","Los puntos y el % muestran la certeza del orden en cada categoría.","Punkte und % zeigen, wie sicher die Sortierung je Kategorie ist.","Os pontos e a % mostram a certeza da organização em cada categoria.","Punti e % mostrano quanto è sicuro l’ordinamento per ogni categoria."],"Someone seems to be waiting for your answer":["Quelqu’un semble attendre votre réponse","Alguien parece estar esperando tu respuesta","Jemand scheint auf Ihre Antwort zu warten","Alguém parece estar à espera da sua resposta","Qualcuno sembra aspettare la tua risposta"],"Not sure":["Pas sûr","No está seguro","Nicht sicher","Não tem certeza","Non sicuro"],"Start by connecting Gmail. A Jev key is optional: it makes sorting faster and cheaper.":["Commencez par connecter Gmail. Une clé Jev est facultative : elle rend le tri plus rapide et moins cher.","Empieza conectando Gmail. La clave de Jev es opcional: hace que ordenar sea más rápido y barato.","Verbinden Sie zuerst Gmail. Ein Jev-Schlüssel ist optional: Er macht das Sortieren schneller und günstiger.","Comece por conectar o Gmail. Uma chave Jev é opcional: torna a organização mais rápida e barata.","Inizia collegando Gmail. Una chiave Jev è facoltativa: rende l’ordinamento più veloce ed economico."],"Sorted by your Orchestrator":["Trié par votre Orchestrateur","Ordenado por tu Orquestador","Sortiert von Ihrem Orchestrator","Organizado pelo seu Orquestrador","Ordinato dal tuo Orchestratore"],"Gmail connecting…":["Connexion de Gmail…","Conectando Gmail…","Gmail wird verbunden…","Conectando o Gmail…","Connessione di Gmail…"],Connecting:["Connexion","Conectando","Verbindung","Conectando","Connessione"],"Gmail is connecting…":["Gmail se connecte…","Gmail se está conectando…","Gmail wird verbunden…","O Gmail está se conectando…","Gmail si sta connettendo…"],"You approved Gmail in Composio. Laboratorio is confirming the connection now; this card updates by itself in a few seconds.":["Vous avez autorisé Gmail dans Composio. Laboratorio confirme la connexion ; cette carte se met à jour seule dans quelques secondes.","Autorizaste Gmail en Composio. Laboratorio está confirmando la conexión; esta tarjeta se actualiza sola en unos segundos.","Sie haben Gmail in Composio freigegeben. Laboratorio bestätigt die Verbindung; diese Karte aktualisiert sich in wenigen Sekunden von selbst.","Você autorizou o Gmail no Composio. O Laboratorio está confirmando a conexão; este cartão se atualiza sozinho em alguns segundos.","Hai autorizzato Gmail in Composio. Laboratorio sta confermando la connessione; questa scheda si aggiorna da sola in pochi secondi."],"Gmail is not connected yet":["Gmail n’est pas encore connecté","Gmail aún no está conectado","Gmail ist noch nicht verbunden","O Gmail ainda não está conectado","Gmail non è ancora connesso"],"Connect Gmail in Integrations when the backend is ready, or use the sample inbox to explore Mail now.":["Connectez Gmail dans Intégrations lorsque le serveur sera prêt, ou explorez dès maintenant avec la boîte fictive.","Conecta Gmail en Integraciones cuando el servidor esté listo o explora ahora con la bandeja de ejemplo.","Verbinden Sie Gmail später unter Integrationen oder testen Sie jetzt den Beispielposteingang.","Conecte o Gmail em Integrações quando o servidor estiver pronto ou explore agora com a caixa de exemplo.","Collega Gmail in Integrazioni quando il server sarà pronto o esplora ora la posta di esempio."],"Open Integrations":["Ouvrir Intégrations","Abrir Integraciones","Integrationen öffnen","Abrir Integrações","Apri Integrazioni"],"Turn off sample inbox":["Désactiver la boîte fictive","Desactivar bandeja de ejemplo","Beispielposteingang ausschalten","Desativar caixa de exemplo","Disattiva posta di esempio"],"Use sample Gmail inbox":["Utiliser la boîte Gmail fictive","Usar bandeja Gmail de ejemplo","Beispiel-Gmail verwenden","Usar caixa Gmail de exemplo","Usa posta Gmail di esempio"],"Sample sorting key is ready":["Clé de tri fictive prête","Clave de ejemplo lista","Beispielschlüssel bereit","Chave de exemplo pronta","Chiave di esempio pronta"],"Sorting needs your OpenRouter key":["Le tri nécessite votre clé OpenRouter","La clasificación necesita tu clave OpenRouter","Sortieren benötigt Ihren OpenRouter-Schlüssel","A classificação precisa da sua chave OpenRouter","Per ordinare serve la tua chiave OpenRouter"],"Manage sorting in Settings. For this preview, a sample key state unlocks the walkthrough without collecting a real key.":["Gérez le tri dans Paramètres. Ici, une clé fictive débloque l’aperçu sans recueillir de vraie clé.","Configura la clasificación en Ajustes. Aquí una clave de ejemplo permite explorar sin recopilar una clave real.","Verwalten Sie das Sortieren in Einstellungen. Ein Beispielschlüssel schaltet die Vorschau frei, ohne echte Schlüssel zu erfassen.","Gerencie a classificação em Configurações. Aqui uma chave de exemplo libera a prévia sem coletar uma chave real.","Gestisci l’ordinamento in Impostazioni. Una chiave di esempio sblocca l’anteprima senza raccogliere chiavi reali."],"Open Settings":["Ouvrir Paramètres","Abrir Ajustes","Einstellungen öffnen","Abrir Configurações","Apri Impostazioni"],"Turn off sample key":["Désactiver la clé fictive","Desactivar clave de ejemplo","Beispielschlüssel ausschalten","Desativar chave de exemplo","Disattiva chiave di esempio"],"Find the categories that fit your mail":["Trouver des catégories adaptées à votre courrier","Encuentra categorías para tu correo","Passende Kategorien für Ihre E-Mails finden","Encontre categorias para seu correio","Trova categorie adatte alla tua posta"],"Laboratorio will examine recent sample messages, then you can rename, merge or change every suggestion.":["Laboratorio examinera des messages fictifs récents. Vous pourrez ensuite renommer, fusionner ou modifier chaque suggestion.","Laboratorio analizará mensajes recientes de ejemplo. Luego podrás renombrar, combinar o cambiar cada sugerencia.","Laboratorio prüft aktuelle Beispielnachrichten. Danach können Sie jeden Vorschlag umbenennen, zusammenführen oder ändern.","O Laboratorio analisará mensagens recentes de exemplo. Depois você poderá renomear, mesclar ou alterar cada sugestão.","Laboratorio esaminerà messaggi recenti di esempio. Poi potrai rinominare, unire o modificare ogni proposta."],"Find my categories":["Trouver mes catégories","Encontrar mis categorías","Meine Kategorien finden","Encontrar minhas categorias","Trova le mie categorie"],"YOUR CATEGORY MAP":["VOTRE PLAN DES CATÉGORIES","MAPA DE TUS CATEGORÍAS","IHRE KATEGORIENÜBERSICHT","SEU MAPA DE CATEGORIAS","MAPPA DELLE TUE CATEGORIE"],"A first draft of your inbox.":["Une première organisation de votre boîte.","Un primer esquema de tu bandeja.","Ein erster Entwurf Ihres Posteingangs.","Uma primeira organização da sua caixa.","Una prima bozza della tua casella."],"Suggested from recent mail. Rename, merge, split, remove or add categories before you sort.":["Suggestions issues des messages récents. Renommez, fusionnez, divisez, supprimez ou ajoutez des catégories avant le tri.","Sugeridas a partir de correos recientes. Renombra, combina, divide, elimina o añade categorías antes de clasificar.","Aus aktuellen E-Mails vorgeschlagen. Vor dem Sortieren können Sie Kategorien umbenennen, zusammenführen, teilen, löschen oder ergänzen.","Sugeridas a partir de e-mails recentes. Renomeie, mescle, divida, remova ou adicione categorias antes de classificar.","Suggerite dalle email recenti. Rinomina, unisci, dividi, rimuovi o aggiungi categorie prima di ordinare."],"emails analyzed":["e-mails analysés","correos analizados","analysierte E-Mails","e-mails analisados","email analizzate"],"Category name":["Nom de la catégorie","Nombre de categoría","Kategoriename","Nome da categoria","Nome categoria"],emails:["e-mails","correos","E-Mails","e-mails","email"],"What belongs here":["Ce qui appartient ici","Qué va aquí","Was gehört hierher","O que pertence aqui","Cosa va qui"],"Category settings":["Paramètres de catégorie","Ajustes de categoría","Kategorieeinstellungen","Configurações da categoria","Impostazioni categoria"],"Move up":["Monter","Subir","Nach oben","Mover para cima","Sposta su"],"Move down":["Descendre","Bajar","Nach unten","Mover para baixo","Sposta giù"],Merge:["Fusionner","Combinar","Zusammenführen","Mesclar","Unisci"],Split:["Diviser","Dividir","Aufteilen","Dividir","Dividi"],"New category":["Nouvelle catégorie","Nueva categoría","Neue Kategorie","Nova categoria","Nuova categoria"],"Add category":["Ajouter une catégorie","Añadir categoría","Kategorie hinzufügen","Adicionar categoria","Aggiungi categoria"],"BEFORE YOU SORT":["AVANT LE TRI","ANTES DE CLASIFICAR","VOR DEM SORTIEREN","ANTES DE CLASSIFICAR","PRIMA DI ORDINARE"],"Choose how far back to go.":["Choisissez la période à trier.","Elige desde cuándo clasificar.","Wählen Sie den Zeitraum.","Escolha o período a classificar.","Scegli da quanto tempo partire."],"A clear estimate before anything starts.":["Une estimation claire avant de commencer.","Una estimación clara antes de empezar.","Ein klarer Kostenvoranschlag vor dem Start.","Uma estimativa clara antes de começar.","Una stima chiara prima di iniziare."],days:["jours","días","Tage","dias","giorni"],"Emails to sort":["E-mails à trier","Correos para clasificar","Zu sortierende E-Mails","E-mails para classificar","Email da ordinare"],"Estimated cost":["Coût estimé","Coste estimado","Geschätzte Kosten","Custo estimado","Costo stimato"],"Illustrative OpenRouter estimate for this preview.":["Estimation OpenRouter indicative pour cet aperçu.","Estimación ilustrativa de OpenRouter para esta vista.","Beispielhafte OpenRouter-Kostenschätzung für diese Vorschau.","Estimativa ilustrativa do OpenRouter para esta prévia.","Stima indicativa OpenRouter per questa anteprima."],"Save and return":["Enregistrer et revenir","Guardar y volver","Speichern und zurück","Salvar e voltar","Salva e torna"],"Start sorting":["Commencer le tri","Empezar a clasificar","Sortieren starten","Iniciar classificação","Avvia ordinamento"],"Give every category a unique name before sorting.":["Donnez un nom unique à chaque catégorie avant le tri.","Da un nombre único a cada categoría antes de clasificar.","Geben Sie jeder Kategorie vor dem Sortieren einen eindeutigen Namen.","Dê um nome único a cada categoria antes de classificar.","Dai a ogni categoria un nome unico prima di ordinare."],"Sorted mail":["Courrier trié","Correo clasificado","Sortierte E-Mails","Correio classificado","Posta ordinata"],"Across your categories":["Dans vos catégories","En tus categorías","In Ihren Kategorien","Nas suas categorias","Nelle tue categorie"],"Urgency 8 to 10":["Urgence de 8 à 10","Urgencia de 8 a 10","Dringlichkeit 8 bis 10","Urgência de 8 a 10","Urgenza da 8 a 10"],"Sorted today":["Triés aujourd’hui","Clasificados hoy","Heute sortiert","Classificados hoje","Ordinati oggi"],"Latest arrival":["Dernier reçu","Última llegada","Letzter Eingang","Último recebimento","Ultimo arrivo"],"YOUR INBOX":["VOTRE BOÎTE","TU BANDEJA","IHR POSTEINGANG","SUA CAIXA","LA TUA POSTA"],"Everything in its place.":["Chaque message à sa place.","Todo en su lugar.","Alles an seinem Platz.","Tudo em seu lugar.","Tutto al suo posto."],"Manage categories":["Gérer les catégories","Gestionar categorías","Kategorien verwalten","Gerenciar categorias","Gestisci categorie"],"Find my categories again":["Retrouver mes catégories","Volver a encontrar mis categorías","Kategorien erneut finden","Encontrar minhas categorias novamente","Trova di nuovo le mie categorie"],"SMART FOLDERS":["DOSSIERS INTELLIGENTS","CARPETAS INTELIGENTES","INTELLIGENTE ORDNER","PASTAS INTELIGENTES","CARTELLE INTELLIGENTI"],"All mail":["Tout le courrier","Todo el correo","Alle E-Mails","Todos os e-mails","Tutta la posta"],CATEGORIES:["CATÉGORIES","CATEGORÍAS","KATEGORIEN","CATEGORIAS","CATEGORIE"],unread:["non lus","sin leer","ungelesen","não lidos","non lette"],"Your categories are yours to shape.":["Vos catégories évoluent avec vous.","Puedes ajustar tus categorías.","Ihre Kategorien bleiben anpassbar.","Suas categorias podem ser ajustadas.","Puoi adattare le tue categorie."],"Search results":["Résultats de recherche","Resultados de búsqueda","Suchergebnisse","Resultados da busca","Risultati di ricerca"],"unread across all mail":["non lus dans tout le courrier","sin leer en todo el correo","ungelesen in allen E-Mails","não lidos em todos os e-mails","non lette in tutta la posta"],"Search all mail":["Rechercher dans tout le courrier","Buscar en todo el correo","Alle E-Mails durchsuchen","Buscar em todos os e-mails","Cerca in tutta la posta"],Other:["Autres","Otros","Sonstiges","Outros","Altro"],Handled:["Traité","Gestionado","Erledigt","Resolvido","Gestita"],"No messages match this view.":["Aucun message ne correspond à cette vue.","No hay mensajes para esta vista.","Keine Nachrichten passen zu dieser Ansicht.","Nenhuma mensagem corresponde a esta visualização.","Nessun messaggio corrisponde a questa vista."],"Try another folder, filter or search.":["Essayez un autre dossier, filtre ou terme.","Prueba otra carpeta, filtro o búsqueda.","Versuchen Sie einen anderen Ordner, Filter oder Suchbegriff.","Tente outra pasta, filtro ou busca.","Prova un’altra cartella, filtro o ricerca."],"Back to mail":["Retour au courrier","Volver al correo","Zurück zu E-Mails","Voltar ao correio","Torna alla posta"],"EMAIL DETAIL":["DÉTAIL DU MESSAGE","DETALLE DEL CORREO","E-MAIL-DETAILS","DETALHES DO E-MAIL","DETTAGLI EMAIL"],"Close email":["Fermer le message","Cerrar correo","E-Mail schließen","Fechar e-mail","Chiudi email"],Urgency:["Urgence","Urgencia","Dringlichkeit","Urgência","Urgenza"],"Why this category?":["Pourquoi cette catégorie ?","¿Por qué esta categoría?","Warum diese Kategorie?","Por que esta categoria?","Perché questa categoria?"],Confidence:["Confiance","Confianza","Sicherheit","Confiança","Affidabilità"],"Move to category":["Déplacer vers une catégorie","Mover a categoría","In Kategorie verschieben","Mover para categoria","Sposta in categoria"],"Marked as needing attention.":["Marqué comme à traiter.","Marcado como pendiente.","Als zu bearbeiten markiert.","Marcado como pendente.","Segnata come da gestire."],"Marked handled.":["Marqué comme traité.","Marcado como gestionado.","Als erledigt markiert.","Marcado como resolvido.","Segnata come gestita."],"Mark handled":["Marquer comme traité","Marcar como gestionado","Als erledigt markieren","Marcar como resolvido","Segna come gestita"],"Mark unhandled":["Marquer comme non traité","Marcar como no gestionado","Als nicht erledigt markieren","Marcar como não resolvido","Segna come non gestita"],"Add personal to-do":["Créer une tâche personnelle","Crear tarea personal","Persönliche Aufgabe erstellen","Criar tarefa pessoal","Crea attività personale"],"Open in Gmail":["Ouvrir dans Gmail","Abrir en Gmail","In Gmail öffnen","Abrir no Gmail","Apri in Gmail"],"This sample email will open in Gmail after a real mailbox is connected.":["Ce message fictif s’ouvrira dans Gmail après la connexion d’une vraie boîte.","Este correo de ejemplo se abrirá en Gmail cuando se conecte una cuenta real.","Diese Beispiel-E-Mail öffnet sich in Gmail, sobald ein echtes Postfach verbunden ist.","Este e-mail de exemplo será aberto no Gmail após conectar uma caixa real.","Questa email di esempio si aprirà in Gmail dopo aver collegato una casella reale."],"A thoughtful reply, ready for your review.":["Une réponse soignée, prête à être relue.","Una respuesta cuidada, lista para revisar.","Eine durchdachte Antwort zur Prüfung.","Uma resposta cuidadosa, pronta para sua revisão.","Una risposta curata, pronta per la tua revisione."],"An agent can prepare it. You decide whether it goes out.":["Un agent peut la préparer. Vous décidez de l’envoi.","Un agente puede prepararla. Tú decides si se envía.","Ein Agent kann sie vorbereiten. Sie entscheiden über den Versand.","Um agente pode prepará-la. Você decide se ela será enviada.","Un agente può prepararla. Decidi tu se inviarla."],"Draft in Approval Inbox":["Brouillon dans les approbations","Borrador en Aprobaciones","Entwurf im Freigabeeingang","Rascunho em Aprovações","Bozza in Approvazioni"],"Ask an agent to draft a reply":["Demander un brouillon à un agent","Pedir a un agente que redacte","Agenten um Antwortentwurf bitten","Pedir a um agente um rascunho","Chiedi a un agente una bozza"],"A clearer view starts here.":["Une vue plus claire commence ici.","Una vista más clara comienza aquí.","Hier beginnt der klare Überblick.","Uma visão mais clara começa aqui.","Una visione più chiara inizia qui."],"Choose a message to read it, organize it, or ask an agent for help.":["Choisissez un message pour le lire, le classer ou demander de l’aide à un agent.","Elige un mensaje para leerlo, organizarlo o pedir ayuda a un agente.","Wählen Sie eine Nachricht zum Lesen, Ordnen oder um einen Agenten zu bitten.","Escolha uma mensagem para ler, organizar ou pedir ajuda a um agente.","Scegli un messaggio per leggerlo, ordinarlo o chiedere aiuto a un agente."],"HOW SORTING IS DOING":["BILAN DU TRI","CÓMO VA LA CLASIFICACIÓN","SORTIERLEISTUNG","COMO VAI A CLASSIFICAÇÃO","ANDAMENTO DELL’ORDINAMENTO"],"It gets better with your corrections.":["Vos corrections améliorent le tri.","Mejora con tus correcciones.","Ihre Korrekturen verbessern das Sortieren.","Suas correções melhoram a classificação.","Migliora con le tue correzioni."],"owner corrections":["corrections du propriétaire","correcciones del propietario","Korrekturen des Besitzers","correções do proprietário","correzioni del proprietario"],"this week":["cette semaine","esta semana","diese Woche","esta semana","questa settimana"],"this month":["ce mois-ci","este mes","diesen Monat","este mês","questo mese"],"What Laboratorio learned":["Ce qu’Laboratorio a appris","Lo que Laboratorio aprendió","Was Laboratorio gelernt hat","O que o Laboratorio aprendeu","Cosa ha imparato Laboratorio"],"Remove learning":["Supprimer cet apprentissage","Eliminar aprendizaje","Lernregel entfernen","Remover aprendizado","Rimuovi apprendimento"],"Move a message to another category and the lesson will appear here.":["Déplacez un message vers une autre catégorie et la leçon apparaîtra ici.","Mueve un mensaje a otra categoría y el aprendizaje aparecerá aquí.","Verschieben Sie eine Nachricht in eine andere Kategorie. Die Lernregel erscheint hier.","Mova uma mensagem para outra categoria e o aprendizado aparecerá aqui.","Sposta un messaggio in un’altra categoria e la regola apparirà qui."],"PRIVACY, IN PLAIN WORDS":["CONFIDENTIALITÉ, EN CLAIR","PRIVACIDAD, EN CLARO","DATENSCHUTZ, EINFACH ERKLÄRT","PRIVACIDADE, SEM COMPLICAÇÃO","PRIVACY, IN PAROLE SEMPLICI"],"Your whole inbox does not go to a model.":["Toute votre boîte ne va pas au modèle.","Tu bandeja completa no va al modelo.","Ihr ganzer Posteingang geht nicht an ein Modell.","Sua caixa inteira não vai para o modelo.","Non inviamo tutta la tua posta al modello."],"When connected, sorting sends the sender, subject and start of each email to OpenRouter. Attachments and whole threads never go there. This preview sends nothing.":["Une fois connecté, le tri envoie à OpenRouter l’expéditeur, l’objet et le début de chaque message. Jamais les pièces jointes ni les conversations entières. Cet aperçu n’envoie rien.","Al conectarse, la clasificación envía a OpenRouter el remitente, el asunto y el inicio de cada correo. Nunca adjuntos ni conversaciones completas. Esta vista no envía nada.","Wenn verbunden, sendet das Sortieren Absender, Betreff und Anfang jeder E-Mail an OpenRouter. Anhänge und ganze Unterhaltungen werden nie gesendet. Diese Vorschau sendet nichts.","Quando conectado, a classificação envia ao OpenRouter remetente, assunto e início de cada e-mail. Nunca anexos ou conversas inteiras. Esta prévia não envia nada.","Quando connesso, l’ordinamento invia a OpenRouter mittente, oggetto e inizio di ogni email. Mai allegati o intere conversazioni. Questa anteprima non invia nulla."],"Category colour":["Couleur de la catégorie","Color de categoría","Kategoriefarbe","Cor da categoria","Colore categoria"],"Choose colour":["Choisir une couleur","Elegir color","Farbe wählen","Escolher cor","Scegli colore"],"Add matching Gmail label":["Ajouter un libellé Gmail correspondant","Añadir etiqueta de Gmail","Passendes Gmail-Label hinzufügen","Adicionar marcador no Gmail","Aggiungi etichetta Gmail"],"Put this category name on matching messages in Gmail.":["Appliquer le nom de cette catégorie aux messages correspondants dans Gmail.","Poner el nombre de esta categoría en los correos correspondientes en Gmail.","Diesen Kategorienamen auf passende Nachrichten in Gmail anwenden.","Aplicar o nome desta categoria às mensagens correspondentes no Gmail.","Applica il nome della categoria ai messaggi corrispondenti in Gmail."],"Prepare a reply for every new email":["Préparer une réponse pour chaque nouveau message","Preparar respuesta para cada correo nuevo","Für jede neue E-Mail eine Antwort vorbereiten","Preparar resposta para cada novo e-mail","Prepara una risposta per ogni nuova email"],"Every draft waits in Approval Inbox. Nothing is sent automatically.":["Chaque brouillon attend votre approbation. Rien n’est envoyé automatiquement.","Cada borrador espera tu aprobación. Nada se envía automáticamente.","Jeder Entwurf wartet auf Ihre Freigabe. Nichts wird automatisch versendet.","Todo rascunho aguarda sua aprovação. Nada é enviado automaticamente.","Ogni bozza attende la tua approvazione. Nulla viene inviato automaticamente."],"Drafting agent":["Agent chargé du brouillon","Agente redactor","Agent für Entwürfe","Agente redator","Agente per le bozze"],"Instructions for the agent":["Instructions pour l’agent","Instrucciones para el agente","Anweisungen für den Agenten","Instruções para o agente","Istruzioni per l’agente"],"How should the agent answer?":["Comment l’agent doit-il répondre ?","¿Cómo debe responder el agente?","Wie soll der Agent antworten?","Como o agente deve responder?","Come deve rispondere l’agente?"],"Notify me about new mail":["M’avertir des nouveaux messages","Avisarme de nuevos correos","Über neue E-Mails benachrichtigen","Avisar sobre novos e-mails","Avvisami delle nuove email"],"Uses your Approval Inbox channels and quiet hours.":["Utilise les canaux et les heures silencieuses de vos approbations.","Usa los canales y horas de silencio de Aprobaciones.","Verwendet Ihre Freigabekanäle und Ruhezeiten.","Usa seus canais de Aprovações e horários de silêncio.","Usa i canali e gli orari silenziosi delle Approvazioni."],"Merge categories":["Fusionner les catégories","Combinar categorías","Kategorien zusammenführen","Mesclar categorias","Unisci categorie"],"Messages and examples from this category will move to the category you choose.":["Les messages et exemples de cette catégorie iront dans celle que vous choisissez.","Los mensajes y ejemplos de esta categoría pasarán a la categoría elegida.","Nachrichten und Beispiele dieser Kategorie werden in die gewählte Kategorie verschoben.","Mensagens e exemplos desta categoria serão movidos para a categoria escolhida.","Messaggi ed esempi di questa categoria passeranno a quella scelta."],"Merge into":["Fusionner avec","Combinar con","Zusammenführen mit","Mesclar com","Unisci con"],"Split category":["Diviser la catégorie","Dividir categoría","Kategorie aufteilen","Dividir categoria","Dividi categoria"],"Create a new category from messages by one example sender.":["Créez une catégorie à partir des messages d’un expéditeur.","Crea una categoría con mensajes de un remitente.","Erstellen Sie eine neue Kategorie aus Nachrichten eines Absenders.","Crie uma categoria a partir das mensagens de um remetente.","Crea una categoria dai messaggi di un mittente."],"New category name":["Nom de la nouvelle catégorie","Nombre de la nueva categoría","Name der neuen Kategorie","Nome da nova categoria","Nome della nuova categoria"],"Example sender to move":["Expéditeur à déplacer","Remitente para mover","Absender zum Verschieben","Remetente a mover","Mittente da spostare"],"Create split":["Créer la division","Crear división","Aufteilung erstellen","Criar divisão","Crea divisione"],"The draft will wait in Approval Inbox. Nothing goes to Gmail without your approval.":["Le brouillon attendra votre approbation. Rien n’ira dans Gmail sans votre accord.","El borrador esperará en Aprobaciones. Nada llegará a Gmail sin tu visto bueno.","Der Entwurf wartet im Freigabeeingang. Nichts geht ohne Ihre Zustimmung an Gmail.","O rascunho aguardará em Aprovações. Nada irá ao Gmail sem sua aprovação.","La bozza aspetterà nelle Approvazioni. Nulla andrà su Gmail senza il tuo consenso."],"Your instruction (optional)":["Votre instruction (facultatif)","Tu instrucción (opcional)","Ihre Anweisung (optional)","Sua instrução (opcional)","La tua istruzione (facoltativa)"],"For example, ask for the budget and proposed dates.":["Par exemple, demandez le budget et les dates proposées.","Por ejemplo, pide el presupuesto y las fechas propuestas.","Fragen Sie zum Beispiel nach Budget und Terminvorschlägen.","Por exemplo, peça o orçamento e as datas propostas.","Per esempio, chiedi budget e date proposte."],"The agent writes the reply and puts it in your Approval Inbox. Nothing is sent until you approve it there.":["L’agent rédige la réponse et la place dans votre boîte d’approbation. Rien n’est envoyé avant votre approbation.","El agente redacta la respuesta y la deja en tu bandeja de aprobación. No se envía nada hasta que la apruebes allí.","Der Agent schreibt die Antwort und legt sie in Ihren Freigabe-Eingang. Nichts wird gesendet, bevor Sie sie dort freigeben.","O agente escreve a resposta e coloca-a na sua caixa de aprovação. Nada é enviado até que a aprove lá.","L’agente scrive la risposta e la mette nella tua casella di approvazione. Nulla viene inviato finché non la approvi lì."],"Prepare draft for approval":["Préparer un brouillon à approuver","Preparar borrador para aprobación","Entwurf zur Freigabe vorbereiten","Preparar rascunho para aprovação","Prepara bozza per approvazione"],All:["Tout","Todos","Alle","Todos","Tutti"],Unread:["Non lus","Sin leer","Ungelesen","Não lidos","Non lette"],Urgent:["Urgent","Urgente","Dringend","Urgente","Urgenti"],Sponsorships:["Parrainages","Patrocinios","Sponsorings","Patrocínios","Sponsorizzazioni"],"Customer support":["Assistance clients","Atención al cliente","Kundensupport","Suporte ao cliente","Assistenza clienti"],Membership:["Abonnements","Membresías","Mitgliedschaft","Assinaturas","Abbonamenti"],Invoices:["Factures","Facturas","Rechnungen","Faturas","Fatture"],Newsletters:["Lettres d’information","Boletines","Newsletter","Newsletters","Newsletter"],"Partnership proposals, paid collaborations and media requests.":["Propositions de partenariat, collaborations rémunérées et demandes presse.","Propuestas de colaboración, patrocinios y solicitudes de medios.","Partnerschaftsvorschläge, bezahlte Kooperationen und Medienanfragen.","Propostas de parceria, colaborações pagas e pedidos da imprensa.","Proposte di partnership, collaborazioni retribuite e richieste stampa."],"Customer questions, access issues and product problems.":["Questions clients, problèmes d’accès et difficultés produit.","Consultas, problemas de acceso y fallos del producto.","Kundenfragen, Zugangsprobleme und Produktfehler.","Dúvidas de clientes, problemas de acesso e do produto.","Domande dei clienti, problemi di accesso e del prodotto."],"Member plans, renewals and account changes.":["Offres, renouvellements et modifications des comptes membres.","Planes, renovaciones y cambios de cuenta.","Mitgliedspläne, Verlängerungen und Kontoänderungen.","Planos, renovações e alterações de contas.","Piani, rinnovi e modifiche degli account."],"Invoices, payment reminders and receipts.":["Factures, rappels de paiement et reçus.","Facturas, recordatorios de pago y recibos.","Rechnungen, Zahlungserinnerungen und Belege.","Faturas, lembretes de pagamento e recibos.","Fatture, solleciti di pagamento e ricevute."],"Recurring digests and reading from subscriptions.":["Résumés réguliers et lectures issues des abonnements.","Resúmenes periódicos y lecturas de suscripciones.","Regelmäßige Zusammenfassungen und abonnierte Inhalte.","Resumos recorrentes e leituras de assinaturas.","Riepiloghi periodici e letture dagli abbonamenti."],"Messages that do not fit another category.":["Messages sans catégorie plus adaptée.","Mensajes que no encajan en otra categoría.","Nachrichten ohne passende andere Kategorie.","Mensagens que não se encaixam em outra categoria.","Messaggi che non rientrano in altre categorie."],"Partnership language and a request for a media kit":["Langage de partenariat et demande de dossier média","Propuesta de colaboración y solicitud de kit de medios","Partnerschaftsanfrage und Bitte um Media-Kit","Proposta de parceria e pedido de kit de mídia","Proposta di partnership e richiesta di media kit"],"Proposal and campaign collaboration language":["Proposition de collaboration de campagne","Propuesta de colaboración en campaña","Vorschlag zur Kampagnenzusammenarbeit","Proposta de colaboração em campanha","Proposta di collaborazione per una campagna"],"Sponsorship request in the subject and body":["Demande de parrainage dans l’objet et le contenu","Solicitud de patrocinio en el asunto y el texto","Sponsoringanfrage in Betreff und Text","Pedido de patrocínio no assunto e no texto","Richiesta di sponsorizzazione nell’oggetto e nel testo"],"A customer reports a blocking product issue":["Un client signale un problème produit bloquant","Un cliente informa de un fallo que bloquea el producto","Ein Kunde meldet einen blockierenden Produktfehler","Um cliente relata um problema que impede o uso","Un cliente segnala un problema bloccante"],"Customer asking for help with access":["Un client demande de l’aide pour accéder au service","Un cliente pide ayuda para acceder","Ein Kunde bittet um Hilfe beim Zugang","Um cliente pede ajuda com o acesso","Un cliente chiede aiuto per l’accesso"],"Customer product question":["Question d’un client sur le produit","Consulta de un cliente sobre el producto","Kundenfrage zum Produkt","Dúvida de cliente sobre o produto","Domanda di un cliente sul prodotto"],"Annual plan and renewal question":["Question sur l’offre annuelle et le renouvellement","Pregunta sobre el plan anual y la renovación","Frage zu Jahresplan und Verlängerung","Dúvida sobre plano anual e renovação","Domanda sul piano annuale e sul rinnovo"],"Member report and renewals":["Rapport des membres et renouvellements","Informe de miembros y renovaciones","Mitgliederbericht und Verlängerungen","Relatório de membros e renovações","Report sugli iscritti e rinnovi"],"Membership plan upgrade request":["Demande de changement d’offre membre","Solicitud de cambio de plan","Anfrage zum Mitgliedschafts-Upgrade","Pedido de mudança de plano","Richiesta di passaggio a un altro piano"],"Invoice number and due date":["Numéro de facture et date d’échéance","Número de factura y fecha de vencimiento","Rechnungsnummer und Fälligkeitsdatum","Número da fatura e vencimento","Numero fattura e scadenza"],"Payment receipt and accounting sender":["Reçu de paiement envoyé par la comptabilité","Recibo de pago de contabilidad","Zahlungsbeleg vom Buchhaltungskontakt","Recibo de pagamento da contabilidade","Ricevuta di pagamento dalla contabilità"],"Payment reminder for an invoice":["Rappel de paiement pour une facture","Recordatorio de pago de una factura","Zahlungserinnerung zu einer Rechnung","Lembrete de pagamento de uma fatura","Sollecito di pagamento di una fattura"],"Periodic editorial digest":["Résumé éditorial périodique","Resumen editorial periódico","Regelmäßige redaktionelle Übersicht","Resumo editorial periódico","Riepilogo editoriale periodico"],"Weekly newsletter format":["Format de lettre hebdomadaire","Formato de boletín semanal","Wöchentliches Newsletter-Format","Formato de newsletter semanal","Formato di newsletter settimanale"],"Recurring reading roundup":["Sélection régulière de lectures","Selección periódica de lecturas","Regelmäßige Leseübersicht","Seleção recorrente de leituras","Raccolta periodica di letture"],"Personal note without a matching business category":["Message personnel sans catégorie professionnelle adaptée","Mensaje personal sin categoría comercial adecuada","Persönliche Nachricht ohne passende Geschäftskategorie","Mensagem pessoal sem categoria comercial adequada","Messaggio personale senza una categoria professionale adatta"],"Event invitation without a closer category":["Invitation à un événement sans catégorie plus adaptée","Invitación a un evento sin categoría más adecuada","Veranstaltungseinladung ohne passendere Kategorie","Convite para evento sem categoria mais adequada","Invito a un evento senza una categoria più adatta"],"Follow-up to a partnership proposal":["Relance d’une proposition de partenariat","Seguimiento de una propuesta de colaboración","Nachfrage zu einem Partnerschaftsvorschlag","Acompanhamento de proposta de parceria","Seguito a una proposta di partnership"],"Follow-up in a customer support thread":["Suite d’un échange avec l’assistance clients","Seguimiento de un hilo de atención al cliente","Rückmeldung in einem Kundensupport-Verlauf","Acompanhamento de conversa de suporte","Seguito di una conversazione di assistenza"],"Billing statement from a finance sender":["Relevé de facturation envoyé par la comptabilité","Extracto de facturación de un remitente financiero","Abrechnung von einem Finanzkontakt","Extrato de cobrança de um remetente financeiro","Estratto di fatturazione da un mittente amministrativo"]},HW=["fr","es","de","pt","it"];function H(a){const e=HW.indexOf(Da().language);return e<0?a:BW[a]?.[e]||Zb(a)}function GW(a,e,n){return new Promise((s,o)=>{const l=new XMLHttpRequest;l.open("POST",`/api/chat/upload?id=${encodeURIComponent(a)}&name=${encodeURIComponent(e.name)}`),l.upload.onprogress=d=>{d.lengthComputable&&n(Math.min(99,Math.round(d.loaded/d.total*100)))},l.onload=()=>{if(l.status>=200&&l.status<300)s();else{let d="";try{d=JSON.parse(l.responseText).error}catch{}o(new Error(d||`${e.name} could not be added.`))}},l.onerror=()=>o(new Error(`${e.name} could not be added. Check the connection and try again.`)),l.send(e)})}const VW=a=>a.url||`/api/chat/file?id=${encodeURIComponent(a.id)}`;async function qW(a){if(a.sample)return new Blob([a.sample],{type:a.type});const e=await fetch(VW(a));if(!e.ok){const n=await e.json().catch(()=>({}));throw new Error(n.error||"This attachment is unavailable. Remove it and add it again.")}return e.blob()}async function VC(a,e=!1){const n=e?null:window.open("","_blank");try{const s=await qW(a),o=URL.createObjectURL(s);if(n)n.location.href=o;else{const l=document.createElement("a");l.href=o,l.download=a.name,l.click()}setTimeout(()=>URL.revokeObjectURL(o),6e4)}catch(s){throw n?.close(),s}}const Pb=a=>a===0?"":a>=1024*1024?`${(a/1024/1024).toFixed(1)} MB`:`${Math.max(1,Math.ceil(a/1024))} KB`,WW=new Set(["B","STRONG","I","EM","U","S","STRIKE","DEL","BR","P","DIV","SPAN","FONT","UL","OL","LI","A","BLOCKQUOTE"]),YW=new Set(["color","background-color","font-size","font-weight","font-style","text-decoration","text-decoration-line"]);function qC(a){const e=document.createElement("div");return e.textContent=a,e.innerHTML.replace(/\n/g,"
")}function NN(a){const e=new DOMParser().parseFromString(`
${a}
`,"text/html"),n=e.body.firstElementChild,s=o=>{for(const l of Array.from(o.children)){if(["SCRIPT","STYLE","IFRAME","OBJECT","EMBED","IMG","SVG","FORM","INPUT","BUTTON"].includes(l.tagName)){l.remove();continue}if(s(l),!WW.has(l.tagName)){l.replaceWith(...Array.from(l.childNodes));continue}for(const d of Array.from(l.attributes)){const h=d.name.toLowerCase();if(!(h==="href"&&l.tagName==="A"&&/^(https?:|mailto:)/i.test(d.value.trim()))){if(h==="style"){const m=d.value.split(";").map(p=>p.trim()).filter(p=>YW.has(p.split(":")[0]?.trim().toLowerCase())&&!/url\(|expression/i.test(p));if(m.length){l.setAttribute("style",m.join(";"));continue}}(h==="color"||h==="size")&&l.tagName==="FONT"||l.removeAttribute(d.name)}}l.tagName==="A"&&(l.setAttribute("target","_blank"),l.setAttribute("rel","noopener noreferrer"))}};return s(n),n.innerHTML}const XW=["#111827","#6b7280","#dc2626","#ea580c","#ca8a04","#16a34a","#0d9488","#2563eb","#7c3aed","#db2777"],KW=["#fef08a","#bbf7d0","#a5f3fc","#bfdbfe","#fbcfe8","#fed7aa"],JW=[["2","Small"],["3","Normal"],["5","Large"],["6","Huge"]];function ZW({html:a,text:e,disabled:n,placeholder:s,onChange:o}){const l=C.useRef(null),d=C.useRef(null),[h,m]=C.useState({}),[p,y]=C.useState(""),[v,x]=C.useState("");C.useEffect(()=>{l.current&&(l.current.innerHTML=NN(a||qC(e||"")))},[]),C.useEffect(()=>{const R=()=>{const N=getSelection();N&&N.rangeCount&&l.current?.contains(N.anchorNode)&&(d.current=N.getRangeAt(0).cloneRange(),m(Object.fromEntries(["bold","italic","underline","strikeThrough","insertUnorderedList","insertOrderedList"].map(I=>[I,document.queryCommandState(I)]))))};return document.addEventListener("selectionchange",R),()=>document.removeEventListener("selectionchange",R)},[]);const S=()=>{const R=l.current;R&&o(R.innerHTML,R.innerText.replace(/\n{3,}/g,` `).trim())},M=()=>{const R=l.current;if(!R)return;R.focus();const N=getSelection();d.current&&N&&(N.removeAllRanges(),N.addRange(d.current))},w=(R,N)=>{M(),document.execCommand("styleWithCSS",!1,"true"),!document.execCommand(R,!1,N)&&R==="hiliteColor"&&document.execCommand("backColor",!1,N),S()},E=R=>R.preventDefault(),A=(R,N,I)=>t.jsx("button",{type:"button",className:h[R]?"on":"","aria-pressed":!!h[R],title:H(N),"aria-label":H(N),disabled:n,onMouseDown:E,onClick:()=>w(R),children:t.jsx(I,{size:15})},R);function k(){const R=v.trim();if(!R){y("");return}const N=/^(https?:|mailto:)/i.test(R)?R:R.includes("@")&&!R.includes("/")?`mailto:${R}`:`https://${R}`;M();const I=getSelection();I&&I.isCollapsed?document.execCommand("insertHTML",!1,`${qC(R)}`):document.execCommand("createLink",!1,N),l.current?.querySelectorAll("a").forEach(z=>{z.target="_blank",z.rel="noopener noreferrer"}),y(""),x(""),S()}return t.jsxs("div",{className:`rich-editor ${n?"disabled":""}`,children:[t.jsxs("div",{className:"rich-toolbar",role:"toolbar","aria-label":H("Formatting"),children:[A("bold","Bold",iU),A("italic","Italic",vU),A("underline","Underline",VU),A("strikeThrough","Strikethrough",HU),t.jsx("i",{className:"rich-sep"}),t.jsxs("select",{"aria-label":H("Text size"),title:H("Text size"),disabled:n,defaultValue:"",onChange:R=>{w("fontSize",R.target.value),R.target.value=""},children:[t.jsx("option",{value:"",disabled:!0,children:H("Size")}),JW.map(([R,N])=>t.jsx("option",{value:R,children:H(N)},R))]}),t.jsxs("span",{className:"rich-pop",children:[t.jsx("button",{type:"button",title:H("Text colour"),"aria-label":H("Text colour"),"aria-expanded":p==="color",disabled:n,onMouseDown:E,onClick:()=>y(p==="color"?"":"color"),children:t.jsx(aU,{size:15})}),p==="color"&&t.jsx("span",{className:"rich-swatches",children:XW.map(R=>t.jsx("button",{type:"button",style:{background:R},"aria-label":R,onMouseDown:E,onClick:()=>{w("foreColor",R),y("")}},R))})]}),t.jsxs("span",{className:"rich-pop",children:[t.jsx("button",{type:"button",title:H("Highlight"),"aria-label":H("Highlight"),"aria-expanded":p==="mark",disabled:n,onMouseDown:E,onClick:()=>y(p==="mark"?"":"mark"),children:t.jsx(gU,{size:15})}),p==="mark"&&t.jsxs("span",{className:"rich-swatches",children:[KW.map(R=>t.jsx("button",{type:"button",style:{background:R},"aria-label":R,onMouseDown:E,onClick:()=>{w("hiliteColor",R),y("")}},R)),t.jsx("button",{type:"button",className:"none","aria-label":H("No highlight"),title:H("No highlight"),onMouseDown:E,onClick:()=>{w("hiliteColor","transparent"),y("")},children:t.jsx(da,{size:12})})]})]}),t.jsx("button",{type:"button",title:H("Link"),"aria-label":H("Link"),"aria-expanded":p==="link",disabled:n,onMouseDown:E,onClick:()=>{y(p==="link"?"":"link"),x("")},children:t.jsx(SU,{size:15})}),t.jsx("i",{className:"rich-sep"}),A("insertUnorderedList","Bulleted list",wj),A("insertOrderedList","Numbered list",EU),t.jsx("button",{type:"button",title:H("Quote"),"aria-label":H("Quote"),disabled:n,onMouseDown:E,onClick:()=>w("formatBlock","blockquote"),children:t.jsx(PU,{size:15})}),t.jsx("button",{type:"button",title:H("Clear formatting"),"aria-label":H("Clear formatting"),disabled:n,onMouseDown:E,onClick:()=>{w("removeFormat"),w("unlink")},children:t.jsx(IU,{size:15})})]}),p==="link"&&t.jsxs("div",{className:"rich-link",children:[t.jsx("input",{autoFocus:!0,value:v,onChange:R=>x(R.target.value),onKeyDown:R=>{R.key==="Enter"&&(R.preventDefault(),k()),R.key==="Escape"&&y("")},placeholder:"https://","aria-label":H("Link address")}),t.jsxs("button",{type:"button",onClick:k,children:[t.jsx(Kt,{size:14}),H("Add link")]}),t.jsx("button",{type:"button",onClick:()=>{w("unlink"),y("")},children:H("Remove link")})]}),t.jsx("div",{ref:l,className:"rich-area",contentEditable:!n,suppressContentEditableWarning:!0,role:"textbox","aria-multiline":"true","aria-label":H("Message"),"data-placeholder":s,onInput:S,onBlur:S,onPaste:R=>{R.preventDefault(),document.execCommand("insertText",!1,R.clipboardData.getData("text/plain")),S()},onKeyDown:R=>{(R.metaKey||R.ctrlKey)&&R.key.toLowerCase()==="k"&&(R.preventDefault(),y("link"))}})]})}function Xp({items:a,onError:e}){return a.length>0&&t.jsxs("section",{className:"mail-received-attachments",children:[t.jsxs("h3",{children:[t.jsx(fo,{size:16}),H("Attachments")," ",t.jsx("span",{children:a.length})]}),a.map(n=>t.jsxs("div",{className:"mail-received-file",children:[t.jsx(Si,{size:20}),t.jsxs("div",{children:[t.jsx("strong",{children:n.name}),t.jsx("small",{children:[n.type,Pb(n.size)].filter(Boolean).join(" · ")})]}),t.jsx("button",{onClick:()=>VC(n).catch(s=>e(H(s.message))),children:H("Open")}),t.jsx("button",{"aria-label":`${H("Save attachment")}: ${n.name}`,onClick:()=>VC(n,!0).catch(s=>e(H(s.message))),children:t.jsx(Eo,{size:17})})]},n.id))]})}function WC({id:a,onClose:e,onDiscard:n,onSent:s}){const o=Eu(),l=o.drafts.find(L=>L.id===a),d=o.emails.find(L=>L.id===l?.sourceId),[h,m]=C.useState(!!l?.cc||!!l?.bcc),[p,y]=C.useState(null),[v,x]=C.useState(""),[S,M]=C.useState(!1),[w,E]=C.useState(!1),A=Fi(p==="sending"),k=C.useRef(null),R=C.useRef(!1);if(!l)return null;const N=L=>{Ka(D=>{const P=D.drafts.find(F=>F.id===a);P&&Object.assign(P,L,{updated:new Date().toISOString()})}),x("")};async function I(L){const D=o.drafts.find(J=>J.id===a);if(!D||!L.length)return;if(Lb(D.attachments)+L.reduce((J,ie)=>J+ie.size,0)>CN){x(H("Attachments exceed 25 MB in total. Remove a file to continue."));return}const P=L.find(J=>J.size>20*1024*1024);if(P){x(`${P.name}: ${H("Each file must be 20 MB or smaller.")}`);return}const F=L.map(J=>({id:crypto.randomUUID(),name:J.name,type:J.type||"application/octet-stream",size:J.size,progress:0,status:"uploading"})),q=(J,ie)=>Ka(Q=>{const V=Q.drafts.find($=>$.id===a)?.attachments.find($=>$.id===J);V&&Object.assign(V,ie)});Ka(J=>{const ie=J.drafts.find(Q=>Q.id===a);ie&&ie.attachments.push(...F)}),await Promise.all(F.map(async(J,ie)=>{try{await GW(J.id,L[ie],Q=>q(J.id,{progress:Q})),q(J.id,{progress:100,status:"ready"})}catch(Q){q(J.id,{status:"failed"}),x(Q.message)}}))}async function z(){if(R.current||!l)return;const L=gW(l);if(L){x(H(L));return}R.current=!0,y("sending"),x(""),M(!1);try{const D=await PW({...structuredClone(l),html:l.html?NN(l.html):void 0});s(H(D))}catch(D){x(`${H("Could not send")}: ${D.message} ${H("Your draft is safe.")}`),M(!0),y(null)}finally{R.current=!1}}async function j(){if(!R.current){R.current=!0,y("saving");try{await LW(a),e()}catch(L){x(L.message)}finally{y(null),R.current=!1}}}return t.jsxs("section",{className:`mail-composer ${w?"dragging":""}`,"aria-label":H("Writing area"),onDragOver:L=>{L.preventDefault(),E(!0)},onDragLeave:L=>{L.currentTarget.contains(L.relatedTarget)||E(!1)},onDrop:L=>{L.preventDefault(),E(!1),!p&&l.mode!=="forward"&&I(Array.from(L.dataTransfer.files))},children:[t.jsxs("header",{children:[t.jsxs("span",{children:[t.jsx(yl,{size:17}),t.jsx("strong",{children:H(l.mode==="new"?"New email":l.mode==="reply"?"Reply":l.mode==="replyAll"?"Reply all":"Forward")})]}),t.jsx("button",{disabled:!!p,title:H("Close and keep draft"),"aria-label":H("Close and keep draft"),onClick:e,children:t.jsx(da,{size:18})})]}),t.jsxs("div",{className:"mail-composer-fields",children:[t.jsxs("label",{children:[t.jsx("span",{children:H("From")}),t.jsx("select",{"aria-label":H("Sending inbox"),disabled:!!p,value:l.fromInboxId,onChange:L=>N({fromInboxId:L.target.value}),children:go.map(L=>t.jsxs("option",{value:L.id,children:[H(L.name)," · ",L.address]},L.id))})]}),t.jsxs("div",{className:"mail-composer-to",children:[t.jsxs("label",{children:[t.jsx("span",{children:H("To")}),t.jsx("input",{"aria-label":H("To recipients"),value:l.to,disabled:!!p,onChange:L=>N({to:L.target.value}),placeholder:"name@example.com"})]}),t.jsxs("button",{"aria-expanded":h,disabled:!!p,onClick:()=>m(!h),children:["Cc / Bcc",t.jsx(Fd,{size:13})]})]}),h&&t.jsxs(t.Fragment,{children:[t.jsxs("label",{children:[t.jsx("span",{children:"Cc"}),t.jsx("input",{"aria-label":"Cc",disabled:!!p,value:l.cc,onChange:L=>N({cc:L.target.value}),placeholder:"name@example.com"})]}),t.jsxs("label",{children:[t.jsx("span",{children:"Bcc"}),t.jsx("input",{"aria-label":"Bcc",disabled:!!p,value:l.bcc,onChange:L=>N({bcc:L.target.value}),placeholder:"name@example.com"})]})]}),t.jsxs("label",{children:[t.jsx("span",{children:H("Subject")}),t.jsx("input",{"aria-label":H("Email subject"),disabled:!!p,value:l.subject,onChange:L=>N({subject:L.target.value})})]})]}),t.jsx(ZW,{html:l.html,text:l.body,disabled:!!p,placeholder:H(l.mode==="forward"?"Add a note (optional)":"Write your message…"),onChange:(L,D)=>N({html:L,body:D})},l.id),l.mode==="forward"&&d&&t.jsxs("details",{className:"mail-quoted-conversation",open:!0,children:[t.jsx("summary",{children:H("Forwarded message")}),t.jsx("strong",{children:d.subject}),t.jsxs("p",{children:[d.sender," <",d.address,">"]}),t.jsx("p",{children:d.body})]}),t.jsx("div",{className:"mail-compose-files",children:l.attachments.map(L=>t.jsxs("div",{className:`mail-compose-file ${L.status}`,children:[t.jsx(Si,{size:18}),t.jsxs("span",{children:[t.jsx("strong",{children:L.name}),t.jsx("small",{children:[Pb(L.size),H(L.status==="uploading"?"Adding attachment…":L.status==="failed"?"Attachment unavailable":"Ready")].filter(Boolean).join(" · ")}),L.status==="uploading"&&t.jsx("i",{children:t.jsx("b",{style:{width:`${L.progress}%`}})})]}),l.mode!=="forward"&&t.jsx("button",{disabled:!!p,"aria-label":`${H("Remove attachment")}: ${L.name}`,onClick:()=>N({attachments:l.attachments.filter(D=>D.id!==L.id)}),children:t.jsx(da,{size:15})})]},L.id))}),l.mode==="forward"?l.attachments.length>0&&t.jsxs("div",{className:"mail-attachment-hint",children:[t.jsx(fo,{size:14}),H("The original attachments go with it.")]}):t.jsxs("div",{className:"mail-attachment-hint",children:[t.jsx(fo,{size:14}),H("Drop files here or add attachments.")," ",t.jsxs("span",{children:[Pb(Lb(l.attachments))||"0 KB"," / 25 MB"]})]}),v&&t.jsxs("div",{className:"mail-composer-error",role:"alert",children:[t.jsx(hl,{size:17}),t.jsx("span",{children:v}),S&&t.jsx("button",{onClick:z,children:H("Try again")})]}),p==="sending"&&t.jsx(Ma,{label:"Sending it through Gmail",since:A,expect:15}),t.jsxs("footer",{children:[t.jsx("input",{hidden:!0,ref:k,type:"file",multiple:!0,"aria-label":H("Add attachments"),onChange:L=>{L.target.files&&I(Array.from(L.target.files)),L.target.value=""}}),t.jsx("button",{className:"primary-btn",onClick:z,disabled:!!p||l.attachments.some(L=>L.status==="uploading"),children:t.jsxs(Xn,{busy:p==="sending",label:"Sending",children:[t.jsx(yl,{size:16}),H("Send")]})}),l.mode!=="forward"&&t.jsx("button",{className:"mail-attach-button",title:H("Add attachments"),"aria-label":H("Add attachments"),disabled:!!p,onClick:()=>k.current?.click(),children:t.jsx(fo,{size:19})}),t.jsx("button",{className:"secondary-btn",disabled:!!p,onClick:j,children:t.jsx(Xn,{busy:p==="saving",label:"Saving draft",children:H("Save as draft")})}),t.jsxs("button",{className:"mail-discard",disabled:!!p,onClick:()=>n(l),children:[t.jsx(ti,{size:16}),H("Discard")]})]}),t.jsxs("div",{className:"mail-composer-status",children:[t.jsx(Kt,{size:13}),H("Saved as you write."),t.jsx("span",{children:H("Sent from your Gmail.")})]}),l.mode!=="new"&&l.mode!=="forward"&&d&&t.jsxs("details",{className:"mail-quoted-conversation",children:[t.jsx("summary",{children:H("Conversation underneath")}),t.jsxs("strong",{children:[d.sender," · ",d.subject]}),t.jsx("p",{children:d.body}),d.conversation.map(L=>t.jsxs("div",{children:[t.jsx("strong",{children:H("You")}),t.jsx("p",{children:L.body})]},L.id))]})]})}const _o=a=>a.toLocaleString();let YC=0;const XC=/\[([^\]\n]{1,300})\]\(((?:https?:|mailto:)[^\s)]+)\)|((?:https?:\/\/|www\.)[^\s<>"]+[^\s<>".,;:!?)\]'])/gi;function QW({text:a}){const e=[];let n=0,s;for(XC.lastIndex=0;s=XC.exec(a);){s.index>n&&e.push(a.slice(n,s.index));const o=s[2]||(s[3].startsWith("www.")?`https://${s[3]}`:s[3]);e.push(t.jsx("a",{href:o,target:"_blank",rel:"noopener noreferrer",title:s[1]?void 0:o,children:s[1]||_W(s[3])},s.index)),n=s.index+s[0].length}return n{if(a.length<=48)return a;try{const e=new URL(a.startsWith("www.")?`https://${a}`:a);return`${e.host.replace(/^www\./,"")}${e.pathname.length>1?e.pathname.slice(0,22)+"…":""}`}catch{return a.slice(0,45)+"…"}},$W=/^(on|am|le|el|il|em|op) .{4,300}(wrote|schrieb|a écrit|escribió|ha scritto|escreveu|schreef)\b.{0,200}:\s*$|^-{2,} ?(original message|forwarded message|ursprüngliche nachricht)/i;function eY(a){const e=[];for(const n of a.split(` `)){if($W.test(n.replace(/^[›> ]+/,"").trim()))break;/^[›>]/.test(n)||e.push(n)}return e.join(` `).replace(/\n{3,}/g,` `).trim()||a}function Kp({text:a}){return t.jsx("div",{className:"mail-body",children:a.split(` `).map((e,n)=>/^\s*[_=\-\u2013\u2014\u00b7*]{5,}\s*$/.test(e)?t.jsx("hr",{className:"mail-rule"},n):t.jsx("p",{className:e.startsWith("›")?"mail-quoted":void 0,children:e.replace(/^(› )+/,"")?t.jsx(QW,{text:e.replace(/^(› )+/,"")}):" "},n))})}function ny({value:a,size:e="small"}){const n=Math.max(0,Math.min(100,Math.round(a||0))),s=Math.round(n/20);return t.jsxs("span",{className:`mail-meter ${e} ${n>=90?"high":n>=70?"mid":"low"}`,role:"img","aria-label":`${H("Sure of this category")}: ${n}%`,title:`${H("Sure of this category")}: ${n}%`,children:[[0,1,2,3,4].map(o=>t.jsx("i",{className:oG.id==="agent-2")?.id||a[0]?.id||""),[J,ie]=C.useState(""),[Q,V]=C.useState(null),$=C.useRef(null),te=dl(l.emails),ne=$0(l.emails),Y=te.filter(G=>G.unread),T=l.emails.find(G=>G.id===p&&!G.deleted),_=l.sent.find(G=>G.id===v),ve=l.drafts.find(G=>G.id===R),je=(h==="check"&&!S?dl(l.emails).filter(G=>G.confidence<70):h==="unread"&&!S?dl(l.emails).filter(G=>G.unread):h==="reply"&&!S?dl(l.emails).filter(Yc):xW(l.emails,S?"all":h)).filter(G=>(!S||[G.subject,G.sender,G.address,G.preview].some(ke=>ke.toLowerCase().includes(S.toLowerCase())))&&(w==="all"||w==="unread"&&G.unread||w==="urgent"&&G.urgency>=8&&!G.handled||w==="addressed"&&G.handled)).sort((G,ke)=>ke.at.localeCompare(G.at)),Je=G=>G.threadId||G.id,xe=G=>l.emails.filter(ke=>!ke.deleted&&Je(ke)===Je(G)&&!!ke.archived==!!G.archived),ee=new Set,Ce=je.filter(G=>{const ke=Je(G);return ee.has(ke)?!1:(ee.add(ke),!0)}),Ze=G=>new Set(G.map(Je)).size,le=G=>Array.from(new Set(G.flatMap(ke=>{const pt=l.emails.find(Mt=>Mt.id===ke);return pt?xe(pt).map(Mt=>Mt.id):[ke]}))),qe=l.drafts.filter(G=>!S||[G.to,G.subject,G.body].some(ke=>ke.toLowerCase().includes(S.toLowerCase()))),xt=l.sent.filter(G=>!S||[G.to,G.subject,G.body].some(ke=>ke.toLowerCase().includes(S.toLowerCase()))),se=A.filter(G=>Ce.some(ke=>ke.id===G)),Pe=Ce.length>0&&se.length===Ce.length;C.useEffect(()=>()=>{$.current&&clearTimeout($.current)},[]);const[mt,it]=C.useState(60);C.useEffect(()=>{k([]),it(60)},[h,S,w]);const[at,Be]=C.useState(!1),[We,ue]=C.useState(!1),[ft,Re]=C.useState([]),[K,B]=C.useState("");C.useEffect(()=>{if(Re([]),Be(!1),ue(!1),!p)return;let G=!0;return B("loading"),UW(p,ke=>{G&&Re(ke.length>1?ke:[])}).then(ke=>{G&&(Re(ke.length>1?ke:[]),B(""))}).catch(()=>{G&&B("failed")}),()=>{G=!1}},[p]);const pe=ft.findIndex(G=>G.id===p),Ae=pe>0?ft.slice(0,pe):[],Ne=pe>=0?ft.slice(pe+1):[],be=C.useRef(new Date().toISOString()),ot=C.useRef(null);C.useEffect(()=>{const G=l.learned;if(!G||G.at{const G=l.checking;if(!Ve.current||!G||G.running||!G.at)return;if(Ve.current=!1,G.error){L(`${H("Could not check Gmail")}: ${G.error}`);return}const ke=[G.new?`${G.new} ${H(G.new===1?"new email sorted":"new emails sorted")}`:H("No new mail"),G.removed?`${G.removed} ${H("deleted in Gmail and removed here")}`:"",G.changed?`${G.changed} ${H("changed in Gmail and updated here")}`:""].filter(Boolean);ut(ke.join(". ")+".")},[l.checking?.running,l.checking?.at]),C.useEffect(()=>{ty()},[]),C.useEffect(()=>{h==="sent"&&ty()},[h]),C.useEffect(()=>{d.view!=="Mail"||d.stamp===YC||(YC=d.stamp,m(d.section==="unread"?"unread":"all"),E("all"),M(""),x(""),d.id?re(d.id):(y(""),requestAnimationFrame(()=>document.querySelector(".mail-workspace")?.scrollIntoView({behavior:"smooth",block:"start"}))))},[d.stamp]);function ut(G,ke){z(G),L(""),$.current&&clearTimeout($.current),V(ke?()=>ke:null),ke&&($.current=setTimeout(()=>V(null),8e3))}function re(G){y(G),x("");const ke=l.emails.find(Mt=>Mt.id===G),pt=ke?xe(ke).filter(Mt=>Mt.id!==G&&Mt.unread).map(Mt=>Mt.id):[];vl(Mt=>{Mt.emails.forEach(Vt=>{(Vt.id===G||pt.includes(Vt.id))&&(Vt.unread=!1)})}),pt.forEach(Mt=>wt("/api/mail/open",{id:Mt}).catch(()=>{})),lt(G),window.innerWidth<=700&&requestAnimationFrame(()=>document.querySelector(".mail-reader")?.scrollIntoView({behavior:"auto",block:"start"}))}const[Se,He]=C.useState({});function lt(G,ke=2){He(pt=>({...pt,[G]:"loading"})),wt("/api/mail/open",{id:G}).then(pt=>{wW(pt.email),He(Mt=>{const Vt={...Mt};return delete Vt[G],Vt})}).catch(()=>{ke>1?setTimeout(()=>lt(G,ke-1),2500):He(pt=>({...pt,[G]:"failed"}))})}function tt(G){m(G),y(""),x(""),k([])}function ct(G,ke,pt){if(!ke.length)return;L("");let Mt;if(G==="move"){const bn=new Date(Date.now()-12e4).toISOString();Ka(Ta=>{Mt=PC(Ta,ke,G,pt)});const fa=()=>{ot.current=null,Ka(Ta=>{IC(Ta,Mt),Ta.corrections=Ta.corrections.filter(ba=>!(ke.includes(ba.emailId)&&ba.at>=bn))}),z(H("Action undone.")),V(null)};ot.current={revert:fa,at:Date.now()},ut(H(ay[G]),fa),k([]);return}vl(bn=>{Mt=PC(bn,ke,G)}),k([]),["archive","delete"].includes(G)&&y("");const Vt=()=>vl(bn=>IC(bn,Mt));if(G==="delete"){const bn=NW(ke,fa=>{z(""),L(`${H("Could not move to Trash in Gmail")}: ${fa}`)});ut(H(ay[G]),()=>{DW(bn),Vt(),z(H("Action undone.")),V(null)});return}const hn=tY[G];ut(H(ay[G]),hn?()=>{Vt(),z(H("Action undone.")),V(null),GC(hn,ke).catch(bn=>L(`${H("Could not update Gmail")}: ${bn.message}`))}:void 0),GC(G,ke).catch(bn=>{Vt(),z(""),V(null),L(`${H("Could not update Gmail")}: ${bn.message} ${H("Your mail is unchanged.")}`)})}function fe(G,ke,pt){const Mt=l.drafts.find(hn=>hn.sourceId&&hn.sourceId===ke?.id&&hn.mode===G);if(Mt&&!pt){N(Mt.id);return}const Vt=vW(G,ke);pt&&(Vt.body=pt),Ka(hn=>{hn.drafts.unshift(Vt)}),N(Vt.id),L(""),ke&&y(ke.id)}function oe(G){Ka(ke=>{ke.drafts=ke.drafts.filter(pt=>pt.id!==G.id)}),N(""),ut(H("Draft discarded."),()=>{Ka(ke=>{ke.drafts.some(pt=>pt.id===G.id)||ke.drafts.unshift(G)}),z(H("Draft restored.")),V(null)})}const Fe={id:R,onClose:()=>{N(""),ut(H("Draft saved. Continue it from Drafts."))},onDiscard:oe,onSent:G=>{N(""),ut(G)}};async function Xe(G){const ke=l.emails.find(Mt=>Mt.id===D);if(!ke)return;const pt=a.find(Mt=>Mt.id===F);try{await ch("/api/mail/draft",{id:ke.id,agentId:F,instruction:J.trim()}),P(""),ut(`${pt?.name||H("Agent")} · ${H(G==="composer"?"Writing a draft. Edit agent reply appears here when it is ready. Nothing is sent.":"Writing a draft. It will wait in Approval Inbox. Nothing is sent.")}`)}catch(Mt){L(Mt.message)}}const dt=G=>l.categories.find(ke=>ke.id===G),W=h==="all"?"All mail":h==="attention"?"Needs attention":h==="check"?"Worth checking":h==="unread"?"Unread":h==="reply"?"Needs a reply":h==="starred"?"Starred":h==="drafts"?"Drafts":h==="sent"?"Sent":h==="archived"?"Archived":h==="trash"?"Trash":dt(h)?.name||"All mail",U=G=>t.jsxs("div",{className:"mail-single-tools",children:[t.jsx("button",{title:H(G.unread?"Mark as read":"Mark as unread"),"aria-label":H(G.unread?"Mark as read":"Mark as unread"),onClick:()=>ct(G.unread?"read":"unread",le([G.id])),children:t.jsx(tw,{size:17})}),t.jsx("button",{title:H(G.handled?"Mark as needing attention":"Mark as addressed"),"aria-label":H(G.handled?"Mark as needing attention":"Mark as addressed"),onClick:()=>ct(G.handled?"unaddressed":"addressed",le([G.id])),children:t.jsx(nl,{size:17})}),t.jsx("button",{title:H(G.starred?"Unstar":"Star"),"aria-label":H(G.starred?"Unstar":"Star"),className:G.starred?"starred":"",onClick:()=>ct(G.starred?"unstar":"star",le([G.id])),children:t.jsx(zd,{size:17,fill:G.starred?"currentColor":"none"})}),G.archived?t.jsx("button",{title:H("Move back to the inbox"),"aria-label":H("Move back to the inbox"),onClick:()=>ct("unarchive",le([G.id])),children:t.jsx(Q1,{size:17})}):t.jsx("button",{title:H("Archive"),"aria-label":H("Archive"),onClick:()=>ct("archive",le([G.id])),children:t.jsx(sl,{size:17})}),t.jsx("button",{title:H("Delete"),"aria-label":H("Delete"),onClick:()=>ct("delete",le([G.id])),children:t.jsx(ti,{size:17})})]}),ce=!!ve&&(ve.mode==="new"||h==="drafts"||!T||ve.sourceId!==T.id);return t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"mail-stats",children:[t.jsxs("div",{className:"panel",children:[t.jsx("span",{children:H("Sorted mail")}),t.jsx("strong",{children:_o(Ze(te))}),t.jsx("small",{children:H("Across your categories")})]}),t.jsxs("div",{className:"panel",children:[t.jsx("span",{children:H("Needs attention")}),t.jsx("strong",{children:_o(Ze(ne))}),t.jsx("small",{children:H("Urgency 8 to 10")})]}),t.jsxs("div",{className:"panel",children:[t.jsx("span",{children:H("Sorted today")}),t.jsx("strong",{children:_o(te.filter(G=>new Date(G.at).toDateString()===new Date().toDateString()).length)}),t.jsxs("small",{children:[H("Latest arrival")," · ",Yn(l.emails[0]?.at||new Date().toISOString())]})]})]}),t.jsxs("div",{className:"mail-inbox-header",children:[t.jsxs("div",{children:[t.jsx("span",{className:"panel-kicker",children:H("YOUR INBOX")}),t.jsx("h2",{children:H("Everything in its place.")})]}),t.jsxs("div",{children:[t.jsxs("button",{className:"secondary-btn",onClick:e,children:[t.jsx(rs,{size:16}),H("Manage categories")]}),t.jsxs("button",{className:"primary-btn",onClick:()=>fe("new"),children:[t.jsx(jn,{size:17}),H("New email")]})]})]}),(I||j)&&t.jsxs("div",{className:`mail-feedback ${j?"mail-action-error":""}`,role:j?"alert":"status",children:[j?t.jsx(hl,{size:17}):t.jsx(Kt,{size:17}),t.jsx("span",{children:j||I}),Q&&!j&&t.jsxs("button",{className:"mail-undo",onClick:Q,children:[t.jsx(L2,{size:15}),H("Undo")]}),t.jsx("button",{"aria-label":H("Dismiss"),onClick:()=>{z(""),L(""),V(null)},children:t.jsx(da,{size:16})})]}),t.jsxs("div",{className:"mail-workspace mail-workspace-extended",children:[t.jsxs("aside",{className:"panel mail-folders",children:[t.jsxs("button",{className:"mail-folder-compose",onClick:()=>fe("new"),children:[t.jsx(jn,{size:17}),t.jsx("span",{children:H("New email")})]}),t.jsx("span",{className:"panel-kicker",children:H("SMART FOLDERS")}),[{id:"all",name:"All mail",Icon:Jd,count:Ze(te)},{id:"unread",name:"Unread",Icon:ei,count:Ze(Y)},{id:"reply",name:"Needs a reply",Icon:hd,count:Ze(te.filter(Yc))},{id:"attention",name:"Needs attention",Icon:rl,count:Ze(ne)},{id:"check",name:"Worth checking",Icon:ly,count:Ze(te.filter(G=>G.confidence<70))},{id:"starred",name:"Starred",Icon:zd,count:Ze(l.emails.filter(G=>G.starred&&!G.deleted))},{id:"drafts",name:"Drafts",Icon:uy,count:l.drafts.length},{id:"sent",name:"Sent",Icon:yl,count:-1}].map(G=>t.jsxs("button",{className:h===G.id?"selected":"",onClick:()=>tt(G.id),title:G.id==="check"?H("Emails sorted with less than 70% certainty"):void 0,children:[t.jsx(G.Icon,{size:17}),t.jsx("span",{children:H(G.name)}),G.count>=0&&t.jsx("b",{children:_o(G.count)})]},G.id)),t.jsxs("div",{className:"mail-folder-divider",children:[t.jsx("span",{children:H("CATEGORIES")}),t.jsx("button",{"aria-label":H("Manage categories"),onClick:e,children:t.jsx(rs,{size:14})})]}),l.categories.map(G=>{const ke=te.filter(pt=>pt.categoryId===G.id);return t.jsxs("button",{className:`mail-folder-category ${h===G.id?"selected":""}`,onClick:()=>tt(G.id),children:[t.jsx("i",{style:{background:G.color}}),t.jsxs("span",{className:"mail-folder-name",children:[H(G.name),t.jsxs("small",{children:[_o(Ze(ke.filter(pt=>pt.unread)))," ",H("unread")]})]}),t.jsx("b",{children:Ze(ke)})]},G.id)}),t.jsx("div",{className:"mail-folder-divider",children:t.jsx("span",{children:H("MAIL FOLDERS")})}),t.jsxs("button",{className:h==="archived"?"selected":"",onClick:()=>tt("archived"),children:[t.jsx(sl,{size:17}),t.jsx("span",{children:H("Archived")}),t.jsx("b",{children:_o(l.emails.filter(G=>G.archived&&!G.deleted).length)})]}),t.jsxs("div",{className:"mail-folder-legend",children:[t.jsx("div",{className:"mail-folder-divider",children:t.jsx("span",{children:H("LEGEND")})}),t.jsxs("div",{className:"mail-legend-row",children:[t.jsx(ny,{value:60}),t.jsx("span",{children:H("Dots and % show how sure the sorting is of each category.")})]})]})]}),t.jsxs("section",{className:"panel mail-list",children:[t.jsxs("div",{className:"mail-list-top",children:[t.jsxs("h3",{children:[H(S?"Search results":W)," ",t.jsx("span",{children:h==="drafts"?qe.length:h==="sent"?xt.length:Ce.length})]}),t.jsxs("div",{className:"mail-list-tools",children:[!["drafts","sent"].includes(h)&&t.jsxs("small",{title:H("unread across all mail"),children:[_o(Ze(Y))," ",H("unread")]}),t.jsxs("button",{className:"mail-check-now",disabled:!!l.checking?.running,onClick:()=>{Ve.current=!0,L(""),FW().catch(G=>L(G.message))},title:l.lastSync?.at?`${H("Last checked with Gmail")}: ${Yn(l.lastSync.at)}`:H("Check Gmail for new mail now"),children:[t.jsx(xl,{size:14,className:l.checking?.running?"spinning":""}),H(l.checking?.running?"Checking…":"Check now"),l.checking?.running&&t.jsx(vi,{since:null})]})]})]}),t.jsxs("label",{className:"mail-search",children:[t.jsx(vo,{size:16}),t.jsx("input",{"aria-label":H("Search all mail"),placeholder:H("Search all mail"),value:S,onChange:G=>M(G.target.value)})]}),!["drafts","sent"].includes(h)&&t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"mail-filters",children:["all","unread","urgent","addressed"].map(G=>t.jsx("button",{"aria-pressed":w===G,className:w===G?"selected":"",onClick:()=>E(G),children:H(G==="all"?"All":G==="unread"?"Unread":G==="urgent"?"Urgent":"Addressed")},G))}),t.jsxs("label",{className:"mail-select-view",children:[t.jsx("input",{type:"checkbox",checked:Pe,onChange:()=>k(Pe?[]:Ce.map(G=>G.id))}),t.jsx("span",{children:se.length?`${se.length} ${H("selected")}`:H("Select all in this view")})]})]}),se.length>0&&t.jsxs("div",{className:"mail-bulk-actions","aria-label":H("Selected mail actions"),children:[[{a:"read",text:"Mark as read",Icon:tw},{a:"unread",text:"Mark as unread",Icon:ei},{a:"addressed",text:"Mark as addressed",Icon:nl},{a:h==="starred"?"unstar":"star",text:h==="starred"?"Unstar":"Star",Icon:zd},{a:h==="archived"?"unarchive":"archive",text:h==="archived"?"Move back to the inbox":"Archive",Icon:h==="archived"?Q1:sl},{a:"delete",text:"Delete",Icon:ti}].map(G=>t.jsx("button",{title:H(G.text),"aria-label":H(G.text),onClick:()=>ct(G.a,le(se)),children:t.jsx(G.Icon,{size:17})},G.a)),t.jsxs("select",{"aria-label":H("Move selection to category"),value:"",onChange:G=>ct("move",le(se),G.target.value),children:[t.jsx("option",{value:"",disabled:!0,children:H("Move to category")}),l.categories.map(G=>t.jsx("option",{value:G.id,children:H(G.name)},G.id))]})]}),t.jsx("div",{className:"mail-messages",children:h==="drafts"?qe.length?qe.map(G=>t.jsxs("div",{className:"mail-draft-list-row",children:[t.jsxs("button",{className:"mail-message",onClick:()=>N(G.id),children:[t.jsxs("div",{className:"mail-message-top",children:[t.jsx(uy,{size:17}),t.jsxs("strong",{children:[H("Draft")," · ",G.to||H("No recipient yet")]})]}),t.jsx("h4",{children:G.subject||H("No subject yet")}),t.jsx("p",{children:G.body||H("Continue writing your message.")}),t.jsx("small",{children:Yn(G.updated)})]}),t.jsx("button",{"aria-label":`${H("Delete draft")}: ${G.subject}`,onClick:()=>oe(G),children:t.jsx(ti,{size:16})})]},G.id)):t.jsx(iy,{icon:"drafts",title:"No unfinished emails",detail:"Messages you save or close while writing will wait here."}):h==="sent"?l.sentLoading&&!xt.length?t.jsxs("div",{className:"mail-empty",children:[t.jsx(Jt,{size:24,className:"spinning"}),t.jsxs("strong",{children:[H("Reading your sent mail from Gmail…"),t.jsx(vi,{since:null})]})]}):l.sentError&&!xt.length?t.jsxs("div",{className:"mail-empty",children:[t.jsx(hl,{size:24}),t.jsx("strong",{children:H("Sent mail could not be read")}),t.jsx("p",{children:l.sentError}),t.jsx("button",{className:"secondary-btn",onClick:()=>ty(),children:H("Try again")})]}):xt.length?xt.map(G=>t.jsxs("button",{className:`mail-message ${v===G.id?"selected":""}`,onClick:()=>{x(G.id),y(""),IW(G.id)},children:[t.jsxs("div",{className:"mail-message-top",children:[t.jsx(yl,{size:17}),t.jsxs("strong",{children:[H("To"),": ",G.to]})]}),t.jsx("h4",{children:G.subject}),t.jsx("p",{children:G.body}),t.jsx("small",{children:Yn(G.sentAt)})]},G.id)):t.jsx(iy,{icon:"sent",title:"Your next email starts here",detail:"Messages sent from Laboratorio or Gmail will appear in Sent."}):Ce.length?t.jsxs(t.Fragment,{children:[Ce.slice(0,mt).map(G=>{const ke=dt(G.categoryId),pt=xe(G);return t.jsxs("div",{className:`mail-message-row ${pt.some(Mt=>Mt.unread)?"unread":""} ${pt.some(Mt=>Mt.id===p)?"selected":""}`,children:[t.jsx("label",{className:"mail-row-checkbox",children:t.jsx("input",{type:"checkbox","aria-label":`${H("Select email")}: ${G.subject}`,checked:se.includes(G.id),onChange:Mt=>k(Mt.target.checked?[...A,G.id]:A.filter(Vt=>Vt!==G.id))})}),t.jsxs("button",{className:"mail-message",onClick:()=>re(G.id),children:[t.jsxs("div",{className:"mail-message-top",children:[t.jsx("span",{className:"mail-avatar",style:{"--mail-category":ke?.color},children:G.sender.slice(0,1)}),t.jsx("strong",{children:G.sender}),pt.length>1&&t.jsx("span",{className:"mail-thread-count",title:`${pt.length} ${H("messages in this conversation")}`,children:pt.length}),t.jsx("time",{className:"mail-row-time",children:Yn(G.at)}),G.starred&&t.jsx(zd,{size:13,className:"mail-star-mark",fill:"currentColor"}),t.jsxs("span",{className:"mail-category-chip",children:[t.jsx("i",{style:{background:ke?.color}}),H(ke?.name||"Other")]})]}),t.jsx("h4",{children:G.subject}),t.jsx("p",{children:G.preview}),t.jsxs("div",{className:"mail-message-bottom",children:[t.jsxs("span",{className:`mail-urgency ${G.urgency>=8?"high":G.urgency>=5?"medium":""}`,title:H("8 to 10 goes to Needs attention."),children:[H("Urgency")," ",G.urgency,"/10"]}),Yc(G)&&t.jsxs("span",{className:"mail-needs-reply",title:`${H("Someone seems to be waiting for your answer")} (${G.needsReply}%)`,children:[t.jsx(hd,{size:13}),H("Needs a reply")]}),G.youReplied?t.jsxs("span",{className:"mail-replied",title:H("You replied to this email"),children:[t.jsx(hd,{size:13}),H("Replied")]}):G.replyToYou&&t.jsxs("span",{className:"mail-replied answer",title:H("This email answers something you sent"),children:[t.jsx(nw,{size:13}),H("Replies to you")]}),G.handled&&t.jsx("span",{className:"mail-addressed",title:H("Addressed"),children:t.jsx(nl,{size:15})}),G.attachments.length>0&&t.jsx(fo,{size:13}),t.jsx(ny,{value:G.confidence})]})]})]},G.id)}),Ce.length>mt&&t.jsxs("button",{className:"secondary-btn mail-show-more",onClick:()=>it(G=>G+60),children:[H(`Show ${Math.min(60,Ce.length-mt)} more`)," · ",Ce.length-mt," ",H("left")]})]}):t.jsx(iy,{icon:h==="starred"?"starred":"mail",title:h==="starred"?"No starred mail":"No emails in this view",detail:h==="starred"?"Star important emails to keep them close.":"Try another folder or clear your filters."})})]}),t.jsxs("section",{className:`panel mail-reader ${T||_?"has-email":""}`,children:[t.jsxs("div",{className:"mail-reader-bar",children:[t.jsx("span",{children:H(_?"SENT EMAIL":"EMAIL DETAIL")}),t.jsxs("button",{"aria-label":H("Close email"),onClick:()=>{y(""),x(""),window.innerWidth<=700&&requestAnimationFrame(()=>document.querySelector(".mail-list")?.scrollIntoView({behavior:"auto",block:"start"}))},children:[t.jsx(eu,{size:16,className:"mail-back"}),t.jsx(da,{size:17})]})]}),_?t.jsx(t.Fragment,{children:t.jsxs("div",{className:"mail-reader-scroll",children:[t.jsx("h2",{children:_.subject}),t.jsxs("p",{className:"mail-sent-meta",children:[go.find(G=>G.id===_.fromInboxId)?.address&&t.jsxs(t.Fragment,{children:[H("From"),": ",go.find(G=>G.id===_.fromInboxId)?.address,t.jsx("br",{})]}),H("To"),": ",_.to,_.cc&&t.jsxs(t.Fragment,{children:[t.jsx("br",{}),"Cc: ",_.cc]}),_.bcc&&t.jsxs(t.Fragment,{children:[t.jsx("br",{}),"Bcc: ",_.bcc]}),t.jsx("br",{}),Yn(_.sentAt)]}),t.jsx(Kp,{text:_.body}),t.jsx(Xp,{items:_.attachments,onError:L}),_.url&&t.jsxs("button",{className:"secondary-btn",onClick:()=>window.open(_.url,"_blank","noopener"),children:[t.jsx(_i,{size:16}),H("Open in Gmail")]})]})}):T?t.jsx(t.Fragment,{children:t.jsxs("div",{className:"mail-reader-scroll",children:[t.jsxs("div",{className:"mail-reader-tags",children:[t.jsxs("span",{className:"mail-category-chip",children:[t.jsx("i",{style:{background:dt(T.categoryId)?.color}}),H(dt(T.categoryId)?.name||"Other")]}),t.jsxs("span",{className:`mail-urgency ${T.urgency>=8?"high":""}`,children:[H("Urgency")," ",T.urgency,"/10"]}),Yc(T)&&t.jsxs("span",{className:"mail-needs-reply",title:H("Someone seems to be waiting for your answer"),children:[t.jsx(hd,{size:13}),H("Needs a reply")," · ",T.needsReply,"%"]}),T.handled&&t.jsxs("span",{className:"mail-addressed",children:[t.jsx(nl,{size:15}),H("Addressed")]})]}),t.jsx("div",{className:"mail-reader-title",children:t.jsx("h2",{children:T.subject})}),t.jsxs("div",{className:"mail-sender",children:[t.jsx("span",{className:"mail-avatar",children:T.sender.slice(0,1)}),t.jsxs("div",{children:[t.jsx("strong",{children:T.sender}),t.jsxs("small",{children:[T.address," · ",Yn(T.at)]}),t.jsxs("small",{children:[H("To"),": ",T.to.join(", "),T.cc.length>0&&` · Cc: ${T.cc.join(", ")}`]})]})]}),U(T),Ae.length>0&&t.jsxs("section",{className:"mail-thread earlier","aria-label":H("Earlier in this conversation"),children:[t.jsxs("h3",{children:[H("Earlier in this conversation")," ",t.jsx("span",{children:Ae.length})]}),Ae.map(G=>t.jsx(KC,{m:G,onError:L},G.id))]}),(()=>{const G=Ae.length?eY(T.body):T.body,ke=G!==T.body;return!T.full&&Se[T.id]?Se[T.id]==="loading"?t.jsxs("div",{className:"mail-full-loading",children:[t.jsx(Jt,{size:15,className:"spinning"}),H("Loading the full email from Gmail…"),t.jsx(vi,{since:null}),t.jsx("p",{children:T.preview})]}):t.jsxs("div",{className:"mail-full-loading failed",children:[t.jsx(hl,{size:15}),H("The full email could not be loaded from Gmail."),t.jsx("button",{className:"secondary-btn",onClick:()=>lt(T.id),children:H("Try again")}),t.jsx("p",{children:T.preview})]}):t.jsxs(t.Fragment,{children:[t.jsx(Kp,{text:ke&&!at?G:T.body}),ke&&t.jsx("button",{className:"mail-quoted-toggle",onClick:()=>Be(!at),children:H(at?"Hide the quoted messages":"Show the quoted messages")})]})})(),Ne.length>0&&t.jsxs("section",{className:"mail-thread later","aria-label":H("Later in this conversation"),children:[t.jsxs("h3",{children:[H("Later in this conversation")," ",t.jsx("span",{children:Ne.length})]}),Ne.map(G=>t.jsx(KC,{m:G,open:!0,onError:L},G.id))]}),K==="loading"&&t.jsxs("p",{className:"mail-thread-note",children:[t.jsx(Jt,{size:13,className:"spinning"}),H("Reading the conversation from Gmail…"),t.jsx(vi,{since:null})]}),t.jsx(Xp,{items:T.attachments,onError:L}),(()=>{const G=bh().find(hn=>hn.kind==="Email draft"&&hn.sourceId===T.id),ke=T.alt?dt(T.alt.categoryId):void 0,pt=dt(T.categoryId),Mt=!!ke&&ke.id!==T.categoryId&&T.confidence<70,Vt=()=>RW(T.id).then(()=>ut(H("Kept. Laboratorio will learn from this."))).catch(hn=>L(hn.message));return t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"mail-reply-bar",children:[t.jsxs("button",{className:"primary-btn",onClick:()=>fe("reply",T),children:[t.jsx(hd,{size:16}),H("Reply")]}),t.jsxs("button",{className:"secondary-btn",onClick:()=>fe("replyAll",T),children:[t.jsx(nw,{size:16}),H("Reply all")]}),t.jsxs("button",{className:"secondary-btn",onClick:()=>fe("forward",T),children:[t.jsx(pU,{size:16}),H("Forward")]}),G?t.jsxs("button",{className:"mail-agent-btn ready",onClick:()=>fe("reply",T,G.body),children:[t.jsx(Ha,{size:15}),H("Edit agent reply")]}):T.draftRequested?t.jsxs("span",{className:"mail-agent-writing",children:[t.jsx(Jt,{size:14,className:"spinning"}),H("An agent is writing a draft…"),t.jsx(vi,{since:null})]}):t.jsxs(t.Fragment,{children:[T.draftError&&t.jsx("span",{className:"mail-agent-error",role:"status",children:H(T.draftError)}),t.jsxs("button",{className:"mail-agent-btn",title:H("An agent can prepare it. You decide whether it goes out."),onClick:()=>{P(T.id),ie("")},children:[t.jsx(Ha,{size:15}),H("Draft with an agent")]})]})]}),ve&&ve.sourceId===T.id&&!ce&&t.jsx(WC,{...Fe}),Mt&&t.jsxs("div",{className:"mail-unsure",children:[t.jsx(ly,{size:15}),t.jsxs("span",{children:[H("Not sure"),": ",t.jsx("strong",{children:H(pt?.name||"Other")})," ",H("or")," ",t.jsx("strong",{children:H(ke.name)}),"?"]}),t.jsxs("button",{onClick:Vt,children:[H("Keep")," ",H(pt?.name||"Other")]}),t.jsxs("button",{onClick:()=>ct("move",le([T.id]),ke.id),children:[H("Move to")," ",H(ke.name)]})]}),t.jsxs("div",{className:"mail-meta-bar",children:[t.jsxs("label",{className:"mail-cat-pick",children:[t.jsx("span",{children:H("Category")}),t.jsx("select",{"aria-label":H("Move to category"),value:T.categoryId,onChange:hn=>ct("move",le([T.id]),hn.target.value),children:l.categories.map(hn=>t.jsx("option",{value:hn.id,children:H(hn.name)},hn.id))})]}),t.jsx(ny,{value:T.confidence}),t.jsx("button",{className:"mail-why-toggle","aria-expanded":We,onClick:()=>ue(!We),children:H("Why?")}),t.jsx("span",{className:"mail-meta-gap"}),t.jsxs("button",{className:"mail-meta-btn",onClick:async()=>{ut(H(await s(T)?"Personal to-do created.":"Could not create the to-do. Please try again."))},children:[t.jsx(jn,{size:14}),H("Add to-do")]}),T.url&&t.jsxs("button",{className:"mail-meta-btn",onClick:()=>window.open(T.url,"_blank","noopener"),children:[t.jsx(_i,{size:14}),H("Open in Gmail")]})]}),We&&t.jsxs("p",{className:"mail-why-line",children:[t.jsx(Ha,{size:14}),H(T.reason),".",ke&&ke.id!==T.categoryId&&!Mt&&t.jsxs(t.Fragment,{children:[" ",H("Could also be")," ",H(ke.name)," (",T.alt.pct,"%)."]})]})]})})(),!ft.length&&T.conversation.length>0&&t.jsxs("section",{className:"mail-conversation",children:[t.jsx("h3",{children:H("Conversation")}),T.conversation.map(G=>t.jsxs("article",{children:[t.jsxs("header",{children:[t.jsxs("strong",{children:[H("You")," · ",go.find(ke=>ke.id===G.fromInboxId)?.address]}),t.jsxs("span",{children:[t.jsx(nl,{size:14}),H("Sent")," · ",Yn(G.sentAt)]})]}),t.jsxs("p",{children:[H("To"),": ",G.to]}),t.jsx(Kp,{text:G.body}),t.jsx(Xp,{items:G.attachments,onError:L})]},G.id))]})]})}):t.jsxs("div",{className:"mail-reader-placeholder",children:[t.jsx("span",{children:t.jsx(ei,{size:29})}),t.jsx("h3",{children:H("A clearer view starts here.")}),t.jsx("p",{children:H("Choose a message to read it, organize it, or ask an agent for help.")})]})]})]}),t.jsx(on,{open:ce,onClose:Fe.onClose,title:H("Your writing desk"),description:H("Your draft stays safe when you close this window."),wide:!0,children:t.jsx(WC,{...Fe})}),t.jsx(on,{open:!!D,onClose:()=>P(""),title:H("Ask an agent to draft a reply"),description:l.emails.find(G=>G.id===D)?.subject,wide:!0,children:t.jsxs("div",{className:"mail-modal-fields",children:[t.jsx("p",{children:H("The agent writes the reply and puts it in your Approval Inbox. Nothing is sent until you approve it there.")}),t.jsxs("label",{children:[H("Choose an agent"),t.jsx("select",{value:F,onChange:G=>q(G.target.value),children:a.map(G=>t.jsx("option",{value:G.id,children:G.name},G.id))})]}),t.jsxs("label",{children:[H("Your instruction (optional)"),t.jsx("textarea",{rows:4,maxLength:800,value:J,onChange:G=>ie(G.target.value),placeholder:H("For example, ask for the budget and proposed dates.")})]}),t.jsx("div",{className:"pro-actions right",children:t.jsxs("button",{className:"primary-btn",onClick:()=>Xe("approval"),children:[H("Prepare draft for approval"),t.jsx(Kn,{size:16})]})})]})})]})}function iy({icon:a,title:e,detail:n}){const s=a==="drafts"?uy:a==="sent"?yl:a==="starred"?zd:ei;return t.jsxs("div",{className:"mail-empty",children:[t.jsx(s,{size:26}),t.jsx("strong",{children:H(e)}),t.jsx("p",{children:H(n)})]})}function KC({m:a,open:e=!1,onError:n}){return t.jsxs("details",{className:`mail-thread-card ${a.mine?"mine":""}`,open:e,children:[t.jsxs("summary",{children:[t.jsx("span",{className:"mail-avatar",children:(a.mine?"Y":a.sender.slice(0,1)).toUpperCase()}),t.jsx("strong",{children:a.mine?H("You"):a.sender}),t.jsx("time",{children:Yn(a.at)}),!e&&t.jsx("em",{children:a.body.replace(/\[([^\]]*)\]\([^)]*\)/g,"$1").slice(0,110)})]}),t.jsx(Kp,{text:a.body}),t.jsx(Xp,{items:a.attachments,onError:n})]})}function DN(){Au();const a=EN(),[e,n]=C.useState(""),[s,o]=C.useState(""),[l,d]=C.useState(!1),[h,m]=C.useState(""),[p,y]=C.useState(!1),[v,x]=C.useState(!1);if(v)return t.jsxs("div",{className:"jev-offer is-done",role:"status",children:[t.jsx(Kt,{size:17}),t.jsx("p",{children:u("Jev now picks the model for every task: the light one for routine work, the strong one for demanding work. Change it any time in Settings, under Models.")})]});if(p||!a.keySet||a.enabled)return null;const S=R=>R.name?`${R.provider}|${R.name}`:"",M=e||S(a.light),w=s||S(a.strong),E=R=>{const N=is.find(I=>`${I.provider}|${I.name}`===R);return N?{name:N.name,provider:N.provider}:{}};async function A(){d(!0),m("");try{await rh({light:E(M),strong:E(w)}),await rh({enabled:!0}),x(!0)}catch(R){m(R.message)}d(!1)}const k=is.map(R=>t.jsxs("option",{value:`${R.provider}|${R.name}`,children:[R.name," · ",R.provider]},R.provider+R.name));return t.jsxs("section",{className:"jev-offer","aria-label":u("Smart model routing"),children:[t.jsxs("header",{children:[t.jsx(dh,{size:19}),t.jsxs("div",{children:[t.jsx("strong",{children:u("Let Jev pick the model too")}),t.jsx("p",{children:u("The same key can choose a light model for routine tasks and a strong one for demanding tasks, so you stop paying your strongest model for easy work. When Jev is not sure, it uses the strong one.")})]})]}),t.jsxs("div",{className:"jev-offer-models",children:[t.jsxs("label",{children:[u("Light model, for routine tasks"),t.jsxs("select",{"aria-label":u("Light model"),value:M,onChange:R=>n(R.target.value),children:[t.jsx("option",{value:"",children:u("Choose a model")}),k]})]}),t.jsxs("label",{children:[u("Strong model, for demanding tasks"),t.jsxs("select",{"aria-label":u("Strong model"),value:w,onChange:R=>o(R.target.value),children:[t.jsx("option",{value:"",children:u("Choose a model")}),k]})]})]}),t.jsxs("div",{className:"jev-offer-actions",children:[t.jsx("button",{className:"primary-btn",disabled:l||!M||!w,onClick:A,children:u(l?"Turning it on...":"Turn on model routing")}),t.jsx("button",{className:"text-btn",onClick:()=>y(!0),children:u("Not now")})]}),h&&t.jsx("p",{className:"jev-offer-note",children:u(h)})]})}const hr=a=>a.toLocaleString(Hn()),aY=a=>new Intl.NumberFormat(Hn(),{style:"currency",currency:"USD",minimumFractionDigits:2,maximumFractionDigits:2}).format(a),JC=a=>new Date(a).toLocaleString(Hn(),Kd({day:"numeric",month:"short",hour:"2-digit",minute:"2-digit"})),Nd=tl;function iY(){const a=Eu(),[e,n]=C.useState(!1),[s,o]=C.useState(""),[l,d]=C.useState(!1),[h,m]=C.useState("");async function p(){if(s.trim()){d(!0),m("");try{await rh({key:s.trim()}),await gl(),o(""),n(!1),m(H("Key saved. Mail can sort now."))}catch(v){m(v.message)}finally{d(!1)}}}const y=v=>v.catch(x=>m(x.message));return t.jsxs("div",{className:"settings-grid",children:[t.jsxs("section",{className:"panel settings-card",children:[t.jsxs("header",{children:[t.jsx(Ha,{size:20}),t.jsxs("div",{children:[t.jsx("h3",{children:H("Mail sorting")}),t.jsx("p",{children:H(a.keySet?"Jev sorts your email. About $0.00002 an email.":"Your Orchestrator’s model sorts your email. A Jev key makes it faster and cheaper: about $0.00002 an email.")})]})]}),t.jsxs("div",{className:"mail-settings-row",children:[t.jsxs("span",{children:[t.jsx("strong",{children:H(a.keySet?"Jev key is set":"Jev key (optional)")}),a.keySet&&a.keyProvider&&t.jsxs("small",{children:[H("Sorting runs through")," ",a.keyProvider,"."]})]}),t.jsx(_t,{tone:a.keySet?"green":"neutral",children:a.keySet?H("Key is set"):H("Using your default model")})]}),e?t.jsxs("form",{className:"mail-key-form",onSubmit:v=>{v.preventDefault(),p()},children:[t.jsx("input",{id:"settings-jev-key",type:"password",autoComplete:"off",autoFocus:!0,"aria-label":H("Paste your Jev key"),placeholder:H("OpenRouter or TypeSafe key"),value:s,onChange:v=>o(v.target.value)}),t.jsxs("div",{children:[t.jsx("button",{type:"submit",className:"primary-btn",disabled:l||!s.trim(),children:t.jsx(Xn,{busy:l,label:"Checking the key",children:H("Save key")})}),t.jsx("button",{type:"button",className:"text-btn",onClick:()=>{n(!1),o("")},children:H("Cancel")})]}),t.jsx("small",{children:H("No key yet? Create one at openrouter.ai/keys or console.typesafe.ai/keys. It is also used for Jev routing in Settings.")})]}):t.jsx("div",{children:t.jsxs("button",{className:"secondary-btn",onClick:()=>n(!0),children:[t.jsx(jn,{size:15}),H(a.keySet?"Change key":"Add key")]})}),h&&t.jsx("p",{className:"pro-small",role:"status",children:h}),a.keySet&&t.jsx(DN,{})]}),t.jsxs("section",{className:"panel settings-card",children:[t.jsxs("header",{children:[t.jsx(xl,{size:20}),t.jsxs("div",{children:[t.jsx("h3",{children:H("Staying in step with Gmail")}),t.jsxs("p",{children:[H("New mail is sorted on its own. Deletions and read changes made in Gmail follow every")," ",(a.interval??2)*3," ",H("minutes"),"."]})]})]}),t.jsxs("div",{className:"mail-switch-row mail-markread",children:[t.jsxs("span",{children:[t.jsx("strong",{children:H("Mark emails as read in Gmail when I open them here")}),t.jsx("small",{children:H("Off: Laboratorio never changes anything in Gmail apart from labels you switch on.")})]}),t.jsx("button",{className:"pref-switch",role:"switch","aria-label":H("Mark emails as read in Gmail when I open them here"),"aria-checked":a.markReadInGmail??!0,onClick:()=>y(jW(!(a.markReadInGmail??!0))),children:t.jsx("i",{})})]}),t.jsxs("label",{children:[H("Check Gmail for new mail every"),t.jsx("select",{value:a.interval??2,onChange:v=>y(TW(Number(v.target.value))),children:[2,5,15,30].map(v=>t.jsxs("option",{value:v,children:[v," ",H("minutes")]},v))})]}),t.jsxs("label",{children:[H("Download past mail from the last"),t.jsx("select",{value:a.sortDays,disabled:!!a.job?.kind,onChange:v=>y(CW(Number(v.target.value))),children:[7,30,90].map(v=>t.jsxs("option",{value:v,children:[v," ",H("days")]},v))})]}),t.jsxs("label",{children:[H("Keep mail for"),t.jsx("select",{value:a.retention??90,onChange:v=>y(MW(Number(v.target.value))),children:[[30,"30 days"],[90,"90 days"],[180,"6 months"],[365,"1 year"],[0,"Everything"]].map(([v,x])=>t.jsx("option",{value:v,disabled:Number(v)!==0&&Number(v){gl();const re=()=>{document.visibilityState==="visible"&&gl()};return window.addEventListener("focus",re),document.addEventListener("visibilitychange",re),()=>{window.removeEventListener("focus",re),document.removeEventListener("visibilitychange",re)}},[]);const o=s.job?.kind||null,[l,d]=C.useState(Date.now());C.useEffect(()=>{if(!o)return;const re=window.setInterval(()=>d(Date.now()),1e3);return()=>window.clearInterval(re)},[o]);const h=s.job,m=Math.max(0,Math.round(l/1e3-(h?.phaseStarted||l/1e3))),p=h?.kind?h.phase==="thinking"?Math.round(40+55*(1-Math.exp(-m/45))):h.phase==="reading"?Math.round((h.total?h.done/h.total:0)*(h.kind==="scanning"?40:45)):Math.round(45+55*(h.total?h.done/h.total:0)):0,[y,v]=C.useState(null),[x,S]=C.useState(""),[M,w]=C.useState(!1),[E,A]=C.useState(""),[k,R]=C.useState(!1),[N,I]=C.useState(!1),[z,j]=C.useState(""),[L,D]=C.useState(!1),[P,F]=C.useState(""),[q,J]=C.useState(""),[ie,Q]=C.useState(""),[V,$]=C.useState(""),[te,ne]=C.useState(""),[Y,T]=C.useState(""),[_,ve]=C.useState(""),je=s.connected,Je=!je&&!!s.connecting,xe=je,ee=s.stage!=="inbox"||L,Ce=s.categories.find(re=>re.id===P),Ze=s.categories.find(re=>re.id===q),le=s.categories.find(re=>re.id===V),qe=s.emails.length,xt=s.periodCounts?.[String(s.sortDays)]??yW(s.emails,s.sortDays),se=Math.max(.01,xt*(s.perEmail||24e-6));C.useEffect(()=>{if(o){v(o);return}y&&(s.job?.error?ve(s.job.error):y==="sorting"&&(D(!1),ve(H("Your mail is sorted."))),v(null))},[o,y,s.job?.error]);async function Pe(){const re=E.trim();if(re){I(!0),j("");try{await rh({key:re}),await gl(),A(""),w(!1),R(!0),ve(H("Key saved. Mail can sort now."))}catch(Se){j(Se.message)}finally{I(!1)}}}const mt=re=>HC({kind:re,done:0,total:re==="scanning"?250:s.periodCounts?.[String(s.sortDays)]||0,error:null,phase:re==="scanning"?"reading":"sorting",phaseStarted:Date.now()/1e3,log:[{at:new Date().toISOString(),text:H("Starting...")}]}),it=re=>HC({kind:null,done:0,total:0,error:re.message,log:[]}),at=s.accounts||[],Be=at.find(re=>re.id===s.account),We=at.length>1,ue=We&&!Be;async function ft(re){try{await kW(re),S(""),D(!1),ve(`${H("Mail will sort")} ${at.find(Se=>Se.id===re)?.email||""}.`)}catch(Se){ve(Se.message)}}const Re=async(re=!1)=>{ve(""),mt("scanning");try{await ch("/api/mail/discover"),re&&D(!0)}catch(Se){it(Se)}},K=async()=>{ve(""),mt("sorting");try{await ch("/api/mail/sort",{days:s.sortDays})}catch(re){it(re)}};function B(re,Se){Ka(He=>{const lt=He.categories.findIndex(ct=>ct.id===re),tt=lt+Se;lt<0||tt<0||tt>=He.categories.length-1||([He.categories[lt],He.categories[tt]]=[He.categories[tt],He.categories[lt]])})}function pe(re){re!==il&&(Ka(Se=>{Se.categories=Se.categories.filter(He=>He.id!==re),Se.emails.forEach(He=>{He.categoryId===re&&(He.categoryId=il)})}),ve(H("Messages moved to Other.")))}function Ae(){!q||!ie||q===ie||(Ka(re=>{const Se=re.categories.find(lt=>lt.id===q),He=re.categories.find(lt=>lt.id===ie);!Se||!He||(He.examples=[...new Set([...He.examples,...Se.examples])].slice(0,4),re.emails.forEach(lt=>{lt.categoryId===q&&(lt.categoryId=ie)}),re.categories=re.categories.filter(lt=>lt.id!==q))}),J(""),Q(""),ve(H("Categories merged.")))}function Ne(){const re=te.trim();if(!le||!re||!Y)return;const Se=Db();Ka(He=>{const lt=He.categories.findIndex(tt=>tt.id===V);He.categories.splice(lt+1,0,{...He.categories[lt],id:Se,name:re,description:"",examples:[Y],color:Nd[(lt+1)%Nd.length],gmailLabel:!1,autoDraft:!1,notify:!1,instructions:""}),He.emails.forEach(tt=>{tt.categoryId===V&&tt.sender===Y&&(tt.categoryId=Se)})}),$(""),ne(""),ve(H("Category split."))}const be=(re,Se)=>Ka(He=>{const lt=He.categories.find(tt=>tt.id===re);lt&&Object.assign(lt,Se)}),ot=s.categories,Ve=ot.map(re=>re.name.trim().toLocaleLowerCase()),ut=Ve.every(Boolean)&&new Set(Ve).size===Ve.length;return t.jsxs("div",{className:`mail-page ${s.stage==="inbox"&&!L?"mail-is-inbox":""}`,children:[t.jsxs("section",{className:"mail-hero",children:[t.jsxs("div",{className:"mail-hero-copy",children:[t.jsxs("span",{className:"mail-eyebrow",children:[t.jsx(Ha,{size:14}),H("A CALMER INBOX")]}),t.jsx("h2",{children:H("Mail, with the signal turned up.")}),t.jsx("p",{children:H("Your messages, organized around what matters to you. The final decisions stay yours.")}),t.jsxs("div",{className:"mail-hero-meta",children:[t.jsxs("span",{children:[t.jsx("span",{className:"mail-live-dot"}),Be?Be.email:H(je?"Gmail connected":Je?"Gmail connecting…":"Gmail not connected")]}),We&&Be&&s.stage!=="intro"&&t.jsx("button",{className:"mail-switch-inbox",onClick:()=>S(at.find(re=>re.id!==Be.id)?.id||""),children:H("Switch inbox")}),t.jsx("span",{children:H(s.keySet?"Sorted by Jev":"Sorted by your Orchestrator")})]})]}),t.jsxs("div",{className:"mail-hero-art","aria-hidden":"true",children:[t.jsx("div",{className:"mail-art-circle one"}),t.jsx("div",{className:"mail-art-circle two"}),t.jsxs("div",{className:"mail-art-card back",children:[t.jsx("span",{}),t.jsx("span",{}),t.jsx("span",{})]}),t.jsxs("div",{className:"mail-art-card front",children:[t.jsx(ei,{size:23}),t.jsx("i",{}),t.jsx("span",{}),t.jsx("span",{}),t.jsx("b",{children:"09"})]})]})]}),!o&&!!s.job?.log?.length&&t.jsxs("details",{className:"panel mail-log-last",children:[t.jsx("summary",{children:H("Show what happened")}),t.jsx("ol",{className:"mail-log",children:s.job.log.map((re,Se)=>t.jsxs("li",{children:[t.jsx("time",{children:JC(re.at).split(", ").pop()}),t.jsx("span",{children:re.text})]},re.at+Se))})]}),_&&t.jsxs("div",{className:"mail-feedback",role:"status",children:[t.jsx(Kt,{size:16}),_,t.jsx("button",{"aria-label":H("Dismiss"),onClick:()=>ve(""),children:t.jsx(da,{size:14})})]}),k&&t.jsx(DN,{}),o&&t.jsxs("section",{className:"panel mail-progress",role:"status","aria-live":"polite",children:[t.jsx("div",{className:"mail-progress-icon",children:t.jsx(xl,{size:24})}),t.jsx("span",{className:"panel-kicker",children:H(o==="scanning"?"FINDING YOUR CATEGORIES":"SORTING YOUR MAIL")}),t.jsx("h2",{children:H(o==="scanning"?"Reading the shape of your inbox.":"Putting every message in its place.")}),t.jsxs("p",{children:[h?.phase==="thinking"?`${hr(h.done)} ${H("emails read. Your Orchestrator is proposing categories.")} ${hr(m)} s`:h?.phase==="reading"&&o==="sorting"?`${hr(h.done||0)} / ${hr(h.total||0)} ${H("emails read from Gmail")}`:`${hr(h?.done||0)} / ${hr(h?.total||0)} ${H(o==="scanning"?"recent emails read":"emails sorted")}`,h?.phase!=="thinking"&&t.jsx(vi,{since:h?.phaseStarted?h.phaseStarted*1e3:null})]}),t.jsx("div",{className:"mail-progress-track",children:t.jsx("i",{style:{width:`${p}%`}})}),!!h?.log?.length&&t.jsx("ol",{className:"mail-log","aria-live":"polite","aria-label":H("What is happening"),ref:re=>{re&&(re.scrollTop=re.scrollHeight)},children:h.log.slice(-14).map((re,Se)=>t.jsxs("li",{children:[t.jsx("time",{children:JC(re.at).split(", ").pop()}),t.jsx("span",{children:re.text})]},re.at+Se))}),t.jsx("small",{children:H(o==="scanning"?"Your Orchestrator reads the sender, subject and first lines of recent mail.":s.keySet?"Sender, subject and the start of each email go to Jev for sorting.":"Sender, subject and the start of each email go to your Orchestrator's model for sorting, 40 at a time, so the count moves in steps.")})]}),!o&&ee&&t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"mail-stepper",children:[t.jsxs("span",{className:xe?"complete":"current",children:[t.jsx("b",{children:"01"}),H("Connect")]}),t.jsx("i",{}),t.jsxs("span",{className:s.stage==="intro"?"current":s.stage==="review"?"complete":"",children:[t.jsx("b",{children:"02"}),H("Discover")]}),t.jsx("i",{}),t.jsxs("span",{className:s.stage==="review"||L?"current":"",children:[t.jsx("b",{children:"03"}),H("Shape categories")]}),t.jsx("i",{}),t.jsxs("span",{className:s.stage==="inbox"?"complete":"",children:[t.jsx("b",{children:"04"}),H("Sort")]})]}),s.stage==="intro"&&!L&&t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"mail-setup-intro",children:[t.jsx("span",{className:"panel-kicker",children:H("FIRST-TIME SETUP")}),t.jsx("h2",{children:H("Make room for the important things.")}),t.jsx("p",{children:H("Start by connecting Gmail. A Jev key is optional: it makes sorting faster and cheaper.")})]}),t.jsxs("div",{className:"mail-prereqs",children:[t.jsxs("article",{className:`panel mail-prereq ${je?"ready":""}`,children:[t.jsx("span",{className:"mail-prereq-icon",children:t.jsx(ei,{size:23})}),t.jsx(_t,{tone:je?"green":"amber",children:je?H("Ready"):Je?t.jsxs(t.Fragment,{children:[t.jsx(Jt,{className:"spin",size:12})," ",H("Connecting"),t.jsx(vi,{since:null})]}):H("Step 01")}),t.jsx("h3",{children:H(je?"Gmail is connected":Je?"Gmail is connecting…":"Gmail is not connected yet")}),t.jsx("p",{children:H(je?"Laboratorio reads your mail through it and never sends anything on its own.":Je?"You approved Gmail in Composio. Laboratorio is confirming the connection now; this card updates by itself in a few seconds.":"Connect Gmail in Integrations. Laboratorio reads your mail through it and never sends anything on its own.")}),je&&We&&t.jsxs("fieldset",{className:"mail-inboxes",children:[t.jsx("legend",{children:H("You have more than one Gmail account. Which inbox should Laboratorio sort?")}),at.map(re=>t.jsxs("label",{className:s.account===re.id?"selected":"",children:[t.jsx("input",{type:"radio",name:"mail-inbox",checked:s.account===re.id,onChange:()=>ft(re.id)}),t.jsxs("span",{children:[t.jsx("strong",{children:re.email||re.alias||re.id}),t.jsxs("small",{children:[re.alias?`${re.alias} · `:"",H(re.fast?"Fast: about 45 emails a second":"About 5 emails a second")]})]})]},re.id))]}),je&&!at.length&&s.accountsLoading&&t.jsx("p",{className:"pro-small",children:H("Checking your Gmail accounts...")}),!je&&!Je&&t.jsx("div",{children:t.jsxs("button",{className:"secondary-btn",onClick:()=>e("Integrations"),children:[H("Open Integrations"),t.jsx(_i,{size:15})]})})]}),t.jsxs("article",{className:`panel mail-prereq ${s.demoKey?"ready":""}`,children:[t.jsx("span",{className:"mail-prereq-icon",children:t.jsx(za,{size:23})}),t.jsx(_t,{tone:s.keySet?"green":"neutral",children:s.keySet?H("Ready"):H("Optional")}),t.jsx("h3",{children:s.keySet?H("Jev key is set"):H("Jev key (optional)")}),s.keySet&&s.keyProvider&&!M&&t.jsxs("p",{children:[H("Sorting runs through")," ",s.keyProvider,"."]}),(!s.keySet||M)&&t.jsx("p",{children:H("Without a key, your Orchestrator’s model sorts your mail. A Jev key from OpenRouter or TypeSafe makes it faster and cheaper: about two cents a month.")}),M?t.jsxs("form",{className:"mail-key-form",onSubmit:re=>{re.preventDefault(),Pe()},children:[t.jsx("input",{id:"mail-openrouter-key",type:"password",autoComplete:"off",autoFocus:!0,"aria-label":H("Paste your Jev key"),placeholder:H("OpenRouter or TypeSafe key"),value:E,onChange:re=>A(re.target.value)}),t.jsxs("div",{children:[t.jsx("button",{type:"submit",className:"primary-btn",disabled:N||!E.trim(),children:t.jsx(Xn,{busy:N,label:"Checking the key",children:H("Save key")})}),t.jsx("button",{type:"button",className:"text-btn",onClick:()=>{w(!1),A(""),j("")},children:H("Cancel")})]}),z&&t.jsx("p",{className:"mail-key-error",role:"alert",children:z}),t.jsx("small",{children:H("No key yet? Create one at openrouter.ai/keys or console.typesafe.ai/keys. It is also used for Jev routing in Settings.")})]}):t.jsx("div",{children:t.jsxs("button",{className:"secondary-btn",onClick:()=>{w(!0),j("")},children:[t.jsx(jn,{size:15}),H(s.keySet?"Change key":"Add key")]})})]})]}),t.jsxs("div",{className:"mail-setup-next",children:[t.jsxs("div",{children:[t.jsx("strong",{children:H("Find the categories that fit your mail")}),t.jsx("p",{children:H("Laboratorio reads up to 250 recent emails, then you can rename, merge or change every suggestion.")})]}),t.jsxs("button",{className:"primary-btn",disabled:!xe||ue,onClick:()=>Re(),children:[t.jsx(Ha,{size:17}),H("Find my categories"),t.jsx(Kn,{size:16})]})]})]}),(s.stage==="review"||L)&&t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"mail-section-head",children:[t.jsxs("div",{children:[t.jsx("span",{className:"panel-kicker",children:H("YOUR CATEGORY MAP")}),t.jsx("h2",{children:H("A first draft of your inbox.")}),t.jsx("p",{children:H("Suggested from recent mail. Rename, merge, split, remove or add categories before you sort.")})]}),t.jsxs("div",{className:"mail-section-head-actions",children:[t.jsxs(_t,{tone:"green",children:[hr(s.analyzed||qe)," ",H("emails analyzed")]}),L&&s.stage==="inbox"&&t.jsxs("button",{className:"secondary-btn",onClick:()=>{D(!1),Re(!0)},children:[t.jsx(xl,{size:16}),H("Find my categories again")]})]})]}),t.jsxs("div",{className:"mail-category-editor",children:[ot.map((re,Se)=>{const He=re.id===il,lt=ml(s.emails.filter(tt=>tt.categoryId===re.id))||re.count||0;return t.jsxs("article",{className:"panel mail-category-card",style:{"--mail-category":re.color},children:[t.jsx("span",{className:"mail-category-symbol",style:{background:re.color},children:H(re.name).slice(0,1).toUpperCase()}),t.jsxs("div",{className:"mail-category-main",children:[t.jsxs("div",{className:"mail-category-title",children:[t.jsx("input",{"aria-label":H("Category name"),value:H(re.name),disabled:He,maxLength:40,onChange:tt=>be(re.id,{name:tt.target.value})}),t.jsxs("span",{children:[hr(lt)," ",H("emails")]})]}),t.jsx("textarea",{rows:2,className:"mail-category-description","aria-label":H("What belongs here"),value:H(re.description),maxLength:150,onChange:tt=>be(re.id,{description:tt.target.value})}),t.jsx("p",{children:re.examples.join(" · ")})]}),t.jsxs("div",{className:"mail-category-actions",children:[t.jsx("button",{title:H("Category settings"),"aria-label":`${H("Category settings")}: ${H(re.name)}`,onClick:()=>F(re.id),children:t.jsx(rs,{size:16})}),!He&&t.jsxs(t.Fragment,{children:[t.jsx("button",{title:H("Move up"),disabled:Se===0,onClick:()=>B(re.id,-1),children:t.jsx(em,{size:16})}),t.jsx("button",{title:H("Move down"),disabled:Se===ot.length-2,onClick:()=>B(re.id,1),children:t.jsx(tU,{size:16})}),t.jsx("button",{title:H("Merge"),onClick:()=>{J(re.id),Q(ot.find(tt=>tt.id!==re.id)?.id||il)},children:t.jsx(RU,{size:16})}),t.jsx("button",{title:H("Split"),onClick:()=>{$(re.id),ne(""),T(s.emails.find(tt=>tt.categoryId===re.id)?.sender||"")},children:t.jsx(BU,{size:16})}),t.jsx("button",{title:H("Delete"),onClick:()=>pe(re.id),children:t.jsx(ti,{size:16})})]})]})]},re.id)}),t.jsxs("button",{className:"mail-add-category",onClick:()=>Ka(re=>{re.categories.splice(re.categories.length-1,0,{id:Db(),name:H("New category"),description:"",examples:[],color:Nd[re.categories.length%Nd.length],gmailLabel:!1,autoDraft:!1,agentId:"agent-orchestrator",instructions:"",notify:!1})}),children:[t.jsx(jn,{size:19}),H("Add category")]})]}),t.jsxs("section",{className:"panel mail-sort-review",children:[t.jsxs("div",{children:[t.jsx("span",{className:"panel-kicker",children:H("BEFORE YOU SORT")}),t.jsx("h3",{children:H("Choose how far back to go.")}),t.jsx("p",{children:H("A clear estimate before anything starts.")}),t.jsx("div",{className:"mail-days",children:[7,30,90].map(re=>t.jsxs("button",{"aria-pressed":s.sortDays===re,className:s.sortDays===re?"selected":"",onClick:()=>Ka(Se=>{Se.sortDays=re}),children:[re," ",H("days")]},re))})]}),t.jsxs("div",{className:"mail-estimate",children:[t.jsxs("div",{children:[t.jsx("span",{children:H("Emails to sort")}),t.jsx("strong",{children:hr(xt)})]}),t.jsxs("div",{children:[t.jsx("span",{children:H("Estimated cost")}),t.jsx("strong",{children:s.keySet?aY(se):H("Your model’s price")})]}),t.jsx("small",{children:H(s.keySet?"Measured Jev price: about $0.00002 an email.":"Sorted by your Orchestrator’s model, 40 emails a turn. A Jev key makes it faster and cheaper.")})]}),!ut&&t.jsx("p",{className:"mail-name-warning",children:H("Give every category a unique name before sorting.")}),t.jsxs("div",{className:"mail-sort-action",children:[s.stage==="inbox"&&t.jsx("button",{className:"secondary-btn",onClick:()=>D(!1),children:H("Save and return")}),t.jsxs("button",{className:"primary-btn",disabled:!ut,onClick:K,children:[H("Start sorting"),t.jsx(Kn,{size:17})]})]})]})]})]}),!o&&s.stage==="inbox"&&!L&&t.jsx(nY,{agents:a,onManage:()=>D(!0),onDiscover:()=>Re(!0),onCreateTodo:n,onNavigate:e}),t.jsx(on,{open:!!Ce,onClose:()=>F(""),title:H("Category settings"),description:Ce?H(Ce.name):"",wide:!0,children:Ce&&t.jsxs("div",{className:"mail-modal-fields",children:[t.jsxs("div",{className:"mail-field-grid",children:[t.jsxs("label",{children:[H("Name"),t.jsx("input",{value:H(Ce.name),disabled:Ce.id===il,maxLength:40,onChange:re=>be(Ce.id,{name:re.target.value})})]}),t.jsxs("label",{children:[H("Description"),t.jsx("input",{value:H(Ce.description),maxLength:150,onChange:re=>be(Ce.id,{description:re.target.value})})]})]}),t.jsxs("div",{children:[t.jsx("span",{className:"mail-field-label",children:H("Category colour")}),t.jsx("div",{className:"mail-colors",children:Nd.map(re=>t.jsx("button",{style:{background:re},className:Ce.color===re?"selected":"","aria-label":`${H("Choose colour")} ${re}`,"aria-pressed":Ce.color===re,onClick:()=>be(Ce.id,{color:re}),children:Ce.color===re&&t.jsx(Kt,{size:16})},re))})]}),t.jsxs("label",{className:"mail-switch-row",children:[t.jsxs("span",{children:[t.jsx("strong",{children:H("Add matching Gmail label")}),t.jsx("small",{children:H("Put this category name on matching messages in Gmail.")})]}),t.jsx("button",{className:"pref-switch",role:"switch","aria-label":H("Add matching Gmail label"),"aria-checked":Ce.gmailLabel,onClick:()=>be(Ce.id,{gmailLabel:!Ce.gmailLabel}),children:t.jsx("i",{})})]}),t.jsxs("label",{className:"mail-switch-row",children:[t.jsxs("span",{children:[t.jsx("strong",{children:H("Prepare a reply for every new email")}),t.jsx("small",{children:H("Every draft waits in Approval Inbox. Nothing is sent automatically.")})]}),t.jsx("button",{className:"pref-switch",role:"switch","aria-label":H("Prepare a reply for every new email"),"aria-checked":Ce.autoDraft,onClick:()=>be(Ce.id,{autoDraft:!Ce.autoDraft}),children:t.jsx("i",{})})]}),Ce.autoDraft&&t.jsxs("div",{className:"mail-field-grid",children:[t.jsxs("label",{children:[H("Drafting agent"),t.jsx("select",{value:Ce.agentId,onChange:re=>be(Ce.id,{agentId:re.target.value}),children:a.map(re=>t.jsx("option",{value:re.id,children:re.name},re.id))})]}),t.jsxs("label",{children:[H("Instructions for the agent"),t.jsx("textarea",{rows:3,value:Ce.instructions,onChange:re=>be(Ce.id,{instructions:re.target.value}),placeholder:H("How should the agent answer?")})]})]}),t.jsxs("label",{className:"mail-switch-row",children:[t.jsxs("span",{children:[t.jsx("strong",{children:H("Notify me about new mail")}),t.jsx("small",{children:H("Uses your Approval Inbox channels and quiet hours.")})]}),t.jsx("button",{className:"pref-switch",role:"switch","aria-label":H("Notify me about new mail"),"aria-checked":Ce.notify,onClick:()=>be(Ce.id,{notify:!Ce.notify}),children:t.jsx("i",{})})]}),t.jsx("div",{className:"pro-actions right",children:t.jsx("button",{className:"primary-btn",onClick:()=>F(""),children:H("Done")})})]})}),t.jsx(on,{open:!!x,onClose:()=>S(""),title:H("Switch inbox"),description:Be?.email||"",children:t.jsxs("div",{className:"mail-modal-fields",children:[t.jsx("p",{children:H("Another inbox gets its own categories and sorting. The current categories, sorted mail and corrections are cleared; nothing changes in Gmail.")}),t.jsxs("label",{children:[H("Sort this inbox instead"),t.jsx("select",{value:x,onChange:re=>S(re.target.value),children:at.filter(re=>re.id!==Be?.id).map(re=>t.jsx("option",{value:re.id,children:re.email||re.alias},re.id))})]}),t.jsxs("div",{className:"pro-actions right",children:[t.jsx("button",{className:"secondary-btn",onClick:()=>S(""),children:H("Cancel")}),t.jsx("button",{className:"primary-btn",onClick:()=>ft(x),children:H("Switch inbox")})]})]})}),t.jsx(on,{open:!!Ze,onClose:()=>J(""),title:H("Merge categories"),description:Ze?H(Ze.name):"",children:t.jsxs("div",{className:"mail-modal-fields",children:[t.jsx("p",{children:H("Messages and examples from this category will move to the category you choose.")}),t.jsxs("label",{children:[H("Merge into"),t.jsx("select",{value:ie,onChange:re=>Q(re.target.value),children:ot.filter(re=>re.id!==q).map(re=>t.jsx("option",{value:re.id,children:H(re.name)},re.id))})]}),t.jsxs("div",{className:"pro-actions right",children:[t.jsx("button",{className:"secondary-btn",onClick:()=>J(""),children:H("Cancel")}),t.jsx("button",{className:"primary-btn",onClick:Ae,children:H("Merge")})]})]})}),t.jsx(on,{open:!!le,onClose:()=>$(""),title:H("Split category"),description:le?H(le.name):"",children:t.jsxs("div",{className:"mail-modal-fields",children:[t.jsx("p",{children:H("Create a new category from messages by one example sender.")}),t.jsxs("label",{children:[H("New category name"),t.jsx("input",{value:te,onChange:re=>ne(re.target.value),maxLength:40})]}),t.jsxs("label",{children:[H("Example sender to move"),t.jsx("select",{value:Y,onChange:re=>T(re.target.value),children:[...new Set(s.emails.filter(re=>re.categoryId===V).map(re=>re.sender))].map(re=>t.jsx("option",{children:re},re))})]}),t.jsxs("div",{className:"pro-actions right",children:[t.jsx("button",{className:"secondary-btn",onClick:()=>$(""),children:H("Cancel")}),t.jsx("button",{className:"primary-btn",disabled:!te.trim()||!Y,onClick:Ne,children:H("Create split")})]})]})})]})}function rY(){const[a,e]=C.useState(null),[n,s]=C.useState(""),o=()=>wt("/api/style").then(e).catch(l=>s(l.message));return C.useEffect(()=>{o()},[]),C.useEffect(()=>{if(!a?.job.running)return;const l=setInterval(o,1500);return()=>clearInterval(l)},[a?.job.running]),{s:a,setS:e,err:n,setErr:s,load:o}}const ZC=a=>{a&&(a.style.height="auto",a.style.height=`${a.scrollHeight}px`)};function oY(){const{s:a,setS:e,err:n,setErr:s}=rY(),[o,l]=C.useState(""),[d,h]=C.useState(!1),[m,p]=C.useState("");async function y(A,k,R=""){h(!0),s(""),p("");try{e(await wt(A,k)),R&&p(R)}catch(N){s(N.message)}h(!1)}if(!a)return t.jsx("div",{className:"settings-grid",children:n?t.jsx(Ot,{error:!0,children:n}):t.jsx("section",{className:"panel settings-card",children:t.jsx("p",{className:"settings-help",children:u("Loading…")})})});const v=a.rules.length>0,x=a.job,S=A=>y("/api/style/save",{rules:A}),M=(A,k)=>y("/api/style/save",{writers:k?[...a.writers,A]:a.writers.filter(R=>R!==A)}),w=()=>{const A=o.trim();A&&(l(""),S([...a.rules,{id:"",text:A,source:"owner"}]))},E=a.learnedAt?new Date(a.learnedAt).toLocaleDateString(Hn(),{day:"numeric",month:"short"}):"";return t.jsxs("div",{className:"voice-settings",children:[t.jsxs("div",{className:"voice-top",children:[t.jsxs("section",{className:"panel settings-card",children:[t.jsxs("header",{children:[t.jsx(Mr,{size:20}),t.jsxs("div",{children:[t.jsx("h3",{children:u("Sounds like you")}),t.jsx("p",{children:u("Your crew writes the way you write: emails, replies and posts that sound like you, not like an AI.")})]})]}),x.running?t.jsx(cY,{stage:x.stage,progress:x.progress}):t.jsxs("div",{className:"voice-status",children:[t.jsxs("span",{children:[t.jsx("strong",{children:u(v?"Your voice is learned":"Not learned yet")}),t.jsx("small",{children:v?t.jsxs(t.Fragment,{children:[u("From")," ",a.learnedFrom," ",u("emails you sent"),E&&t.jsxs(t.Fragment,{children:[" · ",E]})]}):u("It reads the emails you sent recently, once. Nothing is sent anywhere else.")})]}),t.jsxs("button",{className:v?"secondary-btn":"primary-btn",disabled:d,onClick:()=>y("/api/style/learn",{}),children:[t.jsx(Ha,{size:15}),u(v?"Learn again":"Learn my voice")]})]}),x.error&&t.jsx(Ot,{error:!0,children:x.error}),t.jsxs("ol",{className:"voice-how",children:[t.jsx("li",{children:u("It reads the emails you sent recently, once.")}),t.jsx("li",{children:u("Every agent you tick writes like you.")}),t.jsx("li",{children:u("When you edit a draft, it suggests a new rule. Nothing is learned without your yes.")})]}),t.jsxs("div",{className:"pref-toggle-row",children:[t.jsxs("span",{children:[t.jsx("strong",{children:u("Write in my voice")}),t.jsx("small",{children:u(v?a.enabled?"On: every agent below writes like you, from its next conversation.":"Off: agents write in their own style. Switch it on to use your voice.":"Learn your voice first, then switch it on.")})]}),t.jsx("button",{className:"pref-switch",role:"switch","aria-label":u("Write in my voice"),"aria-checked":a.enabled,disabled:d||!v&&!a.enabled,onClick:()=>y("/api/style/save",{enabled:!a.enabled},a.enabled?"Your voice is off. Agents write in their own style again.":"Your voice is on."),children:t.jsx("i",{})})]})]}),t.jsxs("section",{className:"panel settings-card",children:[t.jsxs("header",{children:[t.jsx(hh,{size:20}),t.jsxs("div",{children:[t.jsx("h3",{children:u("Who writes in your voice")}),t.jsx("p",{children:u("Agents with Gmail access are your mail people, so they are ticked for you. Tick anyone else who writes for you.")})]})]}),t.jsx("div",{className:"voice-agents",children:a.agents.map(A=>{const k=a.writers.includes(A.id);return t.jsxs("button",{type:"button",role:"checkbox","aria-checked":k,className:k?"checked":"",disabled:d,onClick:()=>M(A.id,!k),children:[t.jsx("i",{children:k&&t.jsx(Kt,{size:12})}),t.jsx("span",{children:A.name}),A.gmail&&t.jsxs("small",{children:[t.jsx(ei,{size:12}),u("Gmail")]})]},A.id)})}),t.jsxs("div",{className:"voice-how voice-note",children:[t.jsxs("p",{children:[t.jsx("strong",{children:a.writers.length})," ",u(a.writers.length===1?"agent writes in your voice.":"agents write in your voice.")]}),t.jsx("p",{children:u("Gmail access is set in Integrations. Give an agent Gmail there and it is ticked here by itself.")})]})]})]}),t.jsxs("section",{className:"panel settings-card voice-rules",children:[t.jsxs("header",{children:[t.jsx(AU,{size:20}),t.jsxs("div",{children:[t.jsx("h3",{children:u("What it learned")}),t.jsx("p",{children:u("Plain rules every writer follows. Change any of them, or add your own.")})]}),v&&t.jsxs(_t,{tone:"green",children:[a.rules.length," ",u("rules")]})]}),a.suggestions.length>0&&t.jsxs("div",{className:"voice-suggestions",children:[t.jsx("strong",{children:u("New from your edits")}),a.suggestions.map(A=>t.jsxs("div",{children:[t.jsxs("p",{children:["“",A.rule,"”",t.jsxs("small",{children:[u("From your changes to")," ",A.title]})]}),t.jsxs("button",{className:"secondary-btn",disabled:d,onClick:()=>y("/api/style/suggestion",{id:A.id,keep:!0},"Added to your voice."),children:[t.jsx(Kt,{size:14}),u("Keep")]}),t.jsx("button",{className:"text-btn",disabled:d,onClick:()=>y("/api/style/suggestion",{id:A.id,keep:!1}),children:u("Drop")})]},A.id))]}),v?t.jsx("ul",{className:"voice-rule-list",children:a.rules.map(A=>t.jsxs("li",{children:[t.jsx("textarea",{"aria-label":u("Rule"),defaultValue:A.text,maxLength:200,rows:1,ref:ZC,onInput:k=>ZC(k.currentTarget),onBlur:k=>{const R=k.target.value.trim();R&&R!==A.text&&S(a.rules.map(N=>N.id===A.id?{...N,text:R}:N))}}),A.source!=="learned"&&t.jsx("small",{children:u(A.source==="edit"?"from an edit":"yours")}),t.jsx("button",{className:"pro-delete-icon","aria-label":u("Remove this rule"),disabled:d,onClick:()=>S(a.rules.filter(k=>k.id!==A.id)),children:t.jsx(da,{size:15})})]},A.id))}):t.jsx("p",{className:"settings-help",children:u("Press Learn my voice and the rules appear here, for example how you open and sign off, and the phrases you never use.")}),t.jsxs("div",{className:"voice-add",children:[t.jsx("input",{"aria-label":u("Add a rule"),placeholder:u("Add a rule, for example: never mention prices in a first email"),value:o,maxLength:200,onChange:A=>l(A.target.value),onKeyDown:A=>{A.key==="Enter"&&w()}}),t.jsxs("button",{className:"secondary-btn",disabled:d||!o.trim(),onClick:w,children:[t.jsx(jn,{size:15}),u("Add")]})]}),a.examples.length>0&&t.jsxs("div",{className:"voice-examples",children:[t.jsx("strong",{children:u("You, in your own words")}),a.examples.map((A,k)=>t.jsx("blockquote",{children:A},k))]}),(m||n)&&t.jsx("p",{className:`settings-help ${n?"voice-error":""}`,children:u(n||m)})]})]})}function lY(){const[a,e]=C.useState(null),[n,s]=C.useState(!1);if(C.useEffect(()=>{let d=!0;const h=()=>wt("/api/style").then(p=>{d&&e(p)}).catch(()=>{});h();const m=setInterval(h,8e3);return()=>{d=!1,clearInterval(m)}},[]),!a?.enabled||!a.suggestions.length)return null;const o=a.suggestions[0];async function l(d){s(!0);try{e(await wt("/api/style/suggestion",{id:o.id,keep:d}))}catch{}s(!1)}return t.jsxs("div",{className:"voice-remember",role:"status",children:[t.jsx(Mr,{size:17}),t.jsxs("p",{children:[t.jsx("strong",{children:u("Remember that?")})," ",u("From your edit to")," ",o.title,": “",o.rule,"”"]}),t.jsxs("button",{className:"secondary-btn",disabled:n,onClick:()=>l(!0),children:[t.jsx(Kt,{size:14}),u("Yes")]}),t.jsx("button",{className:"text-btn",disabled:n,onClick:()=>l(!1),children:u("No")})]})}function cY({stage:a,progress:e}){const n=Fi(!0),s=xh(vh(n),60),o=Math.max(4,e,Math.min(95,e+(95-e)*s/100));return t.jsxs("div",{className:"voice-learning",children:[t.jsxs("p",{children:[t.jsx(Jt,{size:15,className:"spin"}),u(a||"Starting"),t.jsx(vi,{since:n})]}),t.jsx("div",{className:"pro-progress",children:t.jsx("i",{style:{width:`${o}%`}})})]})}const QC=3,uY=["Downloading the new version","Applying the new version","Restarting the dashboard","Checking that everything works"],dY=["Putting the previous version back","Restarting the dashboard"],Sm=a=>a.action==="undo"?dY:uY,hY=Date.now()/1e3;let Ib=null;const Ub=new Set,nS=a=>{Ib=a,Ub.forEach(e=>e(a))};async function Am(a=!1){const e=await wt(a?"/api/updates/check":"/api/updates",a?{}:void 0);return nS(e),e}function aS(){const[a,e]=C.useState(Ib),[n,s]=C.useState(!1);C.useEffect(()=>(Ub.add(e),Ib||Am().catch(()=>{}),()=>{Ub.delete(e)}),[]);const o=a?.job.state==="running";return C.useEffect(()=>{if(!o)return;const l=setInterval(()=>Am().then(()=>s(!1)).catch(()=>s(!0)),2e3);return()=>clearInterval(l)},[o]),C.useEffect(()=>{const l=a?.job;if(!l||l.state==="running"||!l.finishedAt||l.finishedAtlocation.reload(),900)},[a?.job.finishedAt,a?.job.state]),{s:a,down:n}}function fY(a){try{localStorage.setItem("laboratorio-settings-tab","Updates")}catch{}window.dispatchEvent(new CustomEvent("laboratorio-settings-tab",{detail:"Updates"})),a()}const pY=a=>{if(!a)return"";const e=Math.round((Date.now()/1e3-a)/60);if(e<1)return u("just now");if(e<60)return u("{x} min ago").replace("{x}",String(e));const n=Math.round(e/60);return n<24?u("{x} h ago").replace("{x}",String(n)):new Date(a*1e3).toLocaleDateString(Hn(),{day:"numeric",month:"short"})};function mY({onOpen:a}){const{s:e}=aS(),[n,s]=C.useState(!1);if(C.useEffect(()=>{const h=setInterval(()=>Am().catch(()=>{}),6e5),m=()=>{document.visibilityState==="visible"&&Am().catch(()=>{})};return window.addEventListener("focus",m),document.addEventListener("visibilitychange",m),()=>{clearInterval(h),window.removeEventListener("focus",m),document.removeEventListener("visibilitychange",m)}},[]),!e)return null;const o=e.job.state==="running",l=!!e.latest&&e.skipped===e.latest.version,d=o?t.jsxs("button",{className:"update-pill is-running",onClick:()=>s(!0),"aria-label":u("Updating"),title:u("Updating"),children:[t.jsx(Jt,{size:14,className:"spin"}),t.jsx("span",{children:u("Updating")})]}):e.available&&!l?t.jsxs("button",{className:"update-pill",onClick:()=>s(!0),title:u("A new version of Laboratorio Pro is ready"),"aria-label":u("Update available"),children:[t.jsx("i",{}),t.jsx("span",{children:u("Update available")})]}):null;return t.jsxs(t.Fragment,{children:[d,(d||n)&&t.jsx(gY,{s:e,open:n,onClose:()=>s(!1),onHistory:()=>{s(!1),fY(a)}})]})}function gY({s:a,open:e,onClose:n,onHistory:s}){const{down:o}=aS(),[l,d]=C.useState(""),[h,m]=C.useState(""),[p,y]=C.useState("");async function v(R,N={}){d(R),m("");try{const I=await wt(R,N);return nS(I),I}catch(I){m(I.message)}finally{d("")}}const x=a.job,S=x.state==="running",M=S?Math.max(0,Sm(x).indexOf(x.step||"")):-1,w=a.history.filter(R=>R.new).flatMap(R=>R.items),E=!a.key.saved&&!a.preview,A=()=>v("/api/updates/run",p.trim()?{key:p.trim()}:{}),k=async()=>{a.latest&&await v("/api/updates/skip",{version:a.latest.version})&&n()};return t.jsx(on,{title:u(S?"Updating Laboratorio Pro":"A new version of Laboratorio Pro is ready"),description:S?"This window can stay open: the dashboard reloads itself when the new version is running.":"See what changed, then update in one click, or skip this version.",open:e,onClose:n,children:t.jsxs("div",{className:"update-prompt","aria-live":"polite",children:[t.jsxs("p",{className:"update-jump",children:[t.jsx("span",{children:a.installed.label||u("Your version")}),a.latest&&t.jsxs(t.Fragment,{children:[t.jsx(Kn,{size:15,"aria-hidden":"true"}),t.jsx("strong",{children:a.latest.label})]})]}),S?t.jsxs("div",{className:"update-progress",children:[t.jsx(Ma,{className:"compact",label:x.action==="undo"?"Undoing the update":"Updating Laboratorio Pro",since:x.startedAt?x.startedAt*1e3:null,expect:60}),t.jsx("ol",{children:Sm(x).map((R,N)=>t.jsxs("li",{className:Ny(R.target.value),onKeyDown:R=>{R.key==="Enter"&&p.trim()&&A()}})}),t.jsx("small",{children:u("Updates are for members. Your key stays on this machine and is checked each time you update.")})]}),t.jsxs("button",{className:"primary-btn update-prompt-go",disabled:!!l||E&&!p.trim(),onClick:A,children:[l==="/api/updates/run"?t.jsx(Jt,{size:17,className:"spin"}):t.jsx(Eo,{size:17}),u("Update now")]}),t.jsx("p",{className:"update-prompt-help",children:u("Takes about a minute. Your team, data and settings stay as they are, and the dashboard reloads by itself.")}),a.preview&&t.jsx("p",{className:"update-preview-note",children:u("Preview on this machine: pressing Update now here changes nothing.")}),h&&t.jsx(Ot,{error:!0,children:h}),w.length>0&&t.jsxs("div",{className:"update-prompt-news",children:[t.jsx("strong",{children:u("What's new")}),t.jsx("ul",{className:"update-news",children:w.slice(0,5).map((R,N)=>t.jsx("li",{children:u(R)},N))}),t.jsx("button",{className:"text-btn",onClick:s,children:u(w.length>5?"All {x} changes and the version history":"The version history").replace("{x}",String(w.length))})]}),t.jsxs("div",{className:"update-prompt-alt",children:[t.jsx("button",{className:"secondary-btn",disabled:!!l,onClick:k,children:u("Skip this version")}),t.jsx("button",{className:"text-btn",onClick:n,children:u("Not now")})]}),t.jsx("p",{className:"update-prompt-small",children:u("Skip hides this version until a newer one comes out. You can still install it from Settings, under Updates.")})]})]})})}function vY(){const{s:a,down:e}=aS(),[n,s]=C.useState(""),[o,l]=C.useState(""),[d,h]=C.useState(""),[m,p]=C.useState(!1),[y,v]=C.useState(!1),[x,S]=C.useState(!1),M=C.useRef(null);async function w(D,P={}){s(D),l("");try{nS(await wt(D,P))}catch(F){l(F.message)}s("")}if(!a)return t.jsx("div",{className:"updates-page",children:t.jsx("section",{className:"panel settings-card",children:t.jsx("p",{className:"settings-help",children:u("Loading…")})})});const E=a.job,A=E.state==="running",k=!!E.finishedAt&&Date.now()/1e3-E.finishedAt<6*3600,R=A?Math.max(0,Sm(E).indexOf(E.step||"")):-1,N=a.history.filter(D=>D.new),I=N.flatMap(D=>D.items),z=!a.key.saved||m,j=async()=>{const D=d.trim();if(!D){M.current?.focus();return}await w("/api/updates/key",{key:D}),h(""),p(!1)},L=()=>w("/api/updates/run",d.trim()?{key:d.trim()}:{});return t.jsxs("div",{className:"updates-page",children:[t.jsxs("section",{className:`panel update-hero ${a.available&&!A?"is-ready":""} ${A?"is-running":""}`,"aria-live":"polite",children:[t.jsxs("div",{className:"update-hero-head",children:[t.jsx("span",{className:"update-hero-icon",children:A?t.jsx(Jt,{size:22,className:"spin"}):a.available?t.jsx(Ha,{size:22}):t.jsx(Kt,{size:22})}),t.jsxs("div",{children:[t.jsx("h3",{children:u(A?E.action==="undo"?"Putting the previous version back":"Updating Laboratorio Pro":a.available?"A new version is ready":"You're on the newest Laboratorio Pro")}),t.jsxs("p",{className:"update-jump",children:[t.jsx("span",{children:a.installed.label||u("Your version")}),a.available&&a.latest&&t.jsxs(t.Fragment,{children:[t.jsx(Kn,{size:15,"aria-hidden":"true"}),t.jsx("strong",{children:a.latest.label})]})]})]})]}),A&&t.jsxs("div",{className:"update-progress",children:[t.jsx(Ma,{className:"compact",label:E.action==="undo"?"Undoing the update":"Updating Laboratorio Pro",since:E.startedAt?E.startedAt*1e3:null,expect:60}),t.jsx("ol",{children:Sm(E).map((D,P)=>t.jsxs("li",{className:P0&&t.jsxs("ul",{className:"update-news",children:[I.slice(0,8).map((D,P)=>t.jsx("li",{children:u(D)},P)),I.length>8&&t.jsx("li",{className:"more",children:u("…and {x} more, listed below.").replace("{x}",String(I.length-8))})]}),t.jsxs("div",{className:"update-cta",children:[t.jsxs("button",{className:"primary-btn",disabled:!!n||!a.preview&&z&&!d.trim(),onClick:L,children:[n==="/api/updates/run"?t.jsx(Jt,{size:16,className:"spin"}):t.jsx(Eo,{size:16}),u("Update now")]}),t.jsx("p",{children:u("Takes about a minute. Your team, data and settings stay as they are, and the dashboard reloads by itself.")})]})]}),!A&&!a.available&&t.jsxs("div",{className:"update-cta quiet",children:[t.jsx("button",{className:"secondary-btn",disabled:!!n,onClick:()=>w("/api/updates/check"),children:t.jsxs(Xn,{busy:n==="/api/updates/check",label:"Checking for updates",children:[t.jsx(xl,{size:15}),u("Check again")]})}),t.jsx("p",{children:a.checkError?u("Could not reach the update server just now. Your dashboard works as before; try again later."):a.checkedAt?u("Checked {x}.").replace("{x}",pY(a.checkedAt)):""})]}),a.available&&!A&&a.latest&&a.skipped===a.latest.version&&t.jsxs("p",{className:"update-skipped",children:[u("You skipped this version, so the top bar does not offer it. You can still update here.")," ",t.jsx("button",{className:"text-btn",disabled:!!n,onClick:()=>w("/api/updates/skip",{version:""}),children:u("Offer it again")})]}),a.preview&&a.available&&!A&&t.jsx("p",{className:"update-preview-note",children:u("Preview on this machine: pressing Update now here changes nothing.")}),!A&&k&&E.message&&t.jsx(Ot,{error:E.state==="failed"||E.state==="undone",children:E.message}),o&&t.jsx(Ot,{error:!0,children:o}),t.jsxs("footer",{className:"update-foot",children:[z?t.jsxs("div",{className:"update-key",children:[t.jsxs("label",{htmlFor:"update-key-input",children:[t.jsx(Zd,{size:15}),u("Membership key")]}),t.jsxs("div",{children:[t.jsx("input",{id:"update-key-input",ref:M,type:"password",autoComplete:"off",spellCheck:!1,placeholder:u("Paste your membership key"),value:d,onChange:D=>h(D.target.value),onKeyDown:D=>{D.key==="Enter"&&j()}}),t.jsx("button",{className:"secondary-btn",disabled:!!n||!d.trim(),onClick:j,children:u("Save key")}),a.key.saved&&t.jsx("button",{className:"text-btn",onClick:()=>{p(!1),h("")},children:u("Cancel")})]}),t.jsx("small",{children:u("Updates are for members. Your key stays on this machine and is checked each time you update.")})]}):t.jsxs("p",{className:"update-key-saved",children:[t.jsx(Zd,{size:15}),u("Membership key saved")," ",t.jsx("code",{children:a.key.masked}),t.jsx("button",{className:"text-btn",onClick:()=>{p(!0),setTimeout(()=>M.current?.focus(),0)},children:u("Change")})]}),a.canUndo&&!A&&t.jsxs("button",{className:"text-btn update-undo",onClick:()=>v(!0),children:[t.jsx(ss,{size:14}),u("Undo the last update")]})]})]}),t.jsxs("section",{className:"panel update-history","aria-label":u("Version history"),children:[t.jsxs("header",{children:[t.jsx("h3",{children:u("Version history")}),t.jsx("p",{children:u("Every release of Laboratorio Pro and what it brought, newest first.")})]}),a.history.length===0?t.jsx("p",{className:"settings-help",children:u("The release notes appear here after your first update.")}):t.jsxs(t.Fragment,{children:[t.jsx("ol",{className:"release-line",children:(x?a.history:a.history.slice(0,QC)).map(D=>t.jsxs("li",{className:D.current?"current":D.new?"new":"",children:[t.jsxs("div",{className:"release-when",children:[t.jsx("time",{children:D.label||D.date}),D.current&&t.jsx("span",{className:"release-tag here",children:u("You are here")}),D.new&&t.jsx("span",{className:"release-tag",children:u("New")})]}),t.jsx("ul",{children:D.items.map((P,F)=>t.jsx("li",{children:u(P)},F))})]},D.version+D.date))}),a.history.length>QC&&t.jsx("button",{className:"secondary-btn release-more","aria-expanded":x,onClick:()=>S(!x),children:x?u("Show only the latest releases"):u("Show all {x} releases").replace("{x}",String(a.history.length))})]})]}),t.jsx(on,{title:u("Put the previous version back?"),description:"The dashboard goes back to the version you had before the last update and restarts. Your team, data and settings are not touched.",open:y,onClose:()=>v(!1),children:t.jsxs("div",{className:"pro-actions right",children:[t.jsx("button",{className:"secondary-btn",onClick:()=>v(!1),children:u("Keep this version")}),t.jsxs("button",{className:"primary-btn",onClick:()=>{v(!1),w("/api/updates/undo")},children:[t.jsx(ss,{size:15}),u("Put it back")]})]})})]})}function Jp({label:a,description:e,value:n,onChange:s,locked:o}){return t.jsxs("div",{className:`pref-toggle-row${o?" is-locked":""}`,children:[t.jsxs("span",{children:[t.jsx("strong",{children:u(a)}),t.jsx("small",{children:u(o||e)})]}),t.jsx("button",{className:"pref-switch",role:"switch","aria-label":u(a),"aria-checked":o?!1:n,disabled:!!o,onClick:()=>s(!n),children:t.jsx("i",{})})]})}function xY(){Au();const a=EN(),[e,n]=C.useState(""),[s,o]=C.useState(""),[l,d]=C.useState(!1),[h,m]=C.useState(!1);async function p(x,S=""){d(!0),o("");let M=!1;try{await rh(x),S&&o(S),M=!0}catch(w){o(w.message)}return d(!1),M}const y=(x,S)=>{const M=is.find(w=>`${w.provider}|${w.name}`===S);p({[x]:M?{name:M.name,provider:M.provider}:{}})},v=x=>x.name?`${x.provider}|${x.name}`:"";return t.jsxs("section",{className:"panel settings-card",children:[t.jsxs("header",{children:[t.jsx(dh,{size:20}),t.jsxs("div",{children:[t.jsx("h3",{children:u("Smart model routing")}),t.jsx("p",{children:u("Let Jev choose a light or a strong model for each task.")})]})]}),a.keySet&&!h?t.jsxs("div",{className:"jev-key-saved",children:[t.jsxs(_t,{tone:"green",children:["✓ ",u("Key saved"),a.keyProvider?` · ${a.keyProvider}`:""]}),t.jsxs("div",{className:"settings-data-actions",children:[t.jsxs("button",{className:"secondary-btn",disabled:l,onClick:()=>{m(!0),o("")},children:[t.jsx(Zd,{size:15}),u("Replace key")]}),t.jsx("button",{className:"text-btn",disabled:l,onClick:()=>p({key:"",enabled:!1},"Key removed. Jev is off."),children:u("Remove key")})]})]}):t.jsxs(t.Fragment,{children:[t.jsxs("label",{children:[u("Jev API key (OpenRouter or TypeSafe)"),t.jsx("input",{type:"password",autoComplete:"off",autoFocus:h,"aria-label":u("Jev API key (OpenRouter or TypeSafe)"),placeholder:u("Paste a key from OpenRouter or TypeSafe"),value:e,onChange:x=>n(x.target.value),onKeyDown:x=>{x.key==="Enter"&&e.trim()&&!l&&(x.preventDefault(),x.currentTarget.closest("section")?.querySelector("[data-save-key]")?.click())}})]}),t.jsxs("div",{className:"settings-data-actions",children:[t.jsx("button",{"data-save-key":!0,className:"secondary-btn",disabled:l||!e.trim(),onClick:()=>p({key:e.trim()},a.enabled?"Key checked and saved on your server.":'Key saved. Now choose a light and a strong model below, and switch on "Let Jev pick the model".').then(x=>{x&&(n(""),m(!1))}),children:t.jsxs(Xn,{busy:l,label:"Checking the key",children:[t.jsx(Zd,{size:15}),u("Save key")]})}),a.keySet&&t.jsx("button",{className:"text-btn",disabled:l,onClick:()=>{m(!1),n("")},children:u("Cancel")})]})]}),t.jsxs(t.Fragment,{children:[t.jsxs("label",{children:[u("Light model, for routine tasks"),t.jsxs("select",{"aria-label":u("Light model"),value:v(a.light),disabled:!a.keySet,onChange:x=>y("light",x.target.value),children:[t.jsx("option",{value:"",children:u("Choose a model")}),is.map(x=>t.jsxs("option",{value:`${x.provider}|${x.name}`,children:[x.name," · ",x.provider]},x.provider+x.name))]})]}),t.jsxs("label",{children:[u("Strong model, for demanding tasks"),t.jsxs("select",{"aria-label":u("Strong model"),value:v(a.strong),disabled:!a.keySet,onChange:x=>y("strong",x.target.value),children:[t.jsx("option",{value:"",children:u("Choose a model")}),is.map(x=>t.jsxs("option",{value:`${x.provider}|${x.name}`,children:[x.name," · ",x.provider]},x.provider+x.name))]})]}),t.jsx(Jp,{label:"Let Jev pick the model",description:"Jobs, automations, mail and missions get the right model every time. A chat keeps one model while you talk, so its cache is reused; it moves up to the strong model once if it gets harder, and Jev chooses again after 30 quiet minutes. When Jev is less than 80% sure, the strong model is used.",value:a.enabled,locked:a.keySet?!a.enabled&&!(a.light?.name&&a.strong?.name)?"Choose a light model and a strong model first.":void 0:"Add your Jev key above first. Until then every agent uses its own model.",onChange:x=>p({enabled:x},x?"Jev routing is on.":"Jev routing is off. Each agent uses its own model.")})]}),a.enabled&&a.savings&&a.savings.routed>0&&t.jsxs("p",{className:"jev-savings",children:[t.jsx("strong",{children:u("Last 7 days")})," · ",a.savings.light," ",u("of")," ",a.savings.routed," ",u("tasks on the light model")," · ",new Intl.NumberFormat(Hn(),{notation:"compact",maximumFractionDigits:1}).format(a.savings.lightTokens)," ",u("tokens kept off")," ",a.savings.strongModel,a.savings.savedUsd!==null&&a.savings.savedUsd>0?t.jsxs(t.Fragment,{children:[" · ",u("saved about")," ",new Intl.NumberFormat(Hn(),{style:"currency",currency:"USD",maximumFractionDigits:2}).format(a.savings.savedUsd)]}):a.savings.strongIncluded?t.jsxs(t.Fragment,{children:[" · ",u("your strong model is included in your subscription, so this saves usage, not dollars")]}):null]}),t.jsx("p",{className:"settings-help",children:u(a.keySet?"Each decision costs a tiny fraction of a cent on the account your key is from.":"Optional. Without a key, every agent simply uses its own model.")}),s&&t.jsx("p",{className:"settings-help",children:u(s)})]})}const sy=["General","Appearance","Chat","Models","Mail","Writing style","Backups","Updates"];function yY({onRestored:a=()=>{}}){const e=mu(),[n,s]=C.useState(!1),[o,l]=C.useState(()=>{try{const p=localStorage.getItem("laboratorio-settings-tab")||"";return sy.includes(p)?p:"General"}catch{return"General"}}),d=p=>{l(p);try{localStorage.setItem("laboratorio-settings-tab",p)}catch{}};C.useEffect(()=>{const p=y=>{const v=y.detail;sy.includes(v)&&l(v)};return window.addEventListener("laboratorio-settings-tab",p),()=>window.removeEventListener("laboratorio-settings-tab",p)},[]);const h=p=>$p(p),m=Tl();return C.useEffect(()=>{m.view==="Settings"&&m.section==="backups"&&l("Backups")},[m.stamp]),t.jsxs("div",{className:"settings-page",children:[t.jsxs("div",{className:"settings-banner",children:[t.jsx("span",{children:t.jsx(rs,{size:23})}),t.jsxs("div",{children:[t.jsx("h2",{children:u("Make yourself at home.")}),t.jsx("p",{children:u("A workspace that feels right for you.")})]}),t.jsxs(_t,{tone:"green",children:[t.jsx(Kt,{size:12}),u("Saved automatically")]})]}),t.jsx("div",{className:"settings-tabs",role:"tablist","aria-label":u("Settings sections"),children:sy.map(p=>t.jsx("button",{role:"tab","aria-selected":o===p,className:o===p?"selected":"",onClick:()=>d(p),children:u(p)},p))}),o==="General"&&t.jsxs("div",{className:"settings-grid",children:[t.jsxs("section",{className:"panel settings-card",children:[t.jsxs("header",{children:[t.jsx(Qb,{size:20}),t.jsxs("div",{children:[t.jsx("h3",{children:u("Language & region")}),t.jsx("p",{children:u("Your interface, your language.")})]})]}),t.jsxs("label",{children:[u("Dashboard language"),t.jsx("select",{"aria-label":u("Dashboard language"),value:e.language,onChange:p=>h({language:p.target.value}),children:u(Qp.map(p=>t.jsx("option",{value:p.id,children:p.native},p.id)))})]}),t.jsx("div",{className:"language-choices",children:Qp.map(p=>t.jsxs("button",{className:e.language===p.id?"selected":"","aria-pressed":e.language===p.id,onClick:()=>h({language:p.id}),children:[t.jsx("span",{children:p.native}),t.jsx("small",{children:u(p.label)}),u(e.language===p.id&&t.jsx(Kt,{size:14}))]},p.id))}),t.jsx("p",{className:"settings-help",children:u("Navigation, controls, and interface text update immediately. Your documents, filenames, and agent names keep their original language.")}),t.jsxs("label",{children:[u("Timezone"),t.jsx("select",{"aria-label":u("Workspace timezone"),value:e.timezone,onChange:p=>h({timezone:p.target.value}),children:sL(e.timezone).map(([p,y])=>t.jsx("optgroup",{label:p,children:y.map(v=>t.jsx("option",{value:v.zone,children:v.label},v.zone))},p))})]}),t.jsx(Jp,{label:u("12-hour clock"),description:"Display times with AM and PM.",value:e.hour12,onChange:p=>h({hour12:p})})]}),t.jsxs("section",{className:"panel settings-card",children:[t.jsxs("header",{children:[t.jsx(bU,{size:20}),t.jsxs("div",{children:[t.jsx("h3",{children:u("Workspace defaults")}),t.jsx("p",{children:u("A familiar starting point every time.")})]})]}),t.jsxs("label",{children:[u("Workspace name"),t.jsx("input",{"aria-label":u("Workspace name"),maxLength:50,value:e.workspaceName,onChange:p=>h({workspaceName:p.target.value})})]}),t.jsxs("label",{children:[u("Start page"),t.jsx("select",{"aria-label":u("Start page"),value:e.landing,onChange:p=>h({landing:p.target.value}),children:["Overview","Agents","Chat","Missions","Approval Inbox","Mail","Automations","Docs","Skills","Integrations","Productivity","Settings"].map(p=>t.jsx("option",{value:p,children:u(p)},p))})]}),t.jsxs("label",{children:[u("Default model for new agents"),t.jsx("select",{"aria-label":u("Default model for new agents"),value:e.defaultModel,onChange:p=>h({defaultModel:p.target.value}),children:u(is.map(p=>t.jsxs("option",{value:p.name,children:[p.name," · ",p.provider]},p.provider+p.name)))})]}),t.jsx("p",{className:"settings-help",children:u("Existing agents keep their individual model settings.")})]}),t.jsxs("section",{className:"panel settings-card",children:[t.jsxs("header",{children:[t.jsx(za,{size:20}),t.jsxs("div",{children:[t.jsx("h3",{children:u("Your data")}),t.jsx("p",{children:u("What is saved where, and your preferences as a file.")})]})]}),t.jsxs("div",{className:"settings-storage-note",children:[t.jsx(za,{size:19}),t.jsxs("div",{children:[t.jsx("strong",{children:u("Where things are saved")}),t.jsx("p",{children:u("Everything here is saved on your server, so your settings follow you to every device and browser.")})]})]}),t.jsxs("div",{className:"settings-data-actions",children:[t.jsxs("button",{className:"secondary-btn",onClick:()=>j0("laboratorio-preferences.json",JSON.stringify(e,null,2),"application/json"),children:[t.jsx(Eo,{size:15}),u("Export preferences")]}),t.jsxs("button",{className:"text-btn",onClick:()=>s(!0),children:[t.jsx(ss,{size:14}),u("Reset preferences")]})]})]})]}),o==="Appearance"&&t.jsx("div",{className:"settings-grid",children:t.jsxs("section",{className:"panel settings-card",children:[t.jsxs("header",{children:[t.jsx(py,{size:20}),t.jsxs("div",{children:[t.jsx("h3",{children:u("Appearance")}),t.jsx("p",{children:u("Set the mood and give your work room.")})]})]}),t.jsx("span",{className:"settings-label",children:u("Theme")}),t.jsx("div",{className:"theme-choices",children:[{id:"light",name:"Light",icon:py},{id:"dark",name:"Dark",icon:qj},{id:"system",name:"System",icon:NU}].map(p=>t.jsxs("button",{className:e.theme===p.id?"selected":"","aria-pressed":e.theme===p.id,onClick:()=>h({theme:p.id}),children:[t.jsxs("span",{className:`theme-mini ${p.id}`,children:[t.jsx("i",{}),t.jsx("b",{}),t.jsx("em",{})]}),t.jsxs("span",{children:[t.jsx(p.icon,{size:14}),u(p.name),u(e.theme===p.id&&t.jsx(Kt,{size:13}))]})]},p.id))}),t.jsxs("label",{children:[u("Display density"),t.jsxs("select",{"aria-label":u("Display density"),value:e.density,onChange:p=>h({density:p.target.value}),children:[t.jsx("option",{value:"comfortable",children:u("Comfortable")}),t.jsx("option",{value:"compact",children:u("Compact")})]})]}),t.jsx(Jp,{label:u("Reduced motion"),description:"Minimize animations and smooth scrolling.",value:e.reduceMotion,onChange:p=>h({reduceMotion:p})}),t.jsx(Jp,{label:u("Confirmation messages"),description:"Show small confirmations after workspace changes.",value:e.showToasts,onChange:p=>h({showToasts:p})})]})}),o==="Chat"&&t.jsx("div",{className:"settings-grid",children:t.jsxs("section",{className:"panel settings-card",children:[t.jsxs("header",{children:[t.jsx(yi,{size:20}),t.jsxs("div",{children:[t.jsx("h3",{children:u("Chat preferences")}),t.jsx("p",{children:u("Keep conversations moving your way.")})]})]}),t.jsxs("label",{children:[u("Send messages with"),t.jsxs("select",{"aria-label":u("Send messages with"),value:e.sendKey,onChange:p=>h({sendKey:p.target.value}),children:[t.jsx("option",{value:"enter",children:u("Enter")}),t.jsx("option",{value:"modifier",children:u("Ctrl / ⌘ + Enter")})]})]}),t.jsxs("div",{className:"settings-shortcut",children:[t.jsx(ts,{size:17}),t.jsx("p",{children:u(e.sendKey==="enter"?"Enter sends your message. Shift + Enter adds a new line.":"Ctrl or ⌘ + Enter sends your message. Enter adds a new line.")})]})]})}),o==="Models"&&t.jsx("div",{className:"settings-grid",children:t.jsx(xY,{})}),o==="Mail"&&t.jsx(iY,{}),o==="Writing style"&&t.jsx(oY,{}),o==="Backups"&&t.jsx(fW,{onRestored:a}),o==="Updates"&&t.jsx(vY,{}),t.jsxs(on,{title:u("Reset your preferences?"),description:"Restore language, appearance, and workspace preferences to their defaults.",open:n,onClose:()=>s(!1),children:[t.jsx("p",{className:"pro-small",children:u("Your agents, documents, integrations, and conversations will stay in place.")}),t.jsxs("div",{className:"pro-actions right",children:[t.jsx("button",{className:"secondary-btn",onClick:()=>s(!1),children:u("Keep preferences")}),t.jsx("button",{className:"primary-btn",onClick:()=>{$p(Ud),s(!1)},children:u("Reset preferences")})]})]})]})}function bY({agents:a}){const e=Nl(),n=Bi(),[s,o]=C.useState("all"),[l,d]=C.useState("all"),[h,m]=C.useState(!1),[p,y]=C.useState(""),[v,x]=C.useState(!1),[S,M]=C.useState(""),[w,E]=C.useState(null),[A,k]=C.useState(""),[R,N]=C.useState(!1),[I,z]=C.useState(!1),[j,L]=C.useState(""),[D,P]=C.useState(""),[F,q]=C.useState(!1),J=Fi(F),ie=Tl();C.useEffect(()=>{ie.view==="Approval Inbox"&&ie.id&&(y(ie.id),m(!1),x(!1))},[ie.stamp]);const Q=bh(),V=ee=>(s==="all"||ee.agentId===s)&&(l==="all"||ee.kind===l),$=Q.filter(V),te=e.decisions.filter(ee=>V(ee.item)),ne=$.find(ee=>ee.id===p)||$[0],Y=ee=>[...a,...n.archived].find(Ce=>Ce.id===ee),T=wN(e.notifications,new Date,Da().timezone);async function _(ee,Ce=""){if(!ne||F)return;const Ze=v?S:ne.body;if(!(ee==="Approved"&&!Ze.trim())){q(!0);try{await $c("/api/approvals/decide",{id:ne.id,decision:ee,note:Ce,body:Ze}),await Za(),L(`${ne.title}: ${ee.toLowerCase()}.`),x(!1),E(null),k(""),z(!1)}catch(le){L(le.message)}finally{q(!1)}}}async function ve(){if(ne?.sourceId){q(!0);try{const ee=await wt("/api/approvals/signin",{toolId:ne.sourceId});window.open(ee.url,"_blank","noopener"),L("Finish signing in on the page that just opened. This item clears itself once the connection is active."),z(!1)}catch(ee){L(ee.message)}finally{q(!1)}}}async function je(ee){P("");const Ce=!e.notifications[ee];try{Ce&&ee!=="telegram"&&await MN(ee,e.pushKey),wa(Ze=>{Ze.notifications[ee]=Ce})}catch(Ze){P(Ze.message)}}async function Je(){try{const ee=await wt("/api/owner/test-alert",{});P(ee.message)}catch(ee){P(ee.message)}}function xe(){ne&&(M(ne.body),x(!0))}return t.jsxs("div",{className:"owner-page",children:[t.jsxs("div",{className:"ow-banner",children:[t.jsx("div",{className:"ow-banner-icon",children:t.jsx(Jd,{size:25})}),t.jsxs("div",{children:[t.jsx("span",{className:"panel-kicker",children:u("YOUR NEXT DECISION")}),t.jsx("h2",{children:u("Good work. Your final say.")}),t.jsx("p",{children:u("Review the work, shape the draft, and keep your team moving.")})]}),t.jsxs("button",{className:"secondary-btn",onClick:()=>{P(""),N(!0)},children:[t.jsx(rl,{size:16}),u("Notifications"),T&&t.jsx("span",{className:"ow-dot"})]})]}),t.jsx(lY,{}),t.jsxs("div",{className:"ow-metrics",children:[t.jsxs("div",{children:[t.jsx("span",{children:u("Waiting on you")}),t.jsx("strong",{children:Q.length}),t.jsx("small",{children:u("Across your team")})]}),t.jsxs("div",{children:[t.jsx("span",{children:u("Plans & results")}),t.jsx("strong",{children:Q.filter(ee=>ee.kind.startsWith("Mission")).length}),t.jsx("small",{children:u("Ready for a decision")})]}),t.jsxs("div",{children:[t.jsx("span",{children:u("Decisions made")}),t.jsx("strong",{children:e.decisions.length}),t.jsx("small",{children:u("A complete decision trail")})]})]}),t.jsxs("div",{className:"ow-toolbar",children:[t.jsxs("div",{className:"segmented",children:[t.jsxs("button",{className:h?"":"selected",onClick:()=>m(!1),children:[u("Waiting")," ",t.jsx("b",{children:Q.length})]}),t.jsx("button",{className:h?"selected":"",onClick:()=>m(!0),children:u("Decision history")})]}),t.jsxs("div",{className:"ow-filters",children:[t.jsxs("select",{"aria-label":"Filter approvals by agent",value:s,onChange:ee=>o(ee.target.value),children:[t.jsx("option",{value:"all",children:u("All agents")}),[...a,...n.archived].map(ee=>t.jsx("option",{value:ee.id,children:ee.name},ee.id))]}),t.jsxs("select",{"aria-label":"Filter approvals by kind",value:l,onChange:ee=>d(ee.target.value),children:[t.jsx("option",{value:"all",children:u("Every kind")}),lW.map(ee=>t.jsx("option",{value:ee,children:u(ee)},ee))]})]})]}),j&&t.jsx(Ot,{children:j}),e.decisions.filter(ee=>ee.outcome==="Carrying it out now.").map(ee=>t.jsx(Ma,{className:"compact",label:`Carrying out "${ee.item.title}"`,since:Date.parse(ee.time),expect:45},ee.id)),h?t.jsx("section",{className:"panel ow-history",children:te.length?te.map(ee=>t.jsxs("article",{children:[t.jsx(qt,{agent:Y(ee.item.agentId)||{id:ee.item.agentId,name:"Archived agent"},small:!0}),t.jsxs("div",{children:[t.jsx("h3",{children:ee.item.title}),t.jsxs("p",{children:[Y(ee.item.agentId)?.name||"Archived agent"," · ",u(ee.item.kind)]}),t.jsxs("small",{children:[ee.by," · ",Yn(ee.time)]}),ee.note&&t.jsx("blockquote",{children:ee.note}),ee.outcome==="Carrying it out now."?t.jsx(Ma,{className:"compact",label:"Carrying it out now",since:Date.parse(ee.time),expect:45}):ee.outcome&&t.jsx("p",{className:"pro-small",children:ee.outcome}),t.jsxs("details",{children:[t.jsx("summary",{children:u("View reviewed version")}),t.jsx(So,{text:ee.item.body,breaks:!0})]})]}),t.jsx(_t,{tone:ee.decision==="Approved"?"lime":ee.decision==="Rejected"?"rose":"amber",children:u(ee.decision)})]},ee.id)):t.jsxs("div",{className:"ow-empty",children:[t.jsx(ts,{size:30}),t.jsx("h3",{children:u("No decisions match these filters.")})]})}):t.jsxs("div",{className:"ow-inbox-layout",children:[t.jsx("section",{className:"panel ow-inbox-list","aria-label":"Waiting approvals",children:$.length?$.map(ee=>t.jsxs("button",{className:ne?.id===ee.id?"selected":"",onClick:()=>{y(ee.id),x(!1)},children:[t.jsxs("span",{className:"ow-item-head",children:[t.jsx(qt,{agent:Y(ee.agentId)||{id:ee.agentId,name:"Agent"},small:!0}),t.jsx("span",{children:Y(ee.agentId)?.name||"Agent"}),t.jsx("small",{children:Yn(ee.arrived)})]}),t.jsx("strong",{children:ee.title}),t.jsx("span",{className:"ow-kind",children:u(ee.kind)}),t.jsx("p",{children:ee.body.replace(/[#*]/g,"").slice(0,110)}),t.jsx(_i,{size:16})]},ee.id)):t.jsxs("div",{className:"ow-empty",children:[t.jsx(Kt,{size:28}),t.jsx("h3",{children:u(Q.length?"No items match these filters.":"You are all caught up.")}),t.jsx("p",{children:u(Q.length?"Try another agent or kind to see the waiting work.":"New work will appear here when it needs your decision.")})]})}),t.jsx("section",{className:`panel ow-review ${ne?"":"is-empty"}`,children:ne?t.jsxs(t.Fragment,{children:[t.jsxs("header",{children:[t.jsxs("div",{children:[t.jsx("span",{className:"panel-kicker",children:u(ne.kind)}),t.jsx("h2",{children:ne.title}),t.jsxs("p",{children:[Y(ne.agentId)?.name||"Agent"," · ",Yn(ne.arrived)]})]}),t.jsx(_t,{tone:"amber",children:u("Needs you")})]}),ne.destination&&t.jsxs("div",{className:"ow-destination",children:[t.jsx(_i,{size:15}),ne.destination]}),t.jsx("div",{className:"ow-review-body",children:v?t.jsxs("label",{children:[u("Edit the draft"),t.jsx("textarea",{"aria-label":"Approval draft",rows:14,value:S,onChange:ee=>M(ee.target.value)}),t.jsxs("div",{className:"pro-actions",children:[t.jsx("button",{className:"secondary-btn",onClick:()=>{wa(ee=>{ee.edits[ne.id]=S}),x(!1)},children:u("Save draft")}),t.jsx("button",{className:"text-btn",onClick:()=>x(!1),children:u("Cancel")})]})]}):t.jsx(So,{text:ne.body,breaks:!0})}),t.jsxs("footer",{children:[t.jsxs("div",{className:"pro-actions",children:[t.jsxs("button",{className:"secondary-btn",onClick:xe,children:[t.jsx(Mr,{size:15}),u("Edit draft")]}),t.jsxs("button",{className:"secondary-btn",onClick:()=>{E("Sent back"),k("")},children:[t.jsx(L2,{size:15}),u("Send back")]})]}),t.jsxs("div",{className:"pro-actions",children:[t.jsxs("button",{className:"ow-reject",onClick:()=>{E("Rejected"),k("")},children:[t.jsx(da,{size:15}),u("Reject")]}),t.jsxs("button",{className:"primary-btn",disabled:F||v&&!S.trim(),onClick:()=>ne.kind==="Tool sign-in"?z(!0):_("Approved"),children:[t.jsx(Kt,{size:16}),u(ne.kind==="Tool sign-in"?"Finish sign-in":"Approve")]})]})]})]}):t.jsxs("div",{className:"ow-empty",children:[t.jsx(Jd,{size:34}),t.jsx("h3",{children:u("A little space for the next decision.")})]})})]}),t.jsxs(on,{open:!!w,onClose:()=>E(null),title:w==="Sent back"?"Send back with a note":"Reject this item",description:ne?.title,children:[t.jsxs("label",{children:[u(w==="Sent back"?"What should the agent change?":"Reason (optional)"),t.jsx("textarea",{"aria-label":"Decision note",rows:4,value:A,onChange:ee=>k(ee.target.value)})]}),t.jsxs("div",{className:"pro-actions right",children:[t.jsx("button",{className:"secondary-btn",onClick:()=>E(null),children:u("Cancel")}),t.jsx("button",{className:"primary-btn",disabled:F||w==="Sent back"&&!A.trim(),onClick:()=>w&&_(w,A),children:u(w||"Confirm")})]})]}),t.jsxs(on,{open:I,onClose:()=>z(!1),title:ne?.title||"Finish connecting",description:ne?.destination,children:[t.jsx("div",{className:"ow-connect-icon",children:(ne?.sourceId||"?").slice(0,1).toUpperCase()}),t.jsx("p",{className:"pro-small",children:u("Sign in on the app’s own page, in a new tab. Laboratorio never sees your password.")}),t.jsx(Ot,{children:u("This item clears itself once the connection is active. Reject it instead to remove the connection.")}),F&&t.jsx(Ma,{label:"Asking the app for your sign-in page",since:J,expect:20}),t.jsx("button",{className:"primary-btn",disabled:F,onClick:ve,children:t.jsxs(Xn,{busy:F,label:"Getting the sign-in page",children:[t.jsx(za,{size:16}),u("Open the sign-in page")]})})]}),t.jsxs(on,{open:R,onClose:()=>N(!1),title:"Your attention, on your terms.",description:"Choose where approval alerts arrive.",wide:!0,children:[t.jsx("div",{className:"ow-notification-grid",children:[{key:"browser",name:"Browser notifications",description:"An alert while you work on your computer.",Icon:rl},{key:"phone",name:"Phone notifications",description:"For Laboratorio added to your phone’s home screen.",Icon:fy},{key:"telegram",name:"Telegram messages",description:"A short message with a link to the waiting item.",Icon:yi}].map(ee=>t.jsxs("article",{children:[t.jsx(ee.Icon,{size:21}),t.jsx("h3",{children:u(ee.name)}),t.jsx("p",{children:u(ee.description)}),t.jsx("button",{className:"pref-switch",role:"switch","aria-label":ee.name,"aria-checked":e.notifications[ee.key],onClick:()=>je(ee.key),children:t.jsx("i",{})})]},ee.key))}),e.notifications.phone&&t.jsxs("div",{className:"ow-guide",children:[t.jsx(fy,{size:20}),t.jsxs("div",{children:[t.jsx("strong",{children:u("Add Laboratorio to your home screen")}),t.jsx("p",{children:u("Open the dashboard on your phone, choose Share, then Add to Home Screen. Allow notifications when the connected app asks.")})]})]}),e.notifications.telegram&&t.jsxs("label",{children:[u("Telegram destination"),t.jsx("input",{"aria-label":"Telegram destination",placeholder:"Your chat id, for example 123456789",value:e.notifications.telegramChat,onChange:ee=>wa(Ce=>{Ce.notifications.telegramChat=ee.target.value})})]}),e.notifications.telegram&&!e.telegramReady&&t.jsx(Ot,{error:!0,children:u("Telegram needs your agents’ bot on this server and your chat id above.")}),t.jsxs("div",{className:"ow-quiet",children:[t.jsxs("label",{className:"ow-check",children:[t.jsx("input",{type:"checkbox",checked:e.notifications.quiet,onChange:ee=>wa(Ce=>{Ce.notifications.quiet=ee.target.checked})}),u("Quiet hours")]}),t.jsxs("label",{children:[u("From"),t.jsx("input",{type:"time",value:e.notifications.start,onChange:ee=>wa(Ce=>{Ce.notifications.start=ee.target.value||"22:00"})})]}),t.jsxs("label",{children:[u("Until"),t.jsx("input",{type:"time",value:e.notifications.end,onChange:ee=>wa(Ce=>{Ce.notifications.end=ee.target.value||"08:00"})})]}),t.jsx("small",{children:Da().timezone})]}),t.jsx(Ot,{children:u("Switch notifications on from each device that should buzz. On a phone, add Laboratorio to the home screen first and open it from there.")}),D&&t.jsx(Ot,{children:u(D)}),t.jsxs("div",{className:"pro-actions right",children:[t.jsx("button",{className:"secondary-btn",onClick:Je,children:u("Send a test alert")}),t.jsx("button",{className:"primary-btn",onClick:()=>N(!1),children:u("Done")})]})]})]})}const zN=".pdf,.txt,.md,.csv,.json,.docx,.xlsx,.xls,.png,.jpg,.jpeg,.webp,.gif",SY=20*1024*1024,AY=50*1024*1024,EY=8;function iS(a){const e=a.split(".").at(-1)?.toLowerCase();return["png","jpg","jpeg","webp","gif"].includes(e||"")?"image":["txt","md","csv","json"].includes(e||"")?"text":["xlsx","xls"].includes(e||"")?"spreadsheet":["pdf","docx"].includes(e||"")?"document":null}function LN(a,e){return iS(a.name)?e.length>=EY?"You can attach up to 8 files per message.":a.size>SY?"Each file must be 20 MB or smaller.":a.size+e.reduce((n,s)=>n+s.size,0)>AY?"Attachments must total 50 MB or less.":"":"Choose a supported image, document, or spreadsheet."}const sS=new Map;let Tp;function rS(){return Tp||(Tp=new Promise((a,e)=>{const n=indexedDB.open("laboratorio-pro-attachments-v1",1);n.onupgradeneeded=()=>n.result.createObjectStore("files"),n.onsuccess=()=>a(n.result),n.onerror=()=>{Tp=void 0,e(n.error)}})),Tp}async function wY(a){const e=crypto.randomUUID();sS.set(e,a);let n=!1;try{const s=await rS();await new Promise((o,l)=>{const d=s.transaction("files","readwrite");d.objectStore("files").put(a,e),d.oncomplete=()=>o(),d.onerror=()=>l(d.error),d.onabort=()=>l(d.error)}),n=!0}catch{}return{id:e,name:a.name,size:a.size,type:a.type,kind:iS(a.name),persistent:n}}async function MY(a){const e=sS.get(a);if(e)return e;try{const n=await rS();return await new Promise((s,o)=>{const l=n.transaction("files").objectStore("files").get(a);l.onsuccess=()=>s(l.result||null),l.onerror=()=>o(l.error)})}catch{return null}}async function ON(a){const e=await MY(a);if(e)return e;try{const n=await fetch(`/api/chat/file?id=${encodeURIComponent(a)}`);return n.ok?await n.blob():null}catch{return null}}async function CY(a){sS.delete(a);try{(await rS()).transaction("files","readwrite").objectStore("files").delete(a)}catch{}}function oS(a){return a>=1024*1024?`${(a/1024/1024).toFixed(1)} MB`:`${Math.max(1,Math.ceil(a/1024))} KB`}const PN="laboratorio-chat-dock";let si=(()=>{try{const a=JSON.parse(localStorage.getItem(PN)||"[]");return Array.isArray(a)?a.filter(e=>e&&typeof e.id=="string"):[]}catch{return[]}})(),Fb=si.reduce((a,e)=>Math.max(a,e.seat||0),0);const Bb=new Set;function Dl(a){si=a;try{localStorage.setItem(PN,JSON.stringify(si))}catch{}Bb.forEach(e=>e())}const TY=()=>typeof window>"u"?3:window.innerWidth<760?1:Math.max(1,Math.min(3,Math.floor((window.innerWidth-320)/390)));function IN(a){const e=a.filter(s=>s.open).sort((s,o)=>o.at-s.at),n=new Set(e.slice(0,TY()).map(s=>s.id));return a.map(s=>s.open&&!n.has(s.id)?{...s,open:!1}:s)}function lo(a){const e=Date.now(),n=si.find(s=>s.id===a);Dl(IN(n?si.map(s=>s.id===a?{...s,open:!0,at:e,unread:0,preview:void 0,seat:s.open?s.seat:++Fb}:s):[...si,{id:a,open:!0,seat:++Fb,unread:0,at:e}]))}function jY(a){si.some(e=>e.id===a)||Dl([...si,{id:a,open:!1,seat:++Fb,unread:0,at:Date.now()}])}const UN="laboratorio-chat-dock-drafts";let Bc=(()=>{try{const a=JSON.parse(localStorage.getItem(UN)||"{}");return a&&typeof a=="object"?a:{}}catch{return{}}})();function lS(a,e){if(e.trim())Bc={...Bc,[a]:e};else{const{[a]:n,...s}=Bc;Bc=s}try{localStorage.setItem(UN,JSON.stringify(Bc))}catch{}}function FN(a){const e=Bc[a]||"";return e&&lS(a,""),e}function RY(a){Dl(si.map(e=>e.id===a?{...e,open:!1}:e))}function BN(a){Dl(si.filter(e=>e.id!==a))}function _C(a){Dl(si.map(e=>e.id===a?{...e,at:Date.now()}:e))}function kY(a,e){Dl(si.map(n=>n.id===a&&!n.open?{...n,unread:n.unread+1,preview:e}:n))}function NY(){Dl(IN(si))}function DY(){return C.useSyncExternalStore(a=>(Bb.add(a),()=>Bb.delete(a)),()=>si,()=>si)}function zY({agents:a,onOpenChatTab:e,hidden:n=!1}){const s=DY(),[o,l]=C.useState(null),d=C.useRef({}),h=o?.pending||{},m=o?.data.rooms||{};async function p(){try{const w=await fetch("/api/chat",{cache:"no-store"});if(!w.ok)return;const E=await w.json();for(const A of y.current){const k=E.data.rooms[A.id]||[],R=d.current[A.id];if(R!==void 0&&k.length>R){const N=k.slice(R).filter(I=>I.role==="assistant");N.length&&!A.open&&kY(A.id,N.at(-1).text.replace(/[#*`_>]/g,"").slice(0,90))}d.current[A.id]=k.length}l(E)}catch{}}const y=C.useRef(s);y.current=s;const v=s.some(w=>h[w.id]);C.useEffect(()=>{if(!s.length)return;p();const w=setInterval(p,v?2e3:6e3);return()=>clearInterval(w)},[s.length,v]),C.useEffect(()=>{const w=()=>NY();return addEventListener("resize",w),()=>removeEventListener("resize",w)},[]),C.useEffect(()=>{const w=window.visualViewport;if(!w)return;const E=document.documentElement,A=()=>{const k=Math.max(0,Math.round(innerHeight-w.height-w.offsetTop));E.style.setProperty("--dock-kb",`${k}px`),E.style.setProperty("--dock-vh",`${Math.round(w.height)}px`)};return A(),w.addEventListener("resize",A),w.addEventListener("scroll",A),()=>{w.removeEventListener("resize",A),w.removeEventListener("scroll",A),E.style.removeProperty("--dock-kb"),E.style.removeProperty("--dock-vh")}},[]);const x=s.filter(w=>a.some(E=>E.id===w.id));if(!x.length||n)return null;const S=x.filter(w=>w.open).sort((w,E)=>E.seat-w.seat),M=x.filter(w=>!w.open);return t.jsxs("div",{className:"chat-dock","aria-label":u("Open chats"),children:[t.jsx("div",{className:"chat-dock-windows",children:S.map(w=>t.jsx(LY,{c:w,agent:a.find(E=>E.id===w.id),messages:m[w.id]||[],pending:!!h[w.id],since:h[w.id]||0,failed:o?.failed?.[w.id]?.error,onSent:p,onOpenChatTab:e},w.id))}),!!M.length&&t.jsx("div",{className:"chat-dock-heads",children:M.map(w=>{const E=a.find(A=>A.id===w.id);return t.jsxs("div",{className:`chat-head ${h[w.id]?"replying":""}`,children:[w.preview&&t.jsxs("button",{className:"chat-head-preview",onClick:()=>lo(w.id),children:[t.jsx("strong",{children:E.name}),w.preview]}),t.jsxs("button",{className:"chat-head-face",onClick:()=>lo(w.id),"aria-label":u(`Open the chat with ${E.name}`),title:E.name,children:[t.jsx(qt,{agent:E,working:!!h[w.id]||E.status==="Working"}),w.unread>0&&t.jsx("b",{children:w.unread>9?"9+":w.unread})]}),t.jsx("button",{className:"chat-head-close",onClick:()=>BN(w.id),"aria-label":u(`Close the chat with ${E.name}`),children:t.jsx(da,{size:12})})]},w.id)})})]})}function LY({c:a,agent:e,messages:n,pending:s,since:o=0,failed:l,onSent:d,onOpenChatTab:h}){const m=mu(),[p,y]=C.useState(()=>FN(a.id)),[v,x]=C.useState(!1),[S,M]=C.useState(""),w=C.useRef(null),[E,A]=C.useState([]),[k,R]=C.useState(!1),N=C.useRef(null),I=C.useRef(null);function z(){if(k){N.current?.stop();return}const J=window,ie=J.SpeechRecognition||J.webkitSpeechRecognition;if(!ie){M("This browser cannot listen. Use Chrome or Edge, or type your message.");return}if(!window.isSecureContext){M("The microphone needs the dashboard’s https address.");return}const Q=new ie;Q.lang=navigator.language||"en-US",Q.interimResults=!1,Q.continuous=!1,N.current=Q,R(!0),M(""),Q.onresult=V=>{const $=Array.from(V.results).map(te=>te[0].transcript).join(" ").trim();$&&y(te=>te?`${te} ${$}`:$)},Q.onerror=V=>{V.error==="not-allowed"?M("Allow the microphone for this site in your browser, then try again."):V.error!=="no-speech"&&V.error!=="aborted"&&M(`The microphone stopped: ${V.error}.`)},Q.onend=()=>{N.current=null,R(!1)},Q.start()}C.useEffect(()=>()=>N.current?.stop(),[]);const j=C.useRef(p);j.current=p,C.useEffect(()=>()=>lS(a.id,j.current),[a.id]);async function L(J){for(const ie of Array.from(J||[])){const Q=LN(ie,E);if(Q){M(Q);continue}const V={id:crypto.randomUUID(),name:ie.name,size:ie.size,type:ie.type,kind:iS(ie.name),persistent:!0,uploading:!0};A($=>[...$,V]);try{const $=await fetch(`/api/chat/upload?id=${encodeURIComponent(V.id)}&name=${encodeURIComponent(V.name)}`,{method:"POST",body:ie});if(!$.ok)throw new Error((await $.json().catch(()=>({}))).error||`${V.name} could not be uploaded.`);A(te=>te.map(ne=>ne.id===V.id?{...ne,uploading:!1}:ne))}catch($){A(te=>te.filter(ne=>ne.id!==V.id)),M($.message)}}I.current&&(I.current.value="")}const D=v||s,P=D||e.status==="Working";C.useEffect(()=>{w.current?.scrollIntoView({block:"end"})},[n.length,D]);async function F(){const J=E.filter(Q=>!Q.uploading),ie=p.trim()||(J.length?"Please review the attached files.":"");if(!(!ie||D||E.some(Q=>Q.uploading))){N.current?.stop(),x(!0),M(""),_C(a.id);try{const Q=await fetch("/api/chat",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({room:e.id,text:ie,attachments:J.map(({uploading:$,...te})=>te)})}),V=await Q.json().catch(()=>({}));if(!Q.ok)throw new Error(V.error||"The message could not be sent.");y(""),A([]),d()}catch(Q){M(Q.message)}finally{x(!1)}}}function q(J){(m.sendKey==="enter"?J.key==="Enter"&&!J.shiftKey:J.key==="Enter"&&(J.ctrlKey||J.metaKey))&&(J.preventDefault(),F())}return t.jsxs("section",{className:"chat-window panel","aria-label":u(`Chat with ${e.name}`),onMouseDown:()=>_C(a.id),children:[t.jsxs("header",{children:[t.jsx(qt,{agent:e,small:!0,working:P}),t.jsxs("div",{children:[t.jsx("strong",{children:e.name}),t.jsx("small",{className:P?"is-working":"",children:u(P?"Working…":e.status==="Paused"?"Paused":"Ready")})]}),t.jsx("button",{onClick:()=>h(e.id),"aria-label":u("Open in the Chat tab"),title:u("Open in the Chat tab"),children:t.jsx(yi,{size:15})}),t.jsx("button",{onClick:()=>RY(a.id),"aria-label":u("Minimise"),title:u("Minimise"),children:t.jsx(Hj,{size:16})}),t.jsx("button",{onClick:()=>BN(a.id),"aria-label":u("Close"),title:u("Close"),children:t.jsx(da,{size:16})})]}),t.jsxs("div",{className:"chat-window-body",children:[!n.length&&t.jsx("p",{className:"chat-window-empty",children:u(`Say hello to ${e.name}.`)}),n.slice(-40).map(J=>t.jsxs("div",{className:`chat-bubble ${J.role}`,children:[J.role==="assistant"?t.jsx(So,{text:J.text}):J.text,!!J.attachments?.length&&t.jsx("div",{className:"chat-bubble-files",children:J.attachments.map(ie=>t.jsxs("a",{href:`/api/chat/file?id=${encodeURIComponent(ie.id)}`,target:"_blank",rel:"noopener",children:[t.jsx(Si,{size:12}),ie.name]},ie.id))})]},J.id)),D&&t.jsxs("div",{className:"chat-window-thinking",children:[t.jsx(Jt,{size:14,className:"spinning"}),u(`${e.name} is working on it…`),t.jsx(vi,{since:o?o*1e3:null})]}),!D&&l&&t.jsx("div",{className:"chat-window-error",role:"alert",children:u(`${e.name} could not answer: ${l}`)}),t.jsx("div",{ref:w})]}),t.jsxs("footer",{onPointerDown:J=>{J.target.closest("button")&&J.preventDefault()},children:[S&&t.jsx("p",{className:"chat-window-error",role:"alert",children:S}),!!E.length&&t.jsx("div",{className:"chat-window-files",children:E.map(J=>t.jsxs("span",{className:J.uploading?"uploading":"",children:[J.uploading?t.jsx(Jt,{size:12,className:"spinning"}):t.jsx(Si,{size:12}),J.name,t.jsx("small",{children:oS(J.size)}),t.jsx("button",{onClick:()=>A(ie=>ie.filter(Q=>Q.id!==J.id)),"aria-label":u(`Remove ${J.name}`),children:t.jsx(da,{size:11})})]},J.id))}),t.jsxs("div",{children:[t.jsx("input",{ref:I,type:"file",multiple:!0,hidden:!0,accept:zN,onChange:J=>L(J.target.files)}),t.jsx("button",{className:"chat-window-tool",onClick:()=>I.current?.click(),"aria-label":u("Attach files"),title:u("Attach files"),children:t.jsx(fo,{size:16})}),t.jsx("button",{className:`chat-window-tool ${k?"listening":""}`,onClick:z,"aria-label":u(k?"Stop listening":"Speak instead of typing"),title:u(k?"Stop listening":"Speak instead of typing"),children:t.jsx(_b,{size:16})}),t.jsx("textarea",{rows:1,value:p,onChange:J=>y(J.target.value),onKeyDown:q,placeholder:u(k?"Listening… speak now":`Message ${e.name}`),"aria-label":u(`Message ${e.name}`)}),t.jsx("button",{className:"chat-window-send",disabled:!p.trim()&&!E.some(J=>!J.uploading)||D||E.some(J=>J.uploading),onClick:F,"aria-label":u("Send message"),children:v?t.jsx(Jt,{size:16,className:"spinning"}):t.jsx(em,{size:17})})]})]})]})}const Hb=["Email","Your voice","Approval","Mission","Automation","Schedule","Backup","Tool sign-in","Agent error"];let ys={seen:[],cleared:[],enabled:Object.fromEntries(Hb.map(a=>[a,!0])),disabledAt:{},events:[]};const Gb=new Set,Vb=()=>Gb.forEach(a=>a());function $C(){return ys}function OY(){return C.useSyncExternalStore(a=>(Gb.add(a),()=>Gb.delete(a)),$C,$C)}async function qb(){try{ys={...ys,...await wt("/api/notifications")},Vb()}catch{}}typeof window<"u"&&(qb(),setInterval(qb,3e4));function jp(a){const e=ys,n=structuredClone(ys);a(n),ys=n,Vb();const s=d=>n[d].filter(h=>!e[d].includes(h)),o=JSON.stringify(e.enabled)!==JSON.stringify(n.enabled)?n.enabled:void 0,l={seen:s("seen"),cleared:s("cleared"),enabled:o};!l.seen.length&&!l.cleared.length&&!o||wt("/api/notifications",l,"PUT").then(d=>{ys={...ys,...d},Vb()}).catch(()=>qb())}function PY(a,e,n,s,o,l=ys.events){const d=[...l];if(a.stage==="inbox")for(const h of a.emails.filter(m=>!m.deleted&&m.at>(a.lastSorted||"")&&a.categories.find(p=>p.id===m.categoryId)?.notify).slice(0,50))d.push({id:`email:${h.id}`,kind:"Email",title:h.subject,detail:`${h.sender} · ${a.categories.find(m=>m.id===h.categoryId)?.name||"Other"}`,at:h.at,view:"Mail",targetId:h.id});for(const h of e)d.push({id:`approval:${h.id}`,kind:h.kind.startsWith("Mission")?"Mission":h.kind==="Tool sign-in"?"Tool sign-in":"Approval",title:h.kind==="Mission plan"?"Mission plan ready":h.kind==="Mission result"?"Mission result ready":h.kind==="Tool sign-in"?"Finish signing in":"Waiting for your approval",detail:h.title,at:h.arrived,view:"Approval Inbox",targetId:h.id});for(const h of n.filter(m=>m.status==="Failed"))d.push({id:`mission:${h.id}`,kind:"Mission",title:"Mission needs attention",detail:h.name,at:h.timeline.at(-1)?.time||h.created,view:"Missions",targetId:h.id,failed:!0});for(const h of s)d.push({id:`automation:${h.id}`,kind:"Automation",title:h.status==="Failed"?"Automation needs attention":"Automation completed",detail:h.outcome,at:h.time,view:"Automations",targetId:h.ruleId,section:"history",failed:h.status==="Failed"});for(const h of o)d.push({id:`backup:${h.id}`,kind:"Backup",title:"Team backup made",detail:h.name,at:h.created,view:"Settings",targetId:h.id,section:"backups"});return d.filter((h,m)=>d.findIndex(p=>p.id===h.id)===m).filter(h=>!(ys.disabledAt[h.kind]&&h.at>ys.disabledAt[h.kind])).sort((h,m)=>m.at.localeCompare(h.at))}function IY(a,e,n){return a.filter(s=>!e.includes(s.id)&&!n.includes(s.id))}const Rp=a=>a>99?"99+":a>0?String(a):"",UY={Email:ei,"Your voice":Mr,Approval:Jd,Mission:Ns,Automation:Fs,Schedule:Ds,Backup:tu,"Tool sign-in":Vc,"Agent error":tm};function FY({onOpen:a}){const e=Eu(),n=Nl(),s=Bi(),o=OY(),[l,d]=C.useState(""),[h,m]=C.useState(!1),[p,y]=C.useState(!1),[v,x]=C.useState(!1),[S,M]=C.useState("all"),w=e.stage==="inbox"?dl(e.emails).filter(j=>j.unread):[],E=e.stage==="inbox"?$0(e.emails).length:0,A=PY(e,bh(),s.missions,n.runs,n.backups,o.events).filter(j=>!o.cleared.includes(j.id)),k=IY(A,o.seen,o.cleared),R=A.filter(j=>S==="all"||j.kind===S),N=wN(n.notifications,new Date,Da().timezone);async function I(j){d("");const L=!n.notifications[j];try{L&&j!=="telegram"&&await MN(j,n.pushKey),wa(D=>{D.notifications[j]=L})}catch(D){d(D.message)}}function z(j){jp(L=>{L.seen.includes(j.id)||L.seen.push(j.id)}),m(!1),a(j.view,j.targetId,j.section)}return t.jsxs("div",{className:"workspace-alerts",children:[t.jsxs("div",{className:"top-mail-control",children:[t.jsxs("button",{className:"top-alert-button","aria-label":`${H("Open Mail")}, ${ml(w)} ${H("unread")}`,title:H("Open unread mail"),onClick:()=>a("Mail",void 0,"unread"),children:[t.jsx(ei,{size:20}),Rp(ml(w))&&t.jsx("span",{className:"top-alert-count",children:Rp(ml(w))}),E>0&&t.jsx("i",{className:"top-mail-urgent",title:`${E} ${H("Needs attention")}`,"aria-label":`${E} ${H("Needs attention")}`})]}),t.jsxs(Fw,{open:p,onOpenChange:y,children:[t.jsx(Bw,{className:"top-mail-preview-trigger","aria-label":H("Preview unread mail"),children:t.jsx(Fd,{size:13})}),t.jsx(Hw,{children:t.jsxs(Gw,{className:"workspace-popover mail-top-preview",align:"end",sideOffset:14,children:[t.jsxs("header",{children:[t.jsxs("div",{children:[t.jsx("h2",{children:H("Unread mail")}),t.jsxs("p",{children:[E," ",H("Needs attention")]})]}),t.jsx(Vw,{"aria-label":H("Close preview"),children:t.jsx(da,{size:17})})]}),w.length?w.slice(0,3).map(j=>t.jsxs("button",{className:"mail-preview-item",onClick:()=>{y(!1),a("Mail",j.id)},children:[t.jsx("span",{children:j.sender}),t.jsx("strong",{children:j.subject}),t.jsx("small",{children:H(e.categories.find(L=>L.id===j.categoryId)?.name||"Other")}),t.jsx(Kn,{size:15})]},j.id)):t.jsxs("div",{className:"notification-empty",children:[t.jsx(ei,{size:25}),t.jsx("strong",{children:H("No unread mail")}),t.jsx("p",{children:H("Your inbox is up to date.")})]}),t.jsx("footer",{children:t.jsxs("button",{onClick:()=>{y(!1),a("Mail")},children:[H("Open Mail"),t.jsx(Kn,{size:15})]})})]})})]})]}),t.jsxs(Fw,{open:h,onOpenChange:m,children:[t.jsxs(Bw,{className:"top-alert-button","aria-label":`${H("Notifications")}, ${k.length} ${H("unseen")}`,title:H("Notifications"),children:[t.jsx(rl,{size:20}),Rp(k.length)&&t.jsx("span",{className:"top-alert-count",children:Rp(k.length)})]}),t.jsx(Hw,{children:t.jsxs(Gw,{className:"workspace-popover notification-panel",align:"end",sideOffset:14,children:[t.jsxs("header",{children:[t.jsxs("div",{children:[t.jsx("h2",{children:H("Notifications")}),t.jsxs("p",{children:[k.length?`${k.length} ${H("unseen")}`:H("All caught up"),N&&t.jsx("span",{className:"notification-quiet",children:H("Quiet hours active")})]})]}),t.jsx("button",{"aria-label":H("Notification choices"),onClick:()=>{m(!1),x(!0)},children:t.jsx(rs,{size:18})}),t.jsx(Vw,{"aria-label":H("Close notifications"),children:t.jsx(da,{size:18})})]}),t.jsxs("div",{className:"notification-controls",children:[t.jsxs("select",{"aria-label":H("Filter notifications by kind"),value:S,onChange:j=>M(j.target.value),children:[t.jsx("option",{value:"all",children:H("Every kind")}),Hb.map(j=>t.jsx("option",{value:j,children:H(j)},j))]}),t.jsxs("button",{disabled:!k.length,onClick:()=>jp(j=>{j.seen=[...new Set([...j.seen,...A.map(L=>L.id)])]}),children:[t.jsx(nl,{size:15}),H("Mark all as seen")]})]}),t.jsx("div",{className:"notification-feed",children:R.length?R.map(j=>{const L=UY[j.kind]||rl,D=o.seen.includes(j.id);return t.jsxs("button",{className:`notification-row ${D?"seen":"new"} ${j.failed?"failed":""}`,onClick:()=>z(j),children:[t.jsx("span",{className:"notification-symbol",children:t.jsx(L,{size:18})}),t.jsxs("span",{className:"notification-text",children:[t.jsxs("span",{className:"notification-row-meta",children:[t.jsx("b",{children:H(j.kind)}),t.jsx("time",{children:Yn(j.at)})]}),t.jsx("strong",{children:H(j.title)}),t.jsx("span",{children:j.kind==="Email"?(()=>{const P=e.emails.find(F=>F.id===j.targetId);return P?`${P.sender} · ${H(e.categories.find(F=>F.id===P.categoryId)?.name||"Other")}`:H(j.detail)})():H(j.detail)}),t.jsxs("small",{children:[H(D?"Seen":"New"),j.failed&&t.jsxs(t.Fragment,{children:[t.jsx(hl,{size:12}),H("Needs attention")]})]})]}),!D&&t.jsx("i",{className:"notification-new-dot"})]},j.id)}):t.jsxs("div",{className:"notification-empty",children:[t.jsx(rl,{size:28}),t.jsx("strong",{children:H("Nothing new")}),t.jsx("p",{children:H("Updates from your inbox and team will appear here.")})]})}),t.jsxs("footer",{children:[t.jsx("button",{disabled:!A.some(j=>o.seen.includes(j.id)),onClick:()=>jp(j=>{j.cleared=[...new Set([...j.cleared,...A.filter(L=>j.seen.includes(L.id)).map(L=>L.id)])]}),children:H("Clear seen notifications")}),t.jsxs("button",{onClick:()=>{m(!1),x(!0)},children:[t.jsx(rs,{size:14}),H("Notification choices")]})]})]})})]}),t.jsx(on,{open:v,onClose:()=>x(!1),title:H("Notification choices"),description:H("Choose what reaches you, and when."),wide:!0,children:t.jsxs("div",{className:"notification-preferences",children:[t.jsx("h3",{children:H("Which updates notify you")}),t.jsx("div",{className:"notification-kind-choices",children:Hb.map(j=>t.jsxs("label",{children:[t.jsx("input",{type:"checkbox",checked:o.enabled[j],onChange:L=>jp(D=>{D.enabled[j]=L.target.checked})}),H(j)]},j))}),t.jsx("p",{children:H("Email alerts also follow the choices in each Mail category. These choices affect future alerts, not your existing history.")}),t.jsx("h3",{children:H("Where alerts arrive")}),t.jsx("div",{className:"notification-channel-choices",children:[{key:"browser",label:"Browser notifications",Icon:rl},{key:"phone",label:"Phone notifications",Icon:fy},{key:"telegram",label:"Telegram messages",Icon:yi}].map(j=>t.jsxs("label",{children:[t.jsx(j.Icon,{size:19}),t.jsx("span",{children:H(j.label)}),t.jsx("button",{role:"switch","aria-label":H(j.label),"aria-checked":n.notifications[j.key],className:"pref-switch",onClick:()=>I(j.key),children:t.jsx("i",{})})]},j.key))}),l&&t.jsx("p",{className:"mail-key-error",role:"alert",children:l}),n.notifications.phone&&t.jsx("p",{children:H("On a phone, add Laboratorio to the home screen and open it from there to receive alerts.")}),n.notifications.telegram&&t.jsxs("label",{children:[H("Telegram destination"),t.jsx("input",{value:n.notifications.telegramChat,onChange:j=>wa(L=>{L.notifications.telegramChat=j.target.value})})]}),t.jsxs("div",{className:"notification-quiet-fields",children:[t.jsxs("label",{children:[t.jsx("input",{type:"checkbox",checked:n.notifications.quiet,onChange:j=>wa(L=>{L.notifications.quiet=j.target.checked})}),H("Quiet hours")]}),t.jsxs("label",{children:[H("From"),t.jsx("input",{type:"time",value:n.notifications.start,onChange:j=>wa(L=>{L.notifications.start=j.target.value||"22:00"})})]}),t.jsxs("label",{children:[H("Until"),t.jsx("input",{type:"time",value:n.notifications.end,onChange:j=>wa(L=>{L.notifications.end=j.target.value||"08:00"})})]}),t.jsx("span",{children:Da().timezone})]}),t.jsx("p",{children:H("Quiet hours hold browser, phone and Telegram alerts. The bell always keeps them.")}),t.jsx("button",{className:"primary-btn",onClick:()=>x(!1),children:H("Done")})]})})]})}const BY=[{id:"gallery-email",name:"A reply, ready for you",description:"Draft thoughtful replies to important emails.",trigger:"Email from a sender",instructions:"Prepare a concise email reply. Highlight any commitments for my review.",destination:"Approval Inbox",role:"Content Writer",Icon:ei},{id:"gallery-slack",name:"Mention to action",description:"Keep the next step from getting lost in Slack.",trigger:"Slack mention",instructions:"Summarize the mention and turn the next action into a personal to-do.",destination:"To-do",role:"Orchestrator",Icon:yi},{id:"gallery-watch",name:"Watch the competition",description:"A clear summary when a pricing page changes.",trigger:"Web page changes",instructions:"Compare changes and explain how they affect our positioning.",destination:"Docs",role:"Researcher",Icon:Qb},{id:"gallery-github",name:"Issue to mission",description:"Give every new bug a clear path to resolution.",trigger:"New GitHub issue",instructions:"Triage the issue and prepare a mission plan with acceptance criteria.",destination:"Mission",role:"Developer",Icon:Op}];function HY({data:a,onSave:e}){const n=Nl(),[s,o]=C.useState(""),[l,d]=C.useState(null),[h,m]=C.useState(""),[p,y]=C.useState("All rules"),[v,x]=C.useState(null),[S,M]=C.useState(""),[w,E]=C.useState(""),[A,k]=C.useState(""),[R,N]=C.useState(!1),[I,z]=C.useState(""),j=C.useRef(!1);C.useEffect(()=>{l||z("")},[!!l]);const L=Tl();C.useEffect(()=>{L.view==="Automations"&&L.id&&x(L.id)},[L.stamp]);const D=Y=>a.agents.find(T=>T.id===Y),P=()=>({id:Db(),name:"",trigger:"New email",source:"",sender:"",subject:"",weekdays:!1,at:"",agentId:a.agents[0]?.id||"",instructions:"",destination:"Approval Inbox",enabled:!0,created:new Date().toISOString()}),F=Y=>d(T=>T&&{...T,...Y}),q=n.rules.filter(Y=>p==="All rules"||(p==="Active"?Y.enabled:!Y.enabled)),J=Date.now()-7*864e5;function ie(Y){const T={"New email":"a new email arrives","Email from a sender":"an email arrives","Slack message":"a Slack message arrives","Slack mention":"someone mentions you in Slack","New calendar event":"a calendar event is added","New GitHub issue":"a GitHub issue is opened","New form submission":"a form is submitted","File in a folder":"a file arrives","Web page changes":"a watched web page changes"},_=Y.instructions.trim().replace(/[.!]$/,""),ve={"Approval Inbox":"asks for your approval",Docs:"saves the result to Docs",Telegram:"sends the result to Telegram","To-do":"adds a personal to-do",Mission:"starts a mission plan for your review"};return`${Y.trigger==="On a schedule"?`Every ${Y.weekdays?"weekday":"day"} at ${Y.at||"07:00"}`:`When ${T[Y.trigger]||Y.trigger}${Y.source?` in ${Y.source}`:""}${Y.sender?` from ${Y.sender}`:""}${Y.subject?` containing “${Y.subject}”`:""}${Y.weekdays?" on weekdays":""}`}, ${D(Y.agentId)?.name||"the assigned agent"} follows this brief: “${_||"Your instructions"}”, then ${ve[Y.destination]}.`}function Q(Y){if(n.rules.some(_=>_.templateId===Y.id)){E("This automation is already in your rules.");return}const T={...P(),name:Y.name,trigger:Y.trigger,instructions:Y.instructions,destination:Y.destination,agentId:a.agents.find(_=>_.name===Y.role)?.id||a.agents[0]?.id||"",templateId:Y.id};if(["Email from a sender","Web page changes","New GitHub issue"].includes(Y.trigger)){d({...T,enabled:!0}),E(Y.trigger==="Email from a sender"?"Add the sender’s address, then save to switch it on.":Y.trigger==="Web page changes"?"Add the page to watch, then save to switch it on.":"Add the repository (owner/name), then save to switch it on.");return}wa(_=>{_.rules.unshift(T)}),E("Automation added and switched on.")}function V(){!l||!l.name.trim()||!l.instructions.trim()||!D(l.agentId)||l.trigger==="Email from a sender"&&!l.sender.trim()||["File in a folder","Web page changes"].includes(l.trigger)&&!l.source.trim()||l.trigger==="On a schedule"&&!/^([01]\d|2[0-3]):[0-5]\d$/.test(l.at||"")||(wa(Y=>{const T=Y.rules.findIndex(_=>_.id===l.id);T<0?Y.rules.unshift(l):Y.rules[T]=l}),d(null),E("Rule saved. Your team knows what happens next."))}async function $(Y){if(!S){M(Y.id),k(""),E(""),j.current=!0;try{await $c("/api/automations/test",{id:Y.id})}catch(T){k(T.message),M(""),j.current=!1}}}C.useEffect(()=>{if(!S||!j.current)return;const Y=n.rules.find(T=>T.id===S);if(Y&&!Y.testing){const T=n.runs.find(_=>_.ruleId===S);T&&(T.status==="Completed"?E(`Test complete. ${T.outcome}`):k(T.outcome)),j.current=!1,M("")}},[n,S]);async function te(){N(!0),k(""),E("");try{const Y=await wt("/api/automations/suggest",{words:s});d({...P(),...Y.rule}),z(Y.ask||""),E("Suggested rule filled in. Review the trigger, agent, and destination.")}catch(Y){k(Y.message)}finally{N(!1)}}const ne=n.rules.find(Y=>Y.id===v);return t.jsxs("div",{className:"owner-page",children:[t.jsxs("div",{className:"ow-banner",children:[t.jsx("div",{className:"ow-banner-icon",children:t.jsx(Df,{size:25})}),t.jsxs("div",{children:[t.jsx("span",{className:"panel-kicker",children:u("SMALL RULES. BIG MOMENTUM.")}),t.jsx("h2",{children:u("Your team, on cue.")}),t.jsx("p",{children:u("Turn everyday events into useful work, with your approval where it matters.")})]}),t.jsxs("button",{className:"primary-btn",onClick:()=>d(P()),children:[t.jsx(jn,{size:16}),u("Create rule")]})]}),t.jsxs("section",{className:"panel ow-prompt",children:[t.jsx(Ha,{size:23}),t.jsxs("div",{children:[t.jsx("h3",{children:u("Describe it. Then make it yours.")}),t.jsx("p",{children:u("Tell us what should happen. Review the suggested rule before switching it on.")}),t.jsxs("div",{children:[t.jsx("input",{"aria-label":"Describe an automation",placeholder:"When an email arrives from Maya, draft a reply and ask me first...",value:s,maxLength:1500,onChange:Y=>o(Y.target.value)}),t.jsxs("button",{className:"primary-btn",disabled:!s.trim()||R,onClick:te,children:[t.jsx(Xn,{busy:R,label:"Drafting the rule",children:u("Build a draft")}),!R&&t.jsx(Kn,{size:16})]})]})]})]}),t.jsxs("div",{className:"ow-toolbar",children:[t.jsx("div",{className:"segmented",children:["All rules","Active","Paused"].map(Y=>t.jsx("button",{className:p===Y?"selected":"",onClick:()=>y(Y),children:u(Y)},Y))}),t.jsxs("p",{className:"pro-small",children:[n.rules.filter(Y=>Y.enabled).length," ",u("active")," · ",n.runs.filter(Y=>Date.parse(Y.time)>J).length," ",u("runs this week")]})]}),w&&t.jsx(Ot,{children:w}),(A||n.error)&&t.jsx(Ot,{error:!0,children:A||n.error}),t.jsx("div",{className:"ow-rule-grid",children:q.map(Y=>{const T=n.runs.filter(_=>_.ruleId===Y.id);return t.jsxs("article",{className:"panel ow-rule",children:[t.jsxs("header",{children:[t.jsx("span",{className:"ow-rule-icon",children:t.jsx(Df,{size:19})}),t.jsx(_t,{tone:Y.enabled?"lime":"neutral",children:u(Y.enabled?"Active":"Paused")}),t.jsx("button",{role:"switch","aria-label":`Enable ${Y.name}`,"aria-checked":Y.enabled,className:"pref-switch",onClick:()=>wa(_=>{const ve=_.rules.find(je=>je.id===Y.id);ve&&(ve.enabled=!ve.enabled)}),children:t.jsx("i",{})})]}),t.jsx("h3",{children:Y.name}),t.jsx("p",{children:ie(Y)}),Y.enabled&&Y.problem&&t.jsx(Ot,{error:!0,children:Y.problem}),t.jsxs("div",{className:"ow-rule-agent",children:[t.jsx(qt,{agent:D(Y.agentId)||{id:Y.agentId,name:"Choose an agent"},small:!0}),t.jsx("span",{children:D(Y.agentId)?.name||u("Choose an agent")}),t.jsx(Kn,{size:14}),t.jsx("strong",{children:u(Y.destination)})]}),t.jsxs("div",{className:"ow-rule-meta",children:[t.jsxs("span",{children:[u("Last run"),t.jsx("strong",{children:T[0]?Yn(T[0].time):u("Not yet")})]}),t.jsxs("span",{children:[u("This week"),t.jsxs("strong",{children:[T.filter(_=>Date.parse(_.time)>J).length," ",u("runs")]})]})]}),t.jsx("footer",{children:h===Y.id?t.jsxs("div",{className:"ow-rule-delete",children:[t.jsx("span",{children:u("Delete this rule?")}),t.jsx("button",{className:"text-btn",onClick:()=>m(""),children:u("Keep it")}),t.jsxs("button",{className:"ow-reject",onClick:()=>{wa(_=>{_.rules=_.rules.filter(ve=>ve.id!==Y.id)}),m(""),E("Automation deleted.")},children:[t.jsx(ti,{size:14}),u("Delete")]})]}):t.jsxs(t.Fragment,{children:[t.jsxs("button",{className:"text-btn",onClick:()=>d(structuredClone(Y)),children:[t.jsx(Mr,{size:14}),u("Edit")]}),t.jsxs("button",{className:"text-btn",onClick:()=>x(Y.id),children:[t.jsx(fl,{size:14}),u("History")]}),t.jsx("button",{className:"secondary-btn",disabled:!!S||Y.testing,onClick:()=>$(Y),children:t.jsxs(Xn,{busy:S===Y.id||!!Y.testing,label:"Testing",children:[t.jsx(gi,{size:14})," ",u("Test it")]})}),t.jsx("button",{className:"icon-btn ow-rule-trash","aria-label":u(`Delete ${Y.name}`),title:u("Delete"),onClick:()=>m(Y.id),children:t.jsx(ti,{size:15})})]})})]},Y.id)})}),!q.length&&t.jsxs("div",{className:"ow-empty panel",children:[t.jsx(Df,{size:30}),t.jsx("h3",{children:u("No rules in this view.")})]}),t.jsxs("div",{className:"ow-section-title",children:[t.jsxs("div",{children:[t.jsx("span",{className:"panel-kicker",children:u("READY WHEN YOU ARE")}),t.jsx("h2",{children:u("A head start on the everyday.")})]}),t.jsx("p",{children:u("One click to add a ready-made automation.")})]}),t.jsx("div",{className:"ow-gallery",children:BY.map(Y=>t.jsxs("article",{className:"panel",children:[t.jsx(Y.Icon,{size:22}),t.jsx("h3",{children:Y.name}),t.jsx("p",{children:Y.description}),t.jsxs("button",{className:"secondary-btn",disabled:n.rules.some(T=>T.templateId===Y.id),onClick:()=>Q(Y),children:[n.rules.some(T=>T.templateId===Y.id)?t.jsx(Kt,{size:14}):t.jsx(jn,{size:14})," ",u(n.rules.some(T=>T.templateId===Y.id)?"Added":"Switch on")]})]},Y.id))}),t.jsx(on,{open:!!l,onClose:()=>d(null),title:n.rules.some(Y=>Y.id===l?.id)?"Shape this rule":"Create an automation",description:"When this happens, this agent does this, then this.",wide:!0,children:l&&t.jsxs(t.Fragment,{children:[t.jsxs("label",{children:[u("Rule name"),t.jsx("input",{"aria-label":"Rule name",maxLength:100,value:l.name,onChange:Y=>F({name:Y.target.value})})]}),t.jsxs("div",{className:"ow-rule-builder",children:[t.jsxs("section",{children:[t.jsx("span",{className:"ow-step",children:"01"}),t.jsx("h3",{children:u("WHEN")}),t.jsxs("label",{children:[u("Event"),t.jsx("select",{"aria-label":"Automation event",value:l.trigger,onChange:Y=>F({trigger:Y.target.value,...Y.target.value==="On a schedule"&&!l.at?{at:"07:00"}:{}}),children:cW.map(Y=>t.jsx("option",{value:Y,children:u(Y)},Y))})]}),l.trigger==="On a schedule"?t.jsxs("label",{children:[u("Time of day"),t.jsx("input",{type:"time","aria-label":"Time of day",value:l.at||"",onChange:Y=>F({at:Y.target.value})})]}):t.jsxs("label",{children:[u("App, folder, or page"),t.jsx("input",{"aria-label":"Event source",value:l.source,onChange:Y=>F({source:Y.target.value}),placeholder:l.trigger==="Web page changes"?"https://example.com/pricing":l.trigger==="File in a folder"?"/incoming":"Gmail, #product, or repository"})]}),l.trigger==="Email from a sender"&&t.jsxs("label",{children:[u("Sender"),t.jsx("input",{"aria-label":"Sender filter",value:l.sender,onChange:Y=>F({sender:Y.target.value})})]}),t.jsxs("details",{children:[t.jsx("summary",{children:u("Optional filters")}),l.trigger!=="On a schedule"&&t.jsxs("label",{children:[u("Subject or message contains"),t.jsx("input",{value:l.subject,onChange:Y=>F({subject:Y.target.value})})]}),!["Email from a sender","On a schedule"].includes(l.trigger)&&t.jsxs("label",{children:[u("Sender is"),t.jsx("input",{value:l.sender,onChange:Y=>F({sender:Y.target.value})})]}),t.jsxs("label",{className:"ow-check",children:[t.jsx("input",{type:"checkbox",checked:l.weekdays,onChange:Y=>F({weekdays:Y.target.checked})}),u("Only on weekdays")]})]})]}),t.jsxs("section",{children:[t.jsx("span",{className:"ow-step",children:"02"}),t.jsx("h3",{children:u("WHO")}),t.jsxs("label",{children:[u("Agent"),t.jsx("select",{"aria-label":"Automation agent",value:l.agentId,onChange:Y=>F({agentId:Y.target.value}),children:a.agents.map(Y=>t.jsx("option",{value:Y.id,children:Y.name},Y.id))})]}),D(l.agentId)&&t.jsxs("div",{className:"ow-selected-agent",children:[t.jsx(qt,{agent:D(l.agentId)}),t.jsx("strong",{children:D(l.agentId)?.name}),t.jsx("p",{children:D(l.agentId)?.role})]})]}),t.jsxs("section",{children:[t.jsx("span",{className:"ow-step",children:"03"}),t.jsx("h3",{children:u("DOES WHAT")}),t.jsxs("label",{children:[u("Your instructions"),t.jsx("textarea",{"aria-label":"Automation instructions",rows:6,value:l.instructions,onChange:Y=>F({instructions:Y.target.value}),placeholder:"What should the agent prepare?"})]})]}),t.jsxs("section",{children:[t.jsx("span",{className:"ow-step",children:"04"}),t.jsx("h3",{children:u("THEN")}),t.jsxs("label",{children:[u("Send the result to"),t.jsx("select",{"aria-label":"Automation destination",value:l.destination,onChange:Y=>F({destination:Y.target.value}),children:uW.map(Y=>t.jsx("option",{value:Y,children:u(Y)},Y))})]}),t.jsx("p",{className:"pro-small",children:u(l.destination==="Approval Inbox"?"Ask me first. Work waits for your decision before it goes further.":l.destination==="Telegram"?"Prepare a short Telegram message with the result.":l.destination==="Mission"?"Create a mission plan that waits for your approval.":"Keep a useful result in your workspace.")}),t.jsxs("label",{className:"ow-check",children:[t.jsx("input",{type:"checkbox",checked:l.enabled,onChange:Y=>F({enabled:Y.target.checked})}),u("Switch on after saving")]})]})]}),I&&t.jsx(Ot,{children:I}),t.jsxs("div",{className:"ow-rule-summary",children:[t.jsx(Df,{size:18}),ie(l)]}),t.jsxs("div",{className:"pro-actions right",children:[t.jsx("button",{className:"secondary-btn",onClick:()=>d(null),children:u("Cancel")}),t.jsxs("button",{className:"primary-btn",disabled:!l.name.trim()||!l.instructions.trim()||!D(l.agentId)||l.trigger==="Email from a sender"&&!l.sender.trim()||["File in a folder","Web page changes"].includes(l.trigger)&&!l.source.trim()||l.trigger==="On a schedule"&&!/^([01]\d|2[0-3]):[0-5]\d$/.test(l.at||""),onClick:V,children:[t.jsx(Kt,{size:16}),u("Save rule")]})]})]})}),t.jsx(on,{open:!!v,onClose:()=>x(null),title:ne?.name||"Run history",description:"What happened, what was prepared, and where it went.",wide:!0,children:t.jsxs("div",{className:"ow-run-history",children:[n.runs.filter(Y=>Y.ruleId===v).map(Y=>t.jsxs("article",{children:[t.jsxs("div",{children:[t.jsx(_t,{tone:Y.status==="Completed"?"lime":"rose",children:Y.status}),t.jsx("span",{children:Yn(Y.time)}),t.jsxs("strong",{children:["$",Y.cost.toFixed(3)," · ",Y.tokens.toLocaleString()," tokens"]})]}),t.jsx("h3",{children:Y.trigger}),t.jsx("p",{children:Y.outcome}),t.jsxs("details",{children:[t.jsx("summary",{children:u("See what the agent did")}),t.jsx(So,{text:Y.work})]})]},Y.id)),!n.runs.some(Y=>Y.ruleId===v)&&t.jsxs("div",{className:"ow-empty",children:[t.jsx(fl,{size:30}),t.jsx("h3",{children:u("No runs yet. Test the rule to see its first result.")})]})]})})]})}function eT({values:a=[],color:e="var(--accent)",max:n}){const s=n??Math.max(1,...a),o=a.length>1?a:[a[0]||0,a[0]||0],l=o.map((d,h)=>`${(h*296/(o.length-1)).toFixed(1)},${(65-d/s*60).toFixed(1)}`).join(" ");return t.jsxs("svg",{viewBox:"0 0 300 68",preserveAspectRatio:"none","aria-label":u("Resource history"),role:"img",children:[t.jsx("path",{d:`M ${l.replaceAll(" "," L ")} L 296,68 L 0,68 Z`,fill:e,opacity:".08"}),t.jsx("polyline",{points:l,fill:"none",stroke:e,strokeWidth:"2"}),t.jsx("line",{x1:"0",x2:"300",y1:"67",y2:"67",stroke:"var(--line)"})]})}const ry=a=>`${(a/1e9).toFixed(a>=1e11?0:1)} GB`,tT=(a,e=!1)=>e?a>=1e6?`${(a/1e6).toFixed(1)} Mbps`:`${Math.round(a/1e3)} kbps`:a>=1e6?`${(a/1e6).toFixed(1)} MB/s`:`${Math.round(a/1e3)} KB/s`;function GY({agents:a}){Bi();const[e,n]=C.useState(!1),[s,o]=C.useState(""),[l,d]=C.useState("1 hour"),[h,m]=C.useState(!1),[p,y]=C.useState(""),[v,x]=C.useState(null);async function S(){try{x(await wt("/api/health")),y("")}catch(k){y(k.message)}}C.useEffect(()=>{S();const k=setInterval(()=>{document.hidden||S()},1e4);return()=>clearInterval(k)},[]);const M=v?.checks||[],w=M.filter(k=>!k.ok),E=(v?.processes||[]).map(k=>({...k,agent:a.find(R=>R.id===k.agentId)})).filter(k=>(!e||!!k.agent)&&k.name.toLowerCase().includes(s.toLowerCase()));async function A(){m(!0),await S(),m(!1),y("Checks updated just now.")}return t.jsxs("div",{className:"pro-health",children:[t.jsxs("div",{className:"section-heading",children:[t.jsxs("div",{children:[t.jsxs("h2",{children:[u("Host & health "),t.jsx(_t,{tone:"lime",children:u("PRO")})]}),t.jsx("p",{className:"section-description",children:u("The machine behind the workspace, and the checks that keep it ready.")})]}),t.jsx("span",{className:"pro-small",children:u(v?`Live from ${v.host.host}`:"Reading the machine…")})]}),t.jsxs("section",{className:`panel pro-health-banner ${w.length?"warning":"good"}`,children:[t.jsx("span",{children:u(w.length?t.jsx(iw,{size:24}):t.jsx(za,{size:24}))}),t.jsxs("div",{children:[t.jsx("h3",{children:u(w.length?"Needs attention":"All good")}),t.jsx("p",{children:u(w.length?`${w.length} ${w.length===1?"check needs":"checks need"} a look. The rest of the workspace is healthy.`:"Every check is passing. Your workspace is ready.")})]}),t.jsxs("button",{className:"secondary-btn",disabled:h,onClick:A,children:[u(h?t.jsx(Jt,{size:16,className:"spinning"}):t.jsx(xl,{size:16})),u("Recheck")]})]}),p&&t.jsx(Ot,{children:u(p)}),t.jsx("div",{className:"pro-host-grid",children:[["Operating system",v?.host.os||"…"],["Kernel",v?.host.kernel||"…"],["Time zone",v?.host.timezone||"…"],["Uptime",v?.host.uptime||"…"],["Load average",v?v.host.load.join(" / "):"…"],["Host",v?.host.host||"…"]].map(([k,R])=>t.jsxs("div",{className:"panel",children:[t.jsx("span",{children:u(k)}),t.jsx("strong",{children:u(R)})]},k))}),t.jsxs("div",{className:"pro-health-grid",children:[t.jsxs("section",{className:"panel pro-cores",children:[t.jsxs("div",{className:"panel-title",children:[t.jsxs("div",{children:[t.jsx("h2",{children:u("CPU per core")}),t.jsx("p",{children:u(v?`${v.host.cores} logical cores · ${v.host.cpuModel}`:"Reading…")})]}),t.jsx(_t,{tone:"green",children:u(`${Math.round(v?.cpu||0)}% average`)})]}),t.jsx("div",{children:(v?.cores||[]).map((k,R)=>t.jsxs("div",{children:[t.jsxs("span",{children:[u("Core "),u(R+1)]}),t.jsx("div",{className:"pro-core-track",children:t.jsx("i",{style:{width:`${k}%`}})}),t.jsxs("strong",{children:[u(k),u("%")]}),t.jsx(eT,{values:(v?.history["5 minutes"]?.cpu||[]).length?v.history["5 minutes"].cpu:[k],max:100})]},R))})]}),t.jsxs("section",{className:"panel pro-resource-history",children:[t.jsxs("div",{className:"panel-title",children:[t.jsxs("div",{children:[t.jsx("h2",{children:u("Short history")}),t.jsx("p",{children:u("CPU, memory, disk, and network.")})]}),t.jsxs("select",{"aria-label":u("Resource history period"),value:l,onChange:k=>d(k.target.value),children:[t.jsx("option",{value:"5 minutes",children:u("5 minutes")}),t.jsx("option",{value:"1 hour",children:u("1 hour")}),t.jsx("option",{value:"24 hours",children:u("24 hours")})]})]}),[{name:"CPU",key:"cpu",value:`${Math.round(v?.cpu||0)}%`,icon:cy,color:"var(--chart-resource)",max:100},{name:"Memory",key:"memory",value:`${Math.round(v?.memory||0)}%`,icon:Lj,color:"var(--chart-throughput)",max:100},{name:"Disk I/O",key:"disk",value:tT(v?.current.disk||0),icon:tu,color:"var(--chart-storage)",max:void 0},{name:"Network",key:"network",value:tT(v?.current.network||0,!0),icon:hy,color:"var(--chart-amber)",max:void 0}].map(k=>t.jsxs("div",{children:[t.jsxs("header",{children:[t.jsxs("span",{children:[t.jsx(k.icon,{size:15}),u(k.name)]}),t.jsx("strong",{children:u(k.value)})]}),t.jsx(eT,{values:v?.history[l]?.[k.key]||[],color:k.color,max:k.max})]},k.name))]})]}),t.jsxs("section",{className:"panel pro-processes",children:[t.jsxs("div",{className:"panel-title",children:[t.jsxs("div",{children:[t.jsx("h2",{children:u("Running processes")}),t.jsx("p",{children:u("Agent workers are named after their specialist.")})]}),t.jsxs("div",{className:"pro-actions",children:[t.jsxs("label",{className:"pro-check-label",children:[t.jsx("input",{type:"checkbox",checked:e,onChange:k=>n(k.target.checked)}),u("Agents only")]}),t.jsx("input",{className:"pro-search",value:s,"aria-label":u("Search processes"),placeholder:u("Search processes"),onChange:k=>o(k.target.value)})]})]}),t.jsxs("div",{className:"task-table proc-table",children:[t.jsxs("table",{children:[t.jsx("thead",{children:t.jsxs("tr",{children:[t.jsx("th",{children:u("Process")}),t.jsx("th",{children:u("PID")}),t.jsx("th",{children:u("CPU")}),t.jsx("th",{children:u("Memory")}),t.jsx("th",{children:u("State")})]})}),t.jsx("tbody",{children:E.map(k=>t.jsxs("tr",{children:[t.jsx("td",{children:u(k.agent?t.jsxs("span",{className:"pro-person",children:[t.jsx(qt,{agent:k.agent,small:!0}),k.name]}):t.jsxs("span",{className:"pro-person",children:[t.jsx(FU,{size:18}),k.name]}))}),t.jsx("td",{children:u(k.pid)}),t.jsxs("td",{children:[u(k.cpu),u("%")]}),t.jsxs("td",{children:[u(k.memory),u(" MB")]}),t.jsx("td",{children:t.jsx(_t,{tone:k.state==="Running"?"green":k.state==="Reconnecting"?"amber":"neutral",children:u(k.state)})})]},k.pid))})]}),!E.length&&t.jsx("p",{className:"empty",children:u("No matching processes.")})]})]}),t.jsxs("div",{className:"pro-health-grid",children:[t.jsxs("section",{className:"panel pro-disks",children:[t.jsxs("div",{className:"panel-title",children:[t.jsx("h2",{children:u("Disks")}),t.jsx(tu,{size:18})]}),(v?.disks||[]).map(k=>({name:k.name,device:k.device,value:k.percent,used:`${ry(k.used)} / ${ry(k.total)}`,free:`${ry(k.free)} free`})).map(k=>t.jsxs("article",{children:[t.jsxs("header",{children:[t.jsx("strong",{children:u(k.name)}),t.jsxs("span",{children:[u(k.value),u("%")]})]}),t.jsx("small",{children:u(k.device)}),t.jsx("div",{className:"pro-progress",children:t.jsx("i",{style:{width:`${k.value}%`}})}),t.jsxs("footer",{children:[t.jsx("span",{children:u(k.used)}),t.jsx("span",{children:u(k.free)})]})]},k.name))]}),t.jsxs("section",{className:"panel pro-connections",children:[t.jsxs("div",{className:"panel-title",children:[t.jsx("h2",{children:u("Network connections")}),t.jsx(hy,{size:18})]}),[...(v?.connections||[]).map(k=>[k.name,k.address,k.status])].map(([k,R,N])=>t.jsxs("div",{children:[t.jsxs("span",{children:[t.jsx("strong",{children:u(k)}),t.jsx("small",{children:u(R)})]}),t.jsx(_t,{tone:["Not running","Not listening","Loading","Not installed","Needs configuration"].includes(N)?"amber":N==="Idle"?"neutral":"green",children:u(N)})]},k))]})]}),t.jsxs("section",{className:"panel pro-health-checks",children:[t.jsxs("div",{className:"panel-title",children:[t.jsxs("div",{children:[t.jsx("h2",{children:u("Health checks")}),t.jsx("p",{children:u("What is ready, what needs a look, and what to do next.")})]}),t.jsxs(_t,{tone:w.length?"amber":"green",children:[u(M.length-w.length),u(" / "),u(M.length),u(" passing")]})]}),t.jsx("div",{children:M.map(k=>t.jsxs("article",{className:k.ok?"pass":"warn",children:[t.jsx("span",{children:u(k.ok?t.jsx(Kt,{size:17}):t.jsx(iw,{size:17}))}),t.jsxs("div",{children:[t.jsx("strong",{children:u(k.name)}),t.jsx("p",{children:u(k.detail)})]}),t.jsx(_t,{tone:k.ok?"green":"amber",children:u(k.ok?"Passing":"Attention")})]},k.name))})]})]})}const VY={Orchestrator:{name:"Orchestrator",role:"Coordinate the team and keep work moving",portrait:"orchestrator",skills:["deep-analysis","meetings"],starterId:"agent-orchestrator"},Researcher:{name:"Researcher",role:"Find evidence and turn it into useful insights",portrait:"researcher",skills:["web-research","deep-analysis"],starterId:"agent-1"},"Content Writer":{name:"Content Writer",role:"Turn ideas into compelling stories",portrait:"content-writer",skills:["writing","email"],starterId:"agent-2"},Developer:{name:"Developer",role:"Build, review, and ship reliable software",portrait:"developer",skills:["code-review","deep-analysis"],starterId:"agent-3"},Designer:{name:"Designer",role:"Shape thoughtful visual experiences",portrait:"designer",skills:["images","writing"],starterId:"agent-designer"},"Marketing Strategist":{name:"Marketing Strategist",role:"Create campaigns and find opportunities for growth",portrait:"marketing-strategist",skills:["social","deep-analysis"],starterId:"agent-marketing"},"Data Analyst":{name:"Data Analyst",role:"Turn numbers into clear decisions",portrait:"data-analyst",skills:["spreadsheets","deep-analysis"],starterId:"agent-analyst"},"Automation Specialist":{name:"Automation Specialist",role:"Connect tools and streamline repetitive work",portrait:"automation-specialist",skills:["automation","meetings"],starterId:"agent-automation"},"Personal Assistant":{name:"Personal Assistant",role:"Run your inbox, calendar and follow-ups",portrait:"executive-assistant",skills:["email","meetings"],starterId:"agent-assistant"},"SEO Specialist":{name:"SEO Specialist",role:"Improve search visibility with practical editorial and technical audits",portrait:"seo-specialist",skills:["web-research","writing"]},"Customer Support":{name:"Customer Support",role:"Prepare thoughtful replies and resolve customer questions",portrait:"customer-support",skills:["email","pdf"]},Bookkeeper:{name:"Bookkeeper",role:"Reconcile records and explain cash flow",portrait:"bookkeeper",skills:["spreadsheets","pdf"]},"Executive Assistant":{name:"Executive Assistant",role:"Organize the owner’s calendar, inbox, and follow-ups",portrait:"executive-assistant",skills:["email","meetings"]},"QA Tester":{name:"QA Tester",role:"Reproduce defects and review release quality",portrait:"qa-tester",skills:["code-review","images"]},Sales:{name:"Sales",role:"Qualify leads and prepare personal outreach",portrait:"sales",skills:["email","web-research"]}};function Oc(a,e,n,s,o,l,d,h){return{id:a,name:e,tag:n,description:s,agents:o.map(m=>VY[m]),jobs:[{name:l,agent:d,cron:"0 9 * * 1-5",instructions:`Review priorities and prepare ${l.toLowerCase()} for the owner.`},{name:`${e} weekly review`,agent:o[0],cron:"0 16 * * 5",instructions:"Summarize completed work, blockers, and next week’s priorities."}],playbooks:[{name:`${e}: first project`,goal:h,team:o},{name:`${e}: quality review`,goal:"Review the latest work against its brief. Identify gaps and prepare a useful improvement plan.",team:o.slice(0,3)}]}}const qY=[Oc("content","Content studio","WORDS WITH PURPOSE","From audience research to a polished editorial calendar.",["Orchestrator","Researcher","Content Writer","Designer","SEO Specialist"],"Editorial planning","Content Writer","Research the audience and prepare a complete month of useful content."),Oc("marketing","Marketing agency","CAMPAIGNS THAT CONNECT","Strategy, creative work, and measurement in one coordinated team.",["Orchestrator","Marketing Strategist","Content Writer","Designer","Data Analyst"],"Campaign pulse","Marketing Strategist","Prepare a launch campaign with positioning, creative concepts, and a measurement plan."),Oc("shop","Online shop","A BETTER CUSTOMER DAY","Keep customer support, product content, and daily operations moving.",["Orchestrator","Customer Support","Content Writer","Bookkeeper","Automation Specialist"],"Store operations brief","Customer Support","Review the customer journey and prepare practical improvements for the store."),Oc("personal","Personal assistant","MAKE ROOM FOR LIFE","A calm team for your inbox, calendar, research, and everyday follow-ups.",["Personal Assistant","Researcher","Bookkeeper","Automation Specialist"],"Morning agenda","Personal Assistant","Prepare a clear personal plan for the week with priorities and follow-ups."),Oc("software","Software studio","FROM BRIEF TO RELEASE","Research, design, development, and quality with clear handoffs.",["Orchestrator","Researcher","Designer","Developer","QA Tester"],"Release readiness","QA Tester","Turn a product brief into a tested, reviewable prototype and release checklist."),Oc("consulting","Consulting practice","CLEAR THINKING, USEFUL WORK","Evidence, client communication, and structured deliverables.",["Orchestrator","Researcher","Data Analyst","Content Writer","Sales"],"Client opportunity brief","Sales","Prepare an evidence-led recommendation and a clear client presentation.")];function WY({data:a}){const e=Bi(),n=Nl(),[s,o]=C.useState(!1),[l,d]=C.useState(null),[h,m]=C.useState([]),[p,y]=C.useState("choose"),[v,x]=C.useState(""),S=n.templateJob,M=p==="done"&&S.result||null,w=S.done||0,E=j=>e.archived.find(L=>L.id===j.starterId)||zC(e.archived,j.name),A=j=>a.agents.find(L=>L.id===j.starterId)||zC(a.agents,j.name)||E(j),k=l?.agents.filter(j=>h.includes(j.name))||[];function R(j){d(j),m(j.agents.filter(L=>!E(L)).map(L=>L.name)),y("choose"),x("")}async function N(){if(!(!l||!k.length)){x("");try{await $c("/api/templates/install",{template:l,agents:k.map(j=>j.name),model:Da().defaultModel,timezone:Da().timezone,skillNames:Object.fromEntries(Ls.map(j=>[j.id,j.name])),skillApproval:Object.fromEntries(Ls.map(j=>[j.id,j.approval]))}),y("creating")}catch(j){x(j.message)}}}C.useEffect(()=>{p!=="creating"||S.running||S.templateId!==l?.id||(Za(),S.error?(x(S.error),y("choose")):y("done"))},[p,S.running,S.templateId,S.error,l?.id]);const I=j=>{const L=S.steps?.[j];return L?.state==="created"?"Created":L?.state==="skipped"?"Recognized and skipped":L?.state==="archived"?"Archived, restore first":L?.state==="failed"?L.error||"Could not be created":L?.state==="working"?"Creating...":"Waiting"},z=()=>{p!=="creating"&&(o(!1),d(null))};return t.jsxs(t.Fragment,{children:[t.jsxs("button",{className:"secondary-btn",onClick:()=>{o(!0),d(null),y("choose")},children:[t.jsx(hh,{size:16}),u("Team templates")]}),t.jsxs(on,{open:s,onClose:z,title:p==="done"?"Your team is ready.":p==="creating"?"Making room for your team":l?l.name:"A team for the work you do.",description:l?.description||"Choose specialists, skills, schedules, and playbooks that belong together.",wide:!0,children:[!l&&t.jsx("div",{className:"ow-template-gallery",children:qY.map(j=>t.jsxs("button",{onClick:()=>R(j),children:[t.jsx("span",{className:"panel-kicker",children:j.tag}),t.jsx("h3",{children:j.name}),t.jsx("p",{children:j.description}),t.jsx("div",{className:"ow-portrait-stack",children:j.agents.slice(0,5).map(L=>t.jsx(qt,{agent:{id:L.name,name:L.name,portrait:L.portrait},small:!0},L.name))}),t.jsxs("span",{children:[j.agents.length," ",u("agents")," · ",j.jobs.length," ",u("schedules")," · ",j.playbooks.length," ",u("playbooks")]}),t.jsx(Kn,{size:18})]},j.id))}),l&&p==="choose"&&t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"ow-template-agents",children:l.agents.map(j=>t.jsxs("label",{className:h.includes(j.name)?"selected":"",children:[t.jsx("input",{type:"checkbox",disabled:!!E(j),checked:h.includes(j.name),onChange:()=>m(L=>L.includes(j.name)?L.filter(D=>D!==j.name):[...L,j.name])}),t.jsx(qt,{agent:{id:A(j)?.id||j.name,name:j.name,portrait:j.portrait}}),t.jsxs("span",{children:[t.jsx("strong",{children:j.name}),t.jsx("p",{children:j.role}),t.jsx("small",{children:j.skills.map(L=>Ls.find(D=>D.id===L)?.name).join(" · ")})]}),t.jsx(_t,{tone:A(j)?"neutral":"lime",children:u(E(j)?"Archived, restore first":A(j)?"Already on your team":"New agent")})]},j.name))}),t.jsxs("div",{className:"ow-template-includes",children:[t.jsxs("section",{children:[t.jsxs("h3",{children:[t.jsx(Ds,{size:18}),u("Included schedules")]}),l.jobs.map(j=>t.jsxs("p",{children:[j.name,t.jsxs("small",{children:[j.agent," · ",j.cron," · ",u("Starts paused")]})]},j.name))]}),t.jsxs("section",{children:[t.jsxs("h3",{children:[t.jsx(Ns,{size:18}),u("Mission playbooks")]}),l.playbooks.map(j=>t.jsxs("p",{children:[j.name,t.jsx("small",{children:j.goal})]},j.name))]})]}),t.jsx(Ot,{children:u("Existing agents are skipped. Archived agents must be restored first. New agents receive the listed skills. Included schedules start paused; playbooks wait for your direction. Unticked agents are left out of the included work.")}),n.installedTemplates.includes(l.id)&&t.jsx("p",{className:"pro-small",children:u("This template’s schedules and playbooks are already installed. They will not be duplicated.")}),t.jsxs("div",{className:"pro-actions spread",children:[t.jsx("button",{className:"secondary-btn",onClick:()=>d(null),children:u("Back to teams")}),t.jsxs("button",{className:"primary-btn",disabled:!k.length,onClick:N,children:[t.jsx(jn,{size:16}),u("Add this team")]})]})]}),l&&p==="creating"&&t.jsxs("div",{className:"ow-team-progress",children:[t.jsx(Jt,{className:"spinning",size:34}),t.jsxs("h3",{children:[l.name,t.jsx(vi,{since:null})]}),t.jsx("div",{className:"pro-progress",children:t.jsx("i",{style:{width:`${Math.max(4,w/Math.max(1,k.length)*100)}%`}})}),t.jsx("div",{"aria-live":"polite",children:k.map((j,L)=>t.jsxs("p",{children:[w>L?t.jsx(Kt,{size:17}):t.jsx(Jt,{size:17,className:"spinning"}),t.jsx("strong",{children:j.name}),t.jsx("span",{children:u(I(L))})]},j.name))})]}),p==="done"&&M&&t.jsxs("div",{className:"ow-team-result",children:[t.jsx("span",{children:t.jsx(Kt,{size:35})}),t.jsx("h3",{children:u("A stronger team, ready for the next brief.")}),t.jsxs("div",{className:"ow-metrics",children:[t.jsxs("div",{children:[t.jsx("strong",{children:M.added}),t.jsx("small",{children:u("agents added")})]}),t.jsxs("div",{children:[t.jsx("strong",{children:M.skipped}),t.jsx("small",{children:u("existing agents skipped")})]}),t.jsxs("div",{children:[t.jsx("strong",{children:M.jobs+M.playbooks}),t.jsx("small",{children:u("schedules & playbooks")})]})]}),!!M.failed&&t.jsx(Ot,{error:!0,children:u(`${M.failed} agent${M.failed===1?"":"s"} could not be created. Try adding the team again; agents already created are skipped.`)}),t.jsx("p",{children:u("Find your specialists in Agents, their scheduled jobs (paused) in Schedule, and their playbooks in Missions. Press Replan on a playbook when you want a plan for it.")}),t.jsxs("button",{className:"primary-btn",onClick:z,children:[u("Meet your team"),t.jsx(Kn,{size:16})]})]}),v&&t.jsx(Ot,{error:!0,children:v})]})]})}const YY=["orchestrator","researcher","content-writer","developer","designer","data-analyst","marketing-strategist","automation-specialist","sales","customer-support","bookkeeper","executive-assistant","recruiter","hr-partner","legal-assistant","qa-tester","seo-specialist","social-media-manager","project-manager","customer-success","translator","operations-manager"];function XY({data:a,onReload:e,selectedId:n,onClose:s,mode:o="rename"}){const l=Bi(),[d,h]=C.useState(!1),[m,p]=C.useState(0),[y,v]=C.useState("Sales"),[x,S]=C.useState(!1),[M,w]=C.useState({name:"Sales",shortName:"SAL",role:hx[0][1],directions:"Qualify needs before pitching. Keep outreach personal and useful.",identity:"",portrait:"orchestrator"}),[E,A]=C.useState(0),[k,R]=C.useState(null),[N,I]=C.useState(!1),[z,j]=C.useState(null),[L,D]=C.useState(""),[P,F]=C.useState(""),[q,J]=C.useState(""),[ie,Q]=C.useState([]),[V,$]=C.useState(""),te=Fi(!!V),ne=Fi(m===2),Y=C.useRef([]);C.useEffect(()=>()=>Y.current.forEach(clearTimeout),[]);const T=a.agents.find(le=>le.id===n);C.useEffect(()=>{n&&T&&(F(T.name),D(""),j(o==="retire"&&T.id!=="agent-orchestrator"?"retire":"rename"))},[n,o]),C.useEffect(()=>{d&&wt("/api/agents/roles").then(le=>{if(Q(le.roles),x)return;const qe=le.roles.find(xt=>!xt.hired);qe&&_(qe)}).catch(()=>{})},[d]);function _(le){v(le.name),w(qe=>({...qe,name:le.name,shortName:le.shortName||le.name.slice(0,3).toUpperCase(),role:le.description,directions:`Act as the workspace ${le.name.toLowerCase()}. Confirm the brief, document assumptions, and prepare useful results for the owner.`,portrait:le.portrait}))}function ve(le){const qe=ie.find(se=>se.name===le);if(qe){_(qe);return}v(le);const xt=hx.find(se=>se[0]===le)?.[1]||"";w(se=>({...se,name:le,shortName:(le.includes(" ")?le.split(" ").map(Pe=>Pe[0]).join(""):le.slice(0,3)).toUpperCase().slice(0,3),role:xt,directions:`Act as the workspace ${le.toLowerCase()}. Confirm the brief, document assumptions, and prepare useful results for the owner.`,portrait:le.toLowerCase().replace(/[^a-z]+/g,"-")}))}function je(){if(!M.name.trim()||!M.shortName.trim()||!M.role.trim()||!M.directions.trim())return;if(J(""),[...a.agents,...l.archived].some(qe=>qe.name.toLowerCase()===M.name.trim().toLowerCase())){J("Choose a name that is not already on your team.");return}const le=!x&&ie.find(qe=>qe.name===y&&qe.name===M.name.trim());w(qe=>({...qe,identity:le&&le.soul?le.soul:`# ${qe.name} ## Role ${qe.role} ## Directions ${qe.directions} ## Working style Be professional, specific, and transparent about assumptions. Ask the owner before irreversible actions. ## Delivery Provide clear results and a useful handoff for the next specialist.`})),p(1)}async function Je(){p(2),A(1),J("");try{const le=Da().defaultModel,qe=await wt("/api/agents/hire",{...M,model:le,provider:Yp(le)});A(2),await Promise.all([e(),Za()]),A(3),R(qe.agent),p(3)}catch(le){J(le.message),p(1)}}async function xe(){if(!(!T||!Ww(L,T.name))){$(`Retiring ${T.name}: archiving its files and taking it off the team`);try{await wt("/api/agents/retire",{id:T.id,confirm:L}),await Promise.all([e(),Za()]),j(null),s()}catch(le){J(le.message)}$("")}}async function ee(){if(!(!T||!P.trim())){$(`Renaming to ${P.trim()} and telling the team`);try{await wt("/api/agents/rename",{id:T.id,name:P.trim()}),await Promise.all([e(),Za()]),j(null),s()}catch(le){J(le.message)}$("")}}async function Ce(le){$(`Restoring ${le.name}: putting it back on the team with its tools`);try{await wt("/api/agents/restore",{id:le.id}),await Promise.all([e(),Za()])}catch(qe){J(qe.message)}$("")}const Ze=()=>{m!==2&&(h(!1),p(0),R(null),J(""))};return t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"pro-team-actions",children:[t.jsxs("div",{children:[t.jsx(_t,{tone:"lime",children:u("PRO TEAM")}),t.jsx("span",{children:u("Build a team around the work you do.")})]}),t.jsxs("div",{className:"pro-actions",children:[t.jsx(WY,{data:a}),t.jsxs("button",{className:"secondary-btn",onClick:()=>I(!0),children:[t.jsx(sl,{size:16}),u("Archived "),t.jsx("span",{children:u(l.archived.length)})]}),t.jsxs("button",{className:"primary-btn",onClick:()=>{ve("Sales"),S(!1),p(0),R(null),h(!0)},children:[t.jsx(sw,{size:17}),u("Hire an agent")]})]})]}),t.jsxs(on,{title:u(m===3?"Your team just grew.":m===2?"Creating your agent":m===1?"Review the identity":"Hire a new specialist"),description:m===0?"Choose a ready-made role or describe your own.":m===1?"Make the identity sound right before your agent joins.":"A new specialist, ready for your workspace.",open:d,onClose:Ze,wide:!0,children:[t.jsx("div",{className:"pro-steps",children:["Define role","Review identity","Create agent"].map((le,qe)=>t.jsxs("span",{className:m>=qe?"current":"",children:[u(m>qe?t.jsx(Kt,{size:13}):qe+1)," ",u(le)]},le))}),m===0&&t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"segmented",children:[t.jsx("button",{className:x?"":"selected",onClick:()=>S(!1),children:u("Ready-made role")}),t.jsx("button",{className:x?"selected":"",onClick:()=>S(!0),children:u("Custom specialist")})]}),!x&&t.jsx("div",{className:"pro-role-grid",children:(ie.length?ie:hx.map(([le,qe])=>({id:le,name:le,description:qe,portrait:"",hired:!1}))).map(le=>t.jsxs("button",{disabled:le.hired,className:`${y===le.name?"selected":""} ${le.portrait?"with-portrait":""}`,onClick:()=>ve(le.name),children:[le.portrait&&t.jsx(qt,{agent:{id:`role-${le.id}`,name:le.name,portrait:le.portrait}}),t.jsxs("span",{className:"pro-role-copy",children:[t.jsx("strong",{children:u(le.name)}),t.jsx("span",{children:u(le.archived?"In Archived. Restore it from there.":le.hired?"Already on your team":le.description)})]}),y===le.name&&!le.hired&&t.jsx(Kt,{size:16})]},le.id))}),t.jsxs("div",{className:"pro-form-grid",children:[t.jsxs("label",{children:[u("Agent name"),t.jsx("input",{required:!0,"aria-label":u("Agent name"),maxLength:64,value:M.name,onChange:le=>w(qe=>({...qe,name:le.target.value}))})]}),t.jsxs("label",{children:[u("Short name"),t.jsx("input",{required:!0,maxLength:8,value:M.shortName,onChange:le=>w(qe=>({...qe,shortName:le.target.value}))})]}),t.jsxs("label",{className:"span-2",children:[u("Role"),t.jsx("textarea",{rows:2,required:!0,value:M.role,onChange:le=>w(qe=>({...qe,role:le.target.value}))})]}),t.jsxs("label",{className:"span-2",children:[u("Directions"),t.jsx("textarea",{required:!0,rows:3,value:M.directions,onChange:le=>w(qe=>({...qe,directions:le.target.value}))})]})]}),t.jsx("div",{className:"pro-actions right",children:t.jsxs("button",{className:"primary-btn",disabled:!M.name.trim()||!M.shortName.trim()||!M.role.trim()||!M.directions.trim(),onClick:je,children:[u("Review identity"),t.jsx(Kn,{size:16})]})})]}),m===1&&t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"pro-identity-header",children:[t.jsx(qt,{agent:{id:"new-agent",name:M.name,portrait:M.portrait}}),t.jsxs("div",{children:[t.jsx("h3",{children:M.name}),t.jsx("p",{children:u(M.role)}),t.jsx(_t,{children:u("New specialist")})]})]}),t.jsxs("label",{children:[u("Portrait"),t.jsx("select",{value:M.portrait,onChange:le=>w(qe=>({...qe,portrait:le.target.value})),children:YY.map(le=>t.jsx("option",{value:le,children:u(le.replaceAll("-"," "))},le))})]}),t.jsxs("label",{children:[u("Identity text"),t.jsx("textarea",{className:"pro-code-input","aria-label":u("Identity text"),rows:12,value:M.identity,onChange:le=>w(qe=>({...qe,identity:le.target.value}))})]}),t.jsxs("p",{className:"form-note",children:[t.jsx(za,{size:15}),u("This becomes the agent’s personality file. You can edit it later in Files.")]}),t.jsxs("div",{className:"pro-actions spread",children:[t.jsxs("button",{className:"secondary-btn",onClick:()=>p(0),children:[t.jsx(eu,{size:16}),u("Back")]}),t.jsxs("button",{className:"primary-btn",disabled:!M.identity.trim(),onClick:Je,children:[t.jsx(sw,{size:16}),u("Hire "),M.name]})]})]}),m===2&&t.jsxs("div",{className:"pro-creation",children:[t.jsx(Jt,{className:"spinning",size:40}),t.jsxs("h3",{children:[u("Making room for "),M.name]}),["Creating the identity","Preparing the portrait","Adding to your workspace"].map((le,qe)=>t.jsxs("p",{children:[u(E>qe?t.jsx(Kt,{size:17}):t.jsx(Jt,{className:"spinning",size:17}))," ",u(le)]},le)),t.jsx("div",{className:"pro-progress",children:t.jsx("i",{style:{width:`${Math.max(E/3*100,xh(vh(ne),45))}%`}})}),t.jsx("small",{children:u("Creating the Hermes profile")})]}),m===3&&k&&t.jsxs("div",{className:"pro-creation",children:[t.jsx(qt,{agent:{...k,portrait:M.portrait}}),t.jsxs("h3",{children:[k.name,u(" is ready.")]}),t.jsx("p",{children:u("Your new specialist is available in Chat, Missions, Files, Schedule, System, and Agent City.")}),t.jsxs("button",{className:"primary-btn",onClick:Ze,children:[u("Meet your team"),t.jsx(Kn,{size:16})]})]}),q&&t.jsx(Ot,{error:!0,children:u(q)})]}),t.jsx(on,{title:u(T?`Manage ${T.name}`:"Manage agent"),open:!!z&&!!T,onClose:()=>{j(null),J(""),s()},description:"Keep the identity. Shape the team.",children:T&&t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"pro-identity-header",children:[t.jsx(qt,{agent:T}),t.jsxs("div",{children:[t.jsx("h3",{children:T.name}),t.jsx("p",{children:u(T.role)})]})]}),t.jsxs("div",{className:"segmented",children:[t.jsxs("button",{className:z==="rename"?"selected":"",onClick:()=>j("rename"),children:[t.jsx(Mr,{size:15}),u("Rename")]}),t.jsxs("button",{className:z==="retire"?"selected":"",onClick:()=>j("retire"),children:[t.jsx(sl,{size:15}),u("Retire")]})]}),z==="rename"?t.jsxs(t.Fragment,{children:[t.jsxs("label",{children:[u("Agent name"),t.jsx("input",{value:P,maxLength:64,onChange:le=>F(le.target.value)})]}),t.jsx("button",{className:"primary-btn",disabled:!P.trim()||!!V,onClick:ee,children:t.jsx(Xn,{busy:!!V,label:"Saving",children:u("Save name")})})]}):t.jsxs(t.Fragment,{children:[t.jsx(Ot,{children:u("Retiring archives the agent and keeps its files, conversations, and completed work. Restore it from Archived agents.")}),t.jsxs("label",{children:[u("Type "),t.jsx("strong",{children:T.name}),u(" to confirm"),t.jsx("input",{value:L,placeholder:u(T.name),"aria-label":u("Confirm agent name"),onChange:le=>D(le.target.value)})]}),t.jsx("button",{className:"pro-danger",disabled:!Ww(L,T.name)||!!V,onClick:xe,children:t.jsxs(Xn,{busy:!!V,label:"Retiring",children:[t.jsx(sl,{size:16}),u("Archive agent")]})})]}),V&&t.jsx(Ma,{label:V,since:te,expect:15}),q&&t.jsx(Ot,{error:!0,children:u(q)})]})}),t.jsxs(on,{title:u("Archived agents"),description:"Their files and work are preserved. Restore an agent when you need it.",open:N,onClose:()=>I(!1),children:[V&&t.jsx(Ma,{label:V,since:te,expect:20}),l.archived.length?l.archived.map(le=>t.jsxs("div",{className:"pro-archive-row",children:[t.jsx(qt,{agent:le}),t.jsxs("div",{children:[t.jsx("strong",{children:le.name}),t.jsx("p",{children:u(le.role)})]}),t.jsxs("button",{className:"secondary-btn",disabled:!!V,onClick:()=>Ce(le),children:[t.jsx(ss,{size:16}),u("Restore")]})]},le.id)):t.jsxs("div",{className:"pro-empty",children:[t.jsx(sl,{size:34}),t.jsx("h3",{children:u("No agents archived.")}),t.jsx("p",{children:u("Retired agents will appear here, ready to restore.")})]})]})]})}const KY={rooms:{"agent-orchestrator":[],"agent-1":[],"agent-2":[],"agent-3":[]},busyUntil:0};function JY(a){const[e,n]=C.useState(!1),[s,o]=C.useState(""),l=C.useRef(null),d=C.useRef(a);d.current=a,C.useEffect(()=>()=>l.current?.stop(),[]);function h(){if(e){l.current?.stop();return}o("");const m=window,p=m.SpeechRecognition||m.webkitSpeechRecognition;if(!p){o("This browser cannot listen. Use Chrome, Edge or Safari, or type your message.");return}if(!window.isSecureContext){o("The microphone needs the dashboard’s https address.");return}const y=new p;y.lang=navigator.language||"en-US",y.interimResults=!1,y.continuous=!1,l.current=y,n(!0),y.onresult=v=>{const x=Array.from(v.results).map(S=>S[0].transcript).join(" ").trim();x&&d.current(x)},y.onerror=v=>{v.error==="not-allowed"||v.error==="service-not-allowed"?o("Allow the microphone for this site in your browser, then try again."):v.error!=="no-speech"&&v.error!=="aborted"&&o(`The microphone stopped: ${v.error}.`)},y.onend=()=>{l.current=null,n(!1)};try{y.start()}catch{l.current=null,n(!1),o("The microphone could not start. Try again.")}}return{listening:e,toggle:h,error:s,clearError:()=>o("")}}const kp=/]*href=["'](https?:\/\/[^"'\s]+)["'][^>]*>([^<]*)<\/a>|\[([^\]\n]{1,200})\]\((https?:\/\/[^)\s]+)\)|(https?:\/\/[^\s<>"'`]+)/gi,ZY=a=>a.replace(/[.,;:!?)\]]+$/,"");function HN(a){const e=[],n=String(a||"");let s=0,o;for(kp.lastIndex=0;o=kp.exec(n);){const l=o[1]||o[4]||ZY(o[5]),d=o[5]?o.index+l.length:kp.lastIndex;o.index>s&&e.push({text:n.slice(s,o.index)}),e.push({url:l,label:o[2]||o[3]||l}),s=d,kp.lastIndex=d}return s"url"in e?t.jsx("a",{className:"reply-link",href:e.url,target:"_blank",rel:"noopener noreferrer",children:e.label},n):t.jsx("span",{children:e.text},n))})}function _Y({text:a}){const e=[];for(const s of HN(a))"url"in s&&/\.(png|jpe?g|webp|gif)(\?\S*)?$/i.test(s.url)&&!e.includes(s.url)&&e.push(s.url);const n=e.filter(s=>!/_min\.webp(\?|$)/i.test(s)||e.length===1).slice(0,4);return n.length?t.jsx(t.Fragment,{children:n.map(s=>t.jsx("a",{className:"reply-image",href:s,target:"_blank",rel:"noopener noreferrer",children:t.jsx("img",{src:s,alt:"Image from the agent",loading:"lazy",onError:o=>{o.currentTarget.parentElement.style.display="none"}})},s))}):null}function $Y({agent:a,agents:e,lastReply:n,onTranscript:s,busy:o=!1}){const[l,d]=C.useState(null),[h,m]=C.useState(!1),[p,y]=C.useState(!1),[v,x]=C.useState("idle"),[S,M]=C.useState(""),[w,E]=C.useState(!1),[A,k]=C.useState([]),[R,N]=C.useState(""),[I,z]=C.useState(""),[j,L]=C.useState(!1),D=C.useRef(null),P=C.useRef(null),F=C.useRef(""),q=C.useRef(!1),J=C.useRef(!1),ie=C.useRef(o);ie.current=o;const Q=Fi(v==="waiting"||v==="preparing"),V=Fi(j),$={...l?.settings||{engine:"browser",speed:1,greeting:!1,voices:{}},state:j?"loading":l?.state||"loading"};async function te(){L(!0);try{d(await wt("/api/voice"))}catch(le){z(le.message)}L(!1)}C.useEffect(()=>{te();const le=()=>{"speechSynthesis"in window&&k(window.speechSynthesis.getVoices().filter(qe=>qe.localService))};return le(),window.speechSynthesis?.addEventListener("voiceschanged",le),()=>{window.speechSynthesis?.removeEventListener("voiceschanged",le),window.speechSynthesis?.cancel(),D.current?.pause(),P.current?.stop()}},[]);function ne(){window.speechSynthesis?.cancel(),D.current&&(D.current.pause(),D.current=null),P.current?.stop(),x("idle")}C.useEffect(()=>{q.current=!1,J.current=!1,ne(),y(!1),F.current="",a&&fetch("/api/voice/warm",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({agentId:a.id})}).catch(()=>{})},[a?.id]);function Y(){q.current&&!J.current&&setTimeout(()=>je(),300)}async function T(le,qe=a){if(ne(),!!qe){if(x("speaking"),$.engine==="browser"){const xt=A.find(Pe=>Pe.voiceURI===$.voices[qe.id])||A[0];if(!xt||!("speechSynthesis"in window)){x("idle"),z("This device has no installed voice, so replies are not read out. Choose Piper or ElevenLabs in Voice settings."),Y();return}const se=new SpeechSynthesisUtterance(le.replace(/[#*`]/g,""));se.voice=xt,se.rate=$.speed,se.onend=()=>{x("idle"),Y()},se.onerror=()=>{x("idle"),z("The browser voice could not start. Try another voice."),Y()},window.speechSynthesis.speak(se);return}x("preparing");try{const xt=await fetch("/api/voice/speak",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({text:le,agentId:qe.id})});if(!xt.ok)throw new Error((await xt.json().catch(()=>({}))).error||"The voice could not speak.");const se=URL.createObjectURL(await xt.blob()),Pe=new Audio(se);D.current=Pe,x("speaking"),Pe.onended=Pe.onpause=()=>{URL.revokeObjectURL(se),D.current===Pe&&(D.current=null,x("idle"),Y())},await Pe.play()}catch(xt){x("idle"),z(xt.message),Y()}}}C.useEffect(()=>{p&&n&&F.current!==n&&(F.current=n,T(n))},[n,p]);function _(){p?(q.current=!1,J.current=!1,ne(),y(!1)):(q.current=!0,J.current=!1,y(!0),z(""),F.current=n,$.greeting?T(`Hello. I’m your ${a?.name||"agent"}. What would you like to work on?`):je())}C.useEffect(()=>{q.current&&o&&v!=="speaking"&&x("waiting")},[o]);function ve(){if(q.current){J.current?(J.current=!1,je()):(J.current=!0,ne(),x("paused"));return}if(v==="listening"){ne();return}je()}function je(){if(q.current&&(J.current||ie.current))return;ne();const le=window.SpeechRecognition||window.webkitSpeechRecognition;if(!le){z("This browser cannot listen. Use Chrome or Edge, or type your message.");return}if(!window.isSecureContext){z("The microphone needs a secure address. Open the dashboard through its https link.");return}const qe=new le;qe.lang=navigator.language||"en-US",qe.interimResults=!1,qe.continuous=!1,P.current=qe,x("listening"),z("");let xt=!1;qe.onresult=Pe=>{const mt=Array.from(Pe.results).map(it=>it[0].transcript).join(" ").trim();mt&&(xt=!0,q.current?(x("waiting"),s(mt,!0)):s(mt))};let se=!1;qe.onerror=Pe=>{Pe.error==="not-allowed"?(se=!0,z("Allow the microphone for this site in your browser, then try again.")):Pe.error!=="no-speech"&&Pe.error!=="aborted"&&z(`The microphone stopped: ${Pe.error}.`)},qe.onend=()=>{if(P.current===qe&&(P.current=null),q.current&&!xt&&!se&&!J.current&&!ie.current){setTimeout(()=>{q.current&&!P.current&&je()},250);return}x(Pe=>Pe==="listening"?q.current?se?"paused":"waiting":"idle":Pe)},qe.start()}async function Je(le){L(!0);try{d(await wt("/api/voice/settings",le))}catch(qe){z(qe.message)}L(!1)}function xe(le){Je({engine:le})}async function ee(){E(!0);try{d(await wt("/api/voice/key",{key:R})),N(""),z("ElevenLabs key saved on the server.")}catch(le){z(le.message)}E(!1)}const Ce=l?.detail||"Checking the voice engine...",Ze=$.engine==="piper"?(l?.piper.voices||[]).map(le=>{const[qe,xt]=le.split("-"),se=(xt||le).split("_").map(Pe=>Pe[0]?.toUpperCase()+Pe.slice(1)).join(" ");return{id:le,name:`${se} · ${qe==="en_GB"?"British":qe==="en_US"?"American":qe}`}}):$.engine==="elevenlabs"?l?.elevenlabs.voices||[]:[];return t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:`pro-voice-bar ${p?"active":""}`,children:[t.jsxs("button",{className:p?"selected":"",onClick:_,disabled:!a,children:[t.jsx(nU,{size:17}),u(p?"Talk mode on":"Talk mode"),t.jsx("span",{className:"pro-voice-dot"})]}),t.jsxs("span",{children:[t.jsx(_t,{tone:$.state==="ready"?"green":$.state==="loading"?"neutral":"amber",children:u($.state)}),t.jsx("small",{children:u($.engine==="browser"?"Browser voice":$.engine==="piper"?"Piper · local voice":"ElevenLabs")})]}),t.jsx("button",{className:"icon-btn",title:u("Voice settings"),"aria-label":u("Voice settings"),onClick:()=>m(!0),children:t.jsx(rs,{size:17})})]}),p&&t.jsxs("div",{className:"pro-talk-dock",children:[t.jsxs("div",{children:[t.jsx(qt,{agent:a,small:!0}),t.jsxs("span",{children:[t.jsxs("strong",{children:[u(v==="preparing"?`${a.name} is getting ready to speak`:v==="speaking"?`${a.name} is speaking`:v==="listening"?"Listening… speak now":v==="waiting"?`${a.name} is thinking`:v==="paused"?"Paused":"Starting…"),(v==="waiting"||v==="preparing")&&t.jsx(vi,{since:Q})]}),t.jsx("small",{children:u(v==="preparing"?"Making the voice on your server. The first reply can take a few seconds.":v==="speaking"?"Interrupt anytime to take the floor.":v==="listening"?"Pause when you are done; it sends by itself.":v==="waiting"?"The answer will be read out, then it listens again.":v==="paused"?"Press Resume to keep talking.":"Allow the microphone if your browser asks.")})]})]}),t.jsx("div",{className:`pro-voice-wave ${v}`,"aria-hidden":"true",children:u(Array.from({length:24},(le,qe)=>t.jsx("i",{style:{height:`${8+Math.sin(qe*.6)**2*22}px`,animationDelay:`${qe*.04}s`}},qe)))}),t.jsxs("div",{className:"pro-actions",children:[t.jsxs("button",{className:"secondary-btn pro-mic-toggle",onClick:ve,children:[v==="paused"?t.jsx(_b,{size:16}):t.jsx(nu,{size:16}),u(v==="paused"?"Resume":"Pause")]}),t.jsxs("button",{className:"secondary-btn",disabled:v==="idle",onClick:ne,children:[t.jsx($b,{size:13}),u("Interrupt")]}),t.jsxs("button",{className:"secondary-btn",onClick:_,children:[t.jsx(WU,{size:16}),u("End talk")]})]}),I&&t.jsx("p",{className:"pro-small",children:u(I)})]}),t.jsxs(on,{title:u("Voice settings"),description:"A voice for every specialist. A pace that suits you.",open:h,onClose:()=>{m(!1),N("")},wide:!0,children:[t.jsxs("label",{children:[u("Voice engine"),t.jsxs("select",{"aria-label":u("Voice engine"),value:$.engine,onChange:le=>xe(le.target.value),children:[t.jsx("option",{value:"browser",children:u("Browser voice · installed on this device")}),t.jsx("option",{value:"piper",children:u("Piper · free local voice engine")}),t.jsx("option",{value:"elevenlabs",children:u("ElevenLabs · your API key")})]})]}),t.jsxs("div",{className:"pro-voice-state",children:[u($.state==="loading"?t.jsx(Jt,{size:21,className:"spinning"}):$.state==="ready"?t.jsx(Kt,{size:21}):t.jsx(hl,{size:21})),t.jsxs("div",{children:[t.jsx("strong",{children:u($.state==="ready"?"Ready":$.state==="loading"?"Loading":$.state==="not installed"?"Not installed":"Connection needed")}),$.state==="loading"?t.jsx(Ma,{className:"compact",label:"Checking the selected engine",since:V,expect:6}):t.jsx("p",{children:u(Ce)})]}),t.jsx("button",{className:"secondary-btn",onClick:te,children:u("Check again")})]}),$.engine==="elevenlabs"&&t.jsxs("label",{children:[u("ElevenLabs API key"),t.jsx("input",{type:"password",autoComplete:"off",value:R,placeholder:u("Enter your key"),onChange:le=>N(le.target.value)}),t.jsx("small",{className:"pro-small",children:u(l?.elevenlabs.keySet?"A key is saved on the server. Enter a new one to replace it, or save an empty field to remove it.":"Saved on your server only, never shown again.")}),t.jsx("button",{type:"button",className:"secondary-btn",disabled:w,onClick:ee,children:t.jsx(Xn,{busy:w,label:"Checking the key",children:u("Save key")})})]}),t.jsxs("label",{children:[u("Speaking speed "),t.jsxs("strong",{children:[u($.speed.toFixed(1)),u("×")]}),t.jsx("input",{type:"range",min:"0.6",max:"1.6",step:"0.1",value:$.speed,onChange:le=>Je({speed:Number(le.target.value)})}),t.jsxs("span",{className:"pro-range-labels",children:[t.jsx("span",{children:u("Slower")}),t.jsx("span",{children:u("Natural")}),t.jsx("span",{children:u("Faster")})]})]}),t.jsxs("label",{className:"pro-check-label",children:[t.jsx("input",{type:"checkbox",checked:$.greeting,onChange:le=>Je({greeting:le.target.checked})}),t.jsxs("span",{children:[t.jsx("strong",{children:u("A spoken greeting")}),t.jsx("small",{children:u("Say hello when talk mode begins.")})]})]}),t.jsx("h3",{className:"pro-subtitle",children:u("A voice for each agent")}),t.jsx("div",{className:"pro-agent-voices",children:e.map((le,qe)=>t.jsxs("label",{children:[t.jsx(qt,{agent:le,small:!0}),t.jsx("span",{children:le.name}),t.jsxs("select",{"aria-label":u(`${le.name} voice`),value:$.voices[le.id]||"",onChange:xt=>Je({voices:{...$.voices,[le.id]:xt.target.value}}),children:[t.jsx("option",{value:"",children:u($.engine==="browser"?"Default local voice":"Default voice")}),$.engine==="browser"?A.map(xt=>t.jsxs("option",{value:xt.voiceURI,children:[xt.name,u(" · "),u(xt.lang)]},xt.voiceURI)):Ze.map(xt=>t.jsx("option",{value:xt.id,children:xt.name},xt.id))]}),t.jsx("button",{type:"button",className:"icon-btn","aria-label":u(`Preview ${le.name} voice`),disabled:S===le.id&&v==="preparing",onClick:()=>{M(le.id),T(`Hello, I’m ${le.name}. Let’s make the next step clear.`,le)},children:S===le.id&&v==="preparing"?t.jsx(Jt,{size:15,className:"spin"}):t.jsx(gi,{size:15})})]},le.id))}),t.jsx(Ot,{children:u("Listening uses your browser's speech recognition (Chrome or Edge) and needs the dashboard's https address. Piper and ElevenLabs voices are made on your server.")})]})]})}function nT({file:a,onOpen:e,onRemove:n}){return t.jsxs("div",{className:"attachment-chip",children:[t.jsxs("button",{type:"button",onClick:e,"aria-label":u(`Preview ${a.name}`),children:[u(a.kind==="image"?t.jsx(hj,{size:17}):a.kind==="spreadsheet"?t.jsx(v2,{size:17}):t.jsx(Si,{size:17})),t.jsxs("span",{children:[t.jsx("strong",{children:a.name}),t.jsxs("small",{children:[u(oS(a.size)),u(" · "),u(a.persistent?"Local file":"Session file")]})]})]}),n&&t.jsx("button",{type:"button",className:"attachment-remove",onClick:n,"aria-label":u(`Remove ${a.name}`),children:t.jsx(da,{size:14})})]})}function eX({file:a,onClose:e}){const[n,s]=C.useState(""),[o,l]=C.useState(""),[d,h]=C.useState(!1),[m,p]=C.useState(!1);return C.useEffect(()=>{let y=!0,v="";if(s(""),l(""),p(!1),!!a)return h(!0),ON(a.id).then(async x=>{if(y){if(!x){p(!0),h(!1);return}if(v=URL.createObjectURL(x),s(v),a.kind==="text"){const S=await x.slice(0,1e5).text();y&&l(S)}y&&h(!1)}}).catch(()=>{y&&(p(!0),h(!1))}),()=>{y=!1,v&&URL.revokeObjectURL(v)}},[a?.id]),t.jsx(on,{title:u(a?.name||"Attachment preview"),description:"A local preview of the file attached to your conversation.",open:!!a,onClose:e,wide:!0,children:a&&t.jsxs("div",{className:"attachment-preview",children:[d?t.jsxs("div",{className:"attachment-preview-empty",children:[t.jsx(Jt,{size:30,className:"spinning"}),t.jsx("p",{children:u("Opening attachment…")})]}):m?t.jsx(Ot,{error:!0,children:u("This file is no longer available in this browser. Attach it again to preview it.")}):a.kind==="image"?t.jsx("img",{src:n,alt:u(a.name)}):a.kind==="text"?t.jsxs(t.Fragment,{children:[t.jsx("pre",{children:o}),a.size>1e5&&t.jsx("p",{className:"pro-small",children:u("Preview shows the first 100 KB. Download the file to read everything.")})]}):t.jsxs("div",{className:"attachment-preview-empty",children:[u(a.kind==="spreadsheet"?t.jsx(v2,{size:43}):t.jsx(Si,{size:43})),t.jsx("h3",{children:a.name}),t.jsx("p",{children:u(a.kind==="spreadsheet"?"Spreadsheet attached. Download to open in your preferred editor.":"Document attached. Download to open in your preferred viewer.")}),t.jsx("small",{children:u(oS(a.size))})]}),t.jsxs("footer",{children:[t.jsxs("span",{children:[t.jsx(fo,{size:14}),u("Local attachment · not sent to an AI service")]}),n&&t.jsxs("a",{className:"primary-btn",href:n,download:a.name,children:[t.jsx(Eo,{size:16}),u("Download file")]})]})]})})}function tX(){C.useEffect(()=>{const a=window.visualViewport;if(!a)return;const e=document.documentElement,n=()=>{if(innerWidth>700){e.style.removeProperty("--chat-vh"),e.classList.remove("kb-open");return}e.style.setProperty("--chat-vh",`${Math.round(a.height)}px`),e.classList.toggle("kb-open",a.heightsetTimeout(()=>{n(),window.scrollTo(0,0)},120);return n(),a.addEventListener("resize",n),a.addEventListener("scroll",n),document.addEventListener("focusout",s),()=>{a.removeEventListener("resize",n),a.removeEventListener("scroll",n),document.removeEventListener("focusout",s),e.style.removeProperty("--chat-vh"),e.classList.remove("kb-open")}},[])}const aT=a=>a==="whatsapp"?"WhatsApp":a==="sms"?"SMS":a.charAt(0).toUpperCase()+a.slice(1);function nX({agents:a,initialRoom:e="agent-orchestrator",onModels:n}){tX();const[s,o]=C.useState(e==="team"?"agent-orchestrator":e),[l,d]=C.useState(!1),[h,m]=C.useState({}),[p,y]=C.useState(KY),[v,x]=C.useState(0),[S,M]=C.useState(!1),[w,E]=C.useState(""),[A,k]=C.useState(!1),[R,N]=C.useState(!1),[I,z]=C.useState({}),[j,L]=C.useState({}),[D,P]=C.useState(""),[F,q]=C.useState({}),[J,ie]=C.useState(""),Q=Bi(),V=mu();Au();const[$,te]=C.useState(()=>{try{return JSON.parse(sessionStorage.getItem("laboratorio-chat-attachment-drafts")||"{}")}catch{return{}}}),[ne,Y]=C.useState(!1),[T,_]=C.useState(null),[ve,je]=C.useState(!1),Je=C.useRef(null),xe=C.useRef($),ee=C.useRef(!1);xe.current=$;const Ce=$[s]||[];C.useEffect(()=>{try{sessionStorage.setItem("laboratorio-chat-attachment-drafts",JSON.stringify($))}catch{}},[$]);async function Ze(fe){if(ee.current)return;ee.current=!0,Y(!0),P("");const oe=s,Fe=[...xe.current[oe]||[]];try{for(const Xe of Array.from(fe)){const dt=LN(Xe,Fe);if(dt){P(dt);continue}Fe.push(await wY(Xe))}te(Xe=>({...Xe,[oe]:Fe}))}finally{Y(!1),ee.current=!1,Je.current&&(Je.current.value="")}}function le(fe){te(oe=>({...oe,[s]:(oe[s]||[]).filter(Fe=>Fe.id!==fe.id)})),CY(fe.id)}C.useEffect(()=>{o(a.some(fe=>fe.id===e)?e:a[0]?.id||"")},[e,a.map(fe=>fe.id).join("|")]);const qe=C.useRef(null),xt=C.useRef(null),se=C.useRef(null),Pe=a.find(fe=>fe.id===s),mt=p.rooms[s]||[],it=F[s]||"",at=R||!!I[s],Be=Fi(at),We=JY(fe=>{q(oe=>({...oe,[s]:oe[s]?`${oe[s].replace(/\s+$/,"")} ${fe}`:fe})),xt.current?.focus()}),ue=C.useRef(new Set),ft=C.useRef(F);ft.current=F,C.useEffect(()=>{const fe=FN(s);fe&&q(oe=>oe[s]?oe:{...oe,[s]:fe})},[s]),C.useEffect(()=>()=>{const fe=new Set([...ue.current,...Object.keys(ft.current).filter(oe=>ft.current[oe]?.trim())]);for(const oe of fe)oe!=="team"&&(jY(oe),lS(oe,ft.current[oe]||""))},[]);function Re(fe){y(fe.data),x(fe.version),M(fe.connected),E(fe.model),z(fe.pending||{}),L(fe.failed||{}),d(!!fe.routing),m(fe.routes||{})}async function K(){try{const fe=await na("/api/chat/route",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({room:s})}),oe=await fe.json();if(!fe.ok)throw new Error(oe.error||"Could not change the model.");Re(oe)}catch(fe){P(fe.message)}}async function B(){P("");try{const fe=await na("/api/chat",{cache:"no-store"}),oe=await fe.json();if(!fe.ok)throw new Error(oe.error||"Conversation unavailable.");Re(oe),k(!0)}catch(fe){P(fe.message)}}C.useEffect(()=>{if(Object.keys(I).length)return;const fe=setInterval(async()=>{if(!document.hidden)try{const oe=await na("/api/chat",{cache:"no-store"});oe.ok&&Re(await oe.json())}catch{}},15e3);return()=>clearInterval(fe)},[I]),C.useEffect(()=>{if(!Object.keys(I).length)return;const fe=setInterval(async()=>{try{const oe=await na("/api/chat",{cache:"no-store"});oe.ok&&Re(await oe.json())}catch{}},1500);return()=>clearInterval(fe)},[I]),C.useEffect(()=>{B();try{q(JSON.parse(sessionStorage.getItem("laboratorio-chat-drafts")||"{}"))}catch{}},[]),C.useEffect(()=>{try{sessionStorage.setItem("laboratorio-chat-drafts",JSON.stringify(F))}catch{}},[F]),C.useEffect(()=>{se.current?.scrollIntoView({block:"nearest",inline:"center",behavior:"smooth"})},[s]),C.useEffect(()=>{(mt.length||at)&&qe.current?.scrollIntoView({block:"nearest",behavior:"smooth"})},[mt.length,at,s]);async function pe(fe){const oe=(fe??it).trim()||(Ce.length?"Please review the attached files.":"");if(!oe||at||ne||!A||!S)return;ue.current.add(s);const Fe=[...Ce];N(!0),P("");const Xe=s;y(dt=>({...dt,rooms:{...dt.rooms,[Xe]:[...dt.rooms[Xe]||[],{id:"pending-"+Date.now(),role:"user",text:oe,attachments:Fe,time:new Date().toISOString()}]}})),q(dt=>({...dt,[Xe]:""}));try{for(const U of Fe){const ce=await ON(U.id);if(!ce)throw new Error(`${U.name} is no longer available. Attach it again.`);const G=await na(`/api/chat/upload?id=${encodeURIComponent(U.id)}&name=${encodeURIComponent(U.name)}`,{method:"POST",body:ce});if(!G.ok)throw new Error((await G.json().catch(()=>({}))).error||`${U.name} could not be uploaded.`)}const dt=await na("/api/chat",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({room:Xe,text:oe,attachments:Fe,version:v})}),W=await dt.json();if(!dt.ok)throw new Error(W.error||"Conversation unavailable.");Re(W),te(U=>({...U,[Xe]:[]}))}catch(dt){P(dt.message),q(W=>({...W,[Xe]:W[Xe]||oe}));try{const W=await na("/api/chat");W.ok&&Re(await W.json())}catch{}}finally{N(!1)}}const[Ae,Ne]=C.useState(null),[be,ot]=C.useState([]),[Ve,ut]=C.useState(null),re=C.useRef(""),Se=Ae&&Ae.room===s?Ae:null;async function He(){const fe=it.trim();if(!V.polish||!fe||fe===re.current||Ve||at||ne||!A||!S)return pe();ut(Date.now()),P(""),Ne(null);const oe=s;try{const Fe=await na("/api/chat/polish",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({text:fe,agentName:Pe?.name})}),Xe=await Fe.json();if(!Fe.ok)throw new Error(Xe.error||"Polishing is unavailable. Send your message as it is.");if(Xe.skipped)return re.current=fe,ut(null),pe();ot([]),Ne({room:oe,original:fe,prompt:Xe.prompt||fe,missing:Xe.missing||[],model:Xe.model})}catch(Fe){P(Fe.message),re.current=fe}finally{ut(null)}}function lt(fe){const oe=(Se?.missing||[]).map((Fe,Xe)=>be[Xe]?.trim()?`- ${Fe} ${be[Xe].trim()}`:"").filter(Boolean);return oe.length?`${fe.trimEnd()} ${u("More details:")} ${oe.join(` `)}`:fe}function tt(fe){const oe=lt(fe);Ne(null),ot([]),re.current="",pe(oe)}function ct(){if(!Se)return;const fe=lt(Se.prompt);re.current=fe.trim(),q(oe=>({...oe,[s]:fe})),Ne(null),ot([]),setTimeout(()=>xt.current?.focus(),0)}return t.jsxs("section",{className:"chat-layout panel",children:[t.jsxs("aside",{className:"conversation-rail",children:[t.jsxs("div",{className:"conversation-title",children:[t.jsx("span",{children:u("CONVERSATIONS")}),t.jsx(yi,{size:16})]}),t.jsxs("p",{className:"conversation-label",children:[u("YOUR SPECIALISTS "),t.jsx("span",{children:u(a.length)})]}),a.map(fe=>t.jsxs("button",{ref:s===fe.id?se:void 0,className:`room-button ${s===fe.id?"selected":""}`,onClick:()=>o(fe.id),disabled:R,children:[t.jsx(qt,{agent:fe,working:!!I[fe.id]||fe.status==="Working"}),t.jsxs("span",{children:[t.jsx("strong",{children:fe.name}),t.jsx("small",{className:I[fe.id]||fe.status==="Working"?"room-working":void 0,children:I[fe.id]||fe.status==="Working"?u("Working…"):u(hk[fe.id]?.specialty||Q.identities[fe.id]?.role||fe.role)})]}),u(s===fe.id&&t.jsx("span",{className:"room-indicator"}))]},fe.id)),t.jsxs("div",{className:"conversation-rail-footer",children:[t.jsx("div",{className:"mini-avatar-stack",children:u(a.map(fe=>t.jsx(qt,{agent:fe,small:!0},fe.id)))}),t.jsx("strong",{children:u("A little expertise goes a long way.")}),t.jsx("p",{children:u("Pick a specialist to talk to.")})]})]}),t.jsxs("div",{className:`conversation-main ${ve?"attachment-dragging":""}`,onDragOver:fe=>{fe.dataTransfer.types.includes("Files")&&(fe.preventDefault(),je(!0))},onDragLeave:fe=>{fe.currentTarget.contains(fe.relatedTarget)||je(!1)},onDrop:fe=>{fe.preventDefault(),je(!1),at||Ze(fe.dataTransfer.files)},children:[ve&&t.jsxs("div",{className:"attachment-drop-overlay",children:[t.jsx(F2,{size:35}),t.jsx("strong",{children:u("Drop files into this conversation")}),t.jsx("span",{children:u("Images, PDFs, documents, and spreadsheets")})]}),t.jsxs("header",{className:"conversation-header",children:[t.jsxs("div",{children:[u(Pe?t.jsx(qt,{agent:Pe}):t.jsx("span",{className:"team-room-icon",children:t.jsx(hh,{size:22})})),t.jsxs("span",{children:[t.jsx("h2",{children:u(Pe?.name||"Your agents")}),t.jsx("p",{children:u(Pe?.role||"Waiting for the Laboratorio server")})]})]}),t.jsxs("button",{className:"chat-model-control",onClick:()=>Pe&&n(Pe.id),disabled:!Pe,children:[t.jsx(dh,{size:15}),Pe?.model,t.jsx("span",{children:u(Pe&&hu(Pe.id,Pe.model).fallbackEnabled?"Fallback on":"Fallback off")})]}),t.jsxs("span",{className:`connection-label ${S?"connected":""}`,children:[t.jsx("i",{}),u(S?Pe?.model||"Connected":"Connecting…")]})]}),t.jsx($Y,{agent:Pe,agents:a,lastReply:mt.filter(fe=>fe.role==="assistant").at(-1)?.text||"",busy:at,onTranscript:(fe,oe)=>oe?pe(fe):q(Fe=>({...Fe,[s]:fe}))}),t.jsxs("div",{className:"conversation-messages",role:"log","aria-label":u(`${Pe?.name||"Agent"} conversation`),"aria-live":"polite",children:[A?mt.length?mt.map(fe=>{const oe=a.find(Fe=>Fe.id===fe.agentId);return t.jsxs("article",{className:`chat-message ${fe.role}`,children:[oe&&t.jsx(qt,{agent:oe,small:!0}),t.jsxs("div",{children:[t.jsxs("div",{className:"message-meta",children:[t.jsx("strong",{children:u(oe?.name||"You")}),t.jsx("time",{dateTime:fe.time,children:new Date(fe.time).toLocaleTimeString(Hn(),Kd({hour:"2-digit",minute:"2-digit"}))}),fe.channel&&t.jsx("span",{className:"chat-channel",title:u(`Said in ${aT(fe.channel)}`),children:aT(fe.channel)}),fe.route?t.jsxs("span",{className:`jev-route ${fe.route.tier}`,title:u(fe.route.by==="escalated"?"Jev moved this chat to the strong model when it got harder.":fe.route.by==="you"?"You chose the strong model for this chat.":"Jev chose this model for the chat and keeps it while you talk."),children:[u("Jev")," · ",u(fe.route.tier==="light"?"light":"strong")," · ",fe.route.name]}):u(fe.model&&t.jsx("span",{children:fe.model}))]}),t.jsx("div",{className:"message-bubble",children:fe.role==="assistant"?t.jsx(QY,{text:fe.text}):fe.text}),fe.role==="assistant"&&t.jsx(_Y,{text:fe.text}),l&&fe.route?.tier==="light"&&h[s]?.tier!=="strong"&&fe.id===mt.filter(Fe=>Fe.role==="assistant").at(-1)?.id&&t.jsx("button",{type:"button",className:"jev-upgrade",onClick:K,children:u("Use the strong model")}),!!fe.attachments?.length&&t.jsx("div",{className:"message-attachments",children:u(fe.attachments.map(Fe=>t.jsx(nT,{file:Fe,onOpen:()=>_(Fe)},Fe.id)))})]})]},fe.id)}):t.jsxs("div",{className:"chat-welcome",children:[t.jsx("div",{className:"welcome-portraits",children:u((Pe?[Pe]:a).map(fe=>t.jsx(qt,{agent:fe},fe.id)))}),t.jsx("span",{className:"welcome-kicker",children:u("A GOOD IDEA STARTS WITH A CONVERSATION")}),t.jsx("h3",{children:u(Pe?`Work through it with your ${Pe.name.toLowerCase()}.`:`${a.length} perspectives. One clear direction.`)}),t.jsx("p",{children:u(Pe?"Bring a question, a rough draft, or your next big challenge.":"Bring your team a brief. Each agent contributes their own expertise.")})]}):t.jsxs("div",{className:"chat-welcome",children:[t.jsx(Jt,{className:"spinning",size:24}),t.jsx("p",{children:u("Loading conversations…")})]}),at&&t.jsxs("div",{className:"chat-thinking",children:[t.jsx(Jt,{size:17,className:"spinning"}),u(`${Pe?.name} is thinking…`),t.jsx(vi,{since:I[s]?I[s]*1e3:Be})]}),t.jsx("div",{ref:qe})]}),t.jsxs("div",{className:"composer-wrap",children:[We.error&&t.jsxs("div",{role:"alert",className:"chat-error",children:[u(We.error),t.jsx("button",{onClick:We.clearError,children:u("OK")})]}),(D||!at&&j[s]?.error)&&t.jsxs("div",{role:"alert",className:"chat-error",children:[u(D||`${Pe?.name||"The agent"} could not answer: ${j[s].error}`),t.jsx("button",{onClick:B,children:u("Reload")})]}),Ve&&!Se&&t.jsx(Ma,{className:"polish-wait",label:"Polishing your message",since:Ve,expect:12}),Se&&t.jsxs("div",{className:"polish-card",role:"region","aria-label":u("Polished message"),children:[t.jsxs("div",{className:"polish-head",children:[t.jsx(ow,{size:15}),t.jsx("strong",{children:u("Polished")}),Se.model&&t.jsx("span",{children:Se.model}),t.jsx("button",{type:"button",onClick:()=>Ne(null),"aria-label":u("Close and keep my message"),title:u("Close and keep my message"),children:t.jsx(da,{size:15})})]}),t.jsx("p",{className:"polish-text",children:Se.prompt}),!!Se.missing.length&&t.jsxs("div",{className:"polish-missing",children:[t.jsx("span",{children:u(`${Pe?.name||"Your agent"} may also need to know`)}),t.jsx("small",{children:u("Answer any you like. Your answers are added to the message; empty ones are skipped.")}),t.jsx("div",{className:"polish-qs",children:Se.missing.map((fe,oe)=>t.jsxs("label",{className:"polish-q",children:[t.jsx("span",{children:fe}),t.jsx("input",{id:`polish-answer-${oe}`,value:be[oe]||"",maxLength:300,placeholder:u("Your answer (optional)"),"aria-label":fe,onChange:Fe=>ot(Xe=>{const dt=[...Xe];return dt[oe]=Fe.target.value,dt}),onKeyDown:Fe=>{Fe.key==="Enter"&&(Fe.preventDefault(),(document.getElementById(`polish-answer-${oe+1}`)||document.getElementById("polish-send"))?.focus())}})]},fe))})]}),t.jsxs("div",{className:"polish-actions",children:[t.jsxs("button",{type:"button",id:"polish-send",className:"primary-btn",disabled:at,onClick:()=>tt(Se.prompt),children:[t.jsx(em,{size:15}),u("Send polished")]}),t.jsx("button",{type:"button",className:"secondary-btn",onClick:ct,children:u("Edit")}),t.jsx("button",{type:"button",className:"text-btn",disabled:at,onClick:()=>tt(Se.original),children:u("Send my original")})]})]}),t.jsxs("form",{className:"chat-composer",onSubmit:fe=>{fe.preventDefault(),He()},onPointerDown:fe=>{fe.target.closest("button")&&fe.preventDefault()},children:[t.jsx("input",{type:"file",multiple:!0,accept:zN,ref:Je,onChange:fe=>{fe.target.files&&Ze(fe.target.files)},className:"attachment-file-input","aria-label":u("Choose chat attachments")}),!!Ce.length&&t.jsx("div",{className:"composer-attachments",children:u(Ce.map(fe=>t.jsx(nT,{file:fe,onOpen:()=>_(fe),onRemove:()=>le(fe)},fe.id)))}),t.jsx("textarea",{ref:xt,"aria-label":u("Message agents"),placeholder:u(Pe?`Message ${Pe.name}…`:"What would you like to work on with your team?"),value:it,maxLength:8e3,rows:2,onChange:fe=>q(oe=>({...oe,[s]:fe.target.value})),onKeyDown:fe=>{fe.key==="Enter"&&!fe.shiftKey&&(V.sendKey==="enter"||fe.metaKey||fe.ctrlKey)&&(fe.preventDefault(),He())}}),t.jsxs("div",{className:"composer-bottom",children:[t.jsxs("div",{className:"composer-tools",children:[t.jsx("button",{type:"button",className:"attach-files-button","aria-label":u("Attach files"),title:u("Attach files"),disabled:at||ne,onClick:()=>Je.current?.click(),children:u(ne?t.jsx(Jt,{size:17,className:"spinning"}):t.jsx(fo,{size:18}))}),t.jsx("button",{type:"button",className:`attach-files-button dictate-button ${We.listening?"listening":""}`,"aria-pressed":We.listening,"aria-label":u(We.listening?"Stop listening":"Talk instead of typing"),title:u(We.listening?"Listening… tap to stop":"Talk instead of typing"),onClick:We.toggle,children:We.listening?t.jsx(kU,{size:18}):t.jsx(_b,{size:18})}),t.jsxs("span",{children:[t.jsx(Ha,{size:14}),Pe?.name]})]}),t.jsxs("div",{className:"composer-send",children:[t.jsxs("button",{type:"button",className:`polish-toggle ${V.polish?"on":""}`,"aria-pressed":V.polish,onClick:()=>$p({polish:!V.polish}),title:u(V.polish?"Polish is on: you see a clearer version of your message before it is sent":"Polish: rewrite your message into a clear prompt before it is sent"),children:[t.jsx(ow,{size:14}),u("Polish"),t.jsx("i",{})]}),t.jsx("button",{className:"send-message",type:"submit",disabled:!S||!A||at||ne||!!Ve||!it.trim()&&!Ce.length,"aria-label":u("Send message"),title:u("Send message"),children:u(at?t.jsx(Jt,{size:19,className:"spinning"}):t.jsx(em,{size:21}))})]})]})]}),t.jsxs("div",{className:"composer-foot",children:[t.jsx("span",{children:u(S?V.polish?"Polish is on: you see a clearer version before it is sent":"Replies come from your Hermes agents":"Loading preview...")}),t.jsx("span",{children:u(V.sendKey==="enter"?"Enter to send · Shift + Enter for a new line":"Ctrl / ⌘ + Enter to send")})]})]}),t.jsx(eX,{file:T,onClose:()=>_(null)})]})]})}const Hc={focus:1500,short:300,long:900},aX={notes:[],timer:{mode:"focus",remaining:Hc.focus,endsAt:null,completed:0,taskId:""}};function iT(a,e=Date.now()){return a.endsAt!==null&&a.endsAt<=e?{...a,endsAt:null,remaining:0,completed:a.completed+(a.mode==="focus"?1:0)}:a}function iX({tasks:a,agents:e}){const[n,s]=C.useState(aX),[o,l]=C.useState(!1),[d,h]=C.useState(!1),[m,p]=C.useState(""),[y,v]=C.useState(Date.now()),[x,S]=C.useState(!1),[M,w]=C.useState(null),E=C.useRef(n),A=C.useRef(0),k=C.useRef(!1),R=C.useRef(!1),N=C.useRef(!1),I=C.useRef(!1),z=ne=>{E.current=ne,R.current=!0,S(!0),s(ne)};async function j(){if(!(R.current&&!window.confirm("Reloading will discard unsaved edits. Continue?"))){p("");try{const ne=await na("/api/productivity",{cache:"no-store"}),Y=await ne.json();if(!ne.ok)throw new Error(Y.error||"Focus space unavailable.");E.current=Y.data,A.current=Y.version,R.current=!1,I.current=!1,S(!1),s(Y.data),l(!0),N.current=!0;const T=iT(Y.data.timer);T!==Y.data.timer&&z({...Y.data,timer:T})}catch(ne){p(ne.message)}}}async function L(ne=!1){if(!N.current||k.current||!R.current||I.current&&!ne)return;I.current=!1,k.current=!0,h(!0),p("");const Y=E.current;try{const T=await na("/api/productivity",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({data:Y,version:A.current})}),_=await T.json();if(!T.ok)throw new Error(_.error||"Focus space unavailable.");A.current=_.version,E.current===Y&&(R.current=!1,S(!1))}catch(T){I.current=!0,p(T.message)}finally{k.current=!1,h(!1)}}C.useEffect(()=>{j();const ne=setInterval(()=>v(Date.now()),1e3),Y=setInterval(()=>{R.current&&L()},900),T=_=>{R.current&&(_.preventDefault(),_.returnValue="")};return window.addEventListener("beforeunload",T),()=>{clearInterval(ne),clearInterval(Y),window.removeEventListener("beforeunload",T),R.current&&N.current&&!k.current&&na("/api/productivity",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({data:E.current,version:A.current}),keepalive:!0}).catch(()=>{})}},[]),C.useEffect(()=>{const ne=iT(E.current.timer,y);ne!==E.current.timer&&z({...E.current,timer:ne})},[y]);const D=n.timer,P=D.endsAt?Math.min(Hc[D.mode],Math.max(0,Math.ceil((D.endsAt-y)/1e3))):D.remaining,F=String(Math.floor(P/60)).padStart(2,"0"),q=String(P%60).padStart(2,"0"),J=a.find(ne=>ne.id===D.taskId),ie=a.filter(ne=>ne.status!=="Done");function Q(ne){z({...E.current,timer:{...E.current.timer,...ne}})}function V(){if(D.endsAt)Q({endsAt:null,remaining:P});else{const ne=P||Hc[D.mode];Q({remaining:ne,endsAt:Date.now()+ne*1e3})}}function $(){if(n.notes.length>=30)return;const ne={id:crypto.randomUUID(),text:"",color:["lime","teal","sand"][n.notes.length%3],updated:new Date().toISOString()};z({...E.current,notes:[ne,...E.current.notes]})}function te(ne,Y){z({...E.current,notes:E.current.notes.map(T=>T.id===ne?{...T,...Y,updated:new Date().toISOString()}:T)})}return t.jsxs("div",{className:"productivity-layout",children:[t.jsxs("section",{className:"focus-panel",children:[t.jsxs("div",{className:"focus-top",children:[t.jsxs("span",{children:[t.jsx(ew,{size:18}),u("FOCUS SESSION")]}),t.jsx("span",{className:"focus-tag",children:u("One thing at a time")})]}),t.jsx("div",{className:"focus-modes",role:"group","aria-label":u("Timer mode"),children:[["focus","Pomodoro"],["short","Short break"],["long","Long break"]].map(([ne,Y])=>t.jsx("button",{disabled:!o||d,className:D.mode===ne?"selected":"","aria-pressed":D.mode===ne,onClick:()=>Q({mode:ne,remaining:Hc[ne],endsAt:null}),children:u(Y)},ne))}),t.jsxs("div",{className:"focus-clock",children:[t.jsxs("svg",{viewBox:"0 0 280 280","aria-hidden":"true",children:[t.jsx("circle",{cx:"140",cy:"140",r:"127",className:"clock-track"}),t.jsx("circle",{cx:"140",cy:"140",r:"127",className:"clock-progress",strokeDasharray:"797.96",strokeDashoffset:797.96*(1-P/Hc[D.mode])})]}),t.jsxs("div",{children:[t.jsx("span",{children:u(D.mode==="focus"?"TIME TO FOCUS":"TIME TO RECHARGE")}),t.jsxs("strong",{role:"timer","aria-label":u(`${F} minutes ${q} seconds remaining`),children:[u(F),t.jsx("i",{children:u(":")}),u(q)]}),t.jsx("p",{children:u(D.endsAt?"In the flow. Keep going.":P===0?"Session complete. Take a breath.":"A fresh start for your next idea.")})]})]}),t.jsxs("div",{className:"focus-controls",children:[t.jsxs("button",{className:"focus-start",disabled:!o||d,onClick:V,children:[u(D.endsAt?t.jsx(nu,{size:19}):t.jsx(gi,{size:19}))," ",u(D.endsAt?"Pause session":P===0?"Start again":"Start session")]}),t.jsx("button",{className:"focus-reset",disabled:!o||d,onClick:()=>Q({remaining:Hc[D.mode],endsAt:null}),"aria-label":u("Reset timer"),children:t.jsx(ss,{size:20})})]}),t.jsxs("div",{className:"focus-task",children:[t.jsx("label",{htmlFor:"focus-task",children:u("FOCUS ON")}),t.jsxs("select",{id:"focus-task","aria-label":u("Focus task"),value:D.taskId,disabled:!o,onChange:ne=>Q({taskId:ne.target.value}),children:[t.jsx("option",{value:"",children:u("Choose a task or work freely")}),u(ie.map(ne=>t.jsx("option",{value:ne.id,children:ne.title},ne.id))),J?.status==="Done"&&t.jsxs("option",{value:J.id,children:[J.title,u(" · Done")]})]})]}),t.jsxs("div",{className:"focus-summary",children:[t.jsxs("span",{children:[t.jsx($a,{size:17}),t.jsx("strong",{children:u(D.completed)}),u(" focus sessions")]}),t.jsxs("span",{children:[t.jsx(ts,{size:16}),u(D.completed*25),u(" minutes completed")]})]})]}),t.jsxs("div",{className:"focus-side",children:[t.jsxs("section",{className:"panel sticky-section",children:[t.jsxs("div",{className:"panel-title",children:[t.jsxs("div",{children:[t.jsx("span",{className:"panel-kicker",children:u("CAPTURE THE THOUGHT")}),t.jsxs("h2",{children:[u("Sticky notes "),t.jsx("span",{className:"note-count",children:u(n.notes.length)})]}),t.jsx("p",{children:u("Ideas, reminders, and everything in between.")})]}),t.jsxs("button",{className:"primary-btn",onClick:$,disabled:!o||n.notes.length>=30,children:[t.jsx(jn,{size:17}),u("Add note")]})]}),t.jsxs("div",{className:"notes-grid",children:[n.notes.map((ne,Y)=>t.jsxs("article",{className:`sticky-note note-${ne.color}`,children:[t.jsxs("header",{children:[t.jsx(aw,{size:17}),t.jsxs("span",{children:[u("NOTE "),u(String(Y+1).padStart(2,"0"))]}),t.jsx("button",{className:"icon-btn","aria-label":u(`Delete note ${Y+1}`),onClick:()=>{w(ne),z({...E.current,notes:E.current.notes.filter(T=>T.id!==ne.id)})},children:t.jsx(ti,{size:16})})]}),t.jsx("textarea",{"aria-label":u(`Note ${Y+1}`),placeholder:u("Put that thought somewhere…"),value:ne.text,maxLength:3e3,onChange:T=>te(ne.id,{text:T.target.value})}),t.jsxs("footer",{children:[t.jsxs("span",{children:[u(ne.text.length),u(" / 3000")]}),t.jsx("div",{role:"group","aria-label":u(`Color for note ${Y+1}`),children:["lime","teal","sand"].map(T=>t.jsx("button",{className:`note-swatch ${T} ${T===ne.color?"selected":""}`,"aria-label":u(`${T} note color`),"aria-pressed":T===ne.color,onClick:()=>te(ne.id,{color:T})},T))})]})]},ne.id)),!n.notes.length&&t.jsxs("button",{className:"notes-empty",disabled:!o,onClick:$,children:[t.jsx("span",{children:t.jsx(aw,{size:29})}),t.jsx("strong",{children:u("A little space for what’s on your mind.")}),t.jsx("p",{children:u("Save your first idea, reminder, or next step.")}),t.jsxs("em",{children:[t.jsx(jn,{size:16}),u("Create a note")]})]})]}),M&&t.jsxs("div",{className:"note-undo",role:"status",children:[u("Note removed."),t.jsx("button",{onClick:()=>{z({...E.current,notes:[M,...E.current.notes]}),w(null)},children:u("Undo")})]}),t.jsx("div",{className:"productivity-save",role:"status",children:d?t.jsxs(t.Fragment,{children:[t.jsx(Jt,{size:14,className:"spinning"}),u("Saving changes…")]}):x?"Unsaved changes":o?t.jsxs(t.Fragment,{children:[t.jsx($a,{size:14}),u("Saved on this device")]}):"Loading your focus space…"}),m&&t.jsxs("div",{className:"chat-error",role:"alert",children:[u(m),t.jsx("button",{onClick:()=>L(!0),children:u("Retry save")}),t.jsx("button",{onClick:j,children:u("Reload")})]})]}),t.jsxs("section",{className:"panel next-up",children:[t.jsxs("div",{className:"panel-title",children:[t.jsxs("div",{children:[t.jsx("span",{className:"panel-kicker",children:u("MAKE THE NEXT STEP CLEAR")}),t.jsx("h2",{children:u("Up next")})]}),t.jsxs("span",{className:"muted",children:[u(ie.length),u(" open tasks")]})]}),ie.slice().sort((ne,Y)=>+(Y.priority==="High")-+(ne.priority==="High")).slice(0,3).map(ne=>t.jsxs("button",{className:`next-task ${D.taskId===ne.id?"selected":""}`,disabled:!o,onClick:()=>Q({taskId:ne.id}),children:[t.jsx("span",{className:"next-task-marker",children:u(D.taskId===ne.id?t.jsx(ew,{size:17}):t.jsx("span",{}))}),t.jsxs("span",{children:[t.jsx("strong",{children:ne.title}),t.jsxs("small",{children:[u(ne.status),u(" · "),u(ne.priority),u(" priority")]})]})]},ne.id)),!ie.length&&t.jsx("p",{className:"empty",children:u("You’re all caught up. Make room for your next idea.")})]})]})]})}const sT=(()=>{try{return Intl.DateTimeFormat().resolvedOptions().timeZone||"UTC"}catch{return"UTC"}})(),Zp=()=>{try{return Da().timezone||sT}catch{return sT}},Gc=[{name:"Weekdays at 9:00",cron:"0 9 * * 1-5"},{name:"Every six hours",cron:"0 */6 * * *"},{name:"Mon, Wed, Fri at 10:00",cron:"0 10 * * 1,3,5"},{name:"Weekdays at 16:00",cron:"0 16 * * 1-5"},{name:"Every hour",cron:"0 * * * *"}];function sX(a){return Gc.find(e=>e.cron===a)?.name||"Custom schedule"}function Pc(a,e=Zp()){return a?new Intl.DateTimeFormat("en-GB",{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",timeZone:e}).format(new Date(a)):"–"}const rX={jobs:[],runs:[],metrics:{queued24Hours:0},engine:{configured:!1,lastCheckedAt:null,intervalMinutes:60}};function oX({agents:a,disabled:e,onWorkspaceChange:n,onOpenTask:s}){const[o,l]=C.useState({}),[d,h]=C.useState(rX),[m,p]=C.useState(!1),[y,v]=C.useState(""),[x,S]=C.useState(""),[M,w]=C.useState(""),[E,A]=C.useState("All jobs"),[k,R]=C.useState(""),[N,I]=C.useState("jobs"),[z,j]=C.useState(null),[L,D]=C.useState(!1),[P,F]=C.useState(null),[q,J]=C.useState(!1),[ie,Q]=C.useState(!1),[V,$]=C.useState(Gc[0].cron),[te,ne]=C.useState(Zp()),[Y,T]=C.useState([]),[_,ve]=C.useState(""),je=Tl();C.useEffect(()=>{je.view==="Schedule"&&je.section==="history"&&I("history")},[je.stamp]);const Je=C.useRef(!1),xe=C.useRef(null),ee=C.useRef(null);async function Ce(ue=!1){try{const ft=await na("/api/schedule",{cache:"no-store"}),Re=await ft.json();if(!ft.ok)throw new Error(Re.error);h(Re),p(!0),ue||S("")}catch(ft){S(ft.message)}}C.useEffect(()=>{Ce();const ue=setInterval(()=>{Je.current||Ce(!0)},3e4);return()=>{clearInterval(ue),ee.current&&clearTimeout(ee.current)}},[]),C.useEffect(()=>{if(!L)return;T([]);let ue=!0;const ft=setTimeout(async()=>{try{const Re=await na("/api/schedule",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({action:"preview",cron:V,timezone:te})}),K=await Re.json();if(!ue)return;Re.ok?(T(K.dates||[]),ve("")):(T([]),ve(K.error||"Invalid schedule"))}catch{ue&&(T([]),ve("Could not preview this schedule."))}},350);return()=>{ue=!1,clearTimeout(ft)}},[V,te,L]);function Ze(ue){w(ue),ee.current&&clearTimeout(ee.current),ee.current=setTimeout(()=>w(""),4500)}async function le(ue,ft,Re){if(Je.current||e||!m)return!1;Je.current=!0,v(ft?.id||ue),S("");const K=`${ue}:${ft?.id||"all"}`,B=ue==="run"||ue==="runAll";B&&xe.current?.key!==K&&(xe.current={key:K,id:crypto.randomUUID()});try{const pe=await na("/api/schedule",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({action:ue,...ft?{id:ft.id,version:ft.version}:{},...B?{requestId:xe.current.id}:{},...Re})}),Ae=await pe.json();if(!pe.ok)throw new Error(Ae.error||"Could not update this job.");return h(Ae),xe.current=null,Ze(Ae.message||"Schedule updated"),B&&await n(),!0}catch(pe){return S(pe.message),await Ce(!0),!1}finally{Je.current=!1,v("")}}function qe(ue){j(ue||null),$(ue?.cron||Gc[0].cron),Q(!!ue&&!Gc.some(ft=>ft.cron===ue.cron)),ne(ue?.timezone||Zp()),T([]),ve(""),D(!0)}async function xt(ue){ue.preventDefault();const ft=new FormData(ue.currentTarget),Re={name:String(ft.get("name")).trim(),description:String(ft.get("description")).trim(),agentId:String(ft.get("agentId")),cron:V,timezone:te,priority:String(ft.get("priority"))};await le("save",z||void 0,{job:Re})&&D(!1)}const se=d.jobs.filter(ue=>!ue.deletedAt),Pe=d.jobs.filter(ue=>!!ue.deletedAt),mt=se.filter(ue=>ue.enabled),it=d.metrics.queued24Hours,at=mt.filter(ue=>ue.nextRunAt).sort((ue,ft)=>ue.nextRunAt.localeCompare(ft.nextRunAt))[0],Be=(N==="trash"?Pe:se).filter(ue=>(E==="All jobs"||(E==="Active"?!!ue.enabled:!ue.enabled))&&`${ue.name} ${a.find(ft=>ft.id===ue.agentId)?.name}`.toLowerCase().includes(k.toLowerCase())),We=e||!m||!!y;return t.jsxs("div",{className:"schedule-page",children:[t.jsxs("div",{className:"page-heading schedule-page-heading",children:[t.jsxs("div",{children:[t.jsxs("div",{className:"eyebrow",children:[t.jsx("span",{}),u("WORKSPACE / SCHEDULE")]}),t.jsx("h1",{children:u("Schedule")}),t.jsx("p",{children:u("Put recurring work on a steady rhythm.")})]}),t.jsxs("div",{className:"schedule-heading-actions",children:[t.jsxs("span",{className:"schedule-timezone",children:[t.jsx(ts,{size:15}),u("Default timezone · "),u(Zp())]}),t.jsxs("button",{className:"secondary-btn",disabled:We||!se.length,onClick:()=>J(!0),children:[t.jsx(gi,{size:16}),u("Run all jobs")]}),t.jsxs("button",{className:"primary-btn",disabled:We,onClick:()=>qe(),children:[t.jsx(jn,{size:17}),u("New job")]})]})]}),t.jsxs("div",{className:"schedule-stats",children:[t.jsxs("section",{className:"schedule-stat featured",children:[t.jsxs("span",{children:[t.jsx(Fs,{size:17}),u("Recurring jobs")]}),t.jsxs("div",{children:[t.jsx("strong",{children:u(se.length)}),t.jsxs("small",{children:[u(a.length),u(" specialists in your team")]})]})]}),t.jsxs("section",{className:"schedule-stat",children:[t.jsxs("span",{children:[t.jsx(gi,{size:17}),u("Active schedules")]}),t.jsxs("div",{children:[t.jsx("strong",{children:u(mt.length)}),t.jsxs("small",{children:[u(se.length-mt.length),u(" paused")]})]})]}),t.jsxs("section",{className:"schedule-stat",children:[t.jsxs("span",{children:[t.jsx(ol,{size:17}),u("Tasks queued")]}),t.jsxs("div",{children:[t.jsx("strong",{children:u(it)}),t.jsx("small",{children:u("In the last 24 hours")})]})]}),t.jsxs("section",{className:"schedule-stat",children:[t.jsxs("span",{children:[t.jsx(Ds,{size:17}),u("Next scheduled run")]}),t.jsxs("div",{children:[t.jsx("strong",{className:"next-run-value",children:u(at?Pc(at.nextRunAt,at.timezone):"No active jobs")}),t.jsx("small",{children:u(at?at.name:"Start a job to set the rhythm")})]})]})]}),t.jsxs("div",{className:"schedule-engine",children:[t.jsx("span",{className:"schedule-engine-icon",children:t.jsx(Ds,{size:20})}),t.jsxs("div",{children:[t.jsx("strong",{children:u("Scheduler running")}),t.jsx("p",{children:u("Checks every minute. Each run asks the agent and puts its result on the board for your review.")})]}),t.jsx("span",{className:"engine-last-check",children:u(d.engine.lastCheckedAt?`Last check · ${Pc(d.engine.lastCheckedAt)}`:"Start and pause jobs independently")})]}),x&&t.jsxs("div",{className:"chat-error",role:"alert",children:[u(x),t.jsx("button",{onClick:()=>Ce(),children:u("Reload schedules")})]}),M&&t.jsxs("div",{className:"schedule-notice",role:"status",children:[t.jsx($a,{size:17}),u(M)]}),t.jsxs("div",{className:"schedule-toolbar",children:[t.jsxs("div",{className:"schedule-section-tabs",role:"group","aria-label":u("Schedule view"),children:[t.jsxs("button",{"aria-pressed":N==="jobs",className:N==="jobs"?"selected":"",onClick:()=>{I("jobs"),A("All jobs")},children:[t.jsx(Fs,{size:16}),u("Jobs "),t.jsx("span",{children:u(se.length)})]}),t.jsxs("button",{"aria-pressed":N==="history",className:N==="history"?"selected":"",onClick:()=>I("history"),children:[t.jsx(fl,{size:16}),u("Run history")]}),t.jsxs("button",{"aria-pressed":N==="trash",className:N==="trash"?"selected":"",onClick:()=>{I("trash"),A("All jobs")},children:[t.jsx(ti,{size:15}),u("Trash "),Pe.length>0&&t.jsx("span",{children:u(Pe.length)})]})]}),t.jsx("button",{className:"icon-btn",disabled:We,onClick:()=>Ce(),"aria-label":u("Refresh schedules"),children:t.jsx(xl,{size:17})})]}),N!=="history"&&t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"schedule-filters",children:[t.jsx("div",{className:"filter-tabs",children:["All jobs","Active","Paused"].map(ue=>t.jsx("button",{className:E===ue?"selected":"","aria-pressed":E===ue,onClick:()=>A(ue),children:u(ue)},ue))}),t.jsxs("label",{className:"search-input",children:[t.jsx(vo,{size:17}),t.jsx("input",{"aria-label":u("Search scheduled jobs"),placeholder:u("Find a job or agent…"),value:k,onChange:ue=>R(ue.target.value)})]})]}),t.jsx("div",{className:"scheduled-job-grid",children:Be.map(ue=>{const ft=a.find(K=>K.id===ue.agentId);if(!ft)return null;const Re=d.runs.find(K=>K.jobId===ue.id);return t.jsxs("article",{className:`scheduled-job ${ue.enabled?"job-active":""}`,children:[t.jsxs("header",{children:[t.jsx("span",{className:"scheduled-job-symbol",children:t.jsx(Ds,{size:22})}),t.jsx("span",{className:`job-state ${ue.deletedAt?"trashed":ue.enabled?"active":"paused"}`,children:u(ue.deletedAt?"In Trash":ue.enabled?"Active":"Paused")}),!ue.deletedAt&&t.jsx("button",{className:"icon-btn",disabled:We,onClick:()=>qe(ue),"aria-label":u(`Edit ${ue.name}`),children:t.jsx(LU,{size:16})})]}),t.jsx("h2",{children:ue.name}),t.jsx("p",{className:`job-description ${ue.description.length>150&&!o[ue.id]?"clamped":""}`,children:ue.description}),ue.description.length>150&&t.jsx("button",{className:"job-more","aria-expanded":!!o[ue.id],onClick:()=>l(K=>({...K,[ue.id]:!K[ue.id]})),children:u(o[ue.id]?"Show less":"See full instructions")}),t.jsxs("div",{className:"job-agent",children:[t.jsx(qt,{agent:ft,small:!0}),t.jsxs("span",{children:[t.jsx("strong",{children:ft.name}),t.jsxs("small",{children:[u(ue.priority),u(" priority")]})]}),t.jsx("span",{className:"job-task-type",children:u("Creates task")})]}),t.jsxs("div",{className:"job-cadence",children:[t.jsxs("span",{children:[t.jsx(ts,{size:15}),u(sX(ue.cron))]}),t.jsx("code",{children:u(ue.cron)}),t.jsx("small",{children:u(ue.timezone)})]}),t.jsxs("div",{className:"job-run-details",children:[t.jsxs("div",{children:[t.jsx("span",{children:u("Next run")}),t.jsx("strong",{children:u(ue.enabled?Pc(ue.nextRunAt,ue.timezone):"Paused")})]}),t.jsxs("div",{children:[t.jsx("span",{children:u("Last run")}),t.jsx("strong",{children:Re?t.jsxs(t.Fragment,{children:[t.jsx("span",{className:`last-run-mark ${Re.status.toLowerCase()}`}),u(Re.status),u(" · "),u(Pc(Re.startedAt,ue.timezone))]}):"Not run yet"})]})]}),t.jsx("footer",{children:ue.deletedAt?t.jsxs("button",{className:"secondary-btn",disabled:We,onClick:()=>le("restore",ue),children:[t.jsx(ss,{size:15}),u("Restore job")]}):t.jsxs(t.Fragment,{children:[t.jsxs("button",{className:"job-run-button",disabled:We,onClick:()=>le("run",ue),children:[u(y===ue.id?t.jsx(Jt,{className:"spinning",size:16}):t.jsx(gi,{size:16})),u("Run now")]}),t.jsxs("button",{className:"job-toggle-button",disabled:We,onClick:()=>le(ue.enabled?"stop":"start",ue),"aria-label":u(`${ue.enabled?"Stop":"Start"} ${ue.name}`),children:[u(ue.enabled?t.jsx(nu,{size:15}):t.jsx(gi,{size:15}))," ",u(ue.enabled?"Stop":"Start")]}),t.jsx("button",{className:"icon-btn job-delete",disabled:We,onClick:()=>F(ue),"aria-label":u(`Delete ${ue.name}`),children:t.jsx(ti,{size:16})})]})})]},ue.id)})}),!Be.length&&t.jsxs("div",{className:"panel schedule-empty",children:[t.jsx(Ds,{size:30}),t.jsx("h2",{children:u(m?N==="trash"?"Trash is empty":"No matching jobs":"Loading your schedules…")}),t.jsx("p",{children:u(m?N==="trash"?"Deleted jobs can be restored here.":"Create a job or try a different filter.":"Your jobs and run history will appear here.")})]})]}),N==="history"&&t.jsxs("section",{className:"panel schedule-history",children:[t.jsxs("div",{className:"panel-title",children:[t.jsxs("div",{children:[t.jsx("h2",{children:u("Run history")}),t.jsx("p",{children:u("Every trigger, its outcome, and the task it created.")})]}),t.jsxs("span",{className:"muted",children:[u("Latest "),u(d.runs.length),u(" runs")]})]}),d.runs.length?t.jsx("div",{className:"schedule-history-scroll",tabIndex:0,role:"region","aria-label":u("Scheduled job run history"),children:t.jsxs("table",{children:[t.jsx("thead",{children:t.jsxs("tr",{children:[t.jsx("th",{children:u("Job")}),t.jsx("th",{children:u("Agent")}),t.jsx("th",{children:u("Trigger")}),t.jsx("th",{children:u("Result")}),t.jsx("th",{children:u("Started")}),t.jsx("th",{children:u("Related task")})]})}),t.jsx("tbody",{children:d.runs.map(ue=>{const ft=a.find(Re=>Re.id===ue.agentId);return ft?t.jsxs("tr",{children:[t.jsxs("td",{children:[t.jsx("strong",{children:u(ue.jobName)}),ue.error&&t.jsx("span",{className:"run-error-text",children:u(ue.error)})]}),t.jsx("td",{children:t.jsxs("span",{className:"table-agent",children:[t.jsx(qt,{agent:ft,small:!0}),ft.name]})}),t.jsx("td",{children:u(ue.trigger)}),t.jsx("td",{children:t.jsxs("span",{className:`run-result ${ue.status.toLowerCase()}`,children:[u(ue.status==="Queued"||ue.status==="Done"?t.jsx($a,{size:14}):ue.status==="Running"?t.jsx(Jt,{size:14,className:"spinning"}):t.jsx(da,{size:14}))," ",u(ue.status)]})}),t.jsx("td",{children:u(Pc(ue.startedAt))}),t.jsx("td",{children:ue.taskId?t.jsxs("button",{className:"text-btn",onClick:()=>s(ue.taskId),children:[t.jsx(ol,{size:14}),u("Open task")]}):t.jsx("span",{className:"muted",children:u("–")})})]},ue.id):null})})]})}):t.jsxs("div",{className:"schedule-empty",children:[t.jsx(fl,{size:30}),t.jsx("h2",{children:u("A clean slate.")}),t.jsx("p",{children:u("Run a job to see the first entry here.")})]})]}),t.jsxs("div",{className:"schedule-footnote",children:[t.jsx(VT,{size:15}),t.jsx("p",{children:u("Manual runs work even when a job is paused. Starting a job enables its recurring schedule; stopping it pauses future triggers. Changes are saved on your server.")})]}),t.jsx(Tm,{open:L,onOpenChange:ue=>{y||D(ue)},children:t.jsxs(jm,{children:[t.jsx(Rm,{className:"modal-overlay"}),t.jsxs(km,{className:"modal-content schedule-modal",children:[t.jsx(zm,{className:"modal-close","aria-label":u("Close job editor"),children:t.jsx(da,{size:20})}),t.jsx("span",{className:"modal-symbol",children:t.jsx(Ds,{size:25})}),t.jsx(Nm,{children:u(z?"Edit job":"Create a recurring job")}),t.jsx(Dm,{children:u("Set a cadence and tell your agent what the task should contain.")}),t.jsxs("form",{onSubmit:xt,children:[t.jsxs("label",{children:[u("Job name"),t.jsx("input",{name:"name",required:!0,maxLength:100,placeholder:u("e.g. Weekly research roundup"),defaultValue:z?.name||"",autoFocus:!0})]}),t.jsxs("label",{children:[u("Task brief"),t.jsx("textarea",{name:"description",required:!0,maxLength:2e3,rows:3,placeholder:u("What should this job ask the agent to do?"),defaultValue:z?.description||""})]}),t.jsxs("div",{className:"form-grid",children:[t.jsxs("label",{children:[u("Assigned agent"),t.jsx("select",{name:"agentId",defaultValue:z?.agentId||a[0]?.id,children:u(a.map(ue=>t.jsx("option",{value:ue.id,children:ue.name},ue.id)))})]}),t.jsxs("label",{children:[u("Priority"),t.jsxs("select",{name:"priority",defaultValue:z?.priority||"Medium",children:[t.jsx("option",{value:"Medium",children:u("Medium")}),t.jsx("option",{value:"High",children:u("High")}),t.jsx("option",{value:"Low",children:u("Low")})]})]})]}),t.jsxs("label",{children:[u("Cadence"),t.jsxs("select",{"aria-label":u("Schedule preset"),value:ie?"custom":Gc.some(ue=>ue.cron===V)?V:"custom",onChange:ue=>{Q(ue.target.value==="custom"),ue.target.value!=="custom"&&$(ue.target.value)},children:[u(Gc.map(ue=>t.jsx("option",{value:ue.cron,children:ue.name},ue.cron))),t.jsx("option",{value:"custom",children:u("Custom cron expression")})]})]}),t.jsxs("div",{className:"form-grid",children:[t.jsxs("label",{children:[u("Cron expression"),t.jsx("input",{"aria-label":u("Cron expression"),value:V,onChange:ue=>{Q(!0),$(ue.target.value)},required:!0,maxLength:100,className:"cron-input"})]}),t.jsxs("label",{children:[u("Timezone"),t.jsx("input",{"aria-label":u("Schedule timezone"),value:te,onChange:ue=>ne(ue.target.value),required:!0,maxLength:80,list:"schedule-timezones"}),t.jsx("datalist",{id:"schedule-timezones",children:zp.map(ue=>t.jsx("option",{value:ue,children:uT(ue)},ue))})]})]}),t.jsxs("div",{className:"cron-field-help",children:[t.jsx("span",{children:u("minute")}),t.jsx("span",{children:u("hour")}),t.jsx("span",{children:u("day")}),t.jsx("span",{children:u("month")}),t.jsx("span",{children:u("weekday")})]}),t.jsxs("div",{className:"schedule-preview",children:[t.jsxs("span",{children:[t.jsx(Ds,{size:16}),u("Next three occurrences")]}),Y.map(ue=>t.jsx("div",{children:u(Pc(ue,te))},ue)),_&&t.jsx("p",{role:"alert",children:u(_)})]}),t.jsx("p",{className:"form-note",children:u("Check the next run times before you save. New jobs start paused.")}),x&&t.jsx("p",{className:"form-error",role:"alert",children:u(x)}),t.jsxs("button",{className:"primary-btn form-submit",disabled:We||!!_||!Y.length,children:[u(y?t.jsx(Jt,{size:16,className:"spinning"}):t.jsx(Kt,{size:16}))," ",u(z?"Save changes":"Create job")]})]})]})]})}),t.jsx(yw,{open:!!P,onOpenChange:ue=>{ue||F(null)},children:t.jsxs(bw,{children:[t.jsx(Sw,{className:"modal-overlay"}),t.jsxs(Aw,{className:"modal-content schedule-confirm",children:[t.jsxs(Ew,{children:[u("Delete "),P?.name,u("?")]}),t.jsx(ww,{children:u("The job will move to Trash and stop triggering. Existing tasks and run history stay available.")}),t.jsxs("div",{className:"detail-actions",children:[t.jsx(Cw,{className:"secondary-btn",children:u("Keep job")}),t.jsx(Mw,{className:"schedule-danger-btn",onClick:()=>{P&&le("delete",P)},children:u("Move to Trash")})]})]})]})}),t.jsx(yw,{open:q,onOpenChange:J,children:t.jsxs(bw,{children:[t.jsx(Sw,{className:"modal-overlay"}),t.jsxs(Aw,{className:"modal-content schedule-confirm",children:[t.jsxs(Ew,{children:[u("Run all "),u(se.length),u(" jobs now?")]}),t.jsx(ww,{children:u("This creates one task for each job, including paused jobs. Their recurring schedules stay as they are.")}),t.jsxs("div",{className:"detail-actions",children:[t.jsx(Cw,{className:"secondary-btn",children:u("Cancel")}),t.jsxs(Mw,{className:"primary-btn",onClick:()=>le("runAll"),children:[t.jsx(gi,{size:16}),u("Run all jobs")]})]})]})]})})]})}function lX({onOpen:a}){const e=mu(),[n,s]=C.useState(()=>new Date);C.useEffect(()=>{const p=setInterval(()=>s(new Date),5e3);return()=>clearInterval(p)},[]);let o="",l="";try{const p={timeZone:e.timezone};o=new Intl.DateTimeFormat(Hn(),{...p,hour:"2-digit",minute:"2-digit",hour12:e.hour12}).formatToParts(n).map(v=>v.type==="literal"&&v.value.trim()===":"?"\0":v.value).join(""),l=new Intl.DateTimeFormat(Hn(),{...p,weekday:"short",day:"numeric",month:"short"}).format(n)}catch{o=n.toLocaleTimeString()}const[d,h]=o.split("\0"),m=`${e.timezone.replaceAll("_"," ")}. ${u("Change the timezone in Settings")}`;return t.jsxs("button",{className:"top-clock",onClick:a,title:m,"aria-label":`${o.replace("\0",":")}, ${l}. ${m}`,children:[t.jsx(oU,{size:15}),t.jsx("strong",{children:h!==void 0?t.jsxs(t.Fragment,{children:[d,t.jsx("i",{children:":"}),h]}):o}),t.jsx("span",{className:"top-clock-day",children:l})]})}const cX=a=>new Intl.NumberFormat(Hn(),{notation:"compact",maximumFractionDigits:a>=1e6?1:0}).format(a);function uX(a,e,n){const s=Date.now(),o=x=>{const S=Object.fromEntries(new Intl.DateTimeFormat("en-GB",{timeZone:n,hour:"2-digit",minute:"2-digit",weekday:"short",hourCycle:"h23"}).formatToParts(x).map(M=>[M.type,M.value]));return{min:Number(S.hour)*60+Number(S.minute),day:S.weekday}},l=o(new Date(s)),d=[];for(const x of a)x.enabled&&!x.deletedAt&&x.nextRunAt&&d.push({name:x.name,inMin:(Date.parse(x.nextRunAt)-s)/6e4,view:"Schedule"});for(const x of e){if(x.trigger!=="On a schedule"||!x.enabled||!/^\d\d:\d\d$/.test(x.at||""))continue;const S=Number(x.at.slice(0,2))*60+Number(x.at.slice(3));for(let M=0;M<8;M++){const w=M*1440+S-l.min;if(w<=0)continue;const E=o(new Date(s+w*6e4)).day;if(!(x.weekdays&&(E==="Sat"||E==="Sun"))){d.push({name:x.name,inMin:w,view:"Automations"});break}}}const h=d.sort((x,S)=>x.inMin-S.inMin)[0];if(!h)return null;const m=new Date(s+h.inMin*6e4),p=m.toLocaleTimeString(Hn(),{timeZone:n,hour:"2-digit",minute:"2-digit"}),y=x=>x.toLocaleDateString("en-CA",{timeZone:n}),v=y(m)===y(new Date(s))?`${u("today")} ${p}`:y(m)===y(new Date(s+864e5))?`${u("tomorrow")} ${p}`:`${m.toLocaleDateString(Hn(),{timeZone:n,weekday:"short"})} ${p}`;return{...h,when:v}}const dX={"Content Writer":"Writer","Marketing Strategist":"Marketing","Automation Specialist":"Automation","Personal Assistant":"Assistant","Customer Support":"Support","Customer Success":"Success","Executive Assistant":"Assistant","Social Media Manager":"Social Media","Operations Manager":"Operations","Project Manager":"Projects","Legal Assistant":"Legal","SEO Specialist":"SEO"};function hX({data:a,onNavigate:e,onAgent:n,onChat:s,onTask:o,below:l}){const d=Bi(),h=Nl(),m=Eu(),p=mu(),[y,v]=C.useState(null),[x,S]=C.useState([]);C.useEffect(()=>{let Re=!0;const K=()=>{wt("/api/pulse").then(pe=>{Re&&v(pe)}).catch(()=>{}),wt("/api/schedule").then(pe=>{Re&&S(pe.jobs||[])}).catch(()=>{})};K();const B=setInterval(K,6e4);return()=>{Re=!1,clearInterval(B)}},[]);const M=m.stage==="inbox"?dl(m.emails):[],w=M.filter(Re=>Re.unread),E=M.filter(Yc).sort((Re,K)=>K.at.localeCompare(Re.at)),A=E[0]||[...w].sort((Re,K)=>K.at.localeCompare(Re.at))[0],k=uX(x,h.rules,p.timezone),R=y?.tokens.today||0,N=y?.tokens.usual||0,I=y?N?`${(R/N).toFixed(R/N>=10?0:1)}× ${u("a usual day")}`:u(R?"First day on record":"Quiet so far"):"",[z,j]=C.useState(a.agents[0]?.id||""),[L,D]=C.useState(0),[P,F]=C.useState(7),[q,J]=C.useState(null),ie=a.agents,Q=a.agents.find(Re=>Re.name==="Orchestrator")||a.agents[0],V=a.agents.find(Re=>Re.id===z)||a.agents[0],$=a.agents.filter(Re=>Re.status==="Working").length,te=d.missions.filter(Re=>["Running","In review","Awaiting approval"].includes(Re.status)).sort((Re,K)=>["Running","In review","Awaiting approval"].indexOf(Re.status)-["Running","In review","Awaiting approval"].indexOf(K.status)),ne=te[L%Math.max(1,te.length)];d.missions.filter(Re=>Re.status==="Running").length;const Y=a.agents.reduce((Re,K)=>Re+K.completed,0);Y&&a.agents.reduce((Re,K)=>Re+K.completed*K.success,0)/Y;const T=bh(),_=ne?.steps.filter(Re=>Re.status==="Done").length||0,ve=ne?.steps.length||0,je=ve?Math.round(_/ve*100):0,Je=m.stage==="inbox"?$0(m.emails).sort((Re,K)=>K.urgency-Re.urgency||K.at.localeCompare(Re.at)):[];T[0],Je[0],a.activity.slice(0,4);const xe=Array.from({length:P},(Re,K)=>{const B=new Date;B.setDate(B.getDate()-(P-1-K));const pe=B.toISOString().slice(0,10);return{date:B,label:B.toLocaleDateString(Hn(),{weekday:"short",day:"numeric",month:"short"}),count:a.activity.filter(Ae=>Ae.type==="completed"&&Ae.time.slice(0,10)===pe).length+h.runs.filter(Ae=>Ae.status==="Completed"&&Ae.time.slice(0,10)===pe).length}});Math.max(1,...xe.map(Re=>Re.count)),xe.reduce((Re,K)=>Re+K.count,0),h.runs.reduce((Re,K)=>Re+K.tokens,0),h.runs.reduce((Re,K)=>Re+K.cost,0);const ee=ie.filter(Re=>Re.id!==Q?.id),Ce=a.agents.reduce((Re,K)=>Re+K.completed,0),Ze=Math.max(0,...ee.map(Re=>Re.completed)),le=28,qe=34,xt=Math.min(1,4/Math.max(1,Math.ceil(ee.length/2))),se=Re=>(le+(Ze?qe*Re.completed/Ze:0))*xt,Pe=Re=>Ce?Math.round(Re.completed/Ce*100):0,mt=C.useRef(null),[it,at]=C.useState({});C.useLayoutEffect(()=>{const Re=mt.current;if(!Re)return;const K=()=>{const Ae=Re.getBoundingClientRect();if(!Ae.width||!Ae.height)return;const Ne={},be=[];Re.querySelectorAll("[data-agent]").forEach(re=>{const Se=re.querySelector(".home-conductor-avatar")?.getBoundingClientRect(),He=re.querySelector(".home-conductor-copy")?.getBoundingClientRect();if(!Se)return;const lt=re.classList.contains("right");be.push({id:re.dataset.agent,right:lt,y:Se.top+Se.height/2-Ae.top,edge:lt?Math.min(Se.left,He?.left??Se.left)-Ae.left:Math.max(Se.right,He?.right??Se.right)-Ae.left})});const ot=Ae.width<560?8:18,Ve=Math.max(0,...be.filter(re=>!re.right).map(re=>re.edge))+ot,ut=Math.min(Ae.width,...be.filter(re=>re.right).map(re=>re.edge))-ot;for(const re of be)Ne[re.id]={x:(re.right?ut:Ve)/Ae.width*1200,y:re.y/Ae.height*500};at(Ne)};K();const B=new ResizeObserver(K);B.observe(Re);const pe=setTimeout(K,400);return()=>{B.disconnect(),clearTimeout(pe)}},[a.agents.length]);const Be=ee.slice(0,Math.ceil(ee.length/2)),We=ee.slice(Math.ceil(ee.length/2)),ue=Re=>Re.toLocaleString(Hn()),ft=new Date().toLocaleDateString(Hn(),{weekday:"long",month:"short",day:"numeric",timeZone:p.timezone});return t.jsxs("div",{className:"laboratorio-home",children:[t.jsxs("header",{className:"home-heading",children:[t.jsxs("span",{className:"home-eyebrow",children:[t.jsx("span",{}),u("YOUR TEAM, IN HARMONY")]}),t.jsxs("span",{className:"home-date",children:[t.jsx(NT,{size:15}),ft]})]}),t.jsxs("section",{className:"home-command","aria-label":u("Team command center"),children:[t.jsxs("header",{className:"home-scene-heading",children:[t.jsxs("div",{children:[t.jsxs("span",{className:"home-kicker",children:["01 / ",u("THE COLLECTIVE")]}),t.jsxs("h1",{children:[u("Individual brilliance."),t.jsx("br",{}),t.jsx("em",{children:u("Extraordinary together.")})]})]}),t.jsxs("div",{className:"home-scene-actions",children:[t.jsxs("span",{className:"home-status",children:[t.jsx("span",{}),$," ",u("working now")]}),t.jsxs("button",{className:"home-launch",onClick:()=>e("Missions",void 0,"launch"),children:[t.jsx(jn,{size:17}),u("Launch a mission"),t.jsx(_i,{size:17})]})]})]}),t.jsxs("div",{className:"home-useful-layout",children:[t.jsxs("div",{className:"home-team-canvas",children:[t.jsxs("div",{className:"home-flow-caption",children:[t.jsx("span",{children:u("Individual contributions. Collective momentum.")}),t.jsxs("button",{onClick:()=>{J(null),j(Q?.id||"")},className:q?"":"active",children:[u("All agents"),t.jsx(_i,{size:14})]})]}),t.jsxs("div",{ref:mt,className:`home-conductor ${q?"is-focused":""}`,style:Be.length>4?{minHeight:`${150*(Be.length-1)}px`}:void 0,"aria-label":u("Team command center"),children:[t.jsxs("svg",{className:"home-conductor-bands",viewBox:"0 0 1200 500",preserveAspectRatio:"none",role:"img","aria-label":u("Agent contributions to completed work"),children:[t.jsxs("defs",{children:[[0,1].map(Re=>t.jsxs("linearGradient",{id:`conductor-fade-${Re}`,gradientUnits:"userSpaceOnUse",x1:Re?it[We[0]?.id]?.x??1030:it[Be[0]?.id]?.x??170,x2:Re?665:535,y1:"0",y2:"0",children:[t.jsx("stop",{stopColor:"white"}),t.jsx("stop",{offset:".45",stopColor:"white"}),t.jsx("stop",{offset:".75",stopColor:"#666"}),t.jsx("stop",{offset:"1",stopColor:"black"})]},Re)),[0,1].map(Re=>t.jsx("mask",{id:`conductor-mask-${Re}`,maskUnits:"userSpaceOnUse",x:"0",y:"0",width:"1200",height:"500",children:t.jsx("rect",{width:"1200",height:"500",fill:`url(#conductor-fade-${Re})`})},Re)),ee.map((Re,K)=>t.jsxs("linearGradient",{id:`conductor-${Re.id}`,x1:KRe.map((B,pe)=>{const Ae=it[B.id],Ne=Ae?.y??(Re.length===1?250:65+pe*370/(Re.length-1)),be=Re.length===1?250:195+pe*110/(Re.length-1),ot=se(B),Ve=Ae?.x??(K?1030:170),ut=K?665:535,re=Ve+(ut-Ve)*.52,Se=ut-(ut-Ve)*.33;return t.jsxs("g",{mask:`url(#conductor-mask-${K})`,className:q&&q!==B.id?"muted":"",children:[t.jsx("path",{d:`M ${Ve} ${Ne-ot/2} C ${re} ${Ne-ot/2} ${Se} ${be-5} ${ut} ${be-5} L ${ut} ${be+5} C ${Se} ${be+5} ${re} ${Ne+ot/2} ${Ve} ${Ne+ot/2} Z`,fill:`url(#conductor-${B.id})`,stroke:"#ddffbb",strokeOpacity:".12"}),t.jsx("path",{d:`M ${Ve} ${Ne} C ${re} ${Ne} ${Se} ${be} ${ut} ${be}`,fill:"none",stroke:"#eaffc9",strokeWidth:".7",strokeOpacity:".22"})]},B.id)}))]}),[Be,We].map((Re,K)=>Re.map((B,pe)=>t.jsxs("button",{"data-agent":B.id,className:`home-conductor-agent ${K?"right":"left"} ${z===B.id?"selected":""}`,style:{top:`${Re.length===1?50:13+pe*74/(Re.length-1)}%`},"aria-pressed":z===B.id,onClick:()=>{j(B.id),J(B.id),n(B)},children:[t.jsxs("span",{className:"home-conductor-avatar",children:[t.jsx(qt,{agent:B}),t.jsx("span",{className:"home-agent-orbit","aria-hidden":"true",style:{"--orbit-s":`${8+(pe*2+K*3)%5}s`,"--orbit-d":`${-(pe*1.7+K*4.3)}s`}}),t.jsx("i",{className:B.status.toLowerCase()})]}),t.jsxs("span",{className:"home-conductor-copy",children:[t.jsx("strong",{children:u(dX[B.name]||B.name)}),t.jsxs("small",{children:[ue(B.completed)," ",u("completed agent tasks")]}),t.jsxs("small",{className:"home-share",children:[Pe(B),"%",t.jsxs("span",{className:"home-share-words",children:[" ",u("of the work")]})]})]})]},B.id))),Q&&t.jsxs("div",{className:"home-conductor-center",children:[t.jsx("span",{className:"home-kicker",children:u("THE ORCHESTRATION ENGINE")}),t.jsxs("button",{className:"home-boss-portrait",onClick:()=>n(Q),"aria-label":`${u("Chat with")}: ${u(Q.name)}`,children:[t.jsx(qt,{agent:Q}),t.jsx("span",{className:"home-boss-orbit","aria-hidden":"true"}),t.jsx("span",{className:"home-boss-badge",children:t.jsx(Fs,{size:17})})]}),t.jsx("h2",{children:u(Q.name)}),t.jsx("p",{children:Q.model}),t.jsxs("p",{className:"home-share",children:[Pe(Q),"% ",u("of the team’s work")]}),t.jsxs("span",{className:"home-status",children:[t.jsx("span",{}),u(Q.status)]})]})]})]}),t.jsxs("aside",{className:"home-priority","aria-label":u("YOUR NEXT MOVE"),children:[t.jsxs("header",{children:[t.jsx("span",{className:"home-kicker",children:u("YOUR NEXT MOVE")}),t.jsx("h2",{children:u("Make the next move count.")}),t.jsx("p",{children:u("Your decisions keep the team moving.")})]}),t.jsxs("div",{className:"home-priority-counts",children:[t.jsxs("button",{onClick:()=>e("System"),children:[t.jsx(lU,{size:17}),t.jsx("strong",{children:y?cX(R):"–"}),t.jsxs("span",{children:[u("Tokens, last 24 h"),I&&t.jsxs(t.Fragment,{children:[t.jsx("br",{}),I]})]})]}),t.jsxs("button",{onClick:()=>e("Mail",void 0,"unread"),children:[t.jsx(ei,{size:17}),t.jsx("strong",{children:m.stage==="inbox"?ue(ml(w)).padStart(2,"0"):"–"}),t.jsxs("span",{children:[u("Unread mail"),m.stage==="inbox"&&t.jsxs(t.Fragment,{children:[t.jsx("br",{}),ml(E)," ",u(ml(E)===1?"needs a reply":"need a reply")]})]})]})]}),t.jsxs("div",{className:"home-priority-items",children:[t.jsxs("button",{onClick:()=>e(k?.view||"Automations"),children:[t.jsx("span",{className:"home-priority-item-icon",children:t.jsx(Ds,{size:18})}),t.jsxs("span",{children:[t.jsx("small",{children:k?`${u("Next scheduled run")} · ${k.when}`:u("Nothing scheduled")}),t.jsx("strong",{children:k?.name||u("Create a rule that runs on its own.")})]}),t.jsx(_i,{size:16})]}),t.jsxs("button",{onClick:()=>e("Mail",A?.id),children:[t.jsx("span",{className:"home-priority-item-icon",children:t.jsx(ei,{size:18})}),t.jsxs("span",{children:[t.jsx("small",{children:m.stage!=="inbox"?u("Mail"):A?`${A.sender} · ${u(Yc(A)?"needs a reply":"unread")}`:u("Mail")}),t.jsx("strong",{children:m.stage!=="inbox"?u("Connect your inbox"):A?.subject||u("Nobody is waiting for an answer.")})]}),t.jsx(_i,{size:16})]})]}),t.jsxs("div",{className:"home-priority-mission",children:[t.jsx("span",{className:"home-kicker",children:u("WORK IN MOTION")}),t.jsxs("div",{children:[t.jsxs("span",{className:"home-status",children:[t.jsx("span",{}),u(ne?.status||"Ready for your next idea")]}),t.jsxs("span",{children:[je,"%"]})]}),t.jsx("h3",{children:ne?.name||u("Your next great project")}),t.jsx("i",{className:"home-priority-progress",children:t.jsx("b",{style:{width:`${je}%`}})}),t.jsxs("button",{onClick:()=>e("Missions",ne?.id),children:[u("Open mission"),t.jsx(_i,{size:16})]})]})]})]}),t.jsxs("footer",{className:"home-conductor-footer",children:[V&&t.jsxs("div",{className:"home-conductor-selection",children:[t.jsx(qt,{agent:V,small:!0}),t.jsxs("button",{onClick:()=>n(V),children:[t.jsx("strong",{children:u(V.name)}),t.jsx("span",{children:u(V.lastTask)})]}),t.jsx("button",{className:"home-chat-link","aria-label":`${u("Chat with")}: ${u(V.name)}`,onClick:()=>s(V.id),children:t.jsx(yi,{size:18})})]}),t.jsxs("button",{className:"home-conductor-total",onClick:()=>e("Tasks"),children:[t.jsx("strong",{children:ue(Y)}),t.jsxs("span",{children:[u("WORK DELIVERED"),t.jsx("small",{children:u("completed agent tasks")})]}),t.jsx(_i,{size:18})]})]})]}),l]})}const fX={agents:[],tasks:[],activity:[]},Np=a=>(a/1e9).toFixed(a>=1e11?0:1),pX=a=>a>=1e6?`${(a/1e6).toFixed(1)} Mbps`:`${Math.round(a/1e3)} kbps`,mX=a=>new Date(a+"T12:00:00Z").toLocaleDateString(Hn(),{month:"short",day:"2-digit",timeZone:"UTC"}),Dp=[{name:"Overview",icon:yU},{name:"Approval Inbox",icon:Jd},{name:"Mail",icon:ei},{name:"Agents",icon:tm},{name:"Tasks",icon:ol},{name:"Chat",icon:yi},{name:"Schedule",icon:Ds},{name:"Automations",icon:Fs},{name:"Productivity",icon:GU},{name:"Skills",icon:Ha},{name:"Integrations",icon:Vc},{name:"System",icon:eU},{name:"Missions",icon:Ns},{name:"Docs",icon:Si},{name:"Files",icon:dy},{name:"Terminal",icon:w2},{name:"Agent City",icon:sU},{name:"Settings",icon:rs}],GN=[{name:"Team",icon:qU,pages:["Agents","Agent City","Skills"]},{name:"Automation",icon:Fs,pages:["Schedule","Automations"]}],gX=["Overview","Approval Inbox","Mail","Team","Chat","Missions","Tasks","Docs","Files","Automation","Productivity","Integrations"],rT=a=>GN.find(e=>e.pages.includes(a))?.name||null;function oT({status:a}){return t.jsxs("span",{className:`badge ${a.toLowerCase().replaceAll(" ","-")}`,children:[t.jsx("i",{}),u(a)]})}function vX({agents:a,usage:e}){const n=!!e,s=a.map(m=>({agent:m,model:m.model,...e?.[m.id]||{input:0,output:0}})),o=s.reduce((m,p)=>m+p.input,0),l=s.reduce((m,p)=>m+p.output,0),d=o+l,h=m=>m.toLocaleString(Hn());return t.jsxs("section",{className:"panel token-usage",children:[t.jsxs("div",{className:"panel-title",children:[t.jsxs("div",{children:[t.jsx("h2",{children:u("Agent token usage")}),t.jsx("p",{children:u("Cloud model consumption across your team.")})]}),t.jsx("span",{className:"token-snapshot",children:u(n?"Live usage · all time":"Loading usage…")})]}),t.jsxs("div",{className:"token-summary",children:[t.jsxs("div",{children:[t.jsx("span",{children:u("Total tokens")}),t.jsx("strong",{children:u(h(d))}),t.jsx("small",{children:u("Input + output")})]}),t.jsxs("div",{children:[t.jsx("span",{children:u("Input tokens")}),t.jsx("strong",{children:u(h(o))}),t.jsx("small",{children:u("Prompts and context")})]}),t.jsxs("div",{children:[t.jsx("span",{children:u("Output tokens")}),t.jsx("strong",{children:u(h(l))}),t.jsx("small",{children:u("Model responses")})]})]}),t.jsx("div",{className:"task-table token-table",tabIndex:0,role:"region","aria-label":u("Token usage by agent"),children:t.jsxs("table",{children:[t.jsx("thead",{children:t.jsxs("tr",{children:[t.jsx("th",{scope:"col",children:u("Agent")}),t.jsx("th",{scope:"col",children:u("AI model")}),t.jsx("th",{scope:"col",children:u("Input tokens")}),t.jsx("th",{scope:"col",children:u("Output tokens")}),t.jsx("th",{scope:"col",children:u("Total tokens")}),t.jsx("th",{scope:"col",children:u("Share of usage")})]})}),t.jsx("tbody",{children:s.map(({agent:m,model:p,input:y,output:v})=>{const x=y+v,S=d?x/d*100:0;return t.jsxs("tr",{children:[t.jsx("th",{scope:"row",children:t.jsxs("span",{className:"table-agent",children:[t.jsx(qt,{agent:m,small:!0}),m.name]})}),t.jsx("td",{children:u(p)}),t.jsx("td",{className:"token-number",children:u(h(y))}),t.jsx("td",{className:"token-number",children:u(h(v))}),t.jsx("td",{className:"token-number token-total",children:u(h(x))}),t.jsx("td",{children:t.jsxs("span",{className:"token-share",children:[t.jsx("span",{className:"token-share-track","aria-hidden":"true",children:t.jsx("i",{style:{width:`${S}%`}})}),t.jsxs("span",{children:[u(S.toFixed(1)),u("%")]})]})})]},m.id)})})]})}),t.jsxs("div",{className:"token-note",children:[t.jsx(Em,{size:16}),t.jsx("p",{children:u("Input and output tokens your agents used for chat replies and scheduled jobs, read from each agent’s own Hermes records.")})]})]})}function xX({color:a="var(--chart-resource)",variant:e=0}){const n=["0,31 12,26 24,29 36,18 48,22 60,10 72,15 84,3 96,8 110,1","0,30 12,29 24,17 36,20 48,15 60,22 72,9 84,13 96,3 110,6","0,20 12,14 24,22 36,15 48,19 60,6 72,10 84,5 96,12 110,3"];return t.jsx("svg",{className:"spark",viewBox:"0 0 112 38","aria-hidden":"true",children:t.jsx("polyline",{points:n[e%3],fill:"none",stroke:a,strokeWidth:"2",strokeLinejoin:"round",strokeLinecap:"round"})})}function yX({series:a,resource:e=!1}){const n=e?a.filter(M=>M.value!==null):a,s=n.length>1?n:n.length===1?[n[0],n[0]]:Array.from({length:7},(M,w)=>({date:new Date(Date.now()-(6-w)*864e5).toISOString().slice(0,10),value:0})),o=s.map(M=>M.value??0),l=o.length,d=e?"var(--chart-resource)":"var(--chart-throughput)",h=Math.max(...o,e?0:4),m=e?Math.max(20,Math.ceil(h/20)*20):Math.max(4,Math.ceil(h/4)*4),p=o.map((M,w)=>({x:l>1?w*580/(l-1):290,y:160-M/m*160})),y=l>1?580/(l-1)/2.4:0,v=p.map((M,w)=>w===0?`M ${M.x},${M.y}`:`C ${p[w-1].x+y},${p[w-1].y} ${M.x-y},${M.y} ${M.x},${M.y}`).join(" "),x=n.length===1?[0]:l<=7?s.map((M,w)=>w):[0,1,2,3,4,5,6].map(M=>Math.round(M*(l-1)/6)),S=s.map(M=>mX(M.date));return t.jsxs("div",{className:"throughput",children:[t.jsx("div",{className:"axis-y",children:[m,m*.75,m*.5,m*.25,0].map((M,w)=>t.jsxs("span",{children:[u(Math.round(M)),u(e?"%":"")]},w))}),t.jsxs("div",{className:"graph",children:[t.jsxs("svg",{viewBox:"0 0 580 160",preserveAspectRatio:"none",role:"img","aria-label":u(e?"Average CPU load per day":`Tasks completed over the last ${l} days`),children:[t.jsx("defs",{children:t.jsxs("linearGradient",{id:e?"chart-fill-r":"chart-fill",x1:"0",y1:"0",x2:"0",y2:"1",children:[t.jsx("stop",{offset:"0%",stopColor:d,stopOpacity:".18"}),t.jsx("stop",{offset:"100%",stopColor:d,stopOpacity:"0"})]})}),u([0,40,80,120,160].map(M=>t.jsx("line",{x1:"0",x2:"580",y1:M,y2:M,stroke:"var(--chart-grid)",strokeDasharray:"3 6"},M))),t.jsx("path",{d:`${v} L ${p[l-1].x},160 L ${p[0].x},160 Z`,fill:`url(#${e?"chart-fill-r":"chart-fill"})`}),t.jsx("path",{d:v,fill:"none",stroke:d,strokeWidth:"2.8"}),p.map((M,w)=>(l<=7||x.includes(w))&&t.jsx("circle",{cx:M.x,cy:M.y,r:w===l-1?4:3,fill:d,stroke:"var(--panel)",strokeWidth:"2",children:t.jsx("title",{children:u(`${S[w]}: ${s[w].value===null?"no reading":o[w]+(e?"% CPU":o[w]===1?" task":" tasks")}`)})},w))]}),t.jsx("div",{className:"axis-x",children:x.map(M=>t.jsx("span",{children:u(S[M])},M))})]})]})}function bX(){const a=mu();Au(),Nl(),Bi();const e=bh().length,[n,s]=C.useState("light");C.useEffect(()=>{const W=window.matchMedia("(prefers-color-scheme: dark)"),U=()=>{const ce=a.theme==="system"?W.matches?"dark":"light":a.theme;document.documentElement.dataset.theme=ce,document.documentElement.dataset.density=a.density,document.documentElement.dataset.reduceMotion=String(a.reduceMotion),document.documentElement.lang=a.language,s(ce)};return U(),W.addEventListener("change",U),()=>W.removeEventListener("change",U)},[a.theme,a.language,a.density,a.reduceMotion]);function o(){const W=n==="dark"?"light":"dark";$p({theme:W});try{localStorage.setItem("laboratorio-theme",W)}catch{}}const[l,d]=C.useState(Da().landing),[h,m]=C.useState(fX),[p,y]=C.useState(0),[v,x]=C.useState(!1),[S,M]=C.useState(!1),[w,E]=C.useState(""),[A,k]=C.useState(""),[R,N]=C.useState("All agents"),[I,z]=C.useState(""),[j,L]=C.useState(!0),[D,P]=C.useState(null),[F,q]=C.useState(""),[J,ie]=C.useState(null),[Q,V]=C.useState(null),[$,te]=C.useState("agent-orchestrator"),[ne,Y]=C.useState(!1),[T,_]=C.useState(30),[ve,je]=C.useState("To do"),[Je,xe]=C.useState(()=>rT(Da().landing)||"Team");C.useEffect(()=>{const W=rT(l);W&&xe(W)},[l]);const[ee,Ce]=C.useState(null),[Ze,le]=C.useState(""),[qe,xt]=C.useState(""),[se,Pe]=C.useState(""),[mt,it]=C.useState(""),[at,Be]=C.useState("rename"),[We,ue]=C.useState("");C.useEffect(()=>{if(!We)return;const W=ce=>{ce.target.closest(".agent-card-menu")||ue("")},U=ce=>{ce.key==="Escape"&&ue("")};return document.addEventListener("mousedown",W),document.addEventListener("keydown",U),()=>{document.removeEventListener("mousedown",W),document.removeEventListener("keydown",U)}},[We]);const ft=C.useRef(l);ft.current=l,C.useEffect(()=>{let W=!0;const U=()=>na("/api/system",{cache:"no-store"}).then(G=>G.ok?G.json():null).then(G=>{W&&G&&Ce(G)}).catch(()=>{});U();const ce=setInterval(U,3e4);return()=>{W=!1,clearInterval(ce)}},[]);const Re=new Date().toLocaleDateString(Hn(),{month:"short",day:"2-digit",year:"numeric"}),K=C.useRef(!1),B=C.useRef(null),pe=W=>{Da().showToasts&&(k(W),B.current&&clearTimeout(B.current),B.current=setTimeout(()=>k(""),3500))};async function Ae(){E("");try{const W=await na("/api/workspace",{cache:"no-store"}),U=await W.json();if(!W.ok)throw new Error(U.error);m(U.data),y(U.version),x(!0)}catch(W){E(W.message),x(!1)}}C.useEffect(()=>(Ae(),()=>{B.current&&clearTimeout(B.current)}),[]),C.useEffect(()=>{const W=setInterval(async()=>{if(!(K.current||document.hidden))try{const U=await na("/api/workspace",{cache:"no-store"});if(!U.ok||K.current)return;const ce=await U.json();m(ce.data),y(ce.version),x(!0)}catch{}},5e3);return()=>clearInterval(W)},[]),C.useEffect(()=>{const W=()=>{const U=decodeURIComponent(location.hash.slice(1)),ce=Dp.find(G=>G.name.toLowerCase().replaceAll(" ","-")===U);if(ce&&ce.name!==ft.current){const G=()=>{ft.current=ce.name,d(ce.name),history.replaceState(null,"",`#${ce.name.toLowerCase().replaceAll(" ","-")}`)},ke=new CustomEvent("laboratorio:before-navigate",{cancelable:!0,detail:{proceed:G}});window.dispatchEvent(ke)?G():history.replaceState(null,"",`#${ft.current.toLowerCase().replaceAll(" ","-")}`)}};return W(),window.addEventListener("hashchange",W),()=>window.removeEventListener("hashchange",W)},[]);function Ne(W){if(W===ft.current){Y(!1);return}const U=()=>{ft.current=W,d(W),location.hash=W.toLowerCase().replaceAll(" ","-"),z(""),Y(!1),window.scrollTo({top:0,behavior:"instant"})},ce=new CustomEvent("laboratorio:before-navigate",{cancelable:!0,detail:{proceed:U}});window.dispatchEvent(ce)&&U()}async function be(W,U){if(!v||K.current)return!1;K.current=!0,M(!0),E("");try{const ce=await na("/api/workspace",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({data:W,version:p})}),G=await ce.json();if(!ce.ok)throw new Error(G.error);return m(G.data),y(G.version),pe(U),!0}catch(ce){return E(ce.message),!1}finally{K.current=!1,M(!1)}}function ot(W,U,ce,G="updated"){return{...W,activity:[{id:crypto.randomUUID(),agentId:U,text:ce,time:new Date().toISOString(),type:G},...W.activity].slice(0,200)}}async function Ve(W,U){const ce=h.tasks.find(pt=>pt.id===W);if(!ce||ce.status===U)return;const G={...h,tasks:h.tasks.map(pt=>pt.id===W?{...pt,status:U}:pt)};await be(ot(G,"workspace",`${U==="Done"?"finished a to-do:":`moved a to-do to ${U}:`} ${ce.title}`,"updated"),`Task moved to ${U}`)}async function ut(W){const U=h.tasks.find(G=>G.id===W);if(!U)return;await be(ot({...h,tasks:h.tasks.filter(G=>G.id!==W)},"workspace",`deleted a to-do: ${U.title}`,"updated"),"Task deleted")!==!1&&(q(""),P(null))}async function re(W){const U=W.status==="Paused"?"Idle":"Paused";await be(ot({...h,agents:h.agents.map(G=>G.id===W.id?{...G,status:U}:G)},W.id,U==="Paused"?"was paused":"was resumed"),U==="Paused"?"Agent paused":"Agent resumed")&&J?.id===W.id&&ie({...W,status:U})}async function Se(W){W.preventDefault();const U=new FormData(W.currentTarget),ce=String(U.get("title")).trim();if(!ce)return;const G={id:crypto.randomUUID(),title:ce,description:String(U.get("description")).trim(),agentId:"",priority:String(U.get("priority")),status:ve,created:new Date().toISOString()};await be(ot({...h,tasks:[G,...h.tasks]},"workspace",ve==="Done"?`finished a to-do: ${ce}`:`added a to-do: ${ce}`,"created"),`Task added to ${ve}`)&&(P(null),V(null))}const He=h.tasks.filter(W=>W.status==="Done").length,lt=h.agents.filter(W=>(R==="All agents"||W.status===R)&&`${W.name} ${W.model} ${W.role}`.toLowerCase().includes(I.toLowerCase())),tt=h.tasks.filter(W=>`${W.title} ${W.description}`.toLowerCase().includes(I.toLowerCase())),ct=(W=5,U)=>t.jsxs("div",{className:"event-list",children:[h.activity.filter(ce=>!U||ce.agentId===U).slice(0,W).map((ce,G)=>{const ke=h.agents.find(pt=>pt.id===ce.agentId);return t.jsxs("div",{className:"event",children:[t.jsx("div",{className:"event-mark",children:u(ke?t.jsx(qt,{agent:ke,small:!0}):t.jsx(ol,{size:18}))}),t.jsxs("div",{children:[t.jsxs("p",{children:[t.jsx("strong",{children:u(ke?.name||"You")})," ",ce.text]}),t.jsxs("span",{children:[new Date(ce.time).toLocaleTimeString(Hn(),Kd({hour:"2-digit",minute:"2-digit"})),u(" · "),new Date(ce.time).toLocaleDateString(Hn(),{month:"short",day:"numeric"})]})]}),u(ce.type==="completed"&&t.jsx($a,{className:"event-check",size:16}))]},ce.id)}),U&&!h.activity.some(ce=>ce.agentId===U)&&t.jsx("p",{className:"empty",children:u("No activity recorded for this agent yet.")})]}),fe=(W=!1)=>t.jsxs("section",{className:"panel heat-panel",children:[t.jsxs("div",{className:"panel-title",children:[t.jsxs("div",{children:[t.jsx("h2",{children:u("Agent activity")}),t.jsx("p",{children:u("Daily contributions across your team.")})]}),t.jsxs("select",{"aria-label":u("Heat map period"),value:T,onChange:U=>_(Number(U.target.value)),children:[t.jsx("option",{value:30,children:u("Last 30 days")}),t.jsx("option",{value:7,children:u("Last 7 days")})]})]}),t.jsx("div",{className:"heat-scroll",ref:U=>{U&&!U.dataset.atEnd&&U.scrollWidth>U.clientWidth&&(U.scrollLeft=U.scrollWidth,U.dataset.atEnd="1")},children:t.jsxs("div",{className:"heat-grid",style:{"--days":T},children:[t.jsx("div",{className:"heat-month",children:(()=>{const U=ke=>new Date(Date.now()-ke*864e5).toLocaleDateString(Hn(),{month:"long"}),ce=U(T-1),G=U(0);return ce===G?ce:t.jsxs(t.Fragment,{children:[u(ce)," ",t.jsx("span",{children:u(G)})]})})()}),h.agents.map(U=>t.jsxs("div",{className:"heat-row",children:[t.jsxs("div",{className:"heat-agent",children:[t.jsx(qt,{agent:U,small:!0}),t.jsx("span",{children:U.name})]}),Array.from({length:T},(ce,G)=>{const ke=new Date(Date.now()-(T-1-G)*864e5),pt=ee?.heatmap[U.id]?.[ke.toISOString().slice(0,10)]||0,Mt=pt===0?0:pt<2?1:pt<4?2:pt<7?3:4;return t.jsx("span",{className:`heat-cell h${Mt}`,title:`${U.name} · ${ke.toLocaleDateString(Hn(),{month:"short",day:"numeric"})} · ${pt} ${pt===1?"event":"events"}`,"aria-label":`${U.name}: ${pt} ${pt===1?"event":"events"} on ${ke.toLocaleDateString(Hn(),void 0)}`},G)})]},U.id))]})}),t.jsxs("div",{className:"heat-footer",children:[t.jsxs("span",{children:[t.jsx("span",{className:"tiny-dot"}),u("Live activity · updated "),u(Re)]}),t.jsxs("div",{children:[u("Less "),u([0,1,2,3,4].map(U=>t.jsx("span",{className:`heat-cell h${U}`},U))),u(" More")]})]})]});function oe(W,U="To do"){V(W||null),je(U),P("task")}const Fe=W=>t.jsxs("article",{className:`agent-card agent-${W.color} opens-chat`,title:u(`Chat with ${W.name}`),onClick:U=>{U.target.closest("button,a,select,input,textarea,label,[role=menu]")||lo(W.id)},children:[t.jsxs("div",{className:"agent-card-top",children:[t.jsx(qt,{agent:W}),t.jsx(oT,{status:W.status}),t.jsxs("span",{className:"agent-card-menu",children:[t.jsx("button",{className:"icon-btn","aria-haspopup":"menu","aria-expanded":We===W.id,"aria-label":u(`Options for ${W.name}`),onClick:()=>ue(U=>U===W.id?"":W.id),children:t.jsx($1,{size:19})}),We===W.id&&t.jsxs("span",{className:"agent-card-dropdown",role:"menu",children:[t.jsx("button",{role:"menuitem",onClick:()=>{ue(""),ie(W),P("details")},children:u("Details")}),t.jsx("button",{role:"menuitem",onClick:()=>{ue(""),Be("rename"),Pe(W.id)},children:u("Rename")}),W.id!=="agent-orchestrator"&&t.jsx("button",{role:"menuitem",className:"danger",onClick:()=>{ue(""),Be("retire"),Pe(W.id)},children:u("Retire")})]})]})]}),t.jsx("button",{className:"agent-name",onClick:()=>lo(W.id),children:W.name}),t.jsx("p",{className:"role",children:u(W.role)}),t.jsxs("button",{className:"model model-select-action",onClick:()=>le(W.id),"aria-label":u(`Change AI model for ${W.name}`),children:[t.jsx("span",{className:`model-symbol ${W.model.startsWith("Claude")?"claude":""}`,children:u(W.model.startsWith("Claude")?"✳":"◈")}),W.model,t.jsx(Fd,{size:12})]}),t.jsxs("button",{className:"agent-skills-link",onClick:()=>{xt(W.id),Ne("Skills")},children:[t.jsx(Ha,{size:13}),u("Skills "),t.jsx("span",{children:u(Object.values(hu(W.id).skills).filter(U=>U.enabled).length)})]}),t.jsxs("div",{className:"last-task",children:[t.jsx("span",{children:u("LAST TASK")}),t.jsxs("p",{children:[t.jsx(ol,{size:14}),u(W.lastTask)]})]}),t.jsxs("footer",{children:[t.jsxs("span",{children:[t.jsx(nl,{size:15}),u(W.completed),u(W.completed===1?" task":" tasks")]}),t.jsx("span",{children:u(W.success?`${W.success}% success`:"No results yet")}),t.jsxs("button",{className:"agent-chat-action",onClick:()=>lo(W.id),"aria-label":u(`Chat with ${W.name}`),children:[t.jsx(yi,{size:14}),u("Chat")]}),t.jsxs("button",{className:"agent-action","aria-label":u(W.status==="Paused"?`Resume ${W.name}`:`Pause ${W.name}`),disabled:!v||S,onClick:()=>re(W),children:[u(W.status==="Paused"?t.jsx(gi,{size:15}):t.jsx(nu,{size:15})),t.jsx("span",{children:u(W.status==="Paused"?"Resume":"Pause")})]})]})]},W.id),Xe=()=>t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"lower-grid",children:[u(fe()),t.jsxs("section",{className:"panel activity-panel",children:[t.jsxs("div",{className:"panel-title",children:[t.jsxs("div",{children:[t.jsx("span",{className:"panel-kicker",children:u("WORKSPACE FEED")}),t.jsx("h2",{children:u("Recent activity")})]}),t.jsx("button",{className:"text-btn",onClick:()=>{N("All agents"),Ne("Agents")},children:u("View log")})]}),u(ct(4)),t.jsxs("div",{className:"activity-foot",children:[t.jsx(ts,{size:13}),u("Activity is recorded across your team")]})]})]}),t.jsxs("section",{className:"team-section",children:[t.jsxs("div",{className:"section-heading",children:[t.jsxs("div",{children:[t.jsxs("h2",{children:[u("Your team "),t.jsx("span",{children:u(h.agents.length)})]}),t.jsx("p",{className:"section-description",children:u("Specialists working across your workspace")})]}),t.jsx("button",{className:"text-btn",onClick:()=>{N("All agents"),Ne("Agents")},children:u("All agents")})]}),t.jsx("div",{className:"agent-grid overview-agents",children:u(h.agents.slice(0,4).map(Fe))})]})]}),dt=W=>t.jsxs("article",{className:"task-card",draggable:!S&&v,onDragStart:U=>U.dataTransfer.setData("text/plain",W.id),children:[t.jsxs("div",{className:"task-top",children:[t.jsxs("span",{className:`priority ${W.priority.toLowerCase()}`,children:[t.jsx("span",{}),u(W.priority)]}),t.jsx("button",{className:"icon-btn","aria-label":u(`View ${W.title}`),onClick:()=>oe(W),children:t.jsx($1,{size:18})})]}),t.jsx("button",{className:"task-name",onClick:()=>oe(W),children:W.title}),t.jsx("p",{children:W.description}),t.jsxs("footer",{children:[t.jsxs("span",{children:[t.jsx(mU,{size:15})," ",u(W.id.startsWith("task-")?"ACD-"+W.id.slice(5).padStart(3,"0"):"ACD-"+W.id.slice(0,4).toUpperCase())]}),t.jsx("select",{disabled:S||!v,"aria-label":u(`Status for ${W.title}`),value:W.status,onChange:U=>Ve(W.id,U.target.value),children:Bf.map(U=>t.jsx("option",{value:U,children:u(U)},U))})]})]},W.id);return t.jsxs("div",{className:`app-shell view-${l.toLowerCase().replaceAll(" ","-")}`,children:[ne&&t.jsx("button",{className:"nav-scrim","aria-label":u("Close navigation"),onClick:()=>Y(!1)}),t.jsx(zY,{agents:h.agents,hidden:l==="Chat",onOpenChatTab:W=>{te(W),Ne("Chat")}}),t.jsxs("aside",{className:`sidebar ${ne?"mobile-open":""}`,children:[t.jsxs("a",{href:"#overview",className:"brand",onClick:()=>Ne("Overview"),children:[t.jsx("span",{className:"brand-icon",children:t.jsx(Fs,{size:24})}),u("LABORATORIO")]}),t.jsxs("div",{className:"workspace",children:[t.jsx("span",{className:"workspace-avatar",children:u("A")}),t.jsxs("div",{children:[t.jsx("strong",{children:u(a.workspaceName||"My workspace")}),t.jsx("span",{children:u("Personal")})]}),t.jsx(Fd,{size:14,className:"workspace-chevron"})]}),t.jsxs("nav",{className:"grouped-nav","aria-label":u("Workspace navigation"),children:[gX.map(W=>{const U=GN.find(ke=>ke.name===W);if(!U){const ke=Dp.find(pt=>pt.name===W);return t.jsxs("button",{"aria-current":l===W?"page":void 0,className:l===W?"active":"",onClick:()=>Ne(W),children:[t.jsx(ke.icon,{size:19}),t.jsx("span",{children:u(W)}),W==="Approval Inbox"&&t.jsx("em",{"aria-label":u("Waiting approvals"),children:e})]},W)}const ce=Je===U.name,G=U.pages.includes(l);return t.jsxs("div",{className:`nav-group ${ce?"is-open":""}`,children:[t.jsxs("button",{className:`nav-group-toggle ${G?"contains-active":""}`,"aria-expanded":ce,"aria-controls":`nav-${U.name.toLowerCase()}`,onClick:()=>xe(ce?null:U.name),children:[t.jsx(U.icon,{size:19}),t.jsx("span",{children:u(U.name)}),U.name==="Team"&&t.jsx("em",{children:h.agents.length}),t.jsx(Fd,{size:14,className:`nav-group-chevron ${ce?"expanded":""}`})]}),t.jsx("div",{id:`nav-${U.name.toLowerCase()}`,className:"nav-group-pages",hidden:!ce,children:U.pages.map(ke=>{const pt=Dp.find(Mt=>Mt.name===ke);return t.jsxs("button",{"aria-current":l===ke?"page":void 0,className:l===ke?"active":"",onClick:()=>Ne(ke),children:[t.jsx(pt.icon,{size:17}),t.jsx("span",{children:u(ke)})]},ke)})})]},U.name)}),t.jsx("div",{className:"nav-utilities",children:Dp.filter(W=>["System","Terminal"].includes(W.name)).map(W=>t.jsxs("button",{"aria-current":l===W.name?"page":void 0,className:l===W.name?"active":"",onClick:()=>Ne(W.name),children:[t.jsx(W.icon,{size:17}),t.jsx("span",{children:u(W.name)})]},W.name))})]}),t.jsxs("div",{className:"sidebar-bottom",children:[t.jsxs("button",{className:`nav-settings ${l==="Settings"?"active":""}`,"aria-current":l==="Settings"?"page":void 0,onClick:()=>Ne("Settings"),children:[t.jsx(rs,{size:17}),t.jsx("span",{children:u("Settings")})]}),t.jsx("button",{className:"nav-help","aria-label":u("Help & shortcuts"),title:u("Help & shortcuts"),onClick:()=>P("help"),children:t.jsx(ly,{size:18})})]})]}),t.jsx(oW,{agent:h.agents.find(W=>W.id===Ze),data:h,onSave:be,onClose:()=>le("")}),t.jsxs("div",{className:"main-shell",children:[t.jsxs("header",{className:"topbar",children:[t.jsxs("div",{className:"breadcrumb",children:[t.jsx("button",{className:"icon-btn mobile-toggle",onClick:()=>Y(!ne),"aria-label":u("Toggle navigation"),children:t.jsx(jU,{size:21})}),t.jsx("span",{children:u("Workspace")}),t.jsx(nm,{size:14}),t.jsx("strong",{children:u(l)})]}),t.jsxs("div",{className:"topbar-right",children:[t.jsx(mY,{onOpen:()=>Ne("Settings")}),t.jsx(lX,{onOpen:()=>Ne("Settings")}),t.jsx(FY,{onOpen:(W,U,ce)=>{if(Ne(W),qw(W,U,ce),W==="Agents"&&U&&ce==="models")le(U);else if(W==="Agents"&&U){const G=h.agents.find(ke=>ke.id===U);G&&(ie(G),P("details"))}else W==="Chat"&&U&&te(U)}}),t.jsxs("button",{className:"theme-toggle",onClick:o,"aria-label":u(n==="dark"?"Switch to light theme":"Switch to dark theme"),title:u(n==="dark"?"Switch to light theme":"Switch to dark theme"),children:[u(n==="dark"?t.jsx(py,{size:17}):t.jsx(qj,{size:17})),t.jsx("span",{children:u(n==="dark"?"Light mode":"Dark mode")})]}),t.jsxs("span",{className:"demo-pill",children:[t.jsx("span",{}),u("Live")]})]})]}),t.jsxs("main",{children:[l!=="Schedule"&&l!=="Agent City"&&l!=="Overview"&&t.jsxs("div",{className:"page-heading",children:[t.jsxs("div",{children:[t.jsxs("div",{className:"eyebrow",children:[t.jsx("span",{}),u("WORKSPACE / "),u(l.toUpperCase())]}),t.jsx("h1",{children:u(l==="Overview"?"Overview":l==="Agents"?"Agent fleet":l==="Tasks"?"Task board":l==="Chat"?"Team chat":l==="Productivity"?"Your focus space":l==="Schedule"?"Schedule":l==="System"?"System health":l==="Agent City"?"Agent City":l)}),t.jsx("p",{children:u(l==="Overview"?"Your agents, their work, and the bigger picture.":l==="Agents"?`${h.agents.length} specialists. One coordinated workspace.`:l==="Tasks"?"Your personal to-dos, prioritized and moving.":l==="Chat"?"One conversation. The right expertise.":l==="Productivity"?"Clear your mind. Make room for your best work.":l==="Schedule"?"Put recurring work on a steady rhythm.":l==="System"?"Resource usage and the health of your environment.":l==="Approval Inbox"?"Your decisions keep the team moving.":l==="Automations"?"Turn everyday events into coordinated work.":l==="Missions"?"Turn a clear goal into coordinated work.":l==="Docs"?"Good work, saved and easy to find.":l==="Skills"?"Give every agent the right skills for the work.":l==="Settings"?"Your workspace, your preferences.":l==="Mail"?"Your inbox, sorted around what matters.":l==="Integrations"?"Your everyday tools, connected to your AI team.":l==="Files"?"The files that give your agents their direction.":l==="Terminal"?"Your server console, right inside the workspace.":"See your team and the work between them.")})]}),t.jsx("div",{className:"heading-actions",children:l==="Overview"?t.jsxs(t.Fragment,{children:[t.jsxs("span",{className:"date-label",children:[t.jsx(NT,{size:16}),u(Re)]}),t.jsxs("button",{className:"primary-btn",disabled:!v||S,onClick:()=>oe(),children:[t.jsx(jn,{size:17}),u("New task")]})]}):l==="Agents"?t.jsxs("span",{className:"resource-pill",children:[t.jsx(tm,{size:16}),u("Your core team · "),u(h.agents.length),u(" agents")]}):l==="Tasks"?t.jsxs("button",{className:"primary-btn",disabled:!v||S,onClick:()=>oe(),children:[t.jsx(jn,{size:17}),u("New task")]}):l==="System"?t.jsxs("span",{className:"resource-pill",children:[t.jsx(ts,{size:15}),u("Refreshes every 30s")]}):null})]}),w&&t.jsxs("div",{role:"alert",className:"error-banner",children:[u(w),t.jsx("button",{onClick:Ae,children:u("Reload workspace")})]}),l==="Overview"&&t.jsx(hX,{data:h,onNavigate:(W,U,ce)=>{Ne(W),qw(W,U,ce)},onAgent:W=>lo(W.id),onChat:W=>{te(W),Ne("Chat")},onTask:()=>oe(),below:Xe()}),l==="Agents"&&t.jsxs(t.Fragment,{children:[t.jsx(XY,{data:h,onReload:Ae,selectedId:se,mode:at,onClose:()=>{Pe(""),Be("rename")}}),t.jsxs("div",{className:"section-heading agent-toolbar",children:[t.jsx("div",{className:"filter-tabs",children:["All agents","Working","Idle","Paused"].map(W=>t.jsxs("button",{"aria-pressed":R===W,className:R===W?"selected":"",onClick:()=>N(W),children:[u(W),t.jsx("span",{children:u(W==="All agents"?h.agents.length:h.agents.filter(U=>U.status===W).length)})]},W))}),t.jsxs("label",{className:"search-input",children:[t.jsx(vo,{size:17}),t.jsx("input",{"aria-label":u("Search agents"),placeholder:u("Search agents..."),value:I,onChange:W=>z(W.target.value)})]})]}),t.jsx("div",{className:"agent-grid",children:u(lt.map(Fe))}),lt.length===0&&t.jsx("p",{className:"empty",children:u("No agents match your search.")}),t.jsx("div",{className:"agents-activity",children:u(fe(!0))}),t.jsxs("section",{className:"panel full-log",children:[t.jsxs("div",{className:"panel-title",children:[t.jsx("h2",{children:u("Activity log")}),t.jsxs("span",{className:"muted",children:[u(h.activity.length),u(" events")]})]}),u(ct(200))]})]}),l==="Tasks"&&t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"task-overview-strip",children:[t.jsxs("span",{children:[t.jsx(ol,{size:17}),t.jsx("strong",{children:u(h.tasks.length)}),u(" total tasks")]}),t.jsxs("span",{children:[t.jsx(ts,{size:17}),t.jsx("strong",{children:u(h.tasks.filter(W=>W.status==="In progress").length)}),u(" in progress")]}),t.jsxs("span",{children:[t.jsx($a,{size:17}),t.jsx("strong",{children:u(He)}),u(" completed")]}),t.jsxs("span",{className:"task-progress",children:[u(Math.round(He/h.tasks.length*100)||0),u("% complete "),t.jsx("i",{children:t.jsx("b",{style:{width:`${He/h.tasks.length*100||0}%`}})})]})]}),t.jsxs("div",{className:"section-heading",children:[t.jsxs("div",{className:"segmented",children:[t.jsxs("button",{className:j?"selected":"",onClick:()=>L(!0),children:[t.jsx(cU,{size:16}),u("Board")]}),t.jsxs("button",{className:j?"":"selected",onClick:()=>L(!1),children:[t.jsx(wj,{size:16}),u("List")]})]}),t.jsxs("label",{className:"search-input",children:[t.jsx(vo,{size:17}),t.jsx("input",{"aria-label":u("Search tasks"),value:I,onChange:W=>z(W.target.value),placeholder:u("Search tasks...")})]})]}),j?t.jsx("div",{className:"kanban",children:Bf.map((W,U)=>t.jsxs("section",{className:`kanban-column col-${U}`,onDragOver:ce=>ce.preventDefault(),onDrop:ce=>{ce.preventDefault(),Ve(ce.dataTransfer.getData("text/plain"),W)},children:[t.jsxs("div",{className:"column-heading",children:[t.jsx("span",{className:"column-dot"}),t.jsx("h2",{children:u(W)}),t.jsx("span",{children:u(tt.filter(ce=>ce.status===W).length)}),t.jsx("button",{className:"icon-btn","aria-label":u(`Create task for ${W}`),disabled:!v||S,onClick:()=>oe(void 0,W),children:t.jsx(jn,{size:17})})]}),u(tt.filter(ce=>ce.status===W).map(dt)),!tt.some(ce=>ce.status===W)&&t.jsx("div",{className:"column-empty",children:u("Drop a task here")})]},W))}):t.jsx("div",{className:"panel task-table",children:t.jsxs("table",{children:[t.jsx("thead",{children:t.jsxs("tr",{children:[t.jsx("th",{children:u("Task")}),t.jsx("th",{children:u("Priority")}),t.jsx("th",{children:u("Status")})]})}),t.jsx("tbody",{children:tt.map(W=>t.jsxs("tr",{children:[t.jsx("td",{children:t.jsx("button",{className:"task-name",onClick:()=>oe(W),children:W.title})}),t.jsx("td",{children:t.jsx("span",{className:`priority ${W.priority.toLowerCase()}`,children:u(W.priority)})}),t.jsx("td",{children:t.jsx("select",{disabled:!v||S,"aria-label":u(`Status for ${W.title}`),value:W.status,onChange:U=>Ve(W.id,U.target.value),children:Bf.map(U=>t.jsx("option",{value:U,children:u(U)},U))})})]},W.id))})]})})]}),l==="System"&&t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"system-banner",children:[t.jsx("span",{className:"system-icon",children:t.jsx(za,{size:22})}),t.jsxs("div",{children:[t.jsx("h2",{children:u("Resource capacity")}),t.jsx("p",{children:u(ee?`Live readings from ${ee.environment.host}`:"Reading the machine…")})]}),t.jsxs("span",{className:"badge working",children:[t.jsx("i",{}),u(ee?"Live":"Loading")]})]}),t.jsx("div",{className:"resources-grid",children:[{name:"CPU usage",value:ee?.resources.cpu.percent??0,total:ee?`${ee.resources.cpu.cores} cores`:"…",detail:ee?`${ee.resources.cpu.used} busy`:"…",icon:cy,color:"var(--chart-resource)"},{name:"Memory",value:ee?.resources.memory.percent??0,total:ee?`of ${Np(ee.resources.memory.total)} GB`:"…",detail:ee?`${Np(ee.resources.memory.used)} GB used`:"…",icon:Lj,color:"var(--chart-throughput)"},{name:"Storage",value:ee?.resources.disk.percent??0,total:ee?`of ${Np(ee.resources.disk.total)} GB`:"…",detail:ee?`${Np(ee.resources.disk.used)} GB used`:"…",icon:tu,color:"var(--chart-storage)"},{name:"Network",value:Math.min(100,(ee?.resources.network.bps??0)>0?Math.max(1,Math.round((ee?.resources.network.bps??0)/1e7)):0),total:"right now",detail:ee?pX(ee.resources.network.bps):"…",icon:hy,color:"var(--chart-amber)"}].map(W=>t.jsxs("section",{className:`panel resource-card resource-${W.name.split(" ")[0].toLowerCase()}`,children:[t.jsxs("div",{className:"panel-title",children:[t.jsx("h2",{children:u(W.name)}),t.jsx(W.icon,{size:20})]}),t.jsxs("div",{className:"resource-number",children:[t.jsxs("strong",{children:[u(Math.round(W.value)),t.jsx("span",{children:u("%")})]}),t.jsx(xX,{color:W.color})]}),t.jsx("div",{className:"resource-bar",children:t.jsx("span",{style:{width:`${W.value}%`,background:W.color}})}),t.jsxs("div",{className:"resource-meta",children:[t.jsx("span",{children:u(W.detail)}),t.jsx("strong",{children:u(W.total)})]})]},W.name))}),t.jsxs("div",{className:"overview-grid",children:[t.jsxs("section",{className:"panel",children:[t.jsxs("div",{className:"panel-title",children:[t.jsxs("div",{children:[t.jsx("h2",{children:u("Resource history")}),t.jsx("p",{children:u("Average CPU load · last 7 days")})]}),t.jsx("span",{className:"muted",children:u("Sampled every 5 min")})]}),t.jsx(yX,{series:ee?.history||[],resource:!0})]}),t.jsxs("section",{className:"panel environment",children:[t.jsxs("div",{className:"panel-title",children:[t.jsx("h2",{children:u("Environment")}),t.jsx(cy,{size:18})]}),[["Host",ee?.environment.host||"…"],["Operating system",ee?.environment.os||"…"],["Agents",`${h.agents.length} on ${[...new Set(h.agents.map(W=>W.model))].join(", ")||"…"}`],["Hermes home",ee?.environment.hermesHome||"…"],["Workspace storage",v?"Connected":"Loading…"],["Machine uptime",ee?.environment.uptime||"…"]].map(([W,U])=>t.jsxs("div",{className:"environment-row",children:[t.jsx("span",{children:u(W)}),t.jsx("strong",{children:u(U)})]},W))]})]}),t.jsx(vX,{agents:h.agents,usage:ee?.tokens}),t.jsx(GY,{agents:h.agents})]}),u(l==="Schedule"&&t.jsx(oX,{agents:h.agents,disabled:!v||S,onWorkspaceChange:Ae,onOpenTask:async W=>{const U=await na("/api/workspace");if(U.ok){const ce=await U.json();m(ce.data),y(ce.version);const G=ce.data.tasks.find(ke=>ke.id===W);G&&(Ne("Tasks"),oe(G))}}})),u(l==="Missions"&&t.jsx(W8,{agents:h.agents,onChat:W=>{te(W),Ne("Chat")},onDoc:W=>{it(W),Ne("Docs")}})),u(l==="Docs"&&t.jsx(Y8,{agents:h.agents,initialId:mt,onInitialOpened:()=>it("")})),u(l==="Skills"&&t.jsx(rW,{agents:h.agents,initialAgent:qe,onModel:le})),l==="Approval Inbox"&&t.jsx(bY,{agents:h.agents}),l==="Mail"&&t.jsx(sY,{agents:h.agents,onNavigate:Ne,onCreateTodo:async W=>{if(!v)return!1;const U={id:crypto.randomUUID(),title:`Reply to ${W.sender}: ${W.subject}`,description:`From ${W.address} ${W.preview}`,agentId:"",priority:W.urgency>=8?"High":W.urgency>=5?"Medium":"Low",status:"To do",created:new Date().toISOString()};return be(ot({...h,tasks:[U,...h.tasks]},"workspace",`added a to-do from mail: ${W.subject}`,"created"),"To-do added from Mail")}}),l==="Automations"&&t.jsx(HY,{data:h,onSave:be}),u(l==="Settings"&&t.jsx(yY,{onRestored:async()=>{await Ae(),await Za(),await oh()}})),u(l==="Integrations"&&t.jsx($q,{agents:h.agents})),u(l==="Files"&&t.jsx(X8,{agents:h.agents})),u(l==="Terminal"&&t.jsx(J8,{agents:h.agents})),u(l==="Agent City"&&t.jsx(Xq,{agents:h.agents,onChat:W=>lo(W)})),u(l==="Chat"&&t.jsx(nX,{agents:h.agents,initialRoom:$,onModels:le})),t.jsx("div",{hidden:l!=="Productivity",children:t.jsx(iX,{tasks:h.tasks,agents:h.agents})}),l!=="Agent City"&&t.jsxs("footer",{className:"page-footer",children:[t.jsxs("span",{children:[t.jsx(Fs,{size:13}),u("Laboratorio workspace")]}),t.jsxs("span",{children:[u("Saved on your server · "),u(ee?.environment.host||"Laboratorio")]})]})]})]}),t.jsx(Tm,{open:D!==null,onOpenChange:W=>{W||(P(null),V(null))},children:t.jsxs(jm,{children:[t.jsx(Rm,{className:"modal-overlay"}),t.jsxs(km,{className:"modal-content",children:[t.jsx(zm,{className:"modal-close","aria-label":u("Close dialog"),children:t.jsx(da,{size:20})}),t.jsx("span",{className:"modal-symbol",children:u(D==="task"?t.jsx(ol,{size:25}):t.jsx(tm,{size:25}))}),t.jsx(Nm,{children:u(D==="task"?Q?"Task details":"Create a task":D==="help"?"A space for your team":J?.name)}),t.jsx(Dm,{children:u(D==="task"?"A personal to-do. Keep it short and clear.":D==="help"?"Meet Laboratorio, your AI agent workspace.":J?.role)}),D==="task"&&!Q&&t.jsxs("form",{onSubmit:Se,children:[t.jsxs(t.Fragment,{children:[t.jsxs("label",{children:[u("Task title"),t.jsx("input",{name:"title",required:!0,maxLength:160,placeholder:u("What needs to get done?"),autoFocus:!0})]}),t.jsxs("label",{children:[u("Description"),t.jsx("textarea",{name:"description",maxLength:2e3,placeholder:u("A little context goes a long way."),rows:3})]}),t.jsxs("label",{children:[u("Priority"),t.jsxs("select",{name:"priority",children:[t.jsx("option",{value:"Medium",children:u("Medium")}),t.jsx("option",{value:"High",children:u("High")}),t.jsx("option",{value:"Low",children:u("Low")})]})]}),t.jsxs("p",{className:"form-note",children:[u("This task will be added to "),t.jsx("strong",{children:u(ve)}),u(". Move it through the board as work progresses.")]})]}),t.jsxs("button",{className:"primary-btn form-submit",disabled:!v||S,children:[u(S?t.jsx(Jt,{size:16,className:"spinning"}):t.jsx(jn,{size:17})),u(" Create task")]}),w&&t.jsx("p",{role:"alert",className:"form-error",children:u(w)})]}),D==="details"&&J&&t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"detail-heading",children:[t.jsx(qt,{agent:J}),t.jsxs("div",{children:[t.jsx(oT,{status:J.status}),t.jsx("span",{className:"model",children:J.model})]}),t.jsxs("button",{className:"primary-btn detail-chat",onClick:()=>{lo(J.id),P(null)},children:[t.jsx(yi,{size:16}),u("Chat")]})]}),t.jsxs("div",{className:"detail-stats",children:[t.jsxs("span",{children:[t.jsx("strong",{children:u(J.completed)}),u("Completed tasks")]}),t.jsxs("span",{children:[t.jsxs("strong",{children:[u(J.success||"–"),u(J.success?"%":"")]}),u("Success rate")]})]}),t.jsxs("div",{className:"last-task",children:[t.jsx("span",{children:u("LAST TASK")}),t.jsx("p",{children:u(J.lastTask)})]}),t.jsx("h3",{className:"detail-title",children:u("Recent activity")}),u(ct(4,J.id)),t.jsxs("div",{className:"detail-actions",children:[t.jsxs("button",{className:"secondary-btn",onClick:()=>{te(J.id),P(null),Ne("Chat")},children:[t.jsx(yi,{size:16}),u("Chat")]}),t.jsxs("button",{className:"secondary-btn",disabled:!v||S,onClick:()=>re(J),children:[u(J.status==="Paused"?t.jsx(gi,{size:16}):t.jsx(nu,{size:16}))," ",u(J.status==="Paused"?"Resume agent":"Pause agent")]}),t.jsxs("button",{className:"secondary-btn",onClick:()=>{Be("rename"),Pe(J.id),P(null),Ne("Agents")},children:[t.jsx(Mr,{size:16}),u("Rename or retire")]})]})]}),D==="task"&&Q&&t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"task-detail",children:[t.jsxs("span",{className:`priority ${Q.priority.toLowerCase()}`,children:[u(Q.priority),u(" priority")]}),t.jsx("h3",{children:Q.title}),t.jsx("p",{children:u(Q.description||"No description added.")}),t.jsxs("div",{className:"environment-row",children:[t.jsx("span",{children:u("Created")}),t.jsx("strong",{children:new Date(Q.created).toLocaleString(Hn(),Kd({day:"numeric",month:"short",hour:"2-digit",minute:"2-digit"}))})]}),t.jsxs("label",{children:[u("Status"),t.jsx("select",{disabled:!v||S,value:h.tasks.find(W=>W.id===Q.id)?.status||Q.status,onChange:W=>Ve(Q.id,W.target.value),children:Bf.map(W=>t.jsx("option",{value:W,children:u(W)},W))})]}),t.jsx("div",{className:"task-delete-row",children:F===Q.id?t.jsxs(t.Fragment,{children:[t.jsx("span",{children:u("Delete this task for good?")}),t.jsx("button",{className:"secondary-btn",onClick:()=>q(""),children:u("Keep it")}),t.jsxs("button",{className:"ow-reject",disabled:!v||S,onClick:()=>ut(Q.id),children:[t.jsx(ti,{size:15}),u("Delete")]})]}):t.jsxs("button",{className:"text-btn task-delete",disabled:!v||S,onClick:()=>q(Q.id),children:[t.jsx(ti,{size:15}),u("Delete task")]})})]}),w&&t.jsx("p",{role:"alert",className:"form-error",children:u(w)})]}),D==="help"&&t.jsxs("div",{className:"help-content",children:[t.jsxs("p",{children:[t.jsx("strong",{children:u("Overview")}),u(" brings your team, task throughput, and recent activity together.")]}),t.jsxs("p",{children:[t.jsx("strong",{children:u("Agents")}),u(" lets you inspect their model and last task, and pause or resume their workspace status.")]}),t.jsxs("p",{children:[t.jsx("strong",{children:u("Tasks")}),u(" is your personal to-do board. Drag cards between columns, or use each card’s status menu with your keyboard.")]}),t.jsxs("p",{children:[t.jsx("strong",{children:u("System")}),u(" shows live machine readings and how many tokens each agent has used.")]}),t.jsxs("p",{children:[t.jsx("strong",{children:u("Chat")}),u(" keeps a separate conversation with each of your agents. "),t.jsx("strong",{children:u("Productivity")}),u(" gives you a saved focus timer and sticky notes.")]}),t.jsxs("p",{children:[t.jsx("strong",{children:u("Schedule")}),u(" manages recurring jobs. Each run asks the agent and puts its answer on the board for your review; pause, edit, run manually, or move a job to Trash.")]}),t.jsxs("p",{children:[u("Agents, tasks, and activity changes are saved across sessions. Press "),t.jsx("kbd",{children:u("Esc")}),u(" to close a dialog.")]})]})]})]})}),A&&t.jsxs("div",{className:"toast",role:"status",children:[t.jsx($a,{size:18}),u(A)]}),S&&t.jsxs("span",{className:"save-status",role:"status",children:[t.jsx(Jt,{className:"spinning",size:14}),u("Saving…")]})]})}const SX="data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2064%2064'%3e%3crect%20width='64'%20height='64'%20rx='17'%20fill='%23003139'/%3e%3cpath%20d='M17%2045%2032%2018%2047%2045M23%2035h18'%20fill='none'%20stroke='%23c5fb18'%20stroke-width='6'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3c/svg%3e",cS=document.createElement("link");cS.rel="icon";cS.href="/favicon.png";document.head.appendChild(cS);tL.createRoot(document.getElementById("root")).render(t.jsx(lT.StrictMode,{children:t.jsx(bX,{})}));