lecodes-cli 2.0.5 → 2.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  var Fn=Object.defineProperty;var Mn=(e,t,n)=>t in e?Fn(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var je=(e,t,n)=>Mn(e,typeof t!="symbol"?t+"":t,n);(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const s of document.querySelectorAll('link[rel="modulepreload"]'))r(s);new MutationObserver(s=>{for(const i of s)if(i.type==="childList")for(const o of i.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&r(o)}).observe(document,{childList:!0,subtree:!0});function n(s){const i={};return s.integrity&&(i.integrity=s.integrity),s.referrerPolicy&&(i.referrerPolicy=s.referrerPolicy),s.crossOrigin==="use-credentials"?i.credentials="include":s.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function r(s){if(s.ep)return;s.ep=!0;const i=n(s);fetch(s.href,i)}})();const Pn=e=>{if(typeof e=="string")return e;if(e instanceof Error)return e.stack?`${String(e)}
2
- ${e.stack}`:String(e);try{return JSON.stringify(e)}catch{return String(e)}},In=(e,t)=>{const n=o=>{fetch(`${e}/log`,{method:"POST",body:JSON.stringify(o),headers:{"content-type":"application/json"},keepalive:!0}).catch(()=>{})};let r=-1;const s=async()=>{try{const{v:o}=await(await fetch(`${e}/version`,{cache:"no-store"})).json();typeof o=="number"&&t(o)}catch{}setTimeout(s,2500)};setTimeout(s,2500);const i=()=>{let o;try{o=new WebSocket(e.replace(/^http/,"ws")+"/ws")}catch{return}o.onopen=()=>o.send(JSON.stringify({type:"hello",v:r})),o.onmessage=f=>{let l={};try{l=JSON.parse(String(f.data))}catch{return}l.type==="reload"&&typeof l.v=="number"&&t(l.v)},o.onclose=()=>{setTimeout(i,2e3)}};return i(),{bundleUrl:o=>`${e}/bundle.js?t=web&v=${o}`,versionOf(o,f){const l=Number(o.headers.get("x-lecodes-v"));return o.headers.has("x-lecodes-v")&&Number.isFinite(l)?l:f},ran(o){r=o},log:(o,f)=>n({type:"log",level:o,text:f.map(Pn).join(" ")}),error:o=>n({type:"error",text:o})}},Dn=(e,t)=>{try{const n=new URL(e,t);return n.origin===new URL(t).origin&&(n.protocol==="http:"||n.protocol==="https:")?n.href:null}catch{return null}},Bn="modulepreload",Vn=function(e,t){return new URL(e,t).href},bt={},re=function(t,n,r){let s=Promise.resolve();if(n&&n.length>0){let o=function(b){return Promise.all(b.map(E=>Promise.resolve(E).then(g=>({status:"fulfilled",value:g}),g=>({status:"rejected",reason:g}))))};const f=document.getElementsByTagName("link"),l=document.querySelector("meta[property=csp-nonce]"),d=(l==null?void 0:l.nonce)||(l==null?void 0:l.getAttribute("nonce"));s=o(n.map(b=>{if(b=Vn(b,r),b in bt)return;bt[b]=!0;const E=b.endsWith(".css"),g=E?'[rel="stylesheet"]':"";if(!!r)for(let p=f.length-1;p>=0;p--){const h=f[p];if(h.href===b&&(!E||h.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${b}"]${g}`))return;const a=document.createElement("link");if(a.rel=E?"stylesheet":Bn,E||(a.as="script"),a.crossOrigin="",a.href=b,d&&a.setAttribute("nonce",d),document.head.appendChild(a),E)return new Promise((p,h)=>{a.addEventListener("load",p),a.addEventListener("error",()=>h(new Error(`Unable to preload CSS for ${b}`)))})}))}function i(o){const f=new Event("vite:preloadError",{cancelable:!0});if(f.payload=o,window.dispatchEvent(f),!f.defaultPrevented)throw o}return s.then(o=>{for(const f of o||[])f.status==="rejected"&&i(f.reason);return t().catch(i)})},yt="2.0.5",He=e=>{const t=e==null?void 0:e.match(/^(\d+)\.\d+\.\d+/);return t?Number(t[1]):null},zn=(e,t)=>He(e)!==null&&He(e)===He(t),Wn=(e,t="woff2")=>{const n=/^\/\/ fonts: (.+)$/m.exec(e);if(!n)return[];const r=[];for(const s of n[1].split(";")){const i=s.indexOf("=");if(i===-1)continue;const o=/^(.+)@(\d+)(i?)$/.exec(s.slice(0,i));o&&r.push({family:o[1],weight:parseInt(o[2],10),italic:o[3]==="i",url:s.slice(i+1).replace("{fmt}",t)})}return r},Gn=async(e,t,n=2e3)=>{const r=t??(typeof document>"u"?void 0:document);if(!(r!=null&&r.fonts)||e.length===0)return;const s=[];for(const i of e)try{const o=new FontFace(i.family,`url("${i.url}")`,{weight:String(i.weight),style:i.italic?"italic":"normal"});r.fonts.add(o),s.push(o.load().catch(()=>{}))}catch{}await Promise.race([Promise.all(s),new Promise(i=>setTimeout(i,n))])},jn=e=>{var l,d,b,E;const t=e.slice(0,2e3),n=new Set,r=t.match(/\/\/ preload: (.+)/);if(r)for(const g of r[1].split(";"))n.add(g);const s=t.includes("// gl: disable")?"off":t.includes("// gl: defer")?"defer":"on",i=((l=t.match(/^\/\/ sdk: (\d+\.\d+\.\d+\S*)/m))==null?void 0:l[1])??null,o=((b=(d=t.match(/^\/\/ name: (.+)$/m))==null?void 0:d[1])==null?void 0:b.trim())??null,f=new Set((((E=t.match(/^\/\/ plugins: (.+)$/m))==null?void 0:E[1])??"").split(";").map(g=>g.trim()).filter(Boolean));return{sdk:i,name:o,preloads:n,gl:s,is2d:t.includes("// 2d: enable"),plugins:f,bootFonts:Wn(t)}},Hn=1,Kn=2,Yn=3,qn=4,Xn=5,Jn=6,Et=7,Qn=8,vt=9,Zn=10,er=11,tr=12,nr=13,rr=14,or=15,sr=16,wt=17,ir=18,ar=19,xe=20,ri=21,oi=22,si=23,ii=24,ai=25,cr=26,lr=27,ur=28,fr=29,St=30,_t=31,dr=32,pr=33,Tt=34,kt=35,Oe=1,mr=2,hr=4,le=8,gr=16,Ke=32,br=64,Ye=128,yr=256,Er=512,vr=1024,wr=2048,Sr=4096,Lt=8192,ci=16384,_r=32768,Tr=1<<18,kr=255,xt=256,Rt=512,Lr=1024,Y=0,xr=1,Rr=2,Cr=3,Me=4,Ue=255,sn=e=>{const t=e.clientWidth;if(!t)return 1;const n=e.getBoundingClientRect().width;return n>0?n/t:1},Ct={text:{type:"text"},password:{type:"password"},search:{type:"search"},tel:{type:"tel"},email:{type:"email"},url:{type:"url"},number:{type:"text",mode:"numeric"},decimal:{type:"text",mode:"decimal"},date:{type:"date"},time:{type:"time"}},At=(e,t)=>e==null?t:e===!0||e==="true"||e==="1"||typeof e=="number"&&e>.5,Z=(e,t,n)=>{n===null?e.removeAttribute(t):e.getAttribute(t)!==n&&e.setAttribute(t,n)},Ar=(e,t)=>{if(e.type!=="input"&&e.type!=="textarea")return;const n=e.el,r=t("placeholder");if(Z(n,"placeholder",r==null?null:String(r)),e.type==="input"){const f=Ct[String(t("type")??"text")]??Ct.text,l=n;l.type!==f.type&&(l.type=f.type),Z(n,"inputmode",f.mode??null);const d=t("enterKey");Z(n,"enterkeyhint",d==null?null:String(d))}const s=t("autocapitalize");Z(n,"autocapitalize",s==null?null:String(s));const i=t("autocorrect");i==null?(Z(n,"autocorrect",null),Z(n,"spellcheck",null)):(Z(n,"autocorrect",At(i,!0)?"on":"off"),Z(n,"spellcheck",At(i,!0)?"true":"false"));const o=Number(t("maxLength")??0);Z(n,"maxlength",o>0?String(Math.round(o)):null)},Pe={width:"layout",height:"layout",minWidth:"layout",minHeight:"layout",maxWidth:"layout",maxHeight:"layout",flexBasis:"layout",flexGrow:"layout",flexShrink:"layout",aspectRatio:"layout",gap:"layout",rowGap:"layout",columnGap:"layout",padding:"layout",paddingTop:"layout",paddingRight:"layout",paddingBottom:"layout",paddingLeft:"layout",paddingHorizontal:"layout",paddingVertical:"layout",paddingStart:"layout",paddingEnd:"layout",margin:"layout",marginTop:"layout",marginRight:"layout",marginBottom:"layout",marginLeft:"layout",marginHorizontal:"layout",marginVertical:"layout",marginStart:"layout",marginEnd:"layout",left:"layout",right:"layout",top:"layout",bottom:"layout",start:"layout",end:"layout",inset:"layout",flexDirection:"enum",justifyContent:"enum",alignItems:"enum",alignSelf:"enum",position:"enum",flexWrap:"enum",boxSizing:"enum",display:"enum",overflow:"enum",scrollDirection:"enum",borderWidth:"len",borderTopWidth:"len",borderRightWidth:"len",borderBottomWidth:"len",borderLeftWidth:"len",borderHorizontalWidth:"len",borderVerticalWidth:"len",borderStartWidth:"len",borderEndWidth:"len",color:"color",backgroundColor:"color",borderColor:"color",borderTopColor:"color",borderRightColor:"color",borderBottomColor:"color",borderLeftColor:"color",placeholderColor:"color",refreshControlColor:"color",tintColor:"color",rippleColor:"color",overlayColor:"color",backgroundImage:"str",backgroundSize:"enum",backgroundGradient:"str",borderRadius:"len",borderTopLeftRadius:"len",borderTopRightRadius:"len",borderBottomRightRadius:"len",borderBottomLeftRadius:"len",opacity:"num",transform:"str",transformOrigin:"str",pointerEvents:"enum",fontSize:"len",fontWeight:"num",fontStyle:"enum",fontFamily:"str",lineHeight:"len",letterSpacing:"len",textAlign:"enum",textDecoration:"enum",lineClamp:"num",textOverflow:"enum",objectFit:"enum",placeholder:"str",type:"enum",enterKey:"enum",autocapitalize:"enum",autocorrect:"num",maxLength:"num",keyboardShrink:"num",keyboardDismiss:"num",showScrollbar:"num",overscrollMode:"enum",keyboardDismissMode:"enum",snap:"enum",sheetDetents:"str",sheetDetent:"num",sheetDismissible:"num",dim:"num"},$r={p:"padding",pt:"paddingTop",pr:"paddingRight",pb:"paddingBottom",pl:"paddingLeft",px:"paddingHorizontal",py:"paddingVertical",m:"margin",mt:"marginTop",mr:"marginRight",mb:"marginBottom",ml:"marginLeft",mx:"marginHorizontal",my:"marginVertical",bgColor:"backgroundColor",bgImage:"backgroundImage",bgSize:"backgroundSize",bgGradient:"backgroundGradient"},Or=["placeholderColor","refreshControlColor","tintColor","rippleColor","overlayColor","backgroundGradient"],Ur={display:"flex",overflow:"visible",scrollDirection:"vertical",borderWidth:0,borderTopWidth:0,borderRightWidth:0,borderBottomWidth:0,borderLeftWidth:0,borderHorizontalWidth:0,borderVerticalWidth:0,borderStartWidth:0,borderEndWidth:0,backgroundColor:0,borderColor:0,borderTopColor:0,borderRightColor:0,borderBottomColor:0,borderLeftColor:0,backgroundImage:"",backgroundSize:"cover",borderRadius:0,borderTopLeftRadius:0,borderTopRightRadius:0,borderBottomRightRadius:0,borderBottomLeftRadius:0,opacity:1,transform:"identity",transformOrigin:"50% 50%",pointerEvents:"all",fontSize:14,fontWeight:400,fontStyle:"normal",lineHeight:"normal",letterSpacing:0,textAlign:"start",textDecoration:"none",lineClamp:0,textOverflow:"ellipsis",objectFit:"cover",placeholder:"",type:"text",enterKey:"done",autocapitalize:"sentences",autocorrect:1,maxLength:0,keyboardShrink:1,keyboardDismiss:1,showScrollbar:1,overscrollMode:"default",keyboardDismissMode:"interactive",snap:"none",sheetDetents:"",sheetDetent:0,sheetDismissible:1,dim:0},Nr=["duration","delay","layer","commit","loop","loopMode","name"];function an(e){let t=e.trim();/\sxmlns\s*=/.test(t)||(t=t.replace(/<svg\b/,'<svg xmlns="http://www.w3.org/2000/svg"'));const n=new TextEncoder().encode(t);let r="";for(const s of n)r+=String.fromCharCode(s);return`data:image/svg+xml;base64,${btoa(r)}`}function Fr(e){const t=e.match(/viewBox\s*=\s*["']([^"']+)["']/);return t?t[1]:null}const Mr=/\b(?:calc|min|max|clamp)\(/,Pr=e=>{if(!Mr.test(e))return e;let t="";for(let n=0;n<e.length;n++){if(e.startsWith("var(",n)){let s=0;const i=n;for(;n<e.length;n++)if(e[n]==="(")s++;else if(e[n]===")"&&--s===0)break;t+=e.slice(i,Math.min(n+1,e.length));continue}const r=e[n];if(r==="+"||r==="-"){const s=t[t.length-1]??"";if(!(r==="-"&&(s==="e"&&"btlr".includes(e[n+1]??"")||e.slice(Math.max(0,n-7),n)==="comfort"))&&/[\w%.)]/.test(s)){for(t=t.trimEnd()+" "+r+" ";e[n+1]===" ";)n++;continue}}t+=r}return t.replace(/\d*\.\d+|\d+/g,(n,r,s)=>{const i=s.slice(0,r).trimEnd(),o=s.slice(r+n.length).trimStart();return/[\w.%]$/.test(i)||/^[\w.%]/.test(o)||/[*/]$/.test(i)||/^[*/]/.test(o)?n:n+"px"})},Ir={top:"12px",bottom:"4px",left:"16px",right:"16px"},cn=e=>`max(var(--safe-${e}, 0px), calc(var(--safe-${e}-bar, 0px) + var(--comfort-${e}, ${Ir[e]})))`,Dr={vw:"cqw",vh:"cqh",vmin:"cqmin",vmax:"cqmax"},Te=e=>Pr(e).replace(new RegExp("(?<![-\\w])comfort-(top|bottom|left|right)\\b","g"),(t,n)=>cn(n)).replace(new RegExp("(?<![-\\w])safe-(top|bottom|left|right)\\b","g"),(t,n)=>`var(--safe-${n}, 0px)`).replace(/(\d)(vmin|vmax|vw|vh)\b/g,(t,n,r)=>n+Dr[r]),ft=/^-?\d*\.?\d+$/,ee=e=>{if(typeof e=="number")return e+"px";const t=String(e).trim();return ft.test(t)?t+"px":Te(t)},ke=e=>{if(typeof e=="number")return"#"+(e>>>0).toString(16).padStart(e<=16777215?6:8,"0");const t=String(e);return t==="clear"?"transparent":t},Br=/^(rotate|skew)/,Vr=/^translate/,zr=e=>{const t=String(e).trim();return t===""||t==="identity"?"none":t.replace(/([a-zA-Z0-9]+)\s*\(([^)]*)\)/g,(n,r,s)=>{const i=Vr.test(r)?"px":Br.test(r)?"deg":null;return i===null?n:`${r}(${s.split(",").map(o=>{const f=o.trim();return ft.test(f)?f+i:Te(f)}).join(", ")})`})},ln=e=>typeof e=="number"?e+"px":String(e).trim().split(/\s+/).map(t=>ft.test(t)?t+"px":Te(t)).join(" "),J=0,Q=1,ve=2,Ne=["top","right","bottom","left"],Wr=(e,t)=>e==="safe-all"?`var(--safe-${t}, 0px)`:e==="comfort-all"||e==="comfort-x"||e==="comfort-y"?cn(t):ee(e),st=(e,t)=>{const n=(s,i)=>({rank:i,to:o=>s.map(f=>[t(f),Wr(o,f)])}),r=s=>({rank:Q,to:i=>[[t(s),ee(i)]]});return{[e]:n(Ne,J),[`${e}Horizontal`]:n(["left","right"],Q),[`${e}Vertical`]:n(["top","bottom"],Q),[`${e}Start`]:r("inline-start"),[`${e}End`]:r("inline-end"),[`${e}Top`]:n(["top"],ve),[`${e}Right`]:n(["right"],ve),[`${e}Bottom`]:n(["bottom"],ve),[`${e}Left`]:n(["left"],ve)}},Gr=()=>{const e=st("border",n=>`border-${n}-width`),t={};for(const n of Object.keys(e))t[`${n}Width`]=e[n];return t},dt=e=>{const t=[];let n=0,r="";for(const s of e.trim()){if(s==="("&&n++,s===")"&&n--,/\s/.test(s)&&n===0){r&&t.push(r),r="";continue}r+=s}return r&&t.push(r),t},jr=new Set(["none","solid","dashed","dotted","double","hidden"]),Hr=/^-?\d*\.?\d+([a-z%]*)$|^(calc|min|max|clamp)\(/,ye=(e,t)=>({rank:t,to:n=>{let r=null,s=null,i=null;if(typeof n=="number")r=n+"px";else for(const f of dt(String(n)))jr.has(f)?i=f:Hr.test(f)?r=ee(f):s=ke(f);const o=[];for(const f of e)o.push([`border-${f}-width`,r??(s?"1px":"0px")]),o.push([`border-${f}-color`,s??"transparent"]),i&&o.push([`border-${f}-style`,i]);return o}}),Kr=e=>{const t=String(e).trim(),n=(i,o,f)=>[["flex-grow",i],["flex-shrink",o],["flex-basis",f]];if(t==="none")return n("0","0","auto");if(t==="auto")return n("1","1","auto");if(t==="initial")return n("0","1","auto");const r=dt(t),s=i=>i!==void 0&&/^-?\d*\.?\d+$/.test(i);return s(r[0])?r.length===1?n(r[0],"1","0%"):s(r[1])?n(r[0],r[1],r[2]!==void 0?ee(r[2]):"0%"):n(r[0],"1",ee(r[1])):n("1","1",ee(r[0]??"auto"))},un=e=>{var t;return typeof e=="object"&&e!==null&&"_h"in e&&typeof((t=e._h)==null?void 0:t.id)=="number"},Yr=e=>e.replace(/<svg\b[^>]*>/,t=>t.replace(/\spreserveAspectRatio\s*=\s*("[^"]*"|'[^']*')/,"").replace(/^<svg\b/,'<svg preserveAspectRatio="none"')),fn=(e,t)=>{if(un(e))return`url("${t.bufferUrl(e._h.id)}")`;const n=String(e??"");return n===""?"none":n.startsWith("id:")?`url("${t.bufferUrl(Number(n.slice(3)))}")`:n.startsWith("svg:")?`url("${an(Yr(n.slice(4)))}")`:`url("${n.replace(/["\\\n]/g,r=>"\\"+r)}")`},qr=/^\s*(repeating-)?(linear|radial|conic)-gradient\(/,dn=e=>{const t=String(e??"").trim();return t===""?"none":Te(t)},Xr=(e,t)=>{const n=typeof e=="string"&&qr.test(e),r=un(e)||typeof e=="string"&&/^(id:|https?:|data:|blob:|\.{0,2}\/)/.test(e);return[["--lc-bg-grad",n?dn(e):"none"],["--lc-bg-img",r?fn(e,t):"none"],["background-color",n||r?"transparent":ke(e)]]},Jr=e=>{const t=typeof e=="number"?[e+"px"]:dt(String(e)).map(o=>ln(o)),[n,r=n,s=n,i=r]=t;return[["border-top-left-radius",n??"0px"],["border-top-right-radius",r??"0px"],["border-bottom-right-radius",s??"0px"],["border-bottom-left-radius",i??"0px"]]},Qr=new Set(["serif","sans-serif","monospace","cursive","fantasy","system-ui","ui-monospace","ui-sans-serif","ui-serif","inherit"]),Zr=e=>{const t=String(e).trim();return t==="monospaced"?"monospace":t.startsWith("var(")||t.includes(",")||/^["']/.test(t)||Qr.has(t)?t:`"${t.replace(/"/g,'\\"')}"`},eo=e=>e===!0||e==="true"||typeof e=="number"&&e>.5||e==="1",to=e=>t=>e[String(t)]??String(t),Le={width:{css:"width",as:"len"},height:{css:"height",as:"len"},minWidth:{css:"min-width",as:"len"},minHeight:{css:"min-height",as:"len"},maxWidth:{css:"max-width",as:"len"},maxHeight:{css:"max-height",as:"len"},flexBasis:{css:"flex-basis",as:"len"},flexGrow:{css:"flex-grow",as:"num"},flexShrink:{css:"flex-shrink",as:"num"},aspectRatio:{css:"aspect-ratio",as:"num"},gap:{css:["row-gap","column-gap"],as:"len",rank:J},rowGap:{css:"row-gap",as:"len"},columnGap:{css:"column-gap",as:"len"},...st("padding",e=>`padding-${e}`),...st("margin",e=>`margin-${e}`),inset:{css:Ne,as:"len",rank:J},top:{css:"top",as:"len"},right:{css:"right",as:"len"},bottom:{css:"bottom",as:"len"},left:{css:"left",as:"len"},start:{css:"inset-inline-start",as:"len",rank:Q},end:{css:"inset-inline-end",as:"len",rank:Q},flexDirection:{css:"flex-direction",as:"raw"},justifyContent:{css:"justify-content",as:"raw"},alignItems:{css:"align-items",as:"raw"},alignSelf:{css:"align-self",as:"raw"},position:{css:"position",as:"raw"},flexWrap:{css:"flex-wrap",as:"raw"},boxSizing:{css:"box-sizing",as:"raw"},display:{css:"display",as:"raw"},overflow:{rank:J,to:e=>{const t=e==="scroll"?"auto":String(e);return[["overflow-x",t],["overflow-y",t]]}},scrollDirection:{to:e=>e==="horizontal"?[["overflow-x","auto"],["overflow-y","hidden"],["flex-direction","row"]]:e==="all"?[["overflow-x","auto"],["overflow-y","auto"]]:[["overflow-x","hidden"],["overflow-y","auto"],["flex-direction","column"]],rank:Q},...Gr(),color:{css:"color"},backgroundColor:{css:"background-color"},borderColor:{css:Ne.map(e=>`border-${e}-color`),rank:J},borderTopColor:{css:"border-top-color"},borderRightColor:{css:"border-right-color"},borderBottomColor:{css:"border-bottom-color"},borderLeftColor:{css:"border-left-color"},placeholderColor:{css:"--lc-placeholder"},refreshControlColor:{css:"--lc-refresh"},tintColor:{css:"--lc-tint"},overlayColor:{css:"--lc-overlay"},rippleColor:{none:"a browser has no ripple: the press feedback of a page is `$pressed`"},backgroundImage:{to:(e,t)=>[["--lc-bg-img",fn(e,t)]]},backgroundGradient:{to:e=>[["--lc-bg-grad",dn(e)]]},backgroundSize:{to:e=>e==="tile"?[["background-size","auto"],["background-repeat","repeat"],["background-position","0 0"]]:[["background-size",e==="fill"?"100% 100%":String(e)],["background-repeat","no-repeat"],["background-position","center"]]},borderRadius:{to:Jr,rank:J},borderTopLeftRadius:{css:"border-top-left-radius"},borderTopRightRadius:{css:"border-top-right-radius"},borderBottomRightRadius:{css:"border-bottom-right-radius"},borderBottomLeftRadius:{css:"border-bottom-left-radius"},opacity:{css:"opacity"},transform:{to:e=>[["transform",zr(e)]]},transformOrigin:{css:"transform-origin",as:"lens"},pointerEvents:{to:e=>[["pointer-events",e==="none"?"none":"auto"]]},dim:{css:"--lc-dim"},fontSize:{css:"font-size"},fontWeight:{css:"font-weight",as:"raw"},fontStyle:{to:e=>[["font-style",e===2?"italic":e===0?"normal":String(e)]]},fontFamily:{to:e=>[["font-family",Zr(e)]]},lineHeight:{to:e=>[["line-height",e==="normal"?"1.2":ee(e)]]},letterSpacing:{css:"letter-spacing"},textAlign:{css:"text-align"},textDecoration:{css:"text-decoration-line"},lineClamp:{rank:J,to:e=>Number(e)>0?[["display","-webkit-box"],["-webkit-box-orient","vertical"],["-webkit-line-clamp",String(Math.round(Number(e)))],["overflow-x","hidden"],["overflow-y","hidden"]]:[["-webkit-line-clamp","none"]]},textOverflow:{css:"text-overflow"},objectFit:{to:e=>[["object-fit",String(e)],["--lc-fit",e==="fill"?"100% 100%":String(e)]]},placeholder:{attr:!0},type:{attr:!0},enterKey:{attr:!0},autocapitalize:{attr:!0},autocorrect:{attr:!0},maxLength:{attr:!0},keyboardShrink:{attr:!0},keyboardDismiss:{attr:!0},showScrollbar:{to:e=>[["scrollbar-width",eo(e)?"thin":"none"]]},overscrollMode:{to:e=>[["overscroll-behavior",to({default:"auto",none:"none",absorb:"contain"})(e)]]},keyboardDismissMode:{attr:!0},snap:{to:e=>e==="none"?[["scroll-snap-type","none"],["--lc-snap","none"]]:[["scroll-snap-type","both mandatory"],["--lc-snap",String(e)]]},sheetDetents:{attr:!0},sheetDetent:{attr:!0},sheetDismissible:{attr:!0},background:{to:Xr,rank:J},border:ye(Ne,J),borderTop:ye(["top"],Q),borderRight:ye(["right"],Q),borderBottom:ye(["bottom"],Q),borderLeft:ye(["left"],Q),flex:{to:Kr,rank:J}},qe=e=>$r[e]??e,no=e=>e in Le,pn=e=>{const t=Le[e];return!!t&&"attr"in t},ro={overflow:"overflow-x",pointerEvents:"pointer-events",fontFamily:"font-family",fontStyle:"font-style",lineHeight:"line-height",objectFit:"object-fit",transform:"transform",borderRadius:"border-top-left-radius",borderWidth:"border-top-width",borderColor:"border-top-color",backgroundImage:"--lc-bg-img",backgroundGradient:"--lc-bg-grad",backgroundSize:"background-size",showScrollbar:"scrollbar-width",overscrollMode:"overscroll-behavior",snap:"--lc-snap",lineClamp:"-webkit-line-clamp",borderTopWidth:"border-top-width",borderRightWidth:"border-right-width",borderBottomWidth:"border-bottom-width",borderLeftWidth:"border-left-width",borderHorizontalWidth:"border-left-width",borderVerticalWidth:"border-top-width",borderStartWidth:"border-inline-start-width",borderEndWidth:"border-inline-end-width"},oo=e=>{const t=Le[e];return t&&"css"in t&&typeof t.css=="string"?t.css:ro[e]??null},so={len:ee,lens:ln,num:e=>String(e),raw:e=>String(e),color:ke},io={color:"color",len:"len",enum:"raw",num:"num",str:"raw",layout:"raw"},$t=e=>{const t=Le[e];return t&&"rank"in t&&t.rank!==void 0?t.rank:ve},Xe=(e,t,n)=>{const r=[...e].filter(([,i])=>i!=null);r.sort((i,o)=>$t(i[0])-$t(o[0]));const s=new Map;for(const[i,o]of r){const f=Le[i];if(!f){n==null||n(i);continue}if("attr"in f||"none"in f)continue;if("to"in f){for(const[b,E]of f.to(o,t))s.set(b,E);continue}const l=so[f.as??io[Pe[i]??"layout"]],d=l(o);if(typeof f.css=="string")s.set(f.css,d);else for(const b of f.css)s.set(b,d)}return s},Ot=e=>[...e].sort((t,n)=>t[0]<n[0]?-1:t[0]>n[0]?1:0).map(([t,n])=>`${t}:${n}`).join(";"),mn=0,hn=1,Se=2,_e=3,gn=4,de=65,Ie=1.70158,Re=Ie*1.525,Ut=Ie+1,Nt=2*Math.PI/3,Ft=2*Math.PI/4.5,Ce=e=>e<1/2.75?7.5625*e*e:e<2/2.75?7.5625*(e-=1.5/2.75)*e+.75:e<2.5/2.75?7.5625*(e-=2.25/2.75)*e+.9375:7.5625*(e-=2.625/2.75)*e+.984375,it=[["linear",e=>e],["inSine",e=>1-Math.cos(e*Math.PI/2)],["outSine",e=>Math.sin(e*Math.PI/2)],["inOutSine",e=>-(Math.cos(Math.PI*e)-1)/2],["inQuad",e=>e*e],["outQuad",e=>1-(1-e)*(1-e)],["inOutQuad",e=>e<.5?2*e*e:1-(-2*e+2)**2/2],["inCubic",e=>e*e*e],["outCubic",e=>1-(1-e)**3],["inOutCubic",e=>e<.5?4*e*e*e:1-(-2*e+2)**3/2],["inQuart",e=>e**4],["outQuart",e=>1-(1-e)**4],["inOutQuart",e=>e<.5?8*e**4:1-(-2*e+2)**4/2],["inExpo",e=>e===0?0:2**(10*e-10)],["outExpo",e=>e===1?1:1-2**(-10*e)],["inOutExpo",e=>e===0?0:e===1?1:e<.5?2**(20*e-10)/2:(2-2**(-20*e+10))/2],["inCirc",e=>1-Math.sqrt(1-e*e)],["outCirc",e=>Math.sqrt(1-(e-1)**2)],["inOutCirc",e=>e<.5?(1-Math.sqrt(1-(2*e)**2))/2:(Math.sqrt(1-(-2*e+2)**2)+1)/2],["inBack",e=>Ut*e*e*e-Ie*e*e],["outBack",e=>1+Ut*(e-1)**3+Ie*(e-1)**2],["inOutBack",e=>e<.5?(2*e)**2*((Re+1)*2*e-Re)/2:((2*e-2)**2*((Re+1)*(e*2-2)+Re)+2)/2],["inElastic",e=>e===0?0:e===1?1:-(2**(10*e-10))*Math.sin((e*10-10.75)*Nt)],["outElastic",e=>e===0?0:e===1?1:2**(-10*e)*Math.sin((e*10-.75)*Nt)+1],["inOutElastic",e=>e===0?0:e===1?1:e<.5?-(2**(20*e-10)*Math.sin((20*e-11.125)*Ft))/2:2**(-20*e+10)*Math.sin((20*e-11.125)*Ft)/2+1],["inBounce",e=>1-Ce(1-e)],["outBounce",Ce],["inOutBounce",e=>e<.5?(1-Ce(1-2*e))/2:(1+Ce(2*e-1))/2],["smoothstep",e=>e*e*(3-2*e)]],ao={in:"inQuad",out:"outQuad",inOut:"inOutQuad",easeIn:"inQuad",easeOut:"outQuad",easeInOut:"inOutQuad","ease-in":"inQuad","ease-out":"outQuad","ease-in-out":"inOutQuad"},co=e=>{const t=ao[e]??e;for(let n=0;n<it.length;n++)if(it[n][0]===t)return n;return-1},lo=[.25,.1,.25,1],Ae={kind:mn,p:[0,0,0,0]},uo=e=>{const t=new Float32Array(de);for(let n=0;n<de;n++)t[n]=e(n/(de-1));return t[0]=0,t[de-1]=1,t},fo=e=>{if(e===void 0)return Ae;if(typeof e=="function")return{kind:gn,p:[0,0,0,0],table:uo(e)};if(Array.isArray(e)){const[s,i,o,f]=e;return{kind:Se,p:[s,i,o,f]}}const t=e.trim();if(t==="linear")return Ae;if(t==="ease")return{kind:Se,p:lo};if(t==="steps")return{kind:_e,p:[1,0,0,0]};let n=/^steps\(\s*(\d+)\s*(?:,\s*(start|end|jump-start|jump-end)\s*)?\)$/.exec(t);if(n)return{kind:_e,p:[Math.max(1,parseInt(n[1],10)),n[2]==="start"||n[2]==="jump-start"?1:0,0,0]};if(n=/^cubic-bezier\(\s*([-\d.e]+)\s*,\s*([-\d.e]+)\s*,\s*([-\d.e]+)\s*,\s*([-\d.e]+)\s*\)$/.exec(t),n)return{kind:Se,p:[parseFloat(n[1]),parseFloat(n[2]),parseFloat(n[3]),parseFloat(n[4])]};const r=co(t);return r===0?Ae:r>0?{kind:hn,p:[r,0,0,0]}:(console.warn(`[tween] unknown easing "${t}" — using linear`),Ae)},po=(e,t,n,r,s)=>{const i=1-3*r+3*t,o=3*r-6*t,f=3*t,l=1-3*s+3*n,d=3*s-6*n,b=3*n;let E=e;for(let g=0;g<8;g++){const m=((i*E+o)*E+f)*E-e,a=(3*i*E+2*o)*E+f;if(Math.abs(m)<1e-6||Math.abs(a)<1e-6)break;E-=m/a}return E=Math.min(1,Math.max(0,E)),((l*E+d)*E+b)*E},mo=(e,t)=>{if(t<=0)return e.kind===_e&&e.p[1]===1?1/e.p[0]:0;if(t>=1)return 1;switch(e.kind){case hn:return it[e.p[0]][1](t);case Se:return po(t,e.p[0],e.p[1],e.p[2],e.p[3]);case _e:{const n=e.p[0];return e.p[1]===1?Math.min(1,Math.ceil(t*n)/n):Math.floor(t*n)/n}case gn:{const n=e.table,r=t*(de-1),s=Math.floor(r),i=n[s],o=n[Math.min(s+1,de-1)];return i+(o-i)*(r-s)}default:return t}},Mt=24,Pt=e=>String(Math.round(e*1e4)/1e4),ho="cubic-bezier(0.3333, 0, 0.6667, 1)",go=e=>{switch(e.kind){case mn:return"linear";case Se:return`cubic-bezier(${e.p.map(Pt).join(", ")})`;case _e:return`steps(${e.p[0]}, ${e.p[1]===1?"jump-start":"jump-end"})`}const t=[];for(let n=0;n<=Mt;n++)t.push(Pt(mo(e,n/Mt)));return`linear(${t.join(", ")})`},bo=e=>e===void 0||e==="smoothstep"?ho:go(fo(e)),bn=["lc-base","lc-bag","lc-own","lc-orient","lc-class","lc-hover","lc-press","lc-focus"],yo=["--lc-bg-grad","--lc-bg-img","--lc-tint","--lc-overlay","--lc-refresh","--lc-fit","--lc-src","--lc-src-tint","--lc-iw","--lc-ih","--lc-ir","--lc-crop-size","--lc-crop-pos"],yn="lc-app",Eo=`
2
+ ${e.stack}`:String(e);try{return JSON.stringify(e)}catch{return String(e)}},In=(e,t)=>{const n=o=>{fetch(`${e}/log`,{method:"POST",body:JSON.stringify(o),headers:{"content-type":"application/json"},keepalive:!0}).catch(()=>{})};let r=-1;const s=async()=>{try{const{v:o}=await(await fetch(`${e}/version`,{cache:"no-store"})).json();typeof o=="number"&&t(o)}catch{}setTimeout(s,2500)};setTimeout(s,2500);const i=()=>{let o;try{o=new WebSocket(e.replace(/^http/,"ws")+"/ws")}catch{return}o.onopen=()=>o.send(JSON.stringify({type:"hello",v:r})),o.onmessage=f=>{let l={};try{l=JSON.parse(String(f.data))}catch{return}l.type==="reload"&&typeof l.v=="number"&&t(l.v)},o.onclose=()=>{setTimeout(i,2e3)}};return i(),{bundleUrl:o=>`${e}/bundle.js?t=web&v=${o}`,versionOf(o,f){const l=Number(o.headers.get("x-lecodes-v"));return o.headers.has("x-lecodes-v")&&Number.isFinite(l)?l:f},ran(o){r=o},log:(o,f)=>n({type:"log",level:o,text:f.map(Pn).join(" ")}),error:o=>n({type:"error",text:o})}},Dn=(e,t)=>{try{const n=new URL(e,t);return n.origin===new URL(t).origin&&(n.protocol==="http:"||n.protocol==="https:")?n.href:null}catch{return null}},Bn="modulepreload",Vn=function(e,t){return new URL(e,t).href},bt={},re=function(t,n,r){let s=Promise.resolve();if(n&&n.length>0){let o=function(b){return Promise.all(b.map(E=>Promise.resolve(E).then(g=>({status:"fulfilled",value:g}),g=>({status:"rejected",reason:g}))))};const f=document.getElementsByTagName("link"),l=document.querySelector("meta[property=csp-nonce]"),d=(l==null?void 0:l.nonce)||(l==null?void 0:l.getAttribute("nonce"));s=o(n.map(b=>{if(b=Vn(b,r),b in bt)return;bt[b]=!0;const E=b.endsWith(".css"),g=E?'[rel="stylesheet"]':"";if(!!r)for(let p=f.length-1;p>=0;p--){const h=f[p];if(h.href===b&&(!E||h.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${b}"]${g}`))return;const a=document.createElement("link");if(a.rel=E?"stylesheet":Bn,E||(a.as="script"),a.crossOrigin="",a.href=b,d&&a.setAttribute("nonce",d),document.head.appendChild(a),E)return new Promise((p,h)=>{a.addEventListener("load",p),a.addEventListener("error",()=>h(new Error(`Unable to preload CSS for ${b}`)))})}))}function i(o){const f=new Event("vite:preloadError",{cancelable:!0});if(f.payload=o,window.dispatchEvent(f),!f.defaultPrevented)throw o}return s.then(o=>{for(const f of o||[])f.status==="rejected"&&i(f.reason);return t().catch(i)})},yt="2.0.7",He=e=>{const t=e==null?void 0:e.match(/^(\d+)\.\d+\.\d+/);return t?Number(t[1]):null},zn=(e,t)=>He(e)!==null&&He(e)===He(t),Wn=(e,t="woff2")=>{const n=/^\/\/ fonts: (.+)$/m.exec(e);if(!n)return[];const r=[];for(const s of n[1].split(";")){const i=s.indexOf("=");if(i===-1)continue;const o=/^(.+)@(\d+)(i?)$/.exec(s.slice(0,i));o&&r.push({family:o[1],weight:parseInt(o[2],10),italic:o[3]==="i",url:s.slice(i+1).replace("{fmt}",t)})}return r},Gn=async(e,t,n=2e3)=>{const r=t??(typeof document>"u"?void 0:document);if(!(r!=null&&r.fonts)||e.length===0)return;const s=[];for(const i of e)try{const o=new FontFace(i.family,`url("${i.url}")`,{weight:String(i.weight),style:i.italic?"italic":"normal"});r.fonts.add(o),s.push(o.load().catch(()=>{}))}catch{}await Promise.race([Promise.all(s),new Promise(i=>setTimeout(i,n))])},jn=e=>{var l,d,b,E;const t=e.slice(0,2e3),n=new Set,r=t.match(/\/\/ preload: (.+)/);if(r)for(const g of r[1].split(";"))n.add(g);const s=t.includes("// gl: disable")?"off":t.includes("// gl: defer")?"defer":"on",i=((l=t.match(/^\/\/ sdk: (\d+\.\d+\.\d+\S*)/m))==null?void 0:l[1])??null,o=((b=(d=t.match(/^\/\/ name: (.+)$/m))==null?void 0:d[1])==null?void 0:b.trim())??null,f=new Set((((E=t.match(/^\/\/ plugins: (.+)$/m))==null?void 0:E[1])??"").split(";").map(g=>g.trim()).filter(Boolean));return{sdk:i,name:o,preloads:n,gl:s,is2d:t.includes("// 2d: enable"),plugins:f,bootFonts:Wn(t)}},Hn=1,Kn=2,Yn=3,qn=4,Xn=5,Jn=6,Et=7,Qn=8,vt=9,Zn=10,er=11,tr=12,nr=13,rr=14,or=15,sr=16,wt=17,ir=18,ar=19,xe=20,ri=21,oi=22,si=23,ii=24,ai=25,cr=26,lr=27,ur=28,fr=29,St=30,_t=31,dr=32,pr=33,Tt=34,kt=35,Oe=1,mr=2,hr=4,le=8,gr=16,Ke=32,br=64,Ye=128,yr=256,Er=512,vr=1024,wr=2048,Sr=4096,Lt=8192,ci=16384,_r=32768,Tr=1<<18,kr=255,xt=256,Rt=512,Lr=1024,Y=0,xr=1,Rr=2,Cr=3,Me=4,Ue=255,sn=e=>{const t=e.clientWidth;if(!t)return 1;const n=e.getBoundingClientRect().width;return n>0?n/t:1},Ct={text:{type:"text"},password:{type:"password"},search:{type:"search"},tel:{type:"tel"},email:{type:"email"},url:{type:"url"},number:{type:"text",mode:"numeric"},decimal:{type:"text",mode:"decimal"},date:{type:"date"},time:{type:"time"}},At=(e,t)=>e==null?t:e===!0||e==="true"||e==="1"||typeof e=="number"&&e>.5,Z=(e,t,n)=>{n===null?e.removeAttribute(t):e.getAttribute(t)!==n&&e.setAttribute(t,n)},Ar=(e,t)=>{if(e.type!=="input"&&e.type!=="textarea")return;const n=e.el,r=t("placeholder");if(Z(n,"placeholder",r==null?null:String(r)),e.type==="input"){const f=Ct[String(t("type")??"text")]??Ct.text,l=n;l.type!==f.type&&(l.type=f.type),Z(n,"inputmode",f.mode??null);const d=t("enterKey");Z(n,"enterkeyhint",d==null?null:String(d))}const s=t("autocapitalize");Z(n,"autocapitalize",s==null?null:String(s));const i=t("autocorrect");i==null?(Z(n,"autocorrect",null),Z(n,"spellcheck",null)):(Z(n,"autocorrect",At(i,!0)?"on":"off"),Z(n,"spellcheck",At(i,!0)?"true":"false"));const o=Number(t("maxLength")??0);Z(n,"maxlength",o>0?String(Math.round(o)):null)},Pe={width:"layout",height:"layout",minWidth:"layout",minHeight:"layout",maxWidth:"layout",maxHeight:"layout",flexBasis:"layout",flexGrow:"layout",flexShrink:"layout",aspectRatio:"layout",gap:"layout",rowGap:"layout",columnGap:"layout",padding:"layout",paddingTop:"layout",paddingRight:"layout",paddingBottom:"layout",paddingLeft:"layout",paddingHorizontal:"layout",paddingVertical:"layout",paddingStart:"layout",paddingEnd:"layout",margin:"layout",marginTop:"layout",marginRight:"layout",marginBottom:"layout",marginLeft:"layout",marginHorizontal:"layout",marginVertical:"layout",marginStart:"layout",marginEnd:"layout",left:"layout",right:"layout",top:"layout",bottom:"layout",start:"layout",end:"layout",inset:"layout",flexDirection:"enum",justifyContent:"enum",alignItems:"enum",alignSelf:"enum",position:"enum",flexWrap:"enum",boxSizing:"enum",display:"enum",overflow:"enum",scrollDirection:"enum",borderWidth:"len",borderTopWidth:"len",borderRightWidth:"len",borderBottomWidth:"len",borderLeftWidth:"len",borderHorizontalWidth:"len",borderVerticalWidth:"len",borderStartWidth:"len",borderEndWidth:"len",color:"color",backgroundColor:"color",borderColor:"color",borderTopColor:"color",borderRightColor:"color",borderBottomColor:"color",borderLeftColor:"color",placeholderColor:"color",refreshControlColor:"color",tintColor:"color",rippleColor:"color",overlayColor:"color",backgroundImage:"str",backgroundSize:"enum",backgroundGradient:"str",borderRadius:"len",borderTopLeftRadius:"len",borderTopRightRadius:"len",borderBottomRightRadius:"len",borderBottomLeftRadius:"len",opacity:"num",transform:"str",transformOrigin:"str",pointerEvents:"enum",fontSize:"len",fontWeight:"num",fontStyle:"enum",fontFamily:"str",lineHeight:"len",letterSpacing:"len",textAlign:"enum",textDecoration:"enum",lineClamp:"num",textOverflow:"enum",objectFit:"enum",placeholder:"str",type:"enum",enterKey:"enum",autocapitalize:"enum",autocorrect:"num",maxLength:"num",keyboardShrink:"num",keyboardDismiss:"num",showScrollbar:"num",overscrollMode:"enum",keyboardDismissMode:"enum",snap:"enum",sheetDetents:"str",sheetDetent:"num",sheetDismissible:"num",dim:"num"},$r={p:"padding",pt:"paddingTop",pr:"paddingRight",pb:"paddingBottom",pl:"paddingLeft",px:"paddingHorizontal",py:"paddingVertical",m:"margin",mt:"marginTop",mr:"marginRight",mb:"marginBottom",ml:"marginLeft",mx:"marginHorizontal",my:"marginVertical",bgColor:"backgroundColor",bgImage:"backgroundImage",bgSize:"backgroundSize",bgGradient:"backgroundGradient"},Or=["placeholderColor","refreshControlColor","tintColor","rippleColor","overlayColor","backgroundGradient"],Ur={display:"flex",overflow:"visible",scrollDirection:"vertical",borderWidth:0,borderTopWidth:0,borderRightWidth:0,borderBottomWidth:0,borderLeftWidth:0,borderHorizontalWidth:0,borderVerticalWidth:0,borderStartWidth:0,borderEndWidth:0,backgroundColor:0,borderColor:0,borderTopColor:0,borderRightColor:0,borderBottomColor:0,borderLeftColor:0,backgroundImage:"",backgroundSize:"cover",borderRadius:0,borderTopLeftRadius:0,borderTopRightRadius:0,borderBottomRightRadius:0,borderBottomLeftRadius:0,opacity:1,transform:"identity",transformOrigin:"50% 50%",pointerEvents:"all",fontSize:14,fontWeight:400,fontStyle:"normal",lineHeight:"normal",letterSpacing:0,textAlign:"start",textDecoration:"none",lineClamp:0,textOverflow:"ellipsis",objectFit:"cover",placeholder:"",type:"text",enterKey:"done",autocapitalize:"sentences",autocorrect:1,maxLength:0,keyboardShrink:1,keyboardDismiss:1,showScrollbar:1,overscrollMode:"default",keyboardDismissMode:"interactive",snap:"none",sheetDetents:"",sheetDetent:0,sheetDismissible:1,dim:0},Nr=["duration","delay","layer","commit","loop","loopMode","name"];function an(e){let t=e.trim();/\sxmlns\s*=/.test(t)||(t=t.replace(/<svg\b/,'<svg xmlns="http://www.w3.org/2000/svg"'));const n=new TextEncoder().encode(t);let r="";for(const s of n)r+=String.fromCharCode(s);return`data:image/svg+xml;base64,${btoa(r)}`}function Fr(e){const t=e.match(/viewBox\s*=\s*["']([^"']+)["']/);return t?t[1]:null}const Mr=/\b(?:calc|min|max|clamp)\(/,Pr=e=>{if(!Mr.test(e))return e;let t="";for(let n=0;n<e.length;n++){if(e.startsWith("var(",n)){let s=0;const i=n;for(;n<e.length;n++)if(e[n]==="(")s++;else if(e[n]===")"&&--s===0)break;t+=e.slice(i,Math.min(n+1,e.length));continue}const r=e[n];if(r==="+"||r==="-"){const s=t[t.length-1]??"";if(!(r==="-"&&(s==="e"&&"btlr".includes(e[n+1]??"")||e.slice(Math.max(0,n-7),n)==="comfort"))&&/[\w%.)]/.test(s)){for(t=t.trimEnd()+" "+r+" ";e[n+1]===" ";)n++;continue}}t+=r}return t.replace(/\d*\.\d+|\d+/g,(n,r,s)=>{const i=s.slice(0,r).trimEnd(),o=s.slice(r+n.length).trimStart();return/[\w.%]$/.test(i)||/^[\w.%]/.test(o)||/[*/]$/.test(i)||/^[*/]/.test(o)?n:n+"px"})},Ir={top:"12px",bottom:"4px",left:"16px",right:"16px"},cn=e=>`max(var(--safe-${e}, 0px), calc(var(--safe-${e}-bar, 0px) + var(--comfort-${e}, ${Ir[e]})))`,Dr={vw:"cqw",vh:"cqh",vmin:"cqmin",vmax:"cqmax"},Te=e=>Pr(e).replace(new RegExp("(?<![-\\w])comfort-(top|bottom|left|right)\\b","g"),(t,n)=>cn(n)).replace(new RegExp("(?<![-\\w])safe-(top|bottom|left|right)\\b","g"),(t,n)=>`var(--safe-${n}, 0px)`).replace(/(\d)(vmin|vmax|vw|vh)\b/g,(t,n,r)=>n+Dr[r]),ft=/^-?\d*\.?\d+$/,ee=e=>{if(typeof e=="number")return e+"px";const t=String(e).trim();return ft.test(t)?t+"px":Te(t)},ke=e=>{if(typeof e=="number")return"#"+(e>>>0).toString(16).padStart(e<=16777215?6:8,"0");const t=String(e);return t==="clear"?"transparent":t},Br=/^(rotate|skew)/,Vr=/^translate/,zr=e=>{const t=String(e).trim();return t===""||t==="identity"?"none":t.replace(/([a-zA-Z0-9]+)\s*\(([^)]*)\)/g,(n,r,s)=>{const i=Vr.test(r)?"px":Br.test(r)?"deg":null;return i===null?n:`${r}(${s.split(",").map(o=>{const f=o.trim();return ft.test(f)?f+i:Te(f)}).join(", ")})`})},ln=e=>typeof e=="number"?e+"px":String(e).trim().split(/\s+/).map(t=>ft.test(t)?t+"px":Te(t)).join(" "),J=0,Q=1,ve=2,Ne=["top","right","bottom","left"],Wr=(e,t)=>e==="safe-all"?`var(--safe-${t}, 0px)`:e==="comfort-all"||e==="comfort-x"||e==="comfort-y"?cn(t):ee(e),st=(e,t)=>{const n=(s,i)=>({rank:i,to:o=>s.map(f=>[t(f),Wr(o,f)])}),r=s=>({rank:Q,to:i=>[[t(s),ee(i)]]});return{[e]:n(Ne,J),[`${e}Horizontal`]:n(["left","right"],Q),[`${e}Vertical`]:n(["top","bottom"],Q),[`${e}Start`]:r("inline-start"),[`${e}End`]:r("inline-end"),[`${e}Top`]:n(["top"],ve),[`${e}Right`]:n(["right"],ve),[`${e}Bottom`]:n(["bottom"],ve),[`${e}Left`]:n(["left"],ve)}},Gr=()=>{const e=st("border",n=>`border-${n}-width`),t={};for(const n of Object.keys(e))t[`${n}Width`]=e[n];return t},dt=e=>{const t=[];let n=0,r="";for(const s of e.trim()){if(s==="("&&n++,s===")"&&n--,/\s/.test(s)&&n===0){r&&t.push(r),r="";continue}r+=s}return r&&t.push(r),t},jr=new Set(["none","solid","dashed","dotted","double","hidden"]),Hr=/^-?\d*\.?\d+([a-z%]*)$|^(calc|min|max|clamp)\(/,ye=(e,t)=>({rank:t,to:n=>{let r=null,s=null,i=null;if(typeof n=="number")r=n+"px";else for(const f of dt(String(n)))jr.has(f)?i=f:Hr.test(f)?r=ee(f):s=ke(f);const o=[];for(const f of e)o.push([`border-${f}-width`,r??(s?"1px":"0px")]),o.push([`border-${f}-color`,s??"transparent"]),i&&o.push([`border-${f}-style`,i]);return o}}),Kr=e=>{const t=String(e).trim(),n=(i,o,f)=>[["flex-grow",i],["flex-shrink",o],["flex-basis",f]];if(t==="none")return n("0","0","auto");if(t==="auto")return n("1","1","auto");if(t==="initial")return n("0","1","auto");const r=dt(t),s=i=>i!==void 0&&/^-?\d*\.?\d+$/.test(i);return s(r[0])?r.length===1?n(r[0],"1","0%"):s(r[1])?n(r[0],r[1],r[2]!==void 0?ee(r[2]):"0%"):n(r[0],"1",ee(r[1])):n("1","1",ee(r[0]??"auto"))},un=e=>{var t;return typeof e=="object"&&e!==null&&"_h"in e&&typeof((t=e._h)==null?void 0:t.id)=="number"},Yr=e=>e.replace(/<svg\b[^>]*>/,t=>t.replace(/\spreserveAspectRatio\s*=\s*("[^"]*"|'[^']*')/,"").replace(/^<svg\b/,'<svg preserveAspectRatio="none"')),fn=(e,t)=>{if(un(e))return`url("${t.bufferUrl(e._h.id)}")`;const n=String(e??"");return n===""?"none":n.startsWith("id:")?`url("${t.bufferUrl(Number(n.slice(3)))}")`:n.startsWith("svg:")?`url("${an(Yr(n.slice(4)))}")`:`url("${n.replace(/["\\\n]/g,r=>"\\"+r)}")`},qr=/^\s*(repeating-)?(linear|radial|conic)-gradient\(/,dn=e=>{const t=String(e??"").trim();return t===""?"none":Te(t)},Xr=(e,t)=>{const n=typeof e=="string"&&qr.test(e),r=un(e)||typeof e=="string"&&/^(id:|https?:|data:|blob:|\.{0,2}\/)/.test(e);return[["--lc-bg-grad",n?dn(e):"none"],["--lc-bg-img",r?fn(e,t):"none"],["background-color",n||r?"transparent":ke(e)]]},Jr=e=>{const t=typeof e=="number"?[e+"px"]:dt(String(e)).map(o=>ln(o)),[n,r=n,s=n,i=r]=t;return[["border-top-left-radius",n??"0px"],["border-top-right-radius",r??"0px"],["border-bottom-right-radius",s??"0px"],["border-bottom-left-radius",i??"0px"]]},Qr=new Set(["serif","sans-serif","monospace","cursive","fantasy","system-ui","ui-monospace","ui-sans-serif","ui-serif","inherit"]),Zr=e=>{const t=String(e).trim();return t==="monospaced"?"monospace":t.startsWith("var(")||t.includes(",")||/^["']/.test(t)||Qr.has(t)?t:`"${t.replace(/"/g,'\\"')}"`},eo=e=>e===!0||e==="true"||typeof e=="number"&&e>.5||e==="1",to=e=>t=>e[String(t)]??String(t),Le={width:{css:"width",as:"len"},height:{css:"height",as:"len"},minWidth:{css:"min-width",as:"len"},minHeight:{css:"min-height",as:"len"},maxWidth:{css:"max-width",as:"len"},maxHeight:{css:"max-height",as:"len"},flexBasis:{css:"flex-basis",as:"len"},flexGrow:{css:"flex-grow",as:"num"},flexShrink:{css:"flex-shrink",as:"num"},aspectRatio:{css:"aspect-ratio",as:"num"},gap:{css:["row-gap","column-gap"],as:"len",rank:J},rowGap:{css:"row-gap",as:"len"},columnGap:{css:"column-gap",as:"len"},...st("padding",e=>`padding-${e}`),...st("margin",e=>`margin-${e}`),inset:{css:Ne,as:"len",rank:J},top:{css:"top",as:"len"},right:{css:"right",as:"len"},bottom:{css:"bottom",as:"len"},left:{css:"left",as:"len"},start:{css:"inset-inline-start",as:"len",rank:Q},end:{css:"inset-inline-end",as:"len",rank:Q},flexDirection:{css:"flex-direction",as:"raw"},justifyContent:{css:"justify-content",as:"raw"},alignItems:{css:"align-items",as:"raw"},alignSelf:{css:"align-self",as:"raw"},position:{css:"position",as:"raw"},flexWrap:{css:"flex-wrap",as:"raw"},boxSizing:{css:"box-sizing",as:"raw"},display:{css:"display",as:"raw"},overflow:{rank:J,to:e=>{const t=e==="scroll"?"auto":String(e);return[["overflow-x",t],["overflow-y",t]]}},scrollDirection:{to:e=>e==="horizontal"?[["overflow-x","auto"],["overflow-y","hidden"],["flex-direction","row"]]:e==="all"?[["overflow-x","auto"],["overflow-y","auto"]]:[["overflow-x","hidden"],["overflow-y","auto"],["flex-direction","column"]],rank:Q},...Gr(),color:{css:"color"},backgroundColor:{css:"background-color"},borderColor:{css:Ne.map(e=>`border-${e}-color`),rank:J},borderTopColor:{css:"border-top-color"},borderRightColor:{css:"border-right-color"},borderBottomColor:{css:"border-bottom-color"},borderLeftColor:{css:"border-left-color"},placeholderColor:{css:"--lc-placeholder"},refreshControlColor:{css:"--lc-refresh"},tintColor:{css:"--lc-tint"},overlayColor:{css:"--lc-overlay"},rippleColor:{none:"a browser has no ripple: the press feedback of a page is `$pressed`"},backgroundImage:{to:(e,t)=>[["--lc-bg-img",fn(e,t)]]},backgroundGradient:{to:e=>[["--lc-bg-grad",dn(e)]]},backgroundSize:{to:e=>e==="tile"?[["background-size","auto"],["background-repeat","repeat"],["background-position","0 0"]]:[["background-size",e==="fill"?"100% 100%":String(e)],["background-repeat","no-repeat"],["background-position","center"]]},borderRadius:{to:Jr,rank:J},borderTopLeftRadius:{css:"border-top-left-radius"},borderTopRightRadius:{css:"border-top-right-radius"},borderBottomRightRadius:{css:"border-bottom-right-radius"},borderBottomLeftRadius:{css:"border-bottom-left-radius"},opacity:{css:"opacity"},transform:{to:e=>[["transform",zr(e)]]},transformOrigin:{css:"transform-origin",as:"lens"},pointerEvents:{to:e=>[["pointer-events",e==="none"?"none":"auto"]]},dim:{css:"--lc-dim"},fontSize:{css:"font-size"},fontWeight:{css:"font-weight",as:"raw"},fontStyle:{to:e=>[["font-style",e===2?"italic":e===0?"normal":String(e)]]},fontFamily:{to:e=>[["font-family",Zr(e)]]},lineHeight:{to:e=>[["line-height",e==="normal"?"1.2":ee(e)]]},letterSpacing:{css:"letter-spacing"},textAlign:{css:"text-align"},textDecoration:{css:"text-decoration-line"},lineClamp:{rank:J,to:e=>Number(e)>0?[["display","-webkit-box"],["-webkit-box-orient","vertical"],["-webkit-line-clamp",String(Math.round(Number(e)))],["overflow-x","hidden"],["overflow-y","hidden"]]:[["-webkit-line-clamp","none"]]},textOverflow:{css:"text-overflow"},objectFit:{to:e=>[["object-fit",String(e)],["--lc-fit",e==="fill"?"100% 100%":String(e)]]},placeholder:{attr:!0},type:{attr:!0},enterKey:{attr:!0},autocapitalize:{attr:!0},autocorrect:{attr:!0},maxLength:{attr:!0},keyboardShrink:{attr:!0},keyboardDismiss:{attr:!0},showScrollbar:{to:e=>[["scrollbar-width",eo(e)?"thin":"none"]]},overscrollMode:{to:e=>[["overscroll-behavior",to({default:"auto",none:"none",absorb:"contain"})(e)]]},keyboardDismissMode:{attr:!0},snap:{to:e=>e==="none"?[["scroll-snap-type","none"],["--lc-snap","none"]]:[["scroll-snap-type","both mandatory"],["--lc-snap",String(e)]]},sheetDetents:{attr:!0},sheetDetent:{attr:!0},sheetDismissible:{attr:!0},background:{to:Xr,rank:J},border:ye(Ne,J),borderTop:ye(["top"],Q),borderRight:ye(["right"],Q),borderBottom:ye(["bottom"],Q),borderLeft:ye(["left"],Q),flex:{to:Kr,rank:J}},qe=e=>$r[e]??e,no=e=>e in Le,pn=e=>{const t=Le[e];return!!t&&"attr"in t},ro={overflow:"overflow-x",pointerEvents:"pointer-events",fontFamily:"font-family",fontStyle:"font-style",lineHeight:"line-height",objectFit:"object-fit",transform:"transform",borderRadius:"border-top-left-radius",borderWidth:"border-top-width",borderColor:"border-top-color",backgroundImage:"--lc-bg-img",backgroundGradient:"--lc-bg-grad",backgroundSize:"background-size",showScrollbar:"scrollbar-width",overscrollMode:"overscroll-behavior",snap:"--lc-snap",lineClamp:"-webkit-line-clamp",borderTopWidth:"border-top-width",borderRightWidth:"border-right-width",borderBottomWidth:"border-bottom-width",borderLeftWidth:"border-left-width",borderHorizontalWidth:"border-left-width",borderVerticalWidth:"border-top-width",borderStartWidth:"border-inline-start-width",borderEndWidth:"border-inline-end-width"},oo=e=>{const t=Le[e];return t&&"css"in t&&typeof t.css=="string"?t.css:ro[e]??null},so={len:ee,lens:ln,num:e=>String(e),raw:e=>String(e),color:ke},io={color:"color",len:"len",enum:"raw",num:"num",str:"raw",layout:"raw"},$t=e=>{const t=Le[e];return t&&"rank"in t&&t.rank!==void 0?t.rank:ve},Xe=(e,t,n)=>{const r=[...e].filter(([,i])=>i!=null);r.sort((i,o)=>$t(i[0])-$t(o[0]));const s=new Map;for(const[i,o]of r){const f=Le[i];if(!f){n==null||n(i);continue}if("attr"in f||"none"in f)continue;if("to"in f){for(const[b,E]of f.to(o,t))s.set(b,E);continue}const l=so[f.as??io[Pe[i]??"layout"]],d=l(o);if(typeof f.css=="string")s.set(f.css,d);else for(const b of f.css)s.set(b,d)}return s},Ot=e=>[...e].sort((t,n)=>t[0]<n[0]?-1:t[0]>n[0]?1:0).map(([t,n])=>`${t}:${n}`).join(";"),mn=0,hn=1,Se=2,_e=3,gn=4,de=65,Ie=1.70158,Re=Ie*1.525,Ut=Ie+1,Nt=2*Math.PI/3,Ft=2*Math.PI/4.5,Ce=e=>e<1/2.75?7.5625*e*e:e<2/2.75?7.5625*(e-=1.5/2.75)*e+.75:e<2.5/2.75?7.5625*(e-=2.25/2.75)*e+.9375:7.5625*(e-=2.625/2.75)*e+.984375,it=[["linear",e=>e],["inSine",e=>1-Math.cos(e*Math.PI/2)],["outSine",e=>Math.sin(e*Math.PI/2)],["inOutSine",e=>-(Math.cos(Math.PI*e)-1)/2],["inQuad",e=>e*e],["outQuad",e=>1-(1-e)*(1-e)],["inOutQuad",e=>e<.5?2*e*e:1-(-2*e+2)**2/2],["inCubic",e=>e*e*e],["outCubic",e=>1-(1-e)**3],["inOutCubic",e=>e<.5?4*e*e*e:1-(-2*e+2)**3/2],["inQuart",e=>e**4],["outQuart",e=>1-(1-e)**4],["inOutQuart",e=>e<.5?8*e**4:1-(-2*e+2)**4/2],["inExpo",e=>e===0?0:2**(10*e-10)],["outExpo",e=>e===1?1:1-2**(-10*e)],["inOutExpo",e=>e===0?0:e===1?1:e<.5?2**(20*e-10)/2:(2-2**(-20*e+10))/2],["inCirc",e=>1-Math.sqrt(1-e*e)],["outCirc",e=>Math.sqrt(1-(e-1)**2)],["inOutCirc",e=>e<.5?(1-Math.sqrt(1-(2*e)**2))/2:(Math.sqrt(1-(-2*e+2)**2)+1)/2],["inBack",e=>Ut*e*e*e-Ie*e*e],["outBack",e=>1+Ut*(e-1)**3+Ie*(e-1)**2],["inOutBack",e=>e<.5?(2*e)**2*((Re+1)*2*e-Re)/2:((2*e-2)**2*((Re+1)*(e*2-2)+Re)+2)/2],["inElastic",e=>e===0?0:e===1?1:-(2**(10*e-10))*Math.sin((e*10-10.75)*Nt)],["outElastic",e=>e===0?0:e===1?1:2**(-10*e)*Math.sin((e*10-.75)*Nt)+1],["inOutElastic",e=>e===0?0:e===1?1:e<.5?-(2**(20*e-10)*Math.sin((20*e-11.125)*Ft))/2:2**(-20*e+10)*Math.sin((20*e-11.125)*Ft)/2+1],["inBounce",e=>1-Ce(1-e)],["outBounce",Ce],["inOutBounce",e=>e<.5?(1-Ce(1-2*e))/2:(1+Ce(2*e-1))/2],["smoothstep",e=>e*e*(3-2*e)]],ao={in:"inQuad",out:"outQuad",inOut:"inOutQuad",easeIn:"inQuad",easeOut:"outQuad",easeInOut:"inOutQuad","ease-in":"inQuad","ease-out":"outQuad","ease-in-out":"inOutQuad"},co=e=>{const t=ao[e]??e;for(let n=0;n<it.length;n++)if(it[n][0]===t)return n;return-1},lo=[.25,.1,.25,1],Ae={kind:mn,p:[0,0,0,0]},uo=e=>{const t=new Float32Array(de);for(let n=0;n<de;n++)t[n]=e(n/(de-1));return t[0]=0,t[de-1]=1,t},fo=e=>{if(e===void 0)return Ae;if(typeof e=="function")return{kind:gn,p:[0,0,0,0],table:uo(e)};if(Array.isArray(e)){const[s,i,o,f]=e;return{kind:Se,p:[s,i,o,f]}}const t=e.trim();if(t==="linear")return Ae;if(t==="ease")return{kind:Se,p:lo};if(t==="steps")return{kind:_e,p:[1,0,0,0]};let n=/^steps\(\s*(\d+)\s*(?:,\s*(start|end|jump-start|jump-end)\s*)?\)$/.exec(t);if(n)return{kind:_e,p:[Math.max(1,parseInt(n[1],10)),n[2]==="start"||n[2]==="jump-start"?1:0,0,0]};if(n=/^cubic-bezier\(\s*([-\d.e]+)\s*,\s*([-\d.e]+)\s*,\s*([-\d.e]+)\s*,\s*([-\d.e]+)\s*\)$/.exec(t),n)return{kind:Se,p:[parseFloat(n[1]),parseFloat(n[2]),parseFloat(n[3]),parseFloat(n[4])]};const r=co(t);return r===0?Ae:r>0?{kind:hn,p:[r,0,0,0]}:(console.warn(`[tween] unknown easing "${t}" — using linear`),Ae)},po=(e,t,n,r,s)=>{const i=1-3*r+3*t,o=3*r-6*t,f=3*t,l=1-3*s+3*n,d=3*s-6*n,b=3*n;let E=e;for(let g=0;g<8;g++){const m=((i*E+o)*E+f)*E-e,a=(3*i*E+2*o)*E+f;if(Math.abs(m)<1e-6||Math.abs(a)<1e-6)break;E-=m/a}return E=Math.min(1,Math.max(0,E)),((l*E+d)*E+b)*E},mo=(e,t)=>{if(t<=0)return e.kind===_e&&e.p[1]===1?1/e.p[0]:0;if(t>=1)return 1;switch(e.kind){case hn:return it[e.p[0]][1](t);case Se:return po(t,e.p[0],e.p[1],e.p[2],e.p[3]);case _e:{const n=e.p[0];return e.p[1]===1?Math.min(1,Math.ceil(t*n)/n):Math.floor(t*n)/n}case gn:{const n=e.table,r=t*(de-1),s=Math.floor(r),i=n[s],o=n[Math.min(s+1,de-1)];return i+(o-i)*(r-s)}default:return t}},Mt=24,Pt=e=>String(Math.round(e*1e4)/1e4),ho="cubic-bezier(0.3333, 0, 0.6667, 1)",go=e=>{switch(e.kind){case mn:return"linear";case Se:return`cubic-bezier(${e.p.map(Pt).join(", ")})`;case _e:return`steps(${e.p[0]}, ${e.p[1]===1?"jump-start":"jump-end"})`}const t=[];for(let n=0;n<=Mt;n++)t.push(Pt(mo(e,n/Mt)));return`linear(${t.join(", ")})`},bo=e=>e===void 0||e==="smoothstep"?ho:go(fo(e)),bn=["lc-base","lc-bag","lc-own","lc-orient","lc-class","lc-hover","lc-press","lc-focus"],yo=["--lc-bg-grad","--lc-bg-img","--lc-tint","--lc-overlay","--lc-refresh","--lc-fit","--lc-src","--lc-src-tint","--lc-iw","--lc-ih","--lc-ir","--lc-crop-size","--lc-crop-pos"],yn="lc-app",Eo=`
3
3
  @layer ${bn.join(", ")};
4
4
 
5
5
  @layer lc-base {
@@ -7,6 +7,7 @@ import { CliError, bool, c, defineCommand, log, note, readFlags, type Command }
7
7
  import { OPTIONAL_PEERS, peerSource, peerVersion } from "../../hosts/peers"
8
8
  import { installPeers } from "../../hosts/peerInstall"
9
9
  import { archiveSpec, archivedVersion } from "../../hosts/archives"
10
+ import { commandLine, installGlobalArgv, ownManager } from "../../hosts/packageManager"
10
11
  import { updateDesktop } from "../../hosts/desktopRenderer"
11
12
  import { updateMatc } from "../../hosts/matcTool"
12
13
  import { refreshTypes } from "./types"
@@ -94,7 +95,7 @@ const STANDALONE = existsSync(join(dirname(process.execPath), "runtime")) &&
94
95
  export default defineCommand({
95
96
  name: "update",
96
97
  summary: "Move everything the project depends on to its newest published state",
97
- description: "In dependency order: the desktop host (`desktop update`), matc (`shaders update`), the project's shader compiles, the IDE types (.lecodes/types/ + tsconfig.json, from the server — the former `lecodes types`), the ios/android shell pins (`app update`), then the GLOBAL npm installs: every installed optional peer (lecodes-headless, lecodes-design, lecodes-3d-editor, lecodes-assets) and this CLI that is behind npm's latest gets `npm install -g`.\n\nPinned tools are skipped, not overridden: LECODES_DESKTOP_EXE / LECODES_MATC mean a local build. Keeps going when a step fails; the summary says which.",
98
+ description: "In dependency order: the desktop host (`desktop update`), matc (`shaders update`), the project's shader compiles, the IDE types (.lecodes/types/ + tsconfig.json, from the server — the former `lecodes types`), the ios/android shell pins (`app update`), then the GLOBAL installs: every installed optional peer (lecodes-headless, lecodes-design, lecodes-3d-editor, lecodes-assets) and this CLI that is behind npm's latest is installed again, with the package manager the CLI came by (`npm install -g`, or `bun add -g` for a CLI installed with bun).\n\nPinned tools are skipped, not overridden: LECODES_DESKTOP_EXE / LECODES_MATC mean a local build. Keeps going when a step fails; the summary says which.",
98
99
  flags: {
99
100
  local: bool("types from the SDK bundled in this CLI"),
100
101
  "no-shells": bool("leave ios/android pins alone (no re-sync)"),
@@ -159,8 +160,8 @@ export default defineCommand({
159
160
  return "ok"
160
161
  })
161
162
 
162
- // 6. this CLI + its optional peers — the GLOBAL npm installs (`npm install -g`, how the CLI and its
163
- // peers are installed): every installed one that is behind npm's latest moves forward. The peers go
163
+ // 6. this CLI + its optional peers — the GLOBAL installs (`npm install -g` or `bun install -g`,
164
+ // whichever this CLI came by: hosts/packageManager.ts): every installed one that is behind npm's latest moves forward. The peers go
164
165
  // first, the CLI itself last — replacing the running CLI's files is fine (this process already
165
166
  // holds its code), but its new version is what the next invocation runs, so nothing after it here.
166
167
  // Peers that are NOT installed stay that way: they're optional, installing one is a choice.
@@ -195,7 +196,7 @@ export default defineCommand({
195
196
  const prefixBehind = behind.filter((r) => r.where === "prefix")
196
197
  const globalSpecs = await Promise.all(behind.filter((r) => r.where !== "prefix").map(async (r) => await archiveSpec(r.name) ?? r.name + "@latest"))
197
198
  if (flags.check) {
198
- return ["updated", behind.length + " behind — run: lecodes update" + (globalSpecs.length ? " (global: npm install -g " + globalSpecs.join(" ") + ")" : "")]
199
+ return ["updated", behind.length + " behind — run: lecodes update" + (globalSpecs.length ? " (global: " + commandLine(ownManager(), installGlobalArgv(ownManager(), globalSpecs)) + ")" : "")]
199
200
  }
200
201
  const done: string[] = []
201
202
  if (prefixBehind.length) {
@@ -207,9 +208,13 @@ export default defineCommand({
207
208
  }
208
209
  const toInstall = STANDALONE ? globalSpecs.filter((s) => !s.startsWith("lecodes-cli@")) : globalSpecs
209
210
  if (toInstall.length) {
210
- log(" " + c.dim("$") + " npm install -g " + toInstall.join(" "))
211
- const r = spawnSync("npm", ["install", "-g", ...toInstall], { stdio: "inherit", shell: true })
212
- if (r.status !== 0) throw new CliError("npm install -g exited with " + (r.status ?? "a signal"))
211
+ // with the manager this CLI was installed by: another one's global dir is another copy
212
+ const tool = ownManager()
213
+ const argv = installGlobalArgv(tool, toInstall)
214
+ log(" " + c.dim("$") + " " + commandLine(tool, argv))
215
+ const r = spawnSync(tool, argv, { stdio: "inherit", shell: true })
216
+ if (r.error) throw new CliError(tool + " could not run: " + r.error.message)
217
+ if (r.status !== 0) throw new CliError(commandLine(tool, argv.slice(0, 2)) + " exited with " + (r.status ?? "a signal"))
213
218
  done.push(...behind.filter((r) => r.where !== "prefix" && (!STANDALONE || r.name !== "lecodes-cli")).map((r) => r.name))
214
219
  }
215
220
  if (done.length === 0) return ["skipped", "only the standalone CLI itself is behind — download the release"]
@@ -87,7 +87,7 @@ export const refreshTypes = async (opts: RefreshTypesOptions): Promise<void> =>
87
87
  // The compiler uses the SDK vendored in this CLI, not these declarations — worth saying when the
88
88
  // server's surface is a different one, since that gap shows up as "autocompletes but won't build".
89
89
  if (!opts.local && local && bundleHash(local) !== bundleHash(bundle)) {
90
- warn("The server's SDK surface differs from the one this CLI compiles with — if something autocompletes but fails to compile, update the CLI (`npm install -g lecodes-cli@latest`) or re-run with --local.")
90
+ warn("The server's SDK surface differs from the one this CLI compiles with — if something autocompletes but fails to compile, update the CLI (`lecodes update`) or re-run with --local.")
91
91
  }
92
92
 
93
93
  log("")
@@ -3,6 +3,8 @@ import { createRequire } from "node:module"
3
3
  import { dirname, join } from "node:path"
4
4
  import type { FileKind } from "../project/manifest"
5
5
  import { distRoot } from "../hosts/distRoot"
6
+ import { installPeers } from "../hosts/peerInstall"
7
+ import { peerDirInPrefix } from "../hosts/peers"
6
8
  import {
7
9
  compileProject as sdkCompileProject, compileServerBundle, detectEntry, isServerPath, scanModulesChisel, localAssetNames, ENTRY_CONVENTION,
8
10
  type CompileServerOptions,
@@ -123,40 +125,43 @@ export const compileProject = (opts: CompileOptions): Promise<string> =>
123
125
  export const hasServerFiles = (entries: CompileEntry[]): boolean =>
124
126
  entries.some((e) => e.type === "text" && isServerPath(e.path))
125
127
 
126
- /** TypeScript with its lib files on disk — the endpoint validators are derived by its checker. The
127
- * project's own, else what this CLI's install can see; null when there is none. */
128
- const findTypescript = (root: string): CompileServerOptions["typescript"] | null => {
129
- for (const from of [join(root, "package.json"), import.meta.url]) {
130
- try {
131
- const mod = createRequire(from)("typescript")
132
- const ts = mod?.createProgram ? mod : mod?.default
133
- if (ts?.createProgram) return ts
134
- } catch { /* the next place */ }
128
+ type Typescript = NonNullable<CompileServerOptions["typescript"]>
129
+
130
+ /** TypeScript with its lib files on disk — the server code is checked, and the endpoint validators
131
+ * derived, by its checker. The project's own, else one this CLI's install can see, else the CLI's
132
+ * peer (installed on first use, like the database engine). One WITHOUT the compiler API is passed
133
+ * over: TypeScript 7 — what `install typescript` brings today — is the native compiler, with no
134
+ * `createProgram` to call. */
135
+ const findTypescript = async (root: string): Promise<Typescript> => {
136
+ const api = (mod: any): Typescript | null => mod?.createProgram ? mod : mod?.default?.createProgram ? mod.default : null
137
+ const from = (at: string): Typescript | null => {
138
+ try { return api(createRequire(at)("typescript")) } catch { return null }
139
+ }
140
+ // The peer is loaded by the PATH of its entry, and only once it is on disk: a lookup by name that
141
+ // missed before the install is remembered by the runtime, and would miss again right after it.
142
+ const dir = peerDirInPrefix("typescript")
143
+ const peer = (): Typescript | null => {
144
+ if (!existsSync(join(dir, "package.json"))) return null
145
+ try { return api(createRequire(import.meta.url)(join(dir, "lib", "typescript.js"))) } catch { return null }
135
146
  }
136
- return null
147
+ const found = from(join(root, "package.json")) ?? from(import.meta.url) ?? peer()
148
+ if (found) return found
149
+ await installPeers(["typescript"], "The project's server code (*.server.ts)")
150
+ return peer() ?? (() => { throw new Error(`The typescript installed in ${dir} has no compiler API`) })()
137
151
  }
138
152
 
139
153
  /**
140
154
  * The project's server bundle (its `*.server.ts` files and what they import), or null when it has
141
- * none. `app` = app.json's name (the sign-in mail). Without a TypeScript to derive them with the
142
- * bundle carries no argument validators — said through `onWarning`, since the deployed backend
143
- * (the le.codes build) does check them.
155
+ * none. `app` = app.json's name (the sign-in mail). Always checked with TypeScript, the way the
156
+ * le.codes build checks it: an endpoint that is not async, an unawaited `requireUser()` are errors
157
+ * only the checker finds.
144
158
  */
145
- export const compileServer = async (opts: { entries: CompileEntry[], root: string, app?: CompileServerOptions["app"], onWarning?: (message: string) => void }) => {
146
- const typescript = findTypescript(opts.root)
147
- if (!typescript) {
148
- // Sign-in rests on a check only the compiler makes: `db.auth.requireUser()` is a query, and one that is
149
- // not awaited guards nothing. A server with sign-in is not built without it.
150
- const signIn = opts.entries.find((e) => e.type === "text" && isServerPath(e.path) && /\.withAuth\s*\(/.test(e.text ?? ""))
151
- if (signIn) throw new Error(`${signIn.path} uses sign-in (withAuth): its server code is checked with TypeScript, and none was found — npm install --save-dev typescript in the project.`)
152
- opts.onWarning?.("Endpoint arguments are not checked against their types here: no TypeScript found (npm install --save-dev typescript in the project).")
153
- }
154
- return compileServerBundle({
159
+ export const compileServer = async (opts: { entries: CompileEntry[], root: string, app?: CompileServerOptions["app"] }) =>
160
+ compileServerBundle({
155
161
  entries: opts.entries.map((e) => ({ path: e.path, type: e.type as any, text: e.text })),
156
162
  app: opts.app,
157
- ...(typescript ? { typescript } : { validate: false }),
163
+ typescript: await findTypescript(opts.root),
158
164
  })
159
- }
160
165
 
161
166
  /** Re-exported so the CALLERS that stage files next to the bundle name them the way the bundle asks
162
167
  * for them (see localAssetNames in the SDK compile — two packs shipping SM_Sign_01.glb). */
@@ -187,7 +187,7 @@ export const startDevServer = async (options: DevServerOptions): Promise<DevServ
187
187
  if (ambiguous) warnings.push(ambiguous)
188
188
  }
189
189
  const onWarning = (w: string) => { warnings.push(w) }
190
- const serverBundle = await backend.compile(entries, onWarning)
190
+ const serverBundle = await backend.compile(entries)
191
191
  const js = await compileProject({ entries, name, publicUrl: origin, entryOverride, header: true, fontsHeader, iconsHeader, onWarning, serverUrl: serverBundle ? serverUrl : undefined })
192
192
  // the backend takes the new bundle once the app compiled, and before devices are told to reload
193
193
  warnings.push(...await backend.run(serverBundle))
@@ -33,7 +33,7 @@ export type ProjectBackendOptions = {
33
33
 
34
34
  export type ProjectBackend = {
35
35
  /** The server bundle of these entries; null when the project has no server files. */
36
- compile: (entries: CompileEntry[], onWarning: (w: string) => void) => Promise<ServerBundle | null>
36
+ compile: (entries: CompileEntry[]) => Promise<ServerBundle | null>
37
37
  /** Run this bundle from now on (null = the project has no server side any more: stop). Rejects
38
38
  * when it does not load; resolves to what to tell the developer. */
39
39
  run: (bundle: ServerBundle | null) => Promise<string[]>
@@ -75,11 +75,11 @@ export const createProjectBackend = (options: ProjectBackendOptions): ProjectBac
75
75
  const envelope = (body: unknown) => new Response(JSON.stringify(body), { status: 200, headers: { "content-type": "application/json", "cache-control": "no-store", ...CORS } })
76
76
 
77
77
  return {
78
- compile: async (entries, onWarning) => {
78
+ compile: async (entries) => {
79
79
  if (!hasServerFiles(entries)) return null
80
80
  // the app's name, for the sign-in mail
81
81
  const app = readAppConfigAt(root)
82
- return compileServer({ entries, root, app: app ? { name: app.name } : undefined, onWarning })
82
+ return compileServer({ entries, root, app: app ? { name: app.name } : undefined })
83
83
  },
84
84
  run: async (bundle) => {
85
85
  if (!bundle) {
@@ -182,7 +182,7 @@ export const runBackend = (options: { root: string, command: string, log: (msg:
182
182
 
183
183
  return {
184
184
  start: async (entries, onWarning) => {
185
- const bundle = await backend.compile(entries, onWarning)
185
+ const bundle = await backend.compile(entries)
186
186
  if (!bundle) return undefined
187
187
  for (const w of await backend.run(bundle)) onWarning(w)
188
188
  // the project's port when it is free (two runs of one project at once: the second takes any)
@@ -0,0 +1,45 @@
1
+ import { spawnSync } from "node:child_process"
2
+ import { homedir } from "node:os"
3
+ import { join, resolve, sep } from "node:path"
4
+ import { fileURLToPath } from "node:url"
5
+
6
+ /*
7
+ * ONE answer to "which package manager installs things for this CLI": the one the CLI itself was
8
+ * installed with. A CLI under bun's global dir (`bun install -g lecodes-cli`) installs its peers and
9
+ * updates itself with bun; any other install goes through npm. Mixing them is the failure this
10
+ * removes: `npm install -g lecodes-cli@latest` beside a bun-installed CLI puts a SECOND copy in npm's
11
+ * prefix and leaves the `lecodes` on PATH as old as it was.
12
+ */
13
+ export type PackageManager = "npm" | "bun"
14
+
15
+ const onPath = (cmd: string): boolean => {
16
+ try { return spawnSync(cmd, ["--version"], { stdio: "ignore", shell: process.platform === "win32" }).status === 0 } catch { return false }
17
+ }
18
+
19
+ /** Bun's global install dir (`BUN_INSTALL` moves it). */
20
+ const bunGlobalDir = (): string => join(process.env.BUN_INSTALL ? resolve(process.env.BUN_INSTALL) : join(homedir(), ".bun"), "install", "global")
21
+
22
+ /** The manager that owns the install this file runs from. */
23
+ export const ownManager = (file = fileURLToPath(import.meta.url)): PackageManager => {
24
+ const norm = (p: string) => process.platform === "win32" ? p.toLowerCase() : p
25
+ return norm(resolve(file)).startsWith(norm(bunGlobalDir()) + sep) ? "bun" : "npm"
26
+ }
27
+
28
+ /** The manager to install with: the CLI's own, else whichever of the two is on PATH; null = neither. */
29
+ export const pickManager = (): PackageManager | null => {
30
+ const own = ownManager()
31
+ const other = own === "npm" ? "bun" : "npm"
32
+ return onPath(own) ? own : onPath(other) ? other : null
33
+ }
34
+
35
+ /** `<tool> <argv>` that installs `specs` into the directory `dir` (a private prefix with a package.json). */
36
+ export const installIntoArgv = (tool: PackageManager, dir: string, specs: string[]): string[] =>
37
+ tool === "npm" ? ["install", "--prefix", dir, "--no-audit", "--no-fund", "--loglevel=error", ...specs] : ["add", "--cwd", dir, ...specs]
38
+
39
+ /** `<tool> <argv>` that installs `specs` globally. */
40
+ export const installGlobalArgv = (tool: PackageManager, specs: string[]): string[] =>
41
+ tool === "npm" ? ["install", "-g", ...specs] : ["add", "-g", ...specs]
42
+
43
+ /** The same, as a line a person can run. */
44
+ export const commandLine = (tool: PackageManager, argv: string[]): string =>
45
+ `${tool} ${argv.map((a) => /\s/.test(a) ? `"${a}"` : a).join(" ")}`
@@ -5,6 +5,7 @@ import { pathToFileURL } from "node:url"
5
5
  import pkg from "../../package.json"
6
6
  import { peerDirInPrefix, peersDir, peerVersionGlobal } from "./peers"
7
7
  import { archiveSpec } from "./archives"
8
+ import { commandLine, installGlobalArgv, installIntoArgv, ownManager, pickManager } from "./packageManager"
8
9
  import { CliError, c, confirm, log, note } from "../cli"
9
10
 
10
11
  /*
@@ -19,8 +20,9 @@ import { CliError, c, confirm, log, note } from "../cli"
19
20
  *
20
21
  * Consent: an interactive terminal is asked (default yes); `--yes` / `-y` on any command or
21
22
  * LECODES_YES=1 (CI) skips the question; a non-interactive run without either fails with the exact
22
- * command to run by hand. Installer: npm if on PATH, else bun; neither → a clear error (the standalone
23
- * binary on a machine without Node can't install packages — it says so).
23
+ * command to run by hand. Installer: the package manager this CLI was installed with (./packageManager.ts
24
+ * — bun for a `bun install -g` CLI, npm otherwise), else the other one; neither → a clear error (the
25
+ * standalone binary on a machine without Node can't install packages — it says so).
24
26
  *
25
27
  * Search order when a command needs a peer: the bare specifier (global / the workspace — what the
26
28
  * user installed by hand always wins) → the prefix → install into the prefix, then load from there.
@@ -48,12 +50,7 @@ export const peerSpec = async (name: string): Promise<string> => {
48
50
  /** Peers that only make sense together: the renderer's PNG output needs canvas next to it. */
49
51
  const companions = (name: string): string[] => name === "lecodes-headless" ? ["lecodes-headless", "@napi-rs/canvas"] : [name]
50
52
 
51
- const onPath = (cmd: string): boolean => {
52
- try { return spawnSync(cmd, ["--version"], { stdio: "ignore", shell: process.platform === "win32" }).status === 0 } catch { return false }
53
- }
54
- const pickInstaller = (): "npm" | "bun" | null => onPath("npm") ? "npm" : onPath("bun") ? "bun" : null
55
-
56
- const manualCommand = (dir: string, specs: string[]) => `npm install --prefix "${dir}" ${specs.join(" ")}`
53
+ const manualCommand = (dir: string, specs: string[]) => commandLine(ownManager(), installIntoArgv(ownManager(), dir, specs))
57
54
 
58
55
  /**
59
56
  * Install peers into the prefix. Asks for consent unless `opts.yes` / LECODES_YES / `--yes` say so;
@@ -86,14 +83,12 @@ export const installPeers = async (names: string[], why: string, opts: { yes?: b
86
83
  }
87
84
  }
88
85
 
89
- const tool = pickInstaller()
86
+ const tool = pickManager()
90
87
  if (!tool) throw new CliError(`Neither npm nor bun is on PATH, so ${names.join(" + ")} can't be installed automatically. Install one, or run on a machine with Node: ${manualCommand(dir, specsNow)}`)
91
88
 
92
89
  for (const name of ordered) {
93
90
  const spec = await peerSpec(name) // canvas's range comes from the renderer installed a step earlier
94
- const argv = tool === "npm"
95
- ? ["install", "--prefix", dir, "--no-audit", "--no-fund", "--loglevel=error", spec]
96
- : ["add", "--cwd", dir, spec]
91
+ const argv = installIntoArgv(tool, dir, [spec])
97
92
  note(`$ ${tool} ${argv.join(" ")}`)
98
93
  const r = spawnSync(tool, argv, { stdio: "inherit", shell: process.platform === "win32", timeout: 10 * 60_000 })
99
94
  if (r.error) throw new CliError(`${tool} could not run: ${r.error.message}`)
@@ -157,7 +152,7 @@ export async function loadPeer<T>(name: string, subpath: string | undefined, opt
157
152
  if (opts.install === false) return null
158
153
  // A global install of a DIFFERENT version than the probe expects would have resolved above; here
159
154
  // the peer is nowhere. (Globally installed but broken → the error above was not "not found".)
160
- if (peerVersionGlobal(name, spec) !== null) throw new CliError(`${name} is installed but "${spec}" can't be loaded from it — reinstall it: npm install -g ${await peerSpec(name)}`)
155
+ if (peerVersionGlobal(name, spec) !== null) throw new CliError(`${name} is installed but "${spec}" can't be loaded from it — reinstall it: ${commandLine(ownManager(), installGlobalArgv(ownManager(), [await peerSpec(name)]))}`)
161
156
  await installPeers(companions(name), opts.for)
162
157
  }
163
158
  return (await import(pathToFileURL(resolveEntry(dir, subpath)).href)) as T
@@ -24,6 +24,7 @@ export const OPTIONAL_PEERS: [name: string, probe: string][] = [
24
24
  ["lecodes-assets", "lecodes-assets/cli"],
25
25
  ["@napi-rs/canvas", "@napi-rs/canvas"],
26
26
  ["marcidb-embedded", "marcidb-embedded"],
27
+ ["typescript", "typescript"],
27
28
  ]
28
29
 
29
30
  /** The CLI's own peer install dir. */