',i=p(),a=h("tbody");for(let t=0;tUpdate Binaries',o=p(),tt&&tt.c(),i=p(),et&&et.c(),a=p(),l=h("div"),w=h("h3"),w.textContent="Current Version",E=p(),x=h("div"),k=h("span"),$=g(Q),A=p(),B=h("button"),I=g("Rollback"),L=p(),S=h("div"),C=h("h3"),C.textContent="Install New Version",U=p(),T=h("div"),N=h("label"),N.textContent="Version",O=p(),R=h("input"),P=p(),D=h("div"),q=h("div"),H=h("label"),H.textContent="Binary URLs",F=p(),V=h("button"),j=g("Fill from Release"),z=p();for(let t=0;tn(4,r=t)),i(t,cr,t=>n(11,s=t)),i(t,ur,t=>n(12,o=t)),i(t,pr,t=>n(13,l=t)),i(t,gr,t=>n(5,c=t));let u="",d={orly:"","orly-db-badger":"","orly-acl-follows":"","orly-launcher":""},f=null,h=!1;async function g(){a(pr,l=!0,l);try{a(gr,c=await async function(t,e){const n=await wr("/api/binaries",{},t,e);if(!n.ok)throw new Error(`Failed to fetch binaries: ${n.statusText}`);return n.json()}(o,s),c),a(yr,r="",r)}catch(t){a(yr,r=t.message,r)}finally{a(pr,l=!1,l)}}return B(async()=>{await g()}),[u,d,f,h,r,c,async function(){const t={};for(const[e,n]of Object.entries(d))n.trim()&&(t[e]=n.trim());if(u.trim())if(0!==Object.keys(t).length){n(3,h=!0),n(2,f=null),a(yr,r="",r);try{n(2,f=await async function(t,e,n,r){const s=await wr("/api/update",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({version:n,urls:r})},t,e);if(!s.ok){const t=await s.json();throw new Error(t.message||`Update failed: ${s.statusText}`)}return s.json()}(o,s,u.trim(),t)),await g()}catch(t){a(yr,r=t.message,r)}finally{n(3,h=!1)}}else a(yr,r="At least one binary URL is required",r);else a(yr,r="Version is required",r)},async function(){if(confirm("Are you sure you want to rollback to the previous version?")){n(3,h=!0),a(yr,r="",r);try{const t=await async function(t,e){const n=await wr("/api/rollback",{method:"POST"},t,e);if(!n.ok){const t=await n.json();throw new Error(t.message||`Rollback failed: ${n.statusText}`)}return n.json()}(o,s);n(2,f={success:!0,message:`Rolled back from ${t.previous_version} to ${t.current_version}. Restart services to apply.`}),await g()}catch(t){a(yr,r=t.message,r)}finally{n(3,h=!1)}}},function(){const t=prompt("Enter release base URL (e.g., https://git.mleku.dev/mleku/next.orly.dev/releases/download/v0.55.11):");if(!t)return;const e=t.replace(/\/$/,""),r=prompt("Enter architecture (amd64 or arm64):","amd64");if(!r)return;const s=u.trim()||t.split("/").pop();n(1,d.orly=`${e}/orly-${s.replace("v","")}-linux-${r}`,d),n(1,d["orly-db-badger"]=`${e}/orly-db-badger-${s.replace("v","")}-linux-${r}`,d),n(1,d["orly-acl-follows"]=`${e}/orly-acl-follows-${s.replace("v","")}-linux-${r}`,d),n(1,d["orly-launcher"]=`${e}/orly-launcher-${s.replace("v","")}-linux-${r}`,d),u.trim()||n(0,u=s)},function(){u=this.value,n(0,u)},function(t){d[t]=this.value,n(1,d)}]}class Xr extends Q{constructor(t){super(),J(this,t,Qr,Jr,o,{})}}function ts(e){let n,r;return n=new Xr({}),{c(){Z(n.$$.fragment)},m(t,e){G(n,t,e),r=!0},p:t,i(t){r||(z(n.$$.fragment,t),r=!0)},o(t){K(n.$$.fragment,t),r=!1},d(t){W(n,t)}}}function es(e){let n,r;return n=new Fr({}),{c(){Z(n.$$.fragment)},m(t,e){G(n,t,e),r=!0},p:t,i(t){r||(z(n.$$.fragment,t),r=!0)},o(t){K(n.$$.fragment,t),r=!1},d(t){W(n,t)}}}function ns(e){let n,r;return n=new Ur({}),{c(){Z(n.$$.fragment)},m(t,e){G(n,t,e),r=!0},p:t,i(t){r||(z(n.$$.fragment,t),r=!0)},o(t){K(n.$$.fragment,t),r=!1},d(t){W(n,t)}}}function rs(e){let n,r,s,o,i,a,l,f;return{c(){n=h("div"),r=h("h2"),r.textContent="ORLY Launcher Admin",s=p(),o=h("p"),o.textContent="Please login to manage the relay services.",i=p(),a=h("button"),a.textContent="Login with Nostr",b(r,"class","svelte-4k9oqz"),b(o,"class","svelte-4k9oqz"),b(a,"class","login-btn svelte-4k9oqz"),b(n,"class","login-prompt svelte-4k9oqz")},m(t,d){u(t,n,d),c(n,r),c(n,s),c(n,o),c(n,i),c(n,a),l||(f=y(a,"click",e[10]),l=!0)},p:t,i:t,o:t,d(t){t&&d(n),l=!1,f()}}}function ss(t){let e,n,r,s,o,i,a,l,f,g;n=new st({props:{currentPage:t[0],isLoggedIn:t[4],userPubkey:t[3]}}),n.$on("navigate",t[8]),n.$on("login",t[9]),n.$on("logout",t[6]);const y=[rs,ns,es,ts],w=[];function m(t,e){return t[4]?"dashboard"===t[0]?1:"config"===t[0]?2:"update"===t[0]?3:-1:0}function v(e){t[11](e)}~(o=m(t))&&(i=w[o]=y[o](t));let E={isDarkTheme:t[2]};return void 0!==t[1]&&(E.showModal=t[1]),l=new or({props:E}),S.push(()=>function(t,e,n){const r=t.$$.props[e];void 0!==r&&(t.$$.bound[r]=n,n(t.$$.ctx[r]))}(l,"showModal",v)),l.$on("login",t[5]),l.$on("close",t[12]),{c(){e=h("main"),Z(n.$$.fragment),r=p(),s=h("div"),i&&i.c(),a=p(),Z(l.$$.fragment),b(s,"class","content svelte-4k9oqz"),b(e,"class","svelte-4k9oqz"),x(e,"dark-theme",t[2])},m(t,i){u(t,e,i),G(n,e,null),c(e,r),c(e,s),~o&&w[o].m(s,null),c(e,a),G(l,e,null),g=!0},p(t,[r]){const a={};1&r&&(a.currentPage=t[0]),16&r&&(a.isLoggedIn=t[4]),8&r&&(a.userPubkey=t[3]),n.$set(a);let c=o;o=m(t),o===c?~o&&w[o].p(t,r):(i&&(V(),K(w[c],1,1,()=>{w[c]=null}),j()),~o?(i=w[o],i?i.p(t,r):(i=w[o]=y[o](t),i.c()),z(i,1),i.m(s,null)):i=null);const u={};var d;4&r&&(u.isDarkTheme=t[2]),!f&&2&r&&(f=!0,u.showModal=t[1],d=()=>f=!1,U.push(d)),l.$set(u),(!g||4&r)&&x(e,"dark-theme",t[2])},i(t){g||(z(n.$$.fragment,t),z(i),z(l.$$.fragment,t),g=!0)},o(t){K(n.$$.fragment,t),K(i),K(l.$$.fragment,t),g=!1},d(t){t&&d(e),W(n),~o&&w[o].d(),W(l)}}}function os(t,e,n){let r,s,o,l;i(t,dr,t=>n(13,r=t)),i(t,ur,t=>n(14,s=t)),i(t,cr,t=>n(3,o=t)),i(t,lr,t=>n(4,l=t));let c="dashboard",u=!1,d=!1;function f(t){n(0,c=t)}B(()=>{const t=localStorage.getItem("launcher_auth_method"),e=localStorage.getItem("launcher_pubkey");"extension"===t&&e&&window.nostr&&window.nostr.getPublicKey().then(t=>{t===e&&(a(lr,l=!0,l),a(cr,o=t,o),a(ur,s=window.nostr,s),a(dr,r="extension",r))}).catch(()=>{localStorage.removeItem("launcher_auth_method"),localStorage.removeItem("launcher_pubkey")}),n(2,d=window.matchMedia("(prefers-color-scheme: dark)").matches)});return[c,u,d,o,l,function(t){const{method:e,pubkey:i,signer:c,privateKey:d}=t.detail;a(lr,l=!0,l),a(cr,o=i,o),a(ur,s=c,s),a(dr,r=e,r),localStorage.setItem("launcher_auth_method",e),localStorage.setItem("launcher_pubkey",i),n(1,u=!1)},function(){a(lr,l=!1,l),a(cr,o="",o),a(ur,s=null,s),a(dr,r="",r),localStorage.removeItem("launcher_auth_method"),localStorage.removeItem("launcher_pubkey"),localStorage.removeItem("launcher_privkey_encrypted")},f,t=>f(t.detail),()=>n(1,u=!0),()=>n(1,u=!0),function(t){u=t,n(1,u)},()=>n(1,u=!1)]}return new class extends Q{constructor(t){super(),J(this,t,os,ss,o,{})}}({target:document.body})}();
+function xn(e){if(!Number.isSafeInteger(e))throw new Error(`Wrong integer: ${e}`)}function _n(...e){const t=(e,t)=>n=>e(t(n)),n=Array.from(e).reverse().reduce((e,n)=>e?t(e,n.encode):n.encode,void 0),r=e.reduce((e,n)=>e?t(e,n.decode):n.decode,void 0);return{encode:n,decode:r}}function $n(e){return{encode:t=>{if(!Array.isArray(t)||t.length&&"number"!=typeof t[0])throw new Error("alphabet.encode input should be an array of numbers");return t.map(t=>{if(xn(t),t<0||t>=e.length)throw new Error(`Digit index outside alphabet: ${t} (alphabet: ${e.length})`);return e[t]})},decode:t=>{if(!Array.isArray(t)||t.length&&"string"!=typeof t[0])throw new Error("alphabet.decode input should be array of strings");return t.map(t=>{if("string"!=typeof t)throw new Error(`alphabet.decode: not string element=${t}`);const n=e.indexOf(t);if(-1===n)throw new Error(`Unknown letter: "${t}". Allowed: ${e}`);return n})}}}function kn(e=""){if("string"!=typeof e)throw new Error("join separator should be string");return{encode:t=>{if(!Array.isArray(t)||t.length&&"string"!=typeof t[0])throw new Error("join.encode input should be array of strings");for(let e of t)if("string"!=typeof e)throw new Error(`join.encode: non-string input=${e}`);return t.join(e)},decode:t=>{if("string"!=typeof t)throw new Error("join.decode input should be string");return t.split(e)}}}function An(e,t="="){if(xn(e),"string"!=typeof t)throw new Error("padding chr should be string");return{encode(n){if(!Array.isArray(n)||n.length&&"string"!=typeof n[0])throw new Error("padding.encode input should be array of strings");for(let e of n)if("string"!=typeof e)throw new Error(`padding.encode: non-string input=${e}`);for(;n.length*e%8;)n.push(t);return n},decode(n){if(!Array.isArray(n)||n.length&&"string"!=typeof n[0])throw new Error("padding.encode input should be array of strings");for(let e of n)if("string"!=typeof e)throw new Error(`padding.decode: non-string input=${e}`);let r=n.length;if(r*e%8)throw new Error("Invalid padding: string should have whole number of bytes");for(;r>0&&n[r-1]===t;r--)if(!((r-1)*e%8))throw new Error("Invalid padding: string has too much padding");return n.slice(0,r)}}}function Bn(e){if("function"!=typeof e)throw new Error("normalize fn should be function");return{encode:e=>e,decode:t=>e(t)}}function In(e,t,n){if(t<2)throw new Error(`convertRadix: wrong from=${t}, base cannot be less than 2`);if(n<2)throw new Error(`convertRadix: wrong to=${n}, base cannot be less than 2`);if(!Array.isArray(e))throw new Error("convertRadix: data should be array");if(!e.length)return[];let r=0;const s=[],o=Array.from(e);for(o.forEach(e=>{if(xn(e),e<0||e>=t)throw new Error(`Wrong integer: ${e}`)});;){let e=0,i=!0;for(let s=r;st?Sn(t,e%t):e,Cn=(e,t)=>e+(t-Sn(e,t));function Ln(e,t,n,r){if(!Array.isArray(e))throw new Error("convertRadix2: data should be array");if(t<=0||t>32)throw new Error(`convertRadix2: wrong from=${t}`);if(n<=0||n>32)throw new Error(`convertRadix2: wrong to=${n}`);if(Cn(t,n)>32)throw new Error(`convertRadix2: carry overflow from=${t} to=${n} carryBits=${Cn(t,n)}`);let s=0,o=0;const i=2**n-1,l=[];for(const r of e){if(xn(r),r>=2**t)throw new Error(`convertRadix2: invalid data word=${r} from=${t}`);if(s=s<32)throw new Error(`convertRadix2: carry overflow pos=${o} from=${t}`);for(o+=t;o>=n;o-=n)l.push((s>>o-n&i)>>>0);s&=2**o-1}if(s=s<=t)throw new Error("Excess padding");if(!r&&s)throw new Error(`Non-zero padding: ${s}`);return r&&o>0&&l.push(s>>>0),l}function Nn(e,t=!1){if(xn(e),e<=0||e>32)throw new Error("radix2: bits should be in (0..32]");if(Cn(8,e)>32||Cn(e,8)>32)throw new Error("radix2: carry overflow");return{encode:n=>{if(!(n instanceof Uint8Array))throw new Error("radix2.encode input should be Uint8Array");return Ln(Array.from(n),8,e,!t)},decode:n=>{if(!Array.isArray(n)||n.length&&"number"!=typeof n[0])throw new Error("radix2.decode input should be array of strings");return Uint8Array.from(Ln(n,e,8,t))}}}function Un(e){if("function"!=typeof e)throw new Error("unsafeWrapper fn should be function");return function(...t){try{return e.apply(null,t)}catch(e){}}}const On=_n(Nn(4),$n("0123456789ABCDEF"),kn("")),Tn=_n(Nn(5),$n("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"),An(5),kn(""));_n(Nn(5),$n("0123456789ABCDEFGHIJKLMNOPQRSTUV"),An(5),kn("")),_n(Nn(5),$n("0123456789ABCDEFGHJKMNPQRSTVWXYZ"),kn(""),Bn(e=>e.toUpperCase().replace(/O/g,"0").replace(/[IL]/g,"1")));const Rn=_n(Nn(6),$n("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"),An(6),kn("")),Pn=_n(Nn(6),$n("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"),An(6),kn("")),Dn=e=>{return _n((xn(t=58),{encode:e=>{if(!(e instanceof Uint8Array))throw new Error("radix.encode input should be Uint8Array");return In(Array.from(e),256,t)},decode:e=>{if(!Array.isArray(e)||e.length&&"number"!=typeof e[0])throw new Error("radix.decode input should be array of strings");return Uint8Array.from(In(e,t,256))}}),$n(e),kn(""));var t},qn=Dn("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz");Dn("123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"),Dn("rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz");const Hn=[0,2,3,5,6,7,9,10,11],jn={encode(e){let t="";for(let n=0;n>25;let n=(33554431&e)<<5;for(let e=0;e>e&1)&&(n^=Vn[e]);return n}function Kn(e,t,n=1){const r=e.length;let s=1;for(let t=0;t126)throw new Error(`Invalid prefix (${e})`);s=zn(s)^n>>5}s=zn(s);for(let t=0;tn)throw new TypeError(`Wrong string length: ${e.length} (${e}). Expected (8..${n})`);const r=e.toLowerCase();if(e!==r&&e!==e.toUpperCase())throw new Error("String must be lowercase or uppercase");const s=(e=r).lastIndexOf("1");if(0===s||-1===s)throw new Error('Letter "1" must be present between prefix and data only');const o=e.slice(0,s),i=e.slice(s+1);if(i.length<6)throw new Error("Data must be at least 6 characters long");const l=Fn.decode(i).slice(0,-6),a=Kn(o,l,t);if(!i.endsWith(a))throw new Error(`Invalid checksum in ${e}: expected "${a}"`);return{prefix:o,words:l}}return{encode:function(e,n,r=90){if("string"!=typeof e)throw new Error("bech32.encode prefix should be string, not "+typeof e);if(!Array.isArray(n)||n.length&&"number"!=typeof n[0])throw new Error("bech32.encode words should be array of numbers, not "+typeof n);const s=e.length+7+n.length;if(!1!==r&&s>r)throw new TypeError(`Length ${s} exceeds limit ${r}`);return`${e=e.toLowerCase()}1${Fn.encode(n)}${Kn(e,n,t)}`},decode:i,decodeToBytes:function(e){const{prefix:t,words:n}=i(e,!1);return{prefix:t,words:n,bytes:r(n)}},decodeUnsafe:Un(i),fromWords:r,fromWordsUnsafe:o,toWords:s}}const Zn=Mn("bech32");Mn("bech32m");const Wn={utf8:{encode:e=>(new TextDecoder).decode(e),decode:e=>(new TextEncoder).encode(e)},hex:_n(Nn(4),$n("0123456789abcdef"),kn(""),Bn(e=>{if("string"!=typeof e||e.length%2)throw new TypeError(`hex.decode: expected string, got ${typeof e} with length ${e.length}`);return e.toLowerCase()})),base16:On,base32:Tn,base64:Rn,base64url:Pn,base58:qn,base58xmr:jn};Object.keys(Wn).join(", ");var Gn=new TextDecoder("utf-8");new TextEncoder;function Yn(e){let t={},n=e;for(;n.length>0;){let e=n[0],r=n[1],s=n.slice(2,2+r);if(n=n.slice(2+r),s.lengthGn.decode(e)):[]}}}case"nevent":{let e=Yn(r);if(!e[0]?.[0])throw new Error("missing TLV 0 for nevent");if(32!==e[0][0].length)throw new Error("TLV 0 should be 32 bytes");if(e[2]&&32!==e[2][0].length)throw new Error("TLV 2 should be 32 bytes");if(e[3]&&4!==e[3][0].length)throw new Error("TLV 3 should be 4 bytes");return{type:"nevent",data:{id:Jt(e[0][0]),relays:e[1]?e[1].map(e=>Gn.decode(e)):[],author:e[2]?.[0]?Jt(e[2][0]):void 0,kind:e[3]?.[0]?parseInt(Jt(e[3][0]),16):void 0}}}case"naddr":{let e=Yn(r);if(!e[0]?.[0])throw new Error("missing TLV 0 for naddr");if(!e[2]?.[0])throw new Error("missing TLV 2 for naddr");if(32!==e[2][0].length)throw new Error("TLV 2 should be 32 bytes");if(!e[3]?.[0])throw new Error("missing TLV 3 for naddr");if(4!==e[3][0].length)throw new Error("TLV 3 should be 4 bytes");return{type:"naddr",data:{identifier:Gn.decode(e[0][0]),pubkey:Jt(e[2][0]),kind:parseInt(Jt(e[3][0]),16),relays:e[1]?e[1].map(e=>Gn.decode(e)):[]}}}case"nsec":return{type:t,data:r};case"npub":case"note":return{type:t,data:Jt(r)};default:throw new Error(`unknown prefix ${t}`)}}(e)}catch{throw new Error("Invalid nsec format")}if("nsec"!==t.type)throw new Error("Please enter an nsec (private key)");const s=t.data,o=vn(s),i={getPublicKey:async()=>o,signEvent:async e=>En(e,s)};n(6,u="Successfully logged in!"),r("login",{method:"nsec",pubkey:o,privateKey:e,signer:i}),setTimeout(h,500)}catch(e){n(5,c=e.message)}finally{n(4,a=!1)}}return e.$$set=e=>{"showModal"in e&&n(0,s=e.showModal),"isDarkTheme"in e&&n(1,o=e.isDarkTheme)},[s,o,i,l,a,c,u,f,h,p,async function(){n(5,c=""),n(6,u="");try{const e=wn(),t=Qn("nsec",e),r=Jn(vn(e));d=t,n(7,f=r),n(3,l=t),n(6,u="New key generated!")}catch(e){n(5,c="Failed to generate key: "+e.message)}},async function(){n(4,a=!0),n(5,c=""),n(6,u="");try{if(!window.nostr)throw new Error("No Nostr extension found. Please install nos2x or Alby.");const e=await window.nostr.getPublicKey();e&&(n(6,u="Successfully logged in with extension!"),r("login",{method:"extension",pubkey:e,signer:window.nostr}),setTimeout(h,500))}catch(e){n(5,c=e.message)}finally{n(4,a=!1)}},g,function(e){"Escape"===e.key&&h(),"Enter"===e.key&&"nsec"===i&&g()},function(t){L.call(this,e,t)},function(t){L.call(this,e,t)},()=>p("extension"),()=>p("nsec"),function(){l=this.value,n(3,l)},e=>"Escape"===e.key&&h()]}class ar extends te{constructor(e){super(),ee(this,e,lr,ir,o,{showModal:0,isDarkTheme:1})}}const cr=[];function ur(t,n=e){let r;const s=new Set;function i(e){if(o(t,e)&&(t=e,r)){const e=!cr.length;for(const e of s)e[1](),cr.push(e,t);if(e){for(let e=0;e{s.delete(c),0===s.size&&r&&(r(),r=null)}}}}const dr=ur(!1),fr=ur(""),hr=ur(null),pr=ur(""),gr=ur(null),yr=ur(null),br=ur(null),mr=ur(!1),wr=ur("");async function vr(e,t={},n,r){const s=`${window.location.origin}${e}`,o=t.method||"GET",i=await async function(e,t,n,r){if(!e||!t)return null;try{const t={kind:27235,created_at:Math.floor(Date.now()/1e3),tags:[["u",r],["method",n.toUpperCase()]],content:""},s=await e.signEvent(t),o=JSON.stringify(s);return btoa(o).replace(/\+/g,"-").replace(/\//g,"_")}catch(e){return console.error("createNIP98Auth error:",e),null}}(n,r,o,s),l={...t.headers};return i&&(l.Authorization=`Nostr ${i}`),fetch(s,{...t,headers:l})}async function Er(e,t){const n=await vr("/api/restart",{method:"POST"},e,t);if(!n.ok)throw new Error(`Restart failed: ${n.statusText}`);return n.json()}function xr(e){let t,n,r,s,o,i=e[0].pid+"";return{c(){t=h("div"),n=h("span"),n.textContent="PID:",r=g(),s=h("span"),o=p(i),w(n,"class","label svelte-xh5u5u"),w(s,"class","value svelte-xh5u5u"),w(t,"class","detail-row svelte-xh5u5u")},m(e,i){u(e,t,i),c(t,n),c(t,r),c(t,s),c(s,o)},p(e,t){1&t&&i!==(i=e[0].pid+"")&&v(o,i)},d(e){e&&d(t)}}}function _r(e){let t,n,r,s,o,i=e[0].restarts+"";return{c(){t=h("div"),n=h("span"),n.textContent="Restarts:",r=g(),s=h("span"),o=p(i),w(n,"class","label svelte-xh5u5u"),w(s,"class","value warning svelte-xh5u5u"),w(t,"class","detail-row svelte-xh5u5u")},m(e,i){u(e,t,i),c(t,n),c(t,r),c(t,s),c(s,o)},p(e,t){1&t&&i!==(i=e[0].restarts+"")&&v(o,i)},d(e){e&&d(t)}}}function $r(t){let n,r,s,o,i,l,a,f,y,b,m,E,_,$,k,A,B,I,S,C,L,N,U=Ar(t[0].status)+"",O=t[0].name+"",T=t[0].status+"",R=t[0].binary+"",P=t[0].pid>0&&xr(t),D=t[0].restarts>0&&_r(t);return{c(){n=h("div"),r=h("div"),s=h("span"),o=p(U),i=g(),l=h("span"),a=p(O),f=g(),y=h("div"),b=h("div"),m=h("span"),m.textContent="Status:",E=g(),_=h("span"),$=p(T),k=g(),P&&P.c(),A=g(),B=h("div"),I=h("span"),I.textContent="Binary:",S=g(),C=h("span"),L=p(R),N=g(),D&&D.c(),w(s,"class","status-indicator svelte-xh5u5u"),x(s,"color",kr(t[0].status)),w(l,"class","process-name svelte-xh5u5u"),w(r,"class","process-header svelte-xh5u5u"),w(m,"class","label svelte-xh5u5u"),w(_,"class","value svelte-xh5u5u"),x(_,"color",kr(t[0].status)),w(b,"class","detail-row svelte-xh5u5u"),w(I,"class","label svelte-xh5u5u"),w(C,"class","value binary svelte-xh5u5u"),w(B,"class","detail-row svelte-xh5u5u"),w(y,"class","process-details svelte-xh5u5u"),w(n,"class","process-card svelte-xh5u5u")},m(e,t){u(e,n,t),c(n,r),c(r,s),c(s,o),c(r,i),c(r,l),c(l,a),c(n,f),c(n,y),c(y,b),c(b,m),c(b,E),c(b,_),c(_,$),c(y,k),P&&P.m(y,null),c(y,A),c(y,B),c(B,I),c(B,S),c(B,C),c(C,L),c(y,N),D&&D.m(y,null)},p(e,[t]){1&t&&U!==(U=Ar(e[0].status)+"")&&v(o,U),1&t&&x(s,"color",kr(e[0].status)),1&t&&O!==(O=e[0].name+"")&&v(a,O),1&t&&T!==(T=e[0].status+"")&&v($,T),1&t&&x(_,"color",kr(e[0].status)),e[0].pid>0?P?P.p(e,t):(P=xr(e),P.c(),P.m(y,A)):P&&(P.d(1),P=null),1&t&&R!==(R=e[0].binary+"")&&v(L,R),e[0].restarts>0?D?D.p(e,t):(D=_r(e),D.c(),D.m(y,null)):D&&(D.d(1),D=null)},i:e,o:e,d(e){e&&d(n),P&&P.d(),D&&D.d()}}}function kr(e){switch(e){case"running":return"var(--success)";case"stopped":default:return"var(--muted-color)";case"crashed":return"var(--error)"}}function Ar(e){switch(e){case"running":return"●";case"stopped":return"○";case"crashed":return"✗";default:return"?"}}function Br(e,t,n){let{process:r}=t;return e.$$set=e=>{"process"in e&&n(0,r=e.process)},[r]}class Ir extends te{constructor(e){super(),ee(this,e,Br,$r,o,{process:0})}}function Sr(e,t,n){const r=e.slice();return r[8]=t[n],r}function Cr(e){let t,n;return{c(){t=h("div"),n=p(e[1]),w(t,"class","error-banner svelte-17dya06")},m(e,r){u(e,t,r),c(t,n)},p(e,t){2&t&&v(n,e[1])},d(e){e&&d(t)}}}function Lr(t){let n;return{c(){n=h("div"),n.textContent="Loading status...",w(n,"class","loading svelte-17dya06")},m(e,t){u(e,n,t)},p:e,i:e,o:e,d(e){e&&d(n)}}}function Nr(e){let t,n,r,s,o,i,l,a,y,b,m,E,x,_,$,k,A,B,I,S,C,L,N,U=e[2].version+"",O=e[2].uptime+"",T=(e[2].processes?.length||0)+"",R=G(e[2].processes||[]),P=[];for(let t=0;tW(P[e],1,1,()=>{P[e]=null});return{c(){t=h("div"),n=h("div"),r=h("span"),r.textContent="Version",s=g(),o=h("span"),i=p(U),l=g(),a=h("div"),y=h("span"),y.textContent="Uptime",b=g(),m=h("span"),E=p(O),x=g(),_=h("div"),$=h("span"),$.textContent="Processes",k=g(),A=h("span"),B=p(T),I=g(),S=h("h3"),S.textContent="Managed Processes",C=g(),L=h("div");for(let e=0;e{S[r]=null}),M()),~x?(_=S[x],_?_.p(e,n):(_=S[x]=I[x](e),_.c()),Z(_,1),_.m(t,null)):_=null)},i(e){$||(Z(_),$=!0)},o(e){W(_),$=!1},d(e){e&&d(t),B&&B.d(),~x&&S[x].d(),k=!1,r(A)}}}function Tr(e,t,n){let r,s,o,a,c,u;var d;async function f(){try{l(gr,c=await async function(e,t){const n=await vr("/api/status",{},e,t);if(!n.ok)throw new Error(`Failed to fetch status: ${n.statusText}`);return n.json()}(a,o),c),l(wr,s="",s)}catch(e){l(wr,s=e.message,s)}}return i(e,mr,e=>n(0,r=e)),i(e,wr,e=>n(1,s=e)),i(e,fr,e=>n(6,o=e)),i(e,hr,e=>n(7,a=e)),i(e,gr,e=>n(2,c=e)),S(async()=>{await f(),u=setInterval(f,5e3)}),d=()=>{u&&clearInterval(u)},I().$$.on_destroy.push(d),[r,s,c,f,async function(){if(confirm("Are you sure you want to restart all services?")){l(mr,r=!0,r);try{await Er(a,o),setTimeout(f,2e3)}catch(e){l(wr,s=e.message,s)}finally{l(mr,r=!1,r)}}}]}class Rr extends te{constructor(e){super(),ee(this,e,Tr,Or,o,{})}}function Pr(e,t,n){const r=e.slice();return r[33]=t[n],r[35]=n,r}function Dr(e){let t,n,s,o,i,l,a,f;return{c(){t=h("button"),n=p("Refresh"),s=g(),o=h("button"),i=p("Edit"),w(t,"class","refresh-btn svelte-my2rpu"),t.disabled=e[6],w(o,"class","edit-btn svelte-my2rpu"),o.disabled=l=e[6]||!e[5]},m(r,l){u(r,t,l),c(t,n),u(r,s,l),u(r,o,l),c(o,i),a||(f=[b(t,"click",e[8]),b(o,"click",e[9])],a=!0)},p(e,n){64&n[0]&&(t.disabled=e[6]),96&n[0]&&l!==(l=e[6]||!e[5])&&(o.disabled=l)},d(e){e&&(d(t),d(s),d(o)),a=!1,r(f)}}}function qr(e){let t,n,s,o,i,l,a,f=e[4]?"Saving...":"Save";return{c(){t=h("button"),n=p("Cancel"),s=g(),o=h("button"),i=p(f),w(t,"class","cancel-btn svelte-my2rpu"),t.disabled=e[4],w(o,"class","save-btn svelte-my2rpu"),o.disabled=e[4]},m(r,d){u(r,t,d),c(t,n),u(r,s,d),u(r,o,d),c(o,i),l||(a=[b(t,"click",e[10]),b(o,"click",e[11])],l=!0)},p(e,n){16&n[0]&&(t.disabled=e[4]),16&n[0]&&f!==(f=e[4]?"Saving...":"Save")&&v(i,f),16&n[0]&&(o.disabled=e[4])},d(e){e&&(d(t),d(s),d(o)),l=!1,r(a)}}}function Hr(e){let t,n;return{c(){t=h("div"),n=p(e[7]),w(t,"class","error-banner svelte-my2rpu")},m(e,r){u(e,t,r),c(t,n)},p(e,t){128&t[0]&&v(n,e[7])},d(e){e&&d(t)}}}function jr(e){let t,n,r,s=e[3]&&e[2].includes("Restart required"),o=s&&Fr(e);return{c(){t=h("div"),n=p(e[2]),r=g(),o&&o.c(),w(t,"class","message-banner svelte-my2rpu"),k(t,"success",e[3]),k(t,"error",!e[3])},m(e,s){u(e,t,s),c(t,n),c(t,r),o&&o.m(t,null)},p(e,r){4&r[0]&&v(n,e[2]),12&r[0]&&(s=e[3]&&e[2].includes("Restart required")),s?o?o.p(e,r):(o=Fr(e),o.c(),o.m(t,null)):o&&(o.d(1),o=null),8&r[0]&&k(t,"success",e[3]),8&r[0]&&k(t,"error",!e[3])},d(e){e&&d(t),o&&o.d()}}}function Fr(t){let n,r,s;return{c(){n=h("button"),n.textContent="Restart Now",w(n,"class","restart-btn-inline svelte-my2rpu")},m(e,o){u(e,n,o),r||(s=b(n,"click",t[12]),r=!0)},p:e,d(e){e&&d(n),r=!1,s()}}}function Vr(t){let n;return{c(){n=h("div"),n.textContent="Loading configuration...",w(n,"class","loading svelte-my2rpu")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function zr(e){let t,n,r,s,o,i,l,a,b,m,v,E,x,_,$,k,A,B,I,S,C,L,N,U,O,T,R,P,D,q,H,j,F,V,z,K,M,Z,W,Y,J,Q,X,ee,te,ne,re,se,oe,ie,le,ae,ce,ue,de,fe,he,pe,ge,ye,be,me,we,ve,Ee,xe,_e,$e,ke,Ae,Be,Ie,Se,Ce,Le,Ne,Ue,Oe,Te,Re,Pe,De,qe,He,je,Fe,Ve,ze;function Ke(e,t){return e[0]?Mr:Kr}let Me=Ke(e),Ze=Me(e);function We(e,t){return e[0]?Wr:Zr}let Ge=We(e),Ye=Ge(e);function Je(e,t){return e[0]?Yr:Gr}let Qe=Je(e),Xe=Qe(e);function et(e,t){return e[0]?Qr:Jr}let tt=et(e),nt=tt(e);function rt(e,t){return e[0]?es:Xr}let st=rt(e),ot=st(e);function it(e,t){return e[0]?ns:ts}let lt=it(e),at=lt(e);function ct(e,t){return e[0]?ss:rs}let ut=ct(e),dt=ut(e);function ft(e,t){return e[0]?is:os}let ht=ft(e),pt=ht(e);function gt(e,t){return e[0]?as:ls}let yt=gt(e),bt=yt(e);function mt(e,t){return e[0]?us:cs}let wt=mt(e),vt=wt(e);function Et(e,t){return e[0]?fs:ds}let xt=Et(e),_t=xt(e);function $t(e,t){return e[0]?ps:hs}let kt=$t(e),At=kt(e);function Bt(e,t){return e[0]?ys:gs}let It=Bt(e),St=It(e);function Ct(e,t){return e[0]?ms:bs}let Lt=Ct(e),Nt=Lt(e);function Ut(e,t){return e[0]?vs:ws}let Ot=Ut(e),Tt=Ot(e),Rt=e[0]&&Es(e),Pt=G((e[0]?e[1].admin_owners:e[5].admin_owners)||[]),Dt=[];for(let t=0;te[15].call(t))},m(i,l){u(i,t,l),c(t,n),c(t,r),_(t,e[1].db_backend,!0),s||(o=b(t,"change",e[15]),s=!0)},p(e,n){2&n[0]&&_(t,e[1].db_backend)},d(e){e&&d(t),s=!1,o()}}}function Zr(e){let t,n,r=e[5].db_binary+"";return{c(){t=h("span"),n=p(r),w(t,"class","value mono svelte-my2rpu")},m(e,r){u(e,t,r),c(t,n)},p(e,t){32&t[0]&&r!==(r=e[5].db_binary+"")&&v(n,r)},d(e){e&&d(t)}}}function Wr(e){let t,n,r;return{c(){t=h("input"),w(t,"type","text"),w(t,"placeholder","orly-db-badger"),w(t,"class","svelte-my2rpu")},m(s,o){u(s,t,o),E(t,e[1].db_binary),n||(r=b(t,"input",e[16]),n=!0)},p(e,n){2&n[0]&&t.value!==e[1].db_binary&&E(t,e[1].db_binary)},d(e){e&&d(t),n=!1,r()}}}function Gr(e){let t,n,r=e[5].db_listen+"";return{c(){t=h("span"),n=p(r),w(t,"class","value mono svelte-my2rpu")},m(e,r){u(e,t,r),c(t,n)},p(e,t){32&t[0]&&r!==(r=e[5].db_listen+"")&&v(n,r)},d(e){e&&d(t)}}}function Yr(e){let t,n,r;return{c(){t=h("input"),w(t,"type","text"),w(t,"placeholder","127.0.0.1:50051"),w(t,"class","svelte-my2rpu")},m(s,o){u(s,t,o),E(t,e[1].db_listen),n||(r=b(t,"input",e[17]),n=!0)},p(e,n){2&n[0]&&t.value!==e[1].db_listen&&E(t,e[1].db_listen)},d(e){e&&d(t),n=!1,r()}}}function Jr(e){let t,n,r=e[5].data_dir+"";return{c(){t=h("span"),n=p(r),w(t,"class","value mono svelte-my2rpu")},m(e,r){u(e,t,r),c(t,n)},p(e,t){32&t[0]&&r!==(r=e[5].data_dir+"")&&v(n,r)},d(e){e&&d(t)}}}function Qr(e){let t,n,r;return{c(){t=h("input"),w(t,"type","text"),w(t,"class","svelte-my2rpu")},m(s,o){u(s,t,o),E(t,e[1].data_dir),n||(r=b(t,"input",e[18]),n=!0)},p(e,n){2&n[0]&&t.value!==e[1].data_dir&&E(t,e[1].data_dir)},d(e){e&&d(t),n=!1,r()}}}function Xr(e){let t,n,r=e[5].acl_enabled?"Yes":"No";return{c(){t=h("span"),n=p(r),w(t,"class","value bool svelte-my2rpu"),k(t,"enabled",e[5].acl_enabled)},m(e,r){u(e,t,r),c(t,n)},p(e,s){32&s[0]&&r!==(r=e[5].acl_enabled?"Yes":"No")&&v(n,r),32&s[0]&&k(t,"enabled",e[5].acl_enabled)},d(e){e&&d(t)}}}function es(e){let t,n,r,s,o,i,l,a=e[1].acl_enabled?"Enabled":"Disabled";return{c(){t=h("label"),n=h("input"),r=g(),s=h("span"),o=p(a),w(n,"type","checkbox"),w(n,"class","svelte-my2rpu"),w(t,"class","toggle svelte-my2rpu")},m(a,d){u(a,t,d),c(t,n),n.checked=e[1].acl_enabled,c(t,r),c(t,s),c(s,o),i||(l=b(n,"change",e[19]),i=!0)},p(e,t){2&t[0]&&(n.checked=e[1].acl_enabled),2&t[0]&&a!==(a=e[1].acl_enabled?"Enabled":"Disabled")&&v(o,a)},d(e){e&&d(t),i=!1,l()}}}function ts(e){let t,n,r=e[5].acl_mode+"";return{c(){t=h("span"),n=p(r),w(t,"class","value svelte-my2rpu")},m(e,r){u(e,t,r),c(t,n)},p(e,t){32&t[0]&&r!==(r=e[5].acl_mode+"")&&v(n,r)},d(e){e&&d(t)}}}function ns(e){let t,n,r,s,o,i;return{c(){t=h("select"),n=h("option"),n.textContent="Follows",r=h("option"),r.textContent="Managed",s=h("option"),s.textContent="Curation",n.__value="follows",E(n,n.__value),r.__value="managed",E(r,r.__value),s.__value="curation",E(s,s.__value),w(t,"class","svelte-my2rpu"),void 0===e[1].acl_mode&&D(()=>e[20].call(t))},m(l,a){u(l,t,a),c(t,n),c(t,r),c(t,s),_(t,e[1].acl_mode,!0),o||(i=b(t,"change",e[20]),o=!0)},p(e,n){2&n[0]&&_(t,e[1].acl_mode)},d(e){e&&d(t),o=!1,i()}}}function rs(e){let t,n,r=e[5].acl_binary+"";return{c(){t=h("span"),n=p(r),w(t,"class","value mono svelte-my2rpu")},m(e,r){u(e,t,r),c(t,n)},p(e,t){32&t[0]&&r!==(r=e[5].acl_binary+"")&&v(n,r)},d(e){e&&d(t)}}}function ss(e){let t,n,r;return{c(){t=h("input"),w(t,"type","text"),w(t,"class","svelte-my2rpu")},m(s,o){u(s,t,o),E(t,e[1].acl_binary),n||(r=b(t,"input",e[21]),n=!0)},p(e,n){2&n[0]&&t.value!==e[1].acl_binary&&E(t,e[1].acl_binary)},d(e){e&&d(t),n=!1,r()}}}function os(e){let t,n,r=e[5].acl_listen+"";return{c(){t=h("span"),n=p(r),w(t,"class","value mono svelte-my2rpu")},m(e,r){u(e,t,r),c(t,n)},p(e,t){32&t[0]&&r!==(r=e[5].acl_listen+"")&&v(n,r)},d(e){e&&d(t)}}}function is(e){let t,n,r;return{c(){t=h("input"),w(t,"type","text"),w(t,"placeholder","127.0.0.1:50052"),w(t,"class","svelte-my2rpu")},m(s,o){u(s,t,o),E(t,e[1].acl_listen),n||(r=b(t,"input",e[22]),n=!0)},p(e,n){2&n[0]&&t.value!==e[1].acl_listen&&E(t,e[1].acl_listen)},d(e){e&&d(t),n=!1,r()}}}function ls(e){let t,n,r=e[5].relay_binary+"";return{c(){t=h("span"),n=p(r),w(t,"class","value mono svelte-my2rpu")},m(e,r){u(e,t,r),c(t,n)},p(e,t){32&t[0]&&r!==(r=e[5].relay_binary+"")&&v(n,r)},d(e){e&&d(t)}}}function as(e){let t,n,r;return{c(){t=h("input"),w(t,"type","text"),w(t,"placeholder","orly"),w(t,"class","svelte-my2rpu")},m(s,o){u(s,t,o),E(t,e[1].relay_binary),n||(r=b(t,"input",e[23]),n=!0)},p(e,n){2&n[0]&&t.value!==e[1].relay_binary&&E(t,e[1].relay_binary)},d(e){e&&d(t),n=!1,r()}}}function cs(e){let t,n,r=e[5].log_level+"";return{c(){t=h("span"),n=p(r),w(t,"class","value svelte-my2rpu")},m(e,r){u(e,t,r),c(t,n)},p(e,t){32&t[0]&&r!==(r=e[5].log_level+"")&&v(n,r)},d(e){e&&d(t)}}}function us(e){let t,n,r,s,o,i,l,a;return{c(){t=h("select"),n=h("option"),n.textContent="Trace",r=h("option"),r.textContent="Debug",s=h("option"),s.textContent="Info",o=h("option"),o.textContent="Warn",i=h("option"),i.textContent="Error",n.__value="trace",E(n,n.__value),r.__value="debug",E(r,r.__value),s.__value="info",E(s,s.__value),o.__value="warn",E(o,o.__value),i.__value="error",E(i,i.__value),w(t,"class","svelte-my2rpu"),void 0===e[1].log_level&&D(()=>e[24].call(t))},m(d,f){u(d,t,f),c(t,n),c(t,r),c(t,s),c(t,o),c(t,i),_(t,e[1].log_level,!0),l||(a=b(t,"change",e[24]),l=!0)},p(e,n){2&n[0]&&_(t,e[1].log_level)},d(e){e&&d(t),l=!1,a()}}}function ds(e){let t,n,r=e[5].distributed_sync_enabled?"Enabled":"Disabled";return{c(){t=h("span"),n=p(r),w(t,"class","value bool svelte-my2rpu"),k(t,"enabled",e[5].distributed_sync_enabled)},m(e,r){u(e,t,r),c(t,n)},p(e,s){32&s[0]&&r!==(r=e[5].distributed_sync_enabled?"Enabled":"Disabled")&&v(n,r),32&s[0]&&k(t,"enabled",e[5].distributed_sync_enabled)},d(e){e&&d(t)}}}function fs(e){let t,n,r,s,o,i,l,a=e[1].distributed_sync_enabled?"Enabled":"Disabled";return{c(){t=h("label"),n=h("input"),r=g(),s=h("span"),o=p(a),w(n,"type","checkbox"),w(n,"class","svelte-my2rpu"),w(t,"class","toggle svelte-my2rpu")},m(a,d){u(a,t,d),c(t,n),n.checked=e[1].distributed_sync_enabled,c(t,r),c(t,s),c(s,o),i||(l=b(n,"change",e[25]),i=!0)},p(e,t){2&t[0]&&(n.checked=e[1].distributed_sync_enabled),2&t[0]&&a!==(a=e[1].distributed_sync_enabled?"Enabled":"Disabled")&&v(o,a)},d(e){e&&d(t),i=!1,l()}}}function hs(e){let t,n,r=e[5].cluster_sync_enabled?"Enabled":"Disabled";return{c(){t=h("span"),n=p(r),w(t,"class","value bool svelte-my2rpu"),k(t,"enabled",e[5].cluster_sync_enabled)},m(e,r){u(e,t,r),c(t,n)},p(e,s){32&s[0]&&r!==(r=e[5].cluster_sync_enabled?"Enabled":"Disabled")&&v(n,r),32&s[0]&&k(t,"enabled",e[5].cluster_sync_enabled)},d(e){e&&d(t)}}}function ps(e){let t,n,r,s,o,i,l,a=e[1].cluster_sync_enabled?"Enabled":"Disabled";return{c(){t=h("label"),n=h("input"),r=g(),s=h("span"),o=p(a),w(n,"type","checkbox"),w(n,"class","svelte-my2rpu"),w(t,"class","toggle svelte-my2rpu")},m(a,d){u(a,t,d),c(t,n),n.checked=e[1].cluster_sync_enabled,c(t,r),c(t,s),c(s,o),i||(l=b(n,"change",e[26]),i=!0)},p(e,t){2&t[0]&&(n.checked=e[1].cluster_sync_enabled),2&t[0]&&a!==(a=e[1].cluster_sync_enabled?"Enabled":"Disabled")&&v(o,a)},d(e){e&&d(t),i=!1,l()}}}function gs(e){let t,n,r=e[5].relay_group_enabled?"Enabled":"Disabled";return{c(){t=h("span"),n=p(r),w(t,"class","value bool svelte-my2rpu"),k(t,"enabled",e[5].relay_group_enabled)},m(e,r){u(e,t,r),c(t,n)},p(e,s){32&s[0]&&r!==(r=e[5].relay_group_enabled?"Enabled":"Disabled")&&v(n,r),32&s[0]&&k(t,"enabled",e[5].relay_group_enabled)},d(e){e&&d(t)}}}function ys(e){let t,n,r,s,o,i,l,a=e[1].relay_group_enabled?"Enabled":"Disabled";return{c(){t=h("label"),n=h("input"),r=g(),s=h("span"),o=p(a),w(n,"type","checkbox"),w(n,"class","svelte-my2rpu"),w(t,"class","toggle svelte-my2rpu")},m(a,d){u(a,t,d),c(t,n),n.checked=e[1].relay_group_enabled,c(t,r),c(t,s),c(s,o),i||(l=b(n,"change",e[27]),i=!0)},p(e,t){2&t[0]&&(n.checked=e[1].relay_group_enabled),2&t[0]&&a!==(a=e[1].relay_group_enabled?"Enabled":"Disabled")&&v(o,a)},d(e){e&&d(t),i=!1,l()}}}function bs(e){let t,n,r=e[5].negentropy_enabled?"Enabled":"Disabled";return{c(){t=h("span"),n=p(r),w(t,"class","value bool svelte-my2rpu"),k(t,"enabled",e[5].negentropy_enabled)},m(e,r){u(e,t,r),c(t,n)},p(e,s){32&s[0]&&r!==(r=e[5].negentropy_enabled?"Enabled":"Disabled")&&v(n,r),32&s[0]&&k(t,"enabled",e[5].negentropy_enabled)},d(e){e&&d(t)}}}function ms(e){let t,n,r,s,o,i,l,a=e[1].negentropy_enabled?"Enabled":"Disabled";return{c(){t=h("label"),n=h("input"),r=g(),s=h("span"),o=p(a),w(n,"type","checkbox"),w(n,"class","svelte-my2rpu"),w(t,"class","toggle svelte-my2rpu")},m(a,d){u(a,t,d),c(t,n),n.checked=e[1].negentropy_enabled,c(t,r),c(t,s),c(s,o),i||(l=b(n,"change",e[28]),i=!0)},p(e,t){2&t[0]&&(n.checked=e[1].negentropy_enabled),2&t[0]&&a!==(a=e[1].negentropy_enabled?"Enabled":"Disabled")&&v(o,a)},d(e){e&&d(t),i=!1,l()}}}function ws(e){let t,n,r=e[5].bin_dir+"";return{c(){t=h("span"),n=p(r),w(t,"class","value mono svelte-my2rpu")},m(e,r){u(e,t,r),c(t,n)},p(e,t){32&t[0]&&r!==(r=e[5].bin_dir+"")&&v(n,r)},d(e){e&&d(t)}}}function vs(e){let t,n,r;return{c(){t=h("input"),w(t,"type","text"),w(t,"class","svelte-my2rpu")},m(s,o){u(s,t,o),E(t,e[1].bin_dir),n||(r=b(t,"input",e[29]),n=!0)},p(e,n){2&n[0]&&t.value!==e[1].bin_dir&&E(t,e[1].bin_dir)},d(e){e&&d(t),n=!1,r()}}}function Es(t){let n,r,s;return{c(){n=h("button"),n.textContent="+ Add",w(n,"class","add-owner-btn svelte-my2rpu")},m(e,o){u(e,n,o),r||(s=b(n,"click",t[13]),r=!0)},p:e,d(e){e&&d(n),r=!1,s()}}}function xs(t){let n;return{c(){n=h("span"),n.textContent="No owners configured",w(n,"class","no-owners svelte-my2rpu")},m(e,t){u(e,n,t)},p:e,d(e){e&&d(n)}}}function _s(e){let t,n,r;function s(){return e[30](e[35])}return{c(){t=h("button"),t.textContent="x",w(t,"class","remove-owner-btn svelte-my2rpu")},m(e,o){u(e,t,o),n||(r=b(t,"click",s),n=!0)},p(t,n){e=t},d(e){e&&d(t),n=!1,r()}}}function $s(e){let t,n,r,s,o,i=e[33]+"",l=e[0]&&_s(e);return{c(){t=h("div"),n=h("code"),r=p(i),s=g(),l&&l.c(),o=g(),w(n,"class","owner svelte-my2rpu"),w(t,"class","owner-item svelte-my2rpu")},m(e,i){u(e,t,i),c(t,n),c(n,r),c(t,s),l&&l.m(t,null),c(t,o)},p(e,n){35&n[0]&&i!==(i=e[33]+"")&&v(r,i),e[0]?l?l.p(e,n):(l=_s(e),l.c(),l.m(t,o)):l&&(l.d(1),l=null)},d(e){e&&d(t),l&&l.d()}}}function ks(e){let t,n,r,s,o,i,l,a=e[5].bin_dir?.replace(/\/bin$/,"")+"";return{c(){t=h("div"),n=h("p"),r=p("Configuration is saved to "),s=h("code"),o=p(a),i=p("/launcher.json"),l=p(". Environment variables override file settings."),w(s,"class","svelte-my2rpu"),w(n,"class","svelte-my2rpu"),w(t,"class","config-note svelte-my2rpu")},m(e,a){u(e,t,a),c(t,n),c(n,r),c(n,s),c(s,o),c(s,i),c(n,l)},p(e,t){32&t[0]&&a!==(a=e[5].bin_dir?.replace(/\/bin$/,"")+"")&&v(o,a)},d(e){e&&d(t)}}}function As(t){let n,r,s,o,i,l,a,f;function p(e,t){return e[0]?qr:Dr}let y=p(t),b=y(t),m=t[7]&&Hr(t),v=t[2]&&jr(t);function E(e,t){return e[5]?zr:e[7]?void 0:Vr}let x=E(t),_=x&&x(t);return{c(){n=h("div"),r=h("div"),s=h("h2"),s.textContent="Configuration",o=g(),i=h("div"),b.c(),l=g(),m&&m.c(),a=g(),v&&v.c(),f=g(),_&&_.c(),w(s,"class","svelte-my2rpu"),w(i,"class","header-buttons svelte-my2rpu"),w(r,"class","page-header svelte-my2rpu"),w(n,"class","config-page svelte-my2rpu")},m(e,t){u(e,n,t),c(n,r),c(r,s),c(r,o),c(r,i),b.m(i,null),c(n,l),m&&m.m(n,null),c(n,a),v&&v.m(n,null),c(n,f),_&&_.m(n,null)},p(e,t){y===(y=p(e))&&b?b.p(e,t):(b.d(1),b=y(e),b&&(b.c(),b.m(i,null))),e[7]?m?m.p(e,t):(m=Hr(e),m.c(),m.m(n,a)):m&&(m.d(1),m=null),e[2]?v?v.p(e,t):(v=jr(e),v.c(),v.m(n,f)):v&&(v.d(1),v=null),x===(x=E(e))&&_?_.p(e,t):(_&&_.d(1),_=x&&x(e),_&&(_.c(),_.m(n,null)))},i:e,o:e,d(e){e&&d(n),b.d(),m&&m.d(),v&&v.d(),_&&_.d()}}}function Bs(e,t,n){let r,s,o,a,c;i(e,fr,e=>n(31,r=e)),i(e,hr,e=>n(32,s=e)),i(e,yr,e=>n(5,o=e)),i(e,mr,e=>n(6,a=e)),i(e,wr,e=>n(7,c=e));let u=!1,d={},f="",h=!1,p=!1;async function g(){l(mr,a=!0,a);try{l(yr,o=await async function(e,t){const n=await vr("/api/config",{},e,t);if(!n.ok)throw new Error(`Failed to fetch config: ${n.statusText}`);return n.json()}(s,r),o),n(1,d=JSON.parse(JSON.stringify(o))),l(wr,c="",c)}catch(e){l(wr,c=e.message,c)}finally{l(mr,a=!1,a)}}function y(e){n(1,d.admin_owners=d.admin_owners.filter((t,n)=>n!==e),d)}S(async()=>{await g()});return[u,d,f,h,p,o,a,c,g,function(){n(1,d=JSON.parse(JSON.stringify(o))),n(0,u=!0),n(2,f="")},function(){n(1,d=JSON.parse(JSON.stringify(o))),n(0,u=!1),n(2,f="")},async function(){n(4,p=!0),n(2,f="");try{const e=await async function(e,t,n){const r=await vr("/api/config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)},e,t);if(!r.ok){const e=await r.json().catch(()=>({}));throw new Error(e.message||`Save failed: ${r.statusText}`)}return r.json()}(s,r,d);n(3,h=e.success),n(2,f=e.message),e.success&&(l(yr,o={...d},o),n(0,u=!1))}catch(e){n(3,h=!1),n(2,f=e.message)}finally{n(4,p=!1)}},async function(){if(confirm("Restart all services? This will briefly interrupt the relay."))try{await Er(s,r),n(2,f="Restart initiated. Services are restarting..."),n(3,h=!0)}catch(e){n(2,f=e.message),n(3,h=!1)}},function(){const e=prompt("Enter hex pubkey for new admin owner:");e&&e.match(/^[0-9a-fA-F]{64}$/)?n(1,d.admin_owners=[...d.admin_owners||[],e.toLowerCase()],d):e&&alert("Invalid pubkey. Must be 64 hex characters.")},y,function(){d.db_backend=$(this),n(1,d)},function(){d.db_binary=this.value,n(1,d)},function(){d.db_listen=this.value,n(1,d)},function(){d.data_dir=this.value,n(1,d)},function(){d.acl_enabled=this.checked,n(1,d)},function(){d.acl_mode=$(this),n(1,d)},function(){d.acl_binary=this.value,n(1,d)},function(){d.acl_listen=this.value,n(1,d)},function(){d.relay_binary=this.value,n(1,d)},function(){d.log_level=$(this),n(1,d)},function(){d.distributed_sync_enabled=this.checked,n(1,d)},function(){d.cluster_sync_enabled=this.checked,n(1,d)},function(){d.relay_group_enabled=this.checked,n(1,d)},function(){d.negentropy_enabled=this.checked,n(1,d)},function(){d.bin_dir=this.value,n(1,d)},e=>y(e)]}class Is extends te{constructor(e){super(),ee(this,e,Bs,As,o,{},null,[-1,-1])}}function Ss(e,t,n){const r=e.slice();return r[15]=t[n],r}function Cs(e,t,n){const r=e.slice();return r[18]=t[n],r[19]=t,r[20]=n,r}function Ls(e){let t,n;return{c(){t=h("div"),n=p(e[4]),w(t,"class","error-banner svelte-1ig49gt")},m(e,r){u(e,t,r),c(t,n)},p(e,t){16&t&&v(n,e[4])},d(e){e&&d(t)}}}function Ns(e){let t,n,r,s=e[2].message+"",o=e[2].downloaded_files?.length&&Us(e);return{c(){t=h("div"),n=p(s),r=g(),o&&o.c(),w(t,"class","success-banner svelte-1ig49gt")},m(e,s){u(e,t,s),c(t,n),c(t,r),o&&o.m(t,null)},p(e,r){4&r&&s!==(s=e[2].message+"")&&v(n,s),e[2].downloaded_files?.length?o?o.p(e,r):(o=Us(e),o.c(),o.m(t,null)):o&&(o.d(1),o=null)},d(e){e&&d(t),o&&o.d()}}}function Us(e){let t,n,r,s=e[2].downloaded_files.join(", ")+"";return{c(){t=h("br"),n=p("Downloaded: "),r=p(s)},m(e,s){u(e,t,s),u(e,n,s),u(e,r,s)},p(e,t){4&t&&s!==(s=e[2].downloaded_files.join(", ")+"")&&v(r,s)},d(e){e&&(d(t),d(n),d(r))}}}function Os(e){let t,n,r,s,o,i,l,a,f=e[18]+"";function y(){e[10].call(o,e[18])}return{c(){t=h("div"),n=h("span"),r=p(f),s=g(),o=h("input"),i=g(),w(n,"class","binary-name svelte-1ig49gt"),w(o,"type","text"),w(o,"placeholder","https://..."),o.disabled=e[3],w(o,"class","svelte-1ig49gt"),w(t,"class","url-input svelte-1ig49gt")},m(d,f){u(d,t,f),c(t,n),c(n,r),c(t,s),c(t,o),E(o,e[1][e[18]]),c(t,i),l||(a=b(o,"input",y),l=!0)},p(t,n){e=t,2&n&&f!==(f=e[18]+"")&&v(r,f),8&n&&(o.disabled=e[3]),2&n&&o.value!==e[1][e[18]]&&E(o,e[1][e[18]])},d(e){e&&d(t),l=!1,a()}}}function Ts(e){let t,n,r,s,o,i,l,a=G(e[5].available_versions),p=[];for(let t=0;t
Version
Installed
Binaries
Status
',i=g(),l=h("tbody");for(let e=0;eUpdate Binaries',o=g(),ee&&ee.c(),i=g(),te&&te.c(),l=g(),a=h("div"),y=h("h3"),y.textContent="Current Version",m=g(),x=h("div"),_=h("span"),$=p(Q),k=g(),A=h("button"),B=p("Rollback"),S=g(),C=h("div"),L=h("h3"),L.textContent="Install New Version",N=g(),U=h("div"),O=h("label"),O.textContent="Version",T=g(),R=h("input"),P=g(),D=h("div"),q=h("div"),H=h("label"),H.textContent="Binary URLs",j=g(),F=h("button"),V=p("Fill from Release"),z=g();for(let e=0;en(4,r=e)),i(e,fr,e=>n(11,s=e)),i(e,hr,e=>n(12,o=e)),i(e,mr,e=>n(13,a=e)),i(e,br,e=>n(5,c=e));let u="",d={orly:"","orly-db-badger":"","orly-acl-follows":"","orly-launcher":""},f=null,h=!1;async function p(){l(mr,a=!0,a);try{l(br,c=await async function(e,t){const n=await vr("/api/binaries",{},e,t);if(!n.ok)throw new Error(`Failed to fetch binaries: ${n.statusText}`);return n.json()}(o,s),c),l(wr,r="",r)}catch(e){l(wr,r=e.message,r)}finally{l(mr,a=!1,a)}}return S(async()=>{await p()}),[u,d,f,h,r,c,async function(){const e={};for(const[t,n]of Object.entries(d))n.trim()&&(e[t]=n.trim());if(u.trim())if(0!==Object.keys(e).length){n(3,h=!0),n(2,f=null),l(wr,r="",r);try{n(2,f=await async function(e,t,n,r){const s=await vr("/api/update",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({version:n,urls:r})},e,t);if(!s.ok){const e=await s.json();throw new Error(e.message||`Update failed: ${s.statusText}`)}return s.json()}(o,s,u.trim(),e)),await p()}catch(e){l(wr,r=e.message,r)}finally{n(3,h=!1)}}else l(wr,r="At least one binary URL is required",r);else l(wr,r="Version is required",r)},async function(){if(confirm("Are you sure you want to rollback to the previous version?")){n(3,h=!0),l(wr,r="",r);try{const e=await async function(e,t){const n=await vr("/api/rollback",{method:"POST"},e,t);if(!n.ok){const e=await n.json();throw new Error(e.message||`Rollback failed: ${n.statusText}`)}return n.json()}(o,s);n(2,f={success:!0,message:`Rolled back from ${e.previous_version} to ${e.current_version}. Restart services to apply.`}),await p()}catch(e){l(wr,r=e.message,r)}finally{n(3,h=!1)}}},function(){let e=prompt("Enter release URL (e.g., https://git.mleku.dev/mleku/next.orly.dev/releases/tag/v0.56.0):");if(!e)return;let t=e.replace(/\/$/,"");if(t.includes("/releases/tag/"))t=t.replace("/releases/tag/","/releases/download/");else if(!t.includes("/releases/download/")){const e=u.trim()||"v0.56.0";t=t.replace(/\/$/,"")+"/releases/download/"+e}const r=prompt("Enter architecture (amd64 or arm64):","amd64");if(!r)return;const s=t.split("/"),o=s[s.length-1],i=o.replace("v","");n(1,d.orly=`${t}/orly-${i}-linux-${r}`,d),n(1,d["orly-db-badger"]=`${t}/orly-db-badger-${i}-linux-${r}`,d),n(1,d["orly-acl-follows"]=`${t}/orly-acl-follows-${i}-linux-${r}`,d),n(1,d["orly-launcher"]=`${t}/orly-launcher-${i}-linux-${r}`,d),u.trim()||n(0,u=o)},function(){u=this.value,n(0,u)},function(e){d[e]=this.value,n(1,d)}]}class Hs extends te{constructor(e){super(),ee(this,e,qs,Ds,o,{})}}function js(t){let n,r;return n=new Hs({}),{c(){Y(n.$$.fragment)},m(e,t){J(n,e,t),r=!0},p:e,i(e){r||(Z(n.$$.fragment,e),r=!0)},o(e){W(n.$$.fragment,e),r=!1},d(e){Q(n,e)}}}function Fs(t){let n,r;return n=new Is({}),{c(){Y(n.$$.fragment)},m(e,t){J(n,e,t),r=!0},p:e,i(e){r||(Z(n.$$.fragment,e),r=!0)},o(e){W(n.$$.fragment,e),r=!1},d(e){Q(n,e)}}}function Vs(t){let n,r;return n=new Rr({}),{c(){Y(n.$$.fragment)},m(e,t){J(n,e,t),r=!0},p:e,i(e){r||(Z(n.$$.fragment,e),r=!0)},o(e){W(n.$$.fragment,e),r=!1},d(e){Q(n,e)}}}function zs(t){let n,r,s,o,i,l,a,f;return{c(){n=h("div"),r=h("h2"),r.textContent="ORLY Launcher Admin",s=g(),o=h("p"),o.textContent="Please login to manage the relay services.",i=g(),l=h("button"),l.textContent="Login with Nostr",w(r,"class","svelte-4k9oqz"),w(o,"class","svelte-4k9oqz"),w(l,"class","login-btn svelte-4k9oqz"),w(n,"class","login-prompt svelte-4k9oqz")},m(e,d){u(e,n,d),c(n,r),c(n,s),c(n,o),c(n,i),c(n,l),a||(f=b(l,"click",t[10]),a=!0)},p:e,i:e,o:e,d(e){e&&d(n),a=!1,f()}}}function Ks(e){let t,n,r,s,o,i,l,a,f,p;n=new le({props:{currentPage:e[0],isLoggedIn:e[4],userPubkey:e[3]}}),n.$on("navigate",e[8]),n.$on("login",e[9]),n.$on("logout",e[6]);const y=[zs,Vs,Fs,js],b=[];function m(e,t){return e[4]?"dashboard"===e[0]?1:"config"===e[0]?2:"update"===e[0]?3:-1:0}function v(t){e[11](t)}~(o=m(e))&&(i=b[o]=y[o](e));let E={isDarkTheme:e[2]};return void 0!==e[1]&&(E.showModal=e[1]),a=new ar({props:E}),U.push(()=>function(e,t,n){const r=e.$$.props[t];void 0!==r&&(e.$$.bound[r]=n,n(e.$$.ctx[r]))}(a,"showModal",v)),a.$on("login",e[5]),a.$on("close",e[12]),{c(){t=h("main"),Y(n.$$.fragment),r=g(),s=h("div"),i&&i.c(),l=g(),Y(a.$$.fragment),w(s,"class","content svelte-4k9oqz"),w(t,"class","svelte-4k9oqz"),k(t,"dark-theme",e[2])},m(e,i){u(e,t,i),J(n,t,null),c(t,r),c(t,s),~o&&b[o].m(s,null),c(t,l),J(a,t,null),p=!0},p(e,[r]){const l={};1&r&&(l.currentPage=e[0]),16&r&&(l.isLoggedIn=e[4]),8&r&&(l.userPubkey=e[3]),n.$set(l);let c=o;o=m(e),o===c?~o&&b[o].p(e,r):(i&&(K(),W(b[c],1,1,()=>{b[c]=null}),M()),~o?(i=b[o],i?i.p(e,r):(i=b[o]=y[o](e),i.c()),Z(i,1),i.m(s,null)):i=null);const u={};var d;4&r&&(u.isDarkTheme=e[2]),!f&&2&r&&(f=!0,u.showModal=e[1],d=()=>f=!1,T.push(d)),a.$set(u),(!p||4&r)&&k(t,"dark-theme",e[2])},i(e){p||(Z(n.$$.fragment,e),Z(i),Z(a.$$.fragment,e),p=!0)},o(e){W(n.$$.fragment,e),W(i),W(a.$$.fragment,e),p=!1},d(e){e&&d(t),Q(n),~o&&b[o].d(),Q(a)}}}function Ms(e,t,n){let r,s,o,a;i(e,pr,e=>n(13,r=e)),i(e,hr,e=>n(14,s=e)),i(e,fr,e=>n(3,o=e)),i(e,dr,e=>n(4,a=e));let c="dashboard",u=!1,d=!1;function f(e){n(0,c=e)}S(()=>{const e=localStorage.getItem("launcher_auth_method"),t=localStorage.getItem("launcher_pubkey");"extension"===e&&t&&window.nostr&&window.nostr.getPublicKey().then(e=>{e===t&&(l(dr,a=!0,a),l(fr,o=e,o),l(hr,s=window.nostr,s),l(pr,r="extension",r))}).catch(()=>{localStorage.removeItem("launcher_auth_method"),localStorage.removeItem("launcher_pubkey")}),n(2,d=window.matchMedia("(prefers-color-scheme: dark)").matches)});return[c,u,d,o,a,function(e){const{method:t,pubkey:i,signer:c,privateKey:d}=e.detail;l(dr,a=!0,a),l(fr,o=i,o),l(hr,s=c,s),l(pr,r=t,r),localStorage.setItem("launcher_auth_method",t),localStorage.setItem("launcher_pubkey",i),n(1,u=!1)},function(){l(dr,a=!1,a),l(fr,o="",o),l(hr,s=null,s),l(pr,r="",r),localStorage.removeItem("launcher_auth_method"),localStorage.removeItem("launcher_pubkey"),localStorage.removeItem("launcher_privkey_encrypted")},f,e=>f(e.detail),()=>n(1,u=!0),()=>n(1,u=!0),function(e){u=e,n(1,u)},()=>n(1,u=!1)]}return new class extends te{constructor(e){super(),ee(this,e,Ms,Ks,o,{})}}({target:document.body})}();
diff --git a/cmd/orly-launcher/web/src/api.js b/cmd/orly-launcher/web/src/api.js
index 014dee0..3cbdd44 100644
--- a/cmd/orly-launcher/web/src/api.js
+++ b/cmd/orly-launcher/web/src/api.js
@@ -93,6 +93,24 @@ export async function fetchConfig(signer, pubkey) {
return response.json();
}
+/**
+ * Save launcher configuration
+ * @param {object} config - Configuration object to save
+ */
+export async function saveConfig(signer, pubkey, config) {
+ const response = await authFetch('/api/config', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify(config),
+ }, signer, pubkey);
+
+ if (!response.ok) {
+ const data = await response.json().catch(() => ({}));
+ throw new Error(data.message || `Save failed: ${response.statusText}`);
+ }
+ return response.json();
+}
+
/**
* Fetch available binaries
*/
diff --git a/cmd/orly-launcher/web/src/pages/Config.svelte b/cmd/orly-launcher/web/src/pages/Config.svelte
index bc1de84..23b64b8 100644
--- a/cmd/orly-launcher/web/src/pages/Config.svelte
+++ b/cmd/orly-launcher/web/src/pages/Config.svelte
@@ -1,7 +1,13 @@