This repository has been archived on 2026-07-22. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
mission-control/static/dist/main.js
T
Hitonabi e2fc1d24cf feat(phase-c): Vite + Svelte 5 Infrastruktur + erste 2 Panels migriert
- frontend/ eingerichtet: Vite 6, Svelte 5 (Runes), TypeScript
- Stores: status/jobs/system mit $state-Runes (status.svelte.ts etc.)
- main.ts ersetzt main.js: bundelt Legacy-Panels (overview/models/server/
  jobs/cookbook/connect) + mountet neue Svelte-Panels (guides/news)
- GuidesPanel.svelte: statischer Guide mit Akkordeon-Tutorials + Konzept-Grid
- NewsPanel.svelte: reaktives Newsboard mit API-Fetch + Upgrade-Vorschlaegen
- Vite-Output: static/dist/main.js (committet, kein Build auf dem Server)
- index.html: laedt jetzt static/dist/main.js statt static/js/main.js
- Build: 118 Module → 134 kB (gzip: 44 kB)

Naechste Schritte: Overview → Jobs → Server → Models → Cookbook migrieren.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 21:50:12 +02:00

558 lines
131 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
var ir=Object.defineProperty;var ns=e=>{throw TypeError(e)};var sr=(e,t,n)=>t in e?ir(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var se=(e,t,n)=>sr(e,typeof t!="symbol"?t+"":t,n),oi=(e,t,n)=>t.has(e)||ns("Cannot "+n);var d=(e,t,n)=>(oi(e,t,"read from private field"),n?n.call(e):t.get(e)),_=(e,t,n)=>t.has(e)?ns("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(e):t.set(e,n),y=(e,t,n,i)=>(oi(e,t,"write to private field"),i?i.call(e,n):t.set(e,n),n),T=(e,t,n)=>(oi(e,t,"access private method"),n);var Is=Array.isArray,ar=Array.prototype.indexOf,Nn=Array.prototype.includes,Xn=Array.from,rr=Object.defineProperty,rn=Object.getOwnPropertyDescriptor,lr=Object.getOwnPropertyDescriptors,or=Object.prototype,dr=Array.prototype,Gs=Object.getPrototypeOf,is=Object.isExtensible;const cr=()=>{};function ur(e){for(var t=0;t<e.length;t++)e[t]()}function Ks(){var e,t,n=new Promise((i,s)=>{e=i,t=s});return{promise:n,resolve:e,reject:t}}function ss(e,t){if(Array.isArray(e))return e;if(!(Symbol.iterator in e))return Array.from(e);const n=[];for(const i of e)if(n.push(i),n.length===t)break;return n}const U=2,fn=4,ei=8,qs=1<<24,ke=16,$e=32,et=64,ki=128,ve=512,I=1024,q=2048,De=4096,Q=8192,me=16384,Ut=32768,as=1<<25,It=65536,In=1<<17,fr=1<<18,jt=1<<19,pr=1<<20,Ie=1<<25,yt=65536,Gn=1<<21,At=1<<22,Ze=1<<23,di=Symbol("$state"),Dn=Symbol("attributes"),Mi=Symbol("class"),hr=Symbol("style"),Yt=Symbol("text"),ti=new class extends Error{constructor(){super(...arguments);se(this,"name","StaleReactionError");se(this,"message","The reaction that called `getAbortSignal()` was re-run or destroyed")}};function vr(e){throw new Error("https://svelte.dev/e/lifecycle_outside_component")}function mr(){throw new Error("https://svelte.dev/e/async_derived_orphan")}function gr(e,t,n){throw new Error("https://svelte.dev/e/each_key_duplicate")}function br(e){throw new Error("https://svelte.dev/e/effect_in_teardown")}function wr(){throw new Error("https://svelte.dev/e/effect_in_unowned_derived")}function yr(e){throw new Error("https://svelte.dev/e/effect_orphan")}function xr(){throw new Error("https://svelte.dev/e/effect_update_depth_exceeded")}function _r(){throw new Error("https://svelte.dev/e/state_descriptors_fixed")}function kr(){throw new Error("https://svelte.dev/e/state_prototype_fixed")}function Mr(){throw new Error("https://svelte.dev/e/state_unsafe_mutation")}function Sr(){throw new Error("https://svelte.dev/e/svelte_boundary_reset_onerror")}const $r=1,Er=2,Tr=16,Cr=1,Lr=2,N=Symbol("uninitialized"),Us="http://www.w3.org/1999/xhtml",Ar="http://www.w3.org/2000/svg",zr="http://www.w3.org/1998/Math/MathML";function Dr(){console.warn("https://svelte.dev/e/derived_inert")}function Pr(){console.warn("https://svelte.dev/e/svelte_boundary_reset_noop")}function js(e){return e===this.v}function Or(e,t){return e!=e?t==t:e!==t||e!==null&&typeof e=="object"||typeof e=="function"}function Vs(e){return!Or(e,this.v)}let Y=null;function Gt(e){Y=e}function Ws(e,t=!1,n){Y={p:Y,i:!1,c:null,e:null,s:e,x:null,r:E,l:null}}function Js(e){var t=Y,n=t.e;if(n!==null){t.e=null;for(var i of n)ga(i)}return t.i=!0,Y=t.p,{}}function Qs(){return!0}let Et=[];function Br(){var e=Et;Et=[],ur(e)}function zt(e){if(Et.length===0){var t=Et;queueMicrotask(()=>{t===Et&&Br()})}Et.push(e)}function Ys(e){var t=E;if(t===null)return S.f|=Ze,e;if((t.f&Ut)===0&&(t.f&fn)===0)throw e;Je(e,t)}function Je(e,t){if(!(t!==null&&(t.f&me)!==0)){for(;t!==null;){if((t.f&ki)!==0){if((t.f&Ut)===0)throw e;try{t.b.error(e);return}catch(n){e=n}}t=t.parent}throw e}}const Hr=-7169;function F(e,t){e.f=e.f&Hr|t}function Hi(e){(e.f&ve)!==0||e.deps===null?F(e,I):F(e,De)}function Zs(e){if(e!==null)for(const t of e)(t.f&U)===0||(t.f&yt)===0||(t.f^=yt,Zs(t.deps))}function Xs(e,t,n){(e.f&q)!==0?t.add(e):(e.f&De)!==0&&n.add(e),Zs(e.deps),F(e,I)}function Rr(e){let t=0,n=_t(0),i;return()=>{Gi()&&(M(n),cl(()=>(t===0&&(i=La(()=>e(()=>on(n)))),t+=1,()=>{zt(()=>{t-=1,t===0&&(i==null||i(),i=void 0,on(n))})})))}}var Fr=It|jt;function Nr(e,t,n,i){new Ir(e,t,n,i)}var ue,Bi,fe,ut,Z,pe,W,re,He,ft,Ve,Pt,vn,mn,Re,Qn,H,Gr,Kr,qr,Si,Pn,On,$i,Ei;class Ir{constructor(t,n,i,s){_(this,H);se(this,"parent");se(this,"is_pending",!1);se(this,"transform_error");_(this,ue);_(this,Bi,null);_(this,fe);_(this,ut);_(this,Z);_(this,pe,null);_(this,W,null);_(this,re,null);_(this,He,null);_(this,ft,0);_(this,Ve,0);_(this,Pt,!1);_(this,vn,new Set);_(this,mn,new Set);_(this,Re,null);_(this,Qn,Rr(()=>(y(this,Re,_t(d(this,ft))),()=>{y(this,Re,null)})));var a;y(this,ue,t),y(this,fe,n),y(this,ut,r=>{var o=E;o.b=this,o.f|=ki,i(r)}),this.parent=E.b,this.transform_error=s??((a=this.parent)==null?void 0:a.transform_error)??(r=>r),y(this,Z,Ki(()=>{T(this,H,Si).call(this)},Fr))}defer_effect(t){Xs(t,d(this,vn),d(this,mn))}is_rendered(){return!this.is_pending&&(!this.parent||this.parent.is_rendered())}has_pending_snippet(){return!!d(this,fe).pending}update_pending_count(t,n){T(this,H,$i).call(this,t,n),y(this,ft,d(this,ft)+t),!(!d(this,Re)||d(this,Pt))&&(y(this,Pt,!0),zt(()=>{y(this,Pt,!1),d(this,Re)&&Kt(d(this,Re),d(this,ft))}))}get_effect_pending(){return d(this,Qn).call(this),M(d(this,Re))}error(t){if(!d(this,fe).onerror&&!d(this,fe).failed)throw t;x!=null&&x.is_fork?(d(this,pe)&&x.skip_effect(d(this,pe)),d(this,W)&&x.skip_effect(d(this,W)),d(this,re)&&x.skip_effect(d(this,re)),x.oncommit(()=>{T(this,H,Ei).call(this,t)})):T(this,H,Ei).call(this,t)}}ue=new WeakMap,Bi=new WeakMap,fe=new WeakMap,ut=new WeakMap,Z=new WeakMap,pe=new WeakMap,W=new WeakMap,re=new WeakMap,He=new WeakMap,ft=new WeakMap,Ve=new WeakMap,Pt=new WeakMap,vn=new WeakMap,mn=new WeakMap,Re=new WeakMap,Qn=new WeakMap,H=new WeakSet,Gr=function(){try{y(this,pe,he(()=>d(this,ut).call(this,d(this,ue))))}catch(t){this.error(t)}},Kr=function(t){const n=d(this,fe).failed;n&&y(this,re,he(()=>{n(d(this,ue),()=>t,()=>()=>{})}))},qr=function(){const t=d(this,fe).pending;t&&(this.is_pending=!0,y(this,W,he(()=>t(d(this,ue)))),zt(()=>{var n=y(this,He,document.createDocumentFragment()),i=gt();n.append(i),y(this,pe,T(this,H,On).call(this,()=>he(()=>d(this,ut).call(this,i)))),d(this,Ve)===0&&(d(this,ue).before(n),y(this,He,null),bt(d(this,W),()=>{y(this,W,null)}),T(this,H,Pn).call(this,x))}))},Si=function(){try{if(this.is_pending=this.has_pending_snippet(),y(this,Ve,0),y(this,ft,0),y(this,pe,he(()=>{d(this,ut).call(this,d(this,ue))})),d(this,Ve)>0){var t=y(this,He,document.createDocumentFragment());Ui(d(this,pe),t);const n=d(this,fe).pending;y(this,W,he(()=>n(d(this,ue))))}else T(this,H,Pn).call(this,x)}catch(n){this.error(n)}},Pn=function(t){this.is_pending=!1,t.transfer_effects(d(this,vn),d(this,mn))},On=function(t){var n=E,i=S,s=Y;Pe(d(this,Z)),ge(d(this,Z)),Gt(d(this,Z).ctx);try{return xt.ensure(),t()}catch(a){return Ys(a),null}finally{Pe(n),ge(i),Gt(s)}},$i=function(t,n){var i;if(!this.has_pending_snippet()){this.parent&&T(i=this.parent,H,$i).call(i,t,n);return}y(this,Ve,d(this,Ve)+t),d(this,Ve)===0&&(T(this,H,Pn).call(this,n),d(this,W)&&bt(d(this,W),()=>{y(this,W,null)}),d(this,He)&&(d(this,ue).before(d(this,He)),y(this,He,null)))},Ei=function(t){d(this,pe)&&(ie(d(this,pe)),y(this,pe,null)),d(this,W)&&(ie(d(this,W)),y(this,W,null)),d(this,re)&&(ie(d(this,re)),y(this,re,null));var n=d(this,fe).onerror;let i=d(this,fe).failed;var s=!1,a=!1;const r=()=>{if(s){Pr();return}s=!0,a&&Sr(),d(this,re)!==null&&bt(d(this,re),()=>{y(this,re,null)}),T(this,H,On).call(this,()=>{T(this,H,Si).call(this)})},o=c=>{try{a=!0,n==null||n(c,r),a=!1}catch(u){Je(u,d(this,Z)&&d(this,Z).parent)}i&&y(this,re,T(this,H,On).call(this,()=>{try{return he(()=>{var u=E;u.b=this,u.f|=ki,i(d(this,ue),()=>c,()=>r)})}catch(u){return Je(u,d(this,Z).parent),null}}))};zt(()=>{var c;try{c=this.transform_error(t)}catch(u){Je(u,d(this,Z)&&d(this,Z).parent);return}c!==null&&typeof c=="object"&&typeof c.then=="function"?c.then(o,u=>Je(u,d(this,Z)&&d(this,Z).parent)):o(c)})};function Ur(e,t,n,i){const s=Ri;var a=e.filter(m=>!m.settled),r=t.map(s);if(n.length===0&&a.length===0){i(r);return}var o=E,c=jr(),u=a.length===1?a[0].promise:a.length>1?Promise.all(a.map(m=>m.promise)):null;function p(m){if((o.f&me)===0){c();try{i([...r,...m])}catch(h){Je(h,o)}Kn()}}var v=ea();if(n.length===0){u.then(()=>p([])).finally(v);return}function f(){Promise.all(n.map(m=>Vr(m))).then(p).catch(m=>Je(m,o)).finally(v)}u?u.then(()=>{c(),f(),Kn()}):f()}function jr(){var e=E,t=S,n=Y,i=x;return function(a=!0){Pe(e),ge(t),Gt(n),a&&(e.f&me)===0&&(i==null||i.activate(),i==null||i.apply())}}function Kn(e=!0){Pe(null),ge(null),Gt(null),e&&(x==null||x.deactivate())}function ea(){var e=E,t=e.b,n=x,i=!!(t!=null&&t.is_rendered());return t==null||t.update_pending_count(1,n),n.increment(i,e),()=>{t==null||t.update_pending_count(-1,n),n.decrement(i,e)}}function Ri(e){var t=U|q;return E!==null&&(E.f|=jt),{ctx:Y,deps:null,effects:null,equals:js,f:t,fn:e,reactions:null,rv:0,v:N,wv:0,parent:E,ac:null}}const Zt=Symbol("obsolete");function Vr(e,t,n){let i=E;i===null&&mr();var s=void 0,a=_t(N),r=!S,o=new Set;return dl(()=>{var m,h;var c=E,u=Ks();s=u.promise;try{Promise.resolve(e()).then(u.resolve,b=>{b!==ti&&u.reject(b)}).finally(Kn)}catch(b){u.reject(b),Kn()}var p=x;if(r){if((c.f&Ut)!==0)var v=ea();if((m=i.b)!=null&&m.is_rendered())(h=p.async_deriveds.get(c))==null||h.reject(Zt);else for(const b of o.values())b.reject(Zt);o.add(u),p.async_deriveds.set(c,u)}const f=(b,C=void 0)=>{v==null||v(),o.delete(u),C!==Zt&&(p.activate(),C?(a.f|=Ze,Kt(a,C)):((a.f&Ze)!==0&&(a.f^=Ze),Kt(a,b)),p.deactivate())};u.promise.then(f,b=>f(null,b||"unknown"))}),rl(()=>{for(const c of o)c.reject(Zt)}),new Promise(c=>{function u(p){function v(){p===s?c(a):u(s)}p.then(v,v)}u(s)})}function rs(e){const t=Ri(e);return ka(t),t}function Wr(e){const t=Ri(e);return t.equals=Vs,t}function Jr(e){var t=e.effects;if(t!==null){e.effects=null;for(var n=0;n<t.length;n+=1)ie(t[n])}}function Fi(e){var t,n=E,i=e.parent;if(!tt&&i!==null&&e.v!==N&&(i.f&(me|Q))!==0)return Dr(),e.v;Pe(i);try{e.f&=~yt,Jr(e),t=Ea(e)}finally{Pe(n)}return t}function ta(e){var t=Fi(e);if(!e.equals(t)&&(e.wv=Sa(),(!(x!=null&&x.is_fork)||e.deps===null)&&(x!==null?(x.capture(e,t,!0),ln==null||ln.capture(e,t,!0)):e.v=t,e.deps===null))){F(e,I);return}tt||(K!==null?(Gi()||x!=null&&x.is_fork)&&K.set(e,t):Hi(e))}function Qr(e){var t,n;if(e.effects!==null)for(const i of e.effects)(i.teardown||i.ac)&&((t=i.teardown)==null||t.call(i),(n=i.ac)==null||n.abort(ti),i.fn!==null&&(i.teardown=cr),i.ac=null,pn(i,0),qi(i))}function na(e){if(e.effects!==null)for(const t of e.effects)t.teardown&&t.fn!==null&&qt(t)}let ci=null,kt=null,x=null,ln=null,K=null,Ti=null,ui=!1,Tt=null,Bn=null;var ls=0;let Yr=1;var Ot,We,pt,Bt,Ht,Rt,Fe,Ft,X,gn,Ne,xe,Te,Nt,ht,P,Ci,Xt,Li,ia,sa,$t,Zr,en;const Yn=class Yn{constructor(){_(this,P);se(this,"id",Yr++);_(this,Ot,!1);se(this,"linked",!0);_(this,We,null);_(this,pt,null);se(this,"async_deriveds",new Map);se(this,"current",new Map);se(this,"previous",new Map);_(this,Bt,new Set);_(this,Ht,new Set);_(this,Rt,0);_(this,Fe,new Map);_(this,Ft,null);_(this,X,[]);_(this,gn,[]);_(this,Ne,new Set);_(this,xe,new Set);_(this,Te,new Map);_(this,Nt,new Set);se(this,"is_fork",!1);_(this,ht,!1);kt===null?ci=kt=this:(y(kt,pt,this),y(this,We,kt)),kt=this}skip_effect(t){d(this,Te).has(t)||d(this,Te).set(t,{d:[],m:[]}),d(this,Nt).delete(t)}unskip_effect(t,n=i=>this.schedule(i)){var i=d(this,Te).get(t);if(i){d(this,Te).delete(t);for(var s of i.d)F(s,q),n(s);for(s of i.m)F(s,De),n(s)}d(this,Nt).add(t)}capture(t,n,i=!1){t.v!==N&&!this.previous.has(t)&&this.previous.set(t,t.v),(t.f&Ze)===0&&(this.current.set(t,[n,i]),K==null||K.set(t,n)),this.is_fork||(t.v=n)}activate(){x=this}deactivate(){x=null,K=null}flush(){try{ui=!0,x=this,T(this,P,Xt).call(this)}finally{ls=0,Ti=null,Tt=null,Bn=null,ui=!1,x=null,K=null,mt.clear()}}discard(){var t;for(const n of d(this,Ht))n(this);d(this,Ht).clear();for(const n of this.async_deriveds.values())n.reject(Zt);T(this,P,en).call(this),(t=d(this,Ft))==null||t.resolve()}register_created_effect(t){d(this,gn).push(t)}increment(t,n){if(y(this,Rt,d(this,Rt)+1),t){let i=d(this,Fe).get(n)??0;d(this,Fe).set(n,i+1)}}decrement(t,n){if(y(this,Rt,d(this,Rt)-1),t){let i=d(this,Fe).get(n)??0;i===1?d(this,Fe).delete(n):d(this,Fe).set(n,i-1)}d(this,ht)||(y(this,ht,!0),zt(()=>{y(this,ht,!1),this.linked&&this.flush()}))}transfer_effects(t,n){for(const i of t)d(this,Ne).add(i);for(const i of n)d(this,xe).add(i);t.clear(),n.clear()}oncommit(t){d(this,Bt).add(t)}ondiscard(t){d(this,Ht).add(t)}settled(){return(d(this,Ft)??y(this,Ft,Ks())).promise}static ensure(){if(x===null){const t=x=new Yn;ui||zt(()=>{d(t,Ot)||t.flush()})}return x}apply(){{K=null;return}}schedule(t){var s;if(Ti=t,(s=t.b)!=null&&s.is_pending&&(t.f&(fn|ei|qs))!==0&&(t.f&Ut)===0){t.b.defer_effect(t);return}for(var n=t;n.parent!==null;){n=n.parent;var i=n.f;if(Tt!==null&&n===E&&(S===null||(S.f&U)===0))return;if((i&(et|$e))!==0){if((i&I)===0)return;n.f^=I}}d(this,X).push(n)}};Ot=new WeakMap,We=new WeakMap,pt=new WeakMap,Bt=new WeakMap,Ht=new WeakMap,Rt=new WeakMap,Fe=new WeakMap,Ft=new WeakMap,X=new WeakMap,gn=new WeakMap,Ne=new WeakMap,xe=new WeakMap,Te=new WeakMap,Nt=new WeakMap,ht=new WeakMap,P=new WeakSet,Ci=function(){if(this.is_fork)return!0;for(const i of d(this,Fe).keys()){for(var t=i,n=!1;t.parent!==null;){if(d(this,Te).has(t)){n=!0;break}t=t.parent}if(!n)return!0}return!1},Xt=function(){var c,u,p,v;y(this,Ot,!0),ls++>1e3&&(T(this,P,en).call(this),Xr());for(const f of d(this,Ne))d(this,xe).delete(f),F(f,q),this.schedule(f);for(const f of d(this,xe))F(f,De),this.schedule(f);const t=d(this,X);y(this,X,[]),this.apply();var n=Tt=[],i=[],s=Bn=[];for(const f of t)try{T(this,P,Li).call(this,f,n,i)}catch(m){throw la(f),T(this,P,Ci).call(this)||this.discard(),m}if(x=null,s.length>0){var a=Yn.ensure();for(const f of s)a.schedule(f)}if(Tt=null,Bn=null,T(this,P,Ci).call(this)){T(this,P,$t).call(this,i),T(this,P,$t).call(this,n);for(const[f,m]of d(this,Te))ra(f,m);s.length>0&&T(c=x,P,Xt).call(c);return}const r=T(this,P,ia).call(this);if(r){T(this,P,$t).call(this,i),T(this,P,$t).call(this,n),T(u=r,P,sa).call(u,this);return}d(this,Ne).clear(),d(this,xe).clear();for(const f of d(this,Bt))f(this);d(this,Bt).clear(),ln=this,os(i),os(n),ln=null,(p=d(this,Ft))==null||p.resolve();var o=x;if(d(this,Rt)===0&&(d(this,X).length===0||o!==null)&&T(this,P,en).call(this),d(this,X).length>0)if(o!==null){const f=o;d(f,X).push(...d(this,X).filter(m=>!d(f,X).includes(m)))}else o=this;o!==null&&T(v=o,P,Xt).call(v)},Li=function(t,n,i){t.f^=I;for(var s=t.first;s!==null;){var a=s.f,r=(a&($e|et))!==0,o=r&&(a&I)!==0,c=o||(a&Q)!==0||d(this,Te).has(s);if(!c&&s.fn!==null){r?s.f^=I:(a&fn)!==0?n.push(s):xn(s)&&((a&ke)!==0&&d(this,xe).add(s),qt(s));var u=s.first;if(u!==null){s=u;continue}}for(;s!==null;){var p=s.next;if(p!==null){s=p;break}s=s.parent}}},ia=function(){for(var t=d(this,We);t!==null;){if(!t.is_fork){for(const[n,[,i]]of this.current)if(t.current.has(n)&&!i)return t}t=d(t,We)}return null},sa=function(t){var i;for(const[s,a]of t.current)!this.previous.has(s)&&t.previous.has(s)&&this.previous.set(s,t.previous.get(s)),this.current.set(s,a);for(const[s,a]of t.async_deriveds){const r=this.async_deriveds.get(s);r&&a.promise.then(r.resolve).catch(r.reject)}t.async_deriveds.clear(),this.transfer_effects(d(t,Ne),d(t,xe));const n=s=>{var a=s.reactions;if(a!==null)for(const c of a){var r=c.f;if((r&U)!==0)n(c);else{var o=c;r&(At|ke)&&!this.async_deriveds.has(o)&&(d(this,xe).delete(o),F(o,q),this.schedule(o))}}};for(const s of this.current.keys())n(s);this.oncommit(()=>t.discard()),T(i=t,P,en).call(i),x=this,T(this,P,Xt).call(this)},$t=function(t){for(var n=0;n<t.length;n+=1)Xs(t[n],d(this,Ne),d(this,xe))},Zr=function(){var v;for(let f=ci;f!==null;f=d(f,pt)){var t=f.id<this.id,n=[];for(const[m,[h,b]]of this.current){if(f.current.has(m)){var i=f.current.get(m)[0];if(t&&h!==i)f.current.set(m,[h,b]);else continue}n.push(m)}if(t)for(const[m,h]of this.async_deriveds){const b=f.async_deriveds.get(m);b&&h.promise.then(b.resolve).catch(b.reject)}var s=[...f.current.keys()].filter(m=>!f.current.get(m)[1]);if(!(!d(f,Ot)||s.length===0)){var a=s.filter(m=>!this.current.has(m));if(a.length===0)t&&f.discard();else if(n.length>0){if(t)for(const m of d(this,Nt))f.unskip_effect(m,h=>{var b;(h.f&(ke|At))!==0?f.schedule(h):T(b=f,P,$t).call(b,[h])});f.activate();var r=new Set,o=new Map;for(var c of n)aa(c,a,r,o);o=new Map;var u=[...f.current].filter(([m,h])=>{const b=this.current.get(m);return b?b[0]!==h[0]||b[1]!==h[1]:!0}).map(([m])=>m);if(u.length>0)for(const m of d(this,gn))(m.f&(me|Q|In))===0&&Ni(m,u,o)&&((m.f&(At|ke))!==0?(F(m,q),f.schedule(m)):d(f,Ne).add(m));if(d(f,X).length>0&&!d(f,ht)){f.apply();for(var p of d(f,X))T(v=f,P,Li).call(v,p,[],[]);y(f,X,[])}f.deactivate()}}}},en=function(){if(this.linked){var t=d(this,We),n=d(this,pt);t===null?ci=n:y(t,pt,n),n===null?kt=t:y(n,We,t),this.linked=!1}};let xt=Yn;function Xr(){try{xr()}catch(e){Je(e,Ti)}}let we=null;function os(e){var t=e.length;if(t!==0){for(var n=0;n<t;){var i=e[n++];if((i.f&(me|Q))===0&&xn(i)&&(we=new Set,qt(i),i.deps===null&&i.first===null&&i.nodes===null&&i.teardown===null&&i.ac===null&&ya(i),(we==null?void 0:we.size)>0)){mt.clear();for(const s of we){if((s.f&(me|Q))!==0)continue;const a=[s];let r=s.parent;for(;r!==null;)we.has(r)&&(we.delete(r),a.push(r)),r=r.parent;for(let o=a.length-1;o>=0;o--){const c=a[o];(c.f&(me|Q))===0&&qt(c)}}we.clear()}}we=null}}function aa(e,t,n,i){if(!n.has(e)&&(n.add(e),e.reactions!==null))for(const s of e.reactions){const a=s.f;(a&U)!==0?aa(s,t,n,i):(a&(At|ke))!==0&&(a&q)===0&&Ni(s,t,i)&&(F(s,q),Ii(s))}}function Ni(e,t,n){const i=n.get(e);if(i!==void 0)return i;if(e.deps!==null)for(const s of e.deps){if(Nn.call(t,s))return!0;if((s.f&U)!==0&&Ni(s,t,n))return n.set(s,!0),!0}return n.set(e,!1),!1}function Ii(e){x.schedule(e)}function ra(e,t){if(!((e.f&$e)!==0&&(e.f&I)!==0)){(e.f&q)!==0?t.d.push(e):(e.f&De)!==0&&t.m.push(e),F(e,I);for(var n=e.first;n!==null;)ra(n,t),n=n.next}}function la(e){F(e,I);for(var t=e.first;t!==null;)la(t),t=t.next}let qn=new Set;const mt=new Map;let oa=!1;function _t(e,t){var n={f:0,v:e,reactions:null,equals:js,rv:0,wv:0};return n}function ee(e,t){const n=_t(e);return ka(n),n}function el(e,t=!1,n=!0){const i=_t(e);return t||(i.equals=Vs),i}function V(e,t,n=!1){S!==null&&(!Me||(S.f&In)!==0)&&Qs()&&(S.f&(U|ke|At|In))!==0&&(ze===null||!ze.has(e))&&Mr();let i=n?Qe(t):t;return Kt(e,i,Bn)}function Kt(e,t,n=null){if(!e.equals(t)){mt.set(e,tt?t:e.v);var i=xt.ensure();if(i.capture(e,t),(e.f&U)!==0){const s=e;(e.f&q)!==0&&Fi(s),K===null&&Hi(s)}e.wv=Sa(),da(e,q,n),E!==null&&(E.f&I)!==0&&(E.f&($e|et))===0&&(de===null?fl([e]):de.push(e)),!i.is_fork&&qn.size>0&&!oa&&tl()}return t}function tl(){oa=!1;for(const e of qn){(e.f&I)!==0&&F(e,De);let t;try{t=xn(e)}catch{t=!0}t&&qt(e)}qn.clear()}function on(e){V(e,e.v+1)}function da(e,t,n){var i=e.reactions;if(i!==null)for(var s=i.length,a=0;a<s;a++){var r=i[a],o=r.f,c=(o&q)===0;if(c&&F(r,t),(o&In)!==0)qn.add(r);else if((o&U)!==0){var u=r;K==null||K.delete(u),(o&yt)===0&&(o&ve&&(E===null||(E.f&Gn)===0)&&(r.f|=yt),da(u,De,n))}else if(c){var p=r;(o&ke)!==0&&we!==null&&we.add(p),n!==null?n.push(p):Ii(p)}}}function Qe(e){if(typeof e!="object"||e===null||di in e)return e;const t=Gs(e);if(t!==or&&t!==dr)return e;var n=new Map,i=Is(e),s=ee(0),a=wt,r=o=>{if(wt===a)return o();var c=S,u=wt;ge(null),us(a);var p=o();return ge(c),us(u),p};return i&&n.set("length",ee(e.length)),new Proxy(e,{defineProperty(o,c,u){(!("value"in u)||u.configurable===!1||u.enumerable===!1||u.writable===!1)&&_r();var p=n.get(c);return p===void 0?r(()=>{var v=ee(u.value);return n.set(c,v),v}):V(p,u.value,!0),!0},deleteProperty(o,c){var u=n.get(c);if(u===void 0){if(c in o){const p=r(()=>ee(N));n.set(c,p),on(s)}}else V(u,N),on(s);return!0},get(o,c,u){var m;if(c===di)return e;var p=n.get(c),v=c in o;if(p===void 0&&(!v||(m=rn(o,c))!=null&&m.writable)&&(p=r(()=>{var h=Qe(v?o[c]:N),b=ee(h);return b}),n.set(c,p)),p!==void 0){var f=M(p);return f===N?void 0:f}return Reflect.get(o,c,u)},getOwnPropertyDescriptor(o,c){var u=Reflect.getOwnPropertyDescriptor(o,c);if(u&&"value"in u){var p=n.get(c);p&&(u.value=M(p))}else if(u===void 0){var v=n.get(c),f=v==null?void 0:v.v;if(v!==void 0&&f!==N)return{enumerable:!0,configurable:!0,value:f,writable:!0}}return u},has(o,c){var f;if(c===di)return!0;var u=n.get(c),p=u!==void 0&&u.v!==N||Reflect.has(o,c);if(u!==void 0||E!==null&&(!p||(f=rn(o,c))!=null&&f.writable)){u===void 0&&(u=r(()=>{var m=p?Qe(o[c]):N,h=ee(m);return h}),n.set(c,u));var v=M(u);if(v===N)return!1}return p},set(o,c,u,p){var j;var v=n.get(c),f=c in o;if(i&&c==="length")for(var m=u;m<v.v;m+=1){var h=n.get(m+"");h!==void 0?V(h,N):m in o&&(h=r(()=>ee(N)),n.set(m+"",h))}if(v===void 0)(!f||(j=rn(o,c))!=null&&j.writable)&&(v=r(()=>ee(void 0)),V(v,Qe(u)),n.set(c,v));else{f=v.v!==N;var b=r(()=>Qe(u));V(v,b)}var C=Reflect.getOwnPropertyDescriptor(o,c);if(C!=null&&C.set&&C.set.call(p,u),!f){if(i&&typeof c=="string"){var L=n.get("length"),z=Number(c);Number.isInteger(z)&&z>=L.v&&V(L,z+1)}on(s)}return!0},ownKeys(o){M(s);var c=Reflect.ownKeys(o).filter(v=>{var f=n.get(v);return f===void 0||f.v!==N});for(var[u,p]of n)p.v!==N&&!(u in o)&&c.push(u);return c},setPrototypeOf(){kr()}})}var ds,ca,ua,fa;function nl(){if(ds===void 0){ds=window,ca=/Firefox/.test(navigator.userAgent);var e=Element.prototype,t=Node.prototype,n=Text.prototype;ua=rn(t,"firstChild").get,fa=rn(t,"nextSibling").get,is(e)&&(e[Mi]=void 0,e[Dn]=null,e[hr]=void 0,e.__e=void 0),is(n)&&(n[Yt]=void 0)}}function gt(e=""){return document.createTextNode(e)}function Ye(e){return ua.call(e)}function yn(e){return fa.call(e)}function R(e,t){return Ye(e)}function pa(e,t=!1){{var n=Ye(e);return n instanceof Comment&&n.data===""?yn(n):n}}function J(e,t=1,n=!1){let i=e;for(;t--;)i=yn(i);return i}function il(e){e.textContent=""}function ha(){return!1}function va(e,t,n){return t==null||t===Us?n?document.createElement(e,{is:n}):document.createElement(e):n?document.createElementNS(t,e,{is:n}):document.createElementNS(t,e)}function ma(e){var t=S,n=E;ge(null),Pe(null);try{return e()}finally{ge(t),Pe(n)}}function sl(e){E===null&&(S===null&&yr(),wr()),tt&&br()}function al(e,t){var n=t.last;n===null?t.last=t.first=e:(n.next=e,e.prev=n,t.last=e)}function it(e,t){var n=E;n!==null&&(n.f&Q)!==0&&(e|=Q);var i={ctx:Y,deps:null,nodes:null,f:e|q|ve,first:null,fn:t,last:null,next:null,parent:n,b:n&&n.b,prev:null,teardown:null,wv:0,ac:null};x==null||x.register_created_effect(i);var s=i;if((e&fn)!==0)Tt!==null?Tt.push(i):xt.ensure().schedule(i);else if(t!==null){try{qt(i)}catch(r){throw ie(i),r}s.deps===null&&s.teardown===null&&s.nodes===null&&s.first===s.last&&(s.f&jt)===0&&(s=s.first,(e&ke)!==0&&(e&It)!==0&&s!==null&&(s.f|=It))}if(s!==null&&(s.parent=n,n!==null&&al(s,n),S!==null&&(S.f&U)!==0&&(e&et)===0)){var a=S;(a.effects??(a.effects=[])).push(s)}return i}function Gi(){return S!==null&&!Me}function rl(e){const t=it(ei,null);return F(t,I),t.teardown=e,t}function ll(e){sl();var t=E.f,n=!S&&(t&$e)!==0&&Y!==null&&!Y.i;if(n){var i=Y;(i.e??(i.e=[])).push(e)}else return ga(e)}function ga(e){return it(fn|pr,e)}function ol(e){xt.ensure();const t=it(et|jt,e);return(n={})=>new Promise(i=>{n.outro?bt(t,()=>{ie(t),i(void 0)}):(ie(t),i(void 0))})}function dl(e){return it(At|jt,e)}function cl(e,t=0){return it(ei|t,e)}function ot(e,t=[],n=[],i=[]){Ur(i,t,n,s=>{it(ei,()=>{e(...s.map(M))})})}function Ki(e,t=0){var n=it(ke|t,e);return n}function he(e){return it($e|jt,e)}function ba(e){var t=e.teardown;if(t!==null){const n=tt,i=S;cs(!0),ge(null);try{t.call(null)}finally{cs(n),ge(i)}}}function qi(e,t=!1){var n=e.first;for(e.first=e.last=null;n!==null;){const s=n.ac;s!==null&&ma(()=>{s.abort(ti)});var i=n.next;(n.f&et)!==0?n.parent=null:ie(n,t),n=i}}function ul(e){for(var t=e.first;t!==null;){var n=t.next;(t.f&$e)===0&&ie(t),t=n}}function ie(e,t=!0){var n=!1;(t||(e.f&fr)!==0)&&e.nodes!==null&&e.nodes.end!==null&&(wa(e.nodes.start,e.nodes.end),n=!0),e.f|=as,qi(e,t&&!n),pn(e,0);var i=e.nodes&&e.nodes.t;if(i!==null)for(const a of i)a.stop();ba(e),e.f^=as,e.f|=me;var s=e.parent;s!==null&&s.first!==null&&ya(e),e.next=e.prev=e.teardown=e.ctx=e.deps=e.fn=e.nodes=e.ac=e.b=null}function wa(e,t){for(;e!==null;){var n=e===t?null:yn(e);e.remove(),e=n}}function ya(e){var t=e.parent,n=e.prev,i=e.next;n!==null&&(n.next=i),i!==null&&(i.prev=n),t!==null&&(t.first===e&&(t.first=i),t.last===e&&(t.last=n))}function bt(e,t,n=!0){var i=[];xa(e,i,!0);var s=()=>{n&&ie(e),t&&t()},a=i.length;if(a>0){var r=()=>--a||s();for(var o of i)o.out(r)}else s()}function xa(e,t,n){if((e.f&Q)===0){e.f^=Q;var i=e.nodes&&e.nodes.t;if(i!==null)for(const o of i)(o.is_global||n)&&t.push(o);for(var s=e.first;s!==null;){var a=s.next;if((s.f&et)===0){var r=(s.f&It)!==0||(s.f&$e)!==0&&(e.f&ke)!==0;xa(s,t,r?n:!1)}s=a}}}function Un(e){_a(e,!0)}function _a(e,t){if((e.f&Q)!==0){e.f^=Q,(e.f&I)===0&&(F(e,q),xt.ensure().schedule(e));for(var n=e.first;n!==null;){var i=n.next,s=(n.f&It)!==0||(n.f&$e)!==0;_a(n,s?t:!1),n=i}var a=e.nodes&&e.nodes.t;if(a!==null)for(const r of a)(r.is_global||t)&&r.in()}}function Ui(e,t){if(e.nodes)for(var n=e.nodes.start,i=e.nodes.end;n!==null;){var s=n===i?null:yn(n);t.append(n),n=s}}let Hn=!1,tt=!1;function cs(e){tt=e}let S=null,Me=!1;function ge(e){S=e}let E=null;function Pe(e){E=e}let ze=null;function ka(e){S!==null&&(ze??(ze=new Set)).add(e)}let te=null,ae=0,de=null;function fl(e){de=e}let Ma=1,dt=0,wt=dt;function us(e){wt=e}function Sa(){return++Ma}function xn(e){var t=e.f;if((t&q)!==0)return!0;if(t&U&&(e.f&=~yt),(t&De)!==0){for(var n=e.deps,i=n.length,s=0;s<i;s++){var a=n[s];if(xn(a)&&ta(a),a.wv>e.wv)return!0}(t&ve)!==0&&K===null&&F(e,I)}return!1}function $a(e,t,n=!0){var i=e.reactions;if(i!==null&&!(ze!==null&&ze.has(e)))for(var s=0;s<i.length;s++){var a=i[s];(a.f&U)!==0?$a(a,t,!1):t===a&&(n?F(a,q):(a.f&I)!==0&&F(a,De),Ii(a))}}function Ea(e){var b;var t=te,n=ae,i=de,s=S,a=ze,r=Y,o=Me,c=wt,u=e.f;te=null,ae=0,de=null,S=(u&($e|et))===0?e:null,ze=null,Gt(e.ctx),Me=!1,wt=++dt,e.ac!==null&&(ma(()=>{e.ac.abort(ti)}),e.ac=null);try{e.f|=Gn;var p=e.fn,v=p();e.f|=Ut;var f=e.deps,m=x==null?void 0:x.is_fork;if(te!==null){var h;if(m||pn(e,ae),f!==null&&ae>0)for(f.length=ae+te.length,h=0;h<te.length;h++)f[ae+h]=te[h];else e.deps=f=te;if(Gi()&&(e.f&ve)!==0)for(h=ae;h<f.length;h++)((b=f[h]).reactions??(b.reactions=[])).push(e)}else!m&&f!==null&&ae<f.length&&(pn(e,ae),f.length=ae);if(Qs()&&de!==null&&!Me&&f!==null&&(e.f&(U|De|q))===0)for(h=0;h<de.length;h++)$a(de[h],e);if(s!==null&&s!==e){if(dt++,s.deps!==null)for(let C=0;C<n;C+=1)s.deps[C].rv=dt;if(t!==null)for(const C of t)C.rv=dt;de!==null&&(i===null?i=de:i.push(...de))}return(e.f&Ze)!==0&&(e.f^=Ze),v}catch(C){return Ys(C)}finally{e.f^=Gn,te=t,ae=n,de=i,S=s,ze=a,Gt(r),Me=o,wt=c}}function pl(e,t){let n=t.reactions;if(n!==null){var i=ar.call(n,e);if(i!==-1){var s=n.length-1;s===0?n=t.reactions=null:(n[i]=n[s],n.pop())}}if(n===null&&(t.f&U)!==0&&(te===null||!Nn.call(te,t))){var a=t;(a.f&ve)!==0&&(a.f^=ve,a.f&=~yt),a.v!==N&&Hi(a),Qr(a),pn(a,0)}}function pn(e,t){var n=e.deps;if(n!==null)for(var i=t;i<n.length;i++)pl(e,n[i])}function qt(e){var t=e.f;if((t&me)===0){F(e,I);var n=E,i=Hn;E=e,Hn=!0;try{(t&(ke|qs))!==0?ul(e):qi(e),ba(e);var s=Ea(e);e.teardown=typeof s=="function"?s:null,e.wv=Ma;var a}finally{Hn=i,E=n}}}function M(e){var t=e.f,n=(t&U)!==0;if(S!==null&&!Me){var i=E!==null&&(E.f&me)!==0;if(!i&&(ze===null||!ze.has(e))){var s=S.deps;if((S.f&Gn)!==0)e.rv<dt&&(e.rv=dt,te===null&&s!==null&&s[ae]===e?ae++:te===null?te=[e]:te.push(e));else{S.deps??(S.deps=[]),Nn.call(S.deps,e)||S.deps.push(e);var a=e.reactions;a===null?e.reactions=[S]:Nn.call(a,S)||a.push(S)}}}if(tt&&mt.has(e))return mt.get(e);if(n){var r=e;if(tt){var o=r.v;return((r.f&I)===0&&r.reactions!==null||Ca(r))&&(o=Fi(r)),mt.set(r,o),o}var c=(r.f&ve)===0&&!Me&&S!==null&&(Hn||(S.f&ve)!==0),u=(r.f&Ut)===0;xn(r)&&(c&&(r.f|=ve),ta(r)),c&&!u&&(na(r),Ta(r))}if(K!=null&&K.has(e))return K.get(e);if((e.f&Ze)!==0)throw e.v;return e.v}function Ta(e){if(e.f|=ve,e.deps!==null)for(const t of e.deps)(t.reactions??(t.reactions=[])).push(e),(t.f&U)!==0&&(t.f&ve)===0&&(na(t),Ta(t))}function Ca(e){if(e.v===N)return!0;if(e.deps===null)return!1;for(const t of e.deps)if(mt.has(t)||(t.f&U)!==0&&Ca(t))return!0;return!1}function La(e){var t=Me;try{return Me=!0,e()}finally{Me=t}}const hl=["touchstart","touchmove"];function vl(e){return hl.includes(e)}const ct=Symbol("events"),Aa=new Set,Ai=new Set;function fs(e,t,n){(t[ct]??(t[ct]={}))[e]=n}function ml(e){for(var t=0;t<e.length;t++)Aa.add(e[t]);for(var n of Ai)n(e)}let ps=null;function hs(e){var b,C;var t=this,n=t.ownerDocument,i=e.type,s=((b=e.composedPath)==null?void 0:b.call(e))||[],a=s[0]||e.target;ps=e;var r=0,o=ps===e&&e[ct];if(o){var c=s.indexOf(o);if(c!==-1&&(t===document||t===window)){e[ct]=t;return}var u=s.indexOf(t);if(u===-1)return;c<=u&&(r=c)}if(a=s[r]||e.target,a!==t){rr(e,"currentTarget",{configurable:!0,get(){return a||n}});var p=S,v=E;ge(null),Pe(null);try{for(var f,m=[];a!==null&&a!==t;){try{var h=(C=a[ct])==null?void 0:C[i];h!=null&&(!a.disabled||e.target===a)&&h.call(a,e)}catch(L){f?m.push(L):f=L}if(e.cancelBubble)break;r++,a=r<s.length?s[r]:null}if(f){for(let L of m)queueMicrotask(()=>{throw L});throw f}}finally{e[ct]=t,delete e.currentTarget,ge(p),Pe(v)}}}var Rs;const fi=((Rs=globalThis==null?void 0:globalThis.window)==null?void 0:Rs.trustedTypes)&&globalThis.window.trustedTypes.createPolicy("svelte-trusted-html",{createHTML:e=>e});function gl(e){return(fi==null?void 0:fi.createHTML(e))??e}function bl(e){var t=va("template");return t.innerHTML=gl(e.replaceAll("<!>","<!---->")),t.content}function jn(e,t){var n=E;n.nodes===null&&(n.nodes={start:e,end:t,a:null,t:null})}function be(e,t){var n=(t&Cr)!==0,i=(t&Lr)!==0,s,a=!e.startsWith("<!>");return()=>{s===void 0&&(s=bl(a?e:"<!>"+e),n||(s=Ye(s)));var r=i||ca?document.importNode(s,!0):s.cloneNode(!0);if(n){var o=Ye(r),c=r.lastChild;jn(o,c)}else jn(r,r);return r}}function ce(e,t){e!==null&&e.before(t)}function ye(e,t){var n=t==null?"":typeof t=="object"?`${t}`:t;n!==(e[Yt]??(e[Yt]=e.nodeValue))&&(e[Yt]=n,e.nodeValue=`${n}`)}function za(e,t){return wl(e,t)}const An=new Map;function wl(e,{target:t,anchor:n,props:i={},events:s,context:a,intro:r=!0,transformError:o}){nl();var c=void 0,u=ol(()=>{var p=n??t.appendChild(gt());Nr(p,{pending:()=>{}},m=>{Ws({});var h=Y;a&&(h.c=a),s&&(i.$$events=s),c=e(m,i)||{},Js()},o);var v=new Set,f=m=>{for(var h=0;h<m.length;h++){var b=m[h];if(!v.has(b)){v.add(b);var C=vl(b);for(const j of[t,document]){var L=An.get(j);L===void 0&&(L=new Map,An.set(j,L));var z=L.get(b);z===void 0?(j.addEventListener(b,hs,{passive:C}),L.set(b,1)):L.set(b,z+1)}}}};return f(Xn(Aa)),Ai.add(f),()=>{var C;for(var m of v)for(const L of[t,document]){var h=An.get(L),b=h.get(m);--b==0?(L.removeEventListener(m,hs),h.delete(m),h.size===0&&An.delete(L)):h.set(m,b)}Ai.delete(f),p!==n&&((C=p.parentNode)==null||C.removeChild(p))}});return yl.set(c,u),c}let yl=new WeakMap;var _e,Ce,le,vt,bn,wn,Zn;class xl{constructor(t,n=!0){se(this,"anchor");_(this,_e,new Map);_(this,Ce,new Map);_(this,le,new Map);_(this,vt,new Set);_(this,bn,!0);_(this,wn,t=>{if(d(this,_e).has(t)){var n=d(this,_e).get(t),i=d(this,Ce).get(n);if(i)Un(i),d(this,vt).delete(n);else{var s=d(this,le).get(n);s&&(Un(s.effect),d(this,Ce).set(n,s.effect),d(this,le).delete(n),s.fragment.lastChild.remove(),this.anchor.before(s.fragment),i=s.effect)}for(const[a,r]of d(this,_e)){if(d(this,_e).delete(a),a===t)break;const o=d(this,le).get(r);o&&(ie(o.effect),d(this,le).delete(r))}for(const[a,r]of d(this,Ce)){if(a===n||d(this,vt).has(a))continue;const o=()=>{if(Array.from(d(this,_e).values()).includes(a)){var u=document.createDocumentFragment();Ui(r,u),u.append(gt()),d(this,le).set(a,{effect:r,fragment:u})}else ie(r);d(this,vt).delete(a),d(this,Ce).delete(a)};d(this,bn)||!i?(d(this,vt).add(a),bt(r,o,!1)):o()}}});_(this,Zn,t=>{d(this,_e).delete(t);const n=Array.from(d(this,_e).values());for(const[i,s]of d(this,le))n.includes(i)||(ie(s.effect),d(this,le).delete(i))});this.anchor=t,y(this,bn,n)}ensure(t,n){var i=x,s=ha();if(n&&!d(this,Ce).has(t)&&!d(this,le).has(t))if(s){var a=document.createDocumentFragment(),r=gt();a.append(r),d(this,le).set(t,{effect:he(()=>n(r)),fragment:a})}else d(this,Ce).set(t,he(()=>n(this.anchor)));if(d(this,_e).set(i,t),s){for(const[o,c]of d(this,Ce))o===t?i.unskip_effect(c):i.skip_effect(c);for(const[o,c]of d(this,le))o===t?i.unskip_effect(c.effect):i.skip_effect(c.effect);i.oncommit(d(this,wn)),i.ondiscard(d(this,Zn))}else d(this,wn).call(this,i)}}_e=new WeakMap,Ce=new WeakMap,le=new WeakMap,vt=new WeakMap,bn=new WeakMap,wn=new WeakMap,Zn=new WeakMap;function pi(e,t,n=!1){var i=new xl(e),s=n?It:0;function a(r,o){i.ensure(r,o)}Ki(()=>{var r=!1;t((o,c=0)=>{r=!0,a(c,o)}),r||a(-1,null)},s)}function Vn(e,t){return t}function _l(e,t,n){for(var i=[],s=t.length,a,r=t.length,o=0;o<s;o++){let v=t[o];bt(v,()=>{if(a){if(a.pending.delete(v),a.done.add(v),a.pending.size===0){var f=e.outrogroups;zi(e,Xn(a.done)),f.delete(a),f.size===0&&(e.outrogroups=null)}}else r-=1},!1)}if(r===0){var c=i.length===0&&n!==null;if(c){var u=n,p=u.parentNode;il(p),p.append(u),e.items.clear()}zi(e,t,!c)}else a={pending:new Set(t),done:new Set},(e.outrogroups??(e.outrogroups=new Set)).add(a)}function zi(e,t,n=!0){var i;if(e.pending.size>0){i=new Set;for(const r of e.pending.values())for(const o of r)i.add(e.items.get(o).e)}for(var s=0;s<t.length;s++){var a=t[s];if(i!=null&&i.has(a)){a.f|=Ie;const r=document.createDocumentFragment();Ui(a,r)}else ie(t[s],n)}}var vs;function Wn(e,t,n,i,s,a=null){var r=e,o=new Map;{var c=e;r=c.appendChild(gt())}var u=null,p=Wr(()=>{var z=n();return Is(z)?z:z==null?[]:Xn(z)}),v,f=new Map,m=!0;function h(z){(L.effect.f&me)===0&&(L.pending.delete(z),L.fallback=u,kl(L,v,r,t,i),u!==null&&(v.length===0?(u.f&Ie)===0?Un(u):(u.f^=Ie,tn(u,null,r)):bt(u,()=>{u=null})))}function b(z){L.pending.delete(z)}var C=Ki(()=>{v=M(p);for(var z=v.length,j=new Set,oe=x,Oe=ha(),k=0;k<z;k+=1){var A=v[k],G=i(A,k),O=m?null:o.get(G);O?(O.v&&Kt(O.v,A),O.i&&Kt(O.i,k),Oe&&oe.unskip_effect(O.e)):(O=Ml(o,m?r:vs??(vs=gt()),A,G,k,s,t,n),m||(O.e.f|=Ie),o.set(G,O)),j.add(G)}if(z===0&&a&&!u&&(m?u=he(()=>a(r)):(u=he(()=>a(vs??(vs=gt()))),u.f|=Ie)),z>j.size&&gr(),!m)if(f.set(oe,j),Oe){for(const[Wt,Ke]of o)j.has(Wt)||oe.skip_effect(Ke.e);oe.oncommit(h),oe.ondiscard(b)}else h(oe);M(p)}),L={effect:C,items:o,pending:f,outrogroups:null,fallback:u};m=!1}function Qt(e){for(;e!==null&&(e.f&$e)===0;)e=e.next;return e}function kl(e,t,n,i,s){var G;var a=t.length,r=e.items,o=Qt(e.effect.first),c,u=null,p=[],v=[],f,m,h,b;for(b=0;b<a;b+=1){if(f=t[b],m=s(f,b),h=r.get(m).e,e.outrogroups!==null)for(const O of e.outrogroups)O.pending.delete(h),O.done.delete(h);if((h.f&Q)!==0&&Un(h),(h.f&Ie)!==0)if(h.f^=Ie,h===o)tn(h,null,n);else{var C=u?u.next:o;h===e.effect.last&&(e.effect.last=h.prev),h.prev&&(h.prev.next=h.next),h.next&&(h.next.prev=h.prev),qe(e,u,h),qe(e,h,C),tn(h,C,n),u=h,p=[],v=[],o=Qt(u.next);continue}if(h!==o){if(c!==void 0&&c.has(h)){if(p.length<v.length){var L=v[0],z;u=L.prev;var j=p[0],oe=p[p.length-1];for(z=0;z<p.length;z+=1)tn(p[z],L,n);for(z=0;z<v.length;z+=1)c.delete(v[z]);qe(e,j.prev,oe.next),qe(e,u,j),qe(e,oe,L),o=L,u=oe,b-=1,p=[],v=[]}else c.delete(h),tn(h,o,n),qe(e,h.prev,h.next),qe(e,h,u===null?e.effect.first:u.next),qe(e,u,h),u=h;continue}for(p=[],v=[];o!==null&&o!==h;)(c??(c=new Set)).add(o),v.push(o),o=Qt(o.next);if(o===null)continue}(h.f&Ie)===0&&p.push(h),u=h,o=Qt(h.next)}if(e.outrogroups!==null){for(const O of e.outrogroups)O.pending.size===0&&(zi(e,Xn(O.done)),(G=e.outrogroups)==null||G.delete(O));e.outrogroups.size===0&&(e.outrogroups=null)}if(o!==null||c!==void 0){var Oe=[];if(c!==void 0)for(h of c)(h.f&Q)===0&&Oe.push(h);for(;o!==null;)(o.f&Q)===0&&o!==e.fallback&&Oe.push(o),o=Qt(o.next);var k=Oe.length;if(k>0){var A=a===0?n:null;_l(e,Oe,A)}}}function Ml(e,t,n,i,s,a,r,o){var c=(r&$r)!==0?(r&Tr)===0?el(n,!1,!1):_t(n):null,u=(r&Er)!==0?_t(s):null;return{v:c,i:u,e:he(()=>(a(t,c??n,u??s,o),()=>{e.delete(i)}))}}function tn(e,t,n){if(e.nodes)for(var i=e.nodes.start,s=e.nodes.end,a=t&&(t.f&Ie)===0?t.nodes.start:n;i!==null;){var r=yn(i);if(a.before(i),i===s)return;i=r}}function qe(e,t,n){t===null?e.effect.first=n:t.next=n,n===null?e.effect.last=t:n.prev=t}function Sl(e,t,n=!1,i=!1,s=!1,a=!1){var r=e,o="";if(n)var c=e;ot(()=>{var u=E;if(o!==(o=t()??"")){if(n){u.nodes=null,c.innerHTML=o,o!==""&&jn(Ye(c),c.lastChild);return}if(u.nodes!==null&&(wa(u.nodes.start,u.nodes.end),u.nodes=null),o!==""){var p=i?Ar:s?zr:void 0,v=va(i?"svg":s?"math":"template",p);v.innerHTML=o;var f=i||s?v:v.content;if(jn(Ye(f),f.lastChild),i||s)for(;Ye(f);)r.before(Ye(f));else r.before(f)}}})}function $l(e,t,n){var i=e==null?"":""+e;return i===""?null:i}function ms(e,t,n,i,s,a){var r=e[Mi];if(r!==n||r===void 0){var o=$l(n);o==null?e.removeAttribute("class"):e.className=o,e[Mi]=n}return a}const El=Symbol("is custom element"),Tl=Symbol("is html");function Cl(e,t,n,i){var s=Ll(e);s[t]!==(s[t]=n)&&(n==null?e.removeAttribute(t):typeof n!="string"&&Al(e).includes(t)?e[t]=n:e.setAttribute(t,n))}function Ll(e){return e[Dn]??(e[Dn]={[El]:e.nodeName.includes("-"),[Tl]:e.namespaceURI===Us})}var gs=new Map;function Al(e){var t=e.getAttribute("is")||e.nodeName,n=gs.get(t);if(n)return n;gs.set(t,n=[]);for(var i,s=e,a=Element.prototype;a!==s;){i=lr(s);for(var r in i)i[r].set&&r!=="innerHTML"&&r!=="textContent"&&r!=="innerText"&&n.push(r);s=Gs(s)}return n}function zl(e){Y===null&&vr(),ll(()=>{const t=La(e);if(typeof t=="function")return t})}let hn=localStorage.getItem("mc_token")||"";function Da(){return hn}function Dl(e){hn=(e||"").trim(),localStorage.setItem("mc_token",hn)}function Pl(){const e={"Content-Type":"application/json"};return hn&&(e["X-MC-Token"]=hn),e}function _n(){return localStorage.getItem("mc_hf_token")||""}function Ol(e){localStorage.setItem("mc_hf_token",(e||"").trim())}async function $(e,t={}){const n=await fetch(e,{headers:Pl(),...t}),i=await n.json().catch(()=>({}));if(!n.ok)throw new Error(i.error||"HTTP "+n.status);return i}const l=(e,t=document)=>t.querySelector(e),bs=(e,t=document)=>[...t.querySelectorAll(e)];function g(e){return String(e??"").replace(/[&<>]/g,t=>({"&":"&amp;","<":"&lt;",">":"&gt;"})[t])}let ws;function w(e,t=!1){const n=l("#toast");n&&(n.textContent=e,n.className="toast show"+(t?" err":""),clearTimeout(ws),ws=setTimeout(()=>n.className="toast",3200))}function Bl(e,t){return e==="running"||e==="ready"?'<span class="badge b-run">geladen</span>':e==="loading"||e==="starting"?'<span class="badge b-load">lädt…</span>':e==="downloading"?`<span class="badge b-load">↓ Download${t!=null?` ${Math.round(t)}%`:""}</span>`:'<span class="badge b-run">bereit</span>'}const D=e=>`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round">${e}</svg>`,Pa={logo:D('<circle cx="12" cy="12" r="3.2"/><path d="M12 2v3M12 19v3M2 12h3M19 12h3M5 5l2 2M17 17l2 2M19 5l-2 2M7 17l-2 2"/>'),grid:D('<rect x="3" y="3" width="7" height="7" rx="1.5"/><rect x="14" y="3" width="7" height="7" rx="1.5"/><rect x="3" y="14" width="7" height="7" rx="1.5"/><rect x="14" y="14" width="7" height="7" rx="1.5"/>'),cpu:D('<rect x="6" y="6" width="12" height="12" rx="2"/><path d="M9 1v3M15 1v3M9 20v3M15 20v3M1 9h3M1 15h3M20 9h3M20 15h3"/>'),pulse:D('<path d="M3 12h4l2 6 4-14 2 8h6"/>'),server:D('<rect x="3" y="4" width="18" height="7" rx="2"/><rect x="3" y="13" width="18" height="7" rx="2"/><path d="M7 7.5h.01M7 16.5h.01"/>'),book:D('<path d="M4 5a2 2 0 0 1 2-2h13v16H6a2 2 0 0 0-2 2z"/><path d="M19 19H6a2 2 0 0 0-2 2"/>'),help:D('<circle cx="12" cy="12" r="9"/><path d="M9.5 9.2a2.5 2.5 0 0 1 4.8 1c0 1.7-2.3 2-2.3 3.4"/><path d="M12 17h.01"/>'),settings:D('<circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.6 1.6 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.6 1.6 0 0 0-2.7 1.1V21a2 2 0 1 1-4 0v-.1A1.6 1.6 0 0 0 6.6 19l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1a1.6 1.6 0 0 0-1.1-2.7H2a2 2 0 1 1 0-4h.1A1.6 1.6 0 0 0 4 6.6l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1A1.6 1.6 0 0 0 9 4.6V4a2 2 0 1 1 4 0v.1A1.6 1.6 0 0 0 17.4 6l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.6 1.6 0 0 0 1.1 2.7H21a2 2 0 1 1 0 4h-.1a1.6 1.6 0 0 0-1.5 1z"/>'),swap:D('<path d="M7 4 3 8l4 4"/><path d="M3 8h12a4 4 0 0 1 0 8h-1"/><path d="m17 20 4-4-4-4"/>'),monitor:D('<rect x="3" y="4" width="18" height="12" rx="2"/><path d="M8 20h8M12 16v4"/>'),layers:D('<path d="m12 2 9 5-9 5-9-5z"/><path d="m3 12 9 5 9-5M3 17l9 5 9-5"/>'),alert:D('<path d="M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z"/><path d="M12 9v4M12 17h.01"/>'),gauge:D('<path d="M12 14 16 9"/><circle cx="12" cy="13" r="9"/><path d="M12 4v2M21 13h-2M5 13H3"/>'),search:D('<circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/>'),compass:D('<circle cx="12" cy="12" r="10"/><polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"/>'),code:D('<polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/>'),eye:D('<path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z"/><circle cx="12" cy="12" r="3"/>'),refresh:D('<path d="M3 12a9 9 0 0 1 15-6.7L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-15 6.7L3 16"/><path d="M3 21v-5h5"/>'),file:D('<path d="M14 3H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 3v5h5"/><path d="M9 13h6M9 17h5"/>'),database:D('<ellipse cx="12" cy="5" rx="8" ry="3"/><path d="M4 5v6c0 1.7 3.6 3 8 3s8-1.3 8-3V5"/><path d="M4 11v6c0 1.7 3.6 3 8 3s8-1.3 8-3v-6"/>'),thermo:D('<path d="M14 14.76V5a2 2 0 0 0-4 0v9.76a4 4 0 1 0 4 0z"/>'),shield:D('<path d="M12 3l8 4v5c0 5-3.5 8-8 9-4.5-1-8-4-8-9V7z"/><path d="m9 12 2 2 4-4"/>'),info:D('<circle cx="12" cy="12" r="9"/><path d="M12 16v-4M12 8h.01"/>'),chevron:D('<path d="m9 6 6 6-6 6"/>'),bolt:D('<path d="M13 2 3 14h7l-1 8 10-12h-7z"/>'),x:D('<path d="M18 6 6 18M6 6l12 12"/>'),check:D('<path d="M20 6 9 17l-5-5"/>'),download:D('<path d="M12 3v12M7 10l5 5 5-5"/><path d="M5 21h14"/>'),clock:D('<circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/>')};function nt(e){return Pa[e]||""}function Jn(e){return`<span class="info-dot" tabindex="0" title="${g(e)}" aria-label="${g(e)}">${Pa.info}</span>`}function rt(e){if(!e&&e!==0)return"";const t=e/1024/1024/1024;return t>=1?t.toFixed(1)+" GB":Math.round(e/1024/1024)+" MB"}function Ee({title:e,body:t,confirmLabel:n="Bestätigen",cancelLabel:i="Abbrechen",danger:s=!1}){return new Promise(a=>{const r=document.createElement("div");r.className="modal-overlay",r.innerHTML=`<div class="modal-card" role="dialog" aria-modal="true">
<h3>${g(e)}</h3>
<p>${t}</p>
<div class="modal-actions">
<button data-x="0">${g(i)}</button>
<button class="${s?"danger":"primary"}" data-x="1">${g(n)}</button>
</div></div>`;const o=c=>{r.remove(),a(c)};r.addEventListener("click",c=>{if(c.target===r)return o(!1);const u=c.target.closest("[data-x]");u&&o(u.getAttribute("data-x")==="1")}),document.body.appendChild(r),r.querySelector('[data-x="1"]').focus()})}function Oa({title:e,body:t="",placeholder:n="",password:i=!1,confirmLabel:s="Weiter",danger:a=!1}){return new Promise(r=>{const o=document.createElement("div");o.className="modal-overlay",o.innerHTML=`<div class="modal-card" role="dialog" aria-modal="true">
<h3>${g(e)}</h3>
${t?`<p>${t}</p>`:""}
<input type="${i?"password":"text"}" placeholder="${g(n)}" autocomplete="off" style="margin-bottom:18px">
<div class="modal-actions">
<button data-x="0">Abbrechen</button>
<button class="${a?"danger":"primary"}" data-x="1">${g(s)}</button>
</div></div>`;const c=o.querySelector("input"),u=p=>{o.remove(),r(p)};o.addEventListener("click",p=>{if(p.target===o)return u(null);const v=p.target.closest("[data-x]");v&&u(v.getAttribute("data-x")==="1"?c.value||"":null)}),c.addEventListener("keydown",p=>{p.key==="Enter"&&u(c.value||""),p.key==="Escape"&&u(null)}),document.body.appendChild(o),c.focus()})}function Hl(e="overview"){const t=bs(".nav-item[data-view]:not(.disabled)"),n=bs(".view[data-view]"),i=new Set(n.map(a=>a.dataset.view));function s(a){i.has(a)||(a=e),n.forEach(r=>r.hidden=r.dataset.view!==a),t.forEach(r=>r.classList.toggle("active",r.dataset.view===a)),location.hash!=="#/"+a&&(location.hash="#/"+a)}return t.forEach(a=>a.addEventListener("click",r=>{r.preventDefault(),s(a.dataset.view)})),window.addEventListener("hashchange",()=>s(location.hash.replace("#/",""))),s(location.hash.replace("#/","")||e),{show:s}}let ys=ee(null);const Rl={get value(){return M(ys)},set(e){V(ys,e,!0)}};let xs=ee(Qe([]));const Fl={get value(){return M(xs)},set(e){V(xs,e||[],!0)}},Nl="5";var Fs;typeof window<"u"&&((Fs=window.__svelte??(window.__svelte={})).v??(Fs.v=new Set)).add(Nl);const Il=[["Dein erster Workflow — in 3 Schritten",`
<ol class="tut-steps">
<li><b>Modell holen:</b> Tab <b>Cookbook</b> → wähle deinen Anwendungsfall (z.B. „Coden") →
<b>Komplettes Setup installieren</b>. Der Download läuft im Tab <b>Aktivität</b>.</li>
<li><b>Verbinden:</b> Tab <b>Verbinden</b> → Basis-URL kopieren → in deinem Tool (z.B. OpenCode)
als „OpenAI-kompatibel" einfügen. <b>Verbindung testen</b> bestätigt, dass es läuft.</li>
<li><b>Arbeiten:</b> Im Tool das Modell (z.B. <code>coder</code>) wählen und loslegen. Das passende
Modell wird <b>automatisch geladen</b> — du musst nichts starten.</li>
</ol>`],["Wie leere ich den Kontext? Machen die Tools das selbst?",`
<p><b>Kurz: meistens ja, automatisch.</b> Der Kontext (das „Gedächtnis") gilt pro Unterhaltung.
Startest du im Tool einen <b>neuen Chat / eine neue Session</b>, ist der Kontext wieder leer —
das Tool verwaltet das Fenster für dich.</p>
<p>Du musst nur selten eingreifen: wird ein Gespräch sehr lang, fang einen neuen an. <b>Wichtig:</b>
„Grafikspeicher leeren" (Tab Server) ist etwas anderes — das wirft das <i>Modell</i> aus dem Speicher,
nicht den Gesprächsverlauf.</p>`],["Was passiert, wenn der Kontext volläuft?",`
<p>Ist das Kontextfenster voll, passiert je nach Tool eins von dreien: das Modell <b>vergisst den
Anfang</b> (älteste Nachrichten fallen raus), das Tool <b>kürzt automatisch</b>, oder du bekommst
einen Fehler wie „context length exceeded".</p>
<p><b>So gehst du vor:</b></p>
<ol class="tut-steps">
<li><b>Neuen Chat starten</b> — der einfachste Reset, Kontext ist wieder leer.</li>
<li><b>Zusammenfassen lassen:</b> „Fasse unseren Stand kurz zusammen", dann im neuen Chat einfügen.</li>
<li><b>Kontext vergrößern:</b> Tab <b>Modelle</b> → <b>Konfigurieren</b> → wir zeigen das Optimum
für deine Hardware (mehr Kontext = mehr Speicherbedarf).</li>
</ol>`],["Was ist ein Agent — und wann brauche ich einen?",`
<p>Ein nacktes Modell <b>schreibt nur Text zurück</b>. Ein <b>Agent</b> ist ein Programm drumherum,
das das Modell <b>handeln</b> lässt: Dateien lesen und ändern, Befehle ausführen, im Web suchen —
Schritt für Schritt in einer Schleife, bis die Aufgabe erledigt ist.</p>
<p><b>Wann lohnt sich was?</b></p>
<ul class="tut-steps" style="list-style:disc">
<li><b>Fragen, Texte, Erklärungen, Brainstorming</b> → kein Agent nötig, eine Chat-Oberfläche
wie <b>OpenWebUI</b> reicht völlig.</li>
<li><b>Coden über mehrere Dateien, Befehle ausführen, recherchieren + umsetzen</b>
→ <b>Agent</b> (OpenCode, Cline, Continue).</li>
</ul>
<p><b>Gut zu wissen:</b> Diese Agenten <b>laufen lokal auf deinem PC</b> — du brauchst
<b>keinen</b> Cloud-Dienst.</p>`],["Was sind Skills — und wie installiere ich sie?",`
<p>Ein <b>Skill</b> ist <b>verpacktes Können</b>: eine kurze Anleitung, die dem Agenten beibringt,
eine wiederkehrende Aufgabe jedes Mal so zu erledigen, wie <i>du</i> es willst.</p>
<p><b>Skill vs. MCP:</b> <b>MCP</b> gibt dem Agenten neue <b>Werkzeuge</b>. <b>Skills</b> geben
ihm <b>Know-how</b>. Kurz: <b>Werkzeuge = MCP, Anleitungen = Skills.</b></p>
<p><b>Installieren:</b> meist nur eine Datei ablegen — kein Build, kein Neustart:</p>
<ol class="tut-steps">
<li><b>Pro Projekt:</b> in den Projektordner (z.B. <code>AGENTS.md</code>, <code>.clinerules/</code>).</li>
<li><b>Global:</b> in den Konfig-Ordner des Tools — gilt überall.</li>
</ol>`],["MCP — deinem Agenten echte Werkzeuge geben",`
<p><b>MCP</b> (Model Context Protocol) ist ein einheitlicher „Stecker", über den ein Agent zusätzliche
<b>Werkzeuge</b> bekommt: das Web durchsuchen, Dateien lesen, eine Datenbank abfragen.</p>
<p>Du fügst in deinem Agenten einen „MCP-Server" hinzu (eine Zeile in der Konfiguration je Werkzeug).
Danach entscheidet der Agent selbst, wann er das Werkzeug einsetzt.</p>
<ul class="tut-steps" style="list-style:disc">
<li><b>Faustregel:</b> Fehlt dem Agenten eine <b>Fähigkeit</b> → MCP. Soll er etwas nur
<b>besser machen</b> → Skill.</li>
</ul>`],["Auto-Swap — wie das Laden funktioniert",`
<p>llama-swap lädt automatisch das Modell, das gerade angefragt wird, und entlädt es nach einer
Leerlaufzeit wieder. <b>Es läuft immer nur eines gleichzeitig.</b></p>
<p>Du richtest beliebig viele Modelle ein und wählst im Tool das passende —
das Laden/Entladen passiert im Hintergrund, ohne dass du etwas tun musst.</p>`],["Die empfohlenen Tools optimal nutzen",`
<ul class="tut-steps" style="list-style:disc">
<li><b>OpenCode:</b> Autonomes Coden im Terminal/Editor — ideal für „bau mir Feature X".</li>
<li><b>Cline:</b> Dasselbe als VS-Code-Erweiterung, mit Bestätigung vor jeder Aktion.</li>
<li><b>OpenWebUI:</b> Klassische Chat-Oberfläche für Fragen/Texte.</li>
</ul>
<p><b>Tipp:</b> starkes Modell (<code>coder</code>) für schwere Aufgaben, schnelles
(<code>scout</code>) für einfache — du wählst es einfach im Tool aus.</p>`]],Gl=[["LLM / Modell","Die KI selbst — versteht und schreibt Text (wie ChatGPT, nur lokal auf deinem PC). Ein Modell ist eine konkrete Datei davon, oft auf etwas spezialisiert (Code, Bilder, Chat)."],["GGUF","Das lokal lauffähige Dateiformat. Unsere Engine lädt nur GGUF — Repos ohne GGUF kann sie nicht nutzen."],["Quantisierung (Q4_K_M)","Verkleinert ein Modell (16-Bit → 4-Bit), damit es in den Speicher passt — bei kaum Qualitätsverlust. Q4_K_M ist der beliebte Sweetspot."],["Kontextfenster","Das Kurzzeitgedächtnis: wie viel Text sich das Modell gleichzeitig merkt. Größer = mehr Überblick, mehr Speicher, etwas langsamer."],["Auto-Swap","llama-swap lädt/entlädt Modelle automatisch — immer nur eins gleichzeitig. Du managst nichts."],["Agent","Ein Programm (OpenCode, Cline, Continue), das das Modell handeln lässt — Dateien lesen/ändern, Befehle ausführen, planen, im Loop bis die Aufgabe erledigt ist."],["MCP","Model Context Protocol — der Anschluss, über den ein Agent zusätzliche Werkzeuge bekommt (Web, Dateien, Datenbank). MCP = Werkzeuge."],["Skills","Verpackte Anleitung für wiederkehrende Aufgaben — der Agent liest sie und macht es jedes Mal wie du willst. Skills = Anleitungen."],["Rules / Commands","Die konkrete Form von Skills je Tool: AGENTS.md (OpenCode), .clinerules (Cline), Rules/Prompts (Continue)."]];var Kl=be('<details class="guide-acc"><summary> </summary> <div class="acc-body"></div></details>'),ql=be('<div class="concept"><h4> </h4> <p> </p></div>'),Ul=be('<div class="pagehead"><div><h1>Guide für Einsteiger</h1> <div class="sub">Praktische Workflows + die Local-LLM-Welt in Klartext — ohne Vorwissen.</div></div></div> <div class="card-h"><h3>Tutorials &amp; Workflows</h3></div> <div class="card" style="padding:0;overflow:hidden"></div> <div class="card-h" style="margin-top:8px"><h3>Konzepte kurz erklärt</h3></div> <div class="concept-grid"></div>',1);function jl(e){var t=Ul(),n=J(pa(t),4);Wn(n,21,()=>Il,Vn,(s,a,r)=>{var o=rs(()=>ss(M(a),2));let c=()=>M(o)[0],u=()=>M(o)[1];var p=Kl();p.open=r===0;var v=R(p),f=R(v),m=J(v,2);Sl(m,u,!0),ot(()=>ye(f,c())),ce(s,p)});var i=J(n,4);Wn(i,21,()=>Gl,Vn,(s,a)=>{var r=rs(()=>ss(M(a),2));let o=()=>M(r)[0],c=()=>M(r)[1];var u=ql(),p=R(u),v=R(p),f=J(p,2),m=R(f);ot(()=>{ye(v,o()),ye(m,c())}),ce(s,u)}),ce(e,t)}var Vl=be('<div class="li" style="align-items:flex-start"><div class="li-main"><div class="flex items-center gap-2" style="flex-wrap:wrap"><span class="li-id" style="font-family:var(--sans);font-weight:500"> </span> <span> </span></div> <div class="li-sub"> </div></div> <button class="primary">Installieren</button></div>'),Wl=be('<div class="card" style="margin-bottom:18px;border-color:rgba(45,212,191,.25)"><div class="card-h"><h3>Für dich: Upgrades</h3> <span class="meta"> </span></div> <div class="card-sub">Neuere Modelle, die ein installiertes ersetzen können.</div> <div class="list"></div></div>'),Jl=be('<div class="empty" style="text-align:center;padding:40px">Lade News… (erstes Laden kann kurz dauern)</div>'),Ql=be('<div class="alert err" style="margin:0"> </div>'),Yl=be('<div class="empty-c"><div class="e-t">Keine News geladen</div> <div class="e-s">Die Quellen sind gerade nicht erreichbar — später nochmal probieren.</div></div>'),Zl=be('<span class="news-rel">für dich</span>'),Xl=be('<a target="_blank" rel="noopener"><div class="news-meta"><span class="news-src"> </span> <!> <span class="news-date"> </span></div> <div class="news-title"> </div></a>'),eo=be('<div class="news-grid"></div>'),to=be('<div class="pagehead"><div><h1>News</h1> <div class="sub">Aktuelles aus der Local-LLM-Welt — aus kuratierten Quellen.</div></div> <button class="ghost">Aktualisieren</button></div> <!> <!>',1);function no(e,t){Ws(t,!0);let n=ee(Qe([])),i=ee(Qe([])),s=ee(!0),a=ee("");const r=k=>k==="perfect"?"ok":k==="marginal"?"warn":"bad";function o(k){const A=Math.max(0,Date.now()/1e3-k);return A<60?A+"s":A<3600?Math.floor(A/60)+"m":A<86400?Math.floor(A/3600)+"h":Math.floor(A/86400)+"d"}async function c(){V(s,!0),V(a,"");try{V(n,(await $("/api/news")).items||[],!0)}catch(k){V(a,k.message||"Fehler beim Laden",!0)}finally{V(s,!1)}}async function u(){try{V(i,(await $("/api/cookbook/upgrades")).upgrades||[],!0)}catch{V(i,[],!0)}}async function p(k,A){var G;A.disabled=!0,A.textContent="Starte…";try{await $("/api/cookbook/install-model",{method:"POST",body:JSON.stringify({repo:k.repo,role:k.role,params_b:k.params_b,quant:k.quant,hf_token:_n()})}),(G=document.querySelector(".nav-item[data-view='activity']"))==null||G.dispatchEvent(new MouseEvent("click"))}catch(O){A.disabled=!1,A.textContent="Installieren",alert("Fehler: "+O.message)}}function v(){c(),u()}zl(()=>{c(),u()});var f=to(),m=pa(f),h=J(R(m),2),b=J(m,2);{var C=k=>{var A=Wl(),G=R(A),O=J(R(G),2),Wt=R(O),Ke=J(G,4);Wn(Ke,21,()=>M(i),Vn,($n,Be)=>{var En=Vl(),Jt=R(En),Tn=R(Jt),Cn=R(Tn),si=R(Cn),Ln=J(Cn,2),ai=R(Ln),st=J(Tn,2),ri=R(st),nr=J(Jt,2);ot(li=>{ye(si,M(Be).name),ms(Ln,1,`fit-badge ${li??""}`),ye(ai,M(Be).fit.text),ye(ri,`Ersetzt dein „${M(Be).old??""}". ${M(Be).why??""}`)},[()=>r(M(Be).fit.level)]),fs("click",nr,li=>p(M(Be),li.currentTarget)),ce($n,En)}),ot(()=>ye(Wt,M(i).length)),ce(k,A)};pi(b,k=>{M(i).length&&k(C)})}var L=J(b,2);{var z=k=>{var A=Jl();ce(k,A)},j=k=>{var A=Ql(),G=R(A);ot(()=>ye(G,M(a))),ce(k,A)},oe=k=>{var A=Yl();ce(k,A)},Oe=k=>{var A=eo();Wn(A,21,()=>M(n),Vn,(G,O,Wt)=>{var Ke=Xl();ms(Ke,1,`news-card${Wt===0?" featured":""}`);var $n=R(Ke),Be=R($n),En=R(Be),Jt=J(Be,2);{var Tn=st=>{var ri=Zl();ce(st,ri)};pi(Jt,st=>{M(O).relevant&&st(Tn)})}var Cn=J(Jt,2),si=R(Cn),Ln=J($n,2),ai=R(Ln);ot(st=>{Cl(Ke,"href",M(O).link),ye(En,M(O).source),ye(si,st),ye(ai,M(O).title)},[()=>M(O).ts?o(M(O).ts):""]),ce(G,Ke)}),ce(k,A)};pi(L,k=>{M(s)?k(z):M(a)?k(j,1):M(n).length?k(Oe,-1):k(oe,2)})}fs("click",h,v),ce(e,f),Js()}ml(["click"]);let Ge=null,ne=null;const Ba=new Set(["running","ready","loading","starting"]);function ji(){return(Ge==null?void 0:Ge.models)||[]}function Ha(){return ji().find(e=>Ba.has(e.state))}function io(e){var t;(t=document.querySelector(`.nav-item[data-view="${e}"]`))==null||t.click()}async function so(){if(await Ee({title:"Speicher freigeben?",body:"Alle aktuell geladenen Modelle werden aus dem Grafikspeicher geworfen. Beim nächsten Aufruf lädt das jeweilige Modell einfach neu — es geht nichts verloren.",confirmLabel:"Speicher freigeben"}))try{await $("/api/unload",{method:"POST"}),w("Speicher freigegeben."),setTimeout(()=>document.dispatchEvent(new Event("mc:refresh")),600)}catch(t){w(t.message,!0)}}window.mcOv={go:io,freeMemory:so};function Vi(){let e="Verbinde…",t="";if(Ge){const n=ji().length,i=Ha();Ge.swap_ok?ne&&ne.ram.percent>=90?(e="Achtung: Speicher wird knapp.",t=`Arbeitsspeicher bei ${Math.round(ne.ram.percent)} % — eventuell Speicher freigeben.`):(e="Alles läuft rund.",t=`${n} ${n===1?"Modell":"Modelle"} bereit · ${i?`${i.name}" geladen`:"keins geladen"} · keine Warnungen.`):(e="LLM-Engine offline",t="Der llama-swap-Dienst antwortet gerade nicht.")}l("#ov-hero").innerHTML=`<div class="pagehead"><div>
<h1>${g(e)}</h1><div class="sub">${g(t)}</div></div></div>`}function Mt(e,t,n,i="",s=""){return`<div class="tile"><div class="t-l">${e}</div>
<div class="t-v ${i}">${t}</div><div class="t-s ${s}">${n}</div></div>`}function ao(e){return e==null?"":e<55?"kühl & gesund":e<72?"normal":"läuft heiß"}function Wi(){const e=Ha(),t=Ge==null?void 0:Ge.swap_ok;let n=Mt("LLM-Engine",t?"Online":"Offline","llama-swap",t?"ok":"bad"),i=Mt("Aktives Modell",e?g(e.name):"Keins",e?"im Grafikspeicher":"nichts geladen"),s,a;if(ne){const r=ne.gpu_temp??ne.cpu.temp;s=Mt("GPU-Temperatur",r!=null?`${Math.round(r)}°`:"",ao(r),"",r!=null&&r<72?"ok":"");const o=ne.ram.total-ne.ram.used;a=Mt("Freier Speicher",`${(o/1024**3).toFixed(0)}<small> GB</small>`,`von ${(ne.ram.total/1024**3).toFixed(0)} GB`)}else s=Mt("GPU-Temperatur","","messe…"),a=Mt("Freier Speicher","","messe…");l("#ov-tiles").innerHTML=n+i+s+a}function hi(e,t){const n=Math.max(0,Math.min(100,t||0)),i=n>=90?"bad":n>=75?"warn":"";return`<div class="meter"><div class="meter-h"><span class="mk">${e}</span>
<span class="mv">${Math.round(n)} %</span></div>
<div class="bar ${i}"><i style="width:${Math.max(2,n)}%"></i></div></div>`}function Ra(){const e=`<div class="card-h"><h3>System-Gesundheit</h3></div>
<div class="card-sub">So ausgelastet ist dein Mini-PC gerade.</div>`;if(!ne){l("#ov-health").innerHTML=e+'<div class="empty">Warte auf Messwerte…</div>';return}let t=0;const n=ne.gpu;n&&n.vram.total+n.gtt.total>0&&(t=(n.vram.used+n.gtt.used)/(n.vram.total+n.gtt.total)*100),l("#ov-health").innerHTML=e+hi("Prozessor (CPU)",ne.cpu.percent)+hi("Arbeitsspeicher (RAM)",ne.ram.percent)+hi("Grafikspeicher (VRAM)",t)}function vi(e,t,n,i,s){return`<button class="qa" onclick="${s}">
<span class="qa-ic ${t}">${nt(e)}</span>
<span class="qa-main"><span class="qa-t">${n}</span><span class="qa-s">${i}</span></span>
<span class="qa-arrow">${nt("chevron")}</span></button>`}function Fa(){l("#ov-quickstart").innerHTML=`<div class="card-h"><h3>Schnellstart</h3></div>
<div class="card-sub">Die häufigsten Aufgaben — ein Klick.</div>`+vi("search","teal","Modell finden","Passend zu deiner Hardware","window.mcOv.go('cookbook')")+vi("refresh","amber","Speicher freigeben","Modelle entladen · fragt vorher nach","window.mcOv.freeMemory()")+vi("file","blue","Logs ansehen","Live mitlesen, was läuft","window.mcOv.go('server')")}function ro(e){return e?e.includes("Bild")?'<span class="tag img">Bild</span>':e.includes("Code")?'<span class="tag code">Code</span>':'<span class="tag text">Text</span>':""}function lo(e){var r,o;const t=e.state==="downloading",n=Ba.has(e.state),i=e.state==="loading"||e.state==="starting"||t?"load":n?"on":"";let s;t?s=`↓ Download${e.download_progress!=null?` ${Math.round(e.download_progress)}%`:""}`:s=n?e.state==="loading"?"lädt…":"geladen":"bereit";const a=(r=e.meta)!=null&&r.filename?`<div class="li-sub mono-sm">${g(e.meta.filename)}</div>`:"";return`<div class="li"><span class="li-dot ${i}"></span>
<div class="li-main">
<div class="flex items-center gap-2"><span class="li-id">${g(e.name)}</span>${ro((o=e.meta)==null?void 0:o.caps)}</div>${a}</div>
<span class="li-meta" style="white-space:nowrap">${g(s)}</span></div>`}async function oo(){const e=l("#ov-news");if(!e)return;const t=`<div class="card-h"><h3>Top-News</h3><span class="meta" style="cursor:pointer" onclick="window.mcOv.go('news')">Alle →</span></div>`;e.innerHTML=t+'<div class="empty" style="text-align:center;padding:20px">Lade…</div>';try{const n=((await $("/api/news")).items||[]).slice(0,4);e.innerHTML=t+(n.length?`<div class="list">${n.map(i=>`<a class="li" href="${g(i.link)}" target="_blank" rel="noopener" style="text-decoration:none;color:inherit">
<div class="li-main"><div style="font-size:13px;line-height:1.4">${g(i.title)}</div>
<div class="li-sub">${g(i.source)}</div></div></a>`).join("")}</div>`:'<div class="empty">Keine News.</div>')}catch{e.innerHTML=t+'<div class="empty">News gerade nicht ladbar.</div>'}}function Na(){const e=ji();l("#ov-stack").innerHTML=`<div class="card-h"><h3>Dein Stack</h3><span class="meta">${e.length?e.length+" konfiguriert":""}</span></div>`+(e.length?`<div class="list">${e.map(lo).join("")}</div>`:`<div class="empty-c"><div class="e-t">Noch keine Modelle</div>
<div class="e-s">Hol dir unter „Cookbook" ein Modell, das auf deine Hardware passt.</div></div>`)}function co(){Vi(),Wi(),Ra(),Fa(),Na()}function uo(){Fa(),co(),oo()}function fo(e){Ge=e,Vi(),Wi(),Na()}function po(e){ne=e,Vi(),Wi(),Ra()}const ho={id:"overview",mount:uo,onStatus:fo,onSystem:po};let _s=[];const vo="Kontext = das Kurzzeitgedächtnis des Modells. Größer = merkt sich mehr (längere Dateien/Chats), braucht aber mehr Speicher und wird etwas langsamer.",mo="Die Rolle ist ein zusätzlicher, sprechender Name (z.B. coder). Du kannst in deinen Tools entweder den echten Modellnamen ODER die Rolle angeben — beides führt zum selben Modell.",go=[{id:"coder",label:"Coder",desc:"Programmieren & Code"},{id:"vision",label:"Vision",desc:"Bilder verstehen"},{id:"scout",label:"Scout",desc:"Schneller Allrounder"},{id:"reviewer",label:"Reviewer",desc:"Code/Texte prüfen"},{id:"manager",label:"Manager",desc:"Planen & koordinieren"}];let je=[];function kn(){document.dispatchEvent(new Event("mc:refresh"))}function bo(e){return Bl(e.state,e.download_progress)}function wo(e){return e?`<span class="tag" style="background:rgba(45,212,191,.14);color:var(--accent);border-color:rgba(45,212,191,.3)">${g(e)}</span>`:""}function yo(e){return`<div class="li-sub mono-sm" style="margin-top:3px;display:flex;align-items:center;gap:6px;flex-wrap:wrap">
<span class="text-mut">API-Name:</span>
${(e.api_ids&&e.api_ids.length?e.api_ids:[e.name]).map(n=>`<code style="cursor:pointer" data-action="copy" data-name="${g(n)}" title="Klicken zum Kopieren">${g(n)}</code>`).join('<span class="text-mut">·</span>')}
</div>`}function xo(e){return e!=null&&e.length?e.map(t=>t==="Code"?'<span class="tag code">Code</span>':t==="Bild"?'<span class="tag img">Bild</span>':'<span class="tag text">Text</span>').join(" "):""}function _o(e){if(!e)return"";const t=e.quant||"?",n=e.ctx?Math.round(e.ctx/1024)+"K":"?",i=e.size_bytes?(e.size_bytes/1024**3).toFixed(1)+" GB":"?";return`<span class="mono-sm">${g(t)} · ${n} · ${i}</span>`}function ko(){l("#m-head").innerHTML=`<div class="pagehead"><div>
<h1>Modelle</h1>
<div class="sub">Deine konfigurierten Modelle — testen, Kontext anpassen oder aus dem Speicher werfen.</div></div></div>`,l("#m-chat").innerHTML=`
<div class="card-h"><h3>Schnelltest</h3></div>
<div class="card-sub">Schreib eine Nachricht — das gewählte Modell wird automatisch geweckt.</div>
<label>Modell</label>
<select id="chat-model"></select>
<label>Nachricht</label>
<textarea id="chat-msg" placeholder="z.B. „Erklär mir kurz, was du kannst."></textarea>
<button class="primary" id="chat-btn">Senden</button>
<div id="chat-reply" class="reply" style="display:none"></div>`,l("#m-table").innerHTML=`
<div class="card-h"><h3>Modelle &amp; Ports</h3><span class="meta" id="m-count"></span></div>
<div class="card-sub">Modelle laden automatisch, sobald eine Anfrage kommt — du musst nichts manuell starten.</div>
<table>
<thead><tr><th>Modell</th><th>Kann</th><th>Details</th><th>Status</th><th>Port</th><th style="text-align:right">Aktionen</th></tr></thead>
<tbody id="models"></tbody>
</table>
<div id="models-empty" class="empty-c" style="display:none">
<div class="e-t">Noch keine Modelle konfiguriert</div>
<div class="e-s">Hol dir unter „Cookbook" ein passendes Modell.</div>
</div>
<div id="cfg-modal" class="modal-overlay" style="display:none">
<div class="modal-card">
<button id="cfg-close" class="ghost" style="position:absolute;top:14px;right:14px">Schließen</button>
<h3>Modell konfigurieren</h3>
<p class="mono-sm" id="cfg-model-name" style="margin:-4px 0 16px"></p>
<label>Kontext-Größe (Tokens) ${Jn(vo)}</label>
<input id="cfg-ctx" type="number" value="8192">
<div class="tile" id="cfg-rec" style="display:none;margin:8px 0 10px;justify-content:space-between;align-items:center" >
<div style="flex:1"><div style="font-size:13px">Empfohlen für deine Hardware</div>
<div class="hint" id="cfg-rec-note" style="margin:4px 0 0"></div></div>
<button class="ghost" id="cfg-rec-apply">Optimal übernehmen</button>
</div>
<div class="hint" style="margin-bottom:14px">Es läuft immer nur <b>ein</b> Modell gleichzeitig — ein größerer Kontext hier beeinflusst deine anderen Modelle nicht.</div>
<button class="primary" id="cfg-save" style="width:100%;margin-top:6px">Speichern</button>
</div>
</div>
<div id="role-modal" class="modal-overlay" style="display:none">
<div class="modal-card">
<button id="role-close" class="ghost" style="position:absolute;top:14px;right:14px">Schließen</button>
<h3>Rolle festlegen ${Jn(mo)}</h3>
<p class="mono-sm" id="role-model-name" style="margin:-4px 0 16px"></p>
<div class="hint" style="margin-bottom:10px">Wähle eine Rolle als zweiten, sprechenden Namen. In deinen Tools funktionieren danach <b>beide</b>: der echte Modellname und die Rolle.</div>
<div id="role-chips" class="flex gap-2" style="flex-wrap:wrap;margin-bottom:12px"></div>
<label>Eigene Rolle (optional)</label>
<input id="role-custom" placeholder="z.B. uebersetzer">
<div class="btn-row" style="margin-top:14px;display:flex;gap:8px">
<button class="ghost" id="role-clear" style="flex:1">Rolle entfernen</button>
<button class="primary" id="role-save" style="flex:2">Speichern</button>
</div>
</div>
</div>`,l("#chat-btn").addEventListener("click",Ao),l("#cfg-close").addEventListener("click",()=>l("#cfg-modal").style.display="none"),l("#cfg-modal").addEventListener("click",e=>{e.target.id==="cfg-modal"&&(l("#cfg-modal").style.display="none")}),l("#cfg-save").addEventListener("click",Co),l("#role-close").addEventListener("click",()=>l("#role-modal").style.display="none"),l("#role-modal").addEventListener("click",e=>{e.target.id==="role-modal"&&(l("#role-modal").style.display="none")}),l("#role-save").addEventListener("click",()=>Pi(l("#role-custom").value.trim().toLowerCase())),l("#role-clear").addEventListener("click",()=>Pi("")),l("#m-table").addEventListener("click",e=>{var s,a;const t=e.target.closest("[data-action]");if(!t)return;const n=t.getAttribute("data-name"),i=t.getAttribute("data-action");n&&(i==="cfg"?To(n):i==="role"?Mo(n):i==="unload"?Lo(n):i==="del"?Eo(n):i==="copy"?((s=navigator.clipboard)==null||s.writeText(n),w("Kopiert: "+n)):i==="assign"&&(w("Lade im Cookbook ein Modell und setze den Alias auf: "+n),(a=document.querySelector(".nav-item[data-view='cookbook']"))==null||a.click()))})}let Di=null;function Mo(e){Di=e;const t=je.find(n=>n.name===e);l("#role-model-name").textContent=e,l("#role-custom").value="",l("#role-chips").innerHTML=go.map(n=>`<button class="${(t==null?void 0:t.role)===n.id?"primary":"ghost"}" data-rolepick="${n.id}" title="${g(n.desc)}" style="border-radius:999px">${g(n.label)}</button>`).join(""),l("#role-chips").querySelectorAll("[data-rolepick]").forEach(n=>n.addEventListener("click",()=>Pi(n.getAttribute("data-rolepick")))),l("#role-modal").style.display="flex"}async function Pi(e){if(Di)try{await $("/api/set_role",{method:"POST",body:JSON.stringify({alias:Di,role:e})}),w(e?`Rolle gesetzt: ${e}`:"Rolle entfernt."),l("#role-modal").style.display="none",kn()}catch(t){w(t.message,!0)}}function Ia(){const e=l("#models");if(!e)return;l("#models-empty").style.display=je.length?"none":"flex",l("#m-count").textContent=je.length?je.length+" konfiguriert":"";const t=l("#chat-model"),n=t.value;t.innerHTML="",e.innerHTML=je.map(i=>{var a,r;if(i.incomplete)return`<tr style="opacity:.9">
<td class="mid" style="font-weight:500">${g(i.name)}<div class="li-sub mono-sm" style="color:var(--warn)">kein Modell hinterlegt</div></td>
<td>—</td>
<td><span class="mono-sm text-mut">leere Rolle</span></td>
<td><span class="badge">leer</span></td>
<td class="port">—</td>
<td style="text-align:right;white-space:nowrap">
<button class="ghost" data-action="assign" data-name="${g(i.name)}">Modell zuweisen</button>
<button class="ghost del" data-action="del" data-name="${g(i.name)}">Löschen</button>
</td></tr>`;const s=(a=i.meta)!=null&&a.filename?`<div class="li-sub mono-sm">${g(i.meta.filename)}</div>`:"";return`<tr>
<td class="mid">
<div style="font-weight:500;display:flex;align-items:center;gap:7px;flex-wrap:wrap">${g(i.name)}${wo(i.role)}</div>
${s}${yo(i)}</td>
<td>${xo((r=i.meta)==null?void 0:r.caps)}</td>
<td>${_o(i.meta)}</td>
<td>${bo(i)}</td>
<td class="port">${i.port??"auto"}</td>
<td style="text-align:right;white-space:nowrap">
<button class="ghost" data-action="role" data-name="${g(i.name)}">Rolle</button>
<button class="ghost" data-action="cfg" data-name="${g(i.name)}">Konfigurieren</button>
<button class="ghost" data-action="unload" data-name="${g(i.name)}">Entladen</button>
<button class="ghost del" data-action="del" data-name="${g(i.name)}">Löschen</button>
</td></tr>`}).join("");for(const i of je)i.incomplete||t.insertAdjacentHTML("beforeend",`<option>${g(i.name)}</option>`);n&&(t.value=n)}function So(e){je=(e==null?void 0:e.models)||[],Ia()}function $o(e){_s=e||[],_s.some(n=>(n.state==="running"||n.state==="queued")&&/^download\b/i.test(n.label))&&Ia()}async function Eo(e){if(await Ee({title:`${e}" wirklich löschen?`,body:"Das Modell wird aus der Konfiguration ausgetragen und seine Dateien werden von der Festplatte gelöscht, um Speicher freizugeben. <b>Das lässt sich nicht rückgängig machen</b> — später brauchst du dafür einen neuen Download.",confirmLabel:"Endgültig löschen",danger:!0}))try{const n=await $("/api/delete_model",{method:"POST",body:JSON.stringify({alias:e})});w(n.note||"Gelöscht: "+e),setTimeout(kn,600)}catch(n){w(n.message,!0)}}function To(e){var s,a,r,o,c;const t=je.find(u=>u.name===e);if(!t)return;l("#cfg-model-name").textContent=t.name,l("#cfg-ctx").value=((s=t.meta)==null?void 0:s.ctx)||8192;const n=(a=t.meta)==null?void 0:a.optimal_ctx,i=l("#cfg-rec");if(n){const u=((r=t.meta)==null?void 0:r.ctx)||0,p=(o=t.meta)==null?void 0:o.peak_ram_gb,v=(c=t.meta)==null?void 0:c.peak_ram_optimal_gb;l("#cfg-rec-note").innerHTML=`Optimal ~${Math.round(n/1024)}k → ~${v} GB Spitzenbedarf.<br>Aktuell ~${Math.round(u/1024)}k → ~${p} GB.`,l("#cfg-rec-apply").onclick=()=>{l("#cfg-ctx").value=n},i.style.display="flex"}else i.style.display="none";l("#cfg-modal").style.display="flex"}async function Co(){const e=l("#cfg-model-name").textContent,t=parseInt(l("#cfg-ctx").value)||8192;l("#cfg-save").disabled=!0;try{await $("/api/update_model",{method:"POST",body:JSON.stringify({alias:e,ctx:t})}),w("Gespeichert — aktiv beim nächsten Modell-Start."),l("#cfg-modal").style.display="none",kn()}catch(n){w(n.message,!0)}l("#cfg-save").disabled=!1}async function Lo(e){if(await Ee({title:`${e}" entladen?`,body:"Das Modell wird aus dem Grafikspeicher geworfen und lädt beim nächsten Aufruf automatisch neu.",confirmLabel:"Entladen"}))try{await $("/api/unload?model="+encodeURIComponent(e),{method:"POST"}),w("Entladen: "+e),setTimeout(kn,600)}catch(t){w(t.message,!0)}}async function Ao(){const e=l("#chat-model").value,t=l("#chat-msg").value.trim();if(!e)return w("Kein Modell vorhanden.",!0);if(!t)return;const n=l("#chat-btn");n.disabled=!0,n.textContent="…";const i=l("#chat-reply");i.style.display="block",i.textContent="(wecke Modell, kann beim Laden kurz dauern…)";try{const s=await $("/api/chat",{method:"POST",body:JSON.stringify({model:e,message:t})});i.textContent=s.reply}catch(s){i.textContent="Fehler: "+s.message}n.disabled=!1,n.textContent="Senden",kn()}const zo={id:"models",mount:ko,onStatus:So,onJobs:$o},dn=new Set;let lt=[],B=null;function Ji(e){dn.add(e),Vt()}const Ue={cpu:[],ram:[],gpu:[]},Do=60;function Po(e){return e==="done"?'<span class="badge b-run">fertig</span>':e==="failed"?'<span class="badge b-err">fehler</span>':e==="canceled"?'<span class="badge">abgebrochen</span>':'<span class="badge b-load">läuft…</span>'}function Oo(e){return e==="done"?"on":e==="failed"||e==="canceled"?"":"load"}function Bo(e){if(e.state!=="running")return null;if(typeof e.progress=="number")return Math.min(100,e.progress);const n=((e.log||[])[e.log.length-1]||"").match(/(\d+(?:\.\d+)?)\s*%/);return n?Math.min(100,parseFloat(n[1])):null}function Ho(e){return e==null||e<0?"":e>=90?`noch ~${Math.round(e/60)} min`:`noch ~${Math.max(1,Math.round(e))} s`}async function Ro(e){try{await $(`/api/jobs/${e}/cancel`,{method:"POST"}),w("Abbruch angefordert…"),Vt()}catch(t){w(t.message,!0)}}async function Fo(e){try{await $(`/api/jobs/${e}`,{method:"DELETE"}),Vt()}catch(t){w(t.message,!0)}}async function No(){try{const e=await $("/api/jobs/clear",{method:"POST"});w(`${e.removed} Einträge entfernt.`),Vt()}catch(e){w(e.message,!0)}}function mi(e,t,n){return`<div class="tile"><div class="t-l">${e}</div><div class="t-v">${t}</div><div class="t-s">${n}</div></div>`}function gi(e,t){return'<div style="display:flex;align-items:flex-end;gap:2px;height:38px;margin-top:10px">'+e.map(n=>`<div style="width:4px;background:var(${t});opacity:.55;height:${Math.max(2,n)}%;border-radius:2px"></div>`).join("")+"</div>"}function ks(){const e=B==null?void 0:B.gpu;return e&&e.vram.total+e.gtt.total>0?(e.vram.used+e.gtt.used)/(e.vram.total+e.gtt.total)*100:0}function Ga(){if(!B)return;Ue.cpu.push(B.cpu.percent),Ue.ram.push(B.ram.percent),Ue.gpu.push(ks());for(const s of["cpu","ram","gpu"])Ue[s].length>Do&&Ue[s].shift();const e=l("#act-kpis");e&&(e.innerHTML=mi("Prozessor (CPU)",`${Math.round(B.cpu.percent)}<small> %</small>`,B.cpu.temp!=null?`${Math.round(B.cpu.temp)}° CPU-Temp`:"Auslastung")+mi("Arbeitsspeicher",`${Math.round(B.ram.percent)}<small> %</small>`,`${rt(B.ram.used)} / ${rt(B.ram.total)}`)+mi("Grafikspeicher",`${Math.round(ks())}<small> %</small>`,B.gpu_temp!=null?`${Math.round(B.gpu_temp)}° GPU-Temp`:"VRAM + GTT"));const t=B.gpu,n=t&&t.vram.total+t.gtt.total>0?`${rt(t.vram.used+t.gtt.used)} / ${rt(t.vram.total+t.gtt.total)}`:"",i=l("#act-sys");i&&(i.innerHTML=`
<div class="card-h"><h3>System-Metriken (Bosgame)</h3></div>
<div class="card-sub">Live-Auslastung deines Mini-PCs, alle 0,5 Sekunden.</div>
<div class="kv" style="margin-bottom:6px">
<div class="kv-row"><span class="kv-k">Arbeitsspeicher (RAM)</span><span class="kv-v">${rt(B.ram.used)} / ${rt(B.ram.total)}</span></div>
<div class="kv-row"><span class="kv-k">Grafikspeicher (VRAM + GTT)</span><span class="kv-v">${n}</span></div>
<div class="kv-row"><span class="kv-k">Speicherplatz (Disk)</span><span class="kv-v">${Math.round(B.disk.percent)} % belegt</span></div>
<div class="kv-row"><span class="kv-k">Temperatur (GPU / CPU)</span><span class="kv-v">${B.gpu_temp!=null?Math.round(B.gpu_temp)+"°":""} / ${B.cpu.temp!=null?Math.round(B.cpu.temp)+"°":""}</span></div>
</div>
<div class="grid grid-3" style="margin-top:14px">
<div><div class="meta text-xs">CPU-Verlauf</div>${gi(Ue.cpu,"--accent")}</div>
<div><div class="meta text-xs">RAM-Verlauf</div>${gi(Ue.ram,"--purple")}</div>
<div><div class="meta text-xs">VRAM-Verlauf</div>${gi(Ue.gpu,"--on")}</div>
</div>`)}function Io(){l("#act-head").innerHTML=`<div class="pagehead"><div>
<h1>Aktivität</h1>
<div class="sub">Live-Auslastung und laufende Aufgaben (Downloads, Updates) mit Protokoll.</div></div></div>`,l("#v-activity").innerHTML=`
<div class="card-h"><h3>Hintergrund-Aufgaben</h3><span class="meta" id="job-count"></span>
<button class="ghost" id="jobs-clear" style="margin-left:auto;display:none;padding:4px 11px;font-size:12px">Verlauf leeren</button></div>
<div class="card-sub">Downloads &amp; Updates erscheinen hier mit Live-Protokoll — zum Aufklappen klicken.</div>
<div id="jobs"></div>
<div id="jobs-empty" class="empty-c"><div class="e-t">Gerade nichts los.</div><div class="e-s">Alles ruhig — keine laufenden Aufgaben.</div></div>`,l("#v-activity").addEventListener("click",e=>{if(e.target.closest("#jobs-clear")){No();return}const t=e.target.closest("[data-cancel]");if(t){e.stopPropagation(),Ro(t.getAttribute("data-cancel"));return}const n=e.target.closest("[data-del]");if(n){e.stopPropagation(),Fo(n.getAttribute("data-del"));return}const i=e.target.closest(".job-h");if(!i)return;const s=i.getAttribute("data-id");dn.has(s)?dn.delete(s):dn.add(s),Vt()}),B&&Ga()}function Vt(){const e=l("#jobs");if(!e)return;l("#jobs-empty").style.display=lt.length?"none":"flex";const t=lt.filter(s=>s.state==="failed").length,n=lt.filter(s=>s.state!=="running"&&s.state!=="queued").length;l("#job-count").textContent=lt.length?t?t+" Fehler":lt.length+" gesamt":"";const i=l("#jobs-clear");i&&(i.style.display=n?"":"none"),e.innerHTML=lt.map(s=>{const a=dn.has(s.id)?`<div class="log">${g((s.log||[]).join(`
`))}</div>`:"",r=Bo(s),o=r!=null?`<div class="bar" style="margin-top:8px"><i style="width:${r}%"></i></div>`:"",c=s.state==="running"?Ho(s.eta_s):"",u=s.state==="running"&&s.rate_bps?rt(s.rate_bps)+"/s":"",p=[c,u].filter(Boolean).join(" · "),v=r!=null?`<span class="mono-sm" style="margin-left:auto">${Math.round(r)} %${p?` · ${p}`:""}</span>`:"",f=s.state==="running"?`<button class="ghost" data-cancel="${g(s.id)}" style="${r!=null?"":"margin-left:auto;"}margin-right:2px;padding:2px 9px;font-size:12px">Abbrechen</button>`:`<button class="ghost" data-del="${g(s.id)}" title="Aus Verlauf entfernen" style="margin-left:auto;margin-right:2px;padding:2px 9px;font-size:14px;line-height:1">×</button>`;return`<div class="job"><div class="job-h" data-id="${g(s.id)}">
<span class="li-dot ${Oo(s.state)}"></span><span class="mid">${g(s.label)}</span>${v}${f}${Po(s.state)}</div>${o}${a}</div>`}).join("")}function Go(e){lt=e||[],Vt()}function Ko(e){B=e,l("#act-sys")&&Ga()}const qo={id:"jobs",mount:Io,onJobs:Go,onSystem:Ko};function Qi(){document.dispatchEvent(new Event("mc:refresh"))}function at(e,t,n,i,s){return`<button class="qa${n==="red"?" qa-danger":""}" id="${e}">
<span class="qa-ic ${n}">${nt(t)}</span>
<span class="qa-main"><span class="qa-t">${i}</span><span class="qa-s">${s}</span></span>
<span class="qa-arrow">${nt("chevron")}</span></button>`}function Uo(){l("#wartung").outerHTML=`<div id="wartung" style="display:flex;flex-direction:column;gap:var(--sp-4)">
<div class="pagehead"><div>
<h1>Server &amp; Wartung</h1>
<div class="sub">Dienste steuern, Updates einspielen und live mitlesen — ganz ohne SSH oder Terminal.</div>
</div></div>
<div class="card" id="w-swap-card">
<div class="card-h"><h3>LLM-Engine (llama-swap)</h3>
<span class="chip" id="w-swap-state" style="margin-left:auto">prüfe…</span></div>
<div class="card-sub">Das Herzstück: llama-swap lädt bei jeder Anfrage automatisch das passende Modell und entlädt die anderen — es läuft immer nur <b>eines</b> gleichzeitig.</div>
<div class="kv" style="margin-bottom:6px">
<div class="kv-row"><span class="kv-k">Adresse (für deine Tools)</span><span class="kv-v mono-sm" id="w-swap-url">—</span></div>
<div class="kv-row"><span class="kv-k">Aktuell geladen</span><span class="kv-v" id="w-swap-loaded">—</span></div>
<div class="kv-row"><span class="kv-k">Konfigurierte Modelle</span><span class="kv-v" id="w-swap-count">—</span></div>
</div>
<div class="hint" style="margin:8px 0 12px"><b>Wie ansteuern?</b> In deinem Tool (Zed/OpenCode) die obige Adresse als OpenAI-Basis-URL eintragen und einen <b>Modellnamen oder eine Rolle</b> angeben (siehe „Verbinden"). Eine einzige Anfrage genügt — das Modell wird automatisch geweckt.</div>
<div class="btn-row" style="display:flex;align-items:center;gap:10px"><button class="ghost" id="w-swap-check">Verbindung prüfen</button><span id="w-swap-check-res" class="mono-sm"></span></div>
</div>
<div class="card">
<div class="card-h"><h3>Dienste &amp; Applikation</h3></div>
<div class="card-sub">Diese Aktionen sind harmlos und passwortlos — es geht nichts dabei verloren.</div>
${at("w-restart-swap","refresh","teal","LLM-Engine neustarten","Startet llama-swap neu. Geladene Modelle werden kurz entladen (~5 Sek), laden danach automatisch wieder.")}
${at("w-restart-mc","refresh","blue","Dashboard neustarten","Startet diese Oberfläche neu. Sie trennt kurz und verbindet automatisch wieder.")}
${at("w-self-update","download","teal","Mission Control aktualisieren","Holt die neueste Dashboard-Version aus Gitea und startet automatisch neu (~10 Sek).")}
${at("w-update","bolt","blue","LLM-Engine aktualisieren","Lädt die neueste llama.cpp-Version (ROCm) für deine GPU und installiert sie.")}
${at("w-unload","database","amber","Grafikspeicher leeren","Wirft alle aktuell geladenen Modelle aus dem VRAM. Fragt vorher nach.")}
</div>
<div class="card">
<div class="card-h"><h3>Betriebssystem (Bosgame)</h3></div>
<div class="card-sub">Tiefe Eingriffe — das Dashboard fragt einmalig nach deinem sudo-Passwort.</div>
${at("w-os-update","refresh","amber","OS-Updates installieren","Führt apt update &amp; upgrade aus. Kann ein paar Minuten dauern — Fortschritt in der Aktivität.")}
${at("w-reboot","bolt","red","Server neustarten (Reboot)","Bootet den ganzen Bosgame neu. Alles ist für ~1 Minute offline, auch dieses Dashboard.")}
</div>
<div class="card" id="w-update-card" style="display:none">
<div class="card-h"><h3>Aktueller Vorgang</h3>
<button class="ghost" id="w-update-cancel" style="margin-left:auto;display:none;padding:3px 12px">Abbrechen</button>
<span id="w-update-badge" style="margin-left:10px"></span></div>
<div class="card-sub" id="w-update-label">—</div>
<div id="w-update-bar" class="bar" style="display:none;margin-bottom:10px"><i style="width:0%"></i></div>
<div id="w-update-log" class="log" style="max-height:280px"></div>
</div>
<div class="card">
<div class="card-h"><h3>Live-Konsole</h3>
<select id="w-console-sel" style="margin:0 0 0 auto;width:240px">
<option value="llama-swap">LLM-Engine (llama-swap)</option>
<option value="mission-control">Dashboard (mission-control)</option>
<option value="system">System (ganzer Server)</option>
</select>
</div>
<div class="card-sub">Live mitlesen, was der Dienst gerade tut.</div>
<div id="w-console" class="console">Verbinde…</div>
</div>
</div>`,l("#w-restart-swap").addEventListener("click",()=>Ss("llama-swap","LLM-Engine neustarten?","Die Engine startet neu. Geladene Modelle werden kurz entladen (~5 Sekunden), laden danach automatisch wieder.")),l("#w-restart-mc").addEventListener("click",()=>Ss("mission-control","Dashboard neustarten?","Diese Oberfläche trennt sich kurz und verbindet automatisch wieder. Laufende Downloads laufen weiter.")),l("#w-self-update").addEventListener("click",Qo),l("#w-update").addEventListener("click",Zo),l("#w-unload").addEventListener("click",Jo),l("#w-os-update").addEventListener("click",Xo),l("#w-reboot").addEventListener("click",ed),l("#w-console-sel").addEventListener("change",Ms),l("#w-update-cancel").addEventListener("click",Wo),l("#w-swap-check").addEventListener("click",jo),Oi&&Ka(Oi),Ms()}let Oi=null;function Ka(e){const t=l("#w-swap-state");if(!t)return;const n=!!(e!=null&&e.swap_ok);t.textContent=n?"● erreichbar":"● offline",t.style.cssText="margin-left:auto;"+(n?"background:rgba(63,185,80,.12);border-color:rgba(63,185,80,.25);color:#7ee29a":"background:rgba(248,81,73,.12);border-color:rgba(248,81,73,.3);color:#ff9b95"),l("#w-swap-url").textContent=((e==null?void 0:e.swap_url)||"—")+"/v1";const i=(e==null?void 0:e.models)||[],s=i.find(r=>r.state==="running"||r.state==="loading");l("#w-swap-loaded").innerHTML=s?`<b>${g(s.name)}</b> <span class="text-mut">(${g(s.state)})</span>`:'<span class="text-mut">nichts geladen — lädt bei der nächsten Anfrage</span>';const a=i.filter(r=>!r.incomplete).length;l("#w-swap-count").textContent=a?`${a} bereit`:"keine"}async function jo(){const e=l("#w-swap-check-res");e.textContent="prüfe…",e.style.color="var(--mut)";try{const t=await $("/api/integration/test");t.ok?(e.style.color="#7ee29a",e.textContent=`✓ Engine antwortet — ${t.models.length} Modell(e): ${t.models.join(", ")}`):(e.style.color="#ff9b95",e.textContent="✗ keine Verbindung: "+t.error)}catch(t){e.style.color="#ff9b95",e.textContent="✗ "+t.message}}function Vo(e){Oi=e,Ka(e)}async function Wo(){if(Le&&await Ee({title:Le.label+" abbrechen?",body:"Der laufende Vorgang wird gestoppt. Bei einem Download bleibt eine unvollständige Datei zurück (kannst du später neu starten).",confirmLabel:"Abbrechen",danger:!0}))try{await $(`/api/jobs/${Le.id}/cancel`,{method:"POST"}),w("Abbruch angefordert…")}catch(e){w(e.message,!0)}}let St=null;function Ms(){St&&(St.close(),St=null);const e=l("#w-console-sel").value,t=l("#w-console");t.textContent="Verbinde mit "+e+`
`;const n=location.protocol==="https:"?"wss:":"ws:";St=new WebSocket(`${n}//${location.host}/api/logs/${e}?token=${encodeURIComponent(Da())}`),St.onmessage=i=>{t.textContent+=i.data,t.scrollTop=t.scrollHeight},St.onclose=()=>{t.textContent+=`
— Verbindung getrennt —`}}async function Ss(e,t,n){if(await Ee({title:t,body:n,confirmLabel:"Neustarten"}))try{await $(`/api/service/${e}/restart`,{method:"POST"}),w("Neustart ausgelöst: "+e),setTimeout(Qi,2e3)}catch(i){w(i.message,!0)}}async function Jo(){if(await Ee({title:"Grafikspeicher leeren?",body:"Alle geladenen Modelle werden entladen. Sie laden beim nächsten Aufruf automatisch neu — es geht nichts verloren.",confirmLabel:"Leeren"}))try{await $("/api/unload",{method:"POST"}),w("Grafikspeicher geleert."),setTimeout(Qi,600)}catch(e){w(e.message,!0)}}async function Qo(){if(await Ee({title:"Mission Control aktualisieren?",body:"Holt die neueste Dashboard-Version aus Gitea und startet automatisch neu. Die Seite trennt kurz und verbindet von selbst wieder (~10 Sek)."}))try{const e=await $("/api/self-update",{method:"POST"});w("Update läuft — Dashboard startet gleich neu."),Ji(e.job_id)}catch(e){w(e.message,!0)}}let Le=null;const $s=new Set;function qa(e,t){Le={id:e,label:t};const n=l("#w-update-card");n&&(n.style.display="",l("#w-update-label").textContent=t+" läuft…",l("#w-update-badge").innerHTML='<span class="badge b-load">läuft…</span>',l("#w-update-log").textContent="Starte…",n.scrollIntoView({behavior:"smooth",block:"nearest"}))}function Yo(e){if(!Le)return;const t=(e||[]).find(v=>v.id===Le.id),n=l("#w-update-card");if(!t||!n)return;n.style.display="";const i=l("#w-update-log");i&&(i.textContent=(t.log||[]).join(`
`),i.scrollTop=i.scrollHeight);const s=t.state==="done",a=t.state==="failed",r=t.state==="canceled",o=s||a||r,c=l("#w-update-badge");c&&(c.innerHTML=s?'<span class="badge b-run">✓ fertig</span>':a?'<span class="badge b-err">✗ fehlgeschlagen</span>':r?'<span class="badge">abgebrochen</span>':'<span class="badge b-load">läuft…</span>');let u=null;if(!o)if(typeof t.progress=="number")u=t.progress;else{const f=((t.log||[])[t.log.length-1]||"").match(/(\d+(?:\.\d+)?)\s*%/);f&&(u=parseFloat(f[1]))}const p=l("#w-update-bar");p&&(u!=null?(p.style.display="",p.querySelector("i").style.width=Math.min(100,u)+"%"):p.style.display="none"),l("#w-update-cancel").style.display=o?"none":"",o&&(l("#w-update-label").textContent=Le.label+(s?" — erfolgreich abgeschlossen.":r?" — abgebrochen.":" — fehlgeschlagen (siehe Protokoll)."),$s.has(t.id)||($s.add(t.id),w(s?"✓ "+Le.label+" abgeschlossen.":r?Le.label+" abgebrochen.":"✗ "+Le.label+" fehlgeschlagen.",a),s&&setTimeout(Qi,800)))}async function Zo(){if(await Ee({title:"LLM-Engine aktualisieren?",body:"Lädt die neueste llama.cpp-ROCm-Version und installiert sie. Die Engine ist während des Updates kurz nicht erreichbar."}))try{const e=await $("/api/update",{method:"POST"});w("LLM-Engine-Update läuft."),Ji(e.job_id),qa(e.job_id,"LLM-Engine-Update")}catch(e){w(e.message,!0)}}async function Xo(){if(!await Ee({title:"OS-Updates installieren?",body:"Führt <code>apt update &amp; upgrade</code> aus. Das kann ein paar Minuten dauern; der Fortschritt erscheint in der Aktivität."}))return;const e=await Oa({title:"sudo-Passwort",body:"Für die System-Updates wird einmalig dein sudo-Passwort gebraucht.",placeholder:"sudo-Passwort",password:!0,confirmLabel:"Installieren"});if(e)try{const t=await $("/api/os-update",{method:"POST",body:JSON.stringify({password:e})});w("OS-Update gestartet."),Ji(t.job_id),qa(t.job_id,"OS-Update")}catch(t){w(t.message,!0)}}async function ed(){if(!await Ee({title:"Server wirklich neu starten?",body:"Der ganze Bosgame startet physisch neu. Alles ist für ~1 Minute offline — auch dieses Dashboard.",confirmLabel:"Reboot",danger:!0}))return;const e=await Oa({title:"sudo-Passwort",body:"Für den Reboot wird einmalig dein sudo-Passwort gebraucht.",placeholder:"sudo-Passwort",password:!0,confirmLabel:"Jetzt neustarten",danger:!0});if(e)try{await $("/api/reboot",{method:"POST",body:JSON.stringify({password:e})}),w("Reboot ausgelöst — bis gleich.")}catch(t){w(t.message,!0)}}const td={id:"server",mount:Uo,onJobs:Yo,onStatus:Vo},nd="Kontext = das Kurzzeitgedächtnis des Modells. Größer = merkt sich mehr, braucht aber mehr Speicher und wird etwas langsamer.",Ua="GGUF ist das lokal lauffähige Dateiformat. Unsere Engine lädt nur GGUF — Repos ohne GGUF-Datei kann sie nicht nutzen.",id="MoE (Mixture of Experts): viele Parameter fürs Wissen, aber pro Wort ist nur ein kleiner Teil aktiv → fast große-Modell-Qualität bei hohem Tempo. Ideal für deine APU.",sd={vision:"Bilder",coder:"Coden",reasoning:"Logik",agent:"Agenten & Tools",scout:"Allrounder",reviewer:"Review",manager:"Manager"},ad=[{label:"Bilder",kw:["-vl-","-vl","vision","llava","multimodal","-mm-","pixtral"]},{label:"Coden",kw:["coder","-code-","code-","codestral","starcoder"]},{label:"Logik",kw:["-r1","deepseek-r1","reasoning","qwq","magistral","-think","thinking","-o1"]},{label:"Agenten & Tools",kw:["hermes","-tool","command-r","watt","-fc-","function"]}];function ja(e){const t=(e||"").toLowerCase();for(const n of ad)if(n.kw.some(i=>t.includes(i)))return n.label;return"Allrounder"}function rd(e=""){const t=e.toLowerCase();return/\d+x\d+(\.\d+)?b/.test(t)||new RegExp("(?<![a-z])a\\d+(\\.\\d+)?b\\b").test(t)||t.includes("mixtral")||/\bmoe\b/.test(t)}function ld(e=""){const t=e.toLowerCase().match(new RegExp("(?<![a-z])a(\\d+(?:\\.\\d+)?)b\\b"));return t?t[1]:null}function Yi(e){if(!rd(e))return"";const t=ld(e);return`<span class="chip" title="${g(id)}">MoE${t?` · ~${t}B aktiv`:""}</span>`}function Va(e){return e?`<span class="chip">${g(e)}</span>`:""}const od=[{id:"",label:"Alle"},{id:"coder",label:"Coder"},{id:"scout",label:"Scout"},{id:"vision",label:"Vision"},{id:"manager",label:"Manager"},{id:"reviewer",label:"Reviewer"}];let nn=null,sn=[],Ae=null,Dt="",Mn=[],Wa=null,cn=[];const dd={perfect:0,marginal:1,too_tight:2},Sn=e=>e==="perfect"?"ok":e==="marginal"?"warn":"bad",cd=e=>e==="perfect"?"Passt locker":e==="marginal"?"Wird knapp":"Zu groß";function ud(){const e=l(".view[data-view='cookbook']");e.innerHTML=`
<div class="pagehead"><div>
<h1>Modell-Cookbook</h1>
<div class="sub">Wofür willst du es nutzen? Wir empfehlen das passende Setup für deine Hardware.</div>
</div></div>
<div class="card-h" style="align-items:center"><h3>Wofür möchtest du es nutzen?</h3>
<span class="chip" id="cb-hw" style="margin-left:auto">deine Hardware</span>
<button class="ghost" id="cb-new-open" style="margin-left:10px">+ Eigenes Setup</button></div>
<div class="grid grid-3" id="cb-recipes">
<div class="empty" style="grid-column:1/-1;text-align:center">Lade Setups…</div>
</div>
<div class="card-h" style="align-items:center;margin-top:20px"><h3>Aktuell beste Modelle für dein System</h3>
<span class="chip" id="cb-disc-when" style="margin-left:auto"></span>
<button class="ghost" id="cb-disc-refresh" style="margin-left:10px">Aktualisieren</button></div>
<div class="card-sub" style="margin:-6px 0 10px">Automatisch aus vertrauenswürdigen Quellen (HuggingFace) — laufend aktuell, gefiltert auf das, was auf deine Hardware passt.</div>
<div id="cb-discover"><div class="empty" style="text-align:center">Lade aktuelle Empfehlungen…</div></div>
<details class="guide-acc card" style="padding:0;overflow:hidden;margin-top:18px">
<summary>Profi-Modus: HuggingFace direkt durchsuchen</summary>
<div class="acc-body">
<div class="flex gap-3" style="margin-bottom:8px">
<input id="cb-search" placeholder="Suchen oder HuggingFace-Link/Repo einfügen (z.B. unsloth/MiniMax-M3-GGUF)…" style="margin:0;flex:1">
<button class="primary" id="cb-btn-search" style="white-space:nowrap">Suchen</button>
</div>
<div class="flex gap-2 items-center" style="flex-wrap:wrap">
<div id="cb-filters" class="flex gap-2" style="flex-wrap:wrap;flex:1"></div>
<select id="cb-sort" style="width:auto;margin:0;padding:7px 10px;font-family:var(--sans)">
<option value="downloads">Beliebteste Downloads</option>
<option value="likes">Am beliebtesten (Likes)</option>
<option value="lastModified">Zuletzt aktualisiert</option>
<option value="trendingScore">Im Trend</option>
</select>
</div>
<div class="legend" style="margin:14px 0">
<span><i style="background:var(--on)"></i>passt locker</span>
<span><i style="background:var(--warn)"></i>läuft, aber knapp</span>
<span><i style="background:var(--err)"></i>zu groß für deinen Speicher</span>
</div>
<div class="hint" style="margin:-6px 0 14px">Es werden nur Modelle im GGUF-Format ${Jn(Ua)} gezeigt — nur die laufen lokal.</div>
<div class="grid grid-3" id="cb-grid"></div>
</div>
</details>
<div id="cb-recipe-modal" class="modal-overlay" style="display:none">
<div class="modal-card" style="max-width:580px">
<button id="cb-r-close" class="ghost" style="position:absolute;top:14px;right:14px">Schließen</button>
<h3 id="cb-r-title">Setup</h3>
<p class="text-mut text-sm" id="cb-r-desc" style="margin:-4px 0 16px"></p>
<div id="cb-r-models"></div>
<div class="hint" id="cb-r-note" style="margin-top:12px"></div>
<button class="primary" id="cb-r-install" style="width:100%;margin-top:8px">Komplettes Setup installieren</button>
<div class="hint" style="margin-top:8px">Lädt alle Modelle herunter und pflegt sie mit optimalem Kontext ein. Fortschritt in der Aktivität.</div>
</div>
</div>
<div id="cb-new-modal" class="modal-overlay" style="display:none">
<div class="modal-card" style="max-width:640px">
<button id="cb-new-close" class="ghost" style="position:absolute;top:14px;right:14px">Schließen</button>
<h3 id="cb-new-modal-title">Eigenes Setup erstellen</h3>
<p class="text-mut text-sm" style="margin:-4px 0 16px">Stell dir aus beliebigen Modellen ein eigenes Setup zusammen — es erscheint danach mit Hardware-Ampel hier im Cookbook.</p>
<label>Titel</label>
<input id="cb-new-title" placeholder="z.B. Mein Schreib-Stack">
<label>Kurzbeschreibung (optional)</label>
<input id="cb-new-desc" placeholder="Wofür ist dieses Setup gut?">
<label style="margin-top:10px">Modelle</label>
<div id="cb-new-models"></div>
<button class="ghost" id="cb-new-add" style="margin-top:8px">+ Modell hinzufügen</button>
<div class="hint" style="margin-top:10px">Die <b>Repo-ID</b> findest du über die <b>Profi-Suche</b> weiter unten (z.B. <code>unsloth/Qwen3-8B-GGUF</code>). Die Modellgröße erkennen wir automatisch aus dem Namen.</div>
<button class="primary" id="cb-new-save" style="width:100%;margin-top:14px">Setup speichern</button>
</div>
</div>
<div id="cb-modal" class="modal-overlay" style="display:none">
<div class="modal-card" style="max-width:560px">
<button id="cb-modal-close" class="ghost" style="position:absolute;top:14px;right:14px">Schließen</button>
<h3 id="cb-m-title">Modell</h3>
<p class="mono-sm" id="cb-m-repo" style="margin:-4px 0 16px">repo/name</p>
<label>Quantisierung (GGUF-Datei) wählen</label>
<select id="cb-m-files"></select>
<div class="hint" id="cb-m-loading" style="display:none">Lade Dateien von HuggingFace…</div>
<div class="row" style="margin-top:4px">
<div><label>Rolle (optional)</label><input id="cb-m-alias" placeholder="z.B. coder, vision, scout"></div>
<div><label>Kontext-Größe ${Jn(nd)}</label><input id="cb-m-ctx" type="number" value="8192"></div>
</div>
<div class="hint" id="cb-m-ctx-rec" style="margin:-6px 0 14px"></div>
<div id="cb-m-fit" class="tile" style="display:flex;justify-content:space-between;align-items:center;margin:8px 0 18px">
<div><div style="font-size:13px">Ressourcen-Check</div>
<div class="hint" id="cb-m-fit-text" style="margin:4px 0 0">Berechne…</div></div>
<span id="cb-m-fit-badge"></span>
</div>
<button class="primary" id="cb-m-download" style="width:100%">Herunterladen &amp; Einpflegen</button>
</div>
</div>`,Ja(),l("#cb-btn-search").addEventListener("click",Rn),l("#cb-search").addEventListener("keydown",t=>{t.key==="Enter"&&Rn()}),l("#cb-sort").addEventListener("change",()=>{(l("#cb-search").value.trim()||Dt)&&Rn()}),l("#cb-modal-close").addEventListener("click",()=>l("#cb-modal").style.display="none"),l("#cb-modal").addEventListener("click",t=>{t.target.id==="cb-modal"&&(l("#cb-modal").style.display="none")}),l("#cb-m-download").addEventListener("click",Td),l("#cb-m-files").addEventListener("change",Sd),l("#cb-m-ctx").addEventListener("change",Cs),window.cbSetCtx=t=>{l("#cb-m-ctx").value=t,Cs()},l("#cb-r-close").addEventListener("click",()=>l("#cb-recipe-modal").style.display="none"),l("#cb-recipe-modal").addEventListener("click",t=>{t.target.id==="cb-recipe-modal"&&(l("#cb-recipe-modal").style.display="none")}),l("#cb-new-open").addEventListener("click",gd),l("#cb-new-close").addEventListener("click",()=>l("#cb-new-modal").style.display="none"),l("#cb-new-modal").addEventListener("click",t=>{t.target.id==="cb-new-modal"&&(l("#cb-new-modal").style.display="none")}),l("#cb-new-add").addEventListener("click",()=>l("#cb-new-models").insertAdjacentHTML("beforeend",Xi())),l("#cb-new-models").addEventListener("click",t=>{const n=t.target.closest(".cb-nm-del");n&&n.closest(".cb-nm-row").remove()}),l("#cb-new-save").addEventListener("click",wd),l("#cb-disc-refresh").addEventListener("click",()=>Es(!0)),l("#cb-discover").addEventListener("click",t=>{const n=t.target.closest("[data-inst]");n&&vd(n.getAttribute("data-inst"),n.getAttribute("data-role"),n.getAttribute("data-pb"),n)}),Qa(),Zi(),Es()}function fd(e){const t=Date.now()/1e3-e;return t<90?"gerade eben":t<3600?`vor ${Math.round(t/60)} min`:t<86400?`vor ${Math.round(t/3600)} h`:`vor ${Math.round(t/86400)} Tg.`}async function Es(e=!1){const t=l("#cb-discover"),n=l("#cb-disc-when"),i=l("#cb-disc-refresh");e&&(i.disabled=!0,i.textContent="Suche…",t.innerHTML='<div class="empty" style="text-align:center">Frage Quellen ab…</div>');try{const s=await $("/api/cookbook/discover"+(e?"?force=true":""));n&&(n.textContent=s.updated?`aktualisiert ${fd(s.updated)}`:""),pd(s)}catch(s){t.innerHTML=`<div class="alert warn" style="margin:0"><span class="a-dot"></span><span>Empfehlungen nicht ladbar: ${g(s.message)}</span></div>`}i.disabled=!1,i.textContent="Aktualisieren"}function pd(e){const t=l("#cb-discover"),n=e.categories||[];if(!n.length){t.innerHTML='<div class="empty" style="text-align:center">Keine passenden Modelle gefunden.</div>';return}t.innerHTML=n.map(i=>`
<div style="margin-bottom:8px">
<div class="flex items-center gap-2" style="margin:6px 0 8px"><span class="text-accent">${nt(i.icon)}</span>
<h4 style="margin:0;font-size:13.5px;font-weight:600">${g(i.title)}</h4></div>
<div class="grid grid-3">${i.models.map(s=>hd(s,i.recommended)).join("")}</div>
</div>`).join("")}function hd(e,t){const n=(e.requirements||[]).map(o=>`<div class="li-sub" style="color:var(--warn);margin-top:3px">⚠ ${g(o)}</div>`).join(""),i=t&&e.repo===t,s=i?'<div class="cb-best-tag">★ Beste Wahl für dein System</div>':"",a=`<div class="flex gap-2" style="flex-wrap:wrap;margin-top:7px">${Va(sd[e.role]||ja(e.repo))}${Yi(e.repo)}</div>`,r=e.installed?`<span class="fit-badge ok" title="bereits eingerichtet als ${g(e.installed)}">✓ installiert</span>`:`<button class="primary" data-inst="${g(e.repo)}" data-role="${g(e.role)}" data-pb="${e.params_b}"
style="padding:6px 12px;font-size:12.5px">Installieren</button>`;return`<div class="card${i?" res-best":""}" style="display:flex;flex-direction:column;position:relative">
${s}
<div class="flex justify-between" style="align-items:flex-start;gap:8px">
<div style="min-width:0"><h3 style="margin:0;font-size:14px;font-weight:500;word-break:break-word">${g(e.name)}</h3>
<div class="text-xs text-mut" style="margin-top:3px">${g(e.author)} · ${e.params_b}B</div></div>
<span class="fit-badge ${Sn(e.fit.level)}">${g(e.fit.text)}</span>
</div>
${a}
<div class="mono-sm text-mut" style="margin-top:8px;font-size:11.5px">${Ya(e.fit)} · ⬇ ${(e.downloads||0).toLocaleString()}</div>
${n}
<div style="flex:1;min-height:8px"></div>
<div class="flex justify-end" style="margin-top:10px">${r}</div>
</div>`}async function vd(e,t,n,i){var s;i.disabled=!0,i.textContent="Starte…";try{await $("/api/cookbook/install-model",{method:"POST",body:JSON.stringify({repo:e,role:t,params_b:parseFloat(n)||7,quant:"Q4_K_M",hf_token:_n()})}),w("Download gestartet — siehe Aktivität."),(s=document.querySelector(".nav-item[data-view='activity']"))==null||s.click()}catch(a){w("Fehler: "+a.message,!0),i.disabled=!1,i.textContent="Installieren"}}async function Zi(){try{const e=await $("/api/cookbook/recipes");Mn=e.recipes||[],Wa=e.recommended_id||null,md()}catch(e){l("#cb-recipes").innerHTML=`<div class="alert err" style="grid-column:1/-1">Setups nicht ladbar: ${g(e.message)}</div>`}}function md(){l("#cb-recipes").innerHTML=Mn.map(e=>{const t=e.id===Wa,n=t?'<div class="cb-best-tag">★ Beste Wahl für dein System</div>':e.user?'<div class="cb-best-tag" style="background:var(--act);color:#fff">Dein Setup</div>':"",i=e.user?`
<span class="cb-editr" data-editr="${g(e.id)}" title="Setup bearbeiten"
style="position:absolute;top:10px;right:36px;color:var(--accent);cursor:pointer;font-size:14px;line-height:1">✎</span>
<span class="cb-delr" data-delr="${g(e.id)}" title="Setup löschen"
style="position:absolute;top:9px;right:12px;color:var(--err);cursor:pointer;font-size:18px;line-height:1">×</span>`:"";return`<button class="card-btn${t?" cb-best":""}" data-recipe="${g(e.id)}" style="position:relative">
${i}${n}
<div class="flex justify-between items-center">
<span class="flex items-center gap-2"><span class="text-accent">${nt(e.icon)}</span>
<h3 style="margin:0;font-size:15px">${g(e.title)}</h3></span>
<span class="fit-badge ${Sn(e.fit_level)}">${cd(e.fit_level)}</span>
</div>
<p>${g(e.desc)}</p>
<div class="text-xs text-mut">${e.models.length} Modell${e.models.length>1?"e":""} im Setup</div>
</button>`}).join(""),l("#cb-recipes").querySelectorAll("[data-recipe]").forEach(e=>e.addEventListener("click",()=>xd(e.getAttribute("data-recipe")))),l("#cb-recipes").querySelectorAll("[data-delr]").forEach(e=>e.addEventListener("click",t=>{t.stopPropagation(),yd(e.getAttribute("data-delr"))})),l("#cb-recipes").querySelectorAll("[data-editr]").forEach(e=>e.addEventListener("click",t=>{t.stopPropagation(),bd(e.getAttribute("data-editr"))}))}function Xi(){return`<div class="cb-nm-row flex gap-2" style="margin-bottom:8px;align-items:center">
<input class="cb-nm-repo" placeholder="Repo, z.B. unsloth/Qwen3-8B-GGUF" style="flex:2;margin:0">
<input class="cb-nm-role" placeholder="Rolle (z.B. coder)" style="flex:1;margin:0">
<select class="cb-nm-quant" style="width:auto;margin:0;font-family:var(--sans)">
<option>Q4_K_M</option><option>Q5_K_M</option><option>Q6_K</option><option>Q8_0</option><option>Q3_K_M</option>
</select>
<button class="ghost del cb-nm-del" title="Zeile entfernen" style="margin:0;padding:6px 10px">×</button>
</div>`}let Ct=null;function gd(){Ct=null,l("#cb-new-title").value="",l("#cb-new-desc").value="",l("#cb-new-models").innerHTML=Xi(),l("#cb-new-modal-title").textContent="Eigenes Setup erstellen",l("#cb-new-save").textContent="Setup speichern",l("#cb-new-modal").style.display="flex"}function bd(e){const t=Mn.find(n=>n.id===e);t&&(Ct=e,l("#cb-new-title").value=t.title,l("#cb-new-desc").value=t.desc||"",l("#cb-new-models").innerHTML=t.models.map(n=>{const i=document.createElement("div");i.innerHTML=Xi();const s=i.firstElementChild;s.querySelector(".cb-nm-repo").value=n.repo,s.querySelector(".cb-nm-role").value=n.role;const a=s.querySelector(".cb-nm-quant");return a&&[...a.options].forEach(r=>{r.value===n.quant&&(r.selected=!0)}),s.outerHTML}).join(""),l("#cb-new-modal-title").textContent="Setup bearbeiten",l("#cb-new-save").textContent="Änderungen speichern",l("#cb-new-modal").style.display="flex")}async function wd(){const e=l("#cb-new-title").value.trim();if(!e)return w("Bitte einen Titel angeben.",!0);const t=[...l("#cb-new-models").querySelectorAll(".cb-nm-row")].map(i=>({repo:i.querySelector(".cb-nm-repo").value.trim(),role:i.querySelector(".cb-nm-role").value.trim()||"modell",quant:i.querySelector(".cb-nm-quant").value})).filter(i=>i.repo);if(!t.length)return w("Mindestens ein Modell (Repo) angeben.",!0);const n=l("#cb-new-save");n.disabled=!0,n.textContent="Speichere…";try{const i=JSON.stringify({title:e,desc:l("#cb-new-desc").value.trim(),models:t});Ct?(await $("/api/cookbook/user-recipe/"+encodeURIComponent(Ct),{method:"PUT",body:i}),w("Setup aktualisiert.")):(await $("/api/cookbook/user-recipe",{method:"POST",body:i}),w("Setup gespeichert.")),Ct=null,l("#cb-new-modal").style.display="none",Zi()}catch(i){w("Fehler: "+i.message,!0)}n.disabled=!1,n.textContent=Ct?"Änderungen speichern":"Setup speichern"}async function yd(e){const t=Mn.find(n=>n.id===e);if(await Ee({title:`${t?t.title:e}" löschen?`,body:"Dein eigenes Setup wird aus dem Cookbook entfernt. Bereits installierte Modelle bleiben unangetastet.",confirmLabel:"Löschen",danger:!0}))try{await $("/api/cookbook/user-recipe/"+encodeURIComponent(e),{method:"DELETE"}),w("Setup gelöscht."),Zi()}catch(n){w(n.message,!0)}}function xd(e){const t=Mn.find(s=>s.id===e);if(!t)return;l("#cb-r-title").textContent=t.title,l("#cb-r-desc").textContent=t.desc,l("#cb-r-models").innerHTML=`<div class="list">${t.models.map(s=>`
<div class="li" style="align-items:flex-start">
<div class="li-main">
<div class="flex items-center gap-2" style="flex-wrap:wrap">
<span class="li-id">${g(s.name)}</span><span class="tag text">${g(s.role)}</span>${Yi(s.repo)}</div>
<div class="li-sub">${g(s.why)}</div>
<div class="li-sub mono-sm">~${s.fit.req_gb.toFixed(1)} GB · ~${Math.round(s.fit.tps)} Tok/s · optimal ~${Math.round(s.optimal_ctx/1024)}k Kontext</div>
</div>
<span class="fit-badge ${Sn(s.fit.level)}">${g(s.fit.text)}</span>
</div>`).join("")}</div>`;const n=Math.max(...t.models.map(s=>s.fit.req_gb));l("#cb-r-note").innerHTML=`Größter Spitzenbedarf: <b>~${n.toFixed(1)} GB</b>. Es läuft immer nur <b>ein</b> Modell gleichzeitig — das größte bestimmt, ob das Setup passt (kein Summieren).`;const i=l("#cb-r-install");i.className=t.fit_level==="too_tight"?"primary warn":"primary",i.textContent=t.fit_level==="too_tight"?"Trotzdem installieren (zu groß)":"Komplettes Setup installieren",i.onclick=()=>_d(t.id),l("#cb-recipe-modal").style.display="flex"}async function _d(e){var n;const t=l("#cb-r-install");t.disabled=!0,t.textContent="Starte…";try{const i=await $("/api/cookbook/install-recipe",{method:"POST",body:JSON.stringify({recipe_id:e,hf_token:_n()})});w(`Setup wird installiert (${i.count} Modelle) — siehe Aktivität.`),l("#cb-recipe-modal").style.display="none",(n=document.querySelector(".nav-item[data-view='activity']"))==null||n.click()}catch(i){w("Fehler: "+i.message,!0)}t.disabled=!1,t.textContent="Komplettes Setup installieren"}function Ja(){l("#cb-filters").innerHTML=od.map(e=>`<button class="${Dt===e.id?"primary":"ghost"}" data-f="${e.id}" style="border-radius:999px">${e.label}</button>`).join(""),l("#cb-filters").querySelectorAll("[data-f]").forEach(e=>e.addEventListener("click",()=>{Dt=e.getAttribute("data-f"),Ja(),Rn()}))}function Qa(){var t;const e=l("#cb-hw");e&&(t=nn==null?void 0:nn.ram)!=null&&t.total&&(e.innerHTML=`${nt("cpu")}${Math.round(nn.ram.total/1024**3)} GB Speicher`)}function Ya(e){return`~${e.req_gb.toFixed(1)} GB · ~${Math.round(e.tps)} Tok/s`}function kd(e){e=e.trim();const t=e.match(/huggingface\.co\/([^\s/]+\/[^\s/?#]+)/i);return t?t[1]:/^[\w.-]+\/[\w.-]+$/.test(e)?e:null}async function Rn(){var s;const e=l("#cb-search").value.trim(),t=kd(e);let n=e;if(Dt&&!t&&(n=n?n+" "+Dt:Dt),!n&&!t){l("#cb-grid").innerHTML="";return}const i=l("#cb-btn-search");i.disabled=!0,i.textContent="Lade…",l("#cb-grid").innerHTML='<div class="empty" style="grid-column:1/-1;text-align:center">Suche auf HuggingFace…</div>';try{if(t)sn=[{id:t,author:t.split("/")[0],downloads:0}],Ts(sn);else{const a=((s=l("#cb-sort"))==null?void 0:s.value)||"downloads",r=`https://huggingface.co/api/models?search=${encodeURIComponent(n)}&filter=gguf&sort=${encodeURIComponent(a)}&direction=-1&limit=40`;sn=await(await fetch(r)).json(),Ts(sn)}}catch(a){l("#cb-grid").innerHTML=`<div class="alert err" style="grid-column:1/-1">${g(a.message)}</div>`}i.disabled=!1,i.textContent="Suchen"}function Ts(e){const t=l("#cb-grid");if(cn=[],!(e!=null&&e.length)){t.innerHTML='<div class="empty" style="grid-column:1/-1;text-align:center">Keine GGUF-Modelle gefunden.</div>';return}t.innerHTML=e.map((n,i)=>`
<div class="card" style="display:flex;flex-direction:column;cursor:pointer" data-res="${i}">
<div class="flex justify-between" style="align-items:flex-start;gap:8px">
<div style="min-width:0"><h3 style="margin:0;font-size:14.5px;font-weight:500;word-break:break-word">${g(n.id.split("/").pop())}</h3>
<div class="text-xs text-mut" style="margin-top:3px">${g(n.author||"")}</div></div>
<span class="fit-badge warn" id="cb-b-${i}">prüfe…</span>
</div>
<div class="flex gap-2" style="flex-wrap:wrap;margin-top:7px">${Va(ja(n.id))}${Yi(n.id)}</div>
<div style="flex:1;margin-top:12px"></div>
<div class="flex justify-between items-center text-xs text-mut" style="border-top:1px solid var(--line);padding-top:11px">
<span class="mono-sm" id="cb-m-${i}">Hardware-Fit…</span>
<span class="mono-sm">⬇ ${(n.downloads||0).toLocaleString()}</span></div>
</div>`).join(""),t.querySelectorAll("[data-res]").forEach(n=>n.addEventListener("click",()=>Ed(+n.getAttribute("data-res")))),e.forEach((n,i)=>Md(i,n.id))}async function Md(e,t){var n;try{const i=await $("/api/cookbook/analyze",{method:"POST",body:JSON.stringify({repo_id:t,ctx:8192})}),s=l("#cb-b-"+e),a=l("#cb-m-"+e);if(!s||!a)return;if(!((n=i.files)!=null&&n.length)){s.className="fit-badge",s.style.cssText="background:rgba(139,151,165,.14);color:var(--mut)",s.title=Ua,s.textContent="kein GGUF",a.textContent="—",cn[e]=null,bi();return}let r=i.files.find(o=>{var c;return(c=o.quant)==null?void 0:c.includes("Q4_K_M")})||i.files[0];s.className="fit-badge "+Sn(r.fit.level),s.textContent=r.fit.text,a.textContent=Ya(r.fit)+" · "+(r.quant||"GGUF"),cn[e]=r.fit.level,bi()}catch{const i=l("#cb-b-"+e);i&&(i.className="fit-badge bad",i.textContent="Fehler"),cn[e]=null,bi()}}function bi(){const e=l("#cb-grid");if(!e)return;let t=-1,n=99;if(cn.forEach((s,a)=>{if(s==null)return;const r=dd[s]??99;r<n&&(n=r,t=a)}),e.querySelectorAll("[data-res]").forEach(s=>{var a;s.classList.remove("res-best"),(a=s.querySelector(".cb-best-tag"))==null||a.remove()}),t<0||n>1)return;const i=e.querySelector(`[data-res="${t}"]`);i&&(i.classList.add("res-best"),i.insertAdjacentHTML("afterbegin",'<div class="cb-best-tag">★ Beste Wahl für dein System</div>'))}function es(){const e=l("#cb-m-files").value,t=Ae==null?void 0:Ae.files.find(a=>a.filename===e);if(!t){l("#cb-m-fit").style.display="none";return}l("#cb-m-fit").style.display="flex",l("#cb-m-fit-text").innerHTML=`Bedarf: <b>~${t.fit.req_gb.toFixed(1)} GB</b> · ${Ae.params_b}B · ${g(t.quant)} · ~${Math.round(t.fit.tps)} Tok/s`,l("#cb-m-fit-badge").innerHTML=`<span class="fit-badge ${Sn(t.fit.level)}">${g(t.fit.text)}</span>`;const n=t.optimal_ctx,i=l("#cb-m-ctx-rec");if(n){const a=l("#cb-m-ctx");a&&(a.value==="8192"||a.value==="")&&(a.value=n)}i&&(i.innerHTML=n?`Empfohlener Kontext für deine Hardware: <b>~${Math.round(n/1024)}k</b> — <a href="#" onclick="event.preventDefault();window.cbSetCtx(${n})">übernehmen</a>`:"");const s=l("#cb-m-download");t.fit.level==="too_tight"?(s.className="primary warn",s.textContent="Trotzdem holen (zu groß)"):(s.className="primary",s.textContent="Herunterladen & Einpflegen")}function Sd(){es()}async function Cs(){if(!Ae)return;const e=parseInt(l("#cb-m-ctx").value)||8192,t=l("#cb-m-files").value;try{Ae=await $("/api/cookbook/analyze",{method:"POST",body:JSON.stringify({repo_id:Ae.repo,ctx:e})}),l("#cb-m-files").value=t,es()}catch{}}function $d(e,t){l("#cb-modal").style.display="flex",l("#cb-m-title").textContent=e,l("#cb-m-repo").textContent=t}async function Ed(e){var n;const t=sn[e];if(t){$d(t.id.split("/").pop(),t.id),l("#cb-m-alias").value="",l("#cb-m-files").style.display="none",l("#cb-m-loading").style.display="block",l("#cb-m-download").disabled=!0;try{const i=parseInt(l("#cb-m-ctx").value)||8192;if(Ae=await $("/api/cookbook/analyze",{method:"POST",body:JSON.stringify({repo_id:t.id,ctx:i})}),l("#cb-m-loading").style.display="none",l("#cb-m-files").style.display="block",!((n=Ae.files)!=null&&n.length)){l("#cb-m-files").innerHTML="<option>Keine GGUF-Dateien gefunden</option>",l("#cb-m-fit").style.display="none";return}l("#cb-m-files").innerHTML=Ae.files.map(s=>{const a=s.fit.level==="perfect"?"●":s.fit.level==="marginal"?"◐":"○";return`<option value="${g(s.filename)}">${a} ${g(s.filename)}</option>`}).join(""),l("#cb-m-download").disabled=!1,es()}catch(i){l("#cb-m-loading").textContent="Fehler: "+i.message}}}async function Td(){var a;const e=l("#cb-m-repo").textContent,t=l("#cb-m-files").value,n=l("#cb-m-alias").value.trim().toLowerCase(),i=parseInt(l("#cb-m-ctx").value)||8192;if(!e||!t)return w("Bitte eine GGUF-Datei wählen.",!0);const s=l("#cb-m-download");s.disabled=!0,s.textContent="Starte…";try{const r=await $("/api/download",{method:"POST",body:JSON.stringify({repo:e,file:t,hf_token:_n()})});await $("/api/register",{method:"POST",body:JSON.stringify({role:n,model_path:r.expected_path,ctx:i})}),w("Download gestartet — siehe Aktivität."),l("#cb-modal").style.display="none",(a=document.querySelector(".nav-item[data-view='activity']"))==null||a.click()}catch(r){w("Fehler: "+r.message,!0)}s.disabled=!1,s.textContent="Herunterladen & Einpflegen"}function Cd(e){nn=e,Qa()}const Ld={id:"cookbook",mount:ud,onSystem:Cd};let Fn=null,Ls="",Lt="zed",Se=[];window.mcCopyCode=e=>{var i;const t=e.parentElement.querySelector("code,pre");(i=navigator.clipboard)==null||i.writeText((t==null?void 0:t.textContent)||"");const n=e.textContent;e.textContent="Kopiert!",setTimeout(()=>e.textContent=n,1400)};window.mcCopyVal=e=>{var i;const t=e.previousElementSibling;(i=navigator.clipboard)==null||i.writeText(t.value);const n=e.textContent;e.textContent="Kopiert!",setTimeout(()=>e.textContent=n,1400)};window.cnGo=e=>{var t;return(t=document.querySelector(`.nav-item[data-view="${e}"]`))==null?void 0:t.click()};window.cnSelectTool=e=>{Lt=e,ts()};window.cnToggleModel=e=>{Se.includes(e)?Se=Se.filter(t=>t!==e):Se.push(e),ts()};function Ad(){return`http://${location.hostname}:8080/v1`}function zd(e){return/^\d{1,3}(\.\d{1,3}){3}$/.test(e)}function Dd(){return location.protocol==="https:"||!zd(location.hostname)}function Xe(){return((Fn==null?void 0:Fn.models)||[]).filter(e=>!e.incomplete)}function Pd(){return Se.length?Se:Xe().map(e=>e.name)}function an(e,t){return`<label>${e}</label>
<div class="flex gap-2" style="align-items:stretch;margin-bottom:12px">
<input class="mono-sm" readonly value="${g(t)}" style="flex:1;margin:0">
<button class="ghost" onclick="window.mcCopyVal(this)">Kopieren</button>
</div>`}const Za=e=>`<span class="chip" style="background:rgba(63,185,80,.12);border-color:rgba(63,185,80,.25);color:#7ee29a">${nt("check")}${g(e)}</span>`;function Od(e,t){const i=(t.length?Xe().filter(s=>t.includes(s.name)):Xe().length?Xe():[{name:"coder",meta:{}}]).map(s=>{var o;const r=(((o=s.meta)==null?void 0:o.caps)||[]).some(c=>/Bild|Vision/i.test(c))?', "capabilities": { "tools": true, "images": true }':"";return` { "name": "${s.name}", "display_name": "${s.name}", "max_tokens": 32768${r} }`}).join(`,
`);return`"language_models": {
"openai_compatible": {
"bosgame": {
"api_url": "${e}",
"available_models": [
${i}
]
}
}
}`}function Bd(e,t){const i=(t.length?t:Xe().length?Xe().map(s=>s.name):["coder"]).map(s=>` "${s}": { "name": "${s}" }`).join(`,
`);return`"provider": {
"llama-swap": {
"npm": "@ai-sdk/openai-compatible",
"name": "Bosgame (llama-swap)",
"options": {
"baseURL": "${e}",
"apiKey": "local"
},
"models": {
${i}
}
}
}`}function Hd(e){return`<div class="card" id="cn-conn-card">
<div class="card-h"><h3>1 · Verbindung prüfen</h3></div>
<div class="card-sub">Stelle sicher, dass die LLM-Engine erreichbar ist, bevor du Tools konfigurierst.</div>
${an("Engine-Adresse (für alle Tools)",e)}
${Dd()?`<div class="alert warn" style="margin:0 0 12px"><span class="a-dot"></span><span>
Du öffnest Mission Control über einen <b>Proxy/Namen</b> (HTTPS o.ä.). Die Engine läuft auf <b>Port 8080 ohne HTTPS</b> direkt am Bosgame.
Trag in deinen Tools die <b>LAN-IP</b> ein: <code>http://192.168.178.151:8080/v1</code> — nicht den Proxy-Namen.</span></div>`:""}
<div class="btn-row" style="display:flex;align-items:center;gap:10px">
<button class="primary" id="cn-test">Verbindung testen</button>
<span id="cn-test-result" class="mono-sm"></span>
</div>
</div>`}function Rd(){return`<div class="card">
<div class="card-h"><h3>Wie funktioniert das Auto-Swap?</h3></div>
<div style="display:flex;flex-direction:column;gap:10px">
<div class="tile" style="display:flex;gap:12px;align-items:flex-start">
<span style="font-size:20px;line-height:1;flex:0 0 auto">⚡</span>
<div>
<div style="font-weight:500;font-size:13.5px">Kein manuelles Starten nötig</div>
<div class="card-sub" style="margin:4px 0 0">Wenn du in Zed oder OpenCode <b>„coder"</b> auswählst und eine Anfrage sendest,
lädt llama-swap das Modell automatisch — in ca. 25 Sekunden. Du siehst es hier im Dashboard unter „Aktives Modell".</div>
</div>
</div>
<div class="tile" style="display:flex;gap:12px;align-items:flex-start">
<span style="font-size:20px;line-height:1;flex:0 0 auto">🔄</span>
<div>
<div style="font-weight:500;font-size:13.5px">Modelle wechseln sich automatisch ab</div>
<div class="card-sub" style="margin:4px 0 0">Rufst du ein anderes Modell auf, entlädt llama-swap das aktuelle (nach TTL-Ablauf)
und lädt das neue. Es läuft immer nur <b>eines gleichzeitig</b> — llama-swap verwaltet das komplett selbst.</div>
</div>
</div>
<div class="tile" style="display:flex;gap:12px;align-items:flex-start">
<span style="font-size:20px;line-height:1;flex:0 0 auto">🧠</span>
<div>
<div style="font-weight:500;font-size:13.5px">Zwei Modelle gleichzeitig aktiv halten</div>
<div class="card-sub" style="margin:4px 0 0">Du hast 124 GB RAM — genug für z.B. Scout 8B (~5 GB) <b>dauerhaft geladen</b> + ein
größeres Modell das swappt. Dafür beim Scout im <b>Modelle-Tab → Konfigurieren</b> die TTL auf <code>99999</code> setzen
(= nie automatisch entladen). Das kleine Modell beantwortet schnelle Fragen sofort, ohne jede Wartezeit.</div>
</div>
</div>
</div>
</div>`}function Fd(){const e=Xe();if(!e.length)return"";const t=e.map(i=>`<span class="chip" style="cursor:pointer;${Se.includes(i.name)?"background:rgba(45,212,191,.2);border-color:var(--accent);color:var(--accent)":""}"
onclick="window.cnToggleModel('${g(i.name)}')">${g(i.name)}</span>`).join(" ");return`<div class="card">
<div class="card-h"><h3>2 · Modelle auswählen</h3><span class="meta">${Se.length?`${Se.length} von ${e.length} ausgewählt`:"alle werden eingeschlossen"}</span></div>
<div class="card-sub">Wähle, welche Modelle im Config-Snippet erscheinen sollen. Standardmäßig alle.</div>
<div class="flex gap-2" style="flex-wrap:wrap">${t}</div>
${Se.length?'<div style="margin-top:10px"><a href="#" onclick="event.preventDefault();window.cnClearModels()" style="color:var(--mut);font-size:12.5px">Auswahl aufheben (alle)</a></div>':""}
</div>`}window.cnClearModels=()=>{Se=[],ts()};function zn(e,t,n){return`<button class="card-btn${Lt===e?" cb-best":""}" style="text-align:left;padding:12px 16px"
onclick="window.cnSelectTool('${e}')">
<div style="font-weight:500;font-size:13.5px">${g(t)}</div>
<div class="card-sub" style="margin:3px 0 0">${g(n)}</div>
</button>`}function Nd(){return`<div class="card">
<div class="card-h"><h3>3 · Tool wählen</h3></div>
<div class="card-sub">Für welches Werkzeug brauchst du die Konfiguration?</div>
<div class="grid grid-4" style="gap:8px">
${zn("zed","Zed","Schneller nativer Editor — Empfohlen")}
${zn("opencode","OpenCode","Open-Source Coding-Agent (Terminal/Desktop)")}
${zn("cline","Cline / Cursor","VS Code Extension, Bring-Your-Own-Key")}
${zn("openwebui","OpenWebUI","Browser-Chat-Interface")}
</div>
</div>`}function Id(e){const t=Pd(),n=t[0]||"coder";let i="";if(Lt==="zed"){const s=Od(e,t);i=`
<p>Öffne die Zed-Settings mit <code>Cmd/Strg + ,</code> und <b>füge diesen Block</b> in deine bestehende
<code>settings.json</code> ein. Falls bereits ein <code>"bosgame"</code>-Eintrag existiert: vorher löschen.</p>
<div class="alert warn" style="margin-bottom:12px;padding:10px 14px">
<span class="a-dot"></span><span>Nur diesen Block einfügen, <b>nicht die ganze Datei ersetzen</b> — sonst gehen andere Einstellungen verloren.</span>
</div>
<div style="position:relative;margin-top:4px">
<button class="ghost" style="position:absolute;top:8px;right:8px;z-index:1" onclick="window.mcCopyCode(this)">Kopieren</button>
<div class="log" style="max-height:none"><code>${g(s)}</code></div>
</div>
<p style="margin-top:12px"><b>API-Key:</b> Öffne den Agent-Panel → Anbieter <b>bosgame</b> → trag irgendeinen Wert ein (z.B. <code>local</code>).
Alternativ <code>BOSGAME_API_KEY=local</code> als Umgebungsvariable.</p>
<div class="hint">Danach im Agent-Panel das Modell <b>bosgame / ${g(n)}</b> auswählen. Das Auto-Swap lädt es beim ersten Request.</div>`}else if(Lt==="opencode"){const s=Bd(e,t);i=`
<p>Datei anlegen oder öffnen:</p>
<p class="mono-sm" style="line-height:1.6">Windows: <code>%USERPROFILE%\\.config\\opencode\\opencode.json</code><br>
Linux/Mac: <code>~/.config/opencode/opencode.json</code><br>
Oder im Projektordner: <code>opencode.json</code></p>
<div class="alert warn" style="margin:8px 0 12px;padding:10px 14px">
<span class="a-dot"></span><span>Nur den <code>"provider"</code>-Block einfügen oder mergen.
Falls bereits ein <code>"llama-swap"</code>-Eintrag vorhanden ist: <b>vorher löschen</b>, sonst erscheinen Modelle doppelt.</span>
</div>
<div style="position:relative">
<button class="ghost" style="position:absolute;top:8px;right:8px;z-index:1" onclick="window.mcCopyCode(this)">Kopieren</button>
<div class="log" style="max-height:none"><code>${g(s)}</code></div>
</div>
<p style="margin-top:12px">Danach in OpenCode <code>/models</code> → <b>llama-swap/${g(n)}</b> wählen.</p>
<div class="hint">Statt alles zu ersetzen: nur den <code>provider</code>-Block in deine bestehende Config einfügen — so bleiben andere Anbieter erhalten.</div>`}else Lt==="cline"?i=`
<p>In Cline/Cursor den Provider <b>„OpenAI Compatible"</b> wählen und folgende Felder eintragen:</p>
${an("Basis-URL (OpenAI Compatible)",e)}
${an("Modell-ID",n)}
<div class="hint">API-Key: ein beliebiger Wert (z.B. <code>local</code>) — llama-swap prüft ihn nicht.</div>`:Lt==="openwebui"&&(i=`
<p>Settings → Admin Panel → Connections → neue OpenAI-Verbindung:</p>
${an("Basis-URL",e)}
${an("API-Key","dummy-key")}
<div class="hint">Nach dem Speichern erscheinen die Modelle automatisch in der Modell-Auswahl.</div>`);return`<div class="card">
<div class="card-h"><h3>4 · Config-Snippet</h3></div>
${i}
</div>`}function Gd(e){var i;const t=(i=Xe().find(s=>{var a,r;return(r=(a=s.meta)==null?void 0:a.caps)==null?void 0:r.includes("Bild")}))==null?void 0:i.name;if(!t)return"";const n=`curl ${e}/chat/completions \\
-H "Content-Type: application/json" \\
-d '{
"model": "${t}",
"messages": [{"role":"user","content":[
{"type":"text","text":"Was ist auf dem Bild falsch?"},
{"type":"image_url","image_url":{"url":"data:image/png;base64,<DEIN_BILD>"}}
]}]
}'`;return`<div class="card">
<div class="card-h"><h3>Bilder einbinden (Vision)</h3>${Za(`${t}" bereit`)}</div>
<div class="card-sub">Mit Vision-Modellen kannst du Screenshots oder Fehlerbilder direkt mitschicken.</div>
<div style="position:relative;margin-top:8px">
<button class="ghost" style="position:absolute;top:8px;right:8px;z-index:1" onclick="window.mcCopyCode(this)">Kopieren</button>
<div class="log" style="max-height:none"><code>${g(n)}</code></div>
</div>
</div>`}function un(){var n;const e=l(".view[data-view='connect']");if(!e)return;const t=Ad();e.innerHTML=`
<div class="pagehead"><div>
<h1>Verbinden</h1>
<div class="sub">Schritt für Schritt: KI-Modelle in deine Tools einbinden — getestet, erklärt, mit Copy-Paste-Config.</div>
</div></div>
${Hd(t)}
${Rd()}
${Fd()}
${Nd()}
${Id(t)}
${Gd(t)}`,(n=l("#cn-test"))==null||n.addEventListener("click",Kd)}function ts(){if(!l(".view[data-view='connect'] .card:nth-of-type(3)")){un();return}const t=l(".view[data-view='connect']"),n=t==null?void 0:t.querySelectorAll(".card");if(!n||n.length<3){un();return}un()}async function Kd(){const e=l("#cn-test-result");e.innerHTML='<span class="text-mut">Teste…</span>';try{const t=await $("/api/integration/test");e.innerHTML=t.ok?Za(`Verbunden — ${t.models.length} Modell(e): ${t.models.join(", ")}`):`<span style="color:var(--err)">✗ Keine Verbindung: ${g(t.error)}</span>`}catch(t){e.innerHTML=`<span style="color:var(--err)">✗ ${g(t.message)}</span>`}}function qd(){un()}function Ud(e){Fn=e;const t=((e==null?void 0:e.models)||[]).map(n=>n.name).join(",")+"|"+!!e;t!==Ls&&(Ls=t,un())}const jd={id:"connect",mount:qd,onStatus:Ud},ni=[ho,zo,td,qo,Ld,jd];let As={};function Vd(){const e=document.getElementById("top-active-text");e&&(e.classList.add("swap-flash"),setTimeout(()=>e.classList.remove("swap-flash"),900))}function zs(e){var s;const t=document.getElementById("swdot"),n=document.getElementById("swlabel"),i=document.getElementById("top-active-text");if(!e)t&&(t.className="dot off"),n&&(n.textContent="Backend nicht erreichbar"),i&&(i.textContent="Backend offline"),Ds("Backend nicht erreichbar läuft uvicorn?",!1);else{const a=(e.swap_url||"").replace(/^https?:\/\//,"");t&&(t.className="dot "+(e.swap_ok?"on":"off")),n&&(n.textContent=(e.swap_ok?"LLM-Engine: Online ":"LLM-Engine: Offline ")+a);const r=(e.models||[]).find(c=>c.state==="running");i&&(i.innerHTML=r?`Geladen: <b style="color:var(--teal)">${r.name}</b>`:"Kein Modell im VRAM"),e.swap_ok?Yd():Ds(`LLM-Engine nicht erreichbar unter <b>${a}</b> läuft der llama-swap Dienst?`,!0);const o={};for(const c of e.models||[])o[c.name]=c.state;for(const[c,u]of Object.entries(o)){const p=As[c];if(p&&p!==u&&(u==="running"||u==="loading")){Vd();break}}As=o}Wd(e),Rl.set(e);for(const a of ni)(s=a.onStatus)==null||s.call(a,e)}function Wd(e){const t=document.getElementById("sec-chip"),n=document.getElementById("sec-chip-tx");!t||!n||(t.classList.toggle("ok",!!(e!=null&&e.secured)),n.textContent=e!=null&&e.secured?"Geschützt · Heimnetz":"Nur im Heimnetz (offen)")}function Jd(e){var t;Fl.set(e||[]);for(const n of ni)(t=n.onJobs)==null||t.call(n,e)}function Qd(e){var t;for(const n of ni)(t=n.onSystem)==null||t.call(n,e)}function Ds(e,t){const n=document.getElementById("alert");n.className="alert"+(t?" warn":""),n.innerHTML=`<span class="a-dot"></span><span>${e}</span>`,n.style.display="flex"}function Yd(){const e=document.getElementById("alert");e&&(e.style.display="none")}const Zd=e=>{var t;return(t=document.querySelector(`.nav-item[data-view="${e}"]`))==null?void 0:t.click()};function wi(e,t,n,i){const s=document.createElement("span");return s.className="upd-badge"+(t?" "+t:""),s.textContent=e,i&&(s.title=i),s.onclick=()=>Zd(n),s}async function Xa(){try{const e=await $("/api/updates"),t=document.getElementById("update-badges");if(!t)return;const n=e.apt_cache_age_h,i=n!=null&&n>24,s=n!=null?` · apt-Cache: vor ${n}h`:"";t.innerHTML="",t.appendChild(wi(e.os>0?`OS: ${e.os} Updates`:i?"OS: ?":"OS: aktuell",e.os>0||i?"warn":"ok","server",e.os>0?`${e.os} ausstehende Pakete${s}`:i?`apt-Cache veraltet (${n}h)`:`Keine Updates${s}`)),t.appendChild(wi(e.engine>0?"Engine: Update":"Engine: aktuell",e.engine>0?"warn":"ok","server")),t.appendChild(wi(e.models>0?`Modelle: ${e.models}`:"Modelle: aktuell",e.models>0?"warn":"ok","news"))}catch{}}async function ii(){try{zs(await $("/api/status"))}catch{zs(null)}}async function er(){try{Jd(await $("/api/jobs"))}catch{}}function tr(){const e=window.location.protocol==="https:"?"wss:":"ws:",t=new WebSocket(`${e}//${window.location.host}/api/system/stream`);t.onmessage=n=>{try{Qd(JSON.parse(n.data))}catch{}},t.onclose=()=>{setTimeout(tr,3e3)},t.onerror=()=>t.close()}var Ns;for(const e of ni)(Ns=e.mount)==null||Ns.call(e);const Ps=document.querySelector('.view[data-view="guides"]');Ps&&za(jl,{target:Ps});const Os=document.querySelector('.view[data-view="news"]');Os&&za(no,{target:Os});Hl("overview");const yi=document.getElementById("token");yi&&(yi.value=Da(),yi.addEventListener("change",e=>{Dl(e.target.value),ii()}));const xi=document.getElementById("hf-token");xi&&(xi.value=_n(),xi.addEventListener("change",e=>Ol(e.target.value)));const Bs=document.getElementById("nav-settings"),_i=document.getElementById("settings-modal"),Hs=document.getElementById("sm-close");Bs&&_i&&Hs&&(Bs.addEventListener("click",()=>_i.style.display="flex"),Hs.addEventListener("click",()=>_i.style.display="none"));function Xd(){const e=document.getElementById("clock");e&&(e.textContent=new Date().toTimeString().slice(0,5))}document.addEventListener("mc:refresh",ii);ii();er();tr();setInterval(Xd,1e3);setInterval(ii,3e3);setInterval(er,1500);Xa();setInterval(Xa,6e4);