turbollm 1.2.1 → 1.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cli.js +809 -153
- package/dist/webdist/assets/{ChatScreen-Di2U5guk.js → ChatScreen-DY2flMe9.js} +1 -1
- package/dist/webdist/assets/{CustomizeScreen-C1N3VSzu.js → CustomizeScreen-Cl6H68Sy.js} +4 -4
- package/dist/webdist/assets/DeveloperScreen-zC1nePXh.js +1 -0
- package/dist/webdist/assets/EnginesScreen-CrsziC3B.js +7 -0
- package/dist/webdist/assets/ModelDetailDialog-BOvumdHI.js +1 -0
- package/dist/webdist/assets/{ModelDirs-z0eidPHf.js → ModelDirs-Bj-XrX0c.js} +1 -1
- package/dist/webdist/assets/ModelsScreen-BTir-kDY.js +1 -0
- package/dist/webdist/assets/SettingsScreen-B696egCa.js +1 -0
- package/dist/webdist/assets/check-DFwkcl_5.js +1 -0
- package/dist/webdist/assets/{circle-x-nfGRpYmv.js → circle-x-CsuAddI_.js} +1 -1
- package/dist/webdist/assets/{common-VLx-PnhW.js → common-DIXPIrUd.js} +1 -1
- package/dist/webdist/assets/{copy-button-DvxLdCBa.js → copy-button-BtQZA6P8.js} +1 -1
- package/dist/webdist/assets/{dialog-BQ-Ai22D.js → dialog-Dpyml8ZT.js} +1 -1
- package/dist/webdist/assets/index-BklQn62W.css +1 -0
- package/dist/webdist/assets/{index-BGye3qtk.js → index-sjgdofsd.js} +7 -7
- package/dist/webdist/assets/{pencil-fITP-Ux2.js → pencil-BuQwoNyj.js} +1 -1
- package/dist/webdist/assets/{personas-Cq8LxYil.js → personas-CQapYHeK.js} +1 -1
- package/dist/webdist/assets/{plus-nMHxYBqJ.js → plus-B1w15FoZ.js} +1 -1
- package/dist/webdist/assets/{radix-C-SVreIl.js → radix-BFvMxQq9.js} +1 -1
- package/dist/webdist/assets/refresh-cw-BoAcjLtt.js +1 -0
- package/dist/webdist/assets/save-DE1APWTG.js +1 -0
- package/dist/webdist/assets/{skeleton-CSAyV68N.js → skeleton-Dvq8tYzC.js} +1 -1
- package/dist/webdist/assets/{sparkles-Cs6GG6EW.js → sparkles-C54kYWeQ.js} +1 -1
- package/dist/webdist/assets/{trash-2-BdOxLswi.js → trash-2-DIMVgidH.js} +1 -1
- package/dist/webdist/index.html +3 -3
- package/package.json +1 -1
- package/dist/webdist/assets/DeveloperScreen-DWf0TZqq.js +0 -1
- package/dist/webdist/assets/EnginesScreen-Dqy-jlqZ.js +0 -5
- package/dist/webdist/assets/ModelDetailDialog-BRKjfp4G.js +0 -1
- package/dist/webdist/assets/ModelsScreen-DqIQ4ST-.js +0 -1
- package/dist/webdist/assets/SettingsScreen-DXp8YTPJ.js +0 -1
- package/dist/webdist/assets/check-BnpDXpw8.js +0 -1
- package/dist/webdist/assets/external-link-CO5laD7p.js +0 -1
- package/dist/webdist/assets/index-Bx0PAdfC.css +0 -1
- package/dist/webdist/assets/save-Cm1zJnW7.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{c as T,X as ne,w as $,x as Ne,y as we,d as Se,z as Pe,E as Fe,a as Le,u as Ae,A as q,B as G,t as V}from"./index-sjgdofsd.js";import{b as Ee,j as e,c as Ge,d as Te,e as Re,f as ze,D as De}from"./radix-BFvMxQq9.js";import{r as v}from"./vendor-D_-14Whs.js";import{C as qe,A as Ue,p as $e,q as Be,r as Ke,s as _e,t as Ve,u as He,v as Ie}from"./dialog-Dpyml8ZT.js";import{E as Oe}from"./refresh-cw-BoAcjLtt.js";import{S as We}from"./save-DE1APWTG.js";const Qe=[["path",{d:"m12 14 4-4",key:"9kzdfg"}],["path",{d:"M3.34 19a10 10 0 1 1 17.32 0",key:"19p75a"}]],Y=T("gauge",Qe);const Je=[["path",{d:"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",key:"1357e3"}],["path",{d:"M3 3v5h5",key:"1xhq8a"}]],Xe=T("rotate-ccw",Je);const Ze=[["path",{d:"m21 21-4.34-4.34",key:"14j7rj"}],["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}]],St=T("search",Ze);const Ye=[["path",{d:"M10 5H3",key:"1qgfaw"}],["path",{d:"M12 19H3",key:"yhmn1j"}],["path",{d:"M14 3v4",key:"1sua03"}],["path",{d:"M16 17v4",key:"1q0r14"}],["path",{d:"M21 12h-9",key:"1o4lsq"}],["path",{d:"M21 19h-5",key:"1rlt1p"}],["path",{d:"M21 5h-7",key:"1oszz2"}],["path",{d:"M8 10v4",key:"tgpxqk"}],["path",{d:"M8 12H3",key:"a7s4jb"}]],Pt=T("sliders-horizontal",Ye);const et=[["path",{d:"M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z",key:"1xq2db"}]],ae=T("zap",et);function ee(){return{splitMode:"layer",tensorSplit:[],mainGpu:-1,tensorParallelSize:1}}function tt(){return{maxModelLen:0,gpuMemoryUtilization:.9,maxNumSeqs:0,dtype:"auto",kvCacheDtype:"auto",enforceEager:!1,trustRemoteCode:!1}}const nt=128;function at(n,a){if(!n.length)return 0;if(a?.splitMode==="none"){const s=a.mainGpu>=0?a.mainGpu:0;return n[s]?.vramMb??n[0]?.vramMb??0}return n.reduce((s,r)=>s+(r.vramMb||0),0)}function st(n){switch(n){case"f16":return 2;case"q8_0":case"q8_1":return 1;case"q5_0":case"q5_1":return .625;case"q4_0":case"q4_1":case"turbo4":return .5;case"turbo3":return .375;case"turbo2":return .25;default:return 2}}function lt(n,a,s){if(!s)return{estMb:0,totalVramMb:0,pct:0,verdict:"cpu"};const r=a.sizeBytes/1e6,c=a.blockCount||1,i=a.moe?1-.85*(n.nCpuMoe/c):Math.min(n.ngl,c)/c,d=r*Math.max(0,Math.min(1,i)),f=2*c*n.ctx*(a.headCountKv||8)*nt*st(n.kvTypeK)/1e6*(n.kvUnified?1:Math.max(1,n.parallel)),j=n.useMmproj&&n.mmprojGpu&&a.mmprojPath?600:0,l=Math.round(d+f+800+j),g=l/s,R=g<=.8?"fits":g<=.95?"tight":"overflow";return{estMb:l,totalVramMb:s,pct:g,verdict:R}}const ot=Ee,se=v.forwardRef(({className:n,children:a,...s},r)=>e.jsx(Ge,{children:e.jsxs(Te,{ref:r,className:$("tllm-sheet fixed z-50 flex flex-col border-border bg-panel shadow-[var(--shadow-2)] focus:outline-none",n),...s,children:[a,e.jsx(Re,{className:"absolute right-4 top-4 rounded-sm text-muted hover:text-ink","aria-label":"Close",children:e.jsx(ne,{size:16})})]})}));se.displayName="SheetContent";function rt({className:n,...a}){return e.jsx("div",{className:$("mb-4 flex flex-col gap-1",n),...a})}const le=v.forwardRef(({className:n,...a},s)=>e.jsx(ze,{ref:s,className:$("text-[16px] font-semibold tracking-[-0.01em] text-ink",n),...a}));le.displayName="SheetTitle";const oe=v.forwardRef(({className:n,...a},s)=>e.jsx(De,{ref:s,className:$("text-[13px] text-muted",n),...a}));oe.displayName="SheetDescription";function it(n){switch(n){case"llama-server":return"llamacpp";case"mlx":return"mlx";case"vllm":return"vllm";default:return"none"}}function Ft({modelKey:n,onClose:a,onViewRepo:s}){const r=Ne(n),c=we(),i=Se(),d=Pe(),h=Fe(),[f,j]=v.useState(null),[l,g]=v.useState(null),[R,de]=v.useState(!1),[B,me]=v.useState(!0),pe=Le(),o=r.data,K=Ae().data?.engine.state;v.useEffect(()=>{o&&g(structuredClone(o.profile))},[o]),v.useEffect(()=>{if(!n)return;const t=document.documentElement,m=parseInt(ct()??"",10);if(m>0){const p=Math.min(Math.max(m,Q),ie());t.style.setProperty("--tllm-config-w",`${p}px`)}return t.classList.add("tllm-config-open"),()=>t.classList.remove("tllm-config-open")},[n]),v.useEffect(()=>{f&&(K==="stopped"||K==="error")&&(d.start.mutate({key:f,base:l??void 0}),j(null))},[f,K,d.start]);const S=c.data?.engines.find(t=>t.id===c.data?.activeEngineId),xe=S?.capabilities.kvTypes??["f16"],z=S?.capabilities.flags??[],F=t=>z.length===0||z.includes(t),J=t=>z.length===0||z.includes(`spec-type:${t}`),ue=(o?.arch??"").toLowerCase(),he=(o?.name??"").toLowerCase(),fe=/gemma4/.test(ue)||/gemma[ _-]?4/.test(he),ge=(o?.nextnLayers??0)>0,L=["off"];F("--spec-type")&&F("--mtp-head")&&fe&&L.push("mtp"),F("--spec-type")&&F("--model-draft")&&ge&&(J("nextn")||J("draft-mtp"))&&L.push("nextn"),F("--model-draft")&&L.push("draft");const D=v.useMemo(()=>!o||!l?null:lt(l,o,at(o.gpus??[],l.gpu)),[o,l]),x=(t,m)=>g(p=>p&&{...p,[t]:m}),C=(t,m)=>g(p=>p&&{...p,sampling:{...p.sampling,[t]:m}}),X=(t,m)=>g(p=>p&&{...p,gpu:{...p.gpu??ee(),[t]:m}}),M=(t,m)=>g(p=>p&&{...p,vllm:{...p.vllm??tt(),[t]:m}}),Z=i.load.error instanceof q?i.load.error.message:null,A=!!h&&h.modelKey===o?.key,ve=!!h?.running&&A,E=!!h?.done&&A&&!h.running,je=d.start.error instanceof q?d.start.error.message:null,_=it(S?.kind),P=_==="llamacpp",be=_==="mlx",ye=_==="vllm",ke=()=>{o&&(o.loaded?(j(o.key),i.eject.mutate()):d.start.mutate({key:o.key,base:l??void 0}))};v.useEffect(()=>{E&&o?.key&&pe.invalidateQueries({queryKey:["model",o.key]})},[E,o?.key]);const Ce=()=>{d.save.mutate(void 0,{onSuccess:()=>V.success("Tuned settings saved"),onError:t=>V.error(t instanceof q?t.message:"Could not save tuned settings.")}),a()},Me=()=>{d.cancel.mutate(),a()};return e.jsxs(e.Fragment,{children:[e.jsx(ot,{open:!!n,onOpenChange:t=>!t&&a(),modal:!1,children:e.jsxs(se,{className:"overflow-y-auto p-5 slim-scroll",onPointerDownOutside:t=>t.preventDefault(),onInteractOutside:t=>t.preventDefault(),children:[e.jsx(dt,{}),e.jsxs(rt,{children:[e.jsx(le,{className:"truncate",children:o?.name??"Model"}),e.jsx(oe,{children:o?`${o.arch} · ${o.quant} · ${jt(o.sizeBytes)}`:"Load settings"}),o?.sourceRepo&&s&&e.jsxs("button",{type:"button",onClick:()=>s(o.sourceRepo),className:"mt-1 inline-flex w-fit items-center gap-1 text-[12px] font-medium text-accent hover:underline",title:`View ${o.sourceRepo} on Hugging Face`,children:[e.jsx(Oe,{size:12})," Model card & quants on Hugging Face"]})]}),!o||!l?e.jsx("div",{className:"py-10 text-center text-[13px] text-muted",children:"Loading…"}):e.jsxs("div",{className:"flex flex-col gap-4",children:[D&&e.jsx(pt,{estMb:D.estMb,totalMb:D.totalVramMb,verdict:D.verdict}),P&&o.gpu&&e.jsx(xt,{running:ve,done:E,step:A?h?.step:void 0,bestTps:A?h?.bestTps:void 0,resultError:E?h?.error:void 0,benchTps:o.benchTps,tuned:l.tunedBy==="bench",loaded:o.loaded,startError:je,pending:d.start.isPending||f!==null,onStart:ke,onCancel:()=>d.cancel.mutate()}),be&&e.jsxs("div",{className:"rounded-md border border-border bg-panel-2 px-3 py-2.5 text-[12px] text-muted",children:["MLX (Apple Silicon, mlx-lm) manages context and KV cache automatically — there are no context/GPU-layer/KV knobs to set. Only the ",e.jsx("span",{className:"text-ink",children:"sampling defaults"})," below apply at load; per-conversation overrides still work in chat."]}),ye&&e.jsxs(N,{children:[e.jsx(u,{label:"Max model length",hint:"vLLM --max-model-len. Max context tokens. 0 = derive from the model config.",children:e.jsx(k,{value:l.vllm?.maxModelLen??0,min:0,max:Math.max(0,o.nativeCtx||0),step:1024,onChange:t=>M("maxModelLen",t)})}),e.jsx(b,{label:"GPU memory utilization",hint:"vLLM --gpu-memory-utilization. Fraction of VRAM vLLM may reserve. Lower it to share the GPU.",value:Math.round((l.vllm?.gpuMemoryUtilization??.9)*100),min:10,max:100,step:5,onChange:t=>M("gpuMemoryUtilization",t/100),fmt:t=>`${t}%`}),e.jsx(u,{label:"Max concurrent sequences",hint:"vLLM --max-num-seqs. Requests served in parallel. 0 = vLLM default.",children:e.jsx(k,{value:l.vllm?.maxNumSeqs??0,min:0,max:1024,step:1,onChange:t=>M("maxNumSeqs",t)})}),e.jsx(u,{label:"Compute dtype",hint:"vLLM --dtype. 'auto' follows the model's config.",children:e.jsx(O,{value:l.vllm?.dtype??"auto",options:["auto","bfloat16","float16","float32"],onChange:t=>M("dtype",t)})}),e.jsx(u,{label:"KV cache dtype",hint:"vLLM --kv-cache-dtype. fp8 roughly halves KV-cache memory.",children:e.jsx(O,{value:l.vllm?.kvCacheDtype??"auto",options:["auto","fp8"],onChange:t=>M("kvCacheDtype",t)})}),e.jsx(w,{label:"Enforce eager",hint:"vLLM --enforce-eager. Skips CUDA graphs: less VRAM, somewhat slower.",value:l.vllm?.enforceEager??!1,onChange:t=>M("enforceEager",t)}),e.jsx(w,{label:"Trust remote code",hint:"vLLM --trust-remote-code. Needed for models that ship custom modelling code.",value:l.vllm?.trustRemoteCode??!1,onChange:t=>M("trustRemoteCode",t)})]}),P&&e.jsxs(N,{children:[e.jsx(b,{label:"Context length",hint:"Tokens of history the model can use.",value:l.ctx,min:512,max:Math.max(512,o.nativeCtx||8192),step:512,onChange:t=>x("ctx",t),fmt:t=>t.toLocaleString()}),o.gpu&&e.jsx(b,{label:"GPU layers",hint:o.blockCount>0?`${o.blockCount} total layers.`:"All layers on GPU = max performance.",value:l.ngl,min:0,max:o.blockCount>0?o.blockCount:99,step:1,onChange:t=>x("ngl",t),fmt:t=>t>=(o.blockCount>0?o.blockCount:99)?"All":String(t)}),o.moe&&o.blockCount>0&&e.jsx(b,{label:"MoE experts on CPU",hint:"Higher = less VRAM, slower. Lower = faster if it fits.",value:l.nCpuMoe,min:0,max:o.blockCount,step:1,onChange:t=>x("nCpuMoe",t)}),e.jsx(u,{label:"Context overflow",hint:"What to do when the context window fills up.",children:e.jsx(U,{value:l.contextOverflow,options:["shift","keep"],onChange:t=>x("contextOverflow",t)})}),l.contextOverflow==="keep"&&e.jsx(u,{label:"Tokens to keep",hint:"Preserve this many tokens from the start (e.g. system prompt length) when shifting.",children:e.jsx(k,{value:l.nKeep,min:0,max:l.ctx,onChange:t=>x("nKeep",t)})})]}),o.gpus&&o.gpus.length>1&&(S?.kind==="llama-server"||S?.kind==="vllm")&&e.jsxs(e.Fragment,{children:[e.jsxs(I,{children:["Multi-GPU · ",o.gpus.length," GPUs"]}),e.jsx(N,{children:S.kind==="vllm"?e.jsx(u,{label:"Tensor parallel size",hint:"Shard the model across this many GPUs.",children:e.jsx(k,{value:l.gpu?.tensorParallelSize??1,min:1,max:o.gpus.length,onChange:t=>X("tensorParallelSize",t)})}):e.jsx(ut,{gpus:o.gpus,gpu:l.gpu??ee(),setG:X})})]}),P&&e.jsxs(N,{children:[e.jsx(u,{label:"Parallel slots",children:e.jsx(k,{value:l.parallel,min:1,max:16,onChange:t=>x("parallel",t)})}),e.jsx(u,{label:"KV cache type",hint:"turbo* are TurboQuant-fork exclusive.",children:e.jsx(O,{value:l.kvTypeK,options:xe,onChange:t=>g(m=>m&&{...m,kvTypeK:t,kvTypeV:t})})}),e.jsx(u,{label:"Flash attention",children:e.jsx(U,{value:l.flashAttn,options:["auto","on","off"],onChange:t=>x("flashAttn",t)})}),e.jsx(w,{label:"Use Jinja chat template",value:l.useJinja,onChange:t=>x("useJinja",t)}),l.useJinja&&e.jsx(W,{label:"Template file path (optional)",hint:"Leave empty to use model's built-in template.",value:l.chatTemplateFile,placeholder:"Path to .jinja template file",onChange:t=>x("chatTemplateFile",t)})]}),e.jsx(I,{children:"Sampling"}),e.jsxs(N,{children:[e.jsx(b,{label:"Temperature",value:l.sampling.temp,min:0,max:2,step:.05,onChange:t=>C("temp",t),fmt:t=>t.toFixed(2)}),e.jsx(b,{label:"Top P",value:l.sampling.topP,min:0,max:1,step:.01,onChange:t=>C("topP",t),fmt:t=>t.toFixed(2)}),e.jsx(b,{label:"Top K",value:l.sampling.topK,min:0,max:200,step:1,onChange:t=>C("topK",t)}),e.jsx(b,{label:"Min P",value:l.sampling.minP,min:0,max:1,step:.01,onChange:t=>C("minP",t),fmt:t=>t.toFixed(2)}),P&&e.jsxs(e.Fragment,{children:[e.jsx(b,{label:"Repeat penalty",hint:"Penalise tokens that appeared earlier. 1.0 = off.",value:l.sampling.repeatPenalty,min:1,max:2,step:.05,onChange:t=>C("repeatPenalty",t),fmt:t=>t.toFixed(2)}),e.jsx(b,{label:"Presence penalty",hint:"Flat penalty for any token that appeared. 0 = off.",value:l.sampling.presencePenalty,min:0,max:2,step:.05,onChange:t=>C("presencePenalty",t),fmt:t=>t.toFixed(2)}),e.jsx(b,{label:"Frequency penalty",hint:"Penalty proportional to how often a token appeared. 0 = off.",value:l.sampling.frequencyPenalty,min:0,max:2,step:.05,onChange:t=>C("frequencyPenalty",t),fmt:t=>t.toFixed(2)}),e.jsx(u,{label:"Stop strings",hint:"Halt generation when any of these sequences is produced.",children:e.jsx("div",{className:"w-full"})}),e.jsx(gt,{value:l.sampling.stop,onChange:t=>g(m=>m&&{...m,sampling:{...m.sampling,stop:t}})})]})]}),P&&L.length>1&&e.jsxs(e.Fragment,{children:[e.jsx(I,{children:"Speculative decoding"}),e.jsxs(N,{children:[e.jsx(u,{label:"Mode",hint:"Predict extra tokens per step — faster generation.",children:e.jsx(ft,{value:l.speculative,options:L,onChange:t=>x("speculative",t)})}),l.speculative==="mtp"&&e.jsx(W,{label:"MTP head GGUF",hint:"Gemma-4 assistant model file.",value:l.mtpHeadPath,placeholder:"Path to gemma-4-mtp-assistant.gguf",onChange:t=>x("mtpHeadPath",t)}),l.speculative==="nextn"&&e.jsx("p",{className:"text-[11px] text-faint",children:"Uses this model's built-in NextN head — no extra file needed."}),l.speculative==="draft"&&e.jsx(W,{label:"Draft model GGUF",hint:"A small same-family model.",value:l.draftModelPath,placeholder:"Path to small draft model",onChange:t=>x("draftModelPath",t)})]})]}),P&&e.jsxs(e.Fragment,{children:[e.jsxs("button",{type:"button",onClick:()=>de(t=>!t),className:"flex items-center gap-1 text-[13px] font-medium text-muted hover:text-ink",children:[e.jsx(qe,{size:14,className:R?"rotate-180 transition-transform":"transition-transform"}),"Advanced"]}),R&&e.jsxs(N,{children:[e.jsx(b,{label:"CPU threads",hint:l.threads===0?`Auto — half your cores (${vt(o.cores)} of ${o.cores||"?"})`:`${l.threads} of ${o.cores||"?"} cores`,value:l.threads,min:0,max:Math.max(1,o.cores||64),step:1,onChange:t=>x("threads",t),fmt:t=>t===0?"Auto":String(t)}),e.jsx(w,{label:"Reuse cached prompt",hint:"Skips re-processing the unchanged start of a prompt on repeated or continued requests — faster first token. Recommended on.",value:l.cacheReuse>0,onChange:t=>x("cacheReuse",t?256:0)}),o.vision&&e.jsx(w,{label:"Vision encoder on GPU",value:l.mmprojGpu,onChange:t=>x("mmprojGpu",t)}),l.parallel>1&&e.jsx(w,{label:"Unified KV across slots",value:l.kvUnified,onChange:t=>x("kvUnified",t)}),e.jsx(u,{label:"RoPE scaling",hint:"Extend context beyond the model's trained limit. 'none' = model native.",children:e.jsx(U,{value:l.ropeScalingType,options:["none","linear","yarn"],onChange:t=>x("ropeScalingType",t)})}),l.ropeScalingType!=="none"&&e.jsxs(e.Fragment,{children:[e.jsx(u,{label:"RoPE freq base",hint:"Base frequency override. 0 = model native.",children:e.jsx(k,{value:l.ropeFreqBase,min:0,max:1e7,onChange:t=>x("ropeFreqBase",t)})}),e.jsx(u,{label:"RoPE freq scale",hint:"Frequency scale. 0 = model native; e.g. 0.25 for 4× context.",children:e.jsx(k,{value:l.ropeFreqScale,min:0,max:10,step:.01,onChange:t=>x("ropeFreqScale",t)})})]})]})]}),Z&&e.jsx("p",{className:"text-[12px]",style:{color:"var(--err)"},children:Z}),e.jsxs("label",{className:"flex cursor-pointer items-center gap-2 pt-1 text-[13px] text-ink",children:[e.jsx("input",{type:"checkbox",checked:B,onChange:t=>me(t.target.checked),className:"h-4 w-4 accent-[var(--accent)]"}),"Remember these settings",e.jsx("span",{className:"text-[11px] text-faint",children:B?"· saved as this model's default":"· this load only"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(G,{className:"flex-1",onClick:()=>{const t=()=>i.load.mutate({key:o.key,overrides:l},{onError:m=>V.error(m instanceof q?`Could not load model: ${m.message}`:"Could not load model — check the engine logs on the Engines screen.")});B?i.save.mutate({key:o.key,profile:l},{onSuccess:t,onError:t}):t(),a()},disabled:i.load.isPending,children:[e.jsx(ae,{size:14}),o.loaded?"Reload":"Load model"]}),e.jsxs(G,{variant:"outline",onClick:()=>i.save.mutate({key:o.key,profile:l}),disabled:i.save.isPending,title:"Save without reloading",children:[e.jsx(We,{size:14}),"Save"]}),e.jsx(G,{variant:"ghost",onClick:()=>i.reset.mutate(o.key),disabled:i.reset.isPending,title:"Reset to defaults",children:e.jsx(Xe,{size:14})})]})]})]})}),e.jsx(mt,{result:E&&A?h?.result:void 0,modelName:o?.name,onSave:Ce,onCancel:Me})]})}const re="tllm-config-w",Q=360;function ie(){return Math.max(Q,Math.min(760,window.innerWidth-220))}function ct(){try{return localStorage.getItem(re)}catch{return null}}function dt(){const n=a=>{if(a.button!==0)return;a.preventDefault();const s=document.documentElement;s.classList.add("tllm-config-resizing");const r=i=>{const d=Math.min(Math.max(window.innerWidth-i.clientX,Q),ie());s.style.setProperty("--tllm-config-w",`${Math.round(d)}px`)},c=()=>{s.classList.remove("tllm-config-resizing"),window.removeEventListener("pointermove",r),window.removeEventListener("pointerup",c);try{localStorage.setItem(re,getComputedStyle(s).getPropertyValue("--tllm-config-w").trim())}catch{}};window.addEventListener("pointermove",r),window.addEventListener("pointerup",c)};return e.jsx("div",{className:"tllm-config-resizer",onPointerDown:n,role:"separator","aria-orientation":"vertical","aria-label":"Resize panel"})}function y({label:n,value:a,tag:s}){return e.jsxs("div",{className:"flex items-center justify-between gap-3 py-[3px]",children:[e.jsx("span",{className:"text-muted",children:n}),e.jsxs("span",{className:"flex items-center gap-1.5",children:[s&&e.jsx("span",{className:"rounded px-1 py-0.5 text-[10px] font-medium uppercase tracking-wide",style:{color:"var(--accent)",background:"color-mix(in srgb, var(--accent) 12%, transparent)"},children:s}),e.jsx("span",{className:"font-mono text-ink",children:a})]})]})}function H({title:n}){return e.jsx("div",{className:"mt-2 pb-1 pt-1 text-[11px] font-semibold uppercase tracking-wide text-faint first:mt-0 first:pt-0",children:n})}function mt({result:n,modelName:a,onSave:s,onCancel:r}){const c=n?.recommendedSampling,i=n?.sampling,d=j=>c?.[j]!=null,h=!!c&&(c.temp!=null||c.topP!=null||c.topK!=null||c.minP!=null),f=[{label:"Temperature",key:"temp"},{label:"Top-K",key:"topK"},{label:"Top-P",key:"topP"},{label:"Min-P",key:"minP"}];return e.jsx(Ue,{open:!!n,onOpenChange:j=>{j||r()},children:e.jsxs($e,{children:[e.jsxs(Be,{children:[e.jsx(Ke,{children:"Auto-tune complete"}),e.jsx(_e,{asChild:!0,children:e.jsxs("div",{className:"flex flex-col gap-2.5 text-[13px]",children:[e.jsxs("span",{className:"text-muted",children:["Fastest config found on your machine —"," ",e.jsxs("span",{className:"font-mono font-medium",style:{color:"var(--ok)"},children:[n?.tps.toFixed(1)," tok/s"]}),". Save applies this complete config to ",a??"this model",":"]}),n&&e.jsxs("div",{className:"rounded-md border border-border bg-panel-2 px-3 py-1.5",children:[e.jsx(H,{title:"Runtime"}),e.jsx(y,{label:"GPU layers",value:n.params.ngl}),n.params.nCpuMoe>0&&e.jsx(y,{label:"MoE experts on CPU",value:n.params.nCpuMoe}),e.jsx(y,{label:"Context length",value:`${n.params.ctx.toLocaleString()} tok`}),e.jsx(y,{label:"KV cache type",value:n.params.kvTypeK}),e.jsx(y,{label:"Flash attention",value:n.params.flashAttn}),n.params.parallel>1&&e.jsx(y,{label:"Parallel slots",value:n.params.parallel}),e.jsx(H,{title:"Sampling"}),i?f.map(({label:j,key:l})=>e.jsx(y,{label:j,value:i[l]??"—",tag:d(l)?"from card":void 0},l)):e.jsx(y,{label:"Sampling",value:"model defaults"}),e.jsx(H,{title:"Measured"}),e.jsx(y,{label:"Speed",value:`${n.tps.toFixed(1)} tok/s`}),n.vramMb!=null&&e.jsx(y,{label:"VRAM used",value:`~${n.vramMb.toLocaleString()} MB`}),n.ttftMs?e.jsx(y,{label:"First token",value:`${Math.round(n.ttftMs)} ms`}):null]}),e.jsxs("span",{className:"text-faint",children:[h?e.jsxs(e.Fragment,{children:["Values tagged ",e.jsx("span",{style:{color:"var(--accent)"},children:"from card"})," were read from the model's Hugging Face page. "]}):e.jsx(e.Fragment,{children:"No sampling recommendation was found on the model's card — sampling stays at your current values. "}),"Change any of these later in Sampling."]})]})})]}),e.jsxs(Ve,{children:[e.jsx(He,{onClick:r,children:"Cancel"}),e.jsx(Ie,{onClick:s,children:"Save"})]})]})})}function pt({estMb:n,totalMb:a,verdict:s}){if(s==="cpu"||a===0)return e.jsx("div",{className:"rounded-md border border-border bg-panel-2 px-3 py-2 text-[12px] text-muted",children:"CPU-only — no GPU detected."});const r=s==="fits"?"var(--ok)":s==="tight"?"var(--warn)":"var(--err)",c=Math.min(100,Math.round(n/a*100)),i=s==="overflow"?"will spill to system RAM — expect severe slowdown":s==="tight"?"may slow under desktop load":"fits comfortably";return e.jsxs("div",{className:"rounded-md border border-border bg-panel-2 px-3 py-2.5",children:[e.jsxs("div",{className:"mb-1.5 flex items-center justify-between text-[12px]",children:[e.jsx("span",{className:"text-muted",children:"Estimated VRAM"}),e.jsxs("span",{style:{color:r},children:["~",(n/1e3).toFixed(1)," / ",(a/1e3).toFixed(1)," GB · ",i]})]}),e.jsx("div",{className:"h-2 overflow-hidden rounded-full",style:{background:"var(--border)"},children:e.jsx("div",{className:"h-full rounded-full transition-all",style:{width:`${c}%`,background:r}})})]})}function xt({running:n,done:a,step:s,bestTps:r,resultError:c,benchTps:i,tuned:d,loaded:h,startError:f,pending:j,onStart:l,onCancel:g}){return e.jsx("div",{className:"rounded-lg border border-border bg-panel p-3",children:n?e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("div",{className:"flex items-center gap-2 text-[13px] text-ink",children:[e.jsx(Y,{size:14,className:"animate-pulse",style:{color:"var(--accent)"}}),"Auto-tuning…"]}),e.jsxs(G,{variant:"outline",onClick:g,children:[e.jsx(ne,{size:14}),"Cancel"]})]}),e.jsx("p",{className:"font-mono text-[12px] text-muted",children:s??"Preparing…"}),r!==void 0&&e.jsxs("p",{className:"text-[12px] text-ink",children:["Best so far: ",e.jsxs("span",{className:"font-mono",style:{color:"var(--ok)"},children:[r.toFixed(1)," tok/s"]})]})]}):e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-1.5 text-[13px] font-medium text-ink",children:[e.jsx(Y,{size:14,style:{color:"var(--accent)"}}),"Auto-tune"]}),e.jsx("p",{className:"text-[11px] text-faint",children:i!==null?`Tuned: ${i.toFixed(1)} tok/s on your machine${d?" · settings applied below":""}`:"Measures real speed on your hardware and saves the fastest settings (~3 min)."})]}),e.jsxs(G,{variant:"outline",onClick:l,disabled:j,children:[e.jsx(ae,{size:14}),h?"Stop & benchmark":"Auto-tune"]})]}),a&&r!==void 0&&!c&&e.jsxs("p",{className:"text-[12px] text-ink",children:["Done — ",e.jsxs("span",{className:"font-mono",style:{color:"var(--ok)"},children:[r.toFixed(1)," tok/s"]}),". Saved as this model's default."]}),a&&c&&e.jsx("p",{className:"text-[12px]",style:{color:"var(--warn)"},children:c}),f&&e.jsx("p",{className:"text-[12px]",style:{color:"var(--err)"},children:f})]})})}function N({children:n}){return e.jsx("div",{className:"flex flex-col gap-3 rounded-lg border border-border bg-panel p-3",children:n})}function I({children:n}){return e.jsx("div",{className:"text-[12px] font-semibold uppercase tracking-wide text-faint",children:n})}function b({label:n,hint:a,value:s,min:r,max:c,step:i,onChange:d,fmt:h}){return e.jsxs("div",{children:[e.jsxs("div",{className:"mb-1 flex items-baseline justify-between",children:[e.jsx("span",{className:"text-[13px] text-ink",children:n}),e.jsx("span",{className:"font-mono text-[12px] text-muted",children:h?h(s):s})]}),e.jsx("input",{type:"range",min:r,max:c,step:i,value:s,onChange:f=>d(Number(f.target.value)),className:"w-full accent-[var(--accent)]"}),a&&e.jsx("p",{className:"mt-0.5 text-[11px] text-faint",children:a})]})}function u({label:n,hint:a,children:s}){return e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[13px] text-ink",children:n}),a&&e.jsx("div",{className:"text-[11px] text-faint",children:a})]}),s]})}function k({value:n,min:a,max:s,step:r=1,onChange:c}){return e.jsx("input",{type:"number",min:a,max:s,step:r,value:n,onChange:i=>c(Math.max(a,Math.min(s,Number(i.target.value)||a))),className:"w-20 rounded-md border border-border bg-bg px-2 py-1 text-right text-[13px] text-ink outline-none"})}function O({value:n,options:a,onChange:s}){return e.jsx("select",{value:n,onChange:r=>s(r.target.value),className:"rounded-md border border-border bg-bg px-2 py-1 text-[13px] text-ink outline-none",children:a.map(r=>e.jsx("option",{value:r,children:r},r))})}function U({value:n,options:a,onChange:s}){return e.jsx("div",{className:"flex overflow-hidden rounded-md border border-border",children:a.map(r=>e.jsx("button",{type:"button",onClick:()=>s(r),className:"px-2.5 py-1 text-[12px] capitalize transition-colors",style:{background:n===r?"var(--accent)":"transparent",color:n===r?"var(--on-accent)":"var(--muted)"},children:r},r))})}function ce(n,a){const s=n.vramMb?` (${Math.round(n.vramMb/1024)} GB)`:"";return`GPU ${a}${n.name?` · ${n.name}`:""}${s}`}function te({gpus:n,value:a,allowAuto:s,onChange:r}){return e.jsxs("select",{value:String(a),onChange:c=>r(Number(c.target.value)),className:"max-w-[260px] rounded-md border border-border bg-bg px-2 py-1 text-[13px] text-ink outline-none",children:[s&&e.jsx("option",{value:"-1",children:"Auto"}),n.map((c,i)=>e.jsx("option",{value:String(i),children:ce(c,i)},i))]})}function ut({gpus:n,gpu:a,setG:s}){const r=a.tensorSplit.length>0;return e.jsxs(e.Fragment,{children:[e.jsx(u,{label:"Split mode",hint:"layer = by layers (default) · row = tensor-parallel · none = single GPU.",children:e.jsx(U,{value:a.splitMode,options:["layer","row","none"],onChange:c=>s("splitMode",c)})}),a.splitMode==="none"?e.jsx(u,{label:"GPU",hint:"Which GPU to load the model on.",children:e.jsx(te,{gpus:n,value:a.mainGpu>=0?a.mainGpu:0,allowAuto:!1,onChange:c=>s("mainGpu",c)})}):e.jsxs(e.Fragment,{children:[e.jsx(u,{label:"Main GPU",hint:"Holds the KV cache / small tensors. Auto lets the engine choose.",children:e.jsx(te,{gpus:n,value:a.mainGpu,allowAuto:!0,onChange:c=>s("mainGpu",c)})}),e.jsx(w,{label:"Custom GPU split",hint:"Off = even split across GPUs. On = set each GPU's share.",value:r,onChange:c=>s("tensorSplit",c?n.map(()=>1):[])}),r&&e.jsx("div",{className:"flex flex-col gap-2 pl-1",children:n.map((c,i)=>e.jsx(u,{label:ce(c,i),children:e.jsx(k,{value:a.tensorSplit[i]??0,min:0,max:100,onChange:d=>s("tensorSplit",n.map((h,f)=>f===i?d:a.tensorSplit[f]??0))})},i))})]})]})}const ht={off:"Off",mtp:"MTP",nextn:"NextN",draft:"Draft"};function ft({value:n,options:a,onChange:s}){return e.jsx("div",{className:"flex overflow-hidden rounded-md border border-border",children:a.map(r=>e.jsx("button",{type:"button",onClick:()=>s(r),className:"px-2.5 py-1 text-[12px] transition-colors",style:{background:n===r?"var(--accent)":"transparent",color:n===r?"var(--on-accent)":"var(--muted)"},children:ht[r]},r))})}function W({label:n,hint:a,value:s,placeholder:r,onChange:c}){return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"text-[12px] text-ink",children:[n,a&&e.jsx("span",{className:"ml-1 text-faint",children:a})]}),e.jsx("input",{type:"text",value:s,placeholder:r,onChange:i=>c(i.target.value),className:"w-full rounded-md border border-border bg-bg px-2 py-1 font-mono text-[12px] text-ink outline-none placeholder:text-faint"})]})}function gt({value:n,onChange:a}){const[s,r]=v.useState(""),c=i=>{const d=i.trim();d&&!n.includes(d)&&a([...n,d]),r("")};return e.jsxs("div",{className:"flex flex-col gap-1.5",children:[n.length>0&&e.jsx("div",{className:"flex flex-wrap gap-1",children:n.map(i=>e.jsxs("span",{className:"flex items-center gap-0.5 rounded border border-border bg-panel-2 px-1.5 py-0.5 font-mono text-[11px] text-ink",children:[i,e.jsx("button",{type:"button",onClick:()=>a(n.filter(d=>d!==i)),className:"ml-0.5 text-muted hover:text-[var(--err)]",children:"×"})]},i))}),e.jsx("input",{type:"text",value:s,placeholder:n.length?"Add another…":"Type a stop string, press Enter",onChange:i=>r(i.target.value),onKeyDown:i=>{i.key==="Enter"&&(i.preventDefault(),c(s)),i.key==="Backspace"&&!s&&n.length&&a(n.slice(0,-1))},onBlur:()=>{s.trim()&&c(s)},className:"w-full rounded-md border border-border bg-bg px-2 py-1 font-mono text-[12px] text-ink outline-none placeholder:text-faint"})]})}function w({label:n,hint:a,value:s,onChange:r}){return e.jsxs("label",{className:"flex cursor-pointer items-center justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("span",{className:"text-[13px] text-ink",children:n}),a&&e.jsx("p",{className:"text-[11px] text-faint",children:a})]}),e.jsx("input",{type:"checkbox",checked:s,onChange:c=>r(c.target.checked),className:"h-4 w-4 shrink-0 accent-[var(--accent)]"})]})}function vt(n){return Math.max(1,Math.floor((n||2)/2))}function jt(n){return n>=1e9?`${(n/1e9).toFixed(1)} GB`:`${Math.round(n/1e6)} MB`}export{Ft as M,St as S,ae as Z,Pt as a};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as e}from"./radix-
|
|
1
|
+
import{j as e}from"./radix-BFvMxQq9.js";import{r as p}from"./vendor-D_-14Whs.js";import{c as d,A as x,X as m,I as u,B as h}from"./index-sjgdofsd.js";const f=[["path",{d:"M12 10v6",key:"1bos4e"}],["path",{d:"M9 13h6",key:"1uhe8q"}],["path",{d:"M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z",key:"1kt360"}]],y=d("folder-plus",f);const v=[["path",{d:"M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z",key:"r04s7s"}]],g=d("star",v);function D({dirs:s,primaryDir:t,mut:a}){const[o,n]=p.useState(""),i=a.addDir.error instanceof x?a.addDir.error.message:null,l=()=>{const r=o.trim();r&&a.addDir.mutate(r,{onSuccess:()=>n("")})};return e.jsxs("div",{className:"mb-5 rounded-lg border border-border bg-panel-2 p-4",children:[e.jsx("div",{className:"mb-2 text-[13px] font-medium text-ink",children:"Model folders"}),s.length>0&&e.jsx("div",{className:"mb-3 flex flex-col gap-1.5",children:s.map(r=>{const c=r===t;return e.jsxs("div",{className:"group/dir flex items-center gap-2 text-[13px]",children:[e.jsx("span",{className:"flex-1 truncate font-mono text-muted",children:r}),c?e.jsx(b,{tone:"ok",children:"Primary"}):e.jsxs("button",{type:"button",onClick:()=>a.setPrimaryDir.mutate(r),disabled:a.setPrimaryDir.isPending,title:"Downloads and imports will land in this folder",className:"flex items-center gap-1 rounded px-1.5 py-0.5 text-[11px] text-faint opacity-0 transition-opacity hover:text-ink focus:opacity-100 group-hover/dir:opacity-100",children:[e.jsx(g,{size:12}),"Set as primary"]}),e.jsx("button",{type:"button","aria-label":`Remove ${r}`,onClick:()=>a.removeDir.mutate(r),className:"rounded p-1 text-muted transition-colors hover:text-ink",children:e.jsx(m,{size:14})})]},r)})}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(u,{value:o,onChange:r=>n(r.target.value),onKeyDown:r=>r.key==="Enter"&&l(),placeholder:"Paste an absolute folder path, e.g. D:\\\\models",className:"flex-1 font-mono text-[13px]"}),e.jsxs(h,{size:"sm",onClick:l,disabled:a.addDir.isPending||!o.trim(),children:[e.jsx(y,{size:14}),"Add folder"]})]}),i&&e.jsx("p",{className:"mt-2 text-[12px]",style:{color:"var(--err)"},children:i})]})}function b({children:s,tone:t}){const a=t==="ok"?"var(--ok)":t==="warn"?"var(--warn)":t==="err"?"var(--err)":t==="spec"?"var(--accent)":"var(--muted)";return e.jsx("span",{className:"rounded px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide",style:{color:a,background:`color-mix(in srgb, ${a} 12%, transparent)`},children:s})}export{D as M};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as e}from"./radix-BFvMxQq9.js";import{c as q,j as be,k as P,D as E,B as k,X,l as ve,m as Y,d as ee,u as te,A as _,t as L,I as se,n as ye,b as ne,o as we,p as ke,a as Ne,q as Me,r as Se,L as _e,s as V,v as Ce}from"./index-sjgdofsd.js";import{r as b}from"./vendor-D_-14Whs.js";import{I as K,E as ae,S as De}from"./common-DIXPIrUd.js";import{S as re,B as oe,E as Le}from"./skeleton-Dvq8tYzC.js";import{b as Be,h as le,j as ie,l as ce,m as de,n as ue,o as Fe,A as $e,p as ze,q as Qe,r as Ge,s as qe,t as Ee,u as Re,v as Ae,g as Te,D as Ie,c as Ke,d as Ue,f as W,a as Pe}from"./dialog-Dpyml8ZT.js";import{Z as xe,S as Z,M as He,a as Oe}from"./ModelDetailDialog-BOvumdHI.js";import{E as Xe,R as Ve}from"./refresh-cw-BoAcjLtt.js";import{S as We}from"./sparkles-C54kYWeQ.js";import{M as Ze}from"./ModelDirs-Bj-XrX0c.js";import{T as Je}from"./trash-2-DIMVgidH.js";import"./save-DE1APWTG.js";const Ye=[["path",{d:"M2 9.5a5.5 5.5 0 0 1 9.591-3.676.56.56 0 0 0 .818 0A5.49 5.49 0 0 1 22 9.5c0 2.29-1.5 4-3 5.5l-5.492 5.313a2 2 0 0 1-3 .019L5 15c-1.5-1.5-3-3.2-3-5.5",key:"mvr1a0"}]],et=q("heart",Ye);const tt=[["path",{d:"M9 17H7A5 5 0 0 1 7 7h2",key:"8i5ue5"}],["path",{d:"M15 7h2a5 5 0 1 1 0 10h-2",key:"1b9ql8"}],["line",{x1:"8",x2:"16",y1:"12",y2:"12",key:"1jonct"}]],me=q("link-2",tt);const st=[["rect",{width:"18",height:"11",x:"3",y:"11",rx:"2",ry:"2",key:"1w4ew1"}],["path",{d:"M7 11V7a5 5 0 0 1 10 0v4",key:"fwvmzm"}]],H=q("lock",st);const nt=[["path",{d:"M12 22V12",key:"d0xqtd"}],["path",{d:"M20.27 18.27 22 20",key:"er2am"}],["path",{d:"M21 10.498V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.729l7 4a2 2 0 0 0 2 .001l.98-.559",key:"tok1h1"}],["path",{d:"M3.29 7 12 12l8.71-5",key:"19ckod"}],["path",{d:"m7.5 4.27 8.997 5.148",key:"9yrvtv"}],["circle",{cx:"18.5",cy:"16.5",r:"2.5",key:"ke13xx"}]],at=q("package-search",nt),rt=[{repo:"unsloth/Qwen3.6-35B-A3B-GGUF",name:"Qwen3.6 35B-A3B",blurb:"Sparse MoE flagship — 35B total, 3B active. Fast for its size.",quants:{8:"IQ2_XXS",12:"IQ3_XXS",16:"Q3_K_M",24:"Q4_K_M","32+":"Q5_K_M"}},{repo:"unsloth/Qwen3.6-27B-GGUF",name:"Qwen3.6 27B",blurb:"Dense 27B — strong general reasoning, broad quant range.",quants:{8:"IQ2_XS",12:"IQ3_M",16:"Q3_K_L",24:"Q5_K_M","32+":"Q6_K"}},{repo:"unsloth/Gemma-4-26B-A4B-GGUF",name:"Gemma-4 26B-A4B",blurb:"Google MoE with vision — 26B total, 4B active. Multimodal.",quants:{8:"IQ2_XXS",12:"IQ3_XXS",16:"Q3_K_M",24:"Q4_K_M","32+":"Q5_K_M"}},{repo:"unsloth/Gemma-4-E4B-GGUF",name:"Gemma-4 E4B",blurb:"Compact 4B — runs anywhere, vision-capable, great laptop pick.",quants:{8:"Q4_K_M",12:"Q5_K_M",16:"Q6_K",24:"Q8_0","32+":"Q8_0"}},{repo:"unsloth/Qwen3.5-9B-GGUF",name:"Qwen3.5 9B",blurb:"Dense 9B — efficient, fits midrange GPUs at good quant.",quants:{8:"Q3_K_M",12:"Q4_K_M",16:"Q5_K_M",24:"Q6_K","32+":"Q8_0"}},{repo:"unsloth/GLM-5-Air-GGUF",name:"GLM-5 Air",blurb:"Zhipu MoE — efficient long-context generalist.",quants:{8:"IQ2_XS",12:"IQ3_M",16:"Q3_K_M",24:"Q4_K_M","32+":"Q5_K_M"}},{repo:"unsloth/Llama-3.3-70B-Instruct-GGUF",name:"Llama 3.3 70B",blurb:"Meta 70B — gated; accept the license + add a token to download.",gated:!0,quants:{8:"IQ1_M",12:"IQ2_XXS",16:"IQ2_M",24:"IQ3_M","32+":"Q4_K_M"}},{repo:"unsloth/gpt-oss-20b-GGUF",name:"GPT-OSS 20B",blurb:"OpenAI open-weights 20B — strong tool-use and reasoning.",quants:{8:"IQ2_M",12:"Q3_K_M",16:"Q4_K_M",24:"Q5_K_M","32+":"Q6_K"}}];function ot(t){if(!t)return"16";const s=t/1024;return s<10?"8":s<14?"12":s<20?"16":s<28?"24":"32+"}function lt(){const t=be(),s=P(),a=t.data?.downloads??[];if(a.length===0)return null;const l=a.filter(i=>i.status==="downloading"||i.status==="queued"||i.status==="paused"),o=a.filter(i=>i.status==="error"),r=a.filter(i=>i.status==="done"||i.status==="cancelled"),d=[...l,...o,...r];return e.jsxs("div",{className:"mb-5 rounded-lg border border-border bg-panel-2 p-4",children:[e.jsxs("div",{className:"mb-3 flex items-center gap-2 text-[13px] font-medium text-ink",children:[e.jsx(E,{size:14,className:"text-muted"}),"Downloads",l.length>0&&e.jsxs("span",{className:"text-[12px] font-normal text-muted",children:["· ",l.length," active"]})]}),e.jsx("div",{className:"flex flex-col gap-2",children:d.map(i=>e.jsx(it,{d:i,onCancel:()=>s.cancel.mutate(i.id),onRemove:()=>s.remove.mutate(i.id),cancelling:s.cancel.isPending},i.id))})]})}function it({d:t,onCancel:s,onRemove:a,cancelling:l}){const o=t.total>0?Math.min(100,Math.round(t.received/t.total*100)):0,r=t.status==="downloading"||t.status==="queued"||t.status==="paused",d=t.status==="done",i=t.status==="error",h=t.status==="cancelled",n=i?"var(--err)":d?"var(--ok)":"var(--accent)";return e.jsxs("div",{className:"rounded-md border border-border bg-panel px-3 py-2.5",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[d&&e.jsx(Be,{size:13,style:{color:"var(--ok)"},className:"shrink-0"}),e.jsx("span",{className:"truncate text-[13px] font-medium text-ink",children:t.name})]}),e.jsx("div",{className:"mt-0.5 truncate text-[11px] text-muted",children:e.jsx(ct,{d:t,pct:o})})]}),r&&e.jsxs(k,{size:"sm",variant:"outline",onClick:s,disabled:l,title:"Cancel download",children:[e.jsx(X,{size:13}),"Cancel"]}),(d||i||h)&&e.jsx("button",{type:"button","aria-label":"Remove from list",onClick:a,className:"rounded p-1 text-muted transition-colors hover:text-ink",children:e.jsx(X,{size:14})})]}),(r||i)&&e.jsx("div",{className:"mt-2 h-1.5 overflow-hidden rounded-full",style:{background:"var(--border)"},children:e.jsx("div",{className:"h-full rounded-full transition-all",style:{width:`${i?100:o}%`,background:n}})})]})}function ct({d:t,pct:s}){return t.status==="done"?e.jsx("span",{style:{color:"var(--ok)"},children:"✓ added to library"}):t.status==="error"?e.jsx("span",{style:{color:"var(--err)"},children:t.error??"Download failed"}):t.status==="cancelled"?e.jsx(e.Fragment,{children:"Cancelled"}):t.status==="paused"?e.jsxs(e.Fragment,{children:["Paused · ",Q(t.received)," of ",t.total>0?Q(t.total):"?"]}):t.status==="queued"?e.jsx(e.Fragment,{children:"Queued…"}):e.jsxs(e.Fragment,{children:[s,"% · ",Q(t.received)," of ",t.total>0?Q(t.total):"?",t.bytesPerSec>0?` · ${dt(t.bytesPerSec)}`:""]})}function Q(t){return t>=1e9?`${(t/1e9).toFixed(2)} GB`:`${Math.round(t/1e6)} MB`}function dt(t){return t>=1e6?`${(t/1e6).toFixed(1)} MB/s`:`${Math.round(t/1e3)} KB/s`}function G(t,s){if(!s)return"unknown";const o=(t/1e6*1.15+1e3)/s;return o<=.8?"fits":o<=.95?"tight":"overflow"}const pe={fits:"var(--ok)",tight:"var(--warn)",overflow:"var(--err)",cpu:"var(--muted)",unknown:"var(--faint)"},he={fits:"Fits comfortably on your GPU.",tight:"Tight fit — may slow under desktop load.",overflow:"Larger than your VRAM — will spill to system RAM.",cpu:"CPU-only — no GPU detected.",unknown:"Fit unknown — GPU VRAM not detected."};function fe({repo:t,onClose:s,onSearch:a}){const l=ve(t),o=Y(),r=P(),d=ee(),h=te().data?.engine.kind??"",n=l.data,m=o.data?.gpus?.[0]?.vramMb,f=!!n?.safetensors,[x,y]=b.useState("");b.useEffect(()=>{if(!n)return;const u=n.files.filter(w=>!w.mmproj);if(u.length===0)return;const g=u.filter(w=>G(w.sizeBytes,m)==="fits"),B=[...g.length>0?g:u].sort((w,F)=>{if(F.sizeBytes!==w.sizeBytes)return F.sizeBytes-w.sizeBytes;const T=/q\d_k/i.test(w.quant)?0:1,I=/q\d_k/i.test(F.quant)?0:1;return T-I})[0];y(B.name)},[n,m]);const N=b.useMemo(()=>n?n.files.filter(u=>!u.mmproj).sort((u,g)=>u.sizeBytes-g.sizeBytes):[],[n]),c=N.find(u=>u.name===x)??null,v=!!c?.downloaded,j=c?G(c.sizeBytes,m):"unknown",C=n?.gated??!1,$=C,D=r.enqueue.error instanceof _?r.enqueue.error.message:null,R=()=>{!n||!c||r.enqueue.mutate({repo:n.repo,rfilename:c.name,size:c.sizeBytes,sha256:c.sha256},{onSuccess:()=>{L.success(`Downloading ${c.name}`),s()}})},z=()=>{if(!n?.safetensors||!n.files.length)return;const u=n.repo.split("/").pop()??n.repo;let g=0;for(const S of n.files)r.enqueue.mutate({repo:n.repo,rfilename:S.name,size:S.sizeBytes,sha256:S.sha256,subdir:u}),g++;L.success(`Queued ${g} files for ${u}`),s()},A=()=>{const u=c?.localKey;u&&d.load.mutate({key:u},{onSuccess:()=>{L.success(`Loading ${c?.quant??"model"}`),s()},onError:g=>L.error(g instanceof _?g.message:"Could not load model.")})};return e.jsx(le,{open:!!t,onOpenChange:u=>!u&&s(),children:e.jsxs(ie,{className:"max-h-[88vh] overflow-y-auto sm:max-w-[560px]",children:[e.jsxs(ce,{children:[e.jsx(de,{className:"truncate pr-6",children:e.jsxs("span",{className:"inline-flex items-center gap-1.5",children:[C&&e.jsx(H,{size:14,style:{color:"var(--warn)"}}),t]})}),e.jsx(ue,{children:n?`${n.downloads.toLocaleString()} downloads · ${n.likes.toLocaleString()} likes${n.license?` · ${n.license}`:""}`:"Loading repo…"})]}),l.isLoading?e.jsx("div",{className:"py-10 text-center text-[13px] text-muted",children:"Loading repo…"}):l.isError?e.jsx(xt,{error:l.error,onRetry:()=>l.refetch(),onSearch:a?()=>a(mt(t)):void 0}):f?e.jsx(ut,{detail:n,vramMb:m,engineKind:h,onDownload:z,isPending:r.enqueue.isPending}):!n||N.length===0?e.jsx("div",{className:"py-10 text-center text-[13px] text-muted",children:"No GGUF files found in this repo."}):e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsxs("label",{className:"flex items-center gap-1.5 text-[12px] font-medium text-ink",children:["Quant",n.verifying&&e.jsx("span",{className:"text-[11px] font-normal text-faint",children:"· checking your library…"})]}),e.jsx("select",{value:x,onChange:u=>y(u.target.value),className:"w-full rounded-md border border-border bg-bg px-2 py-2 text-[13px] text-ink outline-none",children:N.map(u=>{const g=G(u.sizeBytes,m),S=!!u.downloaded,B=g==="fits"?"●":g==="tight"?"◐":g==="overflow"?"○":"·";return e.jsxs("option",{value:u.name,children:[u.quant," · ",pt(u.sizeBytes),u.parts>1?` · ${u.parts} parts`:""," · ",B,S?" · Downloaded":""]},u.name)})})]}),c&&e.jsxs("div",{className:"flex items-center gap-2 rounded-md border border-border bg-panel-2 px-3 py-2.5 text-[12px]",children:[e.jsx("span",{className:"h-2.5 w-2.5 shrink-0 rounded-full",style:{background:pe[j]}}),e.jsxs("span",{className:"text-muted",children:[he[j],m?` (${(c.sizeBytes/1e9).toFixed(1)} GB file · ${(m/1024).toFixed(0)} GB VRAM)`:""]})]}),$&&e.jsxs("div",{className:"rounded-md border px-3 py-2.5 text-[12px]",style:{borderColor:"var(--warn)",background:"color-mix(in srgb, var(--warn) 10%, transparent)"},children:[e.jsx("p",{className:"text-ink",children:"This is a gated model."}),e.jsxs("p",{className:"mt-1 text-muted",children:["Accept the license on"," ",e.jsxs("a",{href:`https://huggingface.co/${n.repo}`,target:"_blank",rel:"noreferrer",className:"inline-flex items-center gap-0.5 underline",style:{color:"var(--accent)"},children:["huggingface.co ",e.jsx(Xe,{size:11})]}),", then add a Hugging Face token in Settings → Models."]})]}),D&&e.jsx("p",{className:"text-[12px]",style:{color:"var(--err)"},children:D}),e.jsx("div",{className:"flex items-center gap-2",children:v&&c?.localKey?e.jsxs(k,{className:"flex-1",onClick:A,disabled:d.load.isPending,children:[e.jsx(xe,{size:14}),"Load"]}):e.jsxs(k,{className:"flex-1",onClick:R,disabled:$||r.enqueue.isPending||!c,children:[e.jsx(E,{size:14}),r.enqueue.isPending?"Adding…":v?"Re-download":"Download"]})}),n.card&&e.jsxs("details",{className:"rounded-md border border-border bg-panel-2 px-3 py-2",children:[e.jsx("summary",{className:"cursor-pointer text-[12px] font-medium text-muted",children:"Model card"}),e.jsx("p",{className:"mt-2 whitespace-pre-wrap text-[12px] leading-relaxed text-muted",children:n.card})]})]})]})})}function ut({detail:t,vramMb:s,engineKind:a,onDownload:l,isPending:o}){const r=t.files.reduce((n,m)=>n+m.sizeBytes,0),d=G(r,s),i=a==="mlx"?"MLX model — runs on Apple Silicon via mlx-lm. Downloads as a directory of safetensors weights.":a==="vllm"?"HuggingFace model — runs via vLLM. Downloads as a directory of safetensors weights.":"Safetensors model — downloads as a directory of weight files.",h=a==="mlx"?"Download MLX model":"Download model";return e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsx("div",{className:"rounded-md border border-border bg-panel-2 px-3 py-2.5 text-[12px] text-muted",children:i}),e.jsxs("div",{className:"flex items-center gap-2 rounded-md border border-border bg-panel-2 px-3 py-2.5 text-[12px]",children:[e.jsx("span",{className:"h-2.5 w-2.5 shrink-0 rounded-full",style:{background:pe[d]}}),e.jsxs("span",{className:"text-muted",children:[he[d],s?` (${(r/1e9).toFixed(1)} GB total · ${(s/1024).toFixed(0)} GB VRAM)`:`${(r/1e9).toFixed(1)} GB total`]})]}),e.jsxs(k,{className:"w-full",onClick:l,disabled:t.gated||o,children:[e.jsx(E,{size:14}),o?"Queuing…":h]})]})}function xt({error:t,onRetry:s,onSearch:a}){const l=t instanceof _?t.code:"",o=l==="hf_not_found",r=l==="hf_unreachable";return e.jsxs("div",{className:"flex flex-col items-center gap-3 py-10 text-center",children:[e.jsx("p",{className:"max-w-sm text-[13px] text-muted",children:o?"We couldn't find this exact model on Hugging Face — the local folder name may not match its repo. Try searching for it instead.":r?"Hugging Face is unreachable — check your connection.":t instanceof _?t.message:"Could not load this repo."}),e.jsxs("div",{className:"flex items-center gap-2",children:[o&&a&&e.jsx(k,{size:"sm",onClick:a,children:"Search Hugging Face"}),e.jsx(k,{size:"sm",variant:"outline",onClick:s,children:"Retry"})]})]})}function mt(t){return t?(t.split("/").pop()??t).replace(/[-_]?gguf$/i,"").replace(/[-_]+/g," ").trim():""}function pt(t){return t>=1e9?`${(t/1e9).toFixed(1)} GB`:`${Math.round(t/1e6)} MB`}function ht(t){let s;try{s=new URL(t)}catch{return!1}return s.protocol!=="http:"&&s.protocol!=="https:"?!1:s.pathname.toLowerCase().endsWith(".gguf")?!0:/huggingface\.co\/.*\/resolve\/.*\.gguf$/i.test(`${s.host}${s.pathname}`)}function ft(t){try{const a=new URL(t).pathname.split("/").filter(Boolean).pop()??"";return decodeURIComponent(a)}catch{return""}}function gt({open:t,onClose:s}){const a=P(),[l,o]=b.useState(""),r=l.trim(),d=b.useMemo(()=>ft(r),[r]),i=r.length>0&&ht(r),h=r.length>0&&!i,n=a.enqueue.error instanceof _?a.enqueue.error.message:null,m=()=>{o(""),a.enqueue.reset(),s()},f=()=>{i&&a.enqueue.mutate({url:r},{onSuccess:()=>m()})};return e.jsx(le,{open:t,onOpenChange:x=>!x&&m(),children:e.jsxs(ie,{className:"sm:max-w-[480px]",children:[e.jsxs(ce,{children:[e.jsx(de,{children:"Import from URL"}),e.jsxs(ue,{children:["Paste a direct link to a ",e.jsx("span",{className:"font-mono",children:".gguf"})," file — any HTTPS host, not just Hugging Face."]})]}),e.jsxs("div",{className:"flex flex-col gap-3",children:[e.jsx(se,{autoFocus:!0,value:l,onChange:x=>o(x.target.value),onKeyDown:x=>x.key==="Enter"&&f(),placeholder:"https://huggingface.co/owner/repo/resolve/main/model.Q4_K_M.gguf",className:"font-mono text-[12px]"}),d&&i&&e.jsxs("div",{className:"rounded-md border border-border bg-panel-2 px-3 py-2 text-[12px]",children:[e.jsx("span",{className:"text-muted",children:"Will save as "}),e.jsx("span",{className:"font-mono text-ink",children:d})]}),h&&e.jsxs("p",{className:"text-[12px]",style:{color:"var(--err)"},children:["Enter a valid http(s) link ending in ",e.jsx("span",{className:"font-mono",children:".gguf"})," (or an HF resolve URL)."]}),n&&e.jsx("p",{className:"text-[12px]",style:{color:"var(--err)"},children:n})]}),e.jsxs(Fe,{children:[e.jsx(k,{variant:"outline",onClick:m,children:"Cancel"}),e.jsxs(k,{onClick:f,disabled:!i||a.enqueue.isPending,children:[e.jsx(me,{size:14}),a.enqueue.isPending?"Adding…":"Import"]})]})]})})}function jt(t,s){const l=(t.split("/").pop()??t).toLowerCase().replace(/-gguf$/,"");return s.some(o=>`${o.name} ${o.path}`.toLowerCase().includes(l))}function bt({presetQuery:t=""}){const[s,a]=b.useState(""),[l,o]=b.useState(""),[r,d]=b.useState(null),[i,h]=b.useState(!1);b.useEffect(()=>{t&&a(t)},[t]),b.useEffect(()=>{const j=setTimeout(()=>o(s.trim()),400);return()=>clearTimeout(j)},[s]);const n=ye(l),m=ne(),f=Y(),x=m.data?.models??[],y=ot(f.data?.gpus?.[0]?.vramMb),N=l.length>0,c=n.error instanceof _&&n.error.code==="hf_unreachable",v=n.data?.results??[];return e.jsxs("div",{children:[e.jsx(lt,{}),e.jsxs("div",{className:"mb-5 flex items-center gap-2",children:[e.jsxs("div",{className:"relative flex-1",children:[e.jsx(Z,{size:15,className:"pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-faint"}),e.jsx(se,{value:s,onChange:j=>a(j.target.value),placeholder:"Search Hugging Face for GGUF models, e.g. qwen3.6 gguf",className:"pl-9"})]}),e.jsxs("button",{type:"button",onClick:()=>h(!0),className:"inline-flex shrink-0 items-center gap-1.5 rounded-md border border-border bg-transparent px-3 py-2 text-[13px] font-medium text-ink transition-colors hover:bg-panel-2",children:[e.jsx(me,{size:14}),"Import from URL"]})]}),!N&&e.jsx(vt,{repos:rt,tier:y,models:x,onOpen:j=>d(j)}),N&&e.jsx("div",{className:"flex flex-col gap-2",children:n.isLoading?[0,1,2,3].map(j=>e.jsx(re,{className:"h-[58px] w-full rounded-lg"},j)):c?e.jsx(K,{message:"Hugging Face is unreachable — check your connection.",onRetry:()=>n.refetch()}):n.isError?e.jsx(K,{message:n.error instanceof _?n.error.message:"Search failed.",onRetry:()=>n.refetch()}):v.length===0?e.jsx(ae,{icon:e.jsx(Z,{size:24}),message:`No GGUF repos found for “${l}”.`}):v.map(j=>e.jsx(yt,{item:j,onOpen:()=>d(j.repo)},j.repo))}),e.jsx(fe,{repo:r,onClose:()=>d(null),onSearch:j=>{d(null),a(j)}}),e.jsx(gt,{open:i,onClose:()=>h(!1)})]})}function vt({repos:t,tier:s,models:a,onOpen:l}){return e.jsxs("div",{className:"mb-2",children:[e.jsxs("div",{className:"mb-3 flex items-center gap-1.5 text-[12px] font-semibold uppercase tracking-wide text-faint",children:[e.jsx(We,{size:13}),"Featured"]}),e.jsx("div",{className:"grid grid-cols-1 gap-2 sm:grid-cols-2",children:t.map(o=>{const r=jt(o.repo,a);return e.jsxs("button",{type:"button",onClick:()=>l(o.repo),className:"flex flex-col gap-1.5 rounded-lg border border-border bg-panel px-4 py-3 text-left transition-colors hover:border-border-strong hover:bg-panel-2",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[o.gated&&e.jsx(H,{size:13,style:{color:"var(--warn)"},className:"shrink-0"}),e.jsx("span",{className:"truncate font-medium text-ink",children:o.name}),r&&e.jsx(ge,{})]}),e.jsx("p",{className:"line-clamp-2 text-[12px] text-muted",children:o.blurb}),e.jsxs("div",{className:"mt-0.5 flex items-center gap-1.5 text-[11px] text-faint",children:[e.jsx("span",{children:"Suggested for your GPU:"}),e.jsx("span",{className:"rounded px-1.5 py-0.5 font-mono",style:{color:"var(--accent)",background:"color-mix(in srgb, var(--accent) 12%, transparent)"},children:o.quants[s]})]})]},o.repo)})})]})}function yt({item:t,onOpen:s}){return e.jsx("button",{type:"button",onClick:s,className:"group flex items-center gap-3 rounded-lg border border-border bg-panel px-4 py-3 text-left transition-colors hover:border-border-strong hover:bg-panel-2",children:e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[t.gated&&e.jsx(H,{size:13,style:{color:"var(--warn)"},className:"shrink-0"}),e.jsx("span",{className:"truncate font-medium text-ink",children:t.repo}),t.localCount>0&&e.jsx(ge,{count:t.localCount})]}),e.jsxs("div",{className:"mt-0.5 flex items-center gap-3 text-[12px] text-muted",children:[e.jsxs("span",{children:[J(t.downloads)," downloads"]}),e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx(et,{size:11})," ",J(t.likes)]}),t.updatedAt&&e.jsxs("span",{children:["updated ",wt(t.updatedAt)]})]})]})})}function ge({count:t}){return e.jsx("span",{className:"inline-flex shrink-0 items-center gap-1 rounded-full px-1.5 py-0.5 text-[10px] font-medium",style:{color:"var(--ok)",background:"color-mix(in srgb, var(--ok) 14%, transparent)"},children:t!=null?`↓ ${t} in library`:"✓ in library"})}function J(t){return t>=1e6?`${(t/1e6).toFixed(1)}M`:t>=1e3?`${(t/1e3).toFixed(1)}K`:String(t)}function wt(t){const s=new Date(t);return Number.isNaN(s.getTime())?"":s.toLocaleDateString(void 0,{year:"numeric",month:"short",day:"numeric"})}function kt(t){const s=new Map;for(const o of t){const r=o.name.toLowerCase();(s.get(r)??s.set(r,[]).get(r)).push(o)}const a=[],l=new Set;for(const o of t){const r=o.name.toLowerCase();l.has(r)||(l.add(r),a.push(r))}return a.map(o=>({name:s.get(o)[0].name,variants:s.get(o)}))}function Pt(){const t=ne(),s=we(),a=ke(),l=ee(),o=Mt(),{data:r}=te(),d=r?.engine.state,i=l.load.isPending||d==="starting"||d==="stopping",h=l.load.isPending?l.load.variables?.key:d==="starting"?r?.model?.key:void 0,[n,m]=b.useState("library"),[f,x]=b.useState("all"),[y,N]=b.useState(!1),[c,v]=b.useState(null),[j,C]=b.useState(null),[$,D]=b.useState(null),[R,z]=b.useState(""),A=p=>{p.sourceRepo?D(p.sourceRepo):(z(p.name),m("discover"))},u=t.data?.scanning??!1,g=t.data?.models??[],S=s.data?.dirs??[],B=s.data?.primaryDir??"",w=g.filter(p=>!p.compatibleWithActiveEngine).length,F=g.filter(p=>!y&&!p.compatibleWithActiveEngine?!1:f==="all"?!0:f==="vision"?p.vision:f==="moe"?p.moe:f==="nextn"?(p.nextnLayers??0)>0:f==="embedding"?p.embedding:!0),T=kt(F),I=()=>{const p=j;p&&o.mutate(p.key,{onSuccess:()=>{L.success(`Deleted ${p.name}`),C(null)},onError:O=>{L.error(O instanceof _?O.message:"Could not delete model files."),C(null)}})};return e.jsxs("div",{className:"slim-scroll h-full w-full overflow-y-auto px-6 py-6",children:[e.jsx(De,{title:"Models",description:n==="library"?"GGUF models discovered in your folders — reuse what you already have, no re-downloading.":"Find and download GGUF models from Hugging Face, or import any direct .gguf URL.",actions:n==="library"?e.jsxs(k,{variant:"outline",size:"sm",onClick:()=>a.rescan.mutate(),disabled:u,children:[e.jsx(Ve,{size:14,className:u?"tllm-pulse":""}),u?"Scanning…":"Rescan"]}):void 0}),e.jsx("div",{className:"mb-5 flex items-center gap-1 border-b border-border",children:["library","discover"].map(p=>e.jsx("button",{type:"button",onClick:()=>m(p),className:"-mb-px border-b-2 px-3 py-2 text-[13px] font-medium capitalize transition-colors",style:{borderColor:n===p?"var(--accent)":"transparent",color:n===p?"var(--ink)":"var(--muted)"},children:p==="library"?`Library${g.length?` (${g.length})`:""}`:"Discover"},p))}),n==="library"&&w>0&&e.jsxs("div",{className:"mb-4 flex items-center justify-between gap-3 rounded-[var(--radius)] border border-border bg-panel px-4 py-2.5 text-[12px]",children:[e.jsx("span",{className:"text-muted",children:y?`Showing all models. ${w} can't load on the active engine.`:`${w} ${w===1?"model is":"models are"} hidden — the active engine can't load ${w===1?"it":"them"}.`}),e.jsx("button",{type:"button",onClick:()=>N(p=>!p),className:"shrink-0 font-medium text-accent hover:underline",children:y?"Show compatible only":"Show all"})]}),n==="discover"?e.jsx(bt,{presetQuery:R}):e.jsx(Nt,{modelsQ:t,mut:a,actions:l,loadBusy:i,loadingKey:h,dirs:S,primaryDir:B,scanning:u,models:g,filter:f,setFilter:x,groups:T,setOpenKey:v,setConfirmDelete:C,onDiscover:A}),e.jsx(He,{modelKey:c,onClose:()=>v(null),onViewRepo:p=>{v(null),D(p)}}),e.jsx(fe,{repo:$,onClose:()=>D(null),onSearch:p=>{D(null),z(p),m("discover")}}),e.jsx(_t,{model:j,onCancel:()=>C(null),onConfirm:I,deleting:o.isPending})]})}function Nt({modelsQ:t,mut:s,actions:a,loadBusy:l,loadingKey:o,dirs:r,primaryDir:d,scanning:i,models:h,filter:n,setFilter:m,groups:f,setOpenKey:x,setConfirmDelete:y,onDiscover:N}){return e.jsxs(e.Fragment,{children:[e.jsx(Ze,{dirs:r,primaryDir:d,mut:s}),h.length>0&&e.jsx("div",{className:"mb-4 flex items-center gap-2",children:["all","vision","moe","nextn","embedding"].map(c=>e.jsx(Dt,{active:n===c,onClick:()=>m(c),children:c==="all"?`All ${h.length}`:c==="vision"?"Vision":c==="moe"?"MoE":c==="nextn"?"NextN":"Embed"},c))}),t.isLoading?e.jsx("div",{className:"flex flex-col gap-2",children:[0,1,2].map(c=>e.jsx(re,{className:"h-[58px] w-full rounded-lg"},c))}):t.isError?e.jsx(K,{message:"Could not load models.",onRetry:()=>t.refetch()}):h.length===0?e.jsx(ae,{icon:e.jsx(Se,{size:24}),message:r.length===0?"No model folders yet. Add a folder above to discover the GGUF models you already have.":i?"Scanning your folders…":"No GGUF models found in your folders."}):e.jsx("div",{className:"flex flex-col gap-2",children:f.map(c=>c.variants.length===1?e.jsx(je,{m:c.variants[0],onLoad:()=>a.load.mutate({key:c.variants[0].key}),onEject:()=>a.eject.mutate(),onTune:()=>x(c.variants[0].key),onDelete:()=>y(c.variants[0]),onDiscover:()=>N(c.variants[0]),busy:l,loadingThis:o===c.variants[0].key,ejecting:a.eject.isPending},c.variants[0].key):e.jsx(St,{group:c,onLoad:v=>a.load.mutate({key:v}),onEject:()=>a.eject.mutate(),onTune:v=>x(v),onDelete:v=>y(v),onDiscover:N,busy:l,loadingKey:o,ejecting:a.eject.isPending},c.name.toLowerCase()))})]})}function Mt(){const t=Ne();return Me({mutationFn:s=>Ce(s),onSuccess:()=>{t.invalidateQueries({queryKey:V.models}),t.invalidateQueries({queryKey:V.status})}})}function St({group:t,onLoad:s,onEject:a,onTune:l,onDelete:o,onDiscover:r,busy:d,loadingKey:i,ejecting:h}){const[n,m]=b.useState(!1),f=t.variants.some(x=>x.loaded);return e.jsxs("div",{className:"rounded-lg border border-border bg-panel",children:[e.jsxs("button",{type:"button",onClick:()=>m(x=>!x),className:"flex w-full items-center gap-3 px-4 py-3 text-left",children:[e.jsx(Pe,{size:16,className:`shrink-0 text-muted transition-transform ${n?"rotate-90":""}`}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-1.5",children:[e.jsx("span",{className:"truncate font-medium text-ink",children:t.name}),f&&e.jsx(M,{tone:"ok",children:"loaded"})]}),e.jsxs("div",{className:"mt-0.5 truncate text-[12px] text-muted",children:[t.variants.length," variants",t.variants[0].arch?` · ${t.variants[0].arch}`:""]})]}),e.jsxs(oe,{variant:"mono",children:[t.variants.length," quants"]})]}),n&&e.jsx("div",{className:"flex flex-col gap-2 border-t border-border px-3 pb-3 pt-2",children:t.variants.map(x=>e.jsx(je,{m:x,child:!0,onLoad:()=>s(x.key),onEject:a,onTune:()=>l(x.key),onDelete:()=>o(x),onDiscover:()=>r(x),busy:d,loadingThis:i===x.key,ejecting:h},x.key))})]})}function je({m:t,child:s,onLoad:a,onEject:l,onTune:o,onDelete:r,onDiscover:d,busy:i,loadingThis:h,ejecting:n}){const m=!t.incomplete&&!t.parseError,f=t.compatibleWithActiveEngine!==!1,x=t.format==="gguf"?"llama.cpp":"MLX or vLLM",y=(t.nextnLayers??0)>0;return e.jsxs("div",{className:s?"group flex flex-col gap-2 rounded-md border border-border bg-panel-2 px-3 py-2.5 sm:flex-row sm:items-center sm:gap-3":"group flex flex-col gap-2 rounded-lg border border-border bg-panel px-4 py-3 sm:flex-row sm:items-center sm:gap-3",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-1.5",children:[e.jsx("span",{className:"min-w-0 break-words font-medium text-ink sm:truncate",children:s?t.quant:t.name}),t.loaded&&e.jsx(M,{tone:"ok",children:"loaded"}),t.vision&&e.jsx(M,{children:"vision"}),t.embedding&&e.jsx(M,{children:"embed"}),t.moe&&e.jsx(M,{children:"MoE"}),y&&e.jsx(M,{tone:"spec",children:"NextN"}),t.hasProfile&&e.jsx(M,{children:"tuned"}),t.incomplete&&e.jsx(M,{tone:"warn",children:"missing parts"}),t.parseError&&e.jsx(M,{tone:"err",children:"unreadable"}),!f&&e.jsxs(M,{tone:"warn",children:["needs ",x]})]}),e.jsxs("div",{className:"mt-0.5 truncate text-[12px] text-muted",children:[t.arch,t.dir?` · ${t.dir}`:""]})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-x-3 gap-y-2 sm:flex-nowrap sm:gap-3",children:[!s&&e.jsx(oe,{variant:"mono",children:t.quant}),e.jsx(U,{children:Bt(t.sizeBytes)}),e.jsx(U,{children:t.nativeCtx?`${Ft(t.nativeCtx)} ctx`:"—"}),e.jsx(Lt,{m:t}),e.jsxs("div",{className:"ml-auto flex items-center gap-1 sm:ml-0",children:[e.jsxs(k,{size:"sm",onClick:a,disabled:!m||!f||i,title:m?f?"":`The active engine can't load this model — switch to ${x}`:"Model is incomplete or unreadable",children:[h?e.jsx(_e,{size:14,className:"animate-spin"}):e.jsx(xe,{size:14}),h?"Loading…":t.loaded?"Reload":"Load"]}),t.incomplete&&e.jsxs(k,{size:"sm",variant:"outline",onClick:d,title:"Download the missing shard files",children:[e.jsx(E,{size:14}),"Re-download"]}),t.loaded&&e.jsxs(k,{size:"sm",variant:"outline",onClick:l,disabled:n,title:"Eject model (stop the engine)",children:[e.jsx(Te,{size:14}),"Eject"]}),e.jsx(k,{size:"sm",variant:"ghost",onClick:o,disabled:!m,title:"Load settings",children:e.jsx(Oe,{size:14})}),e.jsxs(Ie,{children:[e.jsx(Ke,{"aria-label":"Model actions",className:"grid h-8 w-8 place-items-center rounded-md text-muted opacity-100 transition-opacity hover:bg-panel-2 hover:text-ink focus:opacity-100 data-[state=open]:opacity-100 sm:opacity-0 sm:group-hover:opacity-100",children:e.jsx(Le,{size:16})}),e.jsxs(Ue,{align:"end",children:[e.jsxs(W,{onSelect:d,children:[e.jsx(at,{size:14})," Find other quants…"]}),e.jsxs(W,{destructive:!0,disabled:t.loaded,onSelect:r,title:t.loaded?"Eject the model before deleting":void 0,children:[e.jsx(Je,{size:14})," Delete file…"]})]})]})]})]})]})}function _t({model:t,onCancel:s,onConfirm:a,deleting:l}){const o=t!==null,r=t?Ct(t):[],d=!!t?.loaded;return e.jsx($e,{open:o,onOpenChange:i=>!i&&s(),children:e.jsxs(ze,{children:[e.jsxs(Qe,{children:[e.jsx(Ge,{children:d?"Model is loaded":"Delete model files?"}),e.jsx(qe,{children:d?"This model is currently loaded in the running engine. Eject it first, then delete.":r.length>1?`This is a split model — all ${r.length} part files will be permanently deleted from disk. This cannot be undone.`:"This file will be permanently deleted from disk. This cannot be undone."})]}),!d&&r.length>0&&e.jsx("div",{className:"max-h-40 overflow-auto rounded-md border border-border bg-panel-2 p-2",children:r.map(i=>e.jsx("div",{className:"truncate font-mono text-[12px] text-muted",children:i},i))}),e.jsxs(Ee,{children:[e.jsx(Re,{children:"Cancel"}),!d&&e.jsx(Ae,{onClick:a,disabled:l,children:l?"Deleting…":"Delete"})]})]})})}function Ct(t){const s=t.path.includes("\\")?"\\":"/",l=t.path.slice(t.path.lastIndexOf(s)+1).match(/^(.*)-(\d{5})-of-(\d{5})\.gguf$/i);if(!l)return[t.path];const o=t.path.slice(0,t.path.lastIndexOf(s)),r=l[1],d=Number(l[3]),i=[];for(let h=1;h<=d;h++){const n=String(h).padStart(5,"0"),m=String(d).padStart(5,"0");i.push(`${o}${s}${r}-${n}-of-${m}.gguf`)}return i}function Dt({active:t,onClick:s,children:a}){return e.jsx("button",{type:"button",onClick:s,className:"rounded-full border px-3 py-1 text-[12px] font-medium transition-colors",style:{borderColor:t?"var(--accent)":"var(--border)",background:t?"color-mix(in srgb, var(--accent) 12%, transparent)":"transparent",color:t?"var(--accent)":"var(--muted)"},children:a})}function M({children:t,tone:s}){const a=s==="ok"?"var(--ok)":s==="warn"?"var(--warn)":s==="err"?"var(--err)":s==="spec"?"var(--accent)":"var(--muted)";return e.jsx("span",{className:"rounded px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide",style:{color:a,background:`color-mix(in srgb, ${a} 12%, transparent)`},children:t})}function U({children:t}){return e.jsx("div",{className:"w-[72px] text-right text-[13px] text-muted",children:t})}function Lt({m:t}){return t.liveTps!=null?e.jsx("div",{className:"w-[72px] text-right text-[13px]",title:"Live tokens/sec (loaded now)",children:e.jsxs("span",{className:"tllm-pulse inline-flex items-center gap-1 font-medium",style:{color:"var(--ok)"},children:[e.jsx("span",{className:"h-1.5 w-1.5 rounded-full",style:{background:"var(--ok)"}}),Math.round(t.liveTps)," t/s"]})}):t.lastTps!=null?e.jsxs("div",{className:"w-[72px] text-right text-[13px] text-ink",title:"Last-session tokens/sec",children:[Math.round(t.lastTps)," t/s"]}):t.benchTps!=null?e.jsxs("div",{className:"w-[72px] text-right text-[13px] text-muted",title:"Benchmark tokens/sec",children:[Math.round(t.benchTps)," t/s"]}):e.jsx(U,{children:"—"})}function Bt(t){return t>=1e9?`${(t/1e9).toFixed(1)} GB`:`${Math.round(t/1e6)} MB`}function Ft(t){return t>=1024?`${Math.round(t/1024)}K`:String(t)}export{Pt as ModelsScreen};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as e}from"./radix-BFvMxQq9.js";import{r as i,d as Ne}from"./vendor-D_-14Whs.js";import{u as ye,g as ke,f as we,P as Ce,i as Se,j as Me}from"./personas-CQapYHeK.js";import{S as Ae,T as Le}from"./common-DIXPIrUd.js";import{c as L,e as de,M as ce,o as Pe,p as Te,B as g,a2 as Ie,t as b,A as k,L as C,u as z,a3 as Ue,X as xe,a4 as Ee,a5 as ze,m as De,a6 as Re}from"./index-sjgdofsd.js";import{C as _e}from"./copy-button-BtQZA6P8.js";import{M as Ge}from"./ModelDirs-Bj-XrX0c.js";import{S as me}from"./save-DE1APWTG.js";import{S as re}from"./sparkles-C54kYWeQ.js";import{C as A}from"./check-DFwkcl_5.js";import{R as ue,E as ie}from"./refresh-cw-BoAcjLtt.js";const Fe=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m16 12-4-4-4 4",key:"177agl"}],["path",{d:"M12 16V8",key:"1sbj14"}]],Oe=L("circle-arrow-up",Fe);const $e=[["rect",{width:"20",height:"14",x:"2",y:"3",rx:"2",key:"48i651"}],["line",{x1:"8",x2:"16",y1:"21",y2:"21",key:"1svkeh"}],["line",{x1:"12",x2:"12",y1:"17",y2:"21",key:"vw1qmm"}]],Be=L("monitor",$e);const qe=[["path",{d:"M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401",key:"kfwtm"}]],He=L("moon",qe);const Ke=[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}],["path",{d:"M12 8v4",key:"1got3b"}],["path",{d:"M12 16h.01",key:"1drbdi"}]],pe=L("shield-alert",Ke);const Ve=[["circle",{cx:"12",cy:"12",r:"4",key:"4exip2"}],["path",{d:"M12 2v2",key:"tus03m"}],["path",{d:"M12 20v2",key:"1lh1kg"}],["path",{d:"m4.93 4.93 1.41 1.41",key:"149t6j"}],["path",{d:"m17.66 17.66 1.41 1.41",key:"ptbguv"}],["path",{d:"M2 12h2",key:"1t8f8n"}],["path",{d:"M20 12h2",key:"1q8mjw"}],["path",{d:"m6.34 17.66-1.41 1.41",key:"1m8zz5"}],["path",{d:"m19.07 4.93-1.41 1.41",key:"1shlcs"}]],Ye=L("sun",Ve),Qe=!1,oe="tllm.thinkingEnabled.default";function y({value:t,min:n,max:a,step:o,onCommit:s,className:l,ariaLabel:c}){const[r,d]=i.useState(String(t));i.useEffect(()=>{d(String(t))},[t]);const h=p=>{let m=p;return n!=null&&(m=Math.max(n,m)),a!=null&&(m=Math.min(a,m)),m};return e.jsx("input",{type:"number",inputMode:"numeric","aria-label":c,min:n,max:a,step:o,value:r,onChange:p=>{const m=p.target.value;if(d(m),m.trim()==="")return;const x=Number(m);Number.isFinite(x)&&s(x)},onBlur:()=>{const p=Number(r),m=r.trim()===""||!Number.isFinite(p)?t:h(p);d(String(m)),s(m)},onKeyDown:p=>{p.key==="Enter"&&p.target.blur()},className:l})}const U=(t,n,a)=>Math.max(n,Math.min(a,Math.round(t)));function gt(){const{theme:t,setTheme:n}=de(),{query:a,save:o}=ce(),s=a.data,l=Pe(),c=Te(),r=l.data?.dirs??[],d=l.data?.primaryDir??"",[h,p]=i.useState(60),[m,x]=i.useState(6996),[P,S]=i.useState(!0),[v,T]=i.useState(!0),[w,f]=i.useState(!1),[j,D]=i.useState(8192),[R,_]=i.useState(99),[G,F]=i.useState(0),[O,$]=i.useState(0),[he,fe]=i.useState("off"),[B,q]=i.useState(!1),[H,K]=i.useState(!0),[V,Y]=i.useState(!1),[Q,W]=i.useState(""),[X,J]=i.useState(!1),[Z,ee]=i.useState(!0),[te,se]=i.useState(1),[E,be]=i.useState(()=>localStorage.getItem(oe)!=="false"),[ge,ae]=i.useState(!1);i.useEffect(()=>{s&&(p(s.idleTtlMinutes),x(s.port??6996),S(s.autoGenerateTitles),T(s.openBrowserOnStart),f(s.autoLoadOnStart??!1),D(s.modelDefaults?.ctx??8192),_(s.modelDefaults?.ngl??99),F(s.modelDefaults?.imageMaxTokens??0),$(s.modelDefaults?.maxTokens??0),fe(s.telemetryLevel??"off"),q(s.lanBind??!1),K(s.requireApiKey??!0),Y(s.comfyui?.enabled??!1),W(s.comfyui?.url??""),J(s.comfyui?.reverseGate??!1),ee(s.gateway?.autoSwap??!0),se(s.gateway?.keepN??1))},[s]),i.useEffect(()=>{localStorage.setItem(oe,E?"true":"false")},[E]);const ne=()=>({idleTtlMinutes:U(h,0,1440),port:U(m,1024,65535),autoGenerateTitles:P,openBrowserOnStart:v,autoLoadOnStart:w,telemetryLevel:he,lanBind:B,requireApiKey:H,modelDefaults:{ctx:Math.max(256,Math.round(j)),ngl:U(R,0,99),imageMaxTokens:Math.max(0,Math.round(G)),maxTokens:Math.max(0,Math.round(O))},comfyui:{enabled:V,url:Q.trim(),reverseGate:X},gateway:{autoSwap:Z,keepN:U(te,1,4)}}),je=()=>{o.mutate(ne(),{onSuccess:u=>{const N=u.rebind;N?.portChanged?(b.success(`Port changed to ${N.port} — reconnecting…`),setTimeout(()=>{const I=new URL(window.location.href);I.port=String(N.port),window.location.href=I.toString()},1300)):N?b.success(N.lanBind?"LAN access enabled — applied (no restart needed)":"LAN access disabled — applied"):b.success("Settings saved")},onError:u=>b.error(u instanceof k?u.message:"Could not save settings.")})},ve=()=>{o.mutate(ne(),{onSuccess:()=>ae(!0),onError:u=>b.error(u instanceof k?u.message:"Could not save settings before restart.")})};return e.jsxs("div",{className:"w-full px-6 py-6",children:[e.jsx(Ae,{title:"Settings",description:"Configure TurboLLM behavior and appearance."}),ge&&e.jsx(st,{onDismiss:()=>ae(!1)}),e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(We,{}),e.jsxs("section",{className:"rounded-lg border border-border bg-panel p-4",children:[e.jsx("h2",{className:"mb-3 text-[13px] font-semibold uppercase tracking-wide text-faint",children:"Appearance"}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[14px] font-medium text-ink",children:"Theme"}),e.jsx("div",{className:"text-[12px] text-muted",children:"Choose light, dark, or follow your system setting"})]}),e.jsx("div",{className:"flex overflow-hidden rounded-lg border border-border",children:[{value:"light",label:"Light",Icon:Ye},{value:"system",label:"System",Icon:Be},{value:"dark",label:"Dark",Icon:He}].map(({value:u,label:N,Icon:I})=>e.jsxs("button",{type:"button",onClick:()=>n(u),className:"flex items-center gap-1.5 px-3 py-2 text-[13px] transition-colors",style:{background:t===u?"var(--accent)":"transparent",color:t===u?"var(--on-accent)":"var(--muted)"},children:[e.jsx(I,{size:14}),N]},u))})]}),e.jsxs("label",{className:"mt-2 flex cursor-pointer items-center justify-between border-t border-border py-2 pt-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[14px] font-medium text-ink",children:"Enable thinking by default"}),e.jsx("div",{className:"text-[12px] text-muted",children:"Let reasoning models think before answering in new chats (you can toggle it per chat). Off = answer directly, faster."})]}),e.jsx("input",{type:"checkbox",checked:E,onChange:u=>be(u.target.checked),className:"h-4 w-4 accent-[var(--accent)]"})]})]}),e.jsxs("section",{className:"rounded-lg border border-border bg-panel p-4",children:[e.jsx("h2",{className:"mb-3 text-[13px] font-semibold uppercase tracking-wide text-faint",children:"Engine"}),e.jsxs("div",{className:"flex items-center justify-between py-2",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[14px] font-medium text-ink",children:"Idle timeout"}),e.jsx("div",{className:"text-[12px] text-muted",children:"Unload model after this many minutes of inactivity (0 = never)"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(y,{value:h,min:0,max:1440,onCommit:p,ariaLabel:"Idle timeout in minutes",className:"w-20 rounded-md border border-border bg-bg px-2 py-1 text-right text-[13px] text-ink outline-none"}),e.jsx("span",{className:"text-[12px] text-muted",children:"min"})]})]})]}),e.jsxs("section",{className:"rounded-lg border border-border bg-panel p-4",children:[e.jsx("h2",{className:"mb-1 text-[13px] font-semibold uppercase tracking-wide text-faint",children:"Model Defaults"}),e.jsx("p",{className:"mb-3 text-[12px] text-muted",children:"Applied the first time a model is loaded. A model's own saved settings always override these."}),e.jsxs("div",{className:"flex items-center justify-between py-2",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[14px] font-medium text-ink",children:"Context length"}),e.jsx("div",{className:"text-[12px] text-muted",children:"Default context window, capped at each model's native max"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(y,{value:j,min:256,step:512,onCommit:D,ariaLabel:"Default context length",className:"w-24 rounded-md border border-border bg-bg px-2 py-1 text-right text-[13px] text-ink outline-none"}),e.jsx("span",{className:"text-[12px] text-muted",children:"tok"})]})]}),e.jsxs("div",{className:"flex items-center justify-between py-2",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[14px] font-medium text-ink",children:"GPU layers"}),e.jsx("div",{className:"text-[12px] text-muted",children:"Layers to offload to the GPU (99 = all); ignored on CPU-only machines"})]}),e.jsx("div",{className:"flex items-center gap-2",children:e.jsx(y,{value:R,min:0,max:99,onCommit:_,ariaLabel:"Default GPU layers",className:"w-20 rounded-md border border-border bg-bg px-2 py-1 text-right text-[13px] text-ink outline-none"})})]}),e.jsxs("div",{className:"flex items-center justify-between py-2",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[14px] font-medium text-ink",children:"Image max tokens"}),e.jsx("div",{className:"text-[12px] text-muted",children:"Per-image token budget for vision models (0 = engine default)"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(y,{value:G,min:0,step:256,onCommit:F,ariaLabel:"Image max tokens",className:"w-24 rounded-md border border-border bg-bg px-2 py-1 text-right text-[13px] text-ink outline-none"}),e.jsx("span",{className:"text-[12px] text-muted",children:"tok"})]})]}),e.jsxs("div",{className:"flex items-center justify-between py-2",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[14px] font-medium text-ink",children:"Max response tokens"}),e.jsx("div",{className:"text-[12px] text-muted",children:"Hard cap on tokens generated per reply (0 = unlimited). Also caps Claude Code / API requests."})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(y,{value:O,min:0,step:256,onCommit:$,ariaLabel:"Max response tokens",className:"w-24 rounded-md border border-border bg-bg px-2 py-1 text-right text-[13px] text-ink outline-none"}),e.jsx("span",{className:"text-[12px] text-muted",children:"tok"})]})]})]}),e.jsxs("section",{className:"rounded-lg border border-border bg-panel p-4",children:[e.jsx("h2",{className:"mb-3 text-[13px] font-semibold uppercase tracking-wide text-faint",children:"Chat"}),e.jsxs("label",{className:"flex cursor-pointer items-center justify-between py-2",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[14px] font-medium text-ink",children:"Auto-generate chat titles"}),e.jsx("div",{className:"text-[12px] text-muted",children:"Uses the model to create a title after the first exchange"})]}),e.jsx("input",{type:"checkbox",checked:P,onChange:u=>S(u.target.checked),className:"h-4 w-4 accent-[var(--accent)]"})]})]}),e.jsx(nt,{}),e.jsxs("section",{className:"rounded-lg border border-border bg-panel p-4",children:[e.jsx("h2",{className:"mb-3 text-[13px] font-semibold uppercase tracking-wide text-faint",children:"Startup"}),e.jsxs("label",{className:"flex cursor-pointer items-center justify-between py-2",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[14px] font-medium text-ink",children:"Open browser on start"}),e.jsx("div",{className:"text-[12px] text-muted",children:"Automatically open the UI when the daemon starts"})]}),e.jsx("input",{type:"checkbox",checked:v,onChange:u=>T(u.target.checked),className:"h-4 w-4 accent-[var(--accent)]"})]}),e.jsxs("label",{className:"flex cursor-pointer items-center justify-between py-2",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[14px] font-medium text-ink",children:"Auto-load last model"}),e.jsx("div",{className:"text-[12px] text-muted",children:"Reload the last-used model automatically when the daemon starts"})]}),e.jsx("input",{type:"checkbox",checked:w,onChange:u=>f(u.target.checked),className:"h-4 w-4 accent-[var(--accent)]"})]})]}),e.jsx(Xe,{enabled:V,setEnabled:Y,gatePath:s?.comfyui?.gatePath??"",url:Q,setUrl:W,reverseGate:X,setReverseGate:J}),e.jsx(Je,{autoSwap:Z,setAutoSwap:ee,keepN:te,setKeepN:se}),e.jsx(Ze,{lanBind:B,setLanBind:q,requireApiKey:H,setRequireApiKey:K,port:m,setPort:x}),e.jsx(Ge,{dirs:r,primaryDir:d,mut:c}),e.jsx(et,{tokenSet:s?.hfTokenSet??!1,onSaved:()=>{a.refetch()}}),Qe,e.jsx(at,{}),e.jsx("div",{className:"flex justify-end",children:e.jsxs(g,{onClick:je,disabled:o.isPending||a.isLoading,children:[e.jsx(me,{size:14}),o.isPending?"Saving…":"Save settings"]})}),e.jsx(tt,{onRestart:ve}),e.jsx(rt,{}),e.jsx(it,{})]})]})}function We(){const t=Ne(),{data:n}=z(),a=ye(),o=de(c=>c.setPendingConversationId),s=n?.engine.state==="running"&&!!n?.model,l=()=>{s&&a.createExpert.mutate(void 0,{onSuccess:c=>{o(c.id),t("/chat")},onError:c=>b.error(c instanceof k?c.message:"Could not launch the Expert assistant.")})};return e.jsxs("section",{className:"rounded-lg border border-border bg-panel p-4",children:[e.jsx("h2",{className:"mb-1 text-[13px] font-semibold uppercase tracking-wide text-faint",children:"TurboLLM Expert"}),e.jsx("p",{className:"mb-3 text-[12px] text-muted",children:"Chat with a built-in assistant that knows TurboLLM — it can explain features, help configure engines, models, and settings, and troubleshoot. Runs on your loaded model."}),s?e.jsxs(g,{onClick:l,disabled:a.createExpert.isPending,children:[e.jsx(re,{size:14}),a.createExpert.isPending?"Launching…":"Launch Expert"]}):e.jsxs("div",{className:"flex items-start gap-2 rounded-md border p-2.5 text-[12px]",style:{borderColor:"color-mix(in srgb, var(--accent) 40%, var(--border))",background:"color-mix(in srgb, var(--accent) 6%, transparent)"},children:[e.jsx(re,{size:14,className:"mt-0.5 shrink-0",style:{color:"var(--accent)"}}),e.jsxs("div",{className:"text-muted",children:["Load a model first to chat with the Expert assistant. Pick one on the"," ",e.jsx("button",{type:"button",onClick:()=>t("/models"),className:"font-medium text-ink underline-offset-2 hover:underline",children:"Models"})," ","screen."]})]})]})}function Xe({enabled:t,setEnabled:n,gatePath:a,url:o,setUrl:s,reverseGate:l,setReverseGate:c}){const{data:r}=z(),{install:d,uninstall:h}=Ue(),[p,m]=i.useState(""),x=r?.comfyui,P=!!a,S=a.replace(/[\\/]turbollm_gate[\\/]?$/,""),v=f=>{if(!f.trim()){b.error("Enter the path to your ComfyUI folder first.");return}d.mutate(f.trim(),{onSuccess:j=>{b.success(`Gate installed at ${j.path}. ${j.note??""}`.trim()),m("")},onError:j=>b.error(j instanceof k?j.message:"Could not install the gate node.")})},T=()=>{h.mutate(void 0,{onSuccess:()=>b.success("ComfyUI gate removed."),onError:f=>b.error(f instanceof k?f.message:"Could not remove the gate node.")})},w=x?.enabled?x.installed?x.held?{color:"var(--warn)",text:"ComfyUI is rendering — the model is unloaded and loads are paused."}:x.lastSignalAgoMs==null?{color:"var(--muted)",text:"Installed. Restart ComfyUI, then run a job to connect."}:{color:"var(--ok)",text:`ComfyUI idle — connected (last signal ${Math.round(x.lastSignalAgoMs/1e3)}s ago).`}:{color:"var(--muted)",text:"Install the gate node in ComfyUI to activate this."}:null;return e.jsxs("section",{className:"rounded-lg border border-border bg-panel p-4",children:[e.jsx("h2",{className:"mb-1 text-[13px] font-semibold uppercase tracking-wide text-faint",children:"ComfyUI"}),e.jsx("p",{className:"mb-3 text-[12px] text-muted",children:"Share the GPU with ComfyUI. The instant ComfyUI starts a render, TurboLLM unloads its model and pauses new loads so they don't fight over VRAM — then reloads the model when ComfyUI's queue is empty. This needs a small one-time setup node installed in ComfyUI."}),e.jsxs("label",{className:"flex cursor-pointer items-center justify-between py-2",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[14px] font-medium text-ink",children:"Pause for ComfyUI"}),e.jsx("div",{className:"text-[12px] text-muted",children:"Unload the model and block loads while ComfyUI renders (Save to apply)"})]}),e.jsx("input",{type:"checkbox",checked:t,onChange:f=>n(f.target.checked),className:"h-4 w-4 accent-[var(--accent)]"})]}),t&&e.jsxs("div",{className:"mt-2 flex flex-col gap-3 border-t border-border pt-3",children:[e.jsx("div",{className:"text-[13px] font-medium text-ink",children:"One-time setup"}),P?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"text-[12px] text-muted",children:[e.jsxs("span",{className:"inline-flex items-center gap-1.5 text-ink",children:[e.jsx(A,{size:13,style:{color:"var(--ok)"}})," Gate installed"]}),e.jsx("div",{className:"mt-1 break-all font-mono text-[11px] text-faint",children:a})]}),x?.installedVersion!=null&&x.installedVersion<(x.currentVersion??1/0)&&e.jsxs("div",{className:"flex items-center justify-between gap-3 rounded-md border px-3 py-2",style:{borderColor:"var(--warn)",background:"color-mix(in srgb, var(--warn) 10%, transparent)"},children:[e.jsxs("span",{className:"inline-flex items-center gap-1.5 text-[12px]",style:{color:"var(--warn)"},children:[e.jsx(Le,{size:13}),"Update available — node v",x.installedVersion," → v",x.currentVersion]}),e.jsx(g,{size:"sm",onClick:()=>v(S),disabled:d.isPending,children:d.isPending?e.jsx(C,{size:13,className:"animate-spin"}):"Update node"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(g,{variant:"outline",size:"sm",onClick:()=>v(S),disabled:d.isPending,children:[d.isPending?e.jsx(C,{size:13,className:"animate-spin"}):e.jsx(ue,{size:13}),"Reinstall / update"]}),e.jsxs(g,{variant:"outline",size:"sm",onClick:T,disabled:h.isPending,children:[h.isPending?e.jsx(C,{size:13,className:"animate-spin"}):e.jsx(xe,{size:13}),"Remove"]})]}),e.jsx("div",{className:"text-[12px] text-faint",children:"Restart ComfyUI after installing or updating for the gate to take effect."})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"text-[12px] text-muted",children:["Enter your ComfyUI folder (the one containing ",e.jsx("span",{className:"font-mono",children:"custom_nodes"}),"), or the",e.jsx("span",{className:"font-mono",children:" custom_nodes"})," folder itself. TurboLLM writes the gate node there, wired to this daemon."]}),e.jsxs("div",{className:"flex flex-col gap-2 sm:flex-row sm:items-center",children:[e.jsx("input",{type:"text",value:p,onChange:f=>m(f.target.value),placeholder:"e.g. D:\\\\ComfyUI_windows_portable\\\\ComfyUI",spellCheck:!1,autoComplete:"off",onKeyDown:f=>{f.key==="Enter"&&v(p)},className:"flex-1 rounded-md border border-border bg-bg px-2 py-1.5 font-mono text-[12px] text-ink outline-none"}),e.jsx(g,{size:"sm",onClick:()=>v(p),disabled:d.isPending||!p.trim(),children:d.isPending?e.jsx(C,{size:13,className:"animate-spin"}):"Install gate"})]})]}),e.jsxs("div",{className:"flex flex-col gap-3 border-t border-border pt-3",children:[e.jsxs("label",{className:"flex cursor-pointer items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[13px] font-medium text-ink",children:"Free ComfyUI when TurboLLM loads"}),e.jsx("div",{className:"text-[12px] text-muted",children:"Before loading a model, tell ComfyUI to unload its VRAM (Save to apply)"})]}),e.jsx("input",{type:"checkbox",checked:l,onChange:f=>c(f.target.checked),className:"h-4 w-4 accent-[var(--accent)]"})]}),l&&e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsxs("div",{className:"text-[12px] text-muted",children:["ComfyUI's address — TurboLLM calls its ",e.jsx("span",{className:"font-mono",children:"/free"})," endpoint here."]}),e.jsx("input",{type:"text",value:o,onChange:f=>s(f.target.value),placeholder:"http://127.0.0.1:8188",spellCheck:!1,autoComplete:"off",className:"rounded-md border border-border bg-bg px-2 py-1.5 font-mono text-[12px] text-ink outline-none"})]})]}),w&&e.jsxs("div",{className:"flex items-center gap-2 border-t border-border pt-3 text-[12px] text-muted",children:[e.jsx("span",{className:"inline-block h-2 w-2 shrink-0 rounded-full",style:{background:w.color}}),w.text]})]})]})}function Je({autoSwap:t,setAutoSwap:n,keepN:a,setKeepN:o}){return e.jsxs("section",{className:"rounded-lg border border-border bg-panel p-4",children:[e.jsx("h2",{className:"mb-1 text-[13px] font-semibold uppercase tracking-wide text-faint",children:"Gateway"}),e.jsxs("p",{className:"mb-3 text-[12px] text-muted",children:["Controls how the OpenAI / Anthropic gateway handles the ",e.jsx("code",{className:"font-mono",children:"model"})," field. Auto-swap loads the requested model on demand; keep-N holds multiple models hot simultaneously."]}),e.jsxs("label",{className:"flex cursor-pointer items-center justify-between py-2",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[14px] font-medium text-ink",children:"Auto model-swap"}),e.jsx("div",{className:"text-[12px] text-muted",children:"Auto-load the model named in each API request (Save to apply)"})]}),e.jsx("input",{type:"checkbox",checked:t,onChange:s=>n(s.target.checked),className:"h-4 w-4 accent-[var(--accent)]"})]}),e.jsxs("div",{className:"flex items-center justify-between py-2",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[14px] font-medium text-ink",children:"Keep-N models loaded"}),e.jsx("div",{className:"text-[12px] text-muted",children:"Max simultaneous hot models (1 = pure swap, 2–4 = pool with LRU eviction)"})]}),e.jsx(y,{value:a,min:1,max:4,onCommit:o,ariaLabel:"Keep-N models",className:"w-16 rounded-md border border-border bg-bg px-2 py-1 text-right text-[13px] text-ink outline-none"})]})]})}function Ze({lanBind:t,setLanBind:n,requireApiKey:a,setRequireApiKey:o,port:s,setPort:l}){const{data:c}=Ee(),r=c?.lanUrl??"",d=c?.hasApiKey??!1;return e.jsxs("section",{className:"rounded-lg border border-border bg-panel p-4",children:[e.jsx("h2",{className:"mb-3 text-[13px] font-semibold uppercase tracking-wide text-faint",children:"Network"}),e.jsxs("div",{className:"flex items-center justify-between py-2",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[14px] font-medium text-ink",children:"Port"}),e.jsx("div",{className:"text-[12px] text-muted",children:"Port the daemon listens on (1024–65535)"})]}),e.jsx(y,{value:s,min:1024,max:65535,onCommit:l,ariaLabel:"Daemon port",className:"w-24 rounded-md border border-border bg-bg px-2 py-1 text-right text-[13px] text-ink outline-none"})]}),e.jsxs("label",{className:"flex cursor-pointer items-center justify-between py-2",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[14px] font-medium text-ink",children:"Expose on local network (LAN)"}),e.jsx("div",{className:"text-[12px] text-muted",children:"Allow other devices on your network to reach the API"})]}),e.jsx("input",{type:"checkbox",checked:t,onChange:h=>n(h.target.checked),className:"h-4 w-4 accent-[var(--accent)]"})]}),t&&e.jsxs("div",{className:"mt-2 flex flex-col gap-3 border-t border-border pt-3",children:[r&&e.jsxs("div",{className:"text-[13px]",children:[e.jsx("span",{className:"text-muted",children:"LAN URL: "}),e.jsx("span",{className:"font-mono text-ink",children:r})]}),e.jsxs("label",{className:"flex cursor-pointer items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[14px] font-medium text-ink",children:"Require an API key"}),e.jsx("div",{className:"text-[12px] text-muted",children:"When off, any device on your network can use this TurboLLM with no key"})]}),e.jsx("input",{type:"checkbox",checked:a,onChange:h=>o(h.target.checked),className:"h-4 w-4 accent-[var(--accent)]"})]}),e.jsxs("div",{className:"flex items-start gap-2 rounded-md border p-2.5 text-[12px]",style:{borderColor:"color-mix(in srgb, var(--warn) 40%, var(--border))",background:"color-mix(in srgb, var(--warn) 8%, transparent)"},children:[e.jsx(pe,{size:14,className:"mt-0.5 shrink-0",style:{color:"var(--warn)"}}),e.jsx("div",{className:"text-muted",children:a?e.jsxs(e.Fragment,{children:["Other devices can reach the API, but a valid API key is required.",!d&&e.jsxs(e.Fragment,{children:[" ","No API key exists yet — create one on the"," ",e.jsx("span",{className:"font-medium text-ink",children:"Developer"})," screen."]})]}):e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"font-medium text-ink",children:"Open access:"})," any device on your network can use this TurboLLM with no key. Only enable this on a network you trust."]})})]})]}),e.jsxs("div",{className:"mt-2 border-t border-border pt-3 text-[12px] text-faint",children:["Click ",e.jsx("span",{className:"font-medium text-ink",children:"Save settings"})," to apply. The listener re-binds in place (no restart, model stays loaded); a port change reconnects this page automatically."]})]})}function et({tokenSet:t,onSaved:n}){const{query:a,save:o}=ce(),s=ze(),[l,c]=i.useState(""),[r,d]=i.useState(null),h=x=>{c(x),d(null)},p=()=>{l.trim()&&s.mutate(l.trim(),{onSuccess:x=>d(x),onError:()=>d({ok:!1})})},m=()=>{o.mutate({hfToken:l.trim()},{onSuccess:()=>{b.success(l.trim()?"Hugging Face token saved":"Hugging Face token cleared"),c(""),d(null),n()},onError:x=>b.error(x instanceof k?x.message:"Could not save the token.")})};return e.jsxs("section",{className:"rounded-lg border border-border bg-panel p-4",children:[e.jsx("h2",{className:"mb-1 text-[13px] font-semibold uppercase tracking-wide text-faint",children:"Models"}),e.jsxs("p",{className:"mb-3 text-[12px] text-muted",children:["A Hugging Face access token lets you download gated models (e.g. Llama). Accept the model's license on huggingface.co, then paste a read token here."," ",e.jsx("a",{href:"https://huggingface.co/settings/tokens",target:"_blank",rel:"noopener noreferrer",className:"text-ink underline-offset-2 hover:underline",children:"Create a token"}),"."]}),e.jsx("div",{className:"flex items-center justify-between py-1",children:e.jsx("div",{className:"text-[13px] text-muted",children:t?e.jsxs("span",{className:"inline-flex items-center gap-1.5 text-ink",children:[e.jsx(A,{size:13,style:{color:"var(--ok)"}}),"A token is configured"]}):"No token configured"})}),e.jsxs("div",{className:"mt-1 flex flex-col gap-2 sm:flex-row sm:items-center",children:[e.jsx("input",{type:"password",value:l,onChange:x=>h(x.target.value),placeholder:t?"Enter a new token to replace the current one":"hf_…",autoComplete:"off",className:"flex-1 rounded-md border border-border bg-bg px-2 py-1.5 font-mono text-[13px] text-ink outline-none"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(g,{variant:"outline",size:"sm",onClick:p,disabled:!l.trim()||s.isPending,children:s.isPending?e.jsx(C,{size:13,className:"animate-spin"}):"Test"}),e.jsx(g,{size:"sm",onClick:m,disabled:o.isPending||a.isFetching,children:l.trim()?"Save token":"Clear token"})]})]}),r&&e.jsx("div",{className:"mt-2 text-[12px]",children:r.ok?e.jsxs("span",{className:"inline-flex items-center gap-1.5",style:{color:"var(--ok)"},children:[e.jsx(A,{size:13}),"Valid",r.name?` — signed in as ${r.name}`:""]}):e.jsxs("span",{className:"inline-flex items-center gap-1.5",style:{color:"var(--err)"},children:[e.jsx(xe,{size:13}),"Invalid or unauthorized token"]})})]})}function tt({onRestart:t}){return e.jsxs("section",{className:"rounded-lg border border-border bg-panel p-4",children:[e.jsx("h2",{className:"mb-1 text-[13px] font-semibold uppercase tracking-wide text-faint",children:"Advanced"}),e.jsx("p",{className:"mb-3 text-[12px] text-muted",children:"Restart the daemon to apply a new port or LAN binding without killing the terminal. Any loaded model is unloaded by a restart and must be reloaded afterward."}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[14px] font-medium text-ink",children:"Restart daemon"}),e.jsx("div",{className:"text-[12px] text-muted",children:"Stops the engine, then re-launches the daemon process"})]}),e.jsxs(g,{variant:"outline",size:"sm",onClick:t,children:[e.jsx(ue,{size:13}),"Restart daemon"]})]})]})}function st({onDismiss:t}){const n=Ie(),[a,o]=i.useState("restarting"),s=i.useRef(!1);return i.useEffect(()=>{if(s.current)return;s.current=!0;let l=!1,c,r;const d=async()=>{if(!l){try{if((await fetch("/api/v1/status",{headers:{Accept:"application/json"}})).ok){l||window.location.reload();return}}catch{}l||(c=setTimeout(d,700))}};return n.mutate(void 0,{onSuccess:()=>{c=setTimeout(d,700),r=setTimeout(()=>{l||o("failed")},2e4)},onError:h=>{l||(o("failed"),b.error(h instanceof k?h.message:"Could not restart the daemon."))}}),()=>{l=!0,c&&clearTimeout(c),r&&clearTimeout(r)}},[]),e.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-bg/90 backdrop-blur-sm",children:e.jsx("div",{className:"flex max-w-sm flex-col items-center gap-3 rounded-lg border border-border bg-panel p-6 text-center",children:a==="restarting"?e.jsxs(e.Fragment,{children:[e.jsx(C,{size:28,className:"animate-spin",style:{color:"var(--accent)"}}),e.jsx("div",{className:"text-[15px] font-medium text-ink",children:"Restarting daemon…"}),e.jsx("div",{className:"text-[12px] text-muted",children:"Applying your changes. The page will reload automatically when the daemon is back."})]}):e.jsxs(e.Fragment,{children:[e.jsx(pe,{size:28,style:{color:"var(--warn)"}}),e.jsx("div",{className:"text-[15px] font-medium text-ink",children:"Daemon is taking a while"}),e.jsx("div",{className:"text-[12px] text-muted",children:"It may have moved to a new port. Try reloading, or check the terminal where you started TurboLLM."}),e.jsxs("div",{className:"mt-1 flex gap-2",children:[e.jsx(g,{variant:"outline",size:"sm",onClick:t,children:"Dismiss"}),e.jsx(g,{size:"sm",onClick:()=>window.location.reload(),children:"Reload now"})]})]})})})}function at(){const{data:t,isLoading:n}=De();return e.jsxs("section",{className:"rounded-lg border border-border bg-panel p-4",children:[e.jsx("h2",{className:"mb-3 text-[13px] font-semibold uppercase tracking-wide text-faint",children:"Hardware"}),n||!t?e.jsx("p",{className:"text-[13px] text-faint",children:"Detecting hardware…"}):e.jsxs("dl",{className:"grid grid-cols-[auto_1fr] gap-x-6 gap-y-1.5",children:[t.gpus.length>0?t.gpus.map((a,o)=>e.jsx(M,{label:t.gpus.length>1?`GPU ${o+1}`:"GPU",value:`${a.name}${a.vramMb>0?` · ${(a.vramMb/1e3).toFixed(1)} GB VRAM`:""}`},o)):e.jsx(M,{label:"GPU",value:"None detected (CPU-only)"}),e.jsx(M,{label:"CPU",value:`${t.cpu||"Unknown"} · ${t.cores} cores`}),e.jsx(M,{label:"RAM",value:`${(t.ramMB/1e3).toFixed(1)} GB`}),e.jsx(M,{label:"OS",value:t.os})]})]})}function M({label:t,value:n}){return e.jsxs(e.Fragment,{children:[e.jsx("dt",{className:"text-[13px] text-muted",children:t}),e.jsx("dd",{className:"text-[13px] text-ink",children:n})]})}function nt(){const[t,n]=i.useState(()=>ke()),[a,o]=i.useState(()=>we()),[s,l]=i.useState(!1),c=()=>{Se(t),Me(a),l(!0),setTimeout(()=>l(!1),2e3)};return e.jsxs("section",{className:"rounded-lg border border-border bg-panel p-4",children:[e.jsx("h2",{className:"mb-1 text-[13px] font-semibold uppercase tracking-wide text-faint",children:"Personalization"}),e.jsx("p",{className:"mb-3 text-[12px] text-muted",children:"Applied as hidden context in every new conversation. Persona can also be changed per-chat."}),e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[14px] font-medium text-ink",children:"Default persona"}),e.jsx("div",{className:"text-[12px] text-muted",children:"Applied to new chats unless overridden in the chat window"})]}),e.jsx("select",{value:t,onChange:r=>n(r.target.value),className:"rounded-md border border-border bg-bg px-2 py-1.5 text-[13px] text-ink outline-none",children:Ce.map(r=>e.jsxs("option",{value:r.id,children:[r.name," — ",r.description]},r.id))})]}),e.jsxs("div",{className:"flex items-center justify-between gap-4",children:[e.jsxs("div",{className:"shrink-0",children:[e.jsx("div",{className:"text-[14px] font-medium text-ink",children:"Assistant name"}),e.jsx("div",{className:"text-[12px] text-muted",children:"What the assistant calls itself (empty = model default)"})]}),e.jsx("input",{type:"text",value:a.assistantName,onChange:r=>o(d=>({...d,assistantName:r.target.value})),placeholder:"e.g. Aria",className:"w-40 rounded-md border border-border bg-bg px-2 py-1 text-[13px] text-ink outline-none placeholder:text-faint"})]}),e.jsxs("div",{className:"flex items-center justify-between gap-4",children:[e.jsxs("div",{className:"shrink-0",children:[e.jsx("div",{className:"text-[14px] font-medium text-ink",children:"Your name"}),e.jsx("div",{className:"text-[12px] text-muted",children:"How the assistant addresses you (empty = not set)"})]}),e.jsx("input",{type:"text",value:a.userName,onChange:r=>o(d=>({...d,userName:r.target.value})),placeholder:"e.g. Alex",className:"w-40 rounded-md border border-border bg-bg px-2 py-1 text-[13px] text-ink outline-none placeholder:text-faint"})]}),e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[14px] font-medium text-ink",children:"Custom instructions"}),e.jsx("div",{className:"text-[12px] text-muted",children:"Extra instructions added to every new conversation"})]}),e.jsx("textarea",{rows:3,value:a.customInstructions,onChange:r=>o(d=>({...d,customInstructions:r.target.value})),placeholder:"e.g. Always respond in Spanish. Prefer functional programming style.",className:"w-full resize-none rounded-md border border-border bg-bg px-2 py-1.5 text-[13px] text-ink outline-none placeholder:text-faint"})]}),e.jsx("div",{className:"flex justify-end",children:e.jsx(g,{onClick:c,size:"sm",children:s?e.jsxs(e.Fragment,{children:[e.jsx(A,{size:13})," Saved"]}):e.jsxs(e.Fragment,{children:[e.jsx(me,{size:13})," Save personalization"]})})})]})]})}const le="npm i -g turbollm";function rt(){const{data:t}=z(),{data:n}=Re(),a=n?.installed||t?.version||"",o=!!n?.hasUpdate&&!!n?.latest;return e.jsxs("section",{className:"rounded-lg border border-border bg-panel p-4",children:[e.jsx("h2",{className:"mb-3 text-[13px] font-semibold uppercase tracking-wide text-faint",children:"About"}),e.jsxs("div",{className:"flex items-center justify-between py-1",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[14px] font-medium text-ink",children:"Version"}),e.jsx("div",{className:"text-[12px] text-muted",children:"The TurboLLM version this daemon is running"})]}),e.jsx("span",{className:"font-mono text-[13px] text-ink",children:a?`v${a}`:"—"})]}),o?e.jsxs("div",{className:"mt-2 flex flex-col gap-2 rounded-md border p-3",style:{borderColor:"color-mix(in srgb, var(--accent) 40%, var(--border))",background:"color-mix(in srgb, var(--accent) 6%, transparent)"},children:[e.jsxs("div",{className:"flex items-center gap-2 text-[13px] font-medium",style:{color:"var(--accent)"},children:[e.jsx(Oe,{size:15}),"TurboLLM v",n.latest," is available"]}),e.jsx("div",{className:"text-[12px] text-muted",children:"Update from your terminal:"}),e.jsxs("div",{className:"flex items-center justify-between gap-2 rounded-md border border-border bg-bg px-2.5 py-1.5",children:[e.jsx("code",{className:"select-all font-mono text-[12px] text-ink",children:le}),e.jsx(_e,{text:le})]})]}):n?.latest&&!n.hasUpdate?e.jsxs("div",{className:"mt-1 inline-flex items-center gap-1.5 text-[12px] text-faint",children:[e.jsx(A,{size:13,style:{color:"var(--ok)"}}),"You're on the latest version"]}):null]})}function it(){return e.jsxs("section",{className:"rounded-lg border border-border bg-panel p-4",children:[e.jsx("h2",{className:"mb-3 text-[13px] font-semibold uppercase tracking-wide text-faint",children:"Help"}),e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("a",{href:"https://github.com/bramha-dev/turbollm/issues/new",target:"_blank",rel:"noopener noreferrer",className:"flex items-center gap-2 text-[13px] text-muted hover:text-ink transition-colors",children:[e.jsx(ie,{size:13}),"Report a bug"]}),e.jsxs("a",{href:"https://github.com/bramha-dev/turbollm/discussions",target:"_blank",rel:"noopener noreferrer",className:"flex items-center gap-2 text-[13px] text-muted hover:text-ink transition-colors",children:[e.jsx(ie,{size:13}),"Send feedback"]})]})]})}export{gt as SettingsScreen};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{c}from"./index-sjgdofsd.js";const e=[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]],t=c("check",e);export{t as C};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c}from"./index-
|
|
1
|
+
import{c}from"./index-sjgdofsd.js";const e=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m15 9-6 6",key:"1uzhvr"}],["path",{d:"m9 9 6 6",key:"z0biqf"}]],o=c("circle-x",e);export{o as C};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as e}from"./radix-
|
|
1
|
+
import{j as e}from"./radix-BFvMxQq9.js";import{c as a,B as n,w as l}from"./index-sjgdofsd.js";const i=[["path",{d:"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3",key:"wmoenq"}],["path",{d:"M12 9v4",key:"juzpu7"}],["path",{d:"M12 17h.01",key:"p32p05"}]],c=a("triangle-alert",i);function o({message:r,onRetry:t,className:s}){return e.jsxs("div",{className:l("flex items-start gap-3 rounded-md border p-3 text-[13px]",s),style:{borderColor:"var(--err)",background:"color-mix(in srgb, var(--err) 10%, transparent)",color:"var(--ink)"},role:"alert",children:[e.jsx(c,{size:16,style:{color:"var(--err)"},className:"mt-0.5 shrink-0"}),e.jsx("div",{className:"flex-1",children:r}),t&&e.jsx(n,{size:"sm",variant:"outline",onClick:t,children:"Retry"})]})}function d({icon:r,message:t,action:s}){return e.jsxs("div",{className:"flex flex-col items-center gap-3 py-12 text-center",children:[e.jsx("div",{className:"text-muted",children:r}),e.jsx("p",{className:"max-w-sm text-[13px] text-muted",children:t}),s]})}function p({title:r,description:t,actions:s}){return e.jsxs("div",{className:"mb-6 flex items-start justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-[18px] font-semibold tracking-[-0.01em] text-ink",children:r}),t&&e.jsx("p",{className:"mt-1 text-[13px] text-muted",children:t})]}),s]})}export{d as E,o as I,p as S,c as T};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as o}from"./radix-
|
|
1
|
+
import{j as o}from"./radix-BFvMxQq9.js";import{r as a}from"./vendor-D_-14Whs.js";import{C as d}from"./check-DFwkcl_5.js";import{c as x}from"./index-sjgdofsd.js";const l=[["rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2",key:"17jyea"}],["path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",key:"zix9uf"}]],u=x("copy",l);function C({text:r,label:e,size:i=13,className:s}){const[t,n]=a.useState(!1),c=()=>{navigator.clipboard.writeText(r).then(()=>{n(!0),setTimeout(()=>n(!1),1500)})},p=e!=null?"px-2 py-1 text-[12px]":"p-1";return o.jsxs("button",{type:"button",onClick:c,title:t?"Copied!":"Copy",className:`inline-flex items-center gap-1.5 rounded transition-colors ${t?"":"text-faint hover:text-ink"} ${p} ${s??""}`,style:t?{color:"var(--ok)"}:void 0,children:[t?o.jsx(d,{size:i}):o.jsx(u,{size:i}),e!=null&&o.jsx("span",{children:t?"Copied!":e})]})}export{C,u as a};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c as l,w as t,
|
|
1
|
+
import{c as l,w as t,_ as i,X as d}from"./index-sjgdofsd.js";import{m,n as x,j as s,o as p,p as f,q as g,I as u,r as D,s as y,t as w,u as N,v as b,w as h,A as j,O as v,b as C,x as A,e as c,c as k,d as R,f as T,D as _,y as $}from"./radix-BFvMxQq9.js";import{r}from"./vendor-D_-14Whs.js";const z=[["path",{d:"m6 9 6 6 6-6",key:"qrunsl"}]],W=l("chevron-down",z);const M=[["path",{d:"m9 18 6-6-6-6",key:"mthhwq"}]],Y=l("chevron-right",M);const I=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]],Z=l("circle-check",I);const O=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["line",{x1:"9",x2:"15",y1:"15",y2:"9",key:"1dfufj"}]],ee=l("circle-slash",O),ae=m,se=x,oe=({className:e,...a})=>s.jsx(g,{className:t("my-1 h-px bg-border",e),...a}),q=r.forwardRef(({className:e,sideOffset:a=6,...o},n)=>s.jsx(p,{children:s.jsx(f,{ref:n,sideOffset:a,className:t("z-50 min-w-[12rem] rounded-md border border-border bg-panel p-1","shadow-[var(--shadow-2)]",e),...o})}));q.displayName="DropdownMenuContent";const P=r.forwardRef(({className:e,destructive:a,...o},n)=>s.jsx(u,{ref:n,className:t("flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none","focus:bg-panel-2 data-[disabled]:pointer-events-none data-[disabled]:opacity-50",a?"text-[color:var(--err)]":"text-ink",e),...o}));P.displayName="DropdownMenuItem";const te=D;function S({className:e,...a}){return s.jsx(v,{className:t("fixed inset-0 z-50 bg-black/40",e),...a})}const E=r.forwardRef(({className:e,...a},o)=>s.jsxs(y,{children:[s.jsx(S,{}),s.jsx(w,{ref:o,className:t("fixed left-1/2 top-1/2 z-50 w-full max-w-md -translate-x-1/2 -translate-y-1/2","rounded-[var(--radius-lg)] border border-border bg-panel p-5 shadow-[var(--shadow-2)]","focus:outline-none",e),...a})]}));E.displayName="AlertDialogContent";function re({className:e,...a}){return s.jsx("div",{className:t("mb-4 flex flex-col gap-1",e),...a})}function ne({className:e,...a}){return s.jsx("div",{className:t("mt-5 flex justify-end gap-2",e),...a})}const F=r.forwardRef(({className:e,...a},o)=>s.jsx(N,{ref:o,className:t("text-[16px] font-semibold tracking-[-0.01em] text-ink",e),...a}));F.displayName="AlertDialogTitle";const H=r.forwardRef(({className:e,...a},o)=>s.jsx(b,{ref:o,className:t("text-[13px] text-muted",e),...a}));H.displayName="AlertDialogDescription";const L=r.forwardRef(({className:e,...a},o)=>s.jsx(j,{ref:o,className:t(i({variant:"destructive"}),e),...a}));L.displayName="AlertDialogAction";const V=r.forwardRef(({className:e,...a},o)=>s.jsx(h,{ref:o,className:t(i({variant:"outline"}),e),...a}));V.displayName="AlertDialogCancel";const le=C,ie=A,ce=c;function X({className:e,...a}){return s.jsx($,{className:t("fixed inset-0 z-50 bg-black/40",e),...a})}const B=r.forwardRef(({className:e,children:a,...o},n)=>s.jsxs(k,{children:[s.jsx(X,{}),s.jsxs(R,{ref:n,className:t("fixed left-1/2 top-1/2 z-50 w-full max-w-md -translate-x-1/2 -translate-y-1/2","rounded-[var(--radius-lg)] border border-border bg-panel p-5 shadow-[var(--shadow-2)]","focus:outline-none",e),...o,children:[a,s.jsx(c,{className:"absolute right-4 top-4 rounded-sm text-muted hover:text-ink","aria-label":"Close",children:s.jsx(d,{size:16})})]})]}));B.displayName="DialogContent";function de({className:e,...a}){return s.jsx("div",{className:t("mb-4 flex flex-col gap-1",e),...a})}function me({className:e,...a}){return s.jsx("div",{className:t("mt-5 flex justify-end gap-2",e),...a})}const G=r.forwardRef(({className:e,...a},o)=>s.jsx(T,{ref:o,className:t("text-[16px] font-semibold tracking-[-0.01em] text-ink",e),...a}));G.displayName="DialogTitle";const J=r.forwardRef(({className:e,...a},o)=>s.jsx(_,{ref:o,className:t("text-[13px] text-muted",e),...a}));J.displayName="DialogDescription";export{te as A,W as C,ae as D,Y as a,Z as b,se as c,q as d,oe as e,P as f,ee as g,le as h,ie as i,B as j,ce as k,de as l,G as m,J as n,me as o,E as p,re as q,F as r,H as s,ne as t,V as u,L as v};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;--color-black:#000;--spacing:.25rem;--container-xs:20rem;--container-sm:24rem;--container-md:28rem;--container-lg:32rem;--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-wide:.025em;--leading-relaxed:1.625;--radius-sm:var(--radius-sm);--radius-md:var(--radius);--radius-lg:var(--radius-lg);--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--blur-sm:8px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;--default-mono-font-family:ui-monospace, "Cascadia Code", Consolas, monospace}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*{border-color:var(--border)}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.inset-0{inset:calc(var(--spacing) * 0)}.-top-1\.5{top:calc(var(--spacing) * -1.5)}.top-1\/2{top:50%}.top-2{top:calc(var(--spacing) * 2)}.top-4{top:calc(var(--spacing) * 4)}.top-9{top:calc(var(--spacing) * 9)}.-right-1\.5{right:calc(var(--spacing) * -1.5)}.right-0{right:calc(var(--spacing) * 0)}.right-1\.5{right:calc(var(--spacing) * 1.5)}.right-2{right:calc(var(--spacing) * 2)}.right-4{right:calc(var(--spacing) * 4)}.bottom-28{bottom:calc(var(--spacing) * 28)}.left-1\/2{left:50%}.left-2\.5{left:calc(var(--spacing) * 2.5)}.left-3{left:calc(var(--spacing) * 3)}.z-50{z-index:50}.z-\[100\]{z-index:100}.mx-4{margin-inline:calc(var(--spacing) * 4)}.my-1{margin-block:calc(var(--spacing) * 1)}.my-2{margin-block:calc(var(--spacing) * 2)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-2\.5{margin-top:calc(var(--spacing) * 2.5)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-5{margin-top:calc(var(--spacing) * 5)}.mr-0\.5{margin-right:calc(var(--spacing) * .5)}.mr-1\.5{margin-right:calc(var(--spacing) * 1.5)}.-mb-px{margin-bottom:-1px}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-2\.5{margin-bottom:calc(var(--spacing) * 2.5)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-5{margin-bottom:calc(var(--spacing) * 5)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.ml-0\.5{margin-left:calc(var(--spacing) * .5)}.ml-1{margin-left:calc(var(--spacing) * 1)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-3{margin-left:calc(var(--spacing) * 3)}.ml-auto{margin-left:auto}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.h-1{height:calc(var(--spacing) * 1)}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-2{height:calc(var(--spacing) * 2)}.h-2\.5{height:calc(var(--spacing) * 2.5)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-12{height:calc(var(--spacing) * 12)}.h-16{height:calc(var(--spacing) * 16)}.h-48{height:calc(var(--spacing) * 48)}.h-\[3px\]{height:3px}.h-\[58px\]{height:58px}.h-full{height:100%}.h-px{height:1px}.max-h-40{max-height:calc(var(--spacing) * 40)}.max-h-48{max-height:calc(var(--spacing) * 48)}.max-h-64{max-height:calc(var(--spacing) * 64)}.max-h-80{max-height:calc(var(--spacing) * 80)}.max-h-\[60vh\]{max-height:60vh}.max-h-\[88vh\]{max-height:88vh}.max-h-\[320px\]{max-height:320px}.min-h-0{min-height:calc(var(--spacing) * 0)}.min-h-9{min-height:calc(var(--spacing) * 9)}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-2{width:calc(var(--spacing) * 2)}.w-2\.5{width:calc(var(--spacing) * 2.5)}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-7{width:calc(var(--spacing) * 7)}.w-8{width:calc(var(--spacing) * 8)}.w-9{width:calc(var(--spacing) * 9)}.w-10{width:calc(var(--spacing) * 10)}.w-12{width:calc(var(--spacing) * 12)}.w-16{width:calc(var(--spacing) * 16)}.w-20{width:calc(var(--spacing) * 20)}.w-24{width:calc(var(--spacing) * 24)}.w-40{width:calc(var(--spacing) * 40)}.w-56{width:calc(var(--spacing) * 56)}.w-\[72px\]{width:72px}.w-\[260px\]{width:260px}.w-\[280px\]{width:280px}.w-fit{width:fit-content}.w-full{width:100%}.w-px{width:1px}.max-w-\[75\%\]{max-width:75%}.max-w-\[220px\]{max-width:220px}.max-w-\[260px\]{max-width:260px}.max-w-full{max-width:100%}.max-w-lg{max-width:var(--container-lg)}.max-w-md{max-width:var(--container-md)}.max-w-sm{max-width:var(--container-sm)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:calc(var(--spacing) * 0)}.min-w-4{min-width:calc(var(--spacing) * 4)}.min-w-\[12rem\]{min-width:12rem}.min-w-\[160px\]{min-width:160px}.min-w-\[180px\]{min-width:180px}.min-w-\[220px\]{min-width:220px}.flex-1{flex:1}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.border-collapse{border-collapse:collapse}.-translate-x-1\/2{--tw-translate-x: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}.rotate-90{rotate:90deg}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.resize-none{resize:none}.list-none{list-style-type:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-\[auto_1fr\]{grid-template-columns:auto 1fr}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.place-items-center{place-items:center}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-3\.5{gap:calc(var(--spacing) * 3.5)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-6{gap:calc(var(--spacing) * 6)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}.gap-x-3{column-gap:calc(var(--spacing) * 3)}.gap-x-6{column-gap:calc(var(--spacing) * 6)}.gap-y-1\.5{row-gap:calc(var(--spacing) * 1.5)}.gap-y-2{row-gap:calc(var(--spacing) * 2)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-border>:not(:last-child)){border-color:var(--border)}.self-start{align-self:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.overscroll-x-contain{overscroll-behavior-x:contain}.rounded{border-radius:.25rem}.rounded-\[var\(--radius\)\]{border-radius:var(--radius)}.rounded-\[var\(--radius-lg\)\]{border-radius:var(--radius-lg)}.rounded-\[var\(--radius-md\)\]{border-radius:var(--radius-md)}.rounded-\[var\(--radius-sm\)\]{border-radius:var(--radius-sm)}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-b-\[var\(--radius\)\]{border-bottom-right-radius:var(--radius);border-bottom-left-radius:var(--radius)}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-\[color\:var\(--accent\)\]{border-color:var(--accent)}.border-\[color\:var\(--err\)\]{border-color:var(--err)}.border-\[color\:var\(--warn\,\#ca8a04\)\]{border-color:var(--warn,#ca8a04)}.border-accent{border-color:var(--accent)}.border-border{border-color:var(--border)}.border-border-strong{border-color:var(--border-strong)}.border-transparent{border-color:#0000}.bg-\[color-mix\(in_srgb\,var\(--err\)_8\%\,transparent\)\]{background-color:var(--err)}@supports (color:color-mix(in lab,red,red)){.bg-\[color-mix\(in_srgb\,var\(--err\)_8\%\,transparent\)\]{background-color:color-mix(in srgb,var(--err) 8%,transparent)}}.bg-\[color-mix\(in_srgb\,var\(--warn\,\#ca8a04\)_8\%\,transparent\)\]{background-color:var(--warn,#ca8a04)}@supports (color:color-mix(in lab,red,red)){.bg-\[color-mix\(in_srgb\,var\(--warn\,\#ca8a04\)_8\%\,transparent\)\]{background-color:color-mix(in srgb,var(--warn,#ca8a04) 8%,transparent)}}.bg-\[color\:color-mix\(in_srgb\,var\(--accent\)_14\%\,transparent\)\]{background-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.bg-\[color\:color-mix\(in_srgb\,var\(--accent\)_14\%\,transparent\)\]{background-color:color-mix(in srgb,var(--accent) 14%,transparent)}}.bg-accent,.bg-accent\/12{background-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.bg-accent\/12{background-color:color-mix(in oklab,var(--accent) 12%,transparent)}}.bg-bg,.bg-bg\/90{background-color:var(--bg)}@supports (color:color-mix(in lab,red,red)){.bg-bg\/90{background-color:color-mix(in oklab,var(--bg) 90%,transparent)}}.bg-black\/40{background-color:#0006}@supports (color:color-mix(in lab,red,red)){.bg-black\/40{background-color:color-mix(in oklab,var(--color-black) 40%,transparent)}}.bg-border{background-color:var(--border)}.bg-panel{background-color:var(--panel)}.bg-panel-2{background-color:var(--panel-2)}.bg-transparent{background-color:#0000}.object-contain{object-fit:contain}.object-cover{object-fit:cover}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-1{padding:calc(var(--spacing) * 1)}.p-2{padding:calc(var(--spacing) * 2)}.p-2\.5{padding:calc(var(--spacing) * 2.5)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.px-0{padding-inline:calc(var(--spacing) * 0)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.px-8{padding-inline:calc(var(--spacing) * 8)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-10{padding-block:calc(var(--spacing) * 10)}.py-12{padding-block:calc(var(--spacing) * 12)}.py-16{padding-block:calc(var(--spacing) * 16)}.py-\[3px\]{padding-block:3px}.pt-0\.5{padding-top:calc(var(--spacing) * .5)}.pt-1{padding-top:calc(var(--spacing) * 1)}.pt-1\.5{padding-top:calc(var(--spacing) * 1.5)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-2\.5{padding-top:calc(var(--spacing) * 2.5)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pr-6{padding-right:calc(var(--spacing) * 6)}.pr-10{padding-right:calc(var(--spacing) * 10)}.pb-1{padding-bottom:calc(var(--spacing) * 1)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pb-5{padding-bottom:calc(var(--spacing) * 5)}.pl-1{padding-left:calc(var(--spacing) * 1)}.pl-7{padding-left:calc(var(--spacing) * 7)}.pl-9{padding-left:calc(var(--spacing) * 9)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.align-super{vertical-align:super}.font-mono{font-family:ui-monospace,Cascadia Code,Consolas,monospace}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-\[0\.88em\]{font-size:.88em}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-\[13px\]{font-size:13px}.text-\[14px\]{font-size:14px}.text-\[15px\]{font-size:15px}.text-\[16px\]{font-size:16px}.text-\[18px\]{font-size:18px}.leading-\[1\.5\]{--tw-leading:1.5;line-height:1.5}.leading-\[1\.6\]{--tw-leading:1.6;line-height:1.6}.leading-\[1\.7\]{--tw-leading:1.7;line-height:1.7}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-\[-0\.01em\]{--tw-tracking:-.01em;letter-spacing:-.01em}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.whitespace-pre{white-space:pre}.whitespace-pre-wrap{white-space:pre-wrap}.text-\[color\:var\(--err\)\]{color:var(--err)}.text-accent{color:var(--accent)}.text-faint{color:var(--faint)}.text-ink{color:var(--ink)}.text-muted{color:var(--muted)}.text-on-accent{color:var(--on-accent)}.capitalize{text-transform:capitalize}.uppercase{text-transform:uppercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.underline{text-decoration-line:underline}.underline-offset-2{text-underline-offset:2px}.accent-\[var\(--accent\)\]{accent-color:var(--accent)}.opacity-0{opacity:0}.opacity-100{opacity:1}.shadow-\[var\(--shadow-1\)\]{--tw-shadow:var(--shadow-1);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[var\(--shadow-2\)\]{--tw-shadow:var(--shadow-2);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[width\]{transition-property:width;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.outline-none{--tw-outline-style:none;outline-style:none}.select-all{-webkit-user-select:all;user-select:all}.select-none{-webkit-user-select:none;user-select:none}@media(hover:hover){.group-hover\:opacity-100:is(:where(.group):hover *),.group-hover\/dir\:opacity-100:is(:where(.group\/dir):hover *){opacity:1}}.placeholder\:overflow-hidden::placeholder{overflow:hidden}.placeholder\:whitespace-nowrap::placeholder{white-space:nowrap}.placeholder\:text-faint::placeholder{color:var(--faint)}.first\:mt-0:first-child{margin-top:calc(var(--spacing) * 0)}.first\:pt-0:first-child{padding-top:calc(var(--spacing) * 0)}.focus-within\:border-\[color\:var\(--accent\)\]:focus-within{border-color:var(--accent)}@media(hover:hover){.hover\:border-\[color\:var\(--accent\)\]:hover,.hover\:border-accent:hover{border-color:var(--accent)}.hover\:border-border-strong:hover{border-color:var(--border-strong)}.hover\:bg-\[color\:color-mix\(in_srgb\,var\(--err\)_12\%\,transparent\)\]:hover{background-color:var(--err)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-\[color\:color-mix\(in_srgb\,var\(--err\)_12\%\,transparent\)\]:hover{background-color:color-mix(in srgb,var(--err) 12%,transparent)}}.hover\:bg-accent-hover:hover{background-color:var(--accent-hover)}.hover\:bg-bg:hover{background-color:var(--bg)}.hover\:bg-panel:hover{background-color:var(--panel)}.hover\:bg-panel-2:hover{background-color:var(--panel-2)}.hover\:text-\[var\(--err\)\]:hover{color:var(--err)}.hover\:text-accent:hover{color:var(--accent)}.hover\:text-err:hover{color:var(--err)}.hover\:text-ink:hover{color:var(--ink)}.hover\:text-muted:hover{color:var(--muted)}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-80:hover{opacity:.8}}.focus\:border-\[color\:var\(--accent\)\]:focus,.focus\:border-accent:focus{border-color:var(--accent)}.focus\:bg-panel-2:focus{background-color:var(--panel-2)}.focus\:opacity-100:focus{opacity:1}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:border-border-strong:focus-visible{border-color:var(--border-strong)}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}.disabled\:opacity-60:disabled{opacity:.6}.data-\[disabled\]\:pointer-events-none[data-disabled]{pointer-events:none}.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}.data-\[state\=checked\]\:translate-x-\[18px\][data-state=checked]{--tw-translate-x:18px;translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[state\=checked\]\:bg-accent[data-state=checked]{background-color:var(--accent)}.data-\[state\=open\]\:opacity-100[data-state=open]{opacity:1}.data-\[state\=unchecked\]\:translate-x-0\.5[data-state=unchecked]{--tw-translate-x:calc(var(--spacing) * .5);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[state\=unchecked\]\:bg-border-strong[data-state=unchecked]{background-color:var(--border-strong)}@media(min-width:40rem){.sm\:ml-0{margin-left:calc(var(--spacing) * 0)}.sm\:block{display:block}.sm\:max-w-\[480px\]{max-width:480px}.sm\:max-w-\[560px\]{max-width:560px}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:flex-nowrap{flex-wrap:nowrap}.sm\:items-center{align-items:center}.sm\:gap-3{gap:calc(var(--spacing) * 3)}.sm\:truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.sm\:opacity-0{opacity:0}@media(hover:hover){.sm\:group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}}}@media(min-width:48rem){.md\:flex{display:flex}.md\:hidden{display:none}.md\:items-end{align-items:flex-end}.md\:justify-end{justify-content:flex-end}}@media(min-width:80rem){.xl\:grid{display:grid}.xl\:hidden{display:none}.xl\:inline{display:inline}.xl\:inline-flex{display:inline-flex}.xl\:w-48{width:calc(var(--spacing) * 48)}.xl\:w-full{width:100%}.xl\:items-start{align-items:flex-start}.xl\:items-stretch{align-items:stretch}.xl\:justify-start{justify-content:flex-start}.xl\:gap-3{gap:calc(var(--spacing) * 3)}.xl\:px-3{padding-inline:calc(var(--spacing) * 3)}.xl\:pl-1{padding-left:calc(var(--spacing) * 1)}.xl\:pl-3{padding-left:calc(var(--spacing) * 3)}}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}}:root{--bg:#faf9f7;--panel:#fff;--panel-2:#f4f2ee;--ink:#1a1a18;--muted:#6b6a66;--faint:#9c9a94;--border:#e7e4de;--border-strong:#d6d2c8;--accent:#c96442;--accent-hover:#b85837;--on-accent:#fff;--ok:#3a9d6b;--warn:#c9913f;--err:#c4453c;--info:#5a7d9a;--radius:12px;--radius-lg:16px;--radius-sm:8px;--shadow-1:0 1px 2px #0000000d;--shadow-2:0 4px 16px #00000012;--log-bg:#0b0b0c;--log-ink:#d6d3cd;--log-faint:#7a7872;--log-err-ink:#e0b3ad}.dark{--bg:#0e0e10;--panel:#17171a;--panel-2:#1d1d21;--ink:#ededec;--muted:#9a9a96;--faint:#6e6e6a;--border:#2a2a2e;--border-strong:#3a3a40;--accent:#e08a5f;--accent-hover:#e89a73;--on-accent:#1a1a18;--ok:#4cc38a;--warn:#d8a45a;--err:#e06c5f;--info:#7da3c4}html,body,#root{height:100%;overflow:hidden}body{background:var(--bg);color:var(--ink);font-family:var(--font-sans);-webkit-font-smoothing:antialiased;margin:0;font-size:14px;line-height:1.5}:focus-visible{outline:2px solid var(--accent)}@supports (color:color-mix(in lab,red,red)){:focus-visible{outline:2px solid color-mix(in srgb,var(--accent) 40%,transparent)}}:focus-visible{outline-offset:1px}@keyframes tllm-pulse{0%,to{opacity:1}50%{opacity:.4}}.tllm-pulse{animation:1.2s ease-in-out infinite tllm-pulse}:root{--tllm-config-w:min(560px, 45vw)}@keyframes tllm-sheet-in-right{0%{transform:translate(100%)}to{transform:translate(0)}}@keyframes tllm-sheet-out-right{0%{transform:translate(0)}to{transform:translate(100%)}}.tllm-sheet{width:100%;max-width:none;inset:0}.tllm-sheet[data-state=open]{animation:.28s cubic-bezier(.32,.72,0,1) tllm-sheet-in-right}.tllm-sheet[data-state=closed]{animation:.24s ease-in tllm-sheet-out-right}.app-shell{transition:padding-right .28s cubic-bezier(.32,.72,0,1)}@media(min-width:768px){.tllm-sheet{width:var(--tllm-config-w);max-width:var(--tllm-config-w);border-left-width:1px;inset:0 0 0 auto}html.tllm-config-open .app-shell{padding-right:var(--tllm-config-w)}}.tllm-config-resizer{display:none}@media(min-width:768px){.tllm-config-resizer{top:0;bottom:0;right:var(--tllm-config-w);z-index:51;cursor:col-resize;touch-action:none;width:10px;margin-right:-5px;display:block;position:fixed}.tllm-config-resizer:after{content:"";background:0 0;transition:background-color .15s;position:absolute;inset:0 4px}.tllm-config-resizer:hover:after,html.tllm-config-resizing .tllm-config-resizer:after{background:var(--accent)}}html.tllm-config-resizing{cursor:col-resize;-webkit-user-select:none;user-select:none}html.tllm-config-resizing .app-shell{transition:none}html.tllm-config-resizing .tllm-sheet{animation:none}.slim-scroll::-webkit-scrollbar{width:5px}.slim-scroll::-webkit-scrollbar-track{background:0 0}.slim-scroll::-webkit-scrollbar-thumb{background-color:var(--border-strong);border-radius:9999px}.slim-scroll::-webkit-scrollbar-thumb:hover{background-color:var(--muted)}.slim-scroll{scrollbar-width:thin;scrollbar-color:var(--border-strong) transparent}[data-sonner-toaster]{--normal-bg:var(--panel);--normal-text:var(--ink);--normal-border:var(--border)}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}
|