Files
pyMC_Repeater/repeater/web/html/assets/Configuration-DLRqFUbq.js
T
2026-05-14 13:54:59 +01:00

1 line
205 KiB
JavaScript

import{B as e,Ct as t,D as n,E as r,J as i,N as a,R as o,S as s,V as c,Y as l,c as u,f as d,g as f,i as p,j as m,k as h,l as g,m as _,nt as v,o as y,p as b,r as x,s as S,u as C,w,xt as T,z as E}from"./runtime-core.esm-bundler-C5QBTNWE.js";import{n as D,r as O}from"./pinia-DP0dFoGY.js";import{g as k,m as A,r as j,t as M}from"./api-Djyhg6JK.js";import{t as N}from"./system-eurEQN-G.js";import{t as P}from"./dataService-7KoBNfjw.js";import{t as F}from"./_plugin-vue_export-helper-TcpyXLsZ.js";import{t as I}from"./Spinner-CYvUNW0P.js";import{d as L,f as R,g as z,h as B,l as V,m as H,p as U}from"./index-1AODY5To.js";import{t as ee}from"./RestartModal-CfNfenZw.js";import{t as W}from"./ConfirmDialog-D6BBDcZH.js";import{t as G}from"./LocationPicker-CULJdpbO.js";import{c as K,d as te,n as ne,t as q}from"./formatters-Cc4UJmeb.js";import{n as re,t as ie}from"./preferences-6MHglq--.js";var J={key:0,class:`fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm`},Y={class:`modal-card max-w-md`},X={class:`flex items-start gap-3 mb-4`},Z={class:`mt-1 text-sm text-content-secondary dark:text-content-muted`},Q={class:`modal-actions`},ae=[`disabled`],$=[`disabled`],oe=f({__name:`UnsavedChangesModal`,props:{show:{type:Boolean},isSaving:{type:Boolean},label:{}},emits:[`discard`,`save`],setup(n){return(r,i)=>(h(),u(p,{to:`body`},[_(V,{"enter-active-class":`transition-opacity duration-200`,"enter-from-class":`opacity-0`,"leave-active-class":`transition-opacity duration-200`,"leave-to-class":`opacity-0`},{default:e(()=>[n.show?(h(),C(`div`,J,[S(`div`,Y,[S(`div`,X,[i[3]||=S(`div`,{class:`flex-shrink-0 w-10 h-10 rounded-full bg-amber-100 dark:bg-amber-900/30 flex items-center justify-center`},[S(`svg`,{class:`w-5 h-5 text-amber-600 dark:text-amber-400`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M12 9v2m0 4h.01M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z`})])],-1),S(`div`,null,[i[2]||=S(`h3`,{class:`text-base font-semibold text-content-primary dark:text-content-primary`},` Unsaved Changes `,-1),S(`p`,Z,t(n.label?n.label:`Settings`)+` have not been saved. What would you like to do? `,1)])]),S(`div`,Q,[S(`button`,{onClick:i[0]||=e=>r.$emit(`discard`),disabled:n.isSaving,class:`modal-btn-cancel`},` Discard Changes `,8,ae),S(`button`,{onClick:i[1]||=e=>r.$emit(`save`),disabled:n.isSaving,class:`modal-btn-primary`},t(n.isSaving?`Saving…`:`Save Settings`),9,$)])])])):g(``,!0)]),_:1})]))}});function se(e,t,n,r){let i=l(!1),a=l(null);A((t,n,r)=>{e.value?(i.value=!0,a.value=()=>r()):r()});function o(t){e.value?(i.value=!0,a.value=t):t()}function s(){n(),i.value=!1,a.value&&=(a.value(),null)}async function c(){await r()&&(i.value=!1,a.value&&=(a.value(),null))}return{showUnsavedModal:i,requestLeave:o,handleDiscard:s,handleSave:c}}var ce={class:`space-y-12`},le={class:`cfg-page-heading flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},ue={class:`flex items-center gap-2 flex-shrink-0`},de=[`disabled`],fe=[`disabled`],pe={key:0,class:`bg-red-100 dark:bg-red-500/20 border border-red-500/50 rounded-lg p-3`},me={class:`text-red-600 dark:text-red-400 text-sm`},he={class:`cfg-section space-y-3`},ge={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},_e={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},ve={key:1,class:`flex items-center gap-2`},ye={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},be={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},xe={key:1},Se=[`value`],Ce={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},we={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},Te={key:1},Ee=[`value`],De={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},Oe={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},ke={key:1,class:`flex items-center gap-2`},Ae={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},je={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},Me={key:1},Ne={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 gap-1`},Pe={class:`text-content-primary dark:text-content-primary font-mono text-sm`},Fe={class:`cfg-section space-y-3`},Ie={class:`flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},Le={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},Re={class:`text-content-primary dark:text-content-primary font-mono text-sm`},ze={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 gap-1`},Be={class:`text-content-primary dark:text-content-primary font-mono text-sm`},Ve=f({__name:`RadioSettings`,setup(e,{expose:n}){let r=k(),i=N(),a=y(()=>i.stats?.config?.radio||{}),s=y(()=>i.stats?.config?.radio?.cad??{}),u=l(!1),d=l(!1),f=l(null),p=l(!1),b=l(0),w=l(0),T=l(0),E=l(0),D=l(0),O=l(0),A=[{value:7.8,label:`7.8 kHz`},{value:10.4,label:`10.4 kHz`},{value:15.6,label:`15.6 kHz`},{value:20.8,label:`20.8 kHz`},{value:31.25,label:`31.25 kHz`},{value:41.7,label:`41.7 kHz`},{value:62.5,label:`62.5 kHz`},{value:125,label:`125 kHz`},{value:250,label:`250 kHz`},{value:500,label:`500 kHz`}];o(a,e=>{e&&!u.value&&(b.value=e.frequency?Number((e.frequency/1e6).toFixed(3)):0,w.value=e.spreading_factor??0,T.value=e.bandwidth?Number((e.bandwidth/1e3).toFixed(1)):0,E.value=e.tx_power??0,D.value=e.coding_rate??0,O.value=e.preamble_length??0)},{immediate:!0});let j=y(()=>{let e=a.value.frequency;return e?(e/1e6).toFixed(3)+` MHz`:`Not set`}),P=y(()=>{let e=a.value.bandwidth;return e?(e/1e3).toFixed(1)+` kHz`:`Not set`}),F=y(()=>{let e=a.value.tx_power;return e===void 0?`Not set`:e+` dBm`}),I=y(()=>{let e=a.value.coding_rate;return e?`4/`+e:`Not set`}),L=y(()=>{let e=a.value.preamble_length;return e?e+` symbols`:`Not set`}),z=y(()=>a.value.spreading_factor??`Not set`),B=()=>{u.value=!0,f.value=null},V=()=>{u.value=!1,f.value=null;let e=a.value;b.value=e.frequency?Number((e.frequency/1e6).toFixed(3)):0,w.value=e.spreading_factor??0,T.value=e.bandwidth?Number((e.bandwidth/1e3).toFixed(1)):0,E.value=e.tx_power??0,D.value=e.coding_rate??0,O.value=e.preamble_length??0},H=async({silent:e=!1}={})=>{d.value=!0,f.value=null;try{let t={};b.value&&(t.frequency=b.value*1e6),w.value&&(t.spreading_factor=w.value),T.value&&(t.bandwidth=T.value*1e3),E.value&&(t.tx_power=E.value),D.value&&(t.coding_rate=D.value);let n=(await M.post(`/update_radio_config`,t)).data;if(n.message||n.persisted)return u.value=!1,await i.fetchStats(),e||(p.value=!0),!0;n.error?f.value=n.error:f.value=`Unknown response from server`}catch(e){console.error(`Failed to update radio settings:`,e),f.value=e.response?.data?.error||`Failed to update settings`}finally{d.value=!1}return!1},{showUnsavedModal:W,requestLeave:G,handleDiscard:K,handleSave:te}=se(u,d,V,()=>H());return n({requestLeave:G,isEditing:u}),(e,n)=>(h(),C(x,null,[_(ee,{modelValue:p.value,"onUpdate:modelValue":n[0]||=e=>p.value=e,title:`Radio Settings Changes require a restart.`,message:`Restart Now?`},null,8,[`modelValue`]),_(oe,{show:v(W),"is-saving":d.value,label:`Radio Settings`,onDiscard:v(K),onSave:v(te)},null,8,[`show`,`is-saving`,`onDiscard`,`onSave`]),S(`div`,ce,[S(`div`,le,[n[8]||=S(`div`,null,[S(`h3`,{class:`text-base sm:text-lg font-semibold text-content-primary dark:text-content-primary mb-1 sm:mb-2`},`Radio Settings`),S(`p`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Configure LoRa radio parameters and frequency presets`)],-1),S(`div`,ue,[u.value?(h(),C(x,{key:1},[S(`button`,{onClick:V,disabled:d.value,class:`cfg-btn-secondary`},` Cancel `,8,de),S(`button`,{onClick:n[1]||=e=>H(),disabled:d.value,class:`cfg-btn-primary`},t(d.value?`Saving...`:`Save Changes`),9,fe)],64)):(h(),C(`button`,{key:0,onClick:B,class:`cfg-btn-primary`},` Edit Settings `))])]),f.value?(h(),C(`div`,pe,[S(`p`,me,t(f.value),1)])):g(``,!0),S(`div`,he,[S(`div`,ge,[n[10]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Frequency`,-1),u.value?(h(),C(`div`,ve,[c(S(`input`,{"onUpdate:modelValue":n[2]||=e=>b.value=e,type:`number`,step:`0.001`,min:`100`,max:`1000`,class:`cfg-input w-32`},null,512),[[U,b.value,void 0,{number:!0}]]),n[9]||=S(`span`,{class:`text-content-muted dark:text-content-muted text-sm`},`MHz`,-1)])):(h(),C(`div`,_e,t(j.value),1))]),S(`div`,ye,[n[11]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Spreading Factor`,-1),u.value?(h(),C(`div`,xe,[c(S(`select`,{"onUpdate:modelValue":n[3]||=e=>w.value=e,class:`cfg-select`},[(h(),C(x,null,m([5,6,7,8,9,10,11,12],e=>S(`option`,{key:e,value:e},t(e),9,Se)),64))],512),[[R,w.value,void 0,{number:!0}]])])):(h(),C(`div`,be,t(z.value),1))]),S(`div`,Ce,[n[12]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Bandwidth`,-1),u.value?(h(),C(`div`,Te,[c(S(`select`,{"onUpdate:modelValue":n[4]||=e=>T.value=e,class:`cfg-select`},[(h(),C(x,null,m(A,e=>S(`option`,{key:e.value,value:e.value},t(e.label),9,Ee)),64))],512),[[R,T.value,void 0,{number:!0}]])])):(h(),C(`div`,we,t(P.value),1))]),S(`div`,De,[n[14]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`TX Power`,-1),u.value?(h(),C(`div`,ke,[c(S(`input`,{"onUpdate:modelValue":n[5]||=e=>E.value=e,type:`number`,min:`2`,max:`30`,class:`cfg-input w-20`},null,512),[[U,E.value,void 0,{number:!0}]]),n[13]||=S(`span`,{class:`text-content-muted dark:text-content-muted text-sm`},`dBm`,-1)])):(h(),C(`div`,Oe,t(F.value),1))]),S(`div`,Ae,[n[16]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Coding Rate`,-1),u.value?(h(),C(`div`,Me,[c(S(`select`,{"onUpdate:modelValue":n[6]||=e=>D.value=e,class:`cfg-select`},[...n[15]||=[S(`option`,{value:5},`4/5`,-1),S(`option`,{value:6},`4/6`,-1),S(`option`,{value:7},`4/7`,-1),S(`option`,{value:8},`4/8`,-1)]],512),[[R,D.value,void 0,{number:!0}]])])):(h(),C(`div`,je,t(I.value),1))]),S(`div`,Ne,[n[17]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Preamble Length`,-1),S(`span`,Pe,t(L.value),1)])]),S(`div`,Fe,[S(`div`,Ie,[n[18]||=S(`div`,null,[S(`h3`,{class:`text-base sm:text-lg font-semibold text-content-primary dark:text-content-primary mb-1 sm:mb-2`},`CAD Calibration`),S(`p`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Channel Activity Detection: Run Calibration to update`),S(`p`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm mt-1`},`These settings tune the receivers ability to detect channel status prior to transmission`)],-1),S(`button`,{onClick:n[7]||=e=>v(r).push(`/cad-calibration`),class:`cfg-btn-secondary flex-shrink-0`},` Run Calibration `)]),n[21]||=S(`div`,{class:`pt-2`},null,-1),S(`div`,Le,[n[19]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Peak Threshold`,-1),S(`span`,Re,t(s.value.peak_threshold??`Not calibrated`),1)]),S(`div`,ze,[n[20]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Min Threshold`,-1),S(`span`,Be,t(s.value.min_threshold??`Not calibrated`),1)])])])],64))}}),He={class:`space-y-12`},Ue={class:`cfg-page-heading flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},We={class:`flex items-center gap-2 flex-shrink-0`},Ge=[`disabled`],Ke=[`disabled`],qe={key:0,class:`bg-green-100 dark:bg-green-500/10 border border-green-300 dark:border-green-500/30 rounded-lg p-3`},Je={class:`text-green-700 dark:text-green-400 text-sm`},Ye={key:1,class:`bg-red-100 dark:bg-red-500/10 border border-red-300 dark:border-red-500/30 rounded-lg p-3`},Xe={class:`text-red-700 dark:text-red-400 text-sm`},Ze={class:`cfg-section space-y-3`},Qe={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},$e={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm break-all`},et={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},tt={class:`text-content-primary dark:text-content-primary font-mono text-xs break-all`},nt={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},rt={class:`flex items-center gap-2 min-w-0 sm:justify-end`},it={class:`text-content-primary dark:text-content-primary font-mono text-xs break-all sm:text-right min-w-0`},at={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},ot={class:`text-content-primary dark:text-content-primary font-mono text-sm`},st={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},ct={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},lt={class:`flex flex-col py-2 gap-2`},ut={class:`flex flex-col sm:flex-row sm:justify-between sm:items-start gap-1`},dt={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm sm:ml-4`},ft={key:1,class:`flex items-center gap-2`},pt={class:`cfg-section space-y-3`},mt={class:`pb-2`},ht={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},gt={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},_t={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 gap-1`},vt={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},yt={class:`bg-surface dark:bg-surface-elevated border border-stroke-subtle dark:border-stroke/20 rounded-[15px] shadow-2xl w-full max-w-md p-6 space-y-4`},bt={class:`block text-sm font-medium text-content-secondary dark:text-content-muted mb-2`},xt=[`maxlength`,`disabled`],St={key:0,class:`text-red-500 text-xs mt-1`},Ct={key:1,class:`text-content-muted dark:text-content-muted text-xs mt-1`},wt=[`disabled`],Tt={key:0,class:`mt-2 bg-amber-500/10 border border-amber-500/30 rounded-lg p-3`},Et={key:0,class:`flex items-center gap-3 bg-blue-500/10 border border-blue-500/30 rounded-lg p-3`},Dt={class:`text-blue-700 dark:text-blue-400 text-xs font-medium`},Ot={class:`text-blue-600 dark:text-blue-500 text-xs mt-0.5`},kt={key:1,class:`bg-red-500/10 border border-red-500/30 rounded-lg p-3`},At={class:`text-red-600 dark:text-red-400 text-sm`},jt={key:2,class:`bg-green-500/10 border border-green-600/40 dark:border-green-500/30 rounded-lg p-3 space-y-2`},Mt={class:`text-green-600 dark:text-green-400 text-sm font-medium`},Nt={class:`font-mono text-xs break-all text-content-primary dark:text-content-primary`},Pt={key:3,class:`bg-amber-500/10 border border-amber-500/30 rounded-lg p-3`},Ft={class:`flex gap-2 mt-3`},It=[`disabled`],Lt=[`disabled`],Rt={class:`flex justify-end gap-3 mt-6`},zt=[`disabled`],Bt=[`disabled`],Vt=f({__name:`RepeaterSettings`,setup(e,{expose:n}){let r=N(),i=y(()=>r.stats?.config||{}),a=y(()=>i.value.repeater||{}),s=y(()=>r.stats),d=l(!1),f=l(!1),m=l(null),E=l(null),D=l(!1),O=l(``),k=l(0),A=l(0),j=l(0),P=l(1),F=y(()=>i.value.mesh||{});o([i,a,F],()=>{if(!d.value){O.value=i.value.node_name||``,k.value=a.value.latitude||0,A.value=a.value.longitude||0,j.value=a.value.send_advert_interval_hours||0;let e=F.value.path_hash_mode;P.value=e===0||e===1||e===2?e+1:1}},{immediate:!0});let I=y(()=>i.value.node_name||`Not set`),L=y(()=>s.value?.local_hash||`Not available`),B=y(()=>{let e=s.value?.public_key;return!e||e===`Not set`?`Not set`:e}),V=y(()=>{let e=a.value.latitude;return e&&e!==0?e.toFixed(6):`Not set`}),H=y(()=>{let e=a.value.longitude;return e&&e!==0?e.toFixed(6):`Not set`}),ee=y(()=>{let e=a.value.mode;return e?e===`no_tx`?`No TX`:e.charAt(0).toUpperCase()+e.slice(1):`Not set`}),W=y(()=>{let e=a.value.send_advert_interval_hours;return e===void 0?`Not set`:e===0?`Disabled`:e+` hour`+(e===1?``:`s`)}),K=y(()=>{let e=F.value.path_hash_mode;return e===0||e===1||e===2?e+1+(e===0?` byte`:` bytes`):`Not set`}),te=()=>{d.value=!0,m.value=null,E.value=null},ne=()=>{d.value=!1,m.value=null,O.value=i.value.node_name||``,k.value=a.value.latitude||0,A.value=a.value.longitude||0,j.value=a.value.send_advert_interval_hours||0;let e=F.value.path_hash_mode;P.value=e===0||e===1||e===2?e+1:1},q=async()=>{f.value=!0,m.value=null,E.value=null;try{let e={};O.value&&(e.node_name=O.value),e.latitude=k.value,e.longitude=A.value,e.flood_advert_interval_hours=j.value,e.path_hash_mode=P.value-1;let t=(await M.post(`/update_radio_config`,e)).data;t.message||t.persisted?(E.value=t.message||`Settings saved successfully`,d.value=!1,await r.fetchStats(),setTimeout(()=>{E.value=null},3e3)):t.error?m.value=t.error:m.value=`Unknown response from server`}catch(e){console.error(`Failed to update repeater settings:`,e),m.value=e.response?.data?.error||`Failed to update settings`}finally{f.value=!1}},re=()=>{D.value=!0},ie=e=>{k.value=e.latitude,A.value=e.longitude},J=l(!1),Y=l(``),X=l(!1),Z=l(null),Q=l(null),ae=l(!1),$=l(!1),ce=l(!1),le=l(0),ue=null,de=y(()=>ce.value?8:4),fe=y(()=>{let e=Y.value.trim();return!e||e.length>de.value?!1:/^[0-9a-fA-F]+$/.test(e)}),pe=y(()=>{let e=Y.value.trim().length;return e===0?``:e===1?`Very fast — ~16 attempts on average`:e===2?`Fast — ~256 attempts on average`:e===3?`Moderate — ~4,096 attempts, a few seconds`:e===4?`Slow — ~65,536 attempts, may take 10-30 seconds`:e===5?`Very slow — ~1 million attempts, could take minutes`:e===6?`Extremely slow — ~16 million attempts, could take a very long time`:e===7?`Extreme — ~268 million attempts, may not complete`:`Extreme — ~4 billion attempts, extremely unlikely to complete`}),me=()=>{le.value=0,ue=setInterval(()=>{le.value++},1e3)},he=()=>{ue&&=(clearInterval(ue),null)};w(()=>he());let ge=()=>{Y.value=``,Z.value=null,Q.value=null,ae.value=!1,ce.value=!1,J.value=!0},_e=async()=>{X.value=!0,Q.value=null,Z.value=null,me();try{let e=await M.generateVanityKey(Y.value.trim());e.success&&e.data?Z.value=e.data:Q.value=e.error||`Generation failed`}catch(e){let t=e;Q.value=t.response?.data?.error||t.message||`Generation failed`}finally{he(),X.value=!1}},ve=async()=>{if(Z.value){$.value=!0,Q.value=null;try{let e=await M.generateVanityKey(Y.value.trim(),!0);e.success&&e.data?(Z.value=e.data,ae.value=!1,J.value=!1,E.value=`New identity key applied. Restart the repeater for the change to take effect.`,await r.fetchStats(),setTimeout(()=>{E.value=null},8e3)):Q.value=e.error||`Failed to apply key`}catch(e){let t=e;Q.value=t.response?.data?.error||t.message||`Failed to apply key`}finally{$.value=!1}}},{showUnsavedModal:ye,requestLeave:be,handleDiscard:xe,handleSave:Se}=se(d,f,ne,async()=>(await q(),!d.value));return n({requestLeave:be,isEditing:d}),(e,n)=>(h(),C(x,null,[_(oe,{show:v(ye),"is-saving":f.value,label:`Repeater Settings`,onDiscard:v(xe),onSave:v(Se)},null,8,[`show`,`is-saving`,`onDiscard`,`onSave`]),S(`div`,He,[S(`div`,Ue,[n[13]||=S(`div`,null,[S(`h3`,{class:`text-base sm:text-lg font-semibold text-content-primary dark:text-content-primary mb-1 sm:mb-2`},`Repeater Settings`),S(`p`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Configure repeater identity, location, and network settings`)],-1),S(`div`,We,[d.value?(h(),C(x,{key:1},[S(`button`,{onClick:ne,disabled:f.value,class:`cfg-btn-secondary`},` Cancel `,8,Ge),S(`button`,{onClick:q,disabled:f.value,class:`cfg-btn-primary`},t(f.value?`Saving...`:`Save Changes`),9,Ke)],64)):(h(),C(`button`,{key:0,onClick:te,class:`cfg-btn-primary`},` Edit Settings `))])]),E.value?(h(),C(`div`,qe,[S(`p`,Je,t(E.value),1)])):g(``,!0),m.value?(h(),C(`div`,Ye,[S(`p`,Xe,t(m.value),1)])):g(``,!0),S(`div`,Ze,[n[23]||=S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary pb-2`},`General Settings`,-1),S(`div`,Qe,[n[14]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Node Name`,-1),d.value?c((h(),C(`input`,{key:1,"onUpdate:modelValue":n[0]||=e=>O.value=e,type:`text`,maxlength:`50`,class:`cfg-input w-full sm:w-64`,placeholder:`Enter node name`},null,512)),[[U,O.value]]):(h(),C(`div`,$e,t(I.value),1))]),S(`div`,et,[n[15]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Local Hash`,-1),S(`span`,tt,t(L.value),1)]),S(`div`,nt,[n[16]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm flex-shrink-0`},`Public Key`,-1),S(`div`,rt,[S(`span`,it,t(B.value),1),d.value?(h(),C(`button`,{key:0,onClick:ge,class:`flex-shrink-0 px-2 py-1 text-xs bg-primary/10 hover:bg-primary/20 text-content-secondary dark:text-content-muted rounded border border-primary/30 transition-colors whitespace-nowrap`},` Generate New Key `)):g(``,!0)])]),S(`div`,at,[n[17]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Mode`,-1),S(`span`,ot,t(ee.value),1)]),S(`div`,st,[n[19]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Path hash length`,-1),d.value?c((h(),C(`select`,{key:1,"onUpdate:modelValue":n[1]||=e=>P.value=e,class:`cfg-select w-full sm:w-32`},[...n[18]||=[S(`option`,{value:1},`1 byte`,-1),S(`option`,{value:2},`2 bytes`,-1),S(`option`,{value:3},`3 bytes`,-1)]],512)),[[R,P.value,void 0,{number:!0}]]):(h(),C(`div`,ct,t(K.value),1))]),S(`div`,lt,[S(`div`,ut,[n[21]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Periodic Advertisement Interval`,-1),d.value?(h(),C(`div`,ft,[c(S(`input`,{"onUpdate:modelValue":n[2]||=e=>j.value=e,type:`number`,min:`0`,max:`48`,class:`cfg-input w-20`},null,512),[[U,j.value,void 0,{number:!0}]]),n[20]||=S(`span`,{class:`text-content-muted dark:text-content-muted text-sm`},`hours`,-1)])):(h(),C(`div`,dt,t(W.value),1))]),n[22]||=S(`span`,{class:`text-content-muted dark:text-content-muted text-xs`},`How often the repeater sends an advertisement packet (0 = disabled, 3-48 hours)`,-1)])]),S(`div`,pt,[S(`div`,mt,[n[25]||=S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-3`},`Location Settings`,-1),d.value?(h(),C(`button`,{key:0,onClick:re,class:`btn-primary flex items-center gap-2`,title:`Pick location on map`},[...n[24]||=[S(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z`}),S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M15 11a3 3 0 11-6 0 3 3 0 016 0z`})],-1),b(` Pick Location on Map `,-1)]])):g(``,!0)]),S(`div`,ht,[n[26]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Manual Latitude`,-1),d.value?c((h(),C(`input`,{key:1,"onUpdate:modelValue":n[3]||=e=>k.value=e,type:`number`,step:`0.000001`,min:`-90`,max:`90`,class:`cfg-input w-full sm:w-48`},null,512)),[[U,k.value,void 0,{number:!0}]]):(h(),C(`div`,gt,t(V.value),1))]),S(`div`,_t,[n[27]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Manual Longitude`,-1),d.value?c((h(),C(`input`,{key:1,"onUpdate:modelValue":n[4]||=e=>A.value=e,type:`number`,step:`0.000001`,min:`-180`,max:`180`,class:`cfg-input w-full sm:w-48`},null,512)),[[U,A.value,void 0,{number:!0}]]):(h(),C(`div`,vt,t(H.value),1))])]),_(G,{"is-open":D.value,latitude:k.value,longitude:A.value,onClose:n[5]||=e=>D.value=!1,onSelect:ie},null,8,[`is-open`,`latitude`,`longitude`]),(h(),u(p,{to:`body`},[J.value?(h(),C(`div`,{key:0,class:`fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm`,onClick:n[12]||=z(e=>J.value=!1,[`self`])},[S(`div`,yt,[n[35]||=S(`h3`,{class:`text-xl font-semibold text-content-primary dark:text-content-primary`},` Generate Vanity Identity Key `,-1),n[36]||=S(`p`,{class:`text-xs text-content-muted dark:text-content-muted`},` Generate a new Ed25519 identity key whose public key starts with your chosen hex prefix (0-9, A-F). Longer prefixes take more time to find. `,-1),S(`div`,null,[S(`label`,bt,`Hex Prefix (1-`+t(de.value)+` characters)`,1),c(S(`input`,{"onUpdate:modelValue":n[6]||=e=>Y.value=e,type:`text`,maxlength:de.value,placeholder:`e.g. F8A1`,disabled:X.value,class:`cfg-input py-2 placeholder-gray-400 dark:placeholder-white/40 font-mono uppercase disabled:opacity-50`},null,8,xt),[[U,Y.value]]),Y.value&&!fe.value?(h(),C(`p`,St,` Enter 1-`+t(de.value)+` valid hex characters (0-9, A-F) `,1)):pe.value?(h(),C(`p`,Ct,t(pe.value),1)):g(``,!0)]),S(`div`,null,[S(`button`,{onClick:n[7]||=e=>ce.value=!ce.value,disabled:X.value,class:`text-xs text-content-muted dark:text-content-muted hover:text-content-secondary dark:hover:text-content-secondary transition-colors disabled:opacity-50 flex items-center gap-1`},[(h(),C(`svg`,{class:T([`w-3 h-3 transition-transform`,{"rotate-90":ce.value}]),fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[...n[28]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M9 5l7 7-7 7`},null,-1)]],2)),n[29]||=b(` Advanced `,-1)],8,wt),ce.value?(h(),C(`div`,Tt,[...n[30]||=[S(`p`,{class:`text-amber-600 dark:text-amber-400 text-xs font-medium`},` Extended prefix mode (up to 8 characters) `,-1),S(`p`,{class:`text-amber-600 dark:text-amber-500 text-xs mt-1`},` Prefixes longer than 4 characters require exponentially more attempts and can take a very long time or may not complete at all. The request may time out. `,-1)]])):g(``,!0)]),X.value?(h(),C(`div`,Et,[n[31]||=S(`svg`,{class:`animate-spin h-5 w-5 text-blue-500 flex-shrink-0`,xmlns:`http://www.w3.org/2000/svg`,fill:`none`,viewBox:`0 0 24 24`},[S(`circle`,{class:`opacity-25`,cx:`12`,cy:`12`,r:`10`,stroke:`currentColor`,"stroke-width":`4`}),S(`path`,{class:`opacity-75`,fill:`currentColor`,d:`M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z`})],-1),S(`div`,null,[S(`p`,Dt,` Searching for key with prefix "`+t(Y.value.toUpperCase())+`"... `,1),S(`p`,Ot,` Elapsed: `+t(le.value)+`s `,1)])])):g(``,!0),Q.value?(h(),C(`div`,kt,[S(`p`,At,t(Q.value),1)])):g(``,!0),Z.value?(h(),C(`div`,jt,[S(`p`,Mt,` Key found in `+t(Z.value.attempts.toLocaleString())+` attempts `,1),S(`div`,null,[n[32]||=S(`span`,{class:`text-xs text-content-muted dark:text-content-muted`},`Public Key:`,-1),S(`p`,Nt,t(Z.value.public_hex),1)])])):g(``,!0),ae.value&&Z.value?(h(),C(`div`,Pt,[n[33]||=S(`p`,{class:`text-amber-600 dark:text-amber-400 text-sm font-medium`},` Warning: This will replace your current identity key. `,-1),n[34]||=S(`p`,{class:`text-amber-600 dark:text-amber-500 text-xs mt-1`},` Your node address and public key will change. Other nodes will need to re-discover you. This cannot be undone unless you have a backup. `,-1),S(`div`,Ft,[S(`button`,{onClick:ve,disabled:$.value,class:`px-3 py-1.5 bg-red-600 hover:bg-red-700 text-white rounded-lg text-xs transition-colors disabled:opacity-50`},t($.value?`Applying...`:`Confirm Replace Key`),9,It),S(`button`,{onClick:n[8]||=e=>ae.value=!1,disabled:$.value,class:`px-3 py-1.5 bg-background-mute dark:bg-white/5 hover:bg-stroke-subtle dark:hover:bg-white/10 text-content-primary dark:text-content-primary rounded-lg border border-stroke-subtle dark:border-stroke/20 text-xs transition-colors`},` Cancel `,8,Lt)])])):g(``,!0),S(`div`,Rt,[S(`button`,{onClick:n[9]||=e=>J.value=!1,disabled:X.value,class:`px-4 py-2 bg-background-mute dark:bg-white/5 hover:bg-stroke-subtle dark:hover:bg-white/10 text-content-primary dark:text-content-primary rounded-lg border border-stroke-subtle dark:border-stroke/10 transition-colors`},` Close `,8,zt),Z.value?(h(),C(x,{key:1},[S(`button`,{onClick:n[10]||=e=>{Z.value=null,Q.value=null},class:`btn-primary`},` Try Again `),ae.value?g(``,!0):(h(),C(`button`,{key:0,onClick:n[11]||=e=>ae.value=!0,class:`px-4 py-2 bg-red-600/20 hover:bg-red-600/30 text-red-600 dark:text-red-400 rounded-lg border border-red-500/50 text-sm transition-colors`},` Apply Key `))],64)):(h(),C(`button`,{key:0,onClick:_e,disabled:!fe.value||X.value,class:`btn-primary`},t(X.value?`Generating...`:`Generate`),9,Bt))])])])):g(``,!0)]))])],64))}}),Ht={class:`space-y-12`},Ut={class:`cfg-page-heading flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},Wt={class:`flex items-center gap-2 flex-shrink-0`},Gt=[`disabled`],Kt=[`disabled`],qt={key:0,class:`bg-green-100 dark:bg-green-500/20 border border-green-500 dark:border-green-500/50 rounded-lg p-3 text-green-700 dark:text-green-400 text-sm`},Jt={key:1,class:`bg-red-100 dark:bg-red-500/20 border border-red-500 dark:border-red-500/50 rounded-lg p-3 text-red-700 dark:text-red-400 text-sm`},Yt={class:`cfg-section`},Xt={class:`space-y-3`},Zt={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},Qt={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},$t={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 gap-1`},en={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},tn=f({__name:`DutyCycle`,setup(e,{expose:n}){let r=N(),i=y(()=>r.stats?.config?.duty_cycle||{}),a=y(()=>{let e=i.value.max_airtime_percent;return typeof e==`number`?e.toFixed(1)+`%`:e&&typeof e==`object`&&`parsedValue`in e?(e.parsedValue||0).toFixed(1)+`%`:`Not set`}),o=y(()=>i.value.enforcement_enabled?`Enabled`:`Disabled`),s=l(!1),u=l(!1),d=l(``),f=l(``),p=l(0),m=l(!0),b=()=>{let e=i.value.max_airtime_percent;typeof e==`number`?p.value=e:e&&typeof e==`object`&&`parsedValue`in e?p.value=e.parsedValue||0:p.value=6,m.value=i.value.enforcement_enabled!==!1,s.value=!0,d.value=``,f.value=``},w=()=>{s.value=!1,d.value=``,f.value=``},{showUnsavedModal:T,requestLeave:E,handleDiscard:D,handleSave:O}=se(s,u,w,async()=>(await k(),!s.value));n({requestLeave:E,isEditing:s});let k=async()=>{u.value=!0,f.value=``,d.value=``;try{let e=(await j.post(`/api/update_duty_cycle_config`,{max_airtime_percent:p.value,enforcement_enabled:m.value})).data;e.message||e.persisted?(d.value=e.message||`Settings saved successfully`,s.value=!1,await r.fetchStats(),setTimeout(()=>{d.value=``},3e3)):f.value=`Failed to save settings`}catch(e){console.error(`Failed to save duty cycle settings:`,e),f.value=e.response?.data?.error||`Failed to save settings`}finally{u.value=!1}};return(e,n)=>(h(),C(x,null,[_(oe,{show:v(T),"is-saving":u.value,label:`Duty Cycle settings`,onDiscard:v(D),onSave:v(O)},null,8,[`show`,`is-saving`,`onDiscard`,`onSave`]),S(`div`,Ht,[S(`div`,Ut,[n[2]||=S(`div`,null,[S(`h3`,{class:`text-base sm:text-lg font-semibold text-content-primary dark:text-content-primary mb-1 sm:mb-2`},`Duty Cycle`),S(`p`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Configure duty cycle limits for channel activity`)],-1),S(`div`,Wt,[s.value?(h(),C(x,{key:1},[S(`button`,{onClick:w,disabled:u.value,class:`cfg-btn-secondary`},` Cancel `,8,Gt),S(`button`,{onClick:k,disabled:u.value,class:`cfg-btn-primary`},t(u.value?`Saving...`:`Save Changes`),9,Kt)],64)):(h(),C(`button`,{key:0,onClick:b,class:`cfg-btn-primary`},` Edit Settings `))])]),d.value?(h(),C(`div`,qt,t(d.value),1)):g(``,!0),f.value?(h(),C(`div`,Jt,t(f.value),1)):g(``,!0),S(`div`,Yt,[S(`div`,Xt,[S(`div`,Zt,[n[3]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Max Airtime %`,-1),s.value?c((h(),C(`input`,{key:1,"onUpdate:modelValue":n[0]||=e=>p.value=e,type:`number`,step:`0.1`,min:`0.1`,max:`100`,class:`cfg-input w-full sm:w-32`},null,512)),[[U,p.value,void 0,{number:!0}]]):(h(),C(`div`,Qt,t(a.value),1))]),S(`div`,$t,[n[5]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Enforcement`,-1),s.value?c((h(),C(`select`,{key:1,"onUpdate:modelValue":n[1]||=e=>m.value=e,class:`cfg-select w-full sm:w-32`},[...n[4]||=[S(`option`,{value:!0},`Enabled`,-1),S(`option`,{value:!1},`Disabled`,-1)]],512)),[[R,m.value]]):(h(),C(`div`,en,t(o.value),1))])])])])],64))}}),nn={class:`space-y-12`},rn={class:`cfg-page-heading flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},an={class:`flex items-center gap-2 flex-shrink-0`},on=[`disabled`],sn=[`disabled`],cn={key:0,class:`bg-green-100 dark:bg-green-500/20 border border-green-500 dark:border-green-500/50 rounded-lg p-3 text-green-700 dark:text-green-400 text-sm`},ln={key:1,class:`bg-red-100 dark:bg-red-500/20 border border-red-500 dark:border-red-500/50 rounded-lg p-3 text-red-700 dark:text-red-400 text-sm`},un={class:`cfg-section space-y-3`},dn={class:`flex flex-col sm:flex-row sm:items-center sm:justify-between py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-3`},fn={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm flex-shrink-0`},pn={class:`flex flex-col sm:flex-row sm:items-center sm:justify-between py-2 gap-3`},mn={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm flex-shrink-0`},hn=f({__name:`TransmissionDelays`,setup(e,{expose:n}){let r=N(),i=y(()=>r.stats?.config?.delays||{}),a=y(()=>{let e=i.value.tx_delay_factor;if(typeof e==`number`)return e.toFixed(2)+`x`;if(e&&typeof e==`object`&&`parsedValue`in e){let t=e.parsedValue;if(typeof t==`number`)return t.toFixed(2)+`x`}return`Not set`}),o=y(()=>{let e=i.value.direct_tx_delay_factor;return typeof e==`number`?e.toFixed(2)+`s`:`Not set`}),s=l(!1),u=l(!1),d=l(``),f=l(``),p=l(0),m=l(0),b=()=>{let e=i.value.tx_delay_factor;e&&typeof e==`object`&&`parsedValue`in e?p.value=e.parsedValue||1:typeof e==`number`?p.value=e:p.value=1;let t=i.value.direct_tx_delay_factor;m.value=typeof t==`number`?t:.5,s.value=!0,d.value=``,f.value=``},w=()=>{s.value=!1,d.value=``,f.value=``},T=async()=>{u.value=!0,f.value=``,d.value=``;try{let e=(await j.post(`/api/update_radio_config`,{tx_delay_factor:p.value,direct_tx_delay_factor:m.value})).data,t=e?.data??e;e.success||t.persisted||t.message?(d.value=t.message||`Settings saved successfully`,s.value=!1,await r.fetchStats(),setTimeout(()=>{d.value=``},3e3)):f.value=`Failed to save settings`}catch(e){console.error(`Failed to save delay settings:`,e),f.value=e.response?.data?.error||`Failed to save settings`}finally{u.value=!1}},{showUnsavedModal:E,requestLeave:D,handleDiscard:O,handleSave:k}=se(s,u,w,async()=>(await T(),!s.value));return n({requestLeave:D,isEditing:s}),(e,n)=>(h(),C(x,null,[_(oe,{show:v(E),"is-saving":u.value,label:`TX Delay settings`,onDiscard:v(O),onSave:v(k)},null,8,[`show`,`is-saving`,`onDiscard`,`onSave`]),S(`div`,nn,[S(`div`,rn,[n[2]||=S(`div`,null,[S(`h3`,{class:`text-base sm:text-lg font-semibold text-content-primary dark:text-content-primary mb-1 sm:mb-2`},`TX Delays`),S(`p`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Configure transmission delay factors for flood and direct packets`)],-1),S(`div`,an,[s.value?(h(),C(x,{key:1},[S(`button`,{onClick:w,disabled:u.value,class:`cfg-btn-secondary`},` Cancel `,8,on),S(`button`,{onClick:T,disabled:u.value,class:`cfg-btn-primary`},t(u.value?`Saving...`:`Save Changes`),9,sn)],64)):(h(),C(`button`,{key:0,onClick:b,class:`cfg-btn-primary`},` Edit Settings `))])]),d.value?(h(),C(`div`,cn,t(d.value),1)):g(``,!0),f.value?(h(),C(`div`,ln,t(f.value),1)):g(``,!0),S(`div`,un,[S(`div`,dn,[n[3]||=S(`div`,{class:`flex flex-col gap-1`},[S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Flood TX Delay Factor`),S(`span`,{class:`text-content-muted dark:text-content-muted text-xs`},`Scales the airtime-based random transmit window for flood packets. Higher values increase delay spread for collision avoidance.`)],-1),s.value?c((h(),C(`input`,{key:1,"onUpdate:modelValue":n[0]||=e=>p.value=e,type:`number`,step:`0.1`,min:`0`,max:`5`,class:`cfg-input w-full sm:w-32 flex-shrink-0`},null,512)),[[U,p.value,void 0,{number:!0}]]):(h(),C(`div`,fn,t(a.value),1))]),S(`div`,pn,[n[4]||=S(`div`,{class:`flex flex-col gap-1`},[S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Direct TX Delay Factor`),S(`span`,{class:`text-content-muted dark:text-content-muted text-xs`},`Fixed delay in seconds before transmitting direct-routed packets. Applied as-is with no randomisation.`)],-1),s.value?c((h(),C(`input`,{key:1,"onUpdate:modelValue":n[1]||=e=>m.value=e,type:`number`,step:`0.1`,min:`0`,max:`5`,class:`cfg-input w-full sm:w-32 flex-shrink-0`},null,512)),[[U,m.value,void 0,{number:!0}]]):(h(),C(`div`,mn,t(o.value),1))])])])],64))}}),gn=D(`treeState`,()=>{let e=i(new Set),t=i({value:null}),n=t=>{e.add(t)},r=t=>{e.delete(t)};return{expandedNodes:e,selectedNodeId:t,addExpandedNode:n,removeExpandedNode:r,isNodeExpanded:t=>e.has(t),setSelectedNode:e=>{t.value=e},toggleExpanded:t=>{e.has(t)?r(t):n(t)}}}),_n={class:`select-none`},vn={class:`flex-shrink-0`},yn={key:0,class:`w-3.5 h-3.5 sm:w-4 sm:h-4 text-secondary`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},bn={key:1,class:`w-3.5 h-3.5 sm:w-4 sm:h-4 text-accent-green`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},xn={key:0,class:`hidden sm:flex items-center gap-1 ml-2`},Sn={class:`relative group`},Cn=[`title`],wn={key:0,class:`text-xs font-mono text-content-secondary dark:text-white/50 bg-stroke-subtle/40 dark:bg-white/5 px-1.5 py-0.5 rounded border border-stroke-subtle dark:border-white/10`},Tn={class:`flex justify-between items-start mb-4`},En={class:`bg-black/20 border border-white/10 rounded-md p-4 mb-4`},Dn={class:`text-sm font-mono text-white/80 break-all leading-relaxed`},On={class:`flex items-center gap-2 sm:gap-3 ml-auto flex-shrink-0`},kn={key:0,class:`hidden sm:flex items-center gap-1`},An=[`title`],jn={key:1,class:`hidden sm:flex items-center gap-1`},Mn={key:3,class:`hidden sm:inline-block px-2 py-1 bg-stroke-subtle dark:bg-white/10 text-content-secondary dark:text-white/60 text-xs rounded-full ml-1`},Nn={key:0,class:`space-y-1`},Pn=F(f({__name:`TreeNode`,props:{node:{},selectedNodeId:{},level:{},disabled:{type:Boolean},unlocked:{type:Boolean}},emits:[`select`,`edit`,`delete`],setup(n,{emit:r}){let i=n,o=r,s=gn(),c=l(!1),d=y({get:()=>s.isNodeExpanded(i.node.id),set:e=>{e?s.addExpandedNode(i.node.id):s.removeExpandedNode(i.node.id)}}),f=y(()=>i.node.children.length>0);function p(){i.unlocked&&E(),f.value&&w()}function w(){f.value&&(d.value=!d.value)}function E(){o(`select`,i.node.id)}function D(e){o(`select`,e)}function O(e){o(`edit`,e)}function k(e){o(`delete`,e)}function A(e){e.stopPropagation(),c.value=!c.value}function j(e){e.stopPropagation(),i.node.transport_key&&window.navigator?.clipboard&&window.navigator.clipboard.writeText(i.node.transport_key)}return(r,s)=>{let l=a(`TreeNode`,!0);return h(),C(`div`,_n,[S(`div`,{class:T([`flex flex-wrap sm:flex-nowrap items-start sm:items-center gap-1 sm:gap-2 py-2 px-2 sm:px-3 rounded-lg border transition-colors duration-150`,i.disabled?`opacity-50`:``,i.unlocked&&n.selectedNodeId===n.node.id?`bg-primary/10 border-primary/30 text-content-primary dark:text-white`:`cfg-card text-content-primary dark:text-white/80`,i.unlocked&&n.selectedNodeId!==n.node.id?`hover:bg-stroke-subtle/40 dark:hover:bg-white/5 hover:border-stroke dark:hover:border-white/15`:``,f.value&&!i.disabled?`cursor-pointer`:``,`ml-${n.level*4}`]),onClick:s[5]||=z(e=>!i.disabled&&p(),[`stop`])},[S(`div`,{class:`flex-shrink-0 w-3 h-3 sm:w-4 sm:h-4 flex items-center justify-center`,onClick:z(w,[`stop`])},[f.value?(h(),C(`svg`,{key:0,class:T([`w-2.5 h-2.5 sm:w-3 sm:h-3 transition-transform duration-200`,d.value?`rotate-90`:`rotate-0`]),fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[...s[6]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M9 5l7 7-7 7`},null,-1)]],2)):g(``,!0)]),S(`div`,vn,[i.node.name.startsWith(`#`)?(h(),C(`svg`,yn,[...s[7]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M7 20l4-16m2 16l4-16M6 9h14M4 15h14`},null,-1)]])):(h(),C(`svg`,bn,[...s[8]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z`},null,-1)]]))]),S(`span`,{class:T([`font-mono text-xs sm:text-sm transition-colors duration-200 break-all`,n.selectedNodeId===n.node.id?`text-primary font-medium`:``])},t(n.node.name.startsWith(`#`)?n.node.name.slice(1):n.node.name),3),n.node.transport_key?(h(),C(`div`,xn,[S(`div`,Sn,[S(`button`,{onClick:A,class:`p-1 rounded hover:bg-stroke-subtle dark:hover:bg-white/10 transition-colors`,title:c.value?`Hide full key`:`Show full key`},[...s[9]||=[S(`svg`,{class:`w-3 h-3 text-content-muted dark:text-white/60 hover:text-content-secondary dark:hover:text-white/80`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M15 12a3 3 0 11-6 0 3 3 0 016 0z`}),S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z`})],-1)]],8,Cn),c.value?g(``,!0):(h(),C(`span`,wn,t(v(te)(n.node.transport_key)),1)),c.value?(h(),C(`div`,{key:1,class:`fixed inset-0 z-[300] flex items-center justify-center bg-black/70 backdrop-blur-md`,onClick:s[2]||=e=>c.value=!1},[S(`div`,{class:`bg-black/20 border border-white/20 rounded-lg shadow-lg p-6 max-w-2xl w-full mx-4`,onClick:s[1]||=z(()=>{},[`stop`])},[S(`div`,Tn,[s[11]||=S(`h3`,{class:`text-lg font-semibold text-white`},`Transport Key`,-1),S(`button`,{onClick:s[0]||=e=>c.value=!1,class:`text-white/60 hover:text-white transition-colors`},[...s[10]||=[S(`svg`,{class:`w-5 h-5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M6 18L18 6M6 6l12 12`})],-1)]])]),S(`div`,En,[S(`div`,Dn,t(n.node.transport_key),1)]),S(`div`,{class:`flex justify-end`},[S(`button`,{onClick:j,class:`btn-success flex items-center gap-2`,title:`Copy to clipboard`},[...s[12]||=[S(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z`})],-1),b(` Copy Key `,-1)]])])])])):g(``,!0)])])):g(``,!0),S(`div`,On,[n.node.last_used?(h(),C(`div`,kn,[s[13]||=S(`span`,{class:`text-xs text-content-muted dark:text-white/40`},`Last Heard:`,-1),S(`span`,{class:`text-xs text-content-secondary dark:text-white/50`,title:n.node.last_used.toLocaleString()},t(v(K)(n.node.last_used)),9,An)])):(h(),C(`div`,jn,[...s[14]||=[S(`span`,{class:`text-xs text-content-muted dark:text-white/30`},`Last Heard:`,-1),S(`span`,{class:`text-xs text-content-muted dark:text-white/30 italic`},`Never`,-1)]])),S(`span`,{class:T([`text-[10px] sm:text-xs`,n.node.floodPolicy===`allow`?`text-accent-green/80`:`text-accent-red/80`])},` Flood: `+t(n.node.floodPolicy===`allow`?`Allow`:`Deny`),3),i.unlocked?(h(),C(x,{key:2},[S(`button`,{onClick:s[3]||=z(e=>o(`edit`,n.node.id),[`stop`]),class:`px-2 py-0.5 text-[10px] sm:text-xs bg-primary/10 hover:bg-primary/20 text-content-secondary dark:text-content-muted rounded border border-primary/30 transition-colors whitespace-nowrap`},` Edit `),S(`button`,{onClick:s[4]||=z(e=>o(`delete`,n.node.id),[`stop`]),class:`p-1 text-accent-red/50 hover:text-accent-red transition-colors`,title:`Delete`},[...s[15]||=[S(`svg`,{class:`w-3.5 h-3.5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16`})],-1)]])],64)):g(``,!0),f.value&&!i.unlocked?(h(),C(`span`,Mn,t(n.node.children.length),1)):g(``,!0)])],2),_(V,{"enter-active-class":`transition-all duration-300 ease-out`,"enter-from-class":`opacity-0 max-h-0 overflow-hidden`,"enter-to-class":`opacity-100 max-h-screen overflow-visible`,"leave-active-class":`transition-all duration-300 ease-in`,"leave-from-class":`opacity-100 max-h-screen overflow-visible`,"leave-to-class":`opacity-0 max-h-0 overflow-hidden`},{default:e(()=>[d.value&&n.node.children.length>0?(h(),C(`div`,Nn,[(h(!0),C(x,null,m(n.node.children,e=>(h(),u(l,{key:e.id,node:e,"selected-node-id":n.selectedNodeId,level:n.level+1,disabled:i.disabled,unlocked:i.unlocked,onSelect:D,onEdit:O,onDelete:k},null,8,[`node`,`selected-node-id`,`level`,`disabled`,`unlocked`]))),128))])):g(``,!0)]),_:1})])}}}),[[`__scopeId`,`data-v-dad29312`]]),Fn={class:`modal-card max-w-md`},In={class:`flex items-center justify-between mb-6`},Ln={class:`text-content-secondary dark:text-content-muted text-sm mt-1`},Rn={key:0},zn={class:`text-primary font-mono`},Bn={key:1},Vn={class:`pb-2`},Hn={class:`flex bg-background-mute dark:bg-stroke/5 rounded-lg border border-stroke-subtle dark:border-stroke/20 p-0.5`},Un={for:`keyName`,class:`block text-sm font-medium text-content-primary dark:text-content-primary mb-2`},Wn={class:`flex items-center`},Gn={key:0,class:`px-3 py-3 bg-secondary/10 border border-r-0 border-secondary/30 rounded-l-lg text-secondary text-sm font-mono`},Kn=[`placeholder`],qn={key:0,class:`text-content-muted dark:text-content-muted text-xs mt-1`},Jn={class:`pt-1 border-t border-stroke-subtle dark:border-stroke/10`},Yn={class:`flex bg-background-mute dark:bg-stroke/5 rounded-lg border border-stroke-subtle dark:border-stroke/20 p-0.5`},Xn={class:`flex gap-3 pt-4`},Zn=[`disabled`],Qn=f({__name:`AddKeyModal`,props:{show:{type:Boolean},selectedNodeName:{},selectedNodeId:{}},emits:[`close`,`add`],setup(e,{emit:n}){let r=e,i=n,a=l(``),o=l(`allow`),s=l(`region`),d=y(()=>s.value===`region`),f=y(()=>({type:d.value?`Region`:`Private Key`,description:d.value?`Regional organisational key`:`Individual assigned key`})),m=y(()=>a.value.trim().length>0),_=()=>{m.value&&(i(`add`,{name:d.value?`#${a.value.trim()}`:a.value.trim(),floodPolicy:o.value,parentId:r.selectedNodeId}),a.value=``,o.value=`allow`,s.value=`region`)},v=()=>{a.value=``,o.value=`allow`,s.value=`region`,i(`close`)};return(n,i)=>(h(),u(p,{to:`body`},[e.show?(h(),C(`div`,{key:0,onClick:i[5]||=z(e=>v(),[`self`]),class:`modal-backdrop`},[S(`div`,Fn,[S(`div`,In,[S(`div`,null,[i[7]||=S(`h3`,{class:`text-xl font-semibold text-content-primary dark:text-content-primary`},` Add New Entry `,-1),S(`p`,Ln,[r.selectedNodeName?(h(),C(`span`,Rn,[i[6]||=b(` Add to: `,-1),S(`span`,zn,t(r.selectedNodeName),1)])):(h(),C(`span`,Bn,` Add to root level (#uk) `))])]),S(`button`,{onClick:v,class:`text-white/60 hover:text-white transition-colors`},[...i[8]||=[S(`svg`,{class:`w-5 h-5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M6 18L18 6M6 6l12 12`})],-1)]])]),S(`form`,{onSubmit:z(_,[`prevent`]),class:`space-y-5`},[S(`div`,Vn,[i[9]||=S(`label`,{class:`block text-sm font-medium text-content-primary dark:text-content-primary mb-2`},` Entry Type `,-1),S(`div`,Hn,[S(`button`,{type:`button`,onClick:i[0]||=e=>s.value=`region`,class:T([`flex-1 px-3 py-1.5 text-xs font-medium rounded transition-colors`,s.value===`region`?`bg-secondary/20 text-secondary border border-secondary/50`:`text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-secondary`])},` REGION `,2),S(`button`,{type:`button`,onClick:i[1]||=e=>s.value=`privateKey`,class:T([`flex-1 px-3 py-1.5 text-xs font-medium rounded transition-colors`,s.value===`privateKey`?`bg-accent-green/20 text-accent-green border border-accent-green/50`:`text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-secondary`])},` PRIVATE KEY `,2)])]),S(`div`,null,[S(`label`,Un,t(f.value.type)+` Name `,1),S(`div`,Wn,[d.value?(h(),C(`span`,Gn,`#`)):g(``,!0),c(S(`input`,{id:`keyName`,"onUpdate:modelValue":i[2]||=e=>a.value=e,type:`text`,placeholder:d.value?`e.g., uk, au, us`:`Enter key name`,class:T([`flex-1 px-4 py-3 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/20 text-content-primary dark:text-content-primary placeholder-gray-500 dark:placeholder-white/50 focus:outline-none focus:border-primary focus:ring-2 focus:ring-primary/20 transition-colors`,d.value?`rounded-r-lg`:`rounded-lg`]),autocomplete:`off`},null,10,Kn),[[U,a.value]])]),d.value?(h(),C(`p`,qn,` The # prefix is added automatically for regions. `)):g(``,!0)]),S(`div`,Jn,[i[10]||=S(`label`,{class:`block text-sm font-medium text-content-primary dark:text-content-primary mb-3 pt-4`},` Flood Policy `,-1),S(`div`,Yn,[S(`button`,{type:`button`,onClick:i[3]||=e=>o.value=`allow`,class:T([`flex-1 px-3 py-1.5 text-xs font-medium rounded transition-colors`,o.value===`allow`?`bg-accent-green/10 text-accent-green border border-accent-green/20`:`text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-secondary`])},` ALLOW `,2),S(`button`,{type:`button`,onClick:i[4]||=e=>o.value=`deny`,class:T([`flex-1 px-3 py-1.5 text-xs font-medium rounded transition-colors`,o.value===`deny`?`bg-accent-red/10 text-accent-red border border-accent-red/20`:`text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-secondary`])},` DENY `,2)])]),S(`div`,Xn,[S(`button`,{type:`button`,onClick:v,class:`flex-1 px-4 py-3 bg-background-mute dark:bg-white/5 hover:bg-stroke-subtle dark:hover:bg-white/10 border border-stroke-subtle dark:border-stroke/20 text-content-primary dark:text-content-primary rounded-lg transition-colors`},` Cancel `),S(`button`,{type:`submit`,disabled:!m.value,class:T([`flex-1 px-4 py-3 rounded-lg transition-colors font-medium`,m.value?`bg-accent-green/20 hover:bg-accent-green/30 border border-accent-green/50 text-accent-green`:`bg-background-mute dark:bg-stroke/5 border border-stroke-subtle dark:border-stroke/20 text-content-muted dark:text-content-muted cursor-not-allowed`])},` Add `+t(f.value.type),11,Zn)])],32)])])):g(``,!0)]))}}),$n={class:`modal-card max-w-lg`},er={class:`flex items-center justify-between mb-6`},tr={class:`text-content-secondary dark:text-content-muted text-sm mt-1`},nr={class:`text-primary font-mono`},rr={class:`pb-2`},ir={class:`flex bg-background-mute dark:bg-stroke/5 rounded-lg border border-stroke-subtle dark:border-stroke/20 p-0.5`},ar={for:`keyName`,class:`block text-sm font-medium text-content-primary dark:text-content-primary mb-2`},or={class:`flex items-center`},sr={key:0,class:`px-3 py-3 bg-secondary/10 border border-r-0 border-secondary/30 rounded-l-lg text-secondary text-sm font-mono`},cr=[`placeholder`],lr={key:0,class:`text-content-muted dark:text-content-muted text-xs mt-1`},ur={key:1,class:`mt-3 bg-background-mute dark:bg-black/20 border border-stroke-subtle dark:border-stroke/10 rounded-md p-3`},dr={class:`flex items-center justify-between mb-1.5`},fr={class:`text-xs font-mono text-content-primary dark:text-content-primary/80 break-all`},pr={key:0,class:`text-xs text-amber-500 dark:text-amber-400 mt-1`},mr={key:0,class:`mt-1 bg-gray-50 dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg p-3`},hr={class:`flex items-center justify-between`},gr={class:`text-right`},_r={class:`text-sm text-content-secondary dark:text-content-muted`},vr={class:`text-xs text-content-muted dark:text-content-muted`},yr={class:`pt-1 border-t border-stroke-subtle dark:border-stroke/10`},br={class:`flex bg-background-mute dark:bg-stroke/5 rounded-lg border border-stroke-subtle dark:border-stroke/20 p-0.5`},xr={class:`flex gap-3 pt-4`},Sr=[`disabled`],Cr=f({__name:`EditKeyModal`,props:{show:{type:Boolean},node:{}},emits:[`close`,`save`],setup(e,{emit:n}){let r=e,i=n,a=l(``),s=l(`allow`),d=l(`region`),f=y(()=>d.value===`region`),m=y(()=>({type:f.value?`Region`:`Private Key`,description:f.value?`Regional organisational key`:`Individual assigned key`}));o(()=>r.node,e=>{if(e){let t=e.name.startsWith(`#`);d.value=t?`region`:`privateKey`,a.value=t?e.name.slice(1):e.name,s.value=e.floodPolicy}else a.value=``,s.value=`allow`,d.value=`region`},{immediate:!0});let _=y(()=>a.value.trim().length>0&&r.node),x=y(()=>{let e=a.value.trim();return e?f.value?`#${e}`:e:r.node?.name||``}),w=y(()=>r.node?r.node.name.startsWith(`#`)?r.node.name.slice(1):r.node.name:``),D=y(()=>a.value.trim()!==w.value);async function O(e){let t=e.startsWith(`#`)?e:`#${e}`,n=new TextEncoder().encode(t),r=await crypto.subtle.digest(`SHA-256`,n),i=new Uint8Array(r).slice(0,16),a=``;return i.forEach(e=>{a+=String.fromCharCode(e)}),btoa(a)}let k=l(null);E(async()=>{let e=a.value.trim();if(!f.value||!e){k.value=null;return}k.value=await O(e)});let A=e=>{window.navigator?.clipboard&&window.navigator.clipboard.writeText(e)},j=async()=>{if(!_.value||!r.node)return;let e=f.value?`#${a.value.trim()}`:a.value.trim(),t=f.value&&D.value?k.value??await O(a.value.trim()):void 0;i(`save`,{id:r.node.id,name:e,floodPolicy:s.value,transportKey:t}),M()},M=()=>{i(`close`)};return(n,r)=>(h(),u(p,{to:`body`},[e.show?(h(),C(`div`,{key:0,onClick:r[6]||=z(e=>M(),[`self`]),class:`modal-backdrop`},[S(`div`,$n,[S(`div`,er,[S(`div`,null,[r[8]||=S(`h3`,{class:`text-xl font-semibold text-content-primary dark:text-content-primary`},` Edit Entry `,-1),S(`p`,tr,[r[7]||=b(` Modify `,-1),S(`span`,nr,t(x.value),1)])]),S(`button`,{onClick:M,class:`text-white/60 hover:text-white transition-colors`},[...r[9]||=[S(`svg`,{class:`w-5 h-5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M6 18L18 6M6 6l12 12`})],-1)]])]),S(`form`,{onSubmit:z(j,[`prevent`]),class:`space-y-5`},[S(`div`,rr,[r[10]||=S(`label`,{class:`block text-sm font-medium text-content-primary dark:text-content-primary mb-2`},` Entry Type `,-1),S(`div`,ir,[S(`button`,{type:`button`,onClick:r[0]||=e=>d.value=`region`,class:T([`flex-1 px-3 py-1.5 text-xs font-medium rounded transition-colors`,d.value===`region`?`bg-secondary/20 text-secondary border border-secondary/50`:`text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-secondary`])},` REGION `,2),S(`button`,{type:`button`,onClick:r[1]||=e=>d.value=`privateKey`,class:T([`flex-1 px-3 py-1.5 text-xs font-medium rounded transition-colors`,d.value===`privateKey`?`bg-accent-green/20 text-accent-green border border-accent-green/50`:`text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-secondary`])},` PRIVATE KEY `,2)])]),S(`div`,null,[S(`label`,ar,t(m.value.type)+` Name `,1),S(`div`,or,[f.value?(h(),C(`span`,sr,`#`)):g(``,!0),c(S(`input`,{id:`keyName`,"onUpdate:modelValue":r[2]||=e=>a.value=e,type:`text`,placeholder:f.value?`e.g., uk, au, us`:`Enter key name`,class:T([`flex-1 px-4 py-3 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/20 text-content-primary dark:text-content-primary placeholder-gray-500 dark:placeholder-white/50 focus:outline-none focus:border-primary focus:ring-2 focus:ring-primary/20 transition-colors`,f.value?`rounded-r-lg`:`rounded-lg`]),autocomplete:`off`},null,10,cr),[[U,a.value]])]),f.value?(h(),C(`p`,lr,` The # prefix is added automatically for regions. `)):g(``,!0),f.value&&e.node?.transport_key?(h(),C(`div`,ur,[S(`div`,dr,[r[12]||=S(`span`,{class:`text-xs font-medium text-content-secondary dark:text-content-muted`},`Transport Key`,-1),D.value?g(``,!0):(h(),C(`button`,{key:0,type:`button`,onClick:r[3]||=t=>A(e.node.transport_key||``),class:`text-xs text-accent-green hover:text-accent-green/80 flex items-center gap-1`,title:`Copy to clipboard`},[...r[11]||=[S(`svg`,{class:`w-3 h-3`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z`})],-1),b(` Copy `,-1)]]))]),S(`div`,fr,t(k.value??e.node.transport_key),1),D.value?(h(),C(`div`,pr,` Updated for "`+t(x.value)+`" `,1)):g(``,!0)])):g(``,!0)]),e.node?.last_used?(h(),C(`div`,mr,[S(`div`,hr,[r[13]||=S(`div`,{class:`flex items-center gap-2`},[S(`svg`,{class:`w-4 h-4 text-primary`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z`})]),S(`span`,{class:`text-sm font-medium text-content-primary dark:text-content-primary`},`Last Used`)],-1),S(`div`,gr,[S(`div`,_r,t(e.node.last_used.toLocaleDateString())+` at `+t(e.node.last_used.toLocaleTimeString()),1),S(`div`,vr,t(v(K)(e.node.last_used)),1)])])])):g(``,!0),S(`div`,yr,[r[14]||=S(`label`,{class:`block text-sm font-medium text-content-primary dark:text-content-primary mb-3 pt-4`},` Flood Policy `,-1),S(`div`,br,[S(`button`,{type:`button`,onClick:r[4]||=e=>s.value=`allow`,class:T([`flex-1 px-3 py-1.5 text-xs font-medium rounded transition-colors`,s.value===`allow`?`bg-accent-green/10 text-accent-green border border-accent-green/20`:`text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-secondary`])},` ALLOW `,2),S(`button`,{type:`button`,onClick:r[5]||=e=>s.value=`deny`,class:T([`flex-1 px-3 py-1.5 text-xs font-medium rounded transition-colors`,s.value===`deny`?`bg-accent-red/10 text-accent-red border border-accent-red/20`:`text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-secondary`])},` DENY `,2)])]),S(`div`,xr,[S(`button`,{type:`button`,onClick:M,class:`flex-1 px-4 py-3 bg-background-mute dark:bg-white/5 hover:bg-stroke-subtle dark:hover:bg-white/10 border border-stroke-subtle dark:border-stroke/20 text-content-primary dark:text-content-primary rounded-lg transition-colors`},` Cancel `),S(`button`,{type:`submit`,disabled:!_.value,class:T([`flex-1 px-4 py-3 rounded-lg transition-colors font-medium`,_.value?`bg-accent-green/20 hover:bg-accent-green/30 border border-accent-green/50 text-accent-green`:`bg-background-mute dark:bg-white/5 border border-stroke-subtle dark:border-stroke/20 text-content-muted dark:text-content-muted/70 cursor-not-allowed`])},` Done `,10,Sr)])],32)])])):g(``,!0)]))}}),wr={class:`modal-card max-w-lg`},Tr={class:`flex items-center gap-3 mb-6`},Er={class:`text-content-secondary dark:text-content-muted text-sm mt-1`},Dr={class:`text-accent-red font-mono`},Or={key:0,class:`bg-accent-red/10 border border-accent-red/30 rounded-lg p-4 mb-6`},kr={class:`flex items-start gap-3`},Ar={class:`flex-1`},jr={class:`text-accent-red font-medium text-sm mb-2`},Mr={class:`space-y-1 max-h-32 overflow-y-auto`},Nr={key:0,class:`w-3 h-3 text-secondary`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},Pr={key:1,class:`w-3 h-3 text-accent-green`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},Fr={class:`font-mono`},Ir={key:0,class:`text-content-secondary dark:text-content-muted text-xs`},Lr={key:1,class:`mb-6`},Rr={class:`mb-3`},zr={class:`relative`},Br={class:`space-y-2 max-h-40 overflow-y-auto border border-stroke-subtle dark:border-stroke/20 rounded-lg p-3 bg-gray-50 dark:bg-white/5`},Vr={key:0,class:`text-center py-4 text-content-secondary dark:text-content-muted text-sm`},Hr={class:`relative`},Ur=[`value`],Wr={class:`flex items-center gap-2 flex-1`},Gr={class:`text-content-primary dark:text-content-primary font-mono text-sm`},Kr={key:0,class:`ml-auto px-2 py-0.5 bg-background-mute dark:bg-stroke/10 text-content-secondary dark:text-content-muted text-xs rounded-full`},qr={class:`flex gap-3`},Jr=f({__name:`DeleteConfirmModal`,props:{show:{type:Boolean},node:{},allNodes:{}},emits:[`close`,`delete-all`,`move-children`],setup(e,{emit:n}){let r=e,i=n,a=l(null),o=l(``),s=e=>{let t=[],n=e=>{for(let r of e.children)t.push(r),n(r)};return n(e),t},d=y(()=>r.node?s(r.node):[]),f=y(()=>{if(!r.node)return[];let e=new Set([r.node.id,...d.value.map(e=>e.id)]),t=n=>{let r=[];for(let i of n)i.name.startsWith(`#`)&&!e.has(i.id)&&r.push(i),i.children.length>0&&r.push(...t(i.children));return r};return t(r.allNodes)}),_=y(()=>{if(!o.value.trim())return f.value;let e=o.value.toLowerCase();return f.value.filter(t=>t.name.toLowerCase().includes(e))}),v=()=>{r.node&&(i(`delete-all`,r.node.id),E())},w=()=>{!r.node||!a.value||(i(`move-children`,{nodeId:r.node.id,targetParentId:a.value}),E())},E=()=>{a.value=null,o.value=``,i(`close`)};return(n,r)=>(h(),u(p,{to:`body`},[e.show&&e.node?(h(),C(`div`,{key:0,onClick:r[2]||=z(e=>E(),[`self`]),class:`modal-backdrop-heavy`},[S(`div`,wr,[S(`div`,Tr,[r[6]||=S(`svg`,{class:`w-6 h-6 text-accent-red`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z`})],-1),S(`div`,null,[r[4]||=S(`h3`,{class:`text-xl font-semibold text-content-primary dark:text-content-primary`},` Confirm Deletion `,-1),S(`p`,Er,[r[3]||=b(` Deleting `,-1),S(`span`,Dr,t(e.node?.name),1)])]),S(`button`,{onClick:E,class:`ml-auto text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-primary transition-colors`},[...r[5]||=[S(`svg`,{class:`w-5 h-5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M6 18L18 6M6 6l12 12`})],-1)]])]),d.value.length>0?(h(),C(`div`,Or,[S(`div`,kr,[r[9]||=S(`svg`,{class:`w-5 h-5 text-accent-red flex-shrink-0 mt-0.5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M12 9v2m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z`})],-1),S(`div`,Ar,[S(`h4`,jr,` This will affect `+t(d.value.length)+` child `+t(d.value.length===1?`entry`:`entries`)+`: `,1),S(`div`,Mr,[(h(!0),C(x,null,m(d.value.slice(0,10),e=>(h(),C(`div`,{key:e.id,class:`flex items-center gap-2 text-xs text-content-secondary dark:text-content-primary/80`},[e.name.startsWith(`#`)?(h(),C(`svg`,Nr,[...r[7]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M7 20l4-16m2 16l4-16M6 9h14M4 15h14`},null,-1)]])):(h(),C(`svg`,Pr,[...r[8]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1721 9z`},null,-1)]])),S(`span`,Fr,t(e.name),1),S(`span`,{class:T([`px-1 py-0.5 text-xs rounded`,e.floodPolicy===`allow`?`bg-accent-green/20 text-accent-green`:`bg-accent-red/20 text-accent-red`])},t(e.floodPolicy),3)]))),128)),d.value.length>10?(h(),C(`div`,Ir,` ...and `+t(d.value.length-10)+` more `,1)):g(``,!0)])])])])):g(``,!0),d.value.length>0&&f.value.length>0?(h(),C(`div`,Lr,[r[13]||=S(`h4`,{class:`text-content-primary dark:text-content-primary font-medium text-sm mb-3`},` Move children to another region: `,-1),S(`div`,Rr,[S(`div`,zr,[r[10]||=S(`svg`,{class:`absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-content-muted dark:text-content-muted`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z`})],-1),c(S(`input`,{"onUpdate:modelValue":r[0]||=e=>o.value=e,type:`text`,placeholder:`Search regions...`,class:`w-full pl-9 pr-4 py-2 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/20 rounded-lg text-content-primary dark:text-content-primary placeholder-gray-500 dark:placeholder-white/50 focus:outline-none focus:border-primary focus:ring-2 focus:ring-primary/20 transition-colors text-sm`},null,512),[[U,o.value]])])]),S(`div`,Br,[_.value.length===0?(h(),C(`div`,Vr,t(o.value?`No regions match your search`:`No available regions`),1)):g(``,!0),(h(!0),C(x,null,m(_.value,e=>(h(),C(`label`,{key:e.id,class:`flex items-center gap-3 p-2 rounded cursor-pointer hover:bg-stroke-subtle dark:hover:bg-white/10 transition-colors group`},[S(`div`,Hr,[c(S(`input`,{type:`radio`,value:e.id,"onUpdate:modelValue":r[1]||=e=>a.value=e,class:`sr-only peer`},null,8,Ur),[[L,a.value]]),r[11]||=S(`div`,{class:`w-4 h-4 border-2 border-stroke dark:border-stroke/30 rounded-full group-hover:border-stroke dark:group-hover:border-stroke/50 peer-checked:border-primary peer-checked:bg-primary/20 transition-all`},[S(`div`,{class:`w-2 h-2 rounded-full bg-primary scale-0 peer-checked:scale-100 transition-transform absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2`})],-1)]),S(`div`,Wr,[r[12]||=S(`svg`,{class:`w-4 h-4 text-secondary`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M7 20l4-16m2 16l4-16M6 9h14M4 15h14`})],-1),S(`span`,Gr,t(e.name),1),e.children.length>0?(h(),C(`span`,Kr,t(e.children.length),1)):g(``,!0)])]))),128))])])):g(``,!0),S(`div`,qr,[S(`button`,{onClick:E,class:`flex-1 px-4 py-3 bg-background-mute dark:bg-white/5 hover:bg-stroke-subtle dark:hover:bg-white/10 border border-stroke-subtle dark:border-stroke/20 text-content-primary dark:text-content-primary rounded-lg transition-colors`},` Cancel `),d.value.length>0&&a.value?(h(),C(`button`,{key:0,onClick:w,class:`modal-btn-primary`},` Move & Delete `)):g(``,!0),S(`button`,{onClick:v,class:`modal-btn-danger`},t(d.value.length>0?`Delete All`:`Delete`),1)])])])):g(``,!0)]))}}),Yr={class:`space-y-12`},Xr={class:`cfg-page-heading flex flex-col sm:flex-row sm:justify-between sm:items-start gap-3`},Zr={class:`flex items-center gap-2 flex-shrink-0`},Qr=[`disabled`],$r=[`disabled`],ei=[`disabled`],ti={key:0,class:`bg-red-100 dark:bg-red-500/20 border border-red-500/50 rounded-lg p-3`},ni={class:`text-red-600 dark:text-red-400 text-sm`},ri={class:`cfg-section`},ii={class:`flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3`},ai={key:0,class:`text-xs text-content-muted dark:text-content-muted pb-1`},oi={key:1,class:`flex items-center justify-center py-8`},si={key:2,class:`text-center py-8`},ci={class:`text-content-secondary dark:text-content-muted text-sm`},li={key:3,class:`text-center py-8`},ui={key:4,class:`space-y-2`},di=f({name:`TransportKeys`,__name:`TransportKeys`,setup(e,{expose:n}){let i=gn(),a=N(),s=l(!1),c=l(!1),d=l(null),f=-1;function p(){return f--}let w=l(`deny`),E=`deny`;o(y(()=>a.stats?.config?.mesh?.unscoped_flood_allow??null),e=>{e!==null&&!s.value&&(w.value=e?`allow`:`deny`)},{immediate:!0});let D=l([]),O=null,k=l(!1),A=l(null),j=l(!1),P=l(!1),F=l(!1),L=l(null),R=l(null);function z(e){return e.map(e=>({...e,children:z(e.children)}))}function B(e,t){let n=[];for(let r of e)n.push({node:r,parentId:t}),n.push(...B(r.children,r.id));return n}function V(e,t){for(let n of e){if(n.id===t)return n;let e=V(n.children,t);if(e)return e}return null}function H(e,t){let n=e.findIndex(e=>e.id===t);if(n!==-1)return e.splice(n,1),!0;for(let n of e)if(H(n.children,t))return!0;return!1}let U=e=>{let t=new Map,n=[];return e.forEach(e=>{t.set(e.id,{id:e.id,name:e.name,floodPolicy:e.flood_policy,transport_key:e.transport_key,last_used:e.last_used?new Date(e.last_used*1e3):void 0,parent_id:e.parent_id,children:[]})}),t.forEach(e=>{e.parent_id&&t.has(e.parent_id)?t.get(e.parent_id).children.push(e):n.push(e)}),n},ee=async()=>{k.value=!0,A.value=null;try{let e=await M.getTransportKeys();e.success&&e.data?D.value=U(e.data):A.value=e.error||`Failed to load regions`}catch(e){A.value=e instanceof Error?e.message:`Unknown error occurred`}finally{k.value=!1}};r(ee);function W(){O=z(D.value),E=w.value,s.value=!0,d.value=null}function G(){O&&(D.value=z(O)),w.value=E,O=null,s.value=!1,d.value=null,i.setSelectedNode(null)}async function K(){c.value=!0,d.value=null;try{let e=B(D.value),t=O?B(O):[],n=new Map(t.map(({node:e})=>[e.id,e])),r=e.filter(({node:e})=>e.id>0),o=e.filter(({node:e})=>e.id<0),c=new Set(r.map(({node:e})=>e.id));for(let{node:e}of t)c.has(e.id)||await M.deleteTransportKey(e.id);let l=new Map,u=[...o],d=u.length*2;for(;u.length&&d-- >0;){let e=u.findIndex(({parentId:e})=>e===void 0||e>0||e<0&&l.has(e));if(e===-1)break;let{node:t,parentId:n}=u.splice(e,1)[0],r=n===void 0?void 0:n>0?n:l.get(n),i=await M.createTransportKey(t.name,t.floodPolicy,t.transport_key,r);i.success&&i.data?.id&&l.set(t.id,i.data.id)}for(let{node:e}of r){let t=n.get(e.id);t&&(e.name!==t.name||e.floodPolicy!==t.floodPolicy||e.transport_key!==t.transport_key)&&await M.updateTransportKey(e.id,e.name,e.floodPolicy,e.transport_key)}w.value!==E&&await M.updateUnscopedFloodPolicy(w.value===`allow`),await ee(),await a.fetchStats(),O=null,s.value=!1,i.setSelectedNode(null)}catch(e){d.value=e instanceof Error?e.message:`Save failed`}finally{c.value=!1}}function te(e){i.setSelectedNode(e)}function ne(){let e=i.selectedNodeId.value;return e?V(D.value,e)?.name:void 0}function q(){j.value=!0}function re(e){let t={id:p(),name:e.name,floodPolicy:e.floodPolicy,children:[]};if(e.parentId){let n=V(D.value,e.parentId);n?n.children.push(t):D.value.push(t)}else D.value.push(t);j.value=!1}function ie(e){let t=V(D.value,e);t&&(L.value=t,P.value=!0)}function J(e){let t=V(D.value,e.id);t&&(t.name=e.name,t.floodPolicy=e.floodPolicy,e.transportKey!==void 0&&(t.transport_key=e.transportKey)),P.value=!1,L.value=null}function Y(){P.value=!1,L.value=null}function X(e){let t=V(D.value,e);t&&(R.value=t,F.value=!0)}function Z(e){H(D.value,e),i.setSelectedNode(null),F.value=!1,R.value=null}function Q(e){let t=V(D.value,e.nodeId);if(t?.children.length){let n=V(D.value,e.targetParentId);n?n.children.push(...t.children):D.value.push(...t.children)}H(D.value,e.nodeId),i.setSelectedNode(null),F.value=!1,R.value=null}function ae(e){w.value=e}let{showUnsavedModal:$,requestLeave:ce,handleDiscard:le,handleSave:ue}=se(s,c,G,async()=>(await K(),!s.value));return n({requestLeave:ce,isEditing:s}),(e,n)=>(h(),C(x,null,[_(oe,{show:v($),"is-saving":c.value,label:`Region Configuration`,onDiscard:v(le),onSave:v(ue)},null,8,[`show`,`is-saving`,`onDiscard`,`onSave`]),S(`div`,Yr,[S(`div`,Xr,[n[6]||=S(`div`,null,[S(`h3`,{class:`text-base sm:text-lg font-semibold text-content-primary dark:text-content-primary mb-1 sm:mb-2`},` Region Configuration `),S(`p`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},` Manage regional key hierarchy `)],-1),S(`div`,Zr,[s.value?(h(),C(`button`,{key:0,onClick:q,class:`cfg-btn-secondary flex items-center gap-1.5`,disabled:c.value},[...n[5]||=[S(`svg`,{class:`w-3.5 h-3.5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M12 4v16m8-8H4`})],-1),b(` Add Region `,-1)]],8,Qr)):g(``,!0),s.value?(h(),C(x,{key:2},[S(`button`,{onClick:G,disabled:c.value,class:`cfg-btn-secondary`},`Cancel`,8,$r),S(`button`,{onClick:K,disabled:c.value,class:`cfg-btn-primary`},t(c.value?`Saving…`:`Save Changes`),9,ei)],64)):(h(),C(`button`,{key:1,onClick:W,class:`cfg-btn-primary`},`Edit Settings`))])]),d.value?(h(),C(`div`,ti,[S(`p`,ni,t(d.value),1)])):g(``,!0),S(`div`,ri,[S(`div`,ii,[n[7]||=S(`div`,null,[S(`h4`,{class:`text-xs sm:text-sm font-medium text-content-primary dark:text-content-primary mb-1`},` Unscoped Flood Policy (*) `),S(`p`,{class:`text-content-secondary dark:text-content-muted text-[10px] sm:text-xs`},` Allow or Deny unscoped flood packets `)],-1),S(`div`,{class:T([`flex bg-background-mute dark:bg-stroke/5 rounded-lg border border-stroke-subtle dark:border-stroke/20 p-0.5 sm:p-1`,s.value?``:`opacity-50 pointer-events-none`])},[S(`button`,{onClick:n[0]||=e=>ae(`deny`),class:T([`px-2 sm:px-3 py-1 text-[10px] sm:text-xs font-medium rounded transition-colors`,w.value===`deny`?`bg-accent-red/20 text-accent-red border border-accent-red/50`:`text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-secondary`])},` DENY `,2),S(`button`,{onClick:n[1]||=e=>ae(`allow`),class:T([`px-2 sm:px-3 py-1 text-[10px] sm:text-xs font-medium rounded transition-colors`,w.value===`allow`?`bg-accent-green/20 text-accent-green border border-accent-green/50`:`text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-secondary`])},` ALLOW `,2)],2)])]),S(`div`,{class:`cfg-section space-y-4`,onClick:n[2]||=e=>s.value&&v(i).setSelectedNode(null)},[n[11]||=S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary`},`Regions`,-1),s.value?(h(),C(`p`,ai,` To add a child region, click on a region to select it, then click "Add Region". `)):g(``,!0),k.value?(h(),C(`div`,oi,[_(I),n[8]||=S(`span`,{class:`ml-2 text-content-secondary dark:text-content-muted`},`Loading regions…`,-1)])):A.value?(h(),C(`div`,si,[n[9]||=S(`div`,{class:`text-accent-red mb-2`},`⚠️ Error loading regions`,-1),S(`div`,ci,t(A.value),1),S(`button`,{onClick:ee,class:`btn-success mt-4`},` Retry `)])):D.value.length===0?(h(),C(`div`,li,[...n[10]||=[S(`div`,{class:`text-content-muted dark:text-content-muted mb-2`},`No regions found`,-1),S(`div`,{class:`text-content-muted dark:text-content-muted/60 text-sm`},` Click "Edit Settings" then "Add Region" to get started `,-1)]])):(h(),C(`div`,ui,[(h(!0),C(x,null,m(D.value,e=>(h(),u(Pn,{key:e.id,node:e,"selected-node-id":v(i).selectedNodeId.value,level:0,unlocked:s.value,onSelect:te,onEdit:ie,onDelete:X},null,8,[`node`,`selected-node-id`,`unlocked`]))),128))]))]),_(Qn,{show:j.value,"selected-node-name":ne(),"selected-node-id":v(i).selectedNodeId.value||void 0,onClose:n[3]||=e=>j.value=!1,onAdd:re},null,8,[`show`,`selected-node-name`,`selected-node-id`]),_(Cr,{show:P.value,node:L.value,onClose:Y,onSave:J},null,8,[`show`,`node`]),_(Jr,{show:F.value,node:R.value,"all-nodes":D.value,onClose:n[4]||=e=>{F.value=!1,R.value=null},onDeleteAll:Z,onMoveChildren:Q},null,8,[`show`,`node`,`all-nodes`])])],64))}}),fi={class:`space-y-12`},pi={class:`cfg-page-heading flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3`},mi={key:0,class:`bg-red-500/10 border border-red-500/30 rounded-lg p-4`},hi={class:`flex items-center gap-2 text-red-600 dark:text-red-400`},gi={key:1,class:`flex items-center justify-center py-12`},_i={class:`text-center`},vi={key:2,class:`space-y-3`},yi={class:`flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3`},bi={class:`flex-1`},xi={class:`flex items-center gap-2 sm:gap-3`},Si={class:`min-w-0 flex-1`},Ci={class:`text-content-primary dark:text-content-primary font-medium text-sm sm:text-base break-all`},wi={class:`flex flex-col sm:flex-row sm:items-center sm:gap-4 mt-1 text-xs text-content-secondary dark:text-content-muted`},Ti={class:`truncate`},Ei={class:`truncate`},Di=[`onClick`,`disabled`],Oi={key:3,class:`text-center py-12`},ki={class:`bg-surface dark:bg-surface-elevated border border-stroke-subtle dark:border-stroke/20 rounded-[15px] p-6 max-w-md w-full shadow-2xl`},Ai={class:`space-y-4`},ji={class:`flex justify-end gap-3 mt-6`},Mi=[`disabled`],Ni=[`disabled`],Pi={class:`bg-surface dark:bg-surface-elevated border border-stroke-subtle dark:border-stroke/20 rounded-[15px] p-6 max-w-lg w-full shadow-2xl`},Fi={class:`space-y-4`},Ii={class:`flex gap-2`},Li=[`value`],Ri={class:`bg-blue-500/10 border border-blue-500/30 rounded-lg p-4`},zi={class:`block bg-blue-500/20 px-3 py-2 rounded text-xs text-blue-100 font-mono overflow-x-auto`},Bi=f({name:`APITokens`,__name:`APITokens`,setup(e){let n=l([]),i=l(!1),a=l(null),o=l(!1),s=l(``),u=l(null),f=l(!1),p=l(!1),v=l(null),w=async()=>{i.value=!0,a.value=null;try{let e=await M.get(`/auth/tokens`);n.value=(e.data||e).tokens||[]}catch(e){console.error(`Failed to fetch API tokens:`,e),a.value=e instanceof Error?e.message:`Failed to fetch tokens`}finally{i.value=!1}},T=async()=>{if(!s.value.trim()){a.value=`Token name is required`;return}i.value=!0,a.value=null;try{let e=await M.post(`/auth/tokens`,{name:s.value.trim()});u.value=(e.data||e).token||null,o.value=!1,f.value=!0,s.value=``,await w()}catch(e){console.error(`Failed to create API token:`,e),a.value=e instanceof Error?e.message:`Failed to create token`}finally{i.value=!1}},E=(e,t)=>{v.value={id:e,name:t},p.value=!0},D=async()=>{if(v.value){i.value=!0,a.value=null;try{await M.delete(`/auth/tokens/${v.value.id}`),await w(),p.value=!1,v.value=null}catch(e){console.error(`Failed to revoke API token:`,e),a.value=e instanceof Error?e.message:`Failed to revoke token`}finally{i.value=!1}}},O=()=>{o.value=!1,s.value=``,a.value=null},k=()=>{f.value=!1,u.value=null},A=()=>{u.value&&navigator.clipboard.writeText(u.value)},j=e=>e?new Date(e*1e3).toLocaleString():`Never`,N=y(()=>`${window.location.origin}/api/stats`);return r(()=>{w()}),(e,r)=>(h(),C(x,null,[S(`div`,fi,[S(`div`,pi,[r[5]||=S(`div`,null,[S(`h2`,{class:`text-lg sm:text-xl font-semibold text-content-primary dark:text-content-primary`},` API Tokens `),S(`p`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm mt-1`},` Manage API tokens for machine-to-machine authentication `)],-1),S(`button`,{onClick:r[0]||=e=>o.value=!0,class:`cfg-btn-primary flex items-center justify-center gap-2`},[...r[4]||=[S(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M12 4v16m8-8H4`})],-1),b(` Create Token `,-1)]])]),r[20]||=d(`<div class="bg-blue-500/10 border border-blue-500/30 rounded-lg p-3 sm:p-4"><div class="flex gap-2 sm:gap-3"><svg class="w-4 h-4 sm:w-5 sm:h-5 text-blue-600 dark:text-blue-400 flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg><div class="text-xs sm:text-sm text-blue-700 dark:text-blue-200"><p><strong>API tokens</strong> are used for machine-to-machine authentication. Include the token in the <code class="bg-blue-500/20 px-1 rounded">X-API-Key</code> header when making API requests. </p><p class="mt-2">Tokens are only shown once at creation. Store them securely.</p></div></div></div>`,1),a.value?(h(),C(`div`,mi,[S(`div`,hi,[r[6]||=S(`svg`,{class:`w-5 h-5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z`})],-1),b(` `+t(a.value),1)])])):g(``,!0),i.value&&n.value.length===0?(h(),C(`div`,gi,[S(`div`,_i,[_(I,{class:`mx-auto mb-4`}),r[7]||=S(`div`,{class:`text-content-secondary dark:text-content-muted`},`Loading tokens...`,-1)])])):n.value.length>0?(h(),C(`div`,vi,[(h(!0),C(x,null,m(n.value,e=>(h(),C(`div`,{key:e.id,class:`bg-background-mute dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg p-3 sm:p-4 hover:bg-stroke-subtle dark:hover:bg-white/10 transition-colors`},[S(`div`,yi,[S(`div`,bi,[S(`div`,xi,[r[8]||=S(`svg`,{class:`w-4 h-4 sm:w-5 sm:h-5 text-primary flex-shrink-0`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z`})],-1),S(`div`,Si,[S(`h3`,Ci,t(e.name),1),S(`div`,wi,[S(`span`,Ti,`Created: `+t(j(e.created_at)),1),S(`span`,Ei,`Last used: `+t(j(e.last_used)),1)])])])]),S(`button`,{onClick:t=>E(e.id,e.name),disabled:i.value,class:`w-full sm:w-auto px-3 py-1.5 bg-red-100 dark:bg-red-500/20 hover:bg-red-500/30 text-red-600 dark:text-red-400 rounded-lg border border-red-500/50 transition-colors disabled:opacity-50 text-sm`},` Revoke `,8,Di)])]))),128))])):(h(),C(`div`,Oi,[r[9]||=S(`svg`,{class:`w-16 h-16 text-content-muted dark:text-content-muted/40 mx-auto mb-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z`})],-1),r[10]||=S(`h3`,{class:`text-content-primary dark:text-content-primary font-medium mb-2`},`No API Tokens`,-1),r[11]||=S(`p`,{class:`text-content-secondary dark:text-content-muted text-sm mb-4`},` Create a token to enable API access `,-1),S(`button`,{onClick:r[1]||=e=>o.value=!0,class:`cfg-btn-primary`},` Create Your First Token `)])),o.value?(h(),C(`div`,{key:4,class:`fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm`,onClick:z(O,[`self`])},[S(`div`,ki,[r[14]||=S(`h3`,{class:`text-xl font-semibold text-content-primary dark:text-content-primary mb-4`},` Create API Token `,-1),S(`div`,Ai,[S(`div`,null,[r[12]||=S(`label`,{class:`block text-sm font-medium text-content-secondary dark:text-content-muted mb-2`},`Token Name`,-1),c(S(`input`,{"onUpdate:modelValue":r[2]||=e=>s.value=e,type:`text`,placeholder:`e.g., Production Server, CI/CD Pipeline`,class:`cfg-input placeholder-gray-400 dark:placeholder-white/40`,onKeydown:B(T,[`enter`])},null,544),[[U,s.value]]),r[13]||=S(`p`,{class:`text-xs text-content-muted dark:text-content-muted mt-1`},` Give your token a descriptive name to identify its purpose `,-1)]),S(`div`,ji,[S(`button`,{onClick:O,disabled:i.value,class:`px-4 py-2 bg-background-mute dark:bg-white/5 hover:bg-stroke-subtle dark:hover:bg-white/10 text-content-primary dark:text-content-primary rounded-lg border border-stroke-subtle dark:border-stroke/10 transition-colors disabled:opacity-50`},` Cancel `,8,Mi),S(`button`,{onClick:T,disabled:i.value||!s.value.trim(),class:`btn-primary`},t(i.value?`Creating...`:`Create Token`),9,Ni)])])])])):g(``,!0),f.value&&u.value?(h(),C(`div`,{key:5,class:`fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm`,onClick:z(k,[`self`])},[S(`div`,Pi,[r[19]||=S(`h3`,{class:`text-xl font-semibold text-content-primary dark:text-content-primary mb-4`},` Token Created Successfully `,-1),S(`div`,Fi,[r[18]||=d(`<div class="bg-yellow-500/10 border border-yellow-500/30 rounded-lg p-4"><div class="flex gap-3"><svg class="w-5 h-5 text-yellow-600 dark:text-yellow-400 flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path></svg><div class="text-sm text-yellow-200"><strong>Save this token now!</strong> For security reasons, it will not be shown again. </div></div></div>`,1),S(`div`,null,[r[16]||=S(`label`,{class:`block text-sm font-medium text-content-secondary dark:text-content-muted mb-2`},`Your API Token`,-1),S(`div`,Ii,[S(`input`,{value:u.value,readonly:``,class:`flex-1 px-4 py-2 bg-background-mute dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary font-mono text-sm`},null,8,Li),S(`button`,{onClick:A,class:`btn-primary flex items-center gap-2`,title:`Copy to clipboard`},[...r[15]||=[S(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z`})],-1),b(` Copy `,-1)]])])]),S(`div`,Ri,[r[17]||=S(`p`,{class:`text-sm text-blue-200 mb-2`},[S(`strong`,null,`Usage Example:`)],-1),S(`code`,zi,` curl -H "X-API-Key: `+t(u.value)+`" `+t(N.value),1)]),S(`div`,{class:`flex justify-end mt-6`},[S(`button`,{onClick:k,class:`btn-primary`},` Done `)])])])])):g(``,!0)]),_(W,{show:p.value,title:`Revoke API Token`,message:`Are you sure you want to revoke the token '${v.value?.name}'? This action cannot be undone.`,"confirm-text":`Revoke`,"cancel-text":`Cancel`,variant:`danger`,onConfirm:D,onClose:r[3]||=e=>p.value=!1},null,8,[`show`,`message`])],64))}}),Vi={class:`space-y-12`},Hi={class:`cfg-section`},Ui={class:`space-y-4`},Wi={class:`flex items-center justify-between`},Gi=[`disabled`],Ki={class:`cfg-section`},qi={class:`space-y-4`},Ji={class:`space-y-3`},Yi=[`checked`,`disabled`],Xi=[`checked`,`disabled`],Zi={class:`flex items-start gap-3`},Qi={key:0,class:`w-5 h-5 text-green-600 dark:text-green-400 flex-shrink-0 mt-0.5`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`},$i={key:1,class:`w-5 h-5 text-accent-cyan flex-shrink-0 mt-0.5`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`},ea={class:`flex-1`},ta={class:`text-sm font-medium text-content-primary dark:text-content-primary`},na={key:0,class:`text-xs text-green-600 dark:text-green-400 mt-1`},ra={key:1,class:`p-4 bg-amber-500/10 border border-amber-500/30 rounded-lg`},ia={class:`flex items-start justify-between gap-3`},aa=[`disabled`],oa={key:0,class:`animate-spin h-4 w-4`,fill:`none`,viewBox:`0 0 24 24`},sa={key:1,class:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`},ca={class:`flex items-center space-x-2`},la={key:0,class:`w-5 h-5 text-green-600 dark:text-green-400`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`},ua={key:1,class:`w-5 h-5 text-red-600 dark:text-red-400`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`},da=f({name:`WebSettings`,__name:`WebSettings`,setup(e){let{stats:n}=O(N()),a=l(!1),o=l(``),s=l(!1),c=l(!1),u=l(!1),f=l(!1),p=l(!0),m=i({cors_enabled:!1,use_default_frontend:!0}),_=y(()=>s.value?`bg-green-500/10 border-green-600/40 dark:border-green-500/30`:`bg-red-500/10 border-red-500/30`);async function v(){try{p.value=!0;let e=await M.get(`/check_pymc_console`);e.success&&e.data&&(f.value=e.data.exists)}catch(e){console.error(`Failed to check PyMC Console:`,e),f.value=!1}finally{p.value=!1}}function w(){let e=n.value?.config?.web||{};m.cors_enabled=e.cors_enabled===!0;let t=e.web_path;m.use_default_frontend=!t||t===``}async function E(){a.value=!0,o.value=``;try{let e={web:{cors_enabled:m.cors_enabled}};m.use_default_frontend?e.web.web_path=null:e.web.web_path=`/opt/pymc_console/web/html`;let t=await M.post(`/update_web_config`,e);t.success?(j(`Settings saved successfully`,!0),c.value=!0):j(t.error||`Failed to save settings`,!1)}catch(e){console.error(`Failed to save web settings:`,e),j(e.message||`Failed to save settings`,!1)}finally{a.value=!1}}async function D(){m.cors_enabled=!m.cors_enabled,await E()}async function k(){m.use_default_frontend=!0,await E()}async function A(){if(!f.value){j(`PyMC Console is not installed. Please install it before switching.`,!1);return}m.use_default_frontend=!1,await E()}function j(e,t){o.value=e,s.value=t,setTimeout(()=>{o.value=``},5e3)}async function P(){u.value=!0,o.value=``;try{let e=await M.post(`/restart_service`,{});e.success?(j(`Service restart initiated. Page will reload...`,!0),c.value=!1,setTimeout(()=>{window.location.reload()},2e3)):j(e.error||`Failed to restart service`,!1)}catch(e){e.code===`ERR_NETWORK`||e.message?.includes(`Network error`)?(j(`Service restarting... Page will reload`,!0),c.value=!1,setTimeout(()=>{window.location.reload()},3e3)):(console.error(`Failed to restart service:`,e),j(e.message||`Failed to restart service`,!1))}finally{u.value=!1}}return r(()=>{w(),v()}),(e,n)=>(h(),C(`div`,Vi,[n[14]||=S(`div`,{class:`cfg-page-heading flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},[S(`div`,null,[S(`h3`,{class:`text-base sm:text-lg font-semibold text-content-primary dark:text-content-primary mb-1 sm:mb-2`},`Web Options`),S(`p`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Configure CORS policy and web frontend selection`)])],-1),S(`div`,Hi,[n[1]||=S(`div`,{class:`flex items-start justify-between mb-4`},[S(`div`,null,[S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-1`},` CORS Settings `),S(`p`,{class:`text-sm text-content-secondary dark:text-content-muted`},` Control cross-origin resource sharing for API access `)])],-1),S(`div`,Ui,[S(`div`,Wi,[n[0]||=S(`div`,null,[S(`label`,{class:`text-sm font-medium text-content-primary dark:text-content-primary`},`Enable CORS`),S(`p`,{class:`text-xs text-content-secondary dark:text-content-muted mt-1`},` Allow web frontends from different origins to access the API `)],-1),S(`button`,{onClick:D,disabled:a.value,class:T([`relative inline-flex h-6 w-11 items-center rounded-full transition-colors border-2`,m.cors_enabled?`bg-cyan-600 dark:bg-teal-500 border-cyan-600 dark:border-teal-500`:`bg-gray-400 dark:bg-gray-600 border-gray-400 dark:border-gray-600`,a.value?`opacity-50 cursor-not-allowed`:`cursor-pointer`])},[S(`span`,{class:T([`inline-block h-4 w-4 transform rounded-full bg-white transition-transform shadow-lg`,m.cors_enabled?`translate-x-5`:`translate-x-0.5`])},null,2)],10,Gi)])])]),S(`div`,Ki,[n[11]||=S(`div`,{class:`flex items-start justify-between mb-4`},[S(`div`,null,[S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-1`},` Web Frontend `),S(`p`,{class:`text-sm text-content-secondary dark:text-content-muted`},` Choose which web interface to use `)])],-1),S(`div`,qi,[S(`div`,Ji,[S(`label`,{class:T([`flex items-start space-x-3 p-4 bg-background-mute dark:bg-background/30 rounded-lg border-2 cursor-pointer transition-all`,m.use_default_frontend?`border-accent-cyan bg-accent-cyan/10`:`border-stroke-subtle dark:border-stroke/10 hover:border-accent-cyan/50`])},[S(`input`,{type:`radio`,name:`frontend`,checked:m.use_default_frontend,onChange:k,disabled:a.value,class:`mt-1 h-4 w-4 text-accent-cyan focus:ring-accent-cyan focus:ring-offset-background`},null,40,Yi),n[2]||=S(`div`,{class:`flex-1`},[S(`div`,{class:`text-sm font-medium text-content-primary dark:text-content-primary`},` Default Frontend `),S(`div`,{class:`text-xs text-content-secondary dark:text-content-muted mt-1`},` Built-in pyMC Repeater web interface `),S(`div`,{class:`text-xs text-content-muted dark:text-content-muted/60 mt-1 font-mono`},` Built-in `)],-1)],2),S(`label`,{class:T([`flex items-start space-x-3 p-4 bg-background-mute dark:bg-background/30 rounded-lg border-2 transition-all`,f.value?`cursor-pointer`:`opacity-50 cursor-not-allowed`,m.use_default_frontend?`border-stroke-subtle dark:border-stroke/10 hover:border-accent-cyan/50`:`border-accent-cyan bg-accent-cyan/10`])},[S(`input`,{type:`radio`,name:`frontend`,checked:!m.use_default_frontend,onChange:A,disabled:a.value||!f.value,class:`mt-1 h-4 w-4 text-accent-cyan focus:ring-accent-cyan focus:ring-offset-background`},null,40,Xi),n[3]||=d(`<div class="flex-1"><div class="flex items-center justify-between"><div class="text-sm font-medium text-content-primary dark:text-content-primary"> PyMC Console </div><span class="text-xs bg-orange-100 dark:bg-orange-500/20 text-orange-600 dark:text-orange-400 px-2 py-0.5 rounded-full border border-orange-500/30 font-medium">@Treehouse⚡</span></div><div class="text-xs text-content-secondary dark:text-content-muted mt-1"> Alternative web interface for pyMC Repeater </div><div class="text-xs text-content-muted dark:text-content-muted/60 mt-1 font-mono"> /opt/pymc_console/web/html </div></div>`,1)],2)]),p.value?g(``,!0):(h(),C(`div`,{key:0,class:T([`p-4 rounded-lg border`,f.value?`bg-green-500/5 border-green-500/20`:`bg-accent-cyan/5 border-accent-cyan/20`])},[S(`div`,Zi,[f.value?(h(),C(`svg`,Qi,[...n[4]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z`},null,-1)]])):(h(),C(`svg`,$i,[...n[5]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z`},null,-1)]])),S(`div`,ea,[S(`h4`,ta,t(f.value?`PyMC Console has been detected`:`PyMC Console Not Installed`),1),f.value?(h(),C(`p`,na,[...n[6]||=[b(` PyMC Console is installed at `,-1),S(`code`,{class:`text-green-700 dark:text-green-300`},`/opt/pymc_console/web/html`,-1)]])):(h(),C(x,{key:1},[n[7]||=d(`<p class="text-xs text-content-secondary dark:text-content-muted mt-1 mb-3"> PyMC Console must be installed at <code class="text-accent-cyan">/opt/pymc_console/web/html</code> before selecting this option. </p><a href="https://github.com/dmduran12/pymc_console-dist" target="_blank" rel="noopener noreferrer" class="inline-flex items-center gap-2 px-4 py-2 bg-accent-cyan/20 hover:bg-accent-cyan/30 border border-accent-cyan/50 text-accent-cyan rounded-lg text-sm font-medium transition-colors"><svg class="w-4 h-4" fill="currentColor" viewBox="0 0 24 24"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"></path></svg> PyMC Console Install Instructions </a>`,2)],64))])])],2)),c.value?(h(),C(`div`,ra,[S(`div`,ia,[n[10]||=d(`<div class="flex items-start space-x-3 flex-1"><svg class="w-5 h-5 text-amber-600 dark:text-amber-400 flex-shrink-0 mt-0.5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path></svg><div class="flex-1"><h4 class="text-sm font-medium text-amber-600 dark:text-amber-400"> Service restart required </h4><p class="text-xs text-amber-700 dark:text-amber-400/80 mt-1"> Web frontend changes will take effect after restarting the pymc-repeater service. </p></div></div>`,1),S(`button`,{onClick:P,disabled:u.value,class:`px-4 py-2 bg-amber-500 hover:bg-amber-600 disabled:bg-amber-500/50 text-white font-medium rounded-lg transition-colors disabled:cursor-not-allowed flex items-center gap-2 whitespace-nowrap`},[u.value?(h(),C(`svg`,oa,[...n[8]||=[S(`circle`,{class:`opacity-25`,cx:`12`,cy:`12`,r:`10`,stroke:`currentColor`,"stroke-width":`4`},null,-1),S(`path`,{class:`opacity-75`,fill:`currentColor`,d:`M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z`},null,-1)]])):(h(),C(`svg`,sa,[...n[9]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15`},null,-1)]])),b(` `+t(u.value?`Restarting...`:`Restart Now`),1)],8,aa)])])):g(``,!0)])]),o.value?(h(),C(`div`,{key:0,class:T([`p-4 rounded-lg border`,_.value])},[S(`div`,ca,[s.value?(h(),C(`svg`,la,[...n[12]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M5 13l4 4L19 7`},null,-1)]])):(h(),C(`svg`,ua,[...n[13]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M6 18L18 6M6 6l12 12`},null,-1)]])),S(`span`,{class:T(s.value?`text-green-600 dark:text-green-400`:`text-red-600 dark:text-red-400`)},t(o.value),3)])],2)):g(``,!0)]))}}),fa={ref:`rootEl`,class:`space-y-12`},pa={class:`cfg-page-heading flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},ma={class:`flex items-center gap-2 flex-shrink-0`},ha=[`disabled`],ga=[`disabled`],_a={key:0,class:`bg-accent-green/20 border border-accent-green/50 rounded-lg p-3 text-accent-green text-sm`},va={key:1,class:`bg-accent-red/20 border border-accent-red/50 rounded-lg p-3 text-accent-red text-sm`},ya={class:`cfg-section space-y-3`},ba={key:0,class:`flex items-center justify-center py-4`},xa={key:1,class:`text-center py-4`},Sa={class:`grid grid-cols-2 sm:grid-cols-4 gap-3`},Ca={class:`text-center p-2 bg-white dark:bg-white/5 rounded-lg border border-stroke-subtle dark:border-white/10`},wa={class:`text-center p-2 bg-white dark:bg-white/5 rounded-lg border border-stroke-subtle dark:border-white/10`},Ta={class:`text-lg font-mono text-content-primary dark:text-content-primary`},Ea={class:`text-center p-2 bg-white dark:bg-white/5 rounded-lg border border-stroke-subtle dark:border-white/10`},Da={class:`text-lg font-mono text-accent-green`},Oa={class:`text-center p-2 bg-white dark:bg-white/5 rounded-lg border border-stroke-subtle dark:border-white/10`},ka={class:`text-lg font-mono text-accent-red`},Aa={key:0,class:`mt-2 p-2 bg-accent-red/10 rounded-lg border border-accent-red/20`},ja={key:1,class:`mt-2 p-2 bg-secondary/10 rounded-lg border border-secondary/20`},Ma={class:`font-medium`},Na={class:`font-mono text-[10px] opacity-70`},Pa={class:`text-[10px]`},Fa={class:`cfg-section space-y-3`},Ia={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},La={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},Ra={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},za={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},Ba={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},Va={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},Ha={key:1,class:`flex items-center gap-2`},Ua={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 gap-1`},Wa={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},Ga={key:1,class:`flex items-center gap-2`},Ka={class:`cfg-section space-y-3`},qa={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},Ja={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},Ya={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},Xa={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},Za={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},Qa={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},$a={key:1,class:`flex items-center gap-2`},eo={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},to={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},no={key:1,class:`flex items-center gap-2`},ro={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 gap-1`},io={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},ao={key:1,class:`flex items-center gap-2`},oo={class:`cfg-section space-y-3`},so={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},co={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},lo={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},uo={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},fo={key:1,class:`flex items-center gap-2`},po={class:`py-2`},mo={class:`grid grid-cols-3 gap-2 mt-2`},ho={class:`text-center p-2 bg-white dark:bg-white/5 rounded-lg border border-stroke-subtle dark:border-white/10`},go={key:0,class:`font-mono text-sm text-content-primary dark:text-content-primary`},_o={class:`text-center p-2 bg-white dark:bg-white/5 rounded-lg border border-stroke-subtle dark:border-white/10`},vo={key:0,class:`font-mono text-sm text-content-primary dark:text-content-primary`},yo={class:`text-center p-2 bg-white dark:bg-white/5 rounded-lg border border-stroke-subtle dark:border-white/10`},bo={key:0,class:`font-mono text-sm text-content-primary dark:text-content-primary`},xo={class:`p-6 space-y-4`},So={class:`flex justify-between items-start`},Co={class:`flex justify-end pt-4 border-t border-stroke-subtle dark:border-stroke/20`},wo=f({__name:`AdvertSettings`,setup(e,{expose:n}){let i=N(),a=y(()=>i.stats?.config?.repeater||{}),u=y(()=>a.value.advert_rate_limit||{}),f=y(()=>a.value.advert_penalty_box||{}),p=y(()=>a.value.advert_adaptive||{}),w=y(()=>p.value.thresholds||{}),E=l(!1),D=l(!1),O=l(``),k=l(``),A=l(!1),M=l(!1),P=l(null),F=l(!0),L=l(2),B=l(1),V=l(10),H=l(60),ee=l(!0),W=l(2),G=l(12),K=l(6),te=l(2),ne=l(24),q=l(!0),re=l(.1),ie=l(5),J=l(.05),Y=l(.2),X=l(.5),Z=async()=>{M.value=!0;try{let e=await j.get(`/api/advert_rate_limit_stats`);e.data?.success&&(P.value=e.data.data)}catch(e){console.error(`Failed to fetch rate limit stats:`,e)}finally{M.value=!1}};o([u,f,p],()=>{E.value||(F.value=u.value.enabled??!1,L.value=u.value.bucket_capacity??2,B.value=u.value.refill_tokens??1,V.value=Math.round((u.value.refill_interval_seconds??36e3)/3600),H.value=Math.round((u.value.min_interval_seconds??0)/60),ee.value=f.value.enabled??!1,W.value=f.value.violation_threshold??2,G.value=Math.round((f.value.violation_decay_seconds??43200)/3600),K.value=Math.round((f.value.base_penalty_seconds??21600)/3600),te.value=f.value.penalty_multiplier??2,ne.value=Math.round((f.value.max_penalty_seconds??86400)/3600),q.value=p.value.enabled??!1,re.value=p.value.ewma_alpha??.1,ie.value=Math.round((p.value.hysteresis_seconds??300)/60),J.value=w.value.quiet_max??.05,Y.value=w.value.normal_max??.2,X.value=w.value.busy_max??.5)},{immediate:!0}),r(()=>{Z()});let Q=()=>{F.value=u.value.enabled??!1,L.value=u.value.bucket_capacity??2,B.value=u.value.refill_tokens??1,V.value=Math.round((u.value.refill_interval_seconds??36e3)/3600),H.value=Math.round((u.value.min_interval_seconds??0)/60),ee.value=f.value.enabled??!1,W.value=f.value.violation_threshold??2,G.value=Math.round((f.value.violation_decay_seconds??43200)/3600),K.value=Math.round((f.value.base_penalty_seconds??21600)/3600),te.value=f.value.penalty_multiplier??2,ne.value=Math.round((f.value.max_penalty_seconds??86400)/3600),q.value=p.value.enabled??!1,re.value=p.value.ewma_alpha??.1,ie.value=Math.round((p.value.hysteresis_seconds??300)/60),J.value=w.value.quiet_max??.05,Y.value=w.value.normal_max??.2,X.value=w.value.busy_max??.5},ae=()=>{E.value=!0,O.value=``,k.value=``},$=()=>{E.value=!1,O.value=``,k.value=``,Q()},ce=async()=>{D.value=!0,k.value=``,O.value=``;try{let e={rate_limit_enabled:F.value,bucket_capacity:L.value,refill_tokens:B.value,refill_interval_seconds:V.value*3600,min_interval_seconds:H.value*60,penalty_enabled:ee.value,violation_threshold:W.value,violation_decay_seconds:G.value*3600,base_penalty_seconds:K.value*3600,penalty_multiplier:te.value,max_penalty_seconds:ne.value*3600,adaptive_enabled:q.value,ewma_alpha:re.value,hysteresis_seconds:ie.value*60,quiet_max:J.value,normal_max:Y.value,busy_max:X.value},t=(await j.post(`/api/update_advert_rate_limit_config`,e)).data;t.success?(O.value=t.data?.message||`Settings saved successfully`,await i.fetchStats(),await Z(),await s(),Q(),E.value=!1,setTimeout(()=>{O.value=``},3e3)):(k.value=t.error||`Failed to save settings`,console.error(`[AdvertSettings] Save failed:`,t.error))}catch(e){console.error(`Failed to save advert settings:`,e),k.value=e.response?.data?.error||`Failed to save settings`}finally{D.value=!1}},{showUnsavedModal:le,requestLeave:ue,handleDiscard:de,handleSave:fe}=se(E,D,$,async()=>(await ce(),!E.value));n({requestLeave:ue,isEditing:E});let pe=y(()=>P.value?.adaptive?.current_tier||`unknown`),me=y(()=>{switch(pe.value){case`quiet`:return`bg-accent-green/20 text-accent-green border-accent-green/50`;case`normal`:return`bg-accent-cyan/20 text-accent-cyan border-accent-cyan/50`;case`busy`:return`bg-secondary/20 text-secondary border-secondary/50`;case`congested`:return`bg-accent-red/20 text-accent-red border-accent-red/50`;default:return`bg-background-mute text-content-muted border-stroke-subtle`}});return(e,n)=>(h(),C(x,null,[_(oe,{show:v(le),"is-saving":D.value,label:`Advert Limit settings`,onDiscard:v(de),onSave:v(fe)},null,8,[`show`,`is-saving`,`onDiscard`,`onSave`]),S(`div`,fa,[S(`div`,pa,[n[20]||=S(`div`,null,[S(`h3`,{class:`text-base sm:text-lg font-semibold text-content-primary dark:text-content-primary mb-1 sm:mb-2`},`Advert Limits`),S(`p`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Configure advertisement rate limiting and adaptive controls`)],-1),S(`div`,ma,[S(`button`,{onClick:n[0]||=e=>A.value=!0,class:`self-stretch flex items-center justify-center px-3 text-xs bg-primary/10 hover:bg-primary/20 text-primary rounded-lg border border-primary/30 transition-colors`,title:`How rate limiting works`},[...n[19]||=[S(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z`})],-1)]]),E.value?(h(),C(x,{key:1},[S(`button`,{onClick:$,disabled:D.value,class:`cfg-btn-secondary`},` Cancel `,8,ha),S(`button`,{onClick:ce,disabled:D.value,class:`cfg-btn-primary`},t(D.value?`Saving...`:`Save Changes`),9,ga)],64)):(h(),C(`button`,{key:0,onClick:ae,class:`cfg-btn-primary`},` Edit Settings `))])]),O.value?(h(),C(`div`,_a,t(O.value),1)):g(``,!0),k.value?(h(),C(`div`,va,t(k.value),1)):g(``,!0),S(`div`,ya,[n[29]||=S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary`},` Current Status `,-1),M.value&&!P.value?(h(),C(`div`,ba,[_(I,{size:`sm`}),n[21]||=S(`span`,{class:`ml-2 text-sm text-content-muted`},`Loading stats...`,-1)])):P.value?(h(),C(x,{key:2},[S(`div`,Sa,[S(`div`,Ca,[n[23]||=S(`div`,{class:`text-xs text-content-muted dark:text-content-muted`},`Mesh Tier`,-1),S(`div`,{class:T([`mt-1 px-2 py-0.5 rounded border text-xs font-medium inline-block`,me.value])},t(pe.value.toUpperCase()),3)]),S(`div`,wa,[n[24]||=S(`div`,{class:`text-xs text-content-muted dark:text-content-muted`},`Adverts/min`,-1),S(`div`,Ta,t(P.value.metrics?.adverts_per_min_ewma?.toFixed(2)||`0.00`),1)]),S(`div`,Ea,[n[25]||=S(`div`,{class:`text-xs text-content-muted dark:text-content-muted`},`Allowed`,-1),S(`div`,Da,t(P.value.stats?.adverts_allowed||0),1)]),S(`div`,Oa,[n[26]||=S(`div`,{class:`text-xs text-content-muted dark:text-content-muted`},`Dropped`,-1),S(`div`,ka,t(P.value.stats?.adverts_dropped||0),1)])]),Object.keys(P.value.active_penalties||{}).length>0?(h(),C(`div`,Aa,[n[27]||=S(`div`,{class:`text-xs font-medium text-accent-red mb-1`},` Active Penalties `,-1),(h(!0),C(x,null,m(P.value.active_penalties,(e,n)=>(h(),C(`div`,{key:n,class:`text-xs font-mono text-accent-red`},t(n)+`... - `+t(Math.round(e))+`s remaining `,1))),128))])):g(``,!0),P.value.recent_drops&&P.value.recent_drops.length>0?(h(),C(`div`,ja,[n[28]||=S(`div`,{class:`text-xs font-medium text-secondary mb-1`},` Recently Dropped Adverts `,-1),(h(!0),C(x,null,m(P.value.recent_drops,(e,n)=>(h(),C(`div`,{key:n,class:`text-xs text-secondary py-0.5`},[S(`span`,Ma,t(e.name),1),S(`span`,Na,`(`+t(e.pubkey)+`...)`,1),S(`span`,Pa,` - `+t(e.reason)+` (`+t(e.seconds_ago)+`s ago)`,1)]))),128))])):g(``,!0)],64)):(h(),C(`div`,xa,[...n[22]||=[S(`p`,{class:`text-xs text-content-muted dark:text-content-muted`},` Stats not available. Click "Refresh Stats" to load. `,-1)]])),n[30]||=d(`<div class="mt-3 p-3 bg-primary/10 border border-primary/20 rounded-lg"><p class="text-xs text-primary leading-relaxed"><strong>There are three layers of advert rate limit control:</strong> Each layer can be enabled/disabled independently and the others will still function. </p><ul class="text-xs text-primary mt-2 space-y-1 ml-4 list-disc"><li><strong>Rate Limiting OFF:</strong> All limiting disabled — adverts pass through freely </li><li><strong>Adaptive OFF:</strong> Token bucket uses fixed limits (no tier scaling), penalty box still works </li><li><strong>Penalty Box OFF:</strong> Token bucket still applies, but no escalating cooldowns for repeat offenders </li></ul><p class="text-xs text-primary mt-2"><strong>Decision flow when all enabled:</strong> Adaptive tier check → Penalty box check → Token bucket check → Violation recording (triggers penalty box) </p><p class="text-xs text-primary mt-1"><strong>Activity tiers:</strong><span class="text-accent-green font-medium">Quiet</span> (bypass limiting) → <span class="text-accent-cyan font-medium">Normal</span> (lighter: 0.5x intervals) → <span class="text-secondary font-medium">Busy</span> (base: 1.0x intervals) → <span class="text-accent-red font-medium">Congested</span> (stricter: 2.0x intervals) </p><p class="text-xs text-primary mt-1"><strong>Note:</strong> Adaptive mode scales refill/min-interval timing; bucket capacity stays at the configured base value. </p></div>`,1)]),S(`div`,Fa,[n[38]||=S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary flex items-center gap-2`},[S(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z`})]),b(` Token Bucket Rate Limiting `)],-1),n[39]||=S(`p`,{class:`text-xs text-content-muted dark:text-content-muted`},` Controls how many adverts each pubkey can send in a given time period. `,-1),S(`div`,Ia,[n[32]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Rate Limiting`,-1),E.value?c((h(),C(`select`,{key:1,"onUpdate:modelValue":n[1]||=e=>F.value=e,class:`cfg-select w-full sm:w-32`},[...n[31]||=[S(`option`,{value:!0},`Enabled`,-1),S(`option`,{value:!1},`Disabled`,-1)]],512)),[[R,F.value]]):(h(),C(`div`,La,t(F.value?`Enabled`:`Disabled`),1))]),S(`div`,Ra,[n[33]||=S(`div`,null,[S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Bucket Capacity`),S(`p`,{class:`text-xs text-content-muted dark:text-content-muted`},`Max burst size (adverts)`)],-1),E.value?c((h(),C(`input`,{key:1,"onUpdate:modelValue":n[2]||=e=>L.value=e,type:`number`,min:`1`,max:`10`,class:`cfg-input w-full sm:w-24`},null,512)),[[U,L.value,void 0,{number:!0}]]):(h(),C(`div`,za,t(L.value),1))]),S(`div`,Ba,[n[35]||=S(`div`,null,[S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Refill Interval`),S(`p`,{class:`text-xs text-content-muted dark:text-content-muted`},` Time between token refills `)],-1),E.value?(h(),C(`div`,Ha,[c(S(`input`,{"onUpdate:modelValue":n[3]||=e=>V.value=e,type:`number`,min:`1`,max:`48`,class:`cfg-input w-20`},null,512),[[U,V.value,void 0,{number:!0}]]),n[34]||=S(`span`,{class:`text-content-muted text-sm`},`hours`,-1)])):(h(),C(`div`,Va,t(V.value)+` hours `,1))]),S(`div`,Ua,[n[37]||=S(`div`,null,[S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Minimum Interval`),S(`p`,{class:`text-xs text-content-muted dark:text-content-muted`},` Hard minimum between adverts `)],-1),E.value?(h(),C(`div`,Ga,[c(S(`input`,{"onUpdate:modelValue":n[4]||=e=>H.value=e,type:`number`,min:`0`,max:`1440`,class:`cfg-input w-20`},null,512),[[U,H.value,void 0,{number:!0}]]),n[36]||=S(`span`,{class:`text-content-muted text-sm`},`min`,-1)])):(h(),C(`div`,Wa,t(H.value)+` min `,1))])]),S(`div`,Ka,[n[49]||=S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary flex items-center gap-2`},[S(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636`})]),b(` Penalty Box (Repeat Offenders) `)],-1),n[50]||=S(`p`,{class:`text-xs text-content-muted dark:text-content-muted`},` Applies escalating cooldowns to pubkeys that repeatedly violate limits. `,-1),S(`div`,qa,[n[41]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Penalty Box`,-1),E.value?c((h(),C(`select`,{key:1,"onUpdate:modelValue":n[5]||=e=>ee.value=e,class:`cfg-select w-full sm:w-32`},[...n[40]||=[S(`option`,{value:!0},`Enabled`,-1),S(`option`,{value:!1},`Disabled`,-1)]],512)),[[R,ee.value]]):(h(),C(`div`,Ja,t(ee.value?`Enabled`:`Disabled`),1))]),S(`div`,Ya,[n[42]||=S(`div`,null,[S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Violation Threshold`),S(`p`,{class:`text-xs text-content-muted dark:text-content-muted`},` Violations before penalty `)],-1),E.value?c((h(),C(`input`,{key:1,"onUpdate:modelValue":n[6]||=e=>W.value=e,type:`number`,min:`1`,max:`10`,class:`cfg-input w-full sm:w-24`},null,512)),[[U,W.value,void 0,{number:!0}]]):(h(),C(`div`,Xa,t(W.value),1))]),S(`div`,Za,[n[44]||=S(`div`,null,[S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Base Penalty Duration`),S(`p`,{class:`text-xs text-content-muted dark:text-content-muted`},`First penalty duration`)],-1),E.value?(h(),C(`div`,$a,[c(S(`input`,{"onUpdate:modelValue":n[7]||=e=>K.value=e,type:`number`,min:`1`,max:`48`,class:`cfg-input w-20`},null,512),[[U,K.value,void 0,{number:!0}]]),n[43]||=S(`span`,{class:`text-content-muted text-sm`},`hours`,-1)])):(h(),C(`div`,Qa,t(K.value)+` hours `,1))]),S(`div`,eo,[n[46]||=S(`div`,null,[S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Penalty Multiplier`),S(`p`,{class:`text-xs text-content-muted dark:text-content-muted`},`Escalation factor`)],-1),E.value?(h(),C(`div`,no,[c(S(`input`,{"onUpdate:modelValue":n[8]||=e=>te.value=e,type:`number`,min:`1`,max:`5`,step:`0.5`,class:`cfg-input w-20`},null,512),[[U,te.value,void 0,{number:!0}]]),n[45]||=S(`span`,{class:`text-content-muted text-sm`},`x`,-1)])):(h(),C(`div`,to,t(te.value)+`x `,1))]),S(`div`,ro,[n[48]||=S(`div`,null,[S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Max Penalty Duration`),S(`p`,{class:`text-xs text-content-muted dark:text-content-muted`},`Maximum cooldown cap`)],-1),E.value?(h(),C(`div`,ao,[c(S(`input`,{"onUpdate:modelValue":n[9]||=e=>ne.value=e,type:`number`,min:`1`,max:`168`,class:`cfg-input w-20`},null,512),[[U,ne.value,void 0,{number:!0}]]),n[47]||=S(`span`,{class:`text-content-muted text-sm`},`hours`,-1)])):(h(),C(`div`,io,t(ne.value)+` hours `,1))])]),S(`div`,oo,[n[60]||=S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary flex items-center gap-2`},[S(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z`})]),b(` Adaptive Rate Limiting `)],-1),S(`div`,so,[n[52]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Adaptive Mode`,-1),E.value?c((h(),C(`select`,{key:1,"onUpdate:modelValue":n[10]||=e=>q.value=e,class:`cfg-select w-full sm:w-32`},[...n[51]||=[S(`option`,{value:!0},`Enabled`,-1),S(`option`,{value:!1},`Disabled`,-1)]],512)),[[R,q.value]]):(h(),C(`div`,co,t(q.value?`Enabled`:`Disabled`),1))]),S(`div`,lo,[n[54]||=S(`div`,null,[S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Tier Change Delay`),S(`p`,{class:`text-xs text-content-muted dark:text-content-muted`},`Prevents tier flapping`)],-1),E.value?(h(),C(`div`,fo,[c(S(`input`,{"onUpdate:modelValue":n[11]||=e=>ie.value=e,type:`number`,min:`0`,max:`60`,class:`cfg-input w-20`},null,512),[[U,ie.value,void 0,{number:!0}]]),n[53]||=S(`span`,{class:`text-content-muted text-sm`},`min`,-1)])):(h(),C(`div`,uo,t(ie.value)+` min `,1))]),S(`div`,po,[n[58]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm mb-2 block`},`Activity Tier Thresholds (adverts/min)`,-1),S(`div`,mo,[S(`div`,ho,[n[55]||=S(`div`,{class:`text-xs text-accent-green mb-1`},`Quiet Max`,-1),E.value?c((h(),C(`input`,{key:1,"onUpdate:modelValue":n[12]||=e=>J.value=e,type:`number`,min:`0`,max:`1`,step:`0.01`,class:`cfg-input w-full py-1 text-center`},null,512)),[[U,J.value,void 0,{number:!0}]]):(h(),C(`div`,go,t(J.value),1))]),S(`div`,_o,[n[56]||=S(`div`,{class:`text-xs text-accent-cyan mb-1`},`Normal Max`,-1),E.value?c((h(),C(`input`,{key:1,"onUpdate:modelValue":n[13]||=e=>Y.value=e,type:`number`,min:`0`,max:`5`,step:`0.01`,class:`cfg-input w-full py-1 text-center`},null,512)),[[U,Y.value,void 0,{number:!0}]]):(h(),C(`div`,vo,t(Y.value),1))]),S(`div`,yo,[n[57]||=S(`div`,{class:`text-xs text-secondary mb-1`},`Busy Max`,-1),E.value?c((h(),C(`input`,{key:1,"onUpdate:modelValue":n[14]||=e=>X.value=e,type:`number`,min:`0`,max:`10`,step:`0.01`,class:`cfg-input w-full py-1 text-center`},null,512)),[[U,X.value,void 0,{number:!0}]]):(h(),C(`div`,bo,t(X.value),1))])]),n[59]||=S(`p`,{class:`text-xs text-content-muted dark:text-content-muted mt-2`},` Above Busy Max = Congested tier (strictest limiting) `,-1)])]),A.value?(h(),C(`div`,{key:2,class:`fixed inset-0 bg-black/50 flex items-start justify-center z-50 p-4 overflow-y-auto`,onClick:n[18]||=z(e=>A.value=!1,[`self`])},[S(`div`,{class:`bg-background dark:bg-background-dark rounded-lg shadow-xl max-w-3xl w-full my-8`,onClick:n[17]||=z(()=>{},[`stop`])},[S(`div`,xo,[S(`div`,So,[n[62]||=S(`h2`,{class:`text-xl font-semibold text-content-primary dark:text-content-primary`},` How Advert Rate Limiting Works `,-1),S(`button`,{onClick:n[15]||=e=>A.value=!1,class:`text-content-muted hover:text-content-primary dark:text-content-muted dark:hover:text-content-primary`},[...n[61]||=[S(`svg`,{class:`w-6 h-6`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M6 18L18 6M6 6l12 12`})],-1)]])]),n[63]||=d(`<div class="bg-primary/10 rounded-lg p-4 border border-primary/20"><h3 class="font-semibold text-primary mb-2"> Why you may see the same advert more than once </h3><p class="text-sm text-primary leading-relaxed"> Mesh traffic can reach your repeater through different paths, so duplicate advert packets are expected. </p><ul class="text-sm text-primary mt-2 space-y-1 list-disc list-inside"><li>First copy arrives and is forwarded</li><li>Second copy arrives through another repeater path</li><li>Later copies may be dropped once limits are hit</li></ul><p class="text-sm text-primary mt-2"> This is normal behavior and helps prevent repeated rebroadcasts from flooding the mesh. </p></div><div class="space-y-2"><h3 class="font-semibold text-content-primary dark:text-content-primary flex items-center gap-2"><svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg> Token Bucket Rate Limiting </h3><p class="text-sm text-content-secondary dark:text-content-muted leading-relaxed"> Each sender has a token bucket. Every forwarded advert uses one token. </p><ul class="text-sm text-content-secondary dark:text-content-muted space-y-1 list-disc list-inside ml-4"><li><strong>Bucket Capacity:</strong> How many adverts can pass in a burst.</li><li><strong>Refill Rate:</strong> How quickly tokens come back over time.</li><li><strong>Min Interval:</strong> Optional gap between adverts from the same sender (usually set to 0). </li></ul><div class="mt-2 p-3 bg-background-mute dark:bg-white/5 rounded text-xs font-mono text-content-muted dark:text-content-muted"> Example (capacity 2):<br> - Copy 1 forwarded (2 → 1 tokens)<br> - Copy 2 forwarded (1 → 0 tokens)<br> - Copy 3 dropped (no tokens left) </div></div><div class="space-y-2"><h3 class="font-semibold text-content-primary dark:text-content-primary flex items-center gap-2"><svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"></path></svg> Penalty Box (Repeat Offenders) </h3><p class="text-sm text-content-secondary dark:text-content-muted leading-relaxed"> If a sender keeps hitting the limit, it is temporarily blocked. </p><ul class="text-sm text-content-secondary dark:text-content-muted space-y-1 list-disc list-inside ml-4"><li><strong>Violation Threshold:</strong> How many hits before penalty starts.</li><li><strong>Base Penalty:</strong> First block duration.</li><li><strong>Multiplier:</strong> Repeated penalties get longer.</li><li><strong>Decay Time:</strong> Violations age out after stable behavior.</li></ul></div><div class="space-y-2"><h3 class="font-semibold text-content-primary dark:text-content-primary flex items-center gap-2"><svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"></path></svg> Adaptive Mesh Activity Tiers </h3><p class="text-sm text-content-secondary dark:text-content-muted leading-relaxed"> Adaptive mode adjusts limits based on recent advert activity. </p><div class="mt-2 p-3 bg-background-mute dark:bg-white/5 rounded-lg text-sm text-content-secondary dark:text-content-muted"><span class="font-semibold">How Congestion is Measured:</span><ul class="mt-1 space-y-1 list-disc list-inside ml-2"><li><strong>What is counted:</strong> Advert packets only (not chat/data traffic) </li><li><strong>Smoothing:</strong> 60-second EWMA to avoid reacting to short spikes </li><li><strong>Score:</strong> Tier is based on adverts per minute</li><li><strong>Hysteresis:</strong> Tier changes must hold for 5 minutes</li></ul></div><div class="grid grid-cols-2 gap-2 mt-2"><div class="p-2 bg-accent-green/10 rounded border border-accent-green/30"><div class="text-xs font-semibold text-accent-green">QUIET</div><div class="text-xs text-accent-green/80">Activity &lt; 0.05/min</div><div class="text-xs text-accent-green font-medium mt-1"> No rate limiting </div></div><div class="p-2 bg-accent-cyan/10 rounded border border-accent-cyan/30"><div class="text-xs font-semibold text-accent-cyan">NORMAL</div><div class="text-xs text-accent-cyan/80">Activity 0.05-0.20/min</div><div class="text-xs text-accent-cyan font-medium mt-1"> Light limiting (50%) </div></div><div class="p-2 bg-secondary/10 rounded border border-secondary/30"><div class="text-xs font-semibold text-secondary">BUSY</div><div class="text-xs text-secondary/80"> Activity 0.20-0.50/min </div><div class="text-xs text-secondary font-medium mt-1"> Standard limiting (100%) </div></div><div class="p-2 bg-accent-red/10 rounded border border-accent-red/30"><div class="text-xs font-semibold text-accent-red">CONGESTED</div><div class="text-xs text-accent-red/80">Activity &gt; 0.50/min</div><div class="text-xs text-accent-red font-medium mt-1"> Aggressive (200%) </div></div></div><div class="mt-2 p-3 bg-background-mute dark:bg-white/5 rounded text-xs font-mono text-content-muted dark:text-content-muted"> Quick examples:<br> - 0.02 adverts/min → <span class="text-accent-green font-semibold">QUIET</span> (bypass)<br> - 0.35 adverts/min → <span class="text-secondary font-semibold">BUSY</span> (tighter limits)<br> - 0.68 adverts/min → <span class="text-accent-red font-semibold">CONGESTED</span> (strict limits) </div></div><div class="bg-accent-green/10 rounded-lg p-4 border border-accent-green/20"><h3 class="font-semibold text-accent-green mb-2"> Recommended starting settings </h3><ul class="text-sm text-accent-green space-y-1 list-disc list-inside"><li><strong>Min Interval:</strong> 0 (disabled), let adaptive mode do the work</li><li><strong>Bucket Capacity:</strong> 2-3 tokens for normal mesh propagation</li><li><strong>Adaptive Mode:</strong> On</li><li><strong>Penalty Box:</strong> On</li></ul></div>`,5),S(`div`,Co,[S(`button`,{onClick:n[16]||=e=>A.value=!1,class:`btn-primary`},` Got it! `)])])])])):g(``,!0)],512)],64))}}),To=[{name:`Letsmesh - US West`,website:`letsmesh.net`,brokers:[{enabled:!0,name:`Letsmesh - US West`,host:`mqtt-us-v1.letsmesh.net`,port:443,audience:`mqtt-us-v1.letsmesh.net`,use_jwt_auth:!0,format:`letsmesh`,transport:`websockets`,retain_status:!1,tls:{enabled:!0,insecure:!1}}]},{name:`Letsmesh - EU`,website:`letsmesh.net`,brokers:[{enabled:!0,name:`Letsmesh - EU`,host:`mqtt-eu-v1.letsmesh.net`,port:443,audience:`mqtt-eu-v1.letsmesh.net`,use_jwt_auth:!0,format:`letsmesh`,transport:`websockets`,retain_status:!1,tls:{enabled:!0,insecure:!1}}]},{name:`Waev`,website:`https://waev.app`,brokers:[{enabled:!0,name:`Waev`,host:`mqtt-a.waev.app`,port:443,audience:`mqtt.waev.app`,use_jwt_auth:!0,format:`letsmesh`,transport:`websockets`,retain_status:!1,tls:{enabled:!0,insecure:!1}}]},{name:`MeshMapper`,website:`https://meshmapper.net`,brokers:[{enabled:!0,name:`MeshMapper`,host:`mqtt.meshmapper.cc`,port:443,audience:`mqtt.meshmapper.cc`,use_jwt_auth:!0,format:`letsmesh`,transport:`websockets`,retain_status:!1,tls:{enabled:!0,insecure:!1}}]}],Eo={class:`modal-card max-w-2xl w-full max-h-[90vh] overflow-y-auto`},Do={class:`flex items-center justify-between mb-7`},Oo={class:`text-xl font-semibold text-content-primary dark:text-content-primary`},ko={class:`text-content-secondary dark:text-content-muted text-sm mt-1`},Ao={class:`grid grid-cols-2 gap-5 items-end`},jo={class:`flex items-center gap-3 pb-1.5`},Mo={key:0,class:`grid grid-cols-2 gap-5`},No={class:`grid grid-cols-2 gap-5 items-end`},Po={class:`flex items-center gap-3 pb-1.5`},Fo={class:`grid grid-cols-2 gap-x-5 gap-y-0`},Io=[`aria-hidden`],Lo={class:`grid grid-cols-2 gap-5 items-center pt-4`},Ro={class:`flex items-center gap-3`},zo={class:`flex items-center gap-6`},Bo={class:`flex items-center gap-3`},Vo={class:`flex items-center gap-3`},Ho={class:`flex flex-wrap gap-2`},Uo=[`onClick`],Wo={class:`modal-actions`},Go=[`disabled`],Ko=f({__name:`BrokerEditModal`,props:{show:{type:Boolean},broker:{},isNew:{type:Boolean}},emits:[`done`,`cancel`],setup(n,{emit:r}){let i=[`REQ`,`RESPONSE`,`TXT_MSG`,`ACK`,`ADVERT`,`GRP_TXT`,`GRP_DATA`,`ANON_REQ`,`PATH`,`TRACE`,`RAW_CUSTOM`],a=n,s=r;function d(e){return{...e,tls:{...e.tls},disallowedInput:[...e.disallowedInput??[]]}}let f=l({_id:0,enabled:!0,name:``,host:``,port:443,format:`letsmesh`,use_jwt_auth:!1,transport:`websockets`,disallowedInput:[],retain_status:!1,tls:{enabled:!0,insecure:!1}});o(()=>a.broker,e=>{e&&(f.value=d(e))},{immediate:!0});let v=y(()=>{let e=f.value;return e.name.trim()!==``&&e.host.trim()!==``&&e.port>=1&&e.port<=65535&&(!e.use_jwt_auth||(e.audience?.trim()??``)!==``)});function w(){let e=f.value;(!e.audience||e.audience===e.host)&&(e.audience=e.host)}function E(e){f.value.disallowedInput||(f.value.disallowedInput=[]);let t=f.value.disallowedInput.indexOf(e);t===-1?f.value.disallowedInput.push(e):f.value.disallowedInput.splice(t,1)}function D(){v.value&&s(`done`,d(f.value))}function O(){s(`cancel`)}return(r,a)=>(h(),u(p,{to:`body`},[_(V,{"enter-active-class":`transition-opacity duration-200`,"enter-from-class":`opacity-0`,"leave-active-class":`transition-opacity duration-200`,"leave-to-class":`opacity-0`},{default:e(()=>[n.show&&n.broker?(h(),C(`div`,{key:0,class:`modal-backdrop`,onClick:a[14]||=z(e=>O(),[`self`])},[S(`div`,Eo,[S(`div`,Do,[S(`div`,null,[S(`h3`,Oo,t(n.isNew?`Add Broker`:`Edit Broker`),1),S(`p`,ko,t(n.isNew?`Configure a new MQTT broker`:`Editing ${n.broker.name||`(unnamed)`}`),1)]),S(`button`,{onClick:O,class:`text-content-secondary dark:text-white/60 hover:text-content-primary dark:hover:text-white transition-colors`},[...a[15]||=[S(`svg`,{class:`w-5 h-5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M6 18L18 6M6 6l12 12`})],-1)]])]),S(`form`,{onSubmit:z(D,[`prevent`]),class:`modal-form`},[S(`div`,null,[a[16]||=S(`label`,{class:`modal-field-label`},[b(` Name `),S(`span`,{class:`text-red-500`},`*`)],-1),c(S(`input`,{"onUpdate:modelValue":a[0]||=e=>f.value.name=e,type:`text`,placeholder:`Broker Name`,class:`modal-input`},null,512),[[U,f.value.name]])]),S(`div`,Ao,[S(`div`,null,[a[18]||=S(`label`,{class:`modal-field-label`},[b(` Format `),S(`span`,{class:`text-red-500`},`*`)],-1),c(S(`select`,{"onUpdate:modelValue":a[1]||=e=>f.value.format=e,class:`modal-select`},[...a[17]||=[S(`option`,{value:`letsmesh`},`LetsMesh MQTT format`,-1),S(`option`,{value:`mqtt`},`pyMC MQTT format`,-1)]],512),[[R,f.value.format]])]),S(`div`,jo,[S(`button`,{type:`button`,onClick:a[2]||=e=>f.value.enabled=!f.value.enabled,class:T([`relative inline-flex h-5 w-9 flex-shrink-0 cursor-pointer rounded-full transition-colors duration-200 ease-in-out focus:outline-none`,f.value.enabled?`bg-primary`:`bg-gray-200 dark:bg-white/15`])},[S(`span`,{class:T([`pointer-events-none absolute top-0.5 left-0.5 inline-block h-4 w-4 transform rounded-full bg-white shadow transition duration-200 ease-in-out`,f.value.enabled?`translate-x-4`:`translate-x-0`])},null,2)],2),a[19]||=S(`span`,{class:`text-sm font-medium text-content-primary dark:text-content-primary`},`Enabled`,-1)])]),f.value.format===`mqtt`?(h(),C(`div`,Mo,[S(`div`,null,[a[20]||=S(`label`,{class:`modal-field-label`},[b(` MQTT Base Topic `),S(`span`,{class:`font-normal text-content-muted dark:text-content-muted/60 ml-1`},`(e.g. meshcore/repeater)`)],-1),c(S(`input`,{"onUpdate:modelValue":a[3]||=e=>f.value.base_topic=e,placeholder:`meshcore/repeater`,class:`modal-input`},null,512),[[U,f.value.base_topic]])]),a[21]||=S(`div`,null,null,-1)])):g(``,!0),S(`div`,No,[S(`div`,null,[a[23]||=S(`label`,{class:`modal-field-label`},[b(` Transport `),S(`span`,{class:`text-red-500`},`*`)],-1),c(S(`select`,{"onUpdate:modelValue":a[4]||=e=>f.value.transport=e,class:`modal-select`},[...a[22]||=[S(`option`,{value:`websockets`},`Websockets`,-1),S(`option`,{value:`tcp`},`TCP`,-1)]],512),[[R,f.value.transport]])]),S(`div`,Po,[S(`button`,{type:`button`,onClick:a[5]||=e=>f.value.use_jwt_auth=!f.value.use_jwt_auth,class:T([`relative inline-flex h-5 w-9 flex-shrink-0 cursor-pointer rounded-full transition-colors duration-200 ease-in-out focus:outline-none`,f.value.use_jwt_auth?`bg-primary`:`bg-gray-200 dark:bg-white/15`])},[S(`span`,{class:T([`pointer-events-none absolute top-0.5 left-0.5 inline-block h-4 w-4 transform rounded-full bg-white shadow transition duration-200 ease-in-out`,f.value.use_jwt_auth?`translate-x-4`:`translate-x-0`])},null,2)],2),a[24]||=S(`span`,{class:`text-sm font-medium text-content-primary dark:text-content-primary`},`Use JWT Auth`,-1)])]),S(`div`,Fo,[S(`div`,null,[a[25]||=S(`label`,{class:`modal-field-label`},[b(` Host `),S(`span`,{class:`text-red-500`},`*`)],-1),c(S(`input`,{"onUpdate:modelValue":a[6]||=e=>f.value.host=e,type:`text`,placeholder:`mqtt.myserver.com`,onBlur:w,class:`modal-input font-mono`},null,544),[[U,f.value.host]])]),S(`div`,null,[f.value.use_jwt_auth?(h(),C(x,{key:0},[a[26]||=S(`label`,{class:`modal-field-label`},[b(` Audience `),S(`span`,{class:`text-red-500`},`*`),S(`span`,{class:`font-normal text-content-muted dark:text-content-muted/60 ml-1`},`(usually same as host)`)],-1),c(S(`input`,{"onUpdate:modelValue":a[7]||=e=>f.value.audience=e,type:`text`,placeholder:`mqtt.myserver.com`,class:`modal-input font-mono`},null,512),[[U,f.value.audience]])],64)):(h(),C(x,{key:1},[a[27]||=S(`label`,{class:`modal-field-label`},[b(` Username `),S(`span`,{class:`font-normal text-content-muted dark:text-content-muted/60 ml-1`},`(blank = anonymous)`)],-1),a[28]||=S(`input`,{type:`text`,autocomplete:`username`,style:{display:`none`}},null,-1),c(S(`input`,{autocomplete:`username`,"onUpdate:modelValue":a[8]||=e=>f.value.username=e,type:`text`,placeholder:`username`,class:`modal-input`},null,512),[[U,f.value.username]])],64))]),S(`div`,null,[a[29]||=S(`label`,{class:`modal-field-label`},[b(` Port `),S(`span`,{class:`text-red-500`},`*`),S(`span`,{class:`font-normal text-content-muted dark:text-content-muted/60 ml-1`},`(443 WS, 1883 TCP)`)],-1),c(S(`input`,{"onUpdate:modelValue":a[9]||=e=>f.value.port=e,type:`number`,min:`0`,max:`65535`,class:`modal-input font-mono`},null,512),[[U,f.value.port,void 0,{number:!0}]])]),S(`div`,{class:T(f.value.use_jwt_auth?`invisible pointer-events-none`:``),"aria-hidden":f.value.use_jwt_auth?`true`:void 0},[a[30]||=S(`label`,{class:`modal-field-label`},`Password`,-1),a[31]||=S(`input`,{type:`password`,autocomplete:`current-password`,style:{display:`none`}},null,-1),c(S(`input`,{autocomplete:`new-password`,"onUpdate:modelValue":a[10]||=e=>f.value.password=e,type:`password`,readonly:``,onfocus:`this.removeAttribute('readonly');`,onblur:`this.setAttribute('readonly', true);`,class:`modal-input`},null,512),[[U,f.value.password]])],10,Io)]),S(`div`,Lo,[S(`div`,Ro,[S(`button`,{type:`button`,onClick:a[11]||=e=>f.value.retain_status=!f.value.retain_status,class:T([`relative inline-flex h-5 w-9 flex-shrink-0 cursor-pointer rounded-full transition-colors duration-200 ease-in-out focus:outline-none`,f.value.retain_status?`bg-primary`:`bg-gray-200 dark:bg-white/15`])},[S(`span`,{class:T([`pointer-events-none absolute top-0.5 left-0.5 inline-block h-4 w-4 transform rounded-full bg-white shadow transition duration-200 ease-in-out`,f.value.retain_status?`translate-x-4`:`translate-x-0`])},null,2)],2),a[32]||=S(`div`,null,[S(`span`,{class:`text-sm font-medium text-content-primary dark:text-content-primary`},`Retain Status`),S(`span`,{class:`text-xs text-content-muted dark:text-content-muted/60 ml-1`},`(MQTT retained)`)],-1)]),S(`div`,zo,[S(`div`,Bo,[S(`button`,{type:`button`,onClick:a[12]||=e=>f.value.tls.enabled=!f.value.tls.enabled,class:T([`relative inline-flex h-5 w-9 flex-shrink-0 cursor-pointer rounded-full transition-colors duration-200 ease-in-out focus:outline-none`,f.value.tls.enabled?`bg-primary`:`bg-gray-200 dark:bg-white/15`])},[S(`span`,{class:T([`pointer-events-none absolute top-0.5 left-0.5 inline-block h-4 w-4 transform rounded-full bg-white shadow transition duration-200 ease-in-out`,f.value.tls.enabled?`translate-x-4`:`translate-x-0`])},null,2)],2),a[33]||=S(`span`,{class:`text-sm font-medium text-content-primary dark:text-content-primary`},`TLS`,-1)]),S(`div`,Vo,[S(`button`,{type:`button`,onClick:a[13]||=e=>f.value.tls.insecure=!f.value.tls.insecure,class:T([`relative inline-flex h-5 w-9 flex-shrink-0 cursor-pointer rounded-full transition-colors duration-200 ease-in-out focus:outline-none`,f.value.tls.insecure?`bg-amber-500`:`bg-gray-200 dark:bg-white/15`])},[S(`span`,{class:T([`pointer-events-none absolute top-0.5 left-0.5 inline-block h-4 w-4 transform rounded-full bg-white shadow transition duration-200 ease-in-out`,f.value.tls.insecure?`translate-x-4`:`translate-x-0`])},null,2)],2),a[34]||=S(`span`,{class:`text-sm font-medium text-content-primary dark:text-content-primary`},`Insecure`,-1)])])]),S(`div`,null,[a[35]||=S(`label`,{class:`modal-field-label`},[b(` Block Packet Types `),S(`span`,{class:`text-content-secondary dark:text-content-muted font-normal text-xs ml-1`},`(prevent publishing to broker)`)],-1),S(`div`,Ho,[(h(),C(x,null,m(i,e=>S(`button`,{key:e,type:`button`,onClick:t=>E(e),class:T([`px-2.5 py-1 rounded text-xs font-mono font-medium border transition-colors`,f.value.disallowedInput?.includes(e)?`bg-red-100 dark:bg-red-900/30 border-red-300 dark:border-red-700/50 text-red-700 dark:text-red-400`:`bg-background-mute dark:bg-white/5 border-stroke-subtle dark:border-stroke/10 text-content-secondary dark:text-content-muted hover:border-primary/40`])},t(e),11,Uo)),64))]),a[36]||=S(`p`,{class:`mt-2 text-xs text-content-secondary dark:text-content-muted`},[S(`span`,{class:`text-red-600 dark:text-red-400 font-medium`},`Red = blocked.`),b(` Leave all unselected to publish all packet types. `)],-1)]),S(`div`,Wo,[S(`button`,{type:`button`,onClick:O,class:`modal-btn-cancel`},` Cancel `),S(`button`,{type:`submit`,disabled:!v.value,class:T([`flex-1 px-4 py-3 rounded-lg transition-colors font-medium`,v.value?`bg-accent-green/20 hover:bg-accent-green/30 border border-accent-green/50 text-accent-green`:`bg-background-mute dark:bg-white/5 border border-stroke-subtle dark:border-stroke/20 text-content-muted dark:text-content-muted/70 cursor-not-allowed`])},` Done `,10,Go)])],32)])])):g(``,!0)]),_:1})]))}}),qo={class:`space-y-12`},Jo={class:`cfg-page-heading flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},Yo={class:`flex items-center gap-2 flex-shrink-0`},Xo=[`disabled`],Zo=[`disabled`],Qo={key:0,class:`bg-red-100 dark:bg-red-500/20 border border-red-500 dark:border-red-500/50 rounded-lg p-3 text-red-700 dark:text-red-400 text-sm`},$o={class:`cfg-section`},es={key:0,class:`text-sm text-content-secondary dark:text-content-muted`},ts={key:1,class:`space-y-3`},ns={class:`flex items-center gap-2`},rs={key:0,class:`space-y-2`},is=[`title`],as={key:1,class:`text-sm text-content-muted dark:text-content-muted/60 italic`},os={class:`cfg-card p-6`},ss={key:0,class:`grid grid-cols-1 sm:grid-cols-2 gap-x-8 gap-y-3`},cs={class:`flex flex-col py-1 border-b border-stroke-subtle dark:border-stroke/10`},ls={class:`text-content-primary dark:text-content-primary font-mono text-sm mt-0.5`},us={class:`flex flex-col py-1 border-b border-stroke-subtle dark:border-stroke/10`},ds={class:`text-content-primary dark:text-content-primary text-sm mt-0.5`},fs={class:`flex flex-col py-1`},ps={class:`text-content-primary dark:text-content-primary text-sm mt-0.5`},ms={class:`flex flex-col py-1`},hs={class:`text-content-primary dark:text-content-primary text-sm mt-0.5`},gs={key:1,class:`space-y-3`},_s={class:`grid grid-cols-1 sm:grid-cols-2 gap-3`},vs={class:`cfg-card p-6`},ys={class:`flex items-start justify-between mb-4`},bs={key:0,class:`flex items-center gap-2 flex-shrink-0 ml-4`},xs={class:`relative`},Ss={key:0,class:`absolute right-0 top-full mt-1 z-20 w-64 rounded-lg shadow-lg border border-stroke-subtle dark:border-stroke/20 bg-white dark:bg-[var(--color-surface)] overflow-hidden`},Cs={class:`py-1`},ws=[`onClick`],Ts={class:`min-w-0 flex-1`},Es={class:`text-sm font-medium text-content-primary dark:text-content-primary group-hover:text-primary transition-colors`},Ds={class:`text-xs text-content-secondary dark:text-content-muted`},Os=[`href`],ks={key:0,class:`flex flex-col items-center justify-center py-8 rounded-lg border-2 border-dashed border-stroke-subtle dark:border-stroke/20 text-content-secondary dark:text-content-muted`},As={key:0,class:`text-xs mt-0.5 opacity-70`},js={key:1,class:`space-y-2`},Ms={class:`flex items-center gap-3 px-4 py-2.5`},Ns={class:`min-w-0 flex-1 flex items-center gap-2 flex-wrap`},Ps={class:`text-sm font-medium text-content-primary dark:text-content-primary`},Fs={class:`text-xs font-mono text-content-secondary dark:text-content-muted`},Is={key:0,class:`flex items-center gap-1.5 flex-shrink-0`},Ls=[`onClick`],Rs=[`onClick`],zs=F(f({__name:`LetsMeshSettings`,setup(i,{expose:a}){let s=N(),u=y(()=>s.stats?.config?.mqtt_brokers||{}),d=To;function f(e){return{...e,tls:{...e.tls},disallowedInput:[...e.disallowedInput??[]]}}let p=l(!1),w=l(!1),E=l(``),D=l(!1),O=l(null),k=l(!1),A=l(``),M=l(300),P=l(``),F=l(``),I=l([]),L=l(null),R=l(!1),B=l(null),H=l({_id:0,enabled:!0,name:``,host:``,port:443,format:`letsmesh`,use_jwt_auth:!1,transport:`websockets`,disallowedInput:[],retain_status:!1,tls:{enabled:!0,insecure:!1}}),W=l(!1),G=l(null),K=l(!1);async function te(){if(!K.value){K.value=!0;try{let e=await j.get(`/api/mqtt_status`);e.data?.success&&(G.value=e.data.data)}catch{}finally{K.value=!1}}}let ne=1;function q(e={}){return{_id:ne++,enabled:e.enabled??!0,name:e.name??``,host:e.host??``,port:e.port??0,audience:e.audience??``,format:e.format??`letsmesh`,use_jwt_auth:e.use_jwt_auth??!1,username:e.username??``,password:e.password??``,transport:e.transport??`websockets`,disallowedInput:Array.isArray(e.disallowedInput)?[...e.disallowedInput]:[],retain_status:e.retain_status??!1,base_topic:e.base_topic??``,tls:{enabled:e.tls?.enabled??!1,insecure:e.tls?.insecure??!1}}}function re(){let e=u.value;A.value=e.iata_code??``,M.value=e.status_interval??300,P.value=e.owner??``,F.value=e.email??``,I.value=Array.isArray(e.brokers)?e.brokers.map(e=>q(e)):[]}o(u,()=>{p.value||re()},{immediate:!0});function ie(){return{iata_code:A.value,status_interval:M.value,owner:P.value,email:F.value,brokers:I.value.map(e=>{let t={name:e.name,enabled:e.enabled,transport:e.transport,host:e.host,port:e.port,use_jwt_auth:e.use_jwt_auth,format:e.format,disallowed_packet_types:e.disallowedInput,base_topic:e.base_topic,retain_status:e.retain_status,tls:{enabled:e.tls?.enabled??!1,insecure:e.tls?.insecure??!1}};return e.use_jwt_auth?{...t,audience:e.audience}:{...t,username:e.username,password:e.password}})}}async function J(){try{let e=(await j.post(`/api/update_mqtt_config`,ie())).data;return e?.success?(await s.fetchStats(),await te(),{success:!0}):{success:!1,error:e?.error||`Save failed`}}catch(e){let t=e;return{success:!1,error:t?.response?.data?.error||t?.message||`Request failed`}}}function Y(){re(),O.value={iata:A.value,interval:M.value,owner:P.value,email:F.value,brokers:I.value.map(f)},p.value=!0,E.value=``}function X(){O.value&&(A.value=O.value.iata,M.value=O.value.interval,P.value=O.value.owner,F.value=O.value.email,I.value=O.value.brokers.map(f)),L.value=null,R.value=!1,B.value=null,k.value=!1,p.value=!1,O.value=null,E.value=``}async function Z(){if(L.value!==null){let e=H.value;if(!e.name.trim()||!e.host.trim()){E.value=`Please complete or cancel the open broker edit before saving.`;return}ce()}w.value=!0,E.value=``;let e=await J();w.value=!1,e.success?(p.value=!1,k.value=!1,O.value=null,D.value=!0):E.value=e.error}function Q(){L.value!==null&&$();let e=q();I.value.push(e),B.value=null,R.value=!0,H.value=f(e),L.value=e._id}function ae(e){L.value!==null&&L.value!==e._id&&$(),B.value=f(e),R.value=!1,H.value=f(e),L.value=e._id}function $(){if(R.value&&L.value!==null)I.value=I.value.filter(e=>e._id!==L.value);else if(B.value){let e=I.value.findIndex(e=>e._id===B.value._id);e!==-1&&I.value.splice(e,1,f(B.value))}L.value=null,R.value=!1,B.value=null}function ce(){let e=H.value,t=I.value.findIndex(t=>t._id===e._id);t!==-1&&I.value.splice(t,1,f(e)),L.value=null,R.value=!1,B.value=null}function le(e){H.value=e,ce()}function ue(e){I.value=I.value.filter(t=>t._id!==e),L.value===e&&(L.value=null,R.value=!1,B.value=null)}function de(e){W.value=!1,L.value!==null&&$(),e.brokers.forEach(e=>I.value.push(q(e)))}let fe=y(()=>{let e=H.value;return e.name.trim()!==``&&e.host.trim()!==``&&e.port>=1&&e.port<=65535&&(!e.use_jwt_auth||(e.audience?.trim()??``)!==``)});async function pe(){L.value!==null&&fe.value&&ce(),w.value=!0,E.value=``;let e=await J();return w.value=!1,e.success?(p.value=!1,k.value=!1,O.value=null,D.value=!0,!0):(E.value=e.error??`Save failed`,!1)}let{showUnsavedModal:me,requestLeave:he,handleDiscard:ge,handleSave:_e}=se(p,w,X,pe);a({requestLeave:he,isEditing:p});let ve=null;return r(()=>{te(),ve=setInterval(te,5e3)}),n(()=>{ve&&clearInterval(ve)}),(n,r)=>(h(),C(x,null,[_(ee,{modelValue:D.value,"onUpdate:modelValue":r[0]||=e=>D.value=e,message:`Broker settings have been saved. A service restart is required for the changes to take effect.`},null,8,[`modelValue`]),_(Ko,{show:L.value!==null,broker:L.value===null?null:H.value,"is-new":R.value,onDone:le,onCancel:$},null,8,[`show`,`broker`,`is-new`]),_(oe,{show:v(me),"is-saving":w.value,label:`Broker settings`,onDiscard:v(ge),onSave:v(_e)},null,8,[`show`,`is-saving`,`onDiscard`,`onSave`]),S(`div`,qo,[S(`div`,Jo,[r[8]||=S(`div`,null,[S(`h3`,{class:`text-base sm:text-lg font-semibold text-content-primary dark:text-content-primary mb-1 sm:mb-2`},` Observer Configuration `),S(`p`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},` Configure LetsMesh observer settings, MQTT brokers, and connection status `)],-1),S(`div`,Yo,[p.value?(h(),C(x,{key:1},[S(`button`,{onClick:X,disabled:w.value,class:`px-3 sm:px-4 py-2 bg-background-mute dark:bg-white/5 hover:bg-stroke-subtle dark:hover:bg-white/10 text-content-primary dark:text-content-primary rounded-lg border border-stroke-subtle dark:border-stroke/20 transition-colors text-sm disabled:opacity-50 disabled:cursor-not-allowed`},` Cancel `,8,Xo),S(`button`,{onClick:Z,disabled:w.value,class:`btn-primary`},t(w.value?`Saving…`:`Save Settings`),9,Zo)],64)):(h(),C(`button`,{key:0,onClick:Y,class:`btn-primary`},` Edit Settings `))])]),E.value?(h(),C(`div`,Qo,t(E.value),1)):g(``,!0),S(`div`,$o,[r[10]||=S(`div`,{class:`mb-4`},[S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-1`},`Observer Status`),S(`p`,{class:`text-sm text-content-secondary dark:text-content-muted`},`Live LetsMesh broker connection state`)],-1),G.value?(h(),C(`div`,ts,[S(`div`,ns,[r[9]||=S(`span`,{class:`text-sm text-content-secondary dark:text-content-muted w-36`},`Handler`,-1),S(`span`,{class:T([`inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-medium`,G.value.handler_active?`bg-green-100 dark:bg-green-900/30 text-green-700 dark:text-green-400`:`bg-gray-100 dark:bg-gray-800/50 text-gray-500 dark:text-gray-400`])},[S(`span`,{class:T([`w-1.5 h-1.5 rounded-full`,G.value.handler_active?`bg-green-500`:`bg-gray-400`])},null,2),b(` `+t(G.value.handler_active?`Active`:`Inactive`),1)],2)]),G.value.brokers.length?(h(),C(`div`,rs,[(h(!0),C(x,null,m(G.value.brokers,e=>(h(),C(`div`,{key:e.host,class:`flex items-center gap-2`},[S(`span`,{class:`text-sm text-content-secondary dark:text-content-muted w-36 truncate`,title:e.name},t(e.name),9,is),S(`span`,{class:T([`inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-medium`,e.status.connected?`bg-green-100 dark:bg-green-900/30 text-green-700 dark:text-green-400`:e.status.reconnecting?`bg-amber-100 dark:bg-amber-900/30 text-amber-700 dark:text-amber-400`:`bg-red-100 dark:bg-red-900/30 text-red-600 dark:text-red-400`])},[S(`span`,{class:T([`w-1.5 h-1.5 rounded-full`,e.status.connected?`bg-green-500`:e.status.reconnecting?`bg-amber-500`:`bg-red-500`])},null,2),b(` `+t(e.status.connected?`Connected`:e.status.reconnecting?`Reconnecting…`:`Disconnected`),1)],2)]))),128))])):(h(),C(`div`,as,`No broker connections configured.`))])):(h(),C(`div`,es,` Status unavailable — service may not be running. `))]),S(`div`,os,[r[19]||=S(`div`,{class:`mb-4`},[S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-1`},`Observer Setup`),S(`p`,{class:`text-sm text-content-secondary dark:text-content-muted`},`IATA code, status interval, and owner details`)],-1),S(`div`,null,[p.value?g(``,!0):(h(),C(`div`,ss,[S(`div`,cs,[r[11]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`IATA Code`,-1),S(`span`,ls,t(u.value.iata_code||``),1)]),S(`div`,us,[r[12]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Status Interval`,-1),S(`span`,ds,t(u.value.status_interval??300)+`s`,1)]),S(`div`,fs,[r[13]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Owner`,-1),S(`span`,ps,t(u.value.owner||``),1)]),S(`div`,ms,[r[14]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Email`,-1),S(`span`,hs,t(u.value.email||``),1)])])),p.value?(h(),C(`div`,gs,[S(`div`,_s,[S(`div`,null,[r[15]||=S(`label`,{class:`block text-xs sm:text-sm text-content-secondary dark:text-content-muted mb-1`},[b(` IATA Code `),S(`span`,{class:`text-content-muted dark:text-content-muted/60 text-xs`},`(e.g. SFO, LHR)`)],-1),c(S(`input`,{"onUpdate:modelValue":r[1]||=e=>A.value=e,type:`text`,maxlength:`10`,placeholder:`TEST`,class:`cfg-input font-mono`},null,512),[[U,A.value]])]),S(`div`,null,[r[16]||=S(`label`,{class:`block text-xs sm:text-sm text-content-secondary dark:text-content-muted mb-1`},[b(` Status Interval `),S(`span`,{class:`text-content-muted dark:text-content-muted/60 text-xs`},`(seconds, min 60)`)],-1),c(S(`input`,{"onUpdate:modelValue":r[2]||=e=>M.value=e,type:`number`,min:`60`,max:`3600`,class:`cfg-input font-mono`},null,512),[[U,M.value,void 0,{number:!0}]])]),S(`div`,null,[r[17]||=S(`label`,{class:`block text-xs sm:text-sm text-content-secondary dark:text-content-muted mb-1`},`Owner Companion Pubkey`,-1),c(S(`input`,{"onUpdate:modelValue":r[3]||=e=>P.value=e,type:`text`,placeholder:`Optional`,class:`cfg-input`},null,512),[[U,P.value]])]),S(`div`,null,[r[18]||=S(`label`,{class:`block text-xs sm:text-sm text-content-secondary dark:text-content-muted mb-1`},`Email`,-1),c(S(`input`,{"onUpdate:modelValue":r[4]||=e=>F.value=e,type:`email`,placeholder:`Optional`,class:`cfg-input`},null,512),[[U,F.value]])])])])):g(``,!0)])]),S(`div`,vs,[S(`div`,ys,[r[25]||=S(`div`,null,[S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-1`},`Broker Settings`),S(`p`,{class:`text-sm text-content-secondary dark:text-content-muted`},`MQTT brokers for observer publishing`)],-1),p.value?(h(),C(`div`,bs,[S(`div`,xs,[S(`button`,{onClick:r[5]||=e=>W.value=!W.value,class:`inline-flex items-center gap-1.5 px-3 sm:px-4 py-2 bg-background-mute dark:bg-white/5 hover:bg-stroke-subtle dark:hover:bg-white/10 text-content-primary dark:text-content-primary rounded-lg border border-stroke-subtle dark:border-stroke/20 transition-colors text-sm`},[r[21]||=b(` From Template `,-1),(h(),C(`svg`,{class:T([`w-3 h-3 transition-transform`,W.value?`rotate-180`:``]),fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[...r[20]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M19 9l-7 7-7-7`},null,-1)]],2))]),_(V,{name:`dropdown`},{default:e(()=>[W.value?(h(),C(`div`,Ss,[r[23]||=S(`div`,{class:`px-3 py-2 border-b border-stroke-subtle dark:border-stroke/10`},[S(`p`,{class:`text-xs font-medium text-content-secondary dark:text-content-muted uppercase tracking-wide`},`Known Networks`)],-1),S(`div`,Cs,[(h(!0),C(x,null,m(v(d),e=>(h(),C(`div`,{key:e.name,class:`flex items-center gap-2 px-3 py-2.5 hover:bg-background-mute dark:hover:bg-background/30 cursor-pointer group`,onClick:t=>de(e)},[S(`div`,Ts,[S(`p`,Es,t(e.name),1),S(`p`,Ds,t(e.brokers.length)+` broker`+t(e.brokers.length===1?``:`s`),1)]),S(`a`,{href:e.website,target:`_blank`,rel:`noopener noreferrer`,title:`Visit website`,class:`flex-shrink-0 p-1 rounded hover:bg-primary/10 text-content-secondary dark:text-content-muted hover:text-primary transition-colors`,onClick:r[6]||=z(()=>{},[`stop`])},[...r[22]||=[S(`svg`,{class:`w-3.5 h-3.5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14`})],-1)]],8,Os)],8,ws))),128))])])):g(``,!0)]),_:1}),W.value?(h(),C(`div`,{key:0,class:`fixed inset-0 z-10`,onClick:r[7]||=e=>W.value=!1})):g(``,!0)]),S(`button`,{onClick:Q,class:`btn-primary inline-flex items-center gap-1.5`},[...r[24]||=[S(`svg`,{class:`w-3.5 h-3.5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M12 4v16m8-8H4`})],-1),b(` Add `,-1)]])])):g(``,!0)]),I.value.length?(h(),C(`div`,js,[(h(!0),C(x,null,m(I.value,e=>(h(),C(`div`,{key:e._id,class:`cfg-card overflow-hidden`},[S(`div`,Ms,[S(`div`,Ns,[S(`span`,{class:T([`inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-medium`,e.enabled?`bg-green-100 dark:bg-green-900/30 text-green-700 dark:text-green-400`:`bg-red-100 dark:bg-red-900/30 text-red-600 dark:text-red-400`])},[S(`span`,{class:T([`w-1.5 h-1.5 rounded-full`,e.enabled?`bg-green-500`:`bg-red-500`])},null,2),b(` `+t(e.enabled?`Enabled`:`Disabled`),1)],2),S(`span`,Ps,t(e.name||`(unnamed)`),1),S(`span`,Fs,t(e.host||``)+`:`+t(e.port),1)]),p.value?(h(),C(`div`,Is,[S(`button`,{onClick:t=>ae(e),class:`px-2.5 py-1 text-xs bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded border border-primary/50 transition-colors`},` Edit `,8,Ls),S(`button`,{onClick:t=>ue(e._id),title:`Remove`,class:`p-1.5 rounded hover:bg-red-500/10 dark:hover:bg-red-900/20 text-content-secondary dark:text-content-muted hover:text-red-600 dark:hover:text-red-400 transition-colors`},[...r[28]||=[S(`svg`,{class:`w-3.5 h-3.5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16`})],-1)]],8,Rs)])):g(``,!0)])]))),128))])):(h(),C(`div`,ks,[r[26]||=S(`svg`,{class:`w-7 h-7 mb-2 opacity-40`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`1.5`,d:`M5 12h14M5 12l4-4m-4 4l4 4`})],-1),r[27]||=S(`p`,{class:`text-sm`},`No brokers configured`,-1),p.value?(h(),C(`p`,As,`Use Add or From Template above`)):g(``,!0)]))])])],64))}}),[[`__scopeId`,`data-v-a86a677e`]]),Bs={class:`space-y-12`},Vs={key:0,class:`rounded-lg border-2 border-red-500/50 dark:border-red-400/40 bg-red-100 dark:bg-red-500/10 p-4`},Hs={class:`cfg-section`},Us=[`disabled`],Ws={key:0,class:`flex items-center gap-2`},Gs={key:1,class:`flex items-center gap-2`},Ks={key:0,class:`text-xs text-green-600 dark:text-green-400 mt-2`},qs={key:1,class:`text-xs text-red-500 dark:text-red-400 mt-2`},Js={class:`cfg-section`},Ys={key:0},Xs={key:1,class:`rounded-lg border-2 border-red-500/50 dark:border-red-400/40 bg-red-50 dark:bg-red-500/10 p-4`},Zs={class:`flex items-start gap-3`},Qs={class:`flex-1`},$s={class:`text-xs text-red-600 dark:text-red-400/80 mt-1`},ec={class:`flex gap-2 mt-3`},tc=[`disabled`],nc=[`disabled`],rc={key:2,class:`text-xs text-green-600 dark:text-green-400 mt-2`},ic={key:3,class:`text-xs text-red-500 dark:text-red-400 mt-2`},ac={class:`cfg-section`},oc={class:`space-y-3`},sc={class:`flex items-center gap-3 cursor-pointer px-4 py-3 bg-background-mute dark:bg-background/30 rounded-lg border-2 border-dashed border-stroke-subtle dark:border-stroke/20 hover:border-cyan-500/50 dark:hover:border-primary/50 transition-colors`},cc={class:`text-sm text-content-secondary dark:text-content-muted`},lc={key:0,class:`bg-background-mute dark:bg-background/30 rounded-lg p-4 border border-stroke-subtle dark:border-stroke/10`},uc={key:0,class:`text-xs text-content-secondary dark:text-content-muted space-y-1 mb-3`},dc={class:`font-mono`},fc={class:`font-mono`},pc={key:0,class:`text-amber-600 dark:text-amber-400 font-medium`},mc={key:1,class:`text-content-muted`},hc={class:`text-xs text-content-secondary dark:text-content-muted`},gc={class:`font-mono`},_c={key:1},vc={key:2,class:`rounded-lg border-2 border-amber-500/50 dark:border-amber-400/40 bg-amber-50 dark:bg-amber-500/10 p-4`},yc={class:`flex items-start gap-3`},bc={class:`flex-1`},xc={class:`text-xs text-amber-700 dark:text-amber-300/80 mt-1`},Sc={class:`flex gap-2 mt-3`},Cc=[`disabled`],wc=[`disabled`],Tc={key:3,class:`text-xs text-green-600 dark:text-green-400 mt-2`},Ec={key:4,class:`text-xs text-red-500 dark:text-red-400 mt-2`},Dc={class:`cfg-section`},Oc={key:0},kc={key:1,class:`rounded-lg border-2 border-red-500/50 dark:border-red-400/40 bg-red-50 dark:bg-red-500/10 p-4`},Ac={class:`flex items-start gap-3`},jc={class:`flex-1`},Mc={class:`text-xs text-red-600 dark:text-red-400/80 mt-1`},Nc={class:`flex gap-2 mt-3`},Pc=[`disabled`],Fc=[`disabled`],Ic={key:2,class:`bg-background-mute dark:bg-background/30 rounded-lg p-4 border border-stroke-subtle dark:border-stroke/10 space-y-2`},Lc={class:`flex items-center justify-between`},Rc={class:`text-xs text-content-secondary dark:text-content-muted space-y-1`},zc={class:`font-mono`},Bc={key:0},Vc={class:`font-mono`},Hc={key:1},Uc={class:`font-mono text-[10px] break-all`},Wc={key:3,class:`text-xs text-red-500 dark:text-red-400 mt-2`},Gc=f({__name:`BackupRestore`,setup(e){let n=y(()=>window.location.protocol===`http:`),r=l(!1),i=l(``),a=l(``);async function o(){r.value=!0,i.value=``,a.value=``;try{let e=await M.exportConfig(!1);if(!e.success||!e.data){a.value=e.error||`Export failed`;return}let t=new Blob([JSON.stringify(e.data,null,2)],{type:`application/json`}),n=URL.createObjectURL(t),r=document.createElement(`a`);r.href=n,r.download=`pymc-repeater-settings-${(e.data.meta?.exported_at||new Date().toISOString()).replace(/[:.]/g,`-`)}.json`,document.body.appendChild(r),r.click(),document.body.removeChild(r),URL.revokeObjectURL(n),i.value=`Settings exported successfully (secrets redacted).`}catch(e){a.value=e instanceof Error?e.message:`Export failed`}finally{r.value=!1}}let s=l(!1),c=l(!1),u=l(``),f=l(``);async function p(){c.value=!0,u.value=``,f.value=``;try{let e=await M.exportConfig(!0);if(!e.success||!e.data){f.value=e.error||`Export failed`;return}let t=new Blob([JSON.stringify(e.data,null,2)],{type:`application/json`}),n=URL.createObjectURL(t),r=document.createElement(`a`);r.href=n,r.download=`pymc-repeater-full-backup-${(e.data.meta?.exported_at||new Date().toISOString()).replace(/[:.]/g,`-`)}.json`,document.body.appendChild(r),r.click(),document.body.removeChild(r),URL.revokeObjectURL(n),u.value=`Full backup exported (includes all secrets).`,s.value=!1}catch(e){f.value=e instanceof Error?e.message:`Export failed`}finally{c.value=!1}}let m=l(null),v=l(null),w=l(!1),T=l(!1),E=l(``),D=l(``),O=l(null),k=y(()=>v.value?.config?Object.keys(v.value.config).join(`, `):``),A=y(()=>{let e=v.value?.meta?.includes_secrets;return e===!0||e===`true`});function j(e){let t=e.target.files?.[0];if(!t)return;m.value=t,v.value=null,w.value=!1,E.value=``,D.value=``;let n=new FileReader;n.onload=e=>{try{let t=JSON.parse(e.target?.result);t.config&&typeof t.config==`object`?v.value={meta:t.meta,config:t.config}:typeof t==`object`&&!Array.isArray(t)?v.value={config:t}:D.value=`Invalid file format — expected a JSON config object.`}catch{D.value=`Invalid JSON file.`}},n.readAsText(t)}function N(){w.value=!1,v.value=null,m.value=null,O.value&&(O.value.value=``)}async function P(){if(v.value?.config){T.value=!0,E.value=``,D.value=``;try{let e=await M.importConfig(v.value.config);if(e.success){let t=e.data,n=e.message||t?.message||`Configuration imported.`;t?.restart_required&&(n+=` A service restart is required for radio changes to take effect.`),E.value=n,w.value=!1,v.value=null,m.value=null,O.value&&(O.value.value=``)}else D.value=e.error||`Import failed`}catch(e){D.value=e instanceof Error?e.message:`Import failed`}finally{T.value=!1}}}let F=l(!1),L=l(!1),R=l(null),z=l(``);async function B(){L.value=!0,z.value=``;try{let e=await M.exportIdentityKey();if(!e.success||!e.data){z.value=e.error||`Export failed`;return}R.value=e.data;let t=new Blob([e.data.identity_key_hex],{type:`text/plain`}),n=URL.createObjectURL(t),r=document.createElement(`a`);r.href=n,r.download=`pymc-identity-${e.data.node_address||`key`}.hex`,document.body.appendChild(r),r.click(),document.body.removeChild(r),URL.revokeObjectURL(n)}catch(e){z.value=e instanceof Error?e.message:`Export failed`}finally{L.value=!1}}return(e,l)=>(h(),C(`div`,Bs,[l[39]||=S(`div`,{class:`cfg-page-heading flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},[S(`div`,null,[S(`h3`,{class:`text-base sm:text-lg font-semibold text-content-primary dark:text-content-primary mb-1 sm:mb-2`},`Backup & Restore`),S(`p`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Export, import, and restore your repeater configuration`)])],-1),n.value?(h(),C(`div`,Vs,[...l[6]||=[d(`<div class="flex items-start gap-3"><svg class="w-6 h-6 text-red-600 dark:text-red-400 shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 16.5c-.77.833.192 2.5 1.732 2.5z"></path></svg><div><h4 class="text-sm font-semibold text-red-700 dark:text-red-400"> Unencrypted Connection </h4><p class="text-xs text-red-600 dark:text-red-400/80 mt-1"> This page is served over <strong>HTTP</strong>, not HTTPS. Exported data (including identity keys) will be transmitted in <strong>plain text</strong>. Only use these features on a trusted local network. </p></div></div>`,1)]])):g(``,!0),S(`div`,Hs,[l[9]||=S(`div`,{class:`flex items-start justify-between mb-4`},[S(`div`,null,[S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-1`},` Export Settings `),S(`p`,{class:`text-sm text-content-secondary dark:text-content-muted`},[b(` Download the current configuration as a JSON file. Passwords, JWT secrets, and identity keys are `),S(`strong`,null,`redacted`),b(`. Safe to share or use as a template for other devices. `)])])],-1),S(`button`,{onClick:o,disabled:r.value,class:`cfg-btn-primary`},[r.value?(h(),C(`span`,Ws,[_(I,{size:`sm`,color:`current`,class:`inline-block`}),l[7]||=b(` Exporting… `,-1)])):(h(),C(`span`,Gs,[...l[8]||=[S(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4`})],-1),b(` Export Settings `,-1)]]))],8,Us),i.value?(h(),C(`p`,Ks,t(i.value),1)):g(``,!0),a.value?(h(),C(`p`,qs,t(a.value),1)):g(``,!0)]),S(`div`,Js,[l[15]||=d(`<div class="flex items-start justify-between mb-4"><div><h3 class="text-lg font-semibold text-content-primary dark:text-content-primary mb-1"> Full Backup </h3><p class="text-sm text-content-secondary dark:text-content-muted"> Download a complete backup including <strong>all passwords, JWT secrets, and identity keys</strong>. Required for restoring to a new device or recovering from a failed SD card. </p></div></div><div class="rounded-lg border border-red-500/30 dark:border-red-400/30 bg-red-50 dark:bg-red-500/10 p-3 mb-4"><p class="text-xs text-red-700 dark:text-red-400"><strong>Contains sensitive data.</strong> The backup file will include plain-text passwords and private keys. Store it securely and never share it. </p></div>`,2),s.value?g(``,!0):(h(),C(`div`,Ys,[S(`button`,{onClick:l[0]||=e=>s.value=!0,class:`px-4 py-2 bg-red-500/20 dark:bg-red-400/20 hover:bg-red-500/30 dark:hover:bg-red-400/30 text-red-900 dark:text-red-200 rounded-lg border border-red-500/50 dark:border-red-400/40 transition-colors text-sm`},[...l[10]||=[S(`span`,{class:`flex items-center gap-2`},[S(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z`})]),b(` Full Backup `)],-1)]])])),s.value?(h(),C(`div`,Xs,[S(`div`,Zs,[l[14]||=S(`svg`,{class:`w-5 h-5 text-red-600 dark:text-red-400 shrink-0 mt-0.5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 16.5c-.77.833.192 2.5 1.732 2.5z`})],-1),S(`div`,Qs,[l[13]||=S(`h4`,{class:`text-sm font-semibold text-red-700 dark:text-red-400`},` Confirm Full Backup `,-1),S(`p`,$s,[l[11]||=b(` This will export `,-1),l[12]||=S(`strong`,null,`all secrets in plain text`,-1),b(` including admin/guest passwords, JWT secret, and your repeater's private identity key`+t(n.value?` over an unencrypted HTTP connection`:``)+`. `,1)]),S(`div`,ec,[S(`button`,{onClick:p,disabled:c.value,class:`px-4 py-2 bg-red-600 hover:bg-red-700 dark:bg-red-500 dark:hover:bg-red-600 text-white rounded-lg transition-colors text-sm disabled:opacity-50`},t(c.value?`Exporting…`:`Yes, Export Full Backup`),9,tc),S(`button`,{onClick:l[1]||=e=>s.value=!1,disabled:c.value,class:`px-4 py-2 bg-background-mute dark:bg-white/5 hover:bg-stroke-subtle dark:hover:bg-white/10 text-content-primary dark:text-content-primary rounded-lg transition-colors text-sm`},` Cancel `,8,nc)])])])])):g(``,!0),u.value?(h(),C(`p`,rc,t(u.value),1)):g(``,!0),f.value?(h(),C(`p`,ic,t(f.value),1)):g(``,!0)]),S(`div`,ac,[l[29]||=S(`div`,{class:`flex items-start justify-between mb-4`},[S(`div`,null,[S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-1`},` Import Configuration `),S(`p`,{class:`text-sm text-content-secondary dark:text-content-muted`},[b(` Restore configuration from a previously exported JSON file. Importing a `),S(`strong`,null,`full backup`),b(` will also restore passwords and identity keys. Importing a `),S(`strong`,null,`settings export`),b(` will only update non-sensitive settings. `)])])],-1),S(`div`,oc,[S(`label`,sc,[l[16]||=S(`svg`,{class:`w-5 h-5 text-content-secondary dark:text-content-muted`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12`})],-1),S(`span`,cc,t(m.value?m.value.name:`Choose a config JSON file…`),1),S(`input`,{ref_key:`fileInputRef`,ref:O,type:`file`,accept:`.json,application/json`,class:`hidden`,onChange:j},null,544)]),v.value?(h(),C(`div`,lc,[l[20]||=S(`h4`,{class:`text-sm font-medium text-content-primary dark:text-content-primary mb-2`},` Import Preview `,-1),v.value.meta?(h(),C(`div`,uc,[S(`p`,null,[l[17]||=b(` Exported: `,-1),S(`span`,dc,t(v.value.meta.exported_at),1)]),S(`p`,null,[l[18]||=b(` Version: `,-1),S(`span`,fc,t(v.value.meta.version),1)]),v.value.meta.includes_secrets===`true`||v.value.meta.includes_secrets===!0?(h(),C(`p`,pc,` ⚠ Full backup — will restore passwords and identity keys `)):(h(),C(`p`,mc,` Settings only — existing secrets will not be changed `))])):g(``,!0),S(`p`,hc,[l[19]||=b(` Sections: `,-1),S(`span`,gc,t(k.value),1)])])):g(``,!0),v.value&&!w.value?(h(),C(`div`,_c,[S(`button`,{onClick:l[2]||=e=>w.value=!0,class:`px-4 py-2 bg-amber-500/20 dark:bg-amber-400/20 hover:bg-amber-500/30 dark:hover:bg-amber-400/30 text-amber-900 dark:text-amber-200 rounded-lg border border-amber-500/50 dark:border-amber-400/40 transition-colors text-sm`},` Review & Import `)])):g(``,!0),w.value?(h(),C(`div`,vc,[S(`div`,yc,[l[28]||=S(`svg`,{class:`w-5 h-5 text-amber-600 dark:text-amber-400 shrink-0 mt-0.5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 16.5c-.77.833.192 2.5 1.732 2.5z`})],-1),S(`div`,bc,[l[27]||=S(`h4`,{class:`text-sm font-semibold text-amber-800 dark:text-amber-300`},` Confirm Import `,-1),S(`p`,xc,[l[24]||=b(` This will overwrite current settings for: `,-1),S(`strong`,null,t(k.value),1),l[25]||=b(`. `,-1),A.value?(h(),C(x,{key:0},[l[21]||=b(` This is a full backup — `,-1),l[22]||=S(`strong`,null,`passwords, JWT secrets, and identity keys will also be overwritten`,-1),l[23]||=b(`. `,-1)],64)):(h(),C(x,{key:1},[b(` Passwords and identity keys will not be changed. `)],64)),l[26]||=b(` Some changes (radio settings) require a service restart. `,-1)]),S(`div`,Sc,[S(`button`,{onClick:P,disabled:T.value,class:`px-4 py-2 bg-amber-600 hover:bg-amber-700 dark:bg-amber-500 dark:hover:bg-amber-600 text-white rounded-lg transition-colors text-sm disabled:opacity-50`},t(T.value?`Importing…`:`Yes, Import`),9,Cc),S(`button`,{onClick:N,disabled:T.value,class:`px-4 py-2 bg-background-mute dark:bg-white/5 hover:bg-stroke-subtle dark:hover:bg-white/10 text-content-primary dark:text-content-primary rounded-lg transition-colors text-sm`},` Cancel `,8,wc)])])])])):g(``,!0),E.value?(h(),C(`p`,Tc,t(E.value),1)):g(``,!0),D.value?(h(),C(`p`,Ec,t(D.value),1)):g(``,!0)])]),S(`div`,Dc,[l[38]||=d(`<div class="flex items-start justify-between mb-4"><div><h3 class="text-lg font-semibold text-content-primary dark:text-content-primary mb-1"> Export Identity Key </h3><p class="text-sm text-content-secondary dark:text-content-muted"> Download the repeater&#39;s private identity key for backup. This key determines the node&#39;s address and cryptographic identity on the mesh. </p></div></div><div class="rounded-lg border border-red-500/30 dark:border-red-400/30 bg-red-50 dark:bg-red-500/10 p-3 mb-4"><p class="text-xs text-red-700 dark:text-red-400"><strong>Sensitive data.</strong> The identity key is the repeater&#39;s private key. Anyone with this key can impersonate your node. Store the exported file securely and never share it. </p></div>`,2),F.value?g(``,!0):(h(),C(`div`,Oc,[S(`button`,{onClick:l[3]||=e=>F.value=!0,class:`px-4 py-2 bg-red-500/20 dark:bg-red-400/20 hover:bg-red-500/30 dark:hover:bg-red-400/30 text-red-900 dark:text-red-200 rounded-lg border border-red-500/50 dark:border-red-400/40 transition-colors text-sm`},[...l[30]||=[S(`span`,{class:`flex items-center gap-2`},[S(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z`})]),b(` Export Identity Key `)],-1)]])])),F.value&&!R.value?(h(),C(`div`,kc,[S(`div`,Ac,[l[32]||=S(`svg`,{class:`w-5 h-5 text-red-600 dark:text-red-400 shrink-0 mt-0.5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 16.5c-.77.833.192 2.5 1.732 2.5z`})],-1),S(`div`,jc,[l[31]||=S(`h4`,{class:`text-sm font-semibold text-red-700 dark:text-red-400`},`Are you sure?`,-1),S(`p`,Mc,` This will transmit your private key `+t(n.value?`over an unencrypted HTTP connection. `:``)+` and download it as a file. `,1),S(`div`,Nc,[S(`button`,{onClick:B,disabled:L.value,class:`px-4 py-2 bg-red-600 hover:bg-red-700 dark:bg-red-500 dark:hover:bg-red-600 text-white rounded-lg transition-colors text-sm disabled:opacity-50`},t(L.value?`Exporting…`:`Yes, Export Key`),9,Pc),S(`button`,{onClick:l[4]||=e=>F.value=!1,disabled:L.value,class:`px-4 py-2 bg-background-mute dark:bg-white/5 hover:bg-stroke-subtle dark:hover:bg-white/10 text-content-primary dark:text-content-primary rounded-lg transition-colors text-sm`},` Cancel `,8,Fc)])])])])):g(``,!0),R.value?(h(),C(`div`,Ic,[S(`div`,Lc,[l[33]||=S(`h4`,{class:`text-sm font-medium text-content-primary dark:text-content-primary`},` Key Exported `,-1),S(`button`,{onClick:l[5]||=e=>{R.value=null,F.value=!1},class:`text-xs text-content-muted hover:text-content-secondary transition-colors`},` Dismiss `)]),S(`div`,Rc,[S(`p`,null,[l[34]||=b(` Key length: `,-1),S(`span`,zc,t(R.value.key_length_bytes)+` bytes`,1)]),R.value.node_address?(h(),C(`p`,Bc,[l[35]||=b(` Node address: `,-1),S(`span`,Vc,t(R.value.node_address),1)])):g(``,!0),R.value.public_key_hex?(h(),C(`p`,Hc,[l[36]||=b(` Public key: `,-1),S(`span`,Uc,t(R.value.public_key_hex),1)])):g(``,!0)]),l[37]||=S(`p`,{class:`text-xs text-green-600 dark:text-green-400`},`File downloaded successfully.`,-1)])):g(``,!0),z.value?(h(),C(`p`,Wc,t(z.value),1)):g(``,!0)])]))}}),Kc={class:`space-y-12`},qc={class:`cfg-page-heading flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},Jc={class:`flex items-center gap-2 flex-shrink-0`},Yc={class:`cfg-section`},Xc={class:`flex items-start justify-between mb-4`},Zc=[`disabled`],Qc={key:0,class:`flex items-center gap-1.5`},$c={key:1},el={key:0,class:`grid grid-cols-2 sm:grid-cols-4 gap-3 mb-6`},tl={class:`bg-background-mute dark:bg-background/30 rounded-lg p-3 border border-stroke-subtle dark:border-stroke/10`},nl={class:`text-lg font-semibold text-content-primary dark:text-content-primary font-mono`},rl={class:`bg-background-mute dark:bg-background/30 rounded-lg p-3 border border-stroke-subtle dark:border-stroke/10`},il={class:`text-lg font-semibold text-content-primary dark:text-content-primary font-mono`},al={class:`bg-background-mute dark:bg-background/30 rounded-lg p-3 border border-stroke-subtle dark:border-stroke/10`},ol={class:`text-lg font-semibold text-content-primary dark:text-content-primary font-mono`},sl={class:`bg-background-mute dark:bg-background/30 rounded-lg p-3 border border-stroke-subtle dark:border-stroke/10`},cl={class:`text-lg font-semibold text-content-primary dark:text-content-primary font-mono`},ll={key:1,class:`flex items-center justify-center py-12`},ul={class:`text-center`},dl={key:2,class:`rounded-lg border border-red-500/30 dark:border-red-400/30 bg-red-50 dark:bg-red-500/10 p-3 mb-4`},fl={class:`text-xs text-red-700 dark:text-red-400`},pl={key:3},ml={class:`overflow-x-auto`},hl={class:`w-full text-sm`},gl={class:`py-2.5 pr-4`},_l={class:`font-mono text-content-primary dark:text-content-primary`},vl={class:`py-2.5 pr-4 text-right`},yl={class:`font-mono text-content-secondary dark:text-content-muted`},bl={class:`py-2.5 pr-4 text-right hidden sm:table-cell`},xl={key:0,class:`text-xs text-content-muted`},Sl={class:`text-content-muted/60 ml-1`},Cl={key:1,class:`text-xs text-content-muted/50`},wl={key:2,class:`text-xs text-content-muted/50`},Tl={class:`py-2.5 text-right`},El=[`onClick`,`disabled`],Dl={key:0,class:`flex items-center gap-1`},Ol={key:1},kl={key:1,class:`text-xs text-content-muted/50`},Al={class:`flex items-start gap-3 mb-5`},jl={class:`flex-1 min-w-0`},Ml={class:`text-lg font-semibold text-content-primary dark:text-content-primary`},Nl={class:`text-sm text-content-secondary dark:text-content-muted mt-1`},Pl={class:`text-content-primary dark:text-content-primary`},Fl={class:`text-content-primary dark:text-content-primary font-mono`},Il={class:`flex gap-3`},Ll=[`disabled`],Rl=[`disabled`],zl={class:`cfg-section`},Bl={class:`flex flex-wrap gap-3`},Vl=[`disabled`],Hl=[`disabled`],Ul={class:`flex items-center gap-2`},Wl={key:0,class:`text-xs text-green-600 dark:text-green-400 mt-3`},Gl={key:1,class:`text-xs text-green-600 dark:text-green-400 mt-3`},Kl=f({__name:`DatabaseManagement`,setup(e){let n=new Set([`packets`,`adverts`,`noise_floor`,`crc_errors`,`room_messages`,`room_client_sync`,`companion_contacts`,`companion_channels`,`companion_messages`,`companion_prefs`]),i=l(!1),a=l(!1),o=l(``),s=l(null),c=l({}),d=l(null),f=l(``),w=l(!1),T=l(``),E=y(()=>s.value?s.value.tables.reduce((e,t)=>e+t.row_count,0):0);function D(e){return n.has(e)}function O(e,t){return!e||!t?0:Math.max(1,Math.round((t-e)/86400))}async function k(){a.value=!0,o.value=``;try{let e=await M.getDbStats();e.success&&e.data?s.value=e.data:o.value=e.error||`Failed to load database stats`}catch(e){o.value=e instanceof Error?e.message:`Failed to load database stats`}finally{a.value=!1}}function A(e,t){f.value=``,d.value={table:e,rowCount:t,executing:!1}}async function j(){if(!d.value)return;let{table:e}=d.value;d.value.executing=!0,f.value=``;try{let t=e===`all`?`all`:[e];e!==`all`&&(c.value[e]=!0);let n=await M.purgeTable(t);if(n.success){let t=n.data||{};f.value=`Deleted ${Object.values(t).reduce((e,t)=>e+(t.deleted||0),0).toLocaleString()} rows${e===`all`?` from all tables`:` from ${e}`}.`,d.value=null,await k()}else o.value=n.error||`Purge failed`,d.value=null}catch(e){o.value=e instanceof Error?e.message:`Purge failed`,d.value=null}finally{e!==`all`&&(c.value[e]=!1)}}async function N(){w.value=!0,T.value=``,o.value=``;try{let e=await M.vacuumDb();if(e.success&&e.data){let t=e.data.freed_bytes;T.value=t>0?`Compacted database — freed ${q(t)} (${q(e.data.size_before)}${q(e.data.size_after)}).`:`Database already compact (${q(e.data.size_after)}).`,await k()}else o.value=e.error||`Vacuum failed`}catch(e){o.value=e instanceof Error?e.message:`Vacuum failed`}finally{w.value=!1}}return r(k),(e,n)=>(h(),C(`div`,Kc,[S(`div`,qc,[n[5]||=S(`div`,null,[S(`h3`,{class:`text-base sm:text-lg font-semibold text-content-primary dark:text-content-primary mb-1 sm:mb-2`},`Database`),S(`p`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`View database statistics and perform maintenance`)],-1),S(`div`,Jc,[S(`button`,{onClick:n[0]||=e=>i.value=!i.value,class:`cfg-btn-primary`},t(i.value?`Lock`:`Unlock`),1)])]),S(`div`,Yc,[S(`div`,Xc,[n[7]||=S(`div`,null,[S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-1`},` Database Overview `),S(`p`,{class:`text-sm text-content-secondary dark:text-content-muted`},` Storage usage and table statistics for the repeater database. `)],-1),S(`button`,{onClick:k,disabled:a.value,class:`cfg-btn-secondary`},[a.value?(h(),C(`span`,Qc,[_(I,{size:`xs`,color:`current`,class:`inline-block`}),n[6]||=b(` Loading… `,-1)])):(h(),C(`span`,$c,`Refresh`))],8,Zc)]),s.value?(h(),C(`div`,el,[S(`div`,tl,[n[8]||=S(`p`,{class:`text-xs text-content-muted mb-1`},`Database Size`,-1),S(`p`,nl,t(v(q)(s.value.database_size_bytes)),1)]),S(`div`,rl,[n[9]||=S(`p`,{class:`text-xs text-content-muted mb-1`},`RRD Metrics`,-1),S(`p`,il,t(v(q)(s.value.rrd_size_bytes)),1)]),S(`div`,al,[n[10]||=S(`p`,{class:`text-xs text-content-muted mb-1`},`Total Size`,-1),S(`p`,ol,t(v(q)(s.value.database_size_bytes+s.value.rrd_size_bytes)),1)]),S(`div`,sl,[n[11]||=S(`p`,{class:`text-xs text-content-muted mb-1`},`Total Rows`,-1),S(`p`,cl,t(E.value.toLocaleString()),1)])])):g(``,!0),a.value&&!s.value?(h(),C(`div`,ll,[S(`div`,ul,[_(I,{class:`mx-auto mb-4`}),n[12]||=S(`div`,{class:`text-content-secondary dark:text-content-muted`},`Loading database info…`,-1)])])):g(``,!0),o.value?(h(),C(`div`,dl,[S(`p`,fl,t(o.value),1)])):g(``,!0),s.value&&s.value.tables.length>0?(h(),C(`div`,pl,[S(`div`,ml,[S(`table`,hl,[n[14]||=S(`thead`,null,[S(`tr`,{class:`border-b border-stroke-subtle dark:border-stroke/10`},[S(`th`,{class:`text-left py-2 pr-4 text-xs font-medium text-content-muted uppercase tracking-wider`},` Table `),S(`th`,{class:`text-right py-2 pr-4 text-xs font-medium text-content-muted uppercase tracking-wider`},` Rows `),S(`th`,{class:`text-right py-2 pr-4 text-xs font-medium text-content-muted uppercase tracking-wider hidden sm:table-cell`},` Date Range `),S(`th`,{class:`text-right py-2 text-xs font-medium text-content-muted uppercase tracking-wider`},` Actions `)])],-1),S(`tbody`,null,[(h(!0),C(x,null,m(s.value.tables,e=>(h(),C(`tr`,{key:e.name,class:`border-b border-stroke-subtle/50 dark:border-stroke/5`},[S(`td`,gl,[S(`span`,_l,t(e.name),1)]),S(`td`,vl,[S(`span`,yl,t(e.row_count.toLocaleString()),1)]),S(`td`,bl,[e.has_timestamp&&e.row_count>0?(h(),C(`span`,xl,[b(t(v(ne)(e.oldest_timestamp))+``+t(v(ne)(e.newest_timestamp))+` `,1),S(`span`,Sl,`(`+t(O(e.oldest_timestamp,e.newest_timestamp))+`d)`,1)])):e.row_count===0?(h(),C(`span`,Cl,``)):(h(),C(`span`,wl,`n/a`))]),S(`td`,Tl,[i.value&&D(e.name)&&e.row_count>0?(h(),C(`button`,{key:0,onClick:t=>A(e.name,e.row_count),disabled:c.value[e.name],class:`px-2.5 py-1 bg-red-500/10 dark:bg-red-400/10 hover:bg-red-500/20 dark:hover:bg-red-400/20 text-red-700 dark:text-red-400 rounded border border-red-500/30 dark:border-red-400/20 transition-colors text-xs disabled:opacity-50`},[c.value[e.name]?(h(),C(`span`,Dl,[_(I,{size:`xs`,color:`current`,class:`inline-block`}),n[13]||=b(` Purging… `,-1)])):(h(),C(`span`,Ol,`Empty`))],8,El)):D(e.name)?g(``,!0):(h(),C(`span`,kl,``))])]))),128))])])])])):g(``,!0)]),(h(),u(p,{to:`body`},[d.value?(h(),C(`div`,{key:0,class:`modal-backdrop-heavy`,onClick:n[3]||=z(e=>!d.value.executing&&(d.value=null),[`self`])},[S(`div`,{class:`modal-card max-w-lg`,onClick:n[2]||=z(()=>{},[`stop`])},[S(`div`,Al,[n[20]||=S(`div`,{class:`flex-shrink-0 w-10 h-10 rounded-full bg-red-500/15 flex items-center justify-center`},[S(`svg`,{class:`w-5 h-5 text-red-500 dark:text-red-400`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 16.5c-.77.833.192 2.5 1.732 2.5z`})])],-1),S(`div`,jl,[S(`h3`,Ml,t(d.value.table===`all`?`Purge All Tables`:`Purge "${d.value.table}"`),1),S(`p`,Nl,[d.value.table===`all`?(h(),C(x,{key:0},[n[15]||=b(` This will permanently delete `,-1),n[16]||=S(`strong`,{class:`text-content-primary dark:text-content-primary`},`all data`,-1),b(` from every data table (`+t(E.value.toLocaleString())+` rows total). This cannot be undone. `,1)],64)):(h(),C(x,{key:1},[n[17]||=b(` This will permanently delete `,-1),S(`strong`,Pl,t(d.value.rowCount.toLocaleString())+` rows`,1),n[18]||=b(` from `,-1),S(`strong`,Fl,t(d.value.table),1),n[19]||=b(`. This cannot be undone. `,-1)],64))])])]),S(`div`,Il,[S(`button`,{onClick:n[1]||=e=>d.value=null,disabled:d.value.executing,class:`flex-1 px-4 py-3 bg-background-mute dark:bg-white/5 hover:bg-stroke-subtle dark:hover:bg-white/10 border border-stroke-subtle dark:border-stroke/20 text-content-primary dark:text-content-primary rounded-lg transition-colors`},` Cancel `,8,Ll),S(`button`,{onClick:j,disabled:d.value.executing,class:`flex-1 px-4 py-3 bg-red-500/20 hover:bg-red-500/30 border border-red-500/50 text-red-600 dark:text-red-400 rounded-lg transition-colors font-medium disabled:opacity-50`},t(d.value.executing?`Purging…`:`Yes, Delete Data`),9,Rl)])])])):g(``,!0)])),S(`div`,zl,[n[23]||=S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-4`},` Maintenance `,-1),S(`div`,Bl,[S(`button`,{onClick:n[4]||=e=>A(`all`,E.value),disabled:!s.value||E.value===0||!i.value,class:`px-4 py-2 bg-red-500/20 dark:bg-red-400/20 hover:bg-red-500/30 dark:hover:bg-red-400/30 text-red-900 dark:text-red-200 rounded-lg border border-red-500/50 dark:border-red-400/40 transition-colors text-sm disabled:opacity-50 disabled:cursor-not-allowed`},[...n[21]||=[S(`span`,{class:`flex items-center gap-2`},[S(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16`})]),b(` Purge All Data `)],-1)]],8,Vl),S(`button`,{onClick:N,disabled:w.value||!s.value,class:`cfg-btn-primary`},[S(`span`,Ul,[n[22]||=S(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15`})],-1),b(` `+t(w.value?`Compacting…`:`Compact Database`),1)])],8,Hl)]),T.value?(h(),C(`p`,Wl,t(T.value),1)):g(``,!0),f.value?(h(),C(`p`,Gl,t(f.value),1)):g(``,!0)])]))}}),ql={class:`space-y-12`},Jl={class:`cfg-section`},Yl={class:`flex items-start justify-between mb-4`},Xl={class:`flex items-center gap-2`},Zl=[`disabled`],Ql={key:0,class:`flex items-center gap-1.5`},$l={key:1},eu=[`disabled`],tu={key:0,class:`flex items-center gap-1.5`},nu={key:1},ru={key:0,class:`mb-4 p-3 rounded-lg bg-red-500/10 border border-red-500/30 text-red-600 dark:text-red-400 text-sm`},iu={key:1,class:`mb-4`},au={class:`bg-background-mute dark:bg-background/30 rounded-lg p-3 border border-stroke-subtle dark:border-stroke/10 inline-block`},ou={class:`text-lg font-semibold text-content-primary dark:text-content-primary font-mono`},su={key:2,class:`p-4 rounded-lg bg-cyan-500/10 dark:bg-primary/10 border border-cyan-400/30 dark:border-primary/30`},cu={key:3},lu=[`innerHTML`],uu={class:`font-semibold text-sm`},du={class:`text-sm mt-0.5 opacity-80`},fu={class:`grid grid-cols-2 sm:grid-cols-3 gap-3 mb-6`},pu={key:0,class:`bg-background-mute dark:bg-background/30 rounded-lg p-3 border border-stroke-subtle dark:border-stroke/10`},mu={class:`text-lg font-semibold text-content-primary dark:text-content-primary font-mono`},hu={key:1,class:`bg-background-mute dark:bg-background/30 rounded-lg p-3 border border-stroke-subtle dark:border-stroke/10`},gu={class:`text-lg font-semibold text-content-primary dark:text-content-primary font-mono`},_u={key:2,class:`bg-background-mute dark:bg-background/30 rounded-lg p-3 border border-stroke-subtle dark:border-stroke/10`},vu={class:`text-lg font-semibold text-content-primary dark:text-content-primary font-mono`},yu={key:0,class:`mb-6`},bu={class:`space-y-2`},xu={class:`flex items-start justify-between gap-3`},Su={class:`flex items-center gap-2 min-w-0`},Cu={class:`shrink-0 text-xs font-medium text-content-muted w-5 text-right`},wu={class:`text-right shrink-0`},Tu={class:`text-xs text-content-muted`},Eu={class:`mt-1.5 ml-7`},Du={class:`text-xs font-mono text-content-secondary dark:text-content-muted break-all`},Ou={key:0,class:`text-xs text-content-muted mt-0.5`},ku={key:1,class:`mb-6 p-4 rounded-lg bg-green-500/10 border border-green-500/30 text-sm flex items-center gap-3`},Au={key:2},ju={key:0,class:`overflow-x-auto rounded-lg border border-stroke-subtle dark:border-stroke/10`},Mu={class:`w-full text-sm`},Nu={class:`px-3 py-2 text-content-muted font-mono text-xs`},Pu={class:`px-3 py-2 text-content-primary dark:text-content-primary font-mono text-xs break-all`},Fu={class:`px-3 py-2 text-right font-mono text-xs text-content-secondary dark:text-content-muted whitespace-nowrap`},Iu={class:`px-3 py-2 text-right font-mono text-xs text-content-secondary dark:text-content-muted`},Lu={key:4,class:`py-8 text-center text-content-muted text-sm`},Ru=F(f({__name:`MemoryDebug`,setup(n){let i=l(!1),a=l(!1),o=l(``),s=l(null),c=l(!1),u=l(null),f=l(!1),p=y(()=>s.value&&(s.value.current_top_20||s.value.growth_since_baseline));async function v(){i.value=!0,o.value=``;try{let e=await M.get(`memory_debug`);e.success&&e.data?(c.value=!!e.data.tracing,u.value=e.data.rss_mb??null,(e.data.current_top_20||e.data.growth_since_baseline)&&(s.value=e.data)):o.value=e.error||`Failed to fetch memory status`}catch(e){o.value=e instanceof Error?e.message:`Failed to fetch memory status`}finally{i.value=!1}}async function w(){a.value=!0,o.value=``;let e=c.value?`stop`:`start`;try{let t=await M.post(`memory_debug`,{action:e});t.success&&t.data?(c.value=!!t.data.tracing,e===`stop`&&(s.value=null,u.value=null)):o.value=t.error||`Failed to ${e} tracing`}catch(t){o.value=t instanceof Error?t.message:`Failed to ${e} tracing`}finally{a.value=!1,c.value&&await v()}}function E(e){return e.size_diff_kb>=100?`critical`:e.size_diff_kb>=10?`warning`:e.size_diff_kb>=1?`low`:`ok`}function D(e){let t=E(e);return t===`critical`?`Investigate`:t===`warning`?`Watch`:t===`low`?`Minor`:`Normal`}function O(e){let t=E(e);return t===`critical`?`bg-red-500/20 text-red-700 dark:text-red-400 border border-red-500/30`:t===`warning`?`bg-amber-500/20 text-amber-700 dark:text-amber-400 border border-amber-500/30`:t===`low`?`bg-blue-500/15 text-blue-600 dark:text-blue-400 border border-blue-500/20`:`bg-green-500/15 text-green-700 dark:text-green-400 border border-green-500/20`}function k(e){let t=E(e);return t===`critical`?`border-red-500/40 dark:border-red-500/30 bg-red-500/5 dark:bg-red-500/5`:t===`warning`?`border-amber-500/40 dark:border-amber-500/30 bg-amber-500/5 dark:bg-amber-500/5`:t===`low`?`border-stroke-subtle dark:border-stroke/10 bg-background-mute/50 dark:bg-background/20`:`border-stroke-subtle/50 dark:border-stroke/5 bg-background-mute/30 dark:bg-background/10 opacity-60`}function A(e){let t=E(e);return t===`critical`?`text-red-600 dark:text-red-400`:t===`warning`?`text-amber-600 dark:text-amber-400`:t===`low`?`text-blue-600 dark:text-blue-400`:`text-green-600 dark:text-green-500`}function j(e){return e>=1024?`${(e/1024).toFixed(1)} MB`:e>=10?`${Math.round(e)} KB`:`${e.toFixed(1)} KB`}function N(e){return e.replace(/.*\/site-packages\//,``).replace(/.*\/lib\/python[^/]*\//,``).replace(/.*\/repeater\//,`repeater/`)}let P=y(()=>s.value?.growth_since_baseline?s.value.growth_since_baseline.reduce((e,t)=>e+t.size_diff_kb,0):0),F=y(()=>P.value>=500?`critical`:P.value>=50?`warning`:P.value>=5?`low`:`ok`),L=y(()=>{let e=F.value;return e===`critical`?`border-red-500/40 dark:border-red-500/30 bg-red-500/10 dark:bg-red-500/10 text-red-800 dark:text-red-300`:e===`warning`?`border-amber-500/40 dark:border-amber-500/30 bg-amber-500/10 dark:bg-amber-500/10 text-amber-800 dark:text-amber-300`:e===`low`?`border-blue-500/30 bg-blue-500/10 dark:bg-blue-500/10 text-blue-800 dark:text-blue-300`:`border-green-500/30 bg-green-500/10 dark:bg-green-500/10 text-green-800 dark:text-green-300`}),R=y(()=>{let e=F.value;return e===`critical`?`<svg class="w-5 h-5 text-red-600 dark:text-red-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.34 16.5c-.77.833.192 2.5 1.732 2.5z"/></svg>`:e===`warning`?`<svg class="w-5 h-5 text-amber-600 dark:text-amber-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.34 16.5c-.77.833.192 2.5 1.732 2.5z"/></svg>`:e===`low`?`<svg class="w-5 h-5 text-blue-600 dark:text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>`:`<svg class="w-5 h-5 text-green-600 dark:text-green-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>`}),z=y(()=>{let e=F.value;return e===`critical`?`Significant memory growth detected`:e===`warning`?`Some memory growth detected`:e===`low`?`Minor memory growth — likely normal`:`Memory looks healthy`}),B=y(()=>{let e=j(P.value),t=F.value;return t===`critical`?`Total growth: ${e}. Red items below need attention.`:t===`warning`?`Total growth: ${e}. Orange items below may need attention over time.`:t===`low`?`Total growth: ${e}. Nothing to worry about right now.`:`No significant growth since tracing started.`});return r(v),(n,r)=>(h(),C(`div`,ql,[r[15]||=S(`div`,{class:`cfg-page-heading flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},[S(`div`,null,[S(`h3`,{class:`text-base sm:text-lg font-semibold text-content-primary dark:text-content-primary mb-1 sm:mb-2`},`Memory`),S(`p`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Diagnose memory usage and trace allocations`)])],-1),S(`div`,Jl,[S(`div`,Yl,[r[2]||=S(`div`,null,[S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-1`},` Memory Diagnostics `),S(`p`,{class:`text-sm text-content-secondary dark:text-content-muted`},` Trace memory allocations to find leaks. Tracing adds overhead — only enable when needed. `)],-1),S(`div`,Xl,[c.value&&p.value?(h(),C(`button`,{key:0,onClick:v,disabled:i.value,class:`cfg-btn-secondary`},[i.value?(h(),C(`span`,Ql,[_(I,{size:`xs`,color:`current`,class:`inline-block`}),r[1]||=b(` Checking… `,-1)])):(h(),C(`span`,$l,`Check Again`))],8,Zl)):g(``,!0),S(`button`,{onClick:w,disabled:a.value,class:T([`px-3 py-1.5 rounded-lg border text-sm transition-colors disabled:opacity-50`,c.value?`bg-red-500/20 hover:bg-red-500/30 text-red-700 dark:text-red-400 border-red-500/50`:`bg-green-500/20 hover:bg-green-500/30 text-green-700 dark:text-green-400 border-green-500/50`])},[a.value?(h(),C(`span`,tu,[_(I,{size:`xs`,color:`current`,class:`inline-block`}),b(` `+t(c.value?`Stopping…`:`Starting…`),1)])):(h(),C(`span`,nu,t(c.value?`Stop Tracing`:`Start Tracing`),1))],10,eu)])]),o.value?(h(),C(`div`,ru,t(o.value),1)):g(``,!0),!c.value&&u.value!==null&&!i.value?(h(),C(`div`,iu,[S(`div`,au,[r[3]||=S(`p`,{class:`text-xs text-content-muted mb-1`},`Current Memory (RSS)`,-1),S(`p`,ou,t(u.value)+` MB`,1)])])):g(``,!0),c.value&&!p.value&&!i.value?(h(),C(`div`,su,[...r[4]||=[d(`<div class="flex items-center gap-2 text-cyan-700 dark:text-primary" data-v-00e540ed><svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" data-v-00e540ed><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" data-v-00e540ed></path></svg><span class="font-medium" data-v-00e540ed>Tracing active</span></div><p class="mt-2 text-sm text-cyan-600 dark:text-primary/80" data-v-00e540ed> Memory tracing is running. Let the repeater run for a few minutes, then click <strong data-v-00e540ed>Check Again</strong> to see which parts of the code are using more memory. </p>`,2)]])):g(``,!0),s.value&&p.value?(h(),C(`div`,cu,[S(`div`,{class:T([`mb-5 p-4 rounded-lg border flex items-start gap-3`,L.value])},[S(`div`,{class:`mt-0.5`,innerHTML:R.value},null,8,lu),S(`div`,null,[S(`p`,uu,t(z.value),1),S(`p`,du,t(B.value),1)])],2),S(`div`,fu,[s.value.rss_mb===void 0?g(``,!0):(h(),C(`div`,pu,[r[5]||=S(`p`,{class:`text-xs text-content-muted mb-1`},`Total Memory Used`,-1),S(`p`,mu,t(s.value.rss_mb)+` MB`,1)])),s.value.traced_current_mb===void 0?g(``,!0):(h(),C(`div`,hu,[r[6]||=S(`p`,{class:`text-xs text-content-muted mb-1`},`Tracked Now`,-1),S(`p`,gu,t(s.value.traced_current_mb)+` MB`,1)])),s.value.traced_peak_mb===void 0?g(``,!0):(h(),C(`div`,_u,[r[7]||=S(`p`,{class:`text-xs text-content-muted mb-1`},`Peak Tracked`,-1),S(`p`,vu,t(s.value.traced_peak_mb)+` MB`,1)]))]),s.value.growth_since_baseline&&s.value.growth_since_baseline.length>0?(h(),C(`div`,yu,[r[8]||=S(`h4`,{class:`text-sm font-semibold text-content-primary dark:text-content-primary mb-1`},`Memory Growth Breakdown`,-1),r[9]||=S(`p`,{class:`text-xs text-content-muted mb-3`},` Items at the top with red/orange tags are the most likely cause of memory issues. Green items are normal and can be ignored. `,-1),S(`div`,bu,[(h(!0),C(x,null,m(s.value.growth_since_baseline,(e,n)=>(h(),C(`div`,{key:n,class:T([`rounded-lg border p-3 transition-colors`,k(e)])},[S(`div`,xu,[S(`div`,Su,[S(`span`,Cu,t(n+1),1),S(`span`,{class:T([`shrink-0 inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-semibold`,O(e)])},t(D(e)),3)]),S(`div`,wu,[S(`span`,{class:T([`font-mono text-sm font-semibold`,A(e)])},`+`+t(j(e.size_diff_kb)),3),S(`p`,Tu,t(j(e.current_size_kb))+` total`,1)])]),S(`div`,Eu,[S(`p`,Du,t(N(e.file)),1),e.count_diff===0?g(``,!0):(h(),C(`p`,Ou,t(e.count_diff>0?`+`:``)+t(e.count_diff)+` new allocation`+t(Math.abs(e.count_diff)===1?``:`s`),1))])],2))),128))])])):s.value.growth_since_baseline&&s.value.growth_since_baseline.length===0?(h(),C(`div`,ku,[...r[10]||=[S(`svg`,{class:`w-5 h-5 text-green-600 dark:text-green-400 shrink-0`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z`})],-1),S(`span`,{class:`text-green-700 dark:text-green-400`},`No memory growth detected. Everything looks healthy.`,-1)]])):g(``,!0),s.value.current_top_20&&s.value.current_top_20.length>0?(h(),C(`div`,Au,[S(`button`,{onClick:r[0]||=e=>f.value=!f.value,class:`flex items-center gap-2 text-sm font-semibold text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-primary transition-colors mb-3`},[(h(),C(`svg`,{class:T([`w-4 h-4 transition-transform`,{"rotate-90":f.value}]),fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[...r[11]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M9 5l7 7-7 7`},null,-1)]],2)),r[12]||=b(` Advanced: Current Top Allocations `,-1)]),_(V,{name:`expand`},{default:e(()=>[f.value?(h(),C(`div`,ju,[S(`table`,Mu,[r[13]||=S(`thead`,null,[S(`tr`,{class:`bg-background-mute dark:bg-background/30 text-left`},[S(`th`,{class:`px-3 py-2 text-xs font-medium text-content-muted`},`#`),S(`th`,{class:`px-3 py-2 text-xs font-medium text-content-muted`},`Location`),S(`th`,{class:`px-3 py-2 text-xs font-medium text-content-muted text-right`},`Size`),S(`th`,{class:`px-3 py-2 text-xs font-medium text-content-muted text-right`},`Count`)])],-1),S(`tbody`,null,[(h(!0),C(x,null,m(s.value.current_top_20,(e,n)=>(h(),C(`tr`,{key:n,class:`border-t border-stroke-subtle/50 dark:border-stroke/5 hover:bg-background-mute/50 dark:hover:bg-background/20 transition-colors`},[S(`td`,Nu,t(n+1),1),S(`td`,Pu,t(N(e.file)),1),S(`td`,Fu,t(j(e.size_kb)),1),S(`td`,Iu,t(e.count),1)]))),128))])])])):g(``,!0)]),_:1})])):g(``,!0)])):g(``,!0),!i.value&&!a.value&&!c.value&&!p.value&&!o.value&&u.value===null?(h(),C(`div`,Lu,[...r[14]||=[b(` Click `,-1),S(`strong`,null,`Start Tracing`,-1),b(` to enable memory diagnostics. `,-1),S(`br`,null,null,-1),S(`span`,{class:`text-xs`},`Tracing uses extra memory — remember to stop it when done.`,-1)]])):g(``,!0)])]))}}),[[`__scopeId`,`data-v-00e540ed`]]),zu={class:`p-3 sm:p-6 space-y-4 sm:space-y-6`},Bu={class:`flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},Vu={class:`glass-card rounded-[15px] p-3 sm:p-6 mt-4 sm:mt-6`},Hu={class:`relative -mx-3 sm:mx-0 mb-4 sm:mb-6`},Uu={key:0,class:`absolute left-0 top-0 bottom-[1px] w-12 z-10 flex items-center`},Wu={key:0,class:`absolute right-0 top-0 bottom-[1px] w-12 z-10 flex items-center justify-end`},Gu=[`onClick`],Ku={class:`flex items-center gap-1 sm:gap-2`},qu={key:0,class:`w-3.5 h-3.5 sm:w-4 sm:h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},Ju={key:1,class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},Yu={key:2,class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},Xu={key:3,class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},Zu={key:4,class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},Qu={key:5,class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},$u={key:6,class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},ed={key:7,class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},td={key:8,class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},nd={key:9,class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},rd={key:10,class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},id={key:11,class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},ad={class:`min-h-[400px]`},od={key:0,class:`flex items-center justify-center py-12`},sd={class:`text-center`},cd={key:1,class:`flex items-center justify-center py-12`},ld={class:`text-center`},ud={class:`text-content-secondary dark:text-content-muted text-sm mb-4`},dd={key:2},fd=F(f({name:`ConfigurationView`,__name:`Configuration`,setup(n){let i=N(),d=P(),f=l(ie(`configuration_activeTab`,`radio`)),p=l(!1),y=l(null),w=l(!1),E=l(!1),D=l(null),O=l(null),k=l(null),A=l(null),j=l(null),M=l(null),F=l(null),L={radio:D,repeater:O,advert:k,duty:A,delays:j,transport:M,observer:F};function R(){let e=L[f.value]?.value;if(!e)return!1;let t=e.isEditing;return typeof t==`boolean`?t:t.value}function z(e){L[f.value]?.value?.requestLeave(e)??e()}function B(){if(!y.value)return;let e=y.value;E.value=e.scrollLeft>4,w.value=e.scrollLeft<e.scrollWidth-e.clientWidth-4}function U(e){y.value&&y.value.scrollBy({left:e===`right`?150:-150,behavior:`smooth`})}o(f,e=>re(`configuration_activeTab`,e));let ee=[{id:`radio`,label:`Radio Settings`,icon:`radio`},{id:`repeater`,label:`Repeater Settings`,icon:`repeater`},{id:`advert`,label:`Advert Limits`,icon:`advert`},{id:`duty`,label:`Duty Cycle`,icon:`duty`},{id:`delays`,label:`TX Delays`,icon:`delays`},{id:`transport`,label:`Region Configuration`,icon:`keys`},{id:`api-tokens`,label:`API Tokens`,icon:`tokens`},{id:`web`,label:`Web Options`,icon:`web`},{id:`observer`,label:`Observer`,icon:`observer`},{id:`backup`,label:`Backup`,icon:`backup`},{id:`database`,label:`Database`,icon:`database`},{id:`memory`,label:`Memory`,icon:`memory`}];r(async()=>{if(i.stats)p.value=!0;else try{await d.ensure(`stats`)}catch(e){console.error(`Failed to load configuration data:`,e)}finally{p.value=!0}s(()=>B())});function W(e){if(e!==f.value&&R()){z(()=>{f.value=e});return}f.value=e}return(n,r)=>{let o=a(`router-link`);return h(),C(`div`,zu,[S(`div`,Bu,[r[4]||=S(`div`,null,[S(`h1`,{class:`text-xl sm:text-2xl font-bold text-content-primary dark:text-content-primary`},` Configuration `),S(`p`,{class:`text-content-secondary dark:text-content-muted mt-1 sm:mt-2 text-sm sm:text-base`},` System configuration and settings `)],-1),p.value&&!(v(i).stats?.config?.radio)?.cad?.peak_threshold?(h(),u(o,{key:0,to:`/cad-calibration`,class:`flex-shrink-0 flex items-center gap-4 px-5 py-3 min-w-[280px] rounded-xl border border-primary/30 bg-primary/10 text-primary hover:bg-primary/20 transition-colors`},{default:e(()=>[...r[3]||=[S(`svg`,{class:`w-5 h-5 flex-shrink-0`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M13 10V3L4 14h7v7l9-11h-7z`})],-1),S(`div`,null,[S(`div`,{class:`text-sm font-semibold`},`CAD Calibration Available`),S(`div`,{class:`text-xs text-primary/70`},`Optimise CAD settings →`)],-1)]]),_:1})):g(``,!0)]),S(`div`,Vu,[S(`div`,Hu,[_(V,{name:`tab-fade`},{default:e(()=>[E.value?(h(),C(`div`,Uu,[r[6]||=S(`div`,{class:`tab-fade-left absolute inset-0 pointer-events-none`},null,-1),S(`button`,{onClick:r[0]||=e=>U(`left`),class:`relative z-10 ml-1.5 w-6 h-6 flex items-center justify-center rounded-full bg-surface shadow-md border border-stroke-subtle dark:border-stroke/30 text-content-muted`},[...r[5]||=[S(`svg`,{class:`w-3 h-3`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2.5`,d:`M15 19l-7-7 7-7`})],-1)]])])):g(``,!0)]),_:1}),_(V,{name:`tab-fade`},{default:e(()=>[w.value?(h(),C(`div`,Wu,[r[8]||=S(`div`,{class:`tab-fade-right absolute inset-0 pointer-events-none`},null,-1),S(`button`,{onClick:r[1]||=e=>U(`right`),class:`relative z-10 mr-1.5 w-6 h-6 flex items-center justify-center rounded-full bg-surface shadow-md border border-stroke-subtle dark:border-stroke/30 text-content-muted`},[...r[7]||=[S(`svg`,{class:`w-3 h-3`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2.5`,d:`M9 5l7 7-7 7`})],-1)]])])):g(``,!0)]),_:1}),S(`div`,{ref_key:`tabsContainer`,ref:y,onScroll:B,class:`flex overflow-x-auto border-b border-stroke-subtle dark:border-stroke px-3 sm:px-0 scrollbar-hide`},[(h(),C(x,null,m(ee,e=>S(`button`,{key:e.id,onClick:t=>W(e.id),class:T([`px-3 sm:px-4 py-2 text-xs sm:text-sm font-medium transition-colors duration-200 border-b-2 mr-3 sm:mr-6 whitespace-nowrap flex-shrink-0`,f.value===e.id?`text-primary border-primary`:`text-content-secondary dark:text-content-muted border-transparent hover:text-content-primary dark:hover:text-content-primary hover:border-stroke-subtle dark:hover:border-stroke/30`])},[S(`div`,Ku,[e.icon===`radio`?(h(),C(`svg`,qu,[...r[9]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M8.111 16.404a5.5 5.5 0 017.778 0M12 20h.01m-7.08-7.071c3.904-3.905 10.236-3.905 14.141 0M1.394 9.822c5.716-5.716 14.976-5.716 20.692 0`},null,-1)]])):e.icon===`repeater`?(h(),C(`svg`,Ju,[...r[10]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M5 12h14M5 12l4-4m-4 4l4 4`},null,-1)]])):e.icon===`advert`?(h(),C(`svg`,Yu,[...r[11]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z`},null,-1)]])):e.icon===`duty`?(h(),C(`svg`,Xu,[...r[12]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z`},null,-1)]])):e.icon===`delays`?(h(),C(`svg`,Zu,[...r[13]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z`},null,-1)]])):e.icon===`keys`?(h(),C(`svg`,Qu,[...r[14]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z`},null,-1)]])):e.icon===`tokens`?(h(),C(`svg`,$u,[...r[15]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z`},null,-1)]])):e.icon===`web`?(h(),C(`svg`,ed,[...r[16]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9`},null,-1)]])):e.icon===`observer`?(h(),C(`svg`,td,[...r[17]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M3.055 11H5a2 2 0 012 2v1a2 2 0 002 2 2 2 0 012 2v2.945M8 3.935V5.5A2.5 2.5 0 0010.5 8h.5a2 2 0 012 2 2 2 0 104 0 2 2 0 012-2h1.064M15 20.488V18a2 2 0 012-2h3.064M21 12a9 9 0 11-18 0 9 9 0 0118 0z`},null,-1)]])):e.icon===`backup`?(h(),C(`svg`,nd,[...r[18]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M8 7H5a2 2 0 00-2 2v9a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-3m-1 4l-3 3m0 0l-3-3m3 3V4`},null,-1)]])):e.icon===`database`?(h(),C(`svg`,rd,[...r[19]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4m0 5c0 2.21-3.582 4-8 4s-8-1.79-8-4`},null,-1)]])):e.icon===`memory`?(h(),C(`svg`,id,[...r[20]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M9 3v2m6-2v2M9 19v2m6-2v2M5 9H3m2 6H3m18-6h-2m2 6h-2M7 19h10a2 2 0 002-2V7a2 2 0 00-2-2H7a2 2 0 00-2 2v10a2 2 0 002 2zM9 9h6v6H9V9z`},null,-1)]])):g(``,!0),b(` `+t(e.label),1)])],10,Gu)),64))],544)]),S(`div`,ad,[!p.value&&v(i).isLoading?(h(),C(`div`,od,[S(`div`,sd,[_(I,{class:`mx-auto mb-4`}),r[21]||=S(`div`,{class:`text-content-secondary dark:text-content-muted`},` Loading configuration... `,-1)])])):p.value&&!v(i).stats?(h(),C(`div`,cd,[S(`div`,ld,[r[22]||=S(`div`,{class:`text-accent-red mb-2`},`Failed to load configuration`,-1),S(`div`,ud,t(v(i).error),1),S(`button`,{onClick:r[2]||=e=>v(i).fetchStats(),class:`btn-primary`},` Retry `)])])):(h(),C(`div`,dd,[c(S(`div`,null,[_(Ve,{ref_key:`radioRef`,ref:D,key:`radio-settings`},null,512)],512),[[H,f.value===`radio`]]),c(S(`div`,null,[_(Vt,{ref_key:`repeaterRef`,ref:O,key:`repeater-settings`},null,512)],512),[[H,f.value===`repeater`]]),c(S(`div`,null,[_(wo,{ref_key:`advertRef`,ref:k,key:`advert-settings`},null,512)],512),[[H,f.value===`advert`]]),c(S(`div`,null,[_(tn,{ref_key:`dutyRef`,ref:A,key:`duty-cycle`},null,512)],512),[[H,f.value===`duty`]]),c(S(`div`,null,[_(hn,{ref_key:`delaysRef`,ref:j,key:`transmission-delays`},null,512)],512),[[H,f.value===`delays`]]),c(S(`div`,null,[_(di,{ref_key:`transportRef`,ref:M,key:`transport-keys`},null,512)],512),[[H,f.value===`transport`]]),c(S(`div`,null,[_(Bi,{key:`api-tokens`})],512),[[H,f.value===`api-tokens`]]),c(S(`div`,null,[_(da,{key:`web-settings`})],512),[[H,f.value===`web`]]),c(S(`div`,null,[_(zs,{ref_key:`letsMeshRef`,ref:F,key:`letsmesh-settings`},null,512)],512),[[H,f.value===`observer`]]),c(S(`div`,null,[_(Gc,{key:`backup-restore`})],512),[[H,f.value===`backup`]]),c(S(`div`,null,[_(Kl,{key:`database-management`})],512),[[H,f.value===`database`]]),c(S(`div`,null,[_(Ru,{key:`memory-debug`})],512),[[H,f.value===`memory`]])]))])])])}}}),[[`__scopeId`,`data-v-d04d8825`]]);export{fd as default};