mirror of
https://github.com/pyMC-dev/pyMC_Repeater.git
synced 2026-06-26 21:11:34 +02:00
2 lines
272 KiB
JavaScript
2 lines
272 KiB
JavaScript
import{C as e,D as t,M as n,N as r,P as i,T as a,U as o,V as s,X as c,_t as l,c as u,f as d,h as f,ht as p,i as m,j as h,k as g,l as _,m as v,o as y,p as b,r as x,s as S,u as C,w,x as T,y as E}from"./runtime-core.esm-bundler-CINEgm0a.js";import{a as D,c as O,i as k,l as A,o as j,r as M,t as N}from"./runtime-dom.esm-bundler-B3VeUO8l.js";import{g as P,h as F,m as I,p as L,t as R,v as z,y as B}from"./api-DSaJA91r.js";import{t as ee}from"./system-BwYDm56e.js";import{t as V}from"./dataService-5Ok9aIVh.js";import{n as H,t as U}from"./TxPowerNoticeModal-DJj923Jw.js";import{t as W}from"./Spinner-CMJUE3iy.js";import{c as G,d as K,r as te,s as q}from"./index-Cijj_ZXo.js";import{t as ne}from"./ConfirmDialog-Dv9g-D0s.js";import{t as re}from"./LocationPicker-DihBA-Pb.js";import{n as ie,t as J}from"./CopyLabel-7zw0wWsl.js";import{c as Y,d as X,n as Z,t as Q}from"./formatters-CHyWlnnq.js";var ae={key:0,class:`fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm`},oe={class:`modal-card max-w-md`},se={class:`flex items-start gap-3 mb-4`},$={class:`mt-1 text-sm text-content-secondary dark:text-content-muted`},ce={class:`modal-actions`},le=[`disabled`],ue=[`disabled`],de=[`disabled`],fe=f({__name:`UnsavedChangesModal`,props:{show:{type:Boolean},isSaving:{type:Boolean},label:{}},emits:[`discard`,`save`,`cancel`],setup(e){return(t,n)=>(a(),u(m,{to:`body`},[v(N,{"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:r(()=>[e.show?(a(),C(`div`,ae,[S(`div`,oe,[S(`div`,se,[n[4]||=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,[n[3]||=S(`h3`,{class:`text-base font-semibold text-content-primary dark:text-content-primary`},` Unsaved Changes `,-1),S(`p`,$,l(e.label?e.label:`Settings`)+` have not been saved. What would you like to do? `,1)])]),S(`div`,ce,[S(`button`,{onClick:n[0]||=e=>t.$emit(`cancel`),disabled:e.isSaving,class:`modal-btn-cancel`},` Keep Editing `,8,le),S(`button`,{onClick:n[1]||=e=>t.$emit(`discard`),disabled:e.isSaving,class:`modal-btn-danger`},` Discard `,8,ue),S(`button`,{onClick:n[2]||=e=>t.$emit(`save`),disabled:e.isSaving,class:`modal-btn-primary`},l(e.isSaving?`Saving…`:`Save Settings`),9,de)])])])):_(``,!0)]),_:1})]))}});function pe(e,t,n,r){let i=o(!1),a=o(null),s=o(null);L((t,n,r)=>{e.value?(i.value=!0,a.value=()=>r(),s.value=()=>r(!1)):r()});function c(t){e.value?(i.value=!0,a.value=t,s.value=null):t()}function l(){n(),i.value=!1,s.value=null,a.value&&=(a.value(),null)}async function u(){await r()&&(i.value=!1,s.value=null,a.value&&=(a.value(),null))}function d(){i.value=!1,s.value&&=(s.value(),null),a.value=null}return{showUnsavedModal:i,requestLeave:c,handleDiscard:l,handleSave:u,handleCancel:d}}var me={class:`space-y-12`},he={class:`cfg-page-heading flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},ge={class:`flex items-center gap-2 shrink-0`},_e=[`disabled`],ve=[`disabled`],ye={key:0,class:`bg-red-100 dark:bg-red-500/20 border border-red-500/50 rounded-lg p-3`},be={class:`text-red-600 dark:text-red-400 text-sm`},xe={class:`cfg-section space-y-3`},Se={class:`w-full max-w-3xl rounded-3xl border border-stroke-subtle dark:border-white/10 bg-white dark:bg-surface-elevated shadow-[0_20px_80px_color-mix(in_srgb,var(--color-shadow-strong)_35%,transparent)] overflow-hidden`},Ce={class:`flex items-start justify-between gap-3 p-5 border-b border-stroke-subtle dark:border-white/10`},we={class:`p-5`},Te={class:`space-y-2 max-h-[60vh] overflow-y-auto pr-1`},Ee=[`onClick`],De={class:`min-w-0`},Oe={class:`flex flex-wrap items-center gap-2`},ke={class:`text-content-primary dark:text-content-primary font-semibold text-sm truncate`},Ae={key:0,class:`inline-flex items-center rounded-full bg-primary/15 text-primary text-[10px] font-semibold px-2 py-0.5`},je={class:`text-content-secondary dark:text-content-muted text-xs mt-1 line-clamp-2`},Me={class:`flex flex-wrap justify-end gap-2 shrink-0 text-[11px] font-mono`},Ne={class:`rounded-full bg-background-mute dark:bg-black/20 px-2 py-1 text-content-secondary dark:text-content-muted`},Pe={class:`rounded-full bg-background-mute dark:bg-black/20 px-2 py-1 text-content-secondary dark:text-content-muted`},Fe={class:`rounded-full bg-background-mute dark:bg-black/20 px-2 py-1 text-content-secondary dark:text-content-muted`},Ie={class:`rounded-full bg-background-mute dark:bg-black/20 px-2 py-1 text-content-secondary dark:text-content-muted`},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={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},ze={key:1,class:`flex items-center gap-2`},Be={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`},Ve={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},He={key:1},Ue=[`value`],We={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`},Ge={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},Ke={key:1},qe=[`value`],Je={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`},Ye={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},Xe={key:1,class:`flex items-center gap-2`},Ze={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`},Qe={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},$e={key:1},et={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 gap-1`},tt={class:`text-content-primary dark:text-content-primary font-mono text-sm`},nt={class:`cfg-section space-y-3`},rt={class:`flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},it={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`},at={class:`text-content-primary dark:text-content-primary font-mono text-sm`},ot={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 gap-1`},st={class:`text-content-primary dark:text-content-primary font-mono text-sm`},ct=f({__name:`RadioSettings`,setup(e,{expose:n}){let s=P(),u=ee(),d=V(),f=H(),m=y(()=>u.stats?.config?.radio||{}),g=y(()=>u.stats?.config?.radio?.cad??{}),b=o(!1),w=o(!1),T=o(null),E=o(!1),O=o(``),k=o(!1),M=o(!1),F=o(!1),I=o(0),L=o(0),z=o(0),B=o(0),W=o(0),G=o(0),K=o(0),q=[{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`}];h(m,e=>{e&&!b.value&&(L.value=e.frequency?Number((e.frequency/1e6).toFixed(3)):0,z.value=e.spreading_factor??0,B.value=e.bandwidth?Number((e.bandwidth/1e3).toFixed(1)):0,W.value=e.tx_power??0,G.value=e.coding_rate??0,K.value=e.preamble_length??0)},{immediate:!0});let ne=y(()=>{let e=m.value.frequency;return e?(e/1e6).toFixed(3)+` MHz`:`Not set`}),re=y(()=>{let e=m.value.bandwidth;return e?(e/1e3).toFixed(1)+` kHz`:`Not set`}),ie=y(()=>{let e=m.value.tx_power;return e===void 0?`Not set`:e+` dBm`}),J=y(()=>{let e=m.value.coding_rate;return e?`4/`+e:`Not set`}),Y=y(()=>{let e=m.value.preamble_length;return e?e+` symbols`:`Not set`}),X=y(()=>m.value.spreading_factor??`Not set`),Z=async()=>{f.radioPresets.length===0&&await f.fetchRadioPresets(),b.value=!0,T.value=null,F.value=!1,I.value=W.value},Q=e=>{L.value=e.frequency?Number(Number(e.frequency).toFixed(3)):0,z.value=e.spreading_factor?Number(e.spreading_factor):0,B.value=e.bandwidth?Number(Number(e.bandwidth).toFixed(1)):0,G.value=e.coding_rate?Number(e.coding_rate):0},ae=e=>e.frequency?`${Number(e.frequency).toFixed(3)} MHz`:`Not set`,oe=e=>e.bandwidth?`${Number(e.bandwidth).toFixed(1)} kHz`:`Not set`,se=e=>e.spreading_factor||`Not set`,$=e=>e.coding_rate?`4/${e.coding_rate}`:`Not set`,ce=()=>{T.value=null;let e=f.radioPresets.find(e=>e.title===O.value);e&&Q(e)};h(O,e=>{!b.value||!e||ce()});let le=e=>{O.value=e;let t=f.radioPresets.find(t=>t.title===e);t&&(Q(t),k.value=!1)},ue=()=>{b.value=!1,T.value=null,O.value=``,k.value=!1,M.value=!1,F.value=!1;let e=m.value;L.value=e.frequency?Number((e.frequency/1e6).toFixed(3)):0,z.value=e.spreading_factor??0,B.value=e.bandwidth?Number((e.bandwidth/1e3).toFixed(1)):0,W.value=e.tx_power??0,G.value=e.coding_rate??0,K.value=e.preamble_length??0},de=async({silent:e=!1}={})=>{w.value=!0,T.value=null;try{if(W.value<-9||W.value>22)return T.value=`TX Power must be between -9 and +22 dBm for SX1262`,!1;let t={};L.value&&(t.frequency=L.value*1e6),z.value&&(t.spreading_factor=z.value),B.value&&(t.bandwidth=B.value*1e3),(W.value||W.value===0)&&(t.tx_power=W.value),G.value&&(t.coding_rate=G.value);let n=(await R.post(`/update_radio_config`,t)).data;if(n.message||n.persisted)return b.value=!1,F.value=!1,await u.fetchStats(),d.invalidate(`radioConfig`),e||(E.value=!0),!0;n.error?T.value=n.error:T.value=`Unknown response from server`}catch(e){console.error(`Failed to update radio settings:`,e),T.value=e.response?.data?.error||`Failed to update settings`}finally{w.value=!1}return!1},ct=y(()=>W.value!==I.value),lt=async({silent:e=!1}={})=>b.value&&ct.value&&!F.value?(M.value=!0,!1):de({silent:e}),ut=async()=>{F.value&&(M.value=!1,await de())},dt=()=>{M.value=!1,F.value=!1},{showUnsavedModal:ft,requestLeave:pt,handleDiscard:mt,handleSave:ht,handleCancel:gt}=pe(b,w,ue,()=>lt());return n({requestLeave:pt,isEditing:b}),(e,n)=>(a(),C(x,null,[v(te,{modelValue:E.value,"onUpdate:modelValue":n[0]||=e=>E.value=e,title:`Radio Settings Changes require a restart.`,message:`Restart Now?`},null,8,[`modelValue`]),v(fe,{show:c(ft),"is-saving":w.value,label:`Radio Settings`,onDiscard:c(mt),onSave:c(ht),onCancel:c(gt)},null,8,[`show`,`is-saving`,`onDiscard`,`onSave`,`onCancel`]),v(U,{show:M.value,confirmed:F.value,busy:w.value,"action-label":`I Understand, Save Changes`,"onUpdate:show":n[1]||=e=>e?M.value=!0:dt(),"onUpdate:confirmed":n[2]||=e=>F.value=e,onConfirm:ut},null,8,[`show`,`confirmed`,`busy`]),S(`div`,me,[S(`div`,he,[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`},`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`,ge,[b.value?(a(),C(x,{key:1},[S(`button`,{onClick:n[3]||=e=>k.value=!k.value,class:`cfg-btn-secondary`},` Prefill Preset `),S(`button`,{onClick:ue,disabled:w.value,class:`cfg-btn-secondary`},` Cancel `,8,_e),S(`button`,{onClick:n[4]||=e=>lt(),disabled:w.value,class:`cfg-btn-primary`},l(w.value?`Saving...`:`Save Changes`),9,ve)],64)):(a(),C(`button`,{key:0,onClick:Z,class:`cfg-btn-primary`},` Edit Settings `))])]),T.value?(a(),C(`div`,ye,[S(`p`,be,l(T.value),1)])):_(``,!0),S(`div`,xe,[v(N,{name:`fade`},{default:r(()=>[b.value&&k.value?(a(),C(`div`,{key:0,class:`fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/40 backdrop-blur-sm`,onClick:n[6]||=A(e=>k.value=!1,[`self`])},[S(`div`,Se,[S(`div`,Ce,[n[14]||=S(`div`,null,[S(`div`,{class:`text-content-primary dark:text-content-primary font-semibold text-base`},` Prefill from preset `),S(`div`,{class:`text-content-muted dark:text-content-muted text-xs mt-1`},` Pick a preset to load its radio values into the form. `)],-1),S(`button`,{type:`button`,class:`cfg-btn-secondary`,onClick:n[5]||=e=>k.value=!1},` Close `)]),S(`div`,we,[S(`div`,Te,[(a(!0),C(x,null,t(c(f).radioPresets,e=>(a(),C(`button`,{key:e.title,type:`button`,onClick:t=>le(e.title),class:p([`w-full text-left rounded-[18px] border px-4 py-3 transition-all duration-200 flex items-center justify-between gap-4`,O.value===e.title?`border-primary/60 bg-primary/10 shadow-sm shadow-primary/10`:`border-stroke-subtle dark:border-white/10 bg-white/60 dark:bg-white/5 hover:border-primary/30 hover:bg-stroke-subtle/60 dark:hover:bg-white/10`])},[S(`div`,De,[S(`div`,Oe,[S(`div`,ke,l(e.title),1),O.value===e.title?(a(),C(`span`,Ae,` Selected `)):_(``,!0)]),S(`div`,je,l(e.description),1)]),S(`div`,Me,[S(`span`,Ne,` Freq `+l(ae(e)),1),S(`span`,Pe,` SF `+l(se(e)),1),S(`span`,Fe,` BW `+l(oe(e)),1),S(`span`,Ie,` CR `+l($(e)),1)])],10,Ee))),128))])])])])):_(``,!0)]),_:1}),S(`div`,Le,[n[16]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Frequency`,-1),b.value?(a(),C(`div`,ze,[i(S(`input`,{"onUpdate:modelValue":n[7]||=e=>L.value=e,type:`number`,step:`0.001`,min:`100`,max:`1000`,class:`cfg-input w-32`},null,512),[[j,L.value,void 0,{number:!0}]]),n[15]||=S(`span`,{class:`text-content-muted dark:text-content-muted text-sm`},`MHz`,-1)])):(a(),C(`div`,Re,l(ne.value),1))]),S(`div`,Be,[n[17]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Spreading Factor`,-1),b.value?(a(),C(`div`,He,[i(S(`select`,{"onUpdate:modelValue":n[8]||=e=>z.value=e,class:`cfg-select`},[(a(),C(x,null,t([5,6,7,8,9,10,11,12],e=>S(`option`,{key:e,value:e},l(e),9,Ue)),64))],512),[[D,z.value,void 0,{number:!0}]])])):(a(),C(`div`,Ve,l(X.value),1))]),S(`div`,We,[n[18]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Bandwidth`,-1),b.value?(a(),C(`div`,Ke,[i(S(`select`,{"onUpdate:modelValue":n[9]||=e=>B.value=e,class:`cfg-select`},[(a(),C(x,null,t(q,e=>S(`option`,{key:e.value,value:e.value},l(e.label),9,qe)),64))],512),[[D,B.value,void 0,{number:!0}]])])):(a(),C(`div`,Ge,l(re.value),1))]),S(`div`,Je,[n[20]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`TX Power`,-1),b.value?(a(),C(`div`,Xe,[i(S(`input`,{"onUpdate:modelValue":n[10]||=e=>W.value=e,type:`number`,min:`-9`,max:`22`,class:`cfg-input w-20`},null,512),[[j,W.value,void 0,{number:!0}]]),n[19]||=S(`span`,{class:`text-content-muted dark:text-content-muted text-sm`},`dBm`,-1)])):(a(),C(`div`,Ye,l(ie.value),1))]),S(`div`,Ze,[n[22]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Coding Rate`,-1),b.value?(a(),C(`div`,$e,[i(S(`select`,{"onUpdate:modelValue":n[11]||=e=>G.value=e,class:`cfg-select`},[...n[21]||=[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),[[D,G.value,void 0,{number:!0}]])])):(a(),C(`div`,Qe,l(J.value),1))]),S(`div`,et,[n[23]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Preamble Length`,-1),S(`span`,tt,l(Y.value),1)])]),S(`div`,nt,[S(`div`,rt,[n[24]||=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[12]||=e=>c(s).push(`/cad-calibration`),class:`cfg-btn-secondary shrink-0`},` Run Calibration `)]),n[27]||=S(`div`,{class:`pt-2`},null,-1),S(`div`,it,[n[25]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Peak Threshold`,-1),S(`span`,at,l(g.value.peak_threshold??`Not calibrated`),1)]),S(`div`,ot,[n[26]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Min Threshold`,-1),S(`span`,st,l(g.value.min_threshold??`Not calibrated`),1)])])])],64))}}),lt={class:`space-y-12`},ut={class:`cfg-page-heading flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},dt={class:`flex items-center gap-2 shrink-0`},ft=[`disabled`],pt=[`disabled`],mt={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`},ht={class:`cfg-section space-y-3`},gt={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`},_t={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},vt={key:1,class:`w-full sm:w-80`},yt=[`value`],bt={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-2`},xt={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm break-all`},St={key:1,class:`w-full sm:w-80 space-y-2`},Ct={class:`flex gap-2`},wt=[`disabled`],Tt=[`value`],Et=[`value`],Dt=[`disabled`],Ot=[`value`],kt=[`value`],At=[`disabled`],jt={class:`flex items-center gap-2 text-xs text-content-secondary dark:text-content-muted`},Mt={key:2,class:`text-xs text-red-600 dark:text-red-400`},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-2`},Pt={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},Ft={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-2`},It={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm break-all`},Lt={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-2`},Rt={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},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-2`},Bt={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},Vt={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-2`},Ht={class:`w-full sm:w-96 space-y-2`},Ut={class:`flex gap-2`},Wt=[`value`],Gt=[`disabled`],Kt={key:0,class:`text-xs text-red-600 dark:text-red-400`},qt={class:`grid grid-cols-1 sm:grid-cols-2 gap-3 py-2 border-b border-stroke-subtle dark:border-stroke/10`},Jt={class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},Yt={key:1,class:`block text-content-primary dark:text-content-primary font-mono text-sm mt-1`},Xt={class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},Zt={key:1,class:`block text-content-primary dark:text-content-primary font-mono text-sm mt-1`},Qt={class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},$t={key:1,class:`block text-content-primary dark:text-content-primary font-mono text-sm mt-1`},en={class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},tn={key:1,class:`block text-content-primary dark:text-content-primary font-mono text-sm mt-1`},nn={class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},rn={key:1,class:`block text-content-primary dark:text-content-primary font-mono text-sm mt-1`},an={class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},on={key:1,class:`block text-content-primary dark:text-content-primary font-mono text-sm mt-1`},sn={class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},cn={key:1,class:`block text-content-primary dark:text-content-primary font-mono text-sm mt-1`},ln={class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},un={key:1,class:`block text-content-primary dark:text-content-primary font-mono text-sm mt-1`},dn={class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},fn={key:1,class:`block text-content-primary dark:text-content-primary font-mono text-sm mt-1`},pn={class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},mn={key:1,class:`block text-content-primary dark:text-content-primary font-mono text-sm mt-1`},hn={class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},gn={key:1,class:`block text-content-primary dark:text-content-primary font-mono text-sm mt-1`},_n={class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},vn={key:1,class:`block text-content-primary dark:text-content-primary font-mono text-sm mt-1`},yn={key:3,class:`grid grid-cols-1 sm:grid-cols-2 gap-3 text-sm`},bn={class:`rounded-lg border border-stroke-subtle dark:border-stroke/10 bg-background-mute dark:bg-white/5 p-3`},xn={class:`text-content-primary dark:text-content-primary font-mono`},Sn={class:`rounded-lg border border-stroke-subtle dark:border-stroke/10 bg-background-mute dark:bg-white/5 p-3`},Cn={class:`text-content-primary dark:text-content-primary font-mono`},wn={class:`rounded-lg border border-stroke-subtle dark:border-stroke/10 bg-background-mute dark:bg-white/5 p-3`},Tn={class:`text-content-primary dark:text-content-primary font-mono`},En={class:`rounded-lg border border-stroke-subtle dark:border-stroke/10 bg-background-mute dark:bg-white/5 p-3`},Dn={class:`text-content-primary dark:text-content-primary font-mono`},On={class:`rounded-lg border border-stroke-subtle dark:border-stroke/10 bg-background-mute dark:bg-white/5 p-3`},kn={class:`text-content-primary dark:text-content-primary font-mono`},An={class:`rounded-lg border border-stroke-subtle dark:border-stroke/10 bg-background-mute dark:bg-white/5 p-3`},jn={class:`text-content-primary dark:text-content-primary font-mono`},Mn={class:`rounded-lg border border-stroke-subtle dark:border-stroke/10 bg-background-mute dark:bg-white/5 p-3`},Nn={class:`text-content-primary dark:text-content-primary font-mono`},Pn={class:`rounded-lg border border-stroke-subtle dark:border-stroke/10 bg-background-mute dark:bg-white/5 p-3`},Fn={class:`text-content-primary dark:text-content-primary font-mono`},In={class:`grid grid-cols-1 sm:grid-cols-2 gap-3 py-2 border-b border-stroke-subtle dark:border-stroke/10`},Ln={class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},Rn={key:1,class:`block text-content-primary dark:text-content-primary font-mono text-sm mt-1`},zn={class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},Bn={key:1,class:`block text-content-primary dark:text-content-primary font-mono text-sm mt-1`},Vn=f({__name:`RadioHardwareSettings`,setup(n,{expose:r}){let s=ee(),u=[{value:`sx1262`,label:`sx1262`,detail:`Linux spidev + system GPIO`},{value:`sx1262_ch341`,label:`sx1262_ch341`,detail:`CH341 USB-to-SPI`},{value:`kiss`,label:`kiss`,detail:`KISS-modem over serial`},{value:`pymc_tcp`,label:`pymc_tcp`,detail:`pymc_tcp firmware modem over Wi-Fi/TCP`},{value:`pymc_usb`,label:`pymc_usb`,detail:`pymc_usb firmware modem over USB-CDC`},{value:`none`,label:`none`,detail:`Disable radio hardware (no RF I/O)`}],d=y(()=>{let e=s.stats;if(!e)return{};let t=e.config??{};return{...e,...t}}),f=o(!1),p=o(!1),m=o(``),g=o(!1),w=o(`none`),T=o([]),E=o(!1),O=o(``),k=o(!1),A=o([]),N=o(!1),P=o(``),F=o(``),I=o(``),L=o(9600),z=o(``),B=o(921600),V=o(``),H=o(5055),U=o(``),W=o(0),G=o(0),K=o(21),q=o(18),ne=o(20),re=o(16),ie=o(-1),J=o(-1),Y=o(-1),X=o(``),Z=o(-1),Q=o(-1),ae=o(6790),oe=o(21778);function se(e,t=``){return e==null?t:String(e)}function $(e,t){let n=Number(e);return Number.isFinite(n)?n:t}function ce(e){if(e==null)return`none`;let t=String(e).trim().toLowerCase();return!t||[`none`,`null`,`disabled`,`off`,`no_radio`].includes(t)?`none`:t===`kiss-modem`?`kiss`:t===`sx1262`?`sx1262`:t===`sx1262_ch341`?`sx1262_ch341`:t===`kiss`?`kiss`:t===`pymc_tcp`?`pymc_tcp`:t===`pymc_usb`?`pymc_usb`:`none`}function le(e){let t=e.config?.radio_type;return t==null||t===``?`sx1262`:ce(t)}let ue=y(()=>w.value!==`sx1262`&&w.value!==`sx1262_ch341`?[]:A.value.filter(e=>le(e)===w.value));function de(e){let t=A.value.find(t=>t.key===e);if(!t||!t.config)return;let n=t.config;W.value=$(n.bus_id,W.value),G.value=$(n.cs_id,G.value),K.value=$(n.cs_pin,K.value),q.value=$(n.reset_pin,q.value),ne.value=$(n.busy_pin,ne.value),re.value=$(n.irq_pin,re.value),ie.value=$(n.txen_pin,ie.value),J.value=$(n.rxen_pin,J.value),Y.value=$(n.en_pin,Y.value),Array.isArray(n.en_pins)?X.value=n.en_pins.map(e=>Number(e)).filter(e=>Number.isFinite(e)).join(`, `):X.value=``,Z.value=$(n.txled_pin,Z.value),Q.value=$(n.rxled_pin,Q.value),w.value===`sx1262_ch341`&&(ae.value=$(n.vid,ae.value),oe.value=$(n.pid,oe.value))}h(d,e=>{if(!f.value){w.value=ce(e.radio_type);let t=e.kiss??{},n=e.pymc_usb??{},r=e.pymc_tcp??{},i=e.sx1262??{},a=e.ch341??{};I.value=se(t.port,`/dev/ttyUSB0`),L.value=$(t.baud_rate,9600),z.value=se(n.port,`/dev/ttyACM0`),B.value=$(n.baudrate,921600),V.value=se(r.host,``),H.value=$(r.port,5055),U.value=se(r.token,``),W.value=$(i.bus_id,0),G.value=$(i.cs_id,0),K.value=$(i.cs_pin,21),q.value=$(i.reset_pin,18),ne.value=$(i.busy_pin,20),re.value=$(i.irq_pin,16),ie.value=$(i.txen_pin,-1),J.value=$(i.rxen_pin,-1),Y.value=$(i.en_pin,-1),Array.isArray(i.en_pins)?X.value=i.en_pins.map(e=>Number(e)).filter(e=>Number.isFinite(e)).join(`, `):X.value=``,Z.value=$(i.txled_pin,-1),Q.value=$(i.rxled_pin,-1),ae.value=$(a.vid,6790),oe.value=$(a.pid,21778),F.value=``}},{immediate:!0});let me=y(()=>ce(d.value.radio_type)),he=y(()=>{let e=u.find(e=>e.value===me.value);return e?`${e.label} - ${e.detail}`:`none - Disable radio hardware (no RF I/O)`});function ge(){w.value=me.value,f.value=!0,m.value=``}function _e(){w.value=me.value,f.value=!1,m.value=``,k.value=!1,F.value=``}function ve(e){return e.split(`,`).map(e=>Number(e.trim())).filter(e=>Number.isFinite(e))}async function ye(){N.value=!0,P.value=``;try{let e=await R.get(`hardware_options`),t=e.hardware;if(Array.isArray(t)){A.value=t;return}if(e.success&&Array.isArray(e.data)){A.value=e.data;return}A.value=[],P.value=e.error||`Could not load hardware presets`}catch(e){let t=e;A.value=[],P.value=t.message||`Could not load hardware presets`}finally{N.value=!1}}async function be(){E.value=!0,O.value=``;try{let e=await R.getSerialPorts();e.success&&Array.isArray(e.data)?T.value=e.data:(T.value=[],O.value=e.error||`Could not load USB serial devices`)}catch(e){let t=e;T.value=[],O.value=t.message||`Could not load USB serial devices`}finally{E.value=!1}}async function xe(){p.value=!0,m.value=``;try{if(w.value===`pymc_tcp`&&!V.value.trim())return m.value=`TCP modem host is required for pymc_tcp`,!1;let e={radio_type:w.value===`none`?null:w.value};if(w.value===`kiss`&&(e.kiss={port:I.value.trim()||`/dev/ttyUSB0`,baud_rate:$(L.value,9600)}),w.value===`pymc_usb`&&(e.pymc_usb={port:z.value.trim()||`/dev/ttyACM0`,baudrate:$(B.value,921600)}),w.value===`pymc_tcp`&&(e.pymc_tcp={host:V.value.trim(),port:$(H.value,5055),token:U.value}),w.value===`sx1262`||w.value===`sx1262_ch341`){let t=ve(X.value);e.sx1262={bus_id:$(W.value,0),cs_id:$(G.value,0),cs_pin:$(K.value,21),reset_pin:$(q.value,18),busy_pin:$(ne.value,20),irq_pin:$(re.value,16),txen_pin:$(ie.value,-1),rxen_pin:$(J.value,-1),...t.length>0?{en_pins:t}:{en_pin:$(Y.value,-1)},txled_pin:$(Z.value,-1),rxled_pin:$(Q.value,-1)}}w.value===`sx1262_ch341`&&(e.ch341={vid:$(ae.value,6790),pid:$(oe.value,21778)});let t=await R.importConfig(e);return t.success?(f.value=!1,await s.fetchStats(),g.value=!0,!0):(m.value=t.error||`Failed to save settings`,!1)}catch(e){let t=e;return m.value=t.response?.data?.error||t.message||`Failed to save settings`,!1}finally{p.value=!1}}let Se=y(()=>w.value===`kiss`||w.value===`pymc_usb`),Ce=y(()=>w.value===`pymc_tcp`),we=y(()=>w.value===`sx1262`||w.value===`sx1262_ch341`),Te=y(()=>w.value===`sx1262_ch341`),{showUnsavedModal:Ee,requestLeave:De,handleDiscard:Oe,handleSave:ke,handleCancel:Ae}=pe(f,p,_e,async()=>xe());return r({requestLeave:De,isEditing:f}),e(()=>{be(),ye()}),h([f,w],([e,t])=>{e&&(t===`kiss`||t===`pymc_usb`)&&be(),e&&(t===`sx1262`||t===`sx1262_ch341`)&&ye(),F.value=``},{immediate:!1}),(e,n)=>(a(),C(x,null,[v(te,{modelValue:g.value,"onUpdate:modelValue":n[0]||=e=>g.value=e,title:`Radio Hardware change requires a restart.`,message:`Restart now?`},null,8,[`modelValue`]),v(fe,{show:c(Ee),"is-saving":p.value,label:`Radio Hardware settings`,onDiscard:c(Oe),onSave:c(ke),onCancel:c(Ae)},null,8,[`show`,`is-saving`,`onDiscard`,`onSave`,`onCancel`]),S(`div`,lt,[S(`div`,ut,[n[28]||=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 Hardware `),S(`p`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},` Select which radio hardware backend this repeater should use `)],-1),S(`div`,dt,[f.value?(a(),C(x,{key:1},[S(`button`,{onClick:_e,disabled:p.value,class:`cfg-btn-secondary`},` Cancel `,8,ft),S(`button`,{onClick:xe,disabled:p.value,class:`cfg-btn-primary`},l(p.value?`Saving...`:`Save Changes`),9,pt)],64)):(a(),C(`button`,{key:0,onClick:ge,class:`cfg-btn-primary`},` Edit Settings `))])]),m.value?(a(),C(`div`,mt,l(m.value),1)):_(``,!0),S(`div`,ht,[S(`div`,gt,[n[29]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Radio Type`,-1),f.value?(a(),C(`div`,vt,[i(S(`select`,{"onUpdate:modelValue":n[1]||=e=>w.value=e,class:`cfg-select`},[(a(),C(x,null,t(u,e=>S(`option`,{key:e.value,value:e.value},l(e.label)+` - `+l(e.detail),9,yt)),64))],512),[[D,w.value]])])):(a(),C(`div`,_t,l(he.value),1))]),Se.value?(a(),C(x,{key:0},[S(`div`,bt,[n[31]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},` Serial Port `,-1),f.value?(a(),C(`div`,St,[S(`div`,Ct,[w.value===`kiss`?i((a(),C(`select`,{key:0,"onUpdate:modelValue":n[2]||=e=>I.value=e,class:`cfg-select flex-1`,disabled:k.value},[I.value&&!T.value.some(e=>e.device===I.value)?(a(),C(`option`,{key:0,value:I.value},l(I.value)+` (current) `,9,Tt)):_(``,!0),(a(!0),C(x,null,t(T.value,e=>(a(),C(`option`,{key:`kiss-${e.device}`,value:e.device},l(e.description||e.device),9,Et))),128))],8,wt)),[[D,I.value]]):i((a(),C(`select`,{key:1,"onUpdate:modelValue":n[3]||=e=>z.value=e,class:`cfg-select flex-1`,disabled:k.value},[z.value&&!T.value.some(e=>e.device===z.value)?(a(),C(`option`,{key:0,value:z.value},l(z.value)+` (current) `,9,Ot)):_(``,!0),(a(!0),C(x,null,t(T.value,e=>(a(),C(`option`,{key:`usb-${e.device}`,value:e.device},l(e.description||e.device),9,kt))),128))],8,Dt)),[[D,z.value]]),S(`button`,{type:`button`,class:`cfg-btn-secondary`,disabled:E.value,onClick:be},l(E.value?`...`:`Refresh`),9,At)]),S(`label`,jt,[i(S(`input`,{"onUpdate:modelValue":n[4]||=e=>k.value=e,type:`checkbox`},null,512),[[M,k.value]]),n[30]||=b(` Enter custom device path `,-1)]),k.value&&w.value===`kiss`?i((a(),C(`input`,{key:0,"onUpdate:modelValue":n[5]||=e=>I.value=e,type:`text`,class:`cfg-input`,placeholder:`/dev/ttyUSB0`},null,512)),[[j,I.value]]):_(``,!0),k.value&&w.value!==`kiss`?i((a(),C(`input`,{key:1,"onUpdate:modelValue":n[6]||=e=>z.value=e,type:`text`,class:`cfg-input`,placeholder:`/dev/ttyACM0`},null,512)),[[j,z.value]]):_(``,!0),O.value?(a(),C(`p`,Mt,l(O.value),1)):_(``,!0)])):(a(),C(`div`,xt,l(w.value===`kiss`?I.value:z.value),1))]),S(`div`,Nt,[n[32]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},` Baud Rate `,-1),f.value?(a(),C(x,{key:1},[w.value===`kiss`?i((a(),C(`input`,{key:0,"onUpdate:modelValue":n[7]||=e=>L.value=e,type:`number`,min:`1`,class:`cfg-input w-full sm:w-40`},null,512)),[[j,L.value,void 0,{number:!0}]]):i((a(),C(`input`,{key:1,"onUpdate:modelValue":n[8]||=e=>B.value=e,type:`number`,min:`1`,class:`cfg-input w-full sm:w-40`},null,512)),[[j,B.value,void 0,{number:!0}]])],64)):(a(),C(`div`,Pt,l(w.value===`kiss`?L.value:B.value),1))])],64)):_(``,!0),Ce.value?(a(),C(x,{key:1},[S(`div`,Ft,[n[33]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`TCP Host`,-1),f.value?i((a(),C(`input`,{key:1,"onUpdate:modelValue":n[9]||=e=>V.value=e,type:`text`,class:`cfg-input w-full sm:w-72`,placeholder:`pymc-3e2834.local`},null,512)),[[j,V.value]]):(a(),C(`div`,It,l(V.value||`Not set`),1))]),S(`div`,Lt,[n[34]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`TCP Port`,-1),f.value?i((a(),C(`input`,{key:1,"onUpdate:modelValue":n[10]||=e=>H.value=e,type:`number`,min:`1`,max:`65535`,class:`cfg-input w-full sm:w-40`},null,512)),[[j,H.value,void 0,{number:!0}]]):(a(),C(`div`,Rt,l(H.value),1))]),S(`div`,zt,[n[35]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`TCP Token`,-1),f.value?i((a(),C(`input`,{key:1,"onUpdate:modelValue":n[11]||=e=>U.value=e,type:`text`,class:`cfg-input w-full sm:w-72`,placeholder:`Optional`},null,512)),[[j,U.value]]):(a(),C(`div`,Bt,l(U.value?`Configured`:`Not set`),1))])],64)):_(``,!0),we.value&&f.value?(a(),C(x,{key:2},[S(`div`,Vt,[n[38]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Board Preset (Quick Apply)`,-1),S(`div`,Ht,[S(`div`,Ut,[i(S(`select`,{"onUpdate:modelValue":n[12]||=e=>F.value=e,class:`cfg-select flex-1`,onChange:n[13]||=e=>de(F.value)},[n[36]||=S(`option`,{value:``},`Leave current pin values unchanged`,-1),(a(!0),C(x,null,t(ue.value,e=>(a(),C(`option`,{key:e.key,value:e.key},l(e.name||e.key),9,Wt))),128))],544),[[D,F.value]]),S(`button`,{type:`button`,class:`cfg-btn-secondary`,disabled:N.value,onClick:ye},l(N.value?`...`:`Refresh`),9,Gt)]),P.value?(a(),C(`p`,Kt,l(P.value),1)):_(``,!0),n[37]||=S(`p`,{class:`text-xs text-content-muted dark:text-content-muted`},` Optional: selecting a preset fills the pin fields below for quick setup changes. `,-1)])]),n[51]||=S(`div`,{class:`pt-2 text-xs text-content-muted dark:text-content-muted`},`SX1262 Board Pin Configuration`,-1),S(`div`,qt,[S(`label`,Jt,[n[39]||=b(`SPI Bus ID `,-1),f.value?i((a(),C(`input`,{key:0,"onUpdate:modelValue":n[14]||=e=>W.value=e,type:`number`,class:`cfg-input mt-1`},null,512)),[[j,W.value,void 0,{number:!0}]]):(a(),C(`span`,Yt,l(W.value),1))]),S(`label`,Xt,[n[40]||=b(`SPI CS ID `,-1),f.value?i((a(),C(`input`,{key:0,"onUpdate:modelValue":n[15]||=e=>G.value=e,type:`number`,class:`cfg-input mt-1`},null,512)),[[j,G.value,void 0,{number:!0}]]):(a(),C(`span`,Zt,l(G.value),1))]),S(`label`,Qt,[n[41]||=b(`CS Pin `,-1),f.value?i((a(),C(`input`,{key:0,"onUpdate:modelValue":n[16]||=e=>K.value=e,type:`number`,class:`cfg-input mt-1`},null,512)),[[j,K.value,void 0,{number:!0}]]):(a(),C(`span`,$t,l(K.value),1))]),S(`label`,en,[n[42]||=b(`Reset Pin `,-1),f.value?i((a(),C(`input`,{key:0,"onUpdate:modelValue":n[17]||=e=>q.value=e,type:`number`,class:`cfg-input mt-1`},null,512)),[[j,q.value,void 0,{number:!0}]]):(a(),C(`span`,tn,l(q.value),1))]),S(`label`,nn,[n[43]||=b(`Busy Pin `,-1),f.value?i((a(),C(`input`,{key:0,"onUpdate:modelValue":n[18]||=e=>ne.value=e,type:`number`,class:`cfg-input mt-1`},null,512)),[[j,ne.value,void 0,{number:!0}]]):(a(),C(`span`,rn,l(ne.value),1))]),S(`label`,an,[n[44]||=b(`IRQ Pin `,-1),f.value?i((a(),C(`input`,{key:0,"onUpdate:modelValue":n[19]||=e=>re.value=e,type:`number`,class:`cfg-input mt-1`},null,512)),[[j,re.value,void 0,{number:!0}]]):(a(),C(`span`,on,l(re.value),1))]),S(`label`,sn,[n[45]||=b(`TX Enable Pin `,-1),f.value?i((a(),C(`input`,{key:0,"onUpdate:modelValue":n[20]||=e=>ie.value=e,type:`number`,class:`cfg-input mt-1`},null,512)),[[j,ie.value,void 0,{number:!0}]]):(a(),C(`span`,cn,l(ie.value),1))]),S(`label`,ln,[n[46]||=b(`RX Enable Pin `,-1),f.value?i((a(),C(`input`,{key:0,"onUpdate:modelValue":n[21]||=e=>J.value=e,type:`number`,class:`cfg-input mt-1`},null,512)),[[j,J.value,void 0,{number:!0}]]):(a(),C(`span`,un,l(J.value),1))]),S(`label`,dn,[n[47]||=b(`Power Enable Pin `,-1),f.value?i((a(),C(`input`,{key:0,"onUpdate:modelValue":n[22]||=e=>Y.value=e,type:`number`,class:`cfg-input mt-1`},null,512)),[[j,Y.value,void 0,{number:!0}]]):(a(),C(`span`,fn,l(Y.value),1))]),S(`label`,pn,[n[48]||=b(`Power Enable Pins (array) `,-1),f.value?i((a(),C(`input`,{key:0,"onUpdate:modelValue":n[23]||=e=>X.value=e,type:`text`,class:`cfg-input mt-1`,placeholder:`26, 23`},null,512)),[[j,X.value]]):(a(),C(`span`,mn,l(X.value||`Not set`),1))]),S(`label`,hn,[n[49]||=b(`TX LED Pin `,-1),f.value?i((a(),C(`input`,{key:0,"onUpdate:modelValue":n[24]||=e=>Z.value=e,type:`number`,class:`cfg-input mt-1`},null,512)),[[j,Z.value,void 0,{number:!0}]]):(a(),C(`span`,gn,l(Z.value),1))]),S(`label`,_n,[n[50]||=b(`RX LED Pin `,-1),f.value?i((a(),C(`input`,{key:0,"onUpdate:modelValue":n[25]||=e=>Q.value=e,type:`number`,class:`cfg-input mt-1`},null,512)),[[j,Q.value,void 0,{number:!0}]]):(a(),C(`span`,vn,l(Q.value),1))])])],64)):we.value?(a(),C(`div`,yn,[S(`div`,bn,[n[52]||=S(`div`,{class:`text-content-muted dark:text-content-muted text-xs mb-1`},`Current SPI bus`,-1),S(`div`,xn,l(W.value),1)]),S(`div`,Sn,[n[53]||=S(`div`,{class:`text-content-muted dark:text-content-muted text-xs mb-1`},`Current SPI CS`,-1),S(`div`,Cn,l(G.value),1)]),S(`div`,wn,[n[54]||=S(`div`,{class:`text-content-muted dark:text-content-muted text-xs mb-1`},`Current CS pin`,-1),S(`div`,Tn,l(K.value),1)]),S(`div`,En,[n[55]||=S(`div`,{class:`text-content-muted dark:text-content-muted text-xs mb-1`},`Current reset pin`,-1),S(`div`,Dn,l(q.value),1)]),S(`div`,On,[n[56]||=S(`div`,{class:`text-content-muted dark:text-content-muted text-xs mb-1`},`Current busy pin`,-1),S(`div`,kn,l(ne.value),1)]),S(`div`,An,[n[57]||=S(`div`,{class:`text-content-muted dark:text-content-muted text-xs mb-1`},`Current IRQ pin`,-1),S(`div`,jn,l(re.value),1)]),S(`div`,Mn,[n[58]||=S(`div`,{class:`text-content-muted dark:text-content-muted text-xs mb-1`},`Current power enable pin`,-1),S(`div`,Nn,l(Y.value),1)]),S(`div`,Pn,[n[59]||=S(`div`,{class:`text-content-muted dark:text-content-muted text-xs mb-1`},`Current power enable pins`,-1),S(`div`,Fn,l(X.value||`Not set`),1)])])):_(``,!0),Te.value?(a(),C(x,{key:4},[n[62]||=S(`div`,{class:`pt-2 text-xs text-content-muted dark:text-content-muted`},`CH341 Adapter Configuration`,-1),S(`div`,In,[S(`label`,Ln,[n[60]||=b(`CH341 VID `,-1),f.value?i((a(),C(`input`,{key:0,"onUpdate:modelValue":n[26]||=e=>ae.value=e,type:`number`,class:`cfg-input mt-1`},null,512)),[[j,ae.value,void 0,{number:!0}]]):(a(),C(`span`,Rn,l(ae.value),1))]),S(`label`,zn,[n[61]||=b(`CH341 PID `,-1),f.value?i((a(),C(`input`,{key:0,"onUpdate:modelValue":n[27]||=e=>oe.value=e,type:`number`,class:`cfg-input mt-1`},null,512)),[[j,oe.value,void 0,{number:!0}]]):(a(),C(`span`,Bn,l(oe.value),1))])])],64)):_(``,!0),n[63]||=S(`div`,{class:`py-2 text-xs text-content-muted dark:text-content-muted`},` Switching hardware saves immediately and requires a service restart to apply. `,-1)])])],64))}}),Hn={class:`space-y-12`},Un={class:`cfg-page-heading flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},Wn={class:`flex items-center gap-2 flex-shrink-0`},Gn=[`disabled`],Kn=[`disabled`],qn={key:0,class:`bg-green-100 dark:bg-green-500/10 border border-green-300 dark:border-green-500/30 rounded-lg p-3`},Jn={class:`text-green-700 dark:text-green-400 text-sm`},Yn={key:1,class:`bg-red-100 dark:bg-red-500/10 border border-red-300 dark:border-red-500/30 rounded-lg p-3`},Xn={class:`text-red-700 dark:text-red-400 text-sm`},Zn={class:`cfg-section space-y-3`},Qn={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`},$n={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm break-all`},er={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`},tr={class:`text-content-primary dark:text-content-primary font-mono text-xs break-all`},nr={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`},rr={class:`flex items-center gap-2 min-w-0 sm:justify-end`},ir={class:`text-content-primary dark:text-content-primary font-mono text-xs break-all sm:text-right min-w-0`},ar={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`},or={class:`text-content-primary dark:text-content-primary font-mono text-sm`},sr={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`},cr={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},lr={class:`flex flex-col py-2 gap-2`},ur={class:`flex flex-col sm:flex-row sm:justify-between sm:items-start gap-1`},dr={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm sm:ml-4`},fr={key:1,class:`flex items-center gap-2`},pr={class:`cfg-section space-y-3`},mr={class:`pb-2`},hr={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`},gr={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},_r={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 gap-1`},vr={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},yr={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`},br={class:`block text-sm font-medium text-content-secondary dark:text-content-muted mb-2`},xr=[`maxlength`,`disabled`],Sr={key:0,class:`text-red-500 text-xs mt-1`},Cr={key:1,class:`text-content-muted dark:text-content-muted text-xs mt-1`},wr=[`disabled`],Tr={key:0,class:`mt-2 bg-amber-500/10 border border-amber-500/30 rounded-lg p-3`},Er={key:0,class:`flex items-center gap-3 bg-blue-500/10 border border-blue-500/30 rounded-lg p-3`},Dr={class:`text-blue-700 dark:text-blue-400 text-xs font-medium`},Or={class:`text-blue-600 dark:text-blue-500 text-xs mt-0.5`},kr={key:1,class:`bg-red-500/10 border border-red-500/30 rounded-lg p-3`},Ar={class:`text-red-600 dark:text-red-400 text-sm`},jr={key:2,class:`bg-green-500/10 border border-green-600/40 dark:border-green-500/30 rounded-lg p-3 space-y-2`},Mr={class:`text-green-600 dark:text-green-400 text-sm font-medium`},Nr={class:`font-mono text-xs break-all text-content-primary dark:text-content-primary`},Pr={key:3,class:`bg-amber-500/10 border border-amber-500/30 rounded-lg p-3`},Fr={class:`flex gap-2 mt-3`},Ir=[`disabled`],Lr=[`disabled`],Rr={class:`flex justify-end gap-3 mt-6`},zr=[`disabled`],Br=[`disabled`],Vr=f({__name:`RepeaterSettings`,setup(e,{expose:t}){let n=ee(),r=y(()=>n.stats?.config||{}),s=y(()=>r.value.repeater||{}),d=y(()=>n.stats),f=o(!1),g=o(!1),w=o(null),E=o(null),O=o(!1),k=o(``),M=o(0),N=o(0),P=o(0),F=o(1),I=y(()=>r.value.mesh||{});h([r,s,I],()=>{if(!f.value){k.value=r.value.node_name||``,M.value=s.value.latitude||0,N.value=s.value.longitude||0,P.value=s.value.send_advert_interval_hours||0;let e=I.value.path_hash_mode;F.value=e===0||e===1||e===2?e+1:1}},{immediate:!0});let L=y(()=>r.value.node_name||`Not set`),z=y(()=>d.value?.local_hash||`Not available`),B=y(()=>{let e=d.value?.public_key;return!e||e===`Not set`?`Not set`:e}),V=y(()=>{let e=s.value.latitude;return e&&e!==0?e.toFixed(6):`Not set`}),H=y(()=>{let e=s.value.longitude;return e&&e!==0?e.toFixed(6):`Not set`}),U=y(()=>{let e=s.value.mode;return e?e===`no_tx`?`No TX`:e.charAt(0).toUpperCase()+e.slice(1):`Not set`}),W=y(()=>{let e=s.value.send_advert_interval_hours;return e===void 0?`Not set`:e===0?`Disabled`:e+` hour`+(e===1?``:`s`)}),G=y(()=>{let e=I.value.path_hash_mode;return e===0||e===1||e===2?e+1+(e===0?` byte`:` bytes`):`Not set`}),K=()=>{f.value=!0,w.value=null,E.value=null},te=()=>{f.value=!1,w.value=null,k.value=r.value.node_name||``,M.value=s.value.latitude||0,N.value=s.value.longitude||0,P.value=s.value.send_advert_interval_hours||0;let e=I.value.path_hash_mode;F.value=e===0||e===1||e===2?e+1:1},q=async()=>{g.value=!0,w.value=null,E.value=null;try{let e={};k.value&&(e.node_name=k.value),e.latitude=M.value,e.longitude=N.value,e.flood_advert_interval_hours=P.value,e.path_hash_mode=F.value-1;let t=(await R.post(`/update_radio_config`,e)).data;t.message||t.persisted?(E.value=t.message||`Settings saved successfully`,f.value=!1,await n.fetchStats(),setTimeout(()=>{E.value=null},3e3)):t.error?w.value=t.error:w.value=`Unknown response from server`}catch(e){console.error(`Failed to update repeater settings:`,e),w.value=e.response?.data?.error||`Failed to update settings`}finally{g.value=!1}},ne=()=>{O.value=!0},ie=e=>{M.value=e.latitude,N.value=e.longitude},J=o(!1),Y=o(``),X=o(!1),Z=o(null),Q=o(null),ae=o(!1),oe=o(!1),se=o(!1),$=o(0),ce=null,le=y(()=>se.value?8:4),ue=y(()=>{let e=Y.value.trim();return!e||e.length>le.value?!1:/^[0-9a-fA-F]+$/.test(e)}),de=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=()=>{$.value=0,ce=setInterval(()=>{$.value++},1e3)},he=()=>{ce&&=(clearInterval(ce),null)};T(()=>he());let ge=()=>{Y.value=``,Z.value=null,Q.value=null,ae.value=!1,se.value=!1,J.value=!0},_e=async()=>{X.value=!0,Q.value=null,Z.value=null,me();try{let e=await R.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){oe.value=!0,Q.value=null;try{let e=await R.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 n.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{oe.value=!1}}},{showUnsavedModal:ye,requestLeave:be,handleDiscard:xe,handleSave:Se,handleCancel:Ce}=pe(f,g,te,async()=>(await q(),!f.value));return t({requestLeave:be,isEditing:f}),(e,t)=>(a(),C(x,null,[v(fe,{show:c(ye),"is-saving":g.value,label:`Repeater Settings`,onDiscard:c(xe),onSave:c(Se),onCancel:c(Ce)},null,8,[`show`,`is-saving`,`onDiscard`,`onSave`,`onCancel`]),S(`div`,Hn,[S(`div`,Un,[t[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`,Wn,[f.value?(a(),C(x,{key:1},[S(`button`,{onClick:te,disabled:g.value,class:`cfg-btn-secondary`},` Cancel `,8,Gn),S(`button`,{onClick:q,disabled:g.value,class:`cfg-btn-primary`},l(g.value?`Saving...`:`Save Changes`),9,Kn)],64)):(a(),C(`button`,{key:0,onClick:K,class:`cfg-btn-primary`},` Edit Settings `))])]),E.value?(a(),C(`div`,qn,[S(`p`,Jn,l(E.value),1)])):_(``,!0),w.value?(a(),C(`div`,Yn,[S(`p`,Xn,l(w.value),1)])):_(``,!0),S(`div`,Zn,[t[23]||=S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary pb-2`},`General Settings`,-1),S(`div`,Qn,[t[14]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Node Name`,-1),f.value?i((a(),C(`input`,{key:1,"onUpdate:modelValue":t[0]||=e=>k.value=e,type:`text`,maxlength:`50`,class:`cfg-input w-full sm:w-64`,placeholder:`Enter node name`},null,512)),[[j,k.value]]):(a(),C(`div`,$n,l(L.value),1))]),S(`div`,er,[t[15]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Local Hash`,-1),S(`span`,tr,l(z.value),1)]),S(`div`,nr,[t[16]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm flex-shrink-0`},`Public Key`,-1),S(`div`,rr,[S(`span`,ir,l(B.value),1),f.value?(a(),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 `)):_(``,!0)])]),S(`div`,ar,[t[17]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Mode`,-1),S(`span`,or,l(U.value),1)]),S(`div`,sr,[t[19]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Path hash length`,-1),f.value?i((a(),C(`select`,{key:1,"onUpdate:modelValue":t[1]||=e=>F.value=e,class:`cfg-select w-full sm:w-32`},[...t[18]||=[S(`option`,{value:1},`1 byte`,-1),S(`option`,{value:2},`2 bytes`,-1),S(`option`,{value:3},`3 bytes`,-1)]],512)),[[D,F.value,void 0,{number:!0}]]):(a(),C(`div`,cr,l(G.value),1))]),S(`div`,lr,[S(`div`,ur,[t[21]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Periodic Advertisement Interval`,-1),f.value?(a(),C(`div`,fr,[i(S(`input`,{"onUpdate:modelValue":t[2]||=e=>P.value=e,type:`number`,min:`0`,max:`48`,class:`cfg-input w-20`},null,512),[[j,P.value,void 0,{number:!0}]]),t[20]||=S(`span`,{class:`text-content-muted dark:text-content-muted text-sm`},`hours`,-1)])):(a(),C(`div`,dr,l(W.value),1))]),t[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`,pr,[S(`div`,mr,[t[25]||=S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-3`},`Location Settings`,-1),f.value?(a(),C(`button`,{key:0,onClick:ne,class:`btn-primary flex items-center gap-2`,title:`Pick location on map`},[...t[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)]])):_(``,!0)]),S(`div`,hr,[t[26]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Manual Latitude`,-1),f.value?i((a(),C(`input`,{key:1,"onUpdate:modelValue":t[3]||=e=>M.value=e,type:`number`,step:`0.000001`,min:`-90`,max:`90`,class:`cfg-input w-full sm:w-48`},null,512)),[[j,M.value,void 0,{number:!0}]]):(a(),C(`div`,gr,l(V.value),1))]),S(`div`,_r,[t[27]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Manual Longitude`,-1),f.value?i((a(),C(`input`,{key:1,"onUpdate:modelValue":t[4]||=e=>N.value=e,type:`number`,step:`0.000001`,min:`-180`,max:`180`,class:`cfg-input w-full sm:w-48`},null,512)),[[j,N.value,void 0,{number:!0}]]):(a(),C(`div`,vr,l(H.value),1))])]),v(re,{"is-open":O.value,latitude:M.value,longitude:N.value,onClose:t[5]||=e=>O.value=!1,onSelect:ie},null,8,[`is-open`,`latitude`,`longitude`]),(a(),u(m,{to:`body`},[J.value?(a(),C(`div`,{key:0,class:`fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm`,onClick:t[12]||=A(e=>J.value=!1,[`self`])},[S(`div`,yr,[t[35]||=S(`h3`,{class:`text-xl font-semibold text-content-primary dark:text-content-primary`},` Generate Vanity Identity Key `,-1),t[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`,br,`Hex Prefix (1-`+l(le.value)+` characters)`,1),i(S(`input`,{"onUpdate:modelValue":t[6]||=e=>Y.value=e,type:`text`,maxlength:le.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,xr),[[j,Y.value]]),Y.value&&!ue.value?(a(),C(`p`,Sr,` Enter 1-`+l(le.value)+` valid hex characters (0-9, A-F) `,1)):de.value?(a(),C(`p`,Cr,l(de.value),1)):_(``,!0)]),S(`div`,null,[S(`button`,{onClick:t[7]||=e=>se.value=!se.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`},[(a(),C(`svg`,{class:p([`w-3 h-3 transition-transform`,{"rotate-90":se.value}]),fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[...t[28]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M9 5l7 7-7 7`},null,-1)]],2)),t[29]||=b(` Advanced `,-1)],8,wr),se.value?(a(),C(`div`,Tr,[...t[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)]])):_(``,!0)]),X.value?(a(),C(`div`,Er,[t[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`,Dr,` Searching for key with prefix "`+l(Y.value.toUpperCase())+`"... `,1),S(`p`,Or,` Elapsed: `+l($.value)+`s `,1)])])):_(``,!0),Q.value?(a(),C(`div`,kr,[S(`p`,Ar,l(Q.value),1)])):_(``,!0),Z.value?(a(),C(`div`,jr,[S(`p`,Mr,` Key found in `+l(Z.value.attempts.toLocaleString())+` attempts `,1),S(`div`,null,[t[32]||=S(`span`,{class:`text-xs text-content-muted dark:text-content-muted`},`Public Key:`,-1),S(`p`,Nr,l(Z.value.public_hex),1)])])):_(``,!0),ae.value&&Z.value?(a(),C(`div`,Pr,[t[33]||=S(`p`,{class:`text-amber-600 dark:text-amber-400 text-sm font-medium`},` Warning: This will replace your current identity key. `,-1),t[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`,Fr,[S(`button`,{onClick:ve,disabled:oe.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`},l(oe.value?`Applying...`:`Confirm Replace Key`),9,Ir),S(`button`,{onClick:t[8]||=e=>ae.value=!1,disabled:oe.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,Lr)])])):_(``,!0),S(`div`,Rr,[S(`button`,{onClick:t[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,zr),Z.value?(a(),C(x,{key:1},[S(`button`,{onClick:t[10]||=e=>{Z.value=null,Q.value=null},class:`btn-primary`},` Try Again `),ae.value?_(``,!0):(a(),C(`button`,{key:0,onClick:t[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)):(a(),C(`button`,{key:0,onClick:_e,disabled:!ue.value||X.value,class:`btn-primary`},l(X.value?`Generating...`:`Generate`),9,Br))])])])):_(``,!0)]))])],64))}}),Hr={class:`space-y-12`},Ur={class:`cfg-page-heading flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},Wr={class:`flex items-center gap-2 flex-shrink-0`},Gr=[`disabled`],Kr=[`disabled`],qr={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`},Jr={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`},Yr={class:`cfg-section`},Xr={class:`space-y-3`},Zr={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`},Qr={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},$r={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 gap-1`},ei={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},ti=f({__name:`DutyCycle`,setup(e,{expose:t}){let n=ee(),r=y(()=>n.stats?.config?.duty_cycle||{}),s=y(()=>{let e=r.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`}),u=y(()=>r.value.enforcement_enabled?`Enabled`:`Disabled`),d=o(!1),f=o(!1),p=o(``),m=o(``),h=o(0),g=o(!0),b=()=>{let e=r.value.max_airtime_percent;typeof e==`number`?h.value=e:e&&typeof e==`object`&&`parsedValue`in e?h.value=e.parsedValue||0:h.value=6,g.value=r.value.enforcement_enabled!==!1,d.value=!0,p.value=``,m.value=``},w=()=>{d.value=!1,p.value=``,m.value=``},{showUnsavedModal:T,requestLeave:E,handleDiscard:O,handleSave:k,handleCancel:A}=pe(d,f,w,async()=>(await M(),!d.value));t({requestLeave:E,isEditing:d});let M=async()=>{f.value=!0,m.value=``,p.value=``;try{let e=(await R.post(`/update_duty_cycle_config`,{max_airtime_percent:h.value,enforcement_enabled:g.value})).data;e?.message||e?.persisted?(p.value=e?.message||`Settings saved successfully`,d.value=!1,await n.fetchStats(),setTimeout(()=>{p.value=``},3e3)):m.value=e?.error||`Failed to save settings`}catch(e){console.error(`Failed to save duty cycle settings:`,e),m.value=e.response?.data?.error||`Failed to save settings`}finally{f.value=!1}};return(e,t)=>(a(),C(x,null,[v(fe,{show:c(T),"is-saving":f.value,label:`Duty Cycle settings`,onDiscard:c(O),onSave:c(k),onCancel:c(A)},null,8,[`show`,`is-saving`,`onDiscard`,`onSave`,`onCancel`]),S(`div`,Hr,[S(`div`,Ur,[t[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`,Wr,[d.value?(a(),C(x,{key:1},[S(`button`,{onClick:w,disabled:f.value,class:`cfg-btn-secondary`},` Cancel `,8,Gr),S(`button`,{onClick:M,disabled:f.value,class:`cfg-btn-primary`},l(f.value?`Saving...`:`Save Changes`),9,Kr)],64)):(a(),C(`button`,{key:0,onClick:b,class:`cfg-btn-primary`},` Edit Settings `))])]),p.value?(a(),C(`div`,qr,l(p.value),1)):_(``,!0),m.value?(a(),C(`div`,Jr,l(m.value),1)):_(``,!0),S(`div`,Yr,[S(`div`,Xr,[S(`div`,Zr,[t[3]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Max Airtime %`,-1),d.value?i((a(),C(`input`,{key:1,"onUpdate:modelValue":t[0]||=e=>h.value=e,type:`number`,step:`0.1`,min:`0.1`,max:`100`,class:`cfg-input w-full sm:w-32`},null,512)),[[j,h.value,void 0,{number:!0}]]):(a(),C(`div`,Qr,l(s.value),1))]),S(`div`,$r,[t[5]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Enforcement`,-1),d.value?i((a(),C(`select`,{key:1,"onUpdate:modelValue":t[1]||=e=>g.value=e,class:`cfg-select w-full sm:w-32`},[...t[4]||=[S(`option`,{value:!0},`Enabled`,-1),S(`option`,{value:!1},`Disabled`,-1)]],512)),[[D,g.value]]):(a(),C(`div`,ei,l(u.value),1))])])])])],64))}}),ni={class:`space-y-12`},ri={class:`cfg-page-heading flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},ii={class:`flex items-center gap-2 flex-shrink-0`},ai=[`disabled`],oi=[`disabled`],si={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`},ci={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`},li={class:`cfg-section space-y-3`},ui={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`},di={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm flex-shrink-0`},fi={class:`flex flex-col sm:flex-row sm:items-center sm:justify-between py-2 gap-3`},pi={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm flex-shrink-0`},mi=f({__name:`TransmissionDelays`,setup(e,{expose:t}){let n=ee(),r=y(()=>n.stats?.config?.delays||{}),s=y(()=>{let e=r.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`}),u=y(()=>{let e=r.value.direct_tx_delay_factor;return typeof e==`number`?e.toFixed(2)+`s`:`Not set`}),d=o(!1),f=o(!1),p=o(``),m=o(``),h=o(0),g=o(0),b=()=>{let e=r.value.tx_delay_factor;e&&typeof e==`object`&&`parsedValue`in e?h.value=e.parsedValue||1:typeof e==`number`?h.value=e:h.value=1;let t=r.value.direct_tx_delay_factor;g.value=typeof t==`number`?t:.5,d.value=!0,p.value=``,m.value=``},w=()=>{d.value=!1,p.value=``,m.value=``},T=async()=>{f.value=!0,m.value=``,p.value=``;try{let e=(await R.post(`/update_radio_config`,{tx_delay_factor:h.value,direct_tx_delay_factor:g.value})).data,t=e?.data??e;e?.success||t?.persisted||t?.message?(p.value=t?.message||`Settings saved successfully`,d.value=!1,await n.fetchStats(),setTimeout(()=>{p.value=``},3e3)):m.value=t?.error||`Failed to save settings`}catch(e){console.error(`Failed to save delay settings:`,e),m.value=e.response?.data?.error||`Failed to save settings`}finally{f.value=!1}},{showUnsavedModal:E,requestLeave:D,handleDiscard:O,handleSave:k,handleCancel:A}=pe(d,f,w,async()=>(await T(),!d.value));return t({requestLeave:D,isEditing:d}),(e,t)=>(a(),C(x,null,[v(fe,{show:c(E),"is-saving":f.value,label:`TX Delay settings`,onDiscard:c(O),onSave:c(k),onCancel:c(A)},null,8,[`show`,`is-saving`,`onDiscard`,`onSave`,`onCancel`]),S(`div`,ni,[S(`div`,ri,[t[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`,ii,[d.value?(a(),C(x,{key:1},[S(`button`,{onClick:w,disabled:f.value,class:`cfg-btn-secondary`},` Cancel `,8,ai),S(`button`,{onClick:T,disabled:f.value,class:`cfg-btn-primary`},l(f.value?`Saving...`:`Save Changes`),9,oi)],64)):(a(),C(`button`,{key:0,onClick:b,class:`cfg-btn-primary`},` Edit Settings `))])]),p.value?(a(),C(`div`,si,l(p.value),1)):_(``,!0),m.value?(a(),C(`div`,ci,l(m.value),1)):_(``,!0),S(`div`,li,[S(`div`,ui,[t[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),d.value?i((a(),C(`input`,{key:1,"onUpdate:modelValue":t[0]||=e=>h.value=e,type:`number`,step:`0.1`,min:`0`,max:`5`,class:`cfg-input w-full sm:w-32 flex-shrink-0`},null,512)),[[j,h.value,void 0,{number:!0}]]):(a(),C(`div`,di,l(s.value),1))]),S(`div`,fi,[t[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),d.value?i((a(),C(`input`,{key:1,"onUpdate:modelValue":t[1]||=e=>g.value=e,type:`number`,step:`0.1`,min:`0`,max:`5`,class:`cfg-input w-full sm:w-32 flex-shrink-0`},null,512)),[[j,g.value,void 0,{number:!0}]]):(a(),C(`div`,pi,l(u.value),1))])])])],64))}}),hi=z(`treeState`,()=>{let e=s(new Set),t=s({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)}}}),gi={class:`select-none`},_i={class:`flex-shrink-0`},vi={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`},yi={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`},bi={key:0,class:`hidden sm:flex items-center gap-1 ml-2`},xi={class:`relative group`},Si=[`title`],Ci={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`},wi={class:`flex justify-between items-start mb-4`},Ti={class:`bg-black/20 border border-white/10 rounded-md p-4 mb-4`},Ei={class:`text-sm font-mono text-white/80 break-all leading-relaxed`},Di={class:`flex justify-end`},Oi={class:`flex items-center gap-2 sm:gap-3 ml-auto flex-shrink-0`},ki={key:0,class:`hidden sm:flex items-center gap-1`},Ai=[`title`],ji={key:1,class:`hidden sm:flex items-center gap-1`},Mi={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`},Ni={key:0,class:`space-y-1`},Pi=K(f({__name:`TreeNode`,props:{node:{},selectedNodeId:{},level:{},disabled:{type:Boolean},unlocked:{type:Boolean}},emits:[`select`,`edit`,`delete`],setup(e,{emit:n}){let i=e,s=n,d=hi(),f=o(!1),m=y({get:()=>d.isNodeExpanded(i.node.id),set:e=>{e?d.addExpandedNode(i.node.id):d.removeExpandedNode(i.node.id)}}),h=y(()=>i.node.children.length>0);function b(){i.unlocked&&T(),h.value&&w()}function w(){h.value&&(m.value=!m.value)}function T(){s(`select`,i.node.id)}function E(e){s(`select`,e)}function D(e){s(`edit`,e)}function O(e){s(`delete`,e)}function k(e){e.stopPropagation(),f.value=!f.value}let{copy:j,copied:M}=ie();function P(e){e.stopPropagation(),i.node.transport_key&&j(i.node.transport_key)}return(n,o)=>{let d=g(`TreeNode`,!0);return a(),C(`div`,gi,[S(`div`,{class:p([`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&&e.selectedNodeId===e.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&&e.selectedNodeId!==e.node.id?`hover:bg-stroke-subtle/40 dark:hover:bg-white/5 hover:border-stroke dark:hover:border-white/15`:``,h.value&&!i.disabled?`cursor-pointer`:``,`ml-${e.level*4}`]),onClick:o[5]||=A(e=>!i.disabled&&b(),[`stop`])},[S(`div`,{class:`flex-shrink-0 w-3 h-3 sm:w-4 sm:h-4 flex items-center justify-center`,onClick:A(w,[`stop`])},[h.value?(a(),C(`svg`,{key:0,class:p([`w-2.5 h-2.5 sm:w-3 sm:h-3 transition-transform duration-200`,m.value?`rotate-90`:`rotate-0`]),fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[...o[6]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M9 5l7 7-7 7`},null,-1)]],2)):_(``,!0)]),S(`div`,_i,[i.node.name.startsWith(`#`)?(a(),C(`svg`,vi,[...o[7]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M7 20l4-16m2 16l4-16M6 9h14M4 15h14`},null,-1)]])):(a(),C(`svg`,yi,[...o[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:p([`font-mono text-xs sm:text-sm transition-colors duration-200 break-all`,e.selectedNodeId===e.node.id?`text-primary font-medium`:``])},l(e.node.name.startsWith(`#`)?e.node.name.slice(1):e.node.name),3),e.node.transport_key?(a(),C(`div`,bi,[S(`div`,xi,[S(`button`,{onClick:k,class:`p-1 rounded hover:bg-stroke-subtle dark:hover:bg-white/10 transition-colors`,title:f.value?`Hide full key`:`Show full key`},[...o[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,Si),f.value?_(``,!0):(a(),C(`span`,Ci,l(c(X)(e.node.transport_key)),1)),f.value?(a(),C(`div`,{key:1,class:`fixed inset-0 z-[300] flex items-center justify-center bg-black/70 backdrop-blur-md`,onClick:o[2]||=e=>f.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:o[1]||=A(()=>{},[`stop`])},[S(`div`,wi,[o[11]||=S(`h3`,{class:`text-lg font-semibold text-white`},`Transport Key`,-1),S(`button`,{onClick:o[0]||=e=>f.value=!1,class:`text-white/60 hover:text-white transition-colors`},[...o[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`,Ti,[S(`div`,Ei,l(e.node.transport_key),1)]),S(`div`,Di,[S(`button`,{onClick:P,class:p([`flex items-center gap-2 transition-colors`,c(M)?`btn-primary`:`btn-success`])},[o[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),v(J,{copied:c(M),label:`Copy Key`},null,8,[`copied`])],2)])])])):_(``,!0)])])):_(``,!0),S(`div`,Oi,[e.node.last_used?(a(),C(`div`,ki,[o[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:e.node.last_used.toLocaleString()},l(c(Y)(e.node.last_used)),9,Ai)])):(a(),C(`div`,ji,[...o[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:p([`text-[10px] sm:text-xs`,e.node.floodPolicy===`allow`?`text-accent-green/80`:`text-accent-red/80`])},` Flood: `+l(e.node.floodPolicy===`allow`?`Allow`:`Deny`),3),i.unlocked?(a(),C(x,{key:2},[S(`button`,{onClick:o[3]||=A(t=>s(`edit`,e.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:o[4]||=A(t=>s(`delete`,e.node.id),[`stop`]),class:`p-1 text-accent-red/50 hover:text-accent-red transition-colors`,title:`Delete`},[...o[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)):_(``,!0),h.value&&!i.unlocked?(a(),C(`span`,Mi,l(e.node.children.length),1)):_(``,!0)])],2),v(N,{"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:r(()=>[m.value&&e.node.children.length>0?(a(),C(`div`,Ni,[(a(!0),C(x,null,t(e.node.children,t=>(a(),u(d,{key:t.id,node:t,"selected-node-id":e.selectedNodeId,level:e.level+1,disabled:i.disabled,unlocked:i.unlocked,onSelect:E,onEdit:D,onDelete:O},null,8,[`node`,`selected-node-id`,`level`,`disabled`,`unlocked`]))),128))])):_(``,!0)]),_:1})])}}}),[[`__scopeId`,`data-v-1b1421f8`]]);function Fi(e){return e instanceof Uint8Array||ArrayBuffer.isView(e)&&e.constructor.name===`Uint8Array`&&`BYTES_PER_ELEMENT`in e&&e.BYTES_PER_ELEMENT===1}function Ii(e,t,n=``){let r=Fi(e),i=e?.length,a=t!==void 0;if(!r||a&&i!==t){let o=n&&`"${n}" `,s=a?` of length ${t}`:``,c=r?`length=${i}`:`type=${typeof e}`,l=o+`expected Uint8Array`+s+`, got `+c;throw r?RangeError(l):TypeError(l)}return e}function Li(e,t=!0){if(e.destroyed)throw Error(`Hash instance has been destroyed`);if(t&&e.finished)throw Error(`Hash#digest() has already been called`)}function Ri(e,t){Ii(e,void 0,`digestInto() output`);let n=t.outputLen;if(e.length<n)throw RangeError(`"digestInto() output" expected to be of length >=`+n)}function zi(...e){for(let t=0;t<e.length;t++)e[t].fill(0)}function Bi(e){return new DataView(e.buffer,e.byteOffset,e.byteLength)}function Vi(e,t){return e<<32-t|e>>>t}new Uint8Array(new Uint32Array([287454020]).buffer)[0],typeof Uint8Array.from([]).toHex==`function`&&Uint8Array.fromHex;function Hi(e,t={}){let n=(t,n)=>e(n).update(t).digest(),r=e(void 0);return n.outputLen=r.outputLen,n.blockLen=r.blockLen,n.canXOF=r.canXOF,n.create=t=>e(t),Object.assign(n,t),Object.freeze(n)}var Ui=e=>({oid:Uint8Array.from([6,9,96,134,72,1,101,3,4,2,e])});function Wi(e,t,n){return e&t^~e&n}function Gi(e,t,n){return e&t^e&n^t&n}var Ki=class{blockLen;outputLen;canXOF=!1;padOffset;isLE;buffer;view;finished=!1;length=0;pos=0;destroyed=!1;constructor(e,t,n,r){this.blockLen=e,this.outputLen=t,this.padOffset=n,this.isLE=r,this.buffer=new Uint8Array(e),this.view=Bi(this.buffer)}update(e){Li(this),Ii(e);let{view:t,buffer:n,blockLen:r}=this,i=e.length;for(let a=0;a<i;){let o=Math.min(r-this.pos,i-a);if(o===r){let t=Bi(e);for(;r<=i-a;a+=r)this.process(t,a);continue}n.set(e.subarray(a,a+o),this.pos),this.pos+=o,a+=o,this.pos===r&&(this.process(t,0),this.pos=0)}return this.length+=e.length,this.roundClean(),this}digestInto(e){Li(this),Ri(e,this),this.finished=!0;let{buffer:t,view:n,blockLen:r,isLE:i}=this,{pos:a}=this;t[a++]=128,zi(this.buffer.subarray(a)),this.padOffset>r-a&&(this.process(n,0),a=0);for(let e=a;e<r;e++)t[e]=0;n.setBigUint64(r-8,BigInt(this.length*8),i),this.process(n,0);let o=Bi(e),s=this.outputLen;if(s%4)throw Error(`_sha2: outputLen must be aligned to 32bit`);let c=s/4,l=this.get();if(c>l.length)throw Error(`_sha2: outputLen bigger than state`);for(let e=0;e<c;e++)o.setUint32(4*e,l[e],i)}digest(){let{buffer:e,outputLen:t}=this;this.digestInto(e);let n=e.slice(0,t);return this.destroy(),n}_cloneInto(e){e||=new this.constructor,e.set(...this.get());let{blockLen:t,buffer:n,length:r,finished:i,destroyed:a,pos:o}=this;return e.destroyed=a,e.finished=i,e.length=r,e.pos=o,r%t&&e.buffer.set(n),e}clone(){return this._cloneInto()}},qi=Uint32Array.from([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),Ji=BigInt(2**32-1),Yi=BigInt(32);function Xi(e,t=!1){return t?{h:Number(e&Ji),l:Number(e>>Yi&Ji)}:{h:Number(e>>Yi&Ji)|0,l:Number(e&Ji)|0}}function Zi(e,t=!1){let n=e.length,r=new Uint32Array(n),i=new Uint32Array(n);for(let a=0;a<n;a++){let{h:n,l:o}=Xi(e[a],t);[r[a],i[a]]=[n,o]}return[r,i]}var Qi=Uint32Array.from([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),$i=new Uint32Array(64),ea=class extends Ki{constructor(e){super(64,e,8,!1)}get(){let{A:e,B:t,C:n,D:r,E:i,F:a,G:o,H:s}=this;return[e,t,n,r,i,a,o,s]}set(e,t,n,r,i,a,o,s){this.A=e|0,this.B=t|0,this.C=n|0,this.D=r|0,this.E=i|0,this.F=a|0,this.G=o|0,this.H=s|0}process(e,t){for(let n=0;n<16;n++,t+=4)$i[n]=e.getUint32(t,!1);for(let e=16;e<64;e++){let t=$i[e-15],n=$i[e-2],r=Vi(t,7)^Vi(t,18)^t>>>3;$i[e]=(Vi(n,17)^Vi(n,19)^n>>>10)+$i[e-7]+r+$i[e-16]|0}let{A:n,B:r,C:i,D:a,E:o,F:s,G:c,H:l}=this;for(let e=0;e<64;e++){let t=Vi(o,6)^Vi(o,11)^Vi(o,25),u=l+t+Wi(o,s,c)+Qi[e]+$i[e]|0,d=(Vi(n,2)^Vi(n,13)^Vi(n,22))+Gi(n,r,i)|0;l=c,c=s,s=o,o=a+u|0,a=i,i=r,r=n,n=u+d|0}n=n+this.A|0,r=r+this.B|0,i=i+this.C|0,a=a+this.D|0,o=o+this.E|0,s=s+this.F|0,c=c+this.G|0,l=l+this.H|0,this.set(n,r,i,a,o,s,c,l)}roundClean(){zi($i)}destroy(){this.destroyed=!0,this.set(0,0,0,0,0,0,0,0),zi(this.buffer)}},ta=class extends ea{A=qi[0]|0;B=qi[1]|0;C=qi[2]|0;D=qi[3]|0;E=qi[4]|0;F=qi[5]|0;G=qi[6]|0;H=qi[7]|0;constructor(){super(32)}},na=Zi(`0x428a2f98d728ae22.0x7137449123ef65cd.0xb5c0fbcfec4d3b2f.0xe9b5dba58189dbbc.0x3956c25bf348b538.0x59f111f1b605d019.0x923f82a4af194f9b.0xab1c5ed5da6d8118.0xd807aa98a3030242.0x12835b0145706fbe.0x243185be4ee4b28c.0x550c7dc3d5ffb4e2.0x72be5d74f27b896f.0x80deb1fe3b1696b1.0x9bdc06a725c71235.0xc19bf174cf692694.0xe49b69c19ef14ad2.0xefbe4786384f25e3.0x0fc19dc68b8cd5b5.0x240ca1cc77ac9c65.0x2de92c6f592b0275.0x4a7484aa6ea6e483.0x5cb0a9dcbd41fbd4.0x76f988da831153b5.0x983e5152ee66dfab.0xa831c66d2db43210.0xb00327c898fb213f.0xbf597fc7beef0ee4.0xc6e00bf33da88fc2.0xd5a79147930aa725.0x06ca6351e003826f.0x142929670a0e6e70.0x27b70a8546d22ffc.0x2e1b21385c26c926.0x4d2c6dfc5ac42aed.0x53380d139d95b3df.0x650a73548baf63de.0x766a0abb3c77b2a8.0x81c2c92e47edaee6.0x92722c851482353b.0xa2bfe8a14cf10364.0xa81a664bbc423001.0xc24b8b70d0f89791.0xc76c51a30654be30.0xd192e819d6ef5218.0xd69906245565a910.0xf40e35855771202a.0x106aa07032bbd1b8.0x19a4c116b8d2d0c8.0x1e376c085141ab53.0x2748774cdf8eeb99.0x34b0bcb5e19b48a8.0x391c0cb3c5c95a63.0x4ed8aa4ae3418acb.0x5b9cca4f7763e373.0x682e6ff3d6b2b8a3.0x748f82ee5defb2fc.0x78a5636f43172f60.0x84c87814a1f0ab72.0x8cc702081a6439ec.0x90befffa23631e28.0xa4506cebde82bde9.0xbef9a3f7b2c67915.0xc67178f2e372532b.0xca273eceea26619c.0xd186b8c721c0c207.0xeada7dd6cde0eb1e.0xf57d4f7fee6ed178.0x06f067aa72176fba.0x0a637dc5a2c898a6.0x113f9804bef90dae.0x1b710b35131c471b.0x28db77f523047d84.0x32caab7b40c72493.0x3c9ebe0a15c9bebc.0x431d67c49c100d4c.0x4cc5d4becb3e42b6.0x597f299cfc657e2a.0x5fcb6fab3ad6faec.0x6c44198c4a475817`.split(`.`).map(e=>BigInt(e)));na[0],na[1];var ra=Hi(()=>new ta,Ui(1)),ia={class:`flex items-center justify-between mb-6`},aa={class:`text-xl font-semibold text-content-primary dark:text-content-primary`},oa={key:0,class:`text-content-secondary dark:text-content-muted text-sm mt-1`},sa={class:`text-primary font-mono`},ca={key:0,class:`mb-4 text-sm text-content-secondary dark:text-content-muted`},la={key:1,class:`mb-4 text-sm text-content-secondary dark:text-content-muted`},ua={class:`pb-2`},da={class:`flex bg-background-mute dark:bg-stroke/5 rounded-lg border border-stroke-subtle dark:border-stroke/20 p-0.5`},fa={class:`modal-field-label`},pa={class:`flex items-center`},ma={key:0,class:`px-3 py-2 bg-secondary/10 border border-r-0 border-secondary/30 rounded-l-md text-secondary text-sm font-mono`},ha=[`placeholder`],ga={key:0,class:`text-content-muted text-xs mt-1`},_a={key:1,class:`mt-3`},va={class:`flex items-center justify-between mb-1`},ya=[`value`],ba={key:0,class:`text-xs text-amber-500 dark:text-amber-400 mt-1`},xa={key:0,class:`bg-background-mute dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg p-3`},Sa={class:`flex items-center justify-between`},Ca={class:`text-right`},wa={class:`text-sm text-content-secondary dark:text-content-muted`},Ta={class:`text-xs text-content-muted dark:text-content-muted`},Ea={class:`pt-1 border-t border-stroke-subtle dark:border-stroke/10`},Da={class:`flex bg-background-mute dark:bg-stroke/5 rounded-lg border border-stroke-subtle dark:border-stroke/20 p-0.5`},Oa={class:`modal-actions`},ka=[`disabled`],Aa=f({name:`KeyModal`,__name:`KeyModal`,props:{show:{type:Boolean},node:{},selectedParentId:{},allNodes:{}},emits:[`close`,`add`,`save`],setup(e,{emit:r}){let s=e,d=r,f=y(()=>s.node===null),g=o(``),w=o(`allow`),T=o(`region`),E=y(()=>T.value===`region`),D=y(()=>({type:E.value?`Region`:`Private Key`}));h(()=>s.node,e=>{if(e){let t=e.name.startsWith(`#`);T.value=t?`region`:`privateKey`,g.value=t?e.name.slice(1):e.name,w.value=e.floodPolicy}else g.value=``,w.value=`allow`,T.value=`region`},{immediate:!0});function O(e,t){for(let n of e){if(n.id===t)return n;let e=O(n.children,t);if(e)return e}return null}function k(e,t){for(let n of e){if(n.id===t)return[n];let e=k(n.children,t);if(e.length)return[n,...e]}return[]}let M=y(()=>{let e=f.value?s.selectedParentId:s.node?.parent_id;return e?k(s.allNodes,e):[]}),N=y(()=>{let e=g.value.trim();return e?E.value?`#${e}`:e:s.node?.name||``}),P=y(()=>s.node?s.node.name.startsWith(`#`)?s.node.name.slice(1):s.node.name:``),F=y(()=>g.value.trim()!==P.value);function I(e){let t=e.startsWith(`#`)?e:`#${e}`,n=ra(new TextEncoder().encode(t)).slice(0,16),r=``;return n.forEach(e=>{r+=String.fromCharCode(e)}),btoa(r)}let L=o(null);n(()=>{if(f.value){L.value=null;return}let e=g.value.trim();if(!E.value||!e){L.value=null;return}L.value=I(e)});let{copy:R,copied:z}=ie(),B=y(()=>f.value?g.value.trim().length>0:g.value.trim().length>0&&s.node!==null),ee=()=>{if(!B.value)return;let e=E.value?`#${g.value.trim()}`:g.value.trim();if(f.value)d(`add`,{name:e,floodPolicy:w.value,parentId:s.selectedParentId}),g.value=``,w.value=`allow`,T.value=`region`;else{let t=E.value&&F.value?L.value??I(g.value.trim()):void 0;d(`save`,{id:s.node.id,name:e,floodPolicy:w.value,transportKey:t}),d(`close`)}},V=()=>{f.value&&(g.value=``,w.value=`allow`,T.value=`region`),d(`close`)};return(n,r)=>(a(),u(m,{to:`body`},[e.show?(a(),C(`div`,{key:0,class:`modal-backdrop`,onClick:A(V,[`self`])},[S(`div`,{class:p([`modal-card`,f.value?`max-w-md`:`max-w-lg`])},[S(`div`,ia,[S(`div`,null,[S(`h3`,aa,l(f.value?`Add New Entry`:`Edit Entry`),1),f.value?_(``,!0):(a(),C(`p`,oa,[r[6]||=b(` Modify `,-1),S(`span`,sa,l(N.value),1)]))]),S(`button`,{onClick:V,class:`text-content-muted hover:text-content-primary transition-colors`},[...r[7]||=[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)]])]),M.value.length>0?(a(),C(`div`,ca,[S(`span`,null,l(f.value?`Adding under:`:`Parent:`),1),(a(!0),C(x,null,t(M.value,(e,t)=>(a(),C(`span`,{key:e.id},[r[8]||=S(`span`,{class:`text-content-muted dark:text-content-muted`},` / `,-1),S(`span`,{class:p(t===M.value.length-1?`text-primary font-mono`:`font-mono`)},l(e.name),3)]))),128))])):f.value?(a(),C(`div`,la,` Adding at root level `)):_(``,!0),S(`form`,{onSubmit:A(ee,[`prevent`]),class:`modal-form`},[S(`div`,ua,[r[9]||=S(`label`,{class:`modal-field-label`},`Entry Type`,-1),S(`div`,da,[S(`button`,{type:`button`,onClick:r[0]||=e=>T.value=`region`,class:p([`flex-1 px-3 py-1.5 text-xs font-medium rounded transition-colors`,T.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=>T.value=`privateKey`,class:p([`flex-1 px-3 py-1.5 text-xs font-medium rounded transition-colors`,T.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`,fa,l(D.value.type)+` Name`,1),S(`div`,pa,[E.value?(a(),C(`span`,ma,`#`)):_(``,!0),i(S(`input`,{"onUpdate:modelValue":r[2]||=e=>g.value=e,type:`text`,placeholder:E.value?`e.g., uk, au, us`:`Enter key name`,class:p([`modal-input`,E.value?`rounded-l-none`:``]),autocomplete:`off`},null,10,ha),[[j,g.value]])]),E.value?(a(),C(`p`,ga,` The # prefix is added automatically for regions. `)):_(``,!0),!f.value&&E.value&&e.node?.transport_key?(a(),C(`div`,_a,[S(`div`,va,[r[11]||=S(`span`,{class:`modal-field-label mb-0 mt-0`},`Transport Key`,-1),F.value?_(``,!0):(a(),C(`button`,{key:0,type:`button`,onClick:r[3]||=t=>c(R)(e.node.transport_key||``),class:p([`text-xs flex items-center gap-1 transition-colors`,c(z)?`text-accent-green`:`text-content-muted hover:text-accent-green`])},[r[10]||=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),v(J,{copied:c(z)},null,8,[`copied`])],2))]),S(`input`,{value:L.value??e.node.transport_key,readonly:``,class:`modal-input-readonly w-full text-xs`},null,8,ya),F.value?(a(),C(`p`,ba,` Updated for "`+l(N.value)+`" `,1)):_(``,!0)])):_(``,!0)]),!f.value&&e.node?.last_used?(a(),C(`div`,xa,[S(`div`,Sa,[r[12]||=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`,Ca,[S(`div`,wa,l(e.node.last_used.toLocaleDateString())+` at `+l(e.node.last_used.toLocaleTimeString()),1),S(`div`,Ta,l(c(Y)(e.node.last_used)),1)])])])):_(``,!0),S(`div`,Ea,[r[13]||=S(`label`,{class:`modal-field-label pt-4`},`Flood Policy`,-1),S(`div`,Da,[S(`button`,{type:`button`,onClick:r[4]||=e=>w.value=`allow`,class:p([`flex-1 px-3 py-1.5 text-xs font-medium rounded transition-colors`,w.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=>w.value=`deny`,class:p([`flex-1 px-3 py-1.5 text-xs font-medium rounded transition-colors`,w.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`,Oa,[S(`button`,{type:`button`,class:`modal-btn-cancel`,onClick:V},`Cancel`),S(`button`,{type:`submit`,disabled:!B.value,class:p([`flex-1 px-4 py-3 rounded-lg transition-colors font-medium`,B.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 cursor-not-allowed`])},l(f.value?`Add ${D.value.type}`:`Done`),11,ka)])],32)],2)])):_(``,!0)]))}}),ja={class:`modal-card max-w-lg`},Ma={class:`flex items-center gap-3 mb-6`},Na={class:`text-content-secondary dark:text-content-muted text-sm mt-1`},Pa={class:`text-accent-red font-mono`},Fa={key:0,class:`bg-accent-red/10 border border-accent-red/30 rounded-lg p-4 mb-6`},Ia={class:`flex items-start gap-3`},La={class:`flex-1`},Ra={class:`text-accent-red font-medium text-sm mb-2`},za={class:`space-y-1 max-h-32 overflow-y-auto`},Ba={key:0,class:`w-3 h-3 text-secondary`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},Va={key:1,class:`w-3 h-3 text-accent-green`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},Ha={class:`font-mono`},Ua={key:0,class:`text-content-secondary dark:text-content-muted text-xs`},Wa={key:1,class:`mb-6`},Ga={class:`mb-3`},Ka={class:`relative`},qa={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`},Ja={key:0,class:`text-center py-4 text-content-secondary dark:text-content-muted text-sm`},Ya={class:`relative`},Xa=[`value`],Za={class:`flex items-center gap-2 flex-1`},Qa={class:`text-content-primary dark:text-content-primary font-mono text-sm`},$a={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`},eo={class:`flex gap-3`},to=f({__name:`DeleteConfirmModal`,props:{show:{type:Boolean},node:{},allNodes:{}},emits:[`close`,`delete-all`,`move-children`],setup(e,{emit:n}){let r=e,s=n,c=o(null),d=o(``),f=e=>{let t=[],n=e=>{for(let r of e.children)t.push(r),n(r)};return n(e),t},h=y(()=>r.node?f(r.node):[]),g=y(()=>{if(!r.node)return[];let e=new Set([r.node.id,...h.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)}),v=y(()=>{if(!d.value.trim())return g.value;let e=d.value.toLowerCase();return g.value.filter(t=>t.name.toLowerCase().includes(e))}),w=()=>{r.node&&(s(`delete-all`,r.node.id),E())},T=()=>{!r.node||!c.value||(s(`move-children`,{nodeId:r.node.id,targetParentId:c.value}),E())},E=()=>{c.value=null,d.value=``,s(`close`)};return(n,r)=>(a(),u(m,{to:`body`},[e.show&&e.node?(a(),C(`div`,{key:0,onClick:r[2]||=A(e=>E(),[`self`]),class:`modal-backdrop-heavy`},[S(`div`,ja,[S(`div`,Ma,[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`,Na,[r[3]||=b(` Deleting `,-1),S(`span`,Pa,l(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)]])]),h.value.length>0?(a(),C(`div`,Fa,[S(`div`,Ia,[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`,La,[S(`h4`,Ra,` This will affect `+l(h.value.length)+` child `+l(h.value.length===1?`entry`:`entries`)+`: `,1),S(`div`,za,[(a(!0),C(x,null,t(h.value.slice(0,10),e=>(a(),C(`div`,{key:e.id,class:`flex items-center gap-2 text-xs text-content-secondary dark:text-content-primary/80`},[e.name.startsWith(`#`)?(a(),C(`svg`,Ba,[...r[7]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M7 20l4-16m2 16l4-16M6 9h14M4 15h14`},null,-1)]])):(a(),C(`svg`,Va,[...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`,Ha,l(e.name),1),S(`span`,{class:p([`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`])},l(e.floodPolicy),3)]))),128)),h.value.length>10?(a(),C(`div`,Ua,` ...and `+l(h.value.length-10)+` more `,1)):_(``,!0)])])])])):_(``,!0),h.value.length>0&&g.value.length>0?(a(),C(`div`,Wa,[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`,Ga,[S(`div`,Ka,[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),i(S(`input`,{"onUpdate:modelValue":r[0]||=e=>d.value=e,type:`text`,placeholder:`Search regions...`,class:`modal-input pl-9`},null,512),[[j,d.value]])])]),S(`div`,qa,[v.value.length===0?(a(),C(`div`,Ja,l(d.value?`No regions match your search`:`No available regions`),1)):_(``,!0),(a(!0),C(x,null,t(v.value,e=>(a(),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`,Ya,[i(S(`input`,{type:`radio`,value:e.id,"onUpdate:modelValue":r[1]||=e=>c.value=e,class:`sr-only peer`},null,8,Xa),[[k,c.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`,Za,[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`,Qa,l(e.name),1),e.children.length>0?(a(),C(`span`,$a,l(e.children.length),1)):_(``,!0)])]))),128))])])):_(``,!0),S(`div`,eo,[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 `),h.value.length>0&&c.value?(a(),C(`button`,{key:0,onClick:T,class:`modal-btn-primary`},` Move & Delete `)):_(``,!0),S(`button`,{onClick:w,class:`modal-btn-danger`},l(h.value.length>0?`Delete All`:`Delete`),1)])])])):_(``,!0)]))}}),no={class:`space-y-12`},ro={class:`cfg-page-heading flex flex-col sm:flex-row sm:justify-between sm:items-start gap-3`},io={class:`flex items-center gap-2 flex-shrink-0`},ao=[`disabled`],oo=[`disabled`],so=[`disabled`],co={key:0,class:`bg-red-100 dark:bg-red-500/20 border border-red-500/50 rounded-lg p-3`},lo={class:`text-red-600 dark:text-red-400 text-sm`},uo={class:`cfg-section`},fo={class:`flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3`},po={key:0,class:`text-xs text-content-muted dark:text-content-muted pb-1`},mo={key:1,class:`flex items-center justify-center py-8`},ho={key:2,class:`text-center py-8`},go={class:`text-content-secondary dark:text-content-muted text-sm`},_o={key:3,class:`text-center py-8`},vo={key:4,class:`space-y-2`},yo=f({name:`TransportKeys`,__name:`TransportKeys`,setup(n,{expose:r}){let i=hi(),s=ee(),d=o(!1),f=o(!1),m=o(null),g=-1;function w(){return g--}let T=o(`deny`),E=`deny`;h(y(()=>s.stats?.config?.mesh?.unscoped_flood_allow??null),e=>{e!==null&&!d.value&&(T.value=e?`allow`:`deny`)},{immediate:!0});let D=o([]),O=null,k=o(!1),A=o(null),j=o(!1),M=o(!1),N=o(!1),P=o(null),F=o(null);function I(e){return e.map(e=>({...e,children:I(e.children)}))}function L(e,t){let n=[];for(let r of e)n.push({node:r,parentId:t}),n.push(...L(r.children,r.id));return n}function z(e,t){for(let n of e){if(n.id===t)return n;let e=z(n.children,t);if(e)return e}return null}function B(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(B(n.children,t))return!0;return!1}let V=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},H=async()=>{k.value=!0,A.value=null;try{let e=await R.getTransportKeys();e.success&&e.data?D.value=V(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}};e(H);function U(){O=I(D.value),E=T.value,d.value=!0,m.value=null}function G(){O&&(D.value=I(O)),T.value=E,O=null,d.value=!1,m.value=null,i.setSelectedNode(null)}async function K(){f.value=!0,m.value=null;try{let e=L(D.value),t=O?L(O):[],n=new Map(t.map(({node:e})=>[e.id,e])),r=e.filter(({node:e})=>e.id>0),a=e.filter(({node:e})=>e.id<0),o=new Set(r.map(({node:e})=>e.id));for(let{node:e}of t)o.has(e.id)||await R.deleteTransportKey(e.id);let c=new Map,l=[...a],u=l.length*2;for(;l.length&&u-- >0;){let e=l.findIndex(({parentId:e})=>e===void 0||e>0||e<0&&c.has(e));if(e===-1)break;let{node:t,parentId:n}=l.splice(e,1)[0],r=n===void 0?void 0:n>0?n:c.get(n),i=await R.createTransportKey(t.name,t.floodPolicy,t.transport_key,r);i.success&&i.data?.id&&c.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 R.updateTransportKey(e.id,e.name,e.floodPolicy,e.transport_key)}T.value!==E&&await R.updateUnscopedFloodPolicy(T.value===`allow`),await H(),await s.fetchStats(),O=null,d.value=!1,i.setSelectedNode(null)}catch(e){m.value=e instanceof Error?e.message:`Save failed`}finally{f.value=!1}}function te(e){i.setSelectedNode(e)}function q(){j.value=!0}function ne(e){let t={id:w(),name:e.name,floodPolicy:e.floodPolicy,children:[]};if(e.parentId){let n=z(D.value,e.parentId);n?n.children.push(t):D.value.push(t)}else D.value.push(t);j.value=!1}function re(e){let t=z(D.value,e);t&&(P.value=t,M.value=!0)}function ie(e){let t=z(D.value,e.id);t&&(t.name=e.name,t.floodPolicy=e.floodPolicy,e.transportKey!==void 0&&(t.transport_key=e.transportKey)),M.value=!1,P.value=null}function J(){M.value=!1,P.value=null}function Y(e){let t=z(D.value,e);t&&(F.value=t,N.value=!0)}function X(e){B(D.value,e),i.setSelectedNode(null),N.value=!1,F.value=null}function Z(e){let t=z(D.value,e.nodeId);if(t?.children.length){let n=z(D.value,e.targetParentId);n?n.children.push(...t.children):D.value.push(...t.children)}B(D.value,e.nodeId),i.setSelectedNode(null),N.value=!1,F.value=null}function Q(e){T.value=e}let{showUnsavedModal:ae,requestLeave:oe,handleDiscard:se,handleSave:$,handleCancel:ce}=pe(d,f,G,async()=>(await K(),!d.value));return r({requestLeave:oe,isEditing:d}),(e,n)=>(a(),C(x,null,[v(fe,{show:c(ae),"is-saving":f.value,label:`Region Configuration`,onDiscard:c(se),onSave:c($),onCancel:c(ce)},null,8,[`show`,`is-saving`,`onDiscard`,`onSave`,`onCancel`]),S(`div`,no,[S(`div`,ro,[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`,io,[d.value?(a(),C(`button`,{key:0,onClick:q,class:`cfg-btn-secondary flex items-center gap-1.5`,disabled:f.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,ao)):_(``,!0),d.value?(a(),C(x,{key:2},[S(`button`,{onClick:G,disabled:f.value,class:`cfg-btn-secondary`},`Cancel`,8,oo),S(`button`,{onClick:K,disabled:f.value,class:`cfg-btn-primary`},l(f.value?`Saving…`:`Save Changes`),9,so)],64)):(a(),C(`button`,{key:1,onClick:U,class:`cfg-btn-primary`},`Edit Settings`))])]),m.value?(a(),C(`div`,co,[S(`p`,lo,l(m.value),1)])):_(``,!0),S(`div`,uo,[S(`div`,fo,[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:p([`flex bg-background-mute dark:bg-stroke/5 rounded-lg border border-stroke-subtle dark:border-stroke/20 p-0.5 sm:p-1`,d.value?``:`opacity-50 pointer-events-none`])},[S(`button`,{onClick:n[0]||=e=>Q(`deny`),class:p([`px-2 sm:px-3 py-1 text-[10px] sm:text-xs font-medium rounded transition-colors`,T.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=>Q(`allow`),class:p([`px-2 sm:px-3 py-1 text-[10px] sm:text-xs font-medium rounded transition-colors`,T.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=>d.value&&c(i).setSelectedNode(null)},[n[11]||=S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary`},`Regions`,-1),d.value?(a(),C(`p`,po,` To add a child region, click on a region to select it, then click "Add Region". `)):_(``,!0),k.value?(a(),C(`div`,mo,[v(W),n[8]||=S(`span`,{class:`ml-2 text-content-secondary dark:text-content-muted`},`Loading regions…`,-1)])):A.value?(a(),C(`div`,ho,[n[9]||=S(`div`,{class:`text-accent-red mb-2`},`⚠️ Error loading regions`,-1),S(`div`,go,l(A.value),1),S(`button`,{onClick:H,class:`btn-success mt-4`},` Retry `)])):D.value.length===0?(a(),C(`div`,_o,[...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)]])):(a(),C(`div`,vo,[(a(!0),C(x,null,t(D.value,e=>(a(),u(Pi,{key:e.id,node:e,"selected-node-id":c(i).selectedNodeId.value,level:0,unlocked:d.value,onSelect:te,onEdit:re,onDelete:Y},null,8,[`node`,`selected-node-id`,`unlocked`]))),128))]))]),v(Aa,{show:j.value,node:null,"selected-parent-id":c(i).selectedNodeId.value||void 0,"all-nodes":D.value,onClose:n[3]||=e=>j.value=!1,onAdd:ne},null,8,[`show`,`selected-parent-id`,`all-nodes`]),v(Aa,{show:M.value,node:P.value,"all-nodes":D.value,onClose:J,onSave:ie},null,8,[`show`,`node`,`all-nodes`]),v(to,{show:N.value,node:F.value,"all-nodes":D.value,onClose:n[4]||=e=>{N.value=!1,F.value=null},onDeleteAll:X,onMoveChildren:Z},null,8,[`show`,`node`,`all-nodes`])])],64))}}),bo={class:`space-y-12`},xo={class:`cfg-page-heading flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3`},So={key:0,class:`bg-red-500/10 border border-red-500/30 rounded-lg p-4`},Co={class:`flex items-center gap-2 text-red-600 dark:text-red-400`},wo={key:1,class:`flex items-center justify-center py-12`},To={class:`text-center`},Eo={key:2,class:`space-y-3`},Do={class:`flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3`},Oo={class:`flex-1`},ko={class:`flex items-center gap-2 sm:gap-3`},Ao={class:`min-w-0 flex-1`},jo={class:`text-content-primary dark:text-content-primary font-medium text-sm sm:text-base break-all`},Mo={class:`flex flex-col sm:flex-row sm:items-center sm:gap-4 mt-1 text-xs text-content-secondary dark:text-content-muted`},No={class:`truncate`},Po={class:`truncate`},Fo=[`onClick`,`disabled`],Io={key:3,class:`text-center py-12`},Lo={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`},Ro={class:`space-y-4`},zo={class:`flex justify-end gap-3 mt-6`},Bo=[`disabled`],Vo=[`disabled`],Ho={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`},Uo={class:`space-y-4`},Wo={class:`flex gap-2`},Go=[`value`],Ko={key:0,class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},qo={key:1,class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},Jo={class:`cfg-card p-4`},Yo={class:`code-block`},Xo=f({name:`APITokens`,__name:`APITokens`,setup(n){let r=o([]),s=o(!1),u=o(null),f=o(!1),m=o(``),h=o(null),g=o(!1),w=o(!1),T=o(null),E=async()=>{s.value=!0,u.value=null;try{let e=await R.get(`/auth/tokens`);r.value=(e.data||e).tokens||[]}catch(e){console.error(`Failed to fetch API tokens:`,e),u.value=e instanceof Error?e.message:`Failed to fetch tokens`}finally{s.value=!1}},D=async()=>{if(!m.value.trim()){u.value=`Token name is required`;return}s.value=!0,u.value=null;try{let e=await R.post(`/auth/tokens`,{name:m.value.trim()});h.value=(e.data||e).token||null,f.value=!1,g.value=!0,m.value=``,await E()}catch(e){console.error(`Failed to create API token:`,e),u.value=e instanceof Error?e.message:`Failed to create token`}finally{s.value=!1}},k=(e,t)=>{T.value={id:e,name:t},w.value=!0},M=async()=>{if(T.value){s.value=!0,u.value=null;try{await R.delete(`/auth/tokens/${T.value.id}`),await E(),w.value=!1,T.value=null}catch(e){console.error(`Failed to revoke API token:`,e),u.value=e instanceof Error?e.message:`Failed to revoke token`}finally{s.value=!1}}},N=()=>{f.value=!1,m.value=``,u.value=null},P=()=>{g.value=!1,h.value=null},{copy:F,copied:I}=ie(),L=()=>{h.value&&F(h.value)},z=e=>e?new Date(e*1e3).toLocaleString():`Never`,B=y(()=>`${window.location.origin}/api/stats`);return e(()=>{E()}),(e,n)=>(a(),C(x,null,[S(`div`,bo,[S(`div`,xo,[n[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:n[0]||=e=>f.value=!0,class:`cfg-btn-primary flex items-center justify-center gap-2`},[...n[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)]])]),n[21]||=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-content-secondary dark:text-content-muted"><p><strong>API tokens</strong> are used for machine-to-machine authentication. Include the token in the <code class="bg-background-mute dark:bg-white/10 px-1 rounded font-mono">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),u.value?(a(),C(`div`,So,[S(`div`,Co,[n[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(` `+l(u.value),1)])])):_(``,!0),s.value&&r.value.length===0?(a(),C(`div`,wo,[S(`div`,To,[v(W,{class:`mx-auto mb-4`}),n[7]||=S(`div`,{class:`text-content-secondary dark:text-content-muted`},`Loading tokens...`,-1)])])):r.value.length>0?(a(),C(`div`,Eo,[(a(!0),C(x,null,t(r.value,e=>(a(),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`,Do,[S(`div`,Oo,[S(`div`,ko,[n[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`,Ao,[S(`h3`,jo,l(e.name),1),S(`div`,Mo,[S(`span`,No,`Created: `+l(z(e.created_at)),1),S(`span`,Po,`Last used: `+l(z(e.last_used)),1)])])])]),S(`button`,{onClick:t=>k(e.id,e.name),disabled:s.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,Fo)])]))),128))])):(a(),C(`div`,Io,[n[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),n[10]||=S(`h3`,{class:`text-content-primary dark:text-content-primary font-medium mb-2`},`No API Tokens`,-1),n[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:n[1]||=e=>f.value=!0,class:`cfg-btn-primary`},` Create Your First Token `)])),f.value?(a(),C(`div`,{key:4,class:`fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm`,onClick:A(N,[`self`])},[S(`div`,Lo,[n[14]||=S(`h3`,{class:`text-xl font-semibold text-content-primary dark:text-content-primary mb-4`},` Create API Token `,-1),S(`div`,Ro,[S(`div`,null,[n[12]||=S(`label`,{class:`block text-sm font-medium text-content-secondary dark:text-content-muted mb-2`},`Token Name`,-1),i(S(`input`,{"onUpdate:modelValue":n[2]||=e=>m.value=e,type:`text`,placeholder:`e.g., Production Server, CI/CD Pipeline`,class:`cfg-input placeholder-gray-400 dark:placeholder-white/40`,onKeydown:O(D,[`enter`])},null,544),[[j,m.value]]),n[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`,zo,[S(`button`,{onClick:N,disabled:s.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,Bo),S(`button`,{onClick:D,disabled:s.value||!m.value.trim(),class:`btn-primary`},l(s.value?`Creating...`:`Create Token`),9,Vo)])])])])):_(``,!0),g.value&&h.value?(a(),C(`div`,{key:5,class:`fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm`,onClick:A(P,[`self`])},[S(`div`,Ho,[n[20]||=S(`h3`,{class:`text-xl font-semibold text-content-primary dark:text-content-primary mb-4`},` Token Created Successfully `,-1),S(`div`,Uo,[n[19]||=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-secondary"><strong>Save this token now!</strong> For security reasons, it will not be shown again. </div></div></div>`,1),S(`div`,null,[n[17]||=S(`label`,{class:`block text-sm font-medium text-content-secondary dark:text-content-muted mb-2`},`Your API Token`,-1),S(`div`,Wo,[S(`input`,{value:h.value,readonly:``,class:`modal-input-readonly flex-1 text-sm`},null,8,Go),S(`button`,{onClick:L,class:p([`flex items-center gap-2 transition-colors`,c(I)?`btn-success`:`btn-primary`])},[c(I)?(a(),C(`svg`,qo,[...n[16]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M5 13l4 4L19 7`},null,-1)]])):(a(),C(`svg`,Ko,[...n[15]||=[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`},null,-1)]])),v(J,{copied:c(I)},null,8,[`copied`])],2)])]),S(`div`,Jo,[n[18]||=S(`p`,{class:`text-sm text-content-secondary dark:text-content-muted mb-2`},[S(`strong`,null,`Usage Example:`)],-1),S(`code`,Yo,` curl -H "X-API-Key: `+l(h.value)+`" `+l(B.value),1)]),S(`div`,{class:`flex justify-end mt-6`},[S(`button`,{onClick:P,class:`btn-primary`},` Done `)])])])])):_(``,!0)]),v(ne,{show:w.value,title:`Revoke API Token`,message:`Are you sure you want to revoke the token '${T.value?.name}'? This action cannot be undone.`,"confirm-text":`Revoke`,"cancel-text":`Cancel`,variant:`danger`,onConfirm:M,onClose:n[3]||=e=>w.value=!1},null,8,[`show`,`message`])],64))}}),Zo={class:`space-y-12`},Qo={class:`cfg-section`},$o={class:`space-y-4`},es=[`disabled`],ts={class:`cfg-section`},ns={class:`space-y-4`},rs={class:`flex items-center justify-between`},is=[`disabled`],as={class:`cfg-section`},os={class:`space-y-4`},ss={class:`space-y-3`},cs=[`checked`,`disabled`],ls=[`checked`,`disabled`],us={class:`flex items-start gap-3`},ds={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`},fs={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`},ps={class:`flex-1`},ms={class:`text-sm font-medium text-content-primary dark:text-content-primary`},hs={key:0,class:`text-xs text-green-600 dark:text-green-400 mt-1`},gs={key:1,class:`p-4 bg-amber-500/10 border border-amber-500/30 rounded-lg`},_s={class:`flex items-start justify-between gap-3`},vs=[`disabled`],ys={key:0,class:`animate-spin h-4 w-4`,fill:`none`,viewBox:`0 0 24 24`},bs={key:1,class:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`},xs={class:`flex items-center space-x-2`},Ss={key:0,class:`w-5 h-5 text-green-600 dark:text-green-400`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`},Cs={key:1,class:`w-5 h-5 text-red-600 dark:text-red-400`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`},ws=f({name:`WebSettings`,__name:`WebSettings`,setup(t){let{stats:n}=B(ee()),r=o(!1),c=o(``),u=o(!1),f=o(!1),m=o(!1),h=o(!1),g=o(!0),v=s({cors_enabled:!1,use_default_frontend:!0,site_name:``}),w=y(()=>u.value?`bg-green-500/10 border-green-600/40 dark:border-green-500/30`:`bg-red-500/10 border-red-500/30`);async function T(){try{g.value=!0;let e=await R.get(`/check_pymc_console`);e.success&&e.data&&(h.value=e.data.exists)}catch(e){console.error(`Failed to check PyMC Console:`,e),h.value=!1}finally{g.value=!1}}function E(){let e=n.value?.config?.web||{};v.cors_enabled=e.cors_enabled===!0;let t=e.web_path;v.use_default_frontend=!t||t===``,v.site_name=typeof n.value?.site_name==`string`?n.value.site_name:``}async function D(){r.value=!0,c.value=``;try{let e={web:{cors_enabled:v.cors_enabled,site_name:v.site_name.trim()}};v.use_default_frontend?e.web.web_path=null:e.web.web_path=`/opt/pymc_console/web/html`;let t=await R.post(`/update_web_config`,e);t.success?(M(`Settings saved successfully`,!0),f.value=!0):M(t.error||`Failed to save settings`,!1)}catch(e){console.error(`Failed to save web settings:`,e),M(e.message||`Failed to save settings`,!1)}finally{r.value=!1}}async function O(){v.cors_enabled=!v.cors_enabled,await D()}async function k(){v.use_default_frontend=!0,await D()}async function A(){if(!h.value){M(`PyMC Console is not installed. Please install it before switching.`,!1);return}v.use_default_frontend=!1,await D()}function M(e,t){c.value=e,u.value=t,setTimeout(()=>{c.value=``},5e3)}async function N(){m.value=!0,c.value=``;try{let e=await R.post(`/restart_service`,{});e.success?(M(`Service restart initiated. Page will reload...`,!0),f.value=!1,setTimeout(()=>{window.location.reload()},2e3)):M(e.error||`Failed to restart service`,!1)}catch(e){e.code===`ERR_NETWORK`||e.message?.includes(`Network error`)?(M(`Service restarting... Page will reload`,!0),f.value=!1,setTimeout(()=>{window.location.reload()},3e3)):(console.error(`Failed to restart service:`,e),M(e.message||`Failed to restart service`,!1))}finally{m.value=!1}}return e(()=>{E(),T()}),(e,t)=>(a(),C(`div`,Zo,[t[18]||=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 site identification, CORS policy and web frontend selection`)])],-1),S(`div`,Qo,[t[3]||=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`},` Site Identification `),S(`p`,{class:`text-sm text-content-secondary dark:text-content-muted`},` Customise the browser tab title and login page caption `)])],-1),S(`div`,$o,[S(`div`,null,[t[1]||=S(`label`,{for:`site-name`,class:`block text-sm font-medium text-content-primary dark:text-content-primary mb-2`},` Site Name `,-1),i(S(`input`,{id:`site-name`,"onUpdate:modelValue":t[0]||=e=>v.site_name=e,type:`text`,maxlength:`80`,placeholder:`e.g. Base Station Alpha`,class:`w-full px-3 py-2 rounded-lg bg-background-mute dark:bg-background/40 border border-stroke-subtle dark:border-stroke/20 text-sm text-content-primary dark:text-content-primary placeholder-gray-400 dark:placeholder-white/30 focus:outline-none focus:border-primary/50 transition-colors`,onChange:D,disabled:r.value},null,40,es),[[j,v.site_name]]),t[2]||=S(`p`,{class:`text-xs text-content-secondary dark:text-content-muted mt-1.5`},` Shown in the browser tab and above the login form. Leave blank to use the default title. `,-1)])])]),S(`div`,ts,[t[5]||=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`,ns,[S(`div`,rs,[t[4]||=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:O,disabled:r.value,class:p([`relative inline-flex h-6 w-11 items-center rounded-full transition-colors border-2`,v.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`,r.value?`opacity-50 cursor-not-allowed`:`cursor-pointer`])},[S(`span`,{class:p([`inline-block h-4 w-4 transform rounded-full bg-white transition-transform shadow-lg`,v.cors_enabled?`translate-x-5`:`translate-x-0.5`])},null,2)],10,is)])])]),S(`div`,as,[t[15]||=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`,os,[S(`div`,ss,[S(`label`,{class:p([`flex items-start space-x-3 p-4 bg-background-mute dark:bg-background/30 rounded-lg border-2 cursor-pointer transition-all`,v.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:v.use_default_frontend,onChange:k,disabled:r.value,class:`mt-1 h-4 w-4 text-accent-cyan focus:ring-accent-cyan focus:ring-offset-background`},null,40,cs),t[6]||=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 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:p([`flex items-start space-x-3 p-4 bg-background-mute dark:bg-background/30 rounded-lg border-2 transition-all`,h.value?`cursor-pointer`:`opacity-50 cursor-not-allowed`,v.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:!v.use_default_frontend,onChange:A,disabled:r.value||!h.value,class:`mt-1 h-4 w-4 text-accent-cyan focus:ring-accent-cyan focus:ring-offset-background`},null,40,ls),t[7]||=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 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)]),g.value?_(``,!0):(a(),C(`div`,{key:0,class:p([`p-4 rounded-lg border`,h.value?`bg-green-500/5 border-green-500/20`:`bg-accent-cyan/5 border-accent-cyan/20`])},[S(`div`,us,[h.value?(a(),C(`svg`,ds,[...t[8]||=[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)]])):(a(),C(`svg`,fs,[...t[9]||=[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`,ps,[S(`h4`,ms,l(h.value?`PyMC Console has been detected`:`PyMC Console Not Installed`),1),h.value?(a(),C(`p`,hs,[...t[10]||=[b(` PyMC Console is installed at `,-1),S(`code`,{class:`text-green-700 dark:text-green-300`},`/opt/pymc_console/web/html`,-1)]])):(a(),C(x,{key:1},[t[11]||=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)),f.value?(a(),C(`div`,gs,[S(`div`,_s,[t[14]||=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:N,disabled:m.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`},[m.value?(a(),C(`svg`,ys,[...t[12]||=[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)]])):(a(),C(`svg`,bs,[...t[13]||=[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(` `+l(m.value?`Restarting...`:`Restart Now`),1)],8,vs)])])):_(``,!0)])]),c.value?(a(),C(`div`,{key:0,class:p([`p-4 rounded-lg border`,w.value])},[S(`div`,xs,[u.value?(a(),C(`svg`,Ss,[...t[16]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M5 13l4 4L19 7`},null,-1)]])):(a(),C(`svg`,Cs,[...t[17]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M6 18L18 6M6 6l12 12`},null,-1)]])),S(`span`,{class:p(u.value?`text-green-600 dark:text-green-400`:`text-red-600 dark:text-red-400`)},l(c.value),3)])],2)):_(``,!0)]))}}),Ts={ref:`rootEl`,class:`space-y-12`},Es={class:`cfg-page-heading flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},Ds={class:`flex items-center gap-2 flex-shrink-0`},Os=[`disabled`],ks=[`disabled`],As={key:0,class:`bg-accent-green/20 border border-accent-green/50 rounded-lg p-3 text-accent-green text-sm`},js={key:1,class:`bg-accent-red/20 border border-accent-red/50 rounded-lg p-3 text-accent-red text-sm`},Ms={class:`cfg-section space-y-3`},Ns={key:0,class:`flex items-center justify-center py-4`},Ps={key:1,class:`text-center py-4`},Fs={class:`grid grid-cols-2 sm:grid-cols-4 gap-3`},Is={class:`text-center p-2 bg-white dark:bg-white/5 rounded-lg border border-stroke-subtle dark:border-white/10`},Ls={class:`text-center p-2 bg-white dark:bg-white/5 rounded-lg border border-stroke-subtle dark:border-white/10`},Rs={class:`text-lg font-mono text-content-primary dark:text-content-primary`},zs={class:`text-center p-2 bg-white dark:bg-white/5 rounded-lg border border-stroke-subtle dark:border-white/10`},Bs={class:`text-lg font-mono text-accent-green`},Vs={class:`text-center p-2 bg-white dark:bg-white/5 rounded-lg border border-stroke-subtle dark:border-white/10`},Hs={class:`text-lg font-mono text-accent-red`},Us={key:0,class:`mt-2 p-2 bg-accent-red/10 rounded-lg border border-accent-red/20`},Ws={key:1,class:`mt-2 p-2 bg-secondary/10 rounded-lg border border-secondary/20`},Gs={class:`font-medium`},Ks={class:`font-mono text-[10px] opacity-70`},qs={class:`text-[10px]`},Js={class:`cfg-section space-y-3`},Ys={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`},Xs={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},Zs={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`},Qs={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},$s={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`},ec={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},tc={key:1,class:`flex items-center gap-2`},nc={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 gap-1`},rc={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},ic={key:1,class:`flex items-center gap-2`},ac={class:`cfg-section space-y-3`},oc={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`},sc={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},cc={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`},lc={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},uc={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`},dc={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},fc={key:1,class:`flex items-center gap-2`},pc={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`},mc={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},hc={key:1,class:`flex items-center gap-2`},gc={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 gap-1`},_c={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},vc={key:1,class:`flex items-center gap-2`},yc={class:`cfg-section space-y-3`},bc={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`},xc={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},Sc={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`},Cc={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},wc={key:1,class:`flex items-center gap-2`},Tc={class:`py-2`},Ec={class:`grid grid-cols-3 gap-2 mt-2`},Dc={class:`text-center p-2 bg-white dark:bg-white/5 rounded-lg border border-stroke-subtle dark:border-white/10`},Oc={key:0,class:`font-mono text-sm text-content-primary dark:text-content-primary`},kc={class:`text-center p-2 bg-white dark:bg-white/5 rounded-lg border border-stroke-subtle dark:border-white/10`},Ac={key:0,class:`font-mono text-sm text-content-primary dark:text-content-primary`},jc={class:`text-center p-2 bg-white dark:bg-white/5 rounded-lg border border-stroke-subtle dark:border-white/10`},Mc={key:0,class:`font-mono text-sm text-content-primary dark:text-content-primary`},Nc={class:`p-6 space-y-4`},Pc={class:`flex justify-between items-start`},Fc={class:`flex justify-end pt-4 border-t border-stroke-subtle dark:border-stroke/20`},Ic=f({__name:`AdvertSettings`,setup(n,{expose:r}){let s=ee(),u=y(()=>s.stats?.config?.repeater||{}),f=y(()=>u.value.advert_rate_limit||{}),m=y(()=>u.value.advert_penalty_box||{}),g=y(()=>u.value.advert_adaptive||{}),w=y(()=>g.value.thresholds||{}),T=o(!1),O=o(!1),k=o(``),M=o(``),N=o(!1),P=o(!1),F=o(null),I=o(!0),L=o(2),z=o(1),B=o(10),V=o(60),H=o(!0),U=o(2),G=o(12),K=o(6),te=o(2),q=o(24),ne=o(!0),re=o(.1),ie=o(5),J=o(.05),Y=o(.2),X=o(.5),Z=async()=>{P.value=!0;try{let e=await R.get(`/advert_rate_limit_stats`);e.success&&(F.value=e.data)}catch(e){console.error(`Failed to fetch rate limit stats:`,e)}finally{P.value=!1}};h([f,m,g],()=>{T.value||(I.value=f.value.enabled??!1,L.value=f.value.bucket_capacity??2,z.value=f.value.refill_tokens??1,B.value=Math.round((f.value.refill_interval_seconds??36e3)/3600),V.value=Math.round((f.value.min_interval_seconds??0)/60),H.value=m.value.enabled??!1,U.value=m.value.violation_threshold??2,G.value=Math.round((m.value.violation_decay_seconds??43200)/3600),K.value=Math.round((m.value.base_penalty_seconds??21600)/3600),te.value=m.value.penalty_multiplier??2,q.value=Math.round((m.value.max_penalty_seconds??86400)/3600),ne.value=g.value.enabled??!1,re.value=g.value.ewma_alpha??.1,ie.value=Math.round((g.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}),e(()=>{Z()});let Q=()=>{I.value=f.value.enabled??!1,L.value=f.value.bucket_capacity??2,z.value=f.value.refill_tokens??1,B.value=Math.round((f.value.refill_interval_seconds??36e3)/3600),V.value=Math.round((f.value.min_interval_seconds??0)/60),H.value=m.value.enabled??!1,U.value=m.value.violation_threshold??2,G.value=Math.round((m.value.violation_decay_seconds??43200)/3600),K.value=Math.round((m.value.base_penalty_seconds??21600)/3600),te.value=m.value.penalty_multiplier??2,q.value=Math.round((m.value.max_penalty_seconds??86400)/3600),ne.value=g.value.enabled??!1,re.value=g.value.ewma_alpha??.1,ie.value=Math.round((g.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=()=>{T.value=!0,k.value=``,M.value=``},oe=()=>{T.value=!1,k.value=``,M.value=``,Q()},se=async()=>{O.value=!0,M.value=``,k.value=``;try{let e={rate_limit_enabled:I.value,bucket_capacity:L.value,refill_tokens:z.value,refill_interval_seconds:B.value*3600,min_interval_seconds:V.value*60,penalty_enabled:H.value,violation_threshold:U.value,violation_decay_seconds:G.value*3600,base_penalty_seconds:K.value*3600,penalty_multiplier:te.value,max_penalty_seconds:q.value*3600,adaptive_enabled:ne.value,ewma_alpha:re.value,hysteresis_seconds:ie.value*60,quiet_max:J.value,normal_max:Y.value,busy_max:X.value},t=await R.post(`/update_advert_rate_limit_config`,e),n=t.data;t.success?(k.value=n?.message||`Settings saved successfully`,await s.fetchStats(),await Z(),await E(),Q(),T.value=!1,setTimeout(()=>{k.value=``},3e3)):(M.value=n?.error||`Failed to save settings`,console.error(`[AdvertSettings] Save failed:`,n?.error))}catch(e){console.error(`Failed to save advert settings:`,e),M.value=e.response?.data?.error||`Failed to save settings`}finally{O.value=!1}},{showUnsavedModal:$,requestLeave:ce,handleDiscard:le,handleSave:ue,handleCancel:de}=pe(T,O,oe,async()=>(await se(),!T.value));r({requestLeave:ce,isEditing:T});let me=y(()=>F.value?.adaptive?.current_tier||`unknown`),he=y(()=>{switch(me.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)=>(a(),C(x,null,[v(fe,{show:c($),"is-saving":O.value,label:`Advert Limit settings`,onDiscard:c(le),onSave:c(ue),onCancel:c(de)},null,8,[`show`,`is-saving`,`onDiscard`,`onSave`,`onCancel`]),S(`div`,Ts,[S(`div`,Es,[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`,Ds,[S(`button`,{onClick:n[0]||=e=>N.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)]]),T.value?(a(),C(x,{key:1},[S(`button`,{onClick:oe,disabled:O.value,class:`cfg-btn-secondary`},` Cancel `,8,Os),S(`button`,{onClick:se,disabled:O.value,class:`cfg-btn-primary`},l(O.value?`Saving...`:`Save Changes`),9,ks)],64)):(a(),C(`button`,{key:0,onClick:ae,class:`cfg-btn-primary`},` Edit Settings `))])]),k.value?(a(),C(`div`,As,l(k.value),1)):_(``,!0),M.value?(a(),C(`div`,js,l(M.value),1)):_(``,!0),S(`div`,Ms,[n[29]||=S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary`},` Current Status `,-1),P.value&&!F.value?(a(),C(`div`,Ns,[v(W,{size:`sm`}),n[21]||=S(`span`,{class:`ml-2 text-sm text-content-muted`},`Loading stats...`,-1)])):F.value?(a(),C(x,{key:2},[S(`div`,Fs,[S(`div`,Is,[n[23]||=S(`div`,{class:`text-xs text-content-muted dark:text-content-muted`},`Mesh Tier`,-1),S(`div`,{class:p([`mt-1 px-2 py-0.5 rounded border text-xs font-medium inline-block`,he.value])},l(me.value.toUpperCase()),3)]),S(`div`,Ls,[n[24]||=S(`div`,{class:`text-xs text-content-muted dark:text-content-muted`},`Adverts/min`,-1),S(`div`,Rs,l(F.value.metrics?.adverts_per_min_ewma?.toFixed(2)||`0.00`),1)]),S(`div`,zs,[n[25]||=S(`div`,{class:`text-xs text-content-muted dark:text-content-muted`},`Allowed`,-1),S(`div`,Bs,l(F.value.stats?.adverts_allowed||0),1)]),S(`div`,Vs,[n[26]||=S(`div`,{class:`text-xs text-content-muted dark:text-content-muted`},`Dropped`,-1),S(`div`,Hs,l(F.value.stats?.adverts_dropped||0),1)])]),Object.keys(F.value.active_penalties||{}).length>0?(a(),C(`div`,Us,[n[27]||=S(`div`,{class:`text-xs font-medium text-accent-red mb-1`},` Active Penalties `,-1),(a(!0),C(x,null,t(F.value.active_penalties,(e,t)=>(a(),C(`div`,{key:t,class:`text-xs font-mono text-accent-red`},l(t)+`... - `+l(Math.round(e))+`s remaining `,1))),128))])):_(``,!0),F.value.recent_drops&&F.value.recent_drops.length>0?(a(),C(`div`,Ws,[n[28]||=S(`div`,{class:`text-xs font-medium text-secondary mb-1`},` Recently Dropped Adverts `,-1),(a(!0),C(x,null,t(F.value.recent_drops,(e,t)=>(a(),C(`div`,{key:t,class:`text-xs text-secondary py-0.5`},[S(`span`,Gs,l(e.name),1),S(`span`,Ks,`(`+l(e.pubkey)+`...)`,1),S(`span`,qs,` - `+l(e.reason)+` (`+l(e.seconds_ago)+`s ago)`,1)]))),128))])):_(``,!0)],64)):(a(),C(`div`,Ps,[...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`,Js,[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`,Ys,[n[32]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Rate Limiting`,-1),T.value?i((a(),C(`select`,{key:1,"onUpdate:modelValue":n[1]||=e=>I.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)),[[D,I.value]]):(a(),C(`div`,Xs,l(I.value?`Enabled`:`Disabled`),1))]),S(`div`,Zs,[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),T.value?i((a(),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)),[[j,L.value,void 0,{number:!0}]]):(a(),C(`div`,Qs,l(L.value),1))]),S(`div`,$s,[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),T.value?(a(),C(`div`,tc,[i(S(`input`,{"onUpdate:modelValue":n[3]||=e=>B.value=e,type:`number`,min:`1`,max:`48`,class:`cfg-input w-20`},null,512),[[j,B.value,void 0,{number:!0}]]),n[34]||=S(`span`,{class:`text-content-muted text-sm`},`hours`,-1)])):(a(),C(`div`,ec,l(B.value)+` hours `,1))]),S(`div`,nc,[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),T.value?(a(),C(`div`,ic,[i(S(`input`,{"onUpdate:modelValue":n[4]||=e=>V.value=e,type:`number`,min:`0`,max:`1440`,class:`cfg-input w-20`},null,512),[[j,V.value,void 0,{number:!0}]]),n[36]||=S(`span`,{class:`text-content-muted text-sm`},`min`,-1)])):(a(),C(`div`,rc,l(V.value)+` min `,1))])]),S(`div`,ac,[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`,oc,[n[41]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Penalty Box`,-1),T.value?i((a(),C(`select`,{key:1,"onUpdate:modelValue":n[5]||=e=>H.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)),[[D,H.value]]):(a(),C(`div`,sc,l(H.value?`Enabled`:`Disabled`),1))]),S(`div`,cc,[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),T.value?i((a(),C(`input`,{key:1,"onUpdate:modelValue":n[6]||=e=>U.value=e,type:`number`,min:`1`,max:`10`,class:`cfg-input w-full sm:w-24`},null,512)),[[j,U.value,void 0,{number:!0}]]):(a(),C(`div`,lc,l(U.value),1))]),S(`div`,uc,[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),T.value?(a(),C(`div`,fc,[i(S(`input`,{"onUpdate:modelValue":n[7]||=e=>K.value=e,type:`number`,min:`1`,max:`48`,class:`cfg-input w-20`},null,512),[[j,K.value,void 0,{number:!0}]]),n[43]||=S(`span`,{class:`text-content-muted text-sm`},`hours`,-1)])):(a(),C(`div`,dc,l(K.value)+` hours `,1))]),S(`div`,pc,[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),T.value?(a(),C(`div`,hc,[i(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),[[j,te.value,void 0,{number:!0}]]),n[45]||=S(`span`,{class:`text-content-muted text-sm`},`x`,-1)])):(a(),C(`div`,mc,l(te.value)+`x `,1))]),S(`div`,gc,[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),T.value?(a(),C(`div`,vc,[i(S(`input`,{"onUpdate:modelValue":n[9]||=e=>q.value=e,type:`number`,min:`1`,max:`168`,class:`cfg-input w-20`},null,512),[[j,q.value,void 0,{number:!0}]]),n[47]||=S(`span`,{class:`text-content-muted text-sm`},`hours`,-1)])):(a(),C(`div`,_c,l(q.value)+` hours `,1))])]),S(`div`,yc,[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`,bc,[n[52]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Adaptive Mode`,-1),T.value?i((a(),C(`select`,{key:1,"onUpdate:modelValue":n[10]||=e=>ne.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)),[[D,ne.value]]):(a(),C(`div`,xc,l(ne.value?`Enabled`:`Disabled`),1))]),S(`div`,Sc,[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),T.value?(a(),C(`div`,wc,[i(S(`input`,{"onUpdate:modelValue":n[11]||=e=>ie.value=e,type:`number`,min:`0`,max:`60`,class:`cfg-input w-20`},null,512),[[j,ie.value,void 0,{number:!0}]]),n[53]||=S(`span`,{class:`text-content-muted text-sm`},`min`,-1)])):(a(),C(`div`,Cc,l(ie.value)+` min `,1))]),S(`div`,Tc,[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`,Ec,[S(`div`,Dc,[n[55]||=S(`div`,{class:`text-xs text-accent-green mb-1`},`Quiet Max`,-1),T.value?i((a(),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)),[[j,J.value,void 0,{number:!0}]]):(a(),C(`div`,Oc,l(J.value),1))]),S(`div`,kc,[n[56]||=S(`div`,{class:`text-xs text-accent-cyan mb-1`},`Normal Max`,-1),T.value?i((a(),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)),[[j,Y.value,void 0,{number:!0}]]):(a(),C(`div`,Ac,l(Y.value),1))]),S(`div`,jc,[n[57]||=S(`div`,{class:`text-xs text-secondary mb-1`},`Busy Max`,-1),T.value?i((a(),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)),[[j,X.value,void 0,{number:!0}]]):(a(),C(`div`,Mc,l(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)])]),N.value?(a(),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]||=A(e=>N.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]||=A(()=>{},[`stop`])},[S(`div`,Nc,[S(`div`,Pc,[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=>N.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 < 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 > 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`,Fc,[S(`button`,{onClick:n[16]||=e=>N.value=!1,class:`btn-primary`},` Got it! `)])])])])):_(``,!0)],512)],64))}}),Lc={class:`modal-card max-w-2xl w-full max-h-[90vh] overflow-y-auto`},Rc={class:`flex items-center justify-between mb-7`},zc={class:`text-xl font-semibold text-content-primary dark:text-content-primary`},Bc={class:`text-content-secondary dark:text-content-muted text-sm mt-1`},Vc={class:`grid grid-cols-2 gap-5 items-end`},Hc={class:`flex items-center gap-3 pb-1.5`},Uc={key:0,class:`grid grid-cols-2 gap-5`},Wc={class:`grid grid-cols-2 gap-5 items-end`},Gc={class:`flex items-center gap-3 pb-1.5`},Kc={class:`grid grid-cols-2 gap-x-5 gap-y-0`},qc=[`aria-hidden`],Jc={class:`grid grid-cols-2 gap-5 items-center pt-4`},Yc={class:`flex items-center gap-3`},Xc={class:`flex items-center gap-6`},Zc={class:`flex items-center gap-3`},Qc={class:`flex items-center gap-3`},$c={class:`flex flex-wrap gap-2`},el=[`onClick`],tl={class:`modal-actions`},nl=[`disabled`],rl=f({__name:`BrokerEditModal`,props:{show:{type:Boolean},broker:{},isNew:{type:Boolean}},emits:[`done`,`cancel`],setup(e,{emit:n}){let s=[`REQ`,`RESPONSE`,`TXT_MSG`,`ACK`,`ADVERT`,`GRP_TXT`,`GRP_DATA`,`ANON_REQ`,`PATH`,`TRACE`,`RAW_CUSTOM`],c=e,d=n;function f(e){return{...e,tls:{...e.tls},disallowedInput:[...e.disallowedInput??[]]}}let g=o({_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}});h(()=>c.broker,e=>{e&&(g.value=f(e))},{immediate:!0});let w=y(()=>{let e=g.value;return e.name.trim()!==``&&e.host.trim()!==``&&e.port>=1&&e.port<=65535&&(!e.use_jwt_auth||(e.audience?.trim()??``)!==``)});function T(){let e=g.value;(!e.audience||e.audience===e.host)&&(e.audience=e.host)}function E(e){g.value.disallowedInput||(g.value.disallowedInput=[]);let t=g.value.disallowedInput.indexOf(e);t===-1?g.value.disallowedInput.push(e):g.value.disallowedInput.splice(t,1)}function O(){w.value&&d(`done`,f(g.value))}function k(){d(`cancel`)}return(n,o)=>(a(),u(m,{to:`body`},[v(N,{"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:r(()=>[e.show&&e.broker?(a(),C(`div`,{key:0,class:`modal-backdrop`,onClick:o[14]||=A(e=>k(),[`self`])},[S(`div`,Lc,[S(`div`,Rc,[S(`div`,null,[S(`h3`,zc,l(e.isNew?`Add Broker`:`Edit Broker`),1),S(`p`,Bc,l(e.isNew?`Configure a new MQTT broker`:`Editing ${e.broker.name||`(unnamed)`}`),1)]),S(`button`,{onClick:k,class:`text-content-secondary dark:text-white/60 hover:text-content-primary dark:hover:text-white transition-colors`},[...o[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:A(O,[`prevent`]),class:`modal-form`},[S(`div`,null,[o[16]||=S(`label`,{class:`modal-field-label`},[b(` Name `),S(`span`,{class:`text-red-500`},`*`)],-1),i(S(`input`,{"onUpdate:modelValue":o[0]||=e=>g.value.name=e,type:`text`,placeholder:`Broker Name`,class:`modal-input`},null,512),[[j,g.value.name]])]),S(`div`,Vc,[S(`div`,null,[o[18]||=S(`label`,{class:`modal-field-label`},[b(` Format `),S(`span`,{class:`text-red-500`},`*`)],-1),i(S(`select`,{"onUpdate:modelValue":o[1]||=e=>g.value.format=e,class:`modal-select`},[...o[17]||=[S(`option`,{value:`meshcoretomqtt`},`Meshcoretomqtt`,-1),S(`option`,{value:`letsmesh`},`Letsmesh`,-1),S(`option`,{value:`waev`},`Waev`,-1),S(`option`,{value:`mqtt`},`pyMC`,-1)]],512),[[D,g.value.format]])]),S(`div`,Hc,[S(`button`,{type:`button`,onClick:o[2]||=e=>g.value.enabled=!g.value.enabled,class:p([`relative inline-flex h-5 w-9 flex-shrink-0 cursor-pointer rounded-full transition-colors duration-200 ease-in-out focus:outline-none`,g.value.enabled?`bg-primary`:`bg-gray-200 dark:bg-white/15`])},[S(`span`,{class:p([`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`,g.value.enabled?`translate-x-4`:`translate-x-0`])},null,2)],2),o[19]||=S(`span`,{class:`text-sm font-medium text-content-primary dark:text-content-primary`},`Enabled`,-1)])]),g.value.format===`mqtt`?(a(),C(`div`,Uc,[S(`div`,null,[o[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),i(S(`input`,{"onUpdate:modelValue":o[3]||=e=>g.value.base_topic=e,placeholder:`meshcore/repeater`,class:`modal-input`},null,512),[[j,g.value.base_topic]])]),o[21]||=S(`div`,null,null,-1)])):_(``,!0),S(`div`,Wc,[S(`div`,null,[o[23]||=S(`label`,{class:`modal-field-label`},[b(` Transport `),S(`span`,{class:`text-red-500`},`*`)],-1),i(S(`select`,{"onUpdate:modelValue":o[4]||=e=>g.value.transport=e,class:`modal-select`},[...o[22]||=[S(`option`,{value:`websockets`},`Websockets`,-1),S(`option`,{value:`tcp`},`TCP`,-1)]],512),[[D,g.value.transport]])]),S(`div`,Gc,[S(`button`,{type:`button`,onClick:o[5]||=e=>g.value.use_jwt_auth=!g.value.use_jwt_auth,class:p([`relative inline-flex h-5 w-9 flex-shrink-0 cursor-pointer rounded-full transition-colors duration-200 ease-in-out focus:outline-none`,g.value.use_jwt_auth?`bg-primary`:`bg-gray-200 dark:bg-white/15`])},[S(`span`,{class:p([`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`,g.value.use_jwt_auth?`translate-x-4`:`translate-x-0`])},null,2)],2),o[24]||=S(`span`,{class:`text-sm font-medium text-content-primary dark:text-content-primary`},`Use JWT Auth`,-1)])]),S(`div`,Kc,[S(`div`,null,[o[25]||=S(`label`,{class:`modal-field-label`},[b(` Host `),S(`span`,{class:`text-red-500`},`*`)],-1),i(S(`input`,{"onUpdate:modelValue":o[6]||=e=>g.value.host=e,type:`text`,placeholder:`mqtt.myserver.com`,onBlur:T,class:`modal-input font-mono`},null,544),[[j,g.value.host]])]),S(`div`,null,[g.value.use_jwt_auth?(a(),C(x,{key:0},[o[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),i(S(`input`,{"onUpdate:modelValue":o[7]||=e=>g.value.audience=e,type:`text`,placeholder:`mqtt.myserver.com`,class:`modal-input font-mono`},null,512),[[j,g.value.audience]])],64)):(a(),C(x,{key:1},[o[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),o[28]||=S(`input`,{type:`text`,autocomplete:`username`,style:{display:`none`}},null,-1),i(S(`input`,{autocomplete:`username`,"onUpdate:modelValue":o[8]||=e=>g.value.username=e,type:`text`,placeholder:`username`,class:`modal-input`},null,512),[[j,g.value.username]])],64))]),S(`div`,null,[o[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),i(S(`input`,{"onUpdate:modelValue":o[9]||=e=>g.value.port=e,type:`number`,min:`0`,max:`65535`,class:`modal-input font-mono`},null,512),[[j,g.value.port,void 0,{number:!0}]])]),S(`div`,{class:p(g.value.use_jwt_auth?`invisible pointer-events-none`:``),"aria-hidden":g.value.use_jwt_auth?`true`:void 0},[o[30]||=S(`label`,{class:`modal-field-label`},`Password`,-1),o[31]||=S(`input`,{type:`password`,autocomplete:`current-password`,style:{display:`none`}},null,-1),i(S(`input`,{autocomplete:`new-password`,"onUpdate:modelValue":o[10]||=e=>g.value.password=e,type:`password`,readonly:``,onfocus:`this.removeAttribute('readonly');`,onblur:`this.setAttribute('readonly', true);`,class:`modal-input`},null,512),[[j,g.value.password]])],10,qc)]),S(`div`,Jc,[S(`div`,Yc,[S(`button`,{type:`button`,onClick:o[11]||=e=>g.value.retain_status=!g.value.retain_status,class:p([`relative inline-flex h-5 w-9 flex-shrink-0 cursor-pointer rounded-full transition-colors duration-200 ease-in-out focus:outline-none`,g.value.retain_status?`bg-primary`:`bg-gray-200 dark:bg-white/15`])},[S(`span`,{class:p([`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`,g.value.retain_status?`translate-x-4`:`translate-x-0`])},null,2)],2),o[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`,Xc,[S(`div`,Zc,[S(`button`,{type:`button`,onClick:o[12]||=e=>g.value.tls.enabled=!g.value.tls.enabled,class:p([`relative inline-flex h-5 w-9 flex-shrink-0 cursor-pointer rounded-full transition-colors duration-200 ease-in-out focus:outline-none`,g.value.tls.enabled?`bg-primary`:`bg-gray-200 dark:bg-white/15`])},[S(`span`,{class:p([`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`,g.value.tls.enabled?`translate-x-4`:`translate-x-0`])},null,2)],2),o[33]||=S(`span`,{class:`text-sm font-medium text-content-primary dark:text-content-primary`},`TLS`,-1)]),S(`div`,Qc,[S(`button`,{type:`button`,onClick:o[13]||=e=>g.value.tls.insecure=!g.value.tls.insecure,class:p([`relative inline-flex h-5 w-9 flex-shrink-0 cursor-pointer rounded-full transition-colors duration-200 ease-in-out focus:outline-none`,g.value.tls.insecure?`bg-amber-500`:`bg-gray-200 dark:bg-white/15`])},[S(`span`,{class:p([`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`,g.value.tls.insecure?`translate-x-4`:`translate-x-0`])},null,2)],2),o[34]||=S(`span`,{class:`text-sm font-medium text-content-primary dark:text-content-primary`},`Insecure`,-1)])])]),S(`div`,null,[o[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`,$c,[(a(),C(x,null,t(s,e=>S(`button`,{key:e,type:`button`,onClick:t=>E(e),class:p([`px-2.5 py-1 rounded text-xs font-mono font-medium border transition-colors`,g.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`])},l(e),11,el)),64))]),o[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`,tl,[S(`button`,{type:`button`,onClick:k,class:`modal-btn-cancel`},` Cancel `),S(`button`,{type:`submit`,disabled:!w.value,class:p([`flex-1 px-4 py-3 rounded-lg transition-colors font-medium`,w.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,nl)])],32)])])):_(``,!0)]),_:1})]))}}),il={class:`space-y-12`},al={class:`cfg-page-heading flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},ol={class:`flex items-center gap-2 flex-shrink-0`},sl=[`disabled`],cl=[`disabled`],ll={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`},ul={class:`cfg-section`},dl={key:0,class:`text-sm text-content-secondary dark:text-content-muted`},fl={key:1,class:`space-y-3`},pl={class:`flex items-center gap-2`},ml={key:0,class:`space-y-2`},hl=[`title`],gl={key:1,class:`text-sm text-content-muted dark:text-content-muted/60 italic`},_l={class:`cfg-card p-6`},vl={key:0,class:`grid grid-cols-1 sm:grid-cols-2 gap-x-8 gap-y-3`},yl={class:`flex flex-col py-1 border-b border-stroke-subtle dark:border-stroke/10`},bl={class:`text-content-primary dark:text-content-primary font-mono text-sm mt-0.5`},xl={class:`flex flex-col py-1 border-b border-stroke-subtle dark:border-stroke/10`},Sl={class:`text-content-primary dark:text-content-primary text-sm mt-0.5`},Cl={class:`flex flex-col py-1`},wl={class:`text-content-primary dark:text-content-primary text-sm mt-0.5`},Tl={class:`flex flex-col py-1`},El={class:`text-content-primary dark:text-content-primary text-sm mt-0.5`},Dl={key:1,class:`space-y-3`},Ol={class:`grid grid-cols-1 sm:grid-cols-2 gap-3`},kl={class:`cfg-card p-6`},Al={class:`flex items-start justify-between mb-4`},jl={key:0,class:`flex items-center gap-2 flex-shrink-0 ml-4`},Ml={class:`relative`},Nl={key:0,class:`absolute right-0 top-full mt-1 z-20 w-72 rounded-lg shadow-lg border border-stroke-subtle dark:border-stroke/20 bg-white dark:bg-[var(--color-surface)] overflow-hidden`},Pl={key:0,class:`px-3 py-3 text-xs text-content-secondary dark:text-content-muted italic`},Fl={key:1,class:`px-3 py-3 text-xs text-red-600 dark:text-red-400`},Il={key:2,class:`px-3 py-3 text-xs text-content-secondary dark:text-content-muted italic`},Ll={key:3,class:`py-1`},Rl=[`onClick`],zl={class:`min-w-0 flex-1`},Bl={class:`text-sm font-medium text-content-primary dark:text-content-primary group-hover:text-primary transition-colors`},Vl={class:`text-xs text-content-secondary dark:text-content-muted`},Hl=[`onClick`,`title`],Ul=[`href`],Wl={key:0,class:`bg-background-mute/40 dark:bg-background/20 border-t border-stroke-subtle dark:border-stroke/10`},Gl=[`onClick`],Kl={class:`min-w-0 flex-1`},ql={class:`text-xs font-medium text-content-primary dark:text-content-primary truncate`},Jl={class:`text-[11px] font-mono text-content-secondary dark:text-content-muted truncate`},Yl={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`},Xl={key:0,class:`text-xs mt-0.5 opacity-70`},Zl={key:1,class:`space-y-2`},Ql={class:`flex items-center gap-3 px-4 py-2.5`},$l={class:`min-w-0 flex-1 flex items-center gap-2 flex-wrap`},eu={class:`text-sm font-medium text-content-primary dark:text-content-primary`},tu={class:`text-xs font-mono text-content-secondary dark:text-content-muted`},nu={key:0,class:`flex items-center gap-1.5 flex-shrink-0`},ru=[`onClick`],iu=[`onClick`],au=K(f({__name:`LetsMeshSettings`,setup(n,{expose:s}){let u=ee(),d=y(()=>u.stats?.config?.mqtt_brokers||{}),f=o([]),m=o(!1),g=o(``),T=o(null);function E(e){return{...e,tls:{...e.tls},disallowedInput:[...e.disallowedInput??[]]}}let D=o(!1),O=o(!1),k=o(``),M=o(!1),P=o(null),F=o(!1),I=o(``),L=o(300),z=o(``),B=o(``),V=o([]),H=o(null),U=o(!1),W=o(null),G=o({_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}}),K=o(!1),q=o(null),ne=o(!1);async function re(){if(!ne.value){ne.value=!0;try{let e=await R.get(`/mqtt_status`);e.success&&(q.value=e.data)}catch{}finally{ne.value=!1}}}let ie=1;function J(e={}){return{_id:ie++,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 Y(){let e=d.value;I.value=e.iata_code??``,L.value=e.status_interval??300,z.value=e.owner??``,B.value=e.email??``,V.value=Array.isArray(e.brokers)?e.brokers.map(e=>J(e)):[]}h(d,()=>{D.value||Y()},{immediate:!0});function X(){return{iata_code:I.value,status_interval:L.value,owner:z.value,email:B.value,brokers:V.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 Z(){try{let e=await R.post(`/update_mqtt_config`,X());return e.success?(await u.fetchStats(),await re(),{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 Q(){Y(),P.value={iata:I.value,interval:L.value,owner:z.value,email:B.value,brokers:V.value.map(E)},D.value=!0,k.value=``}function ae(){P.value&&(I.value=P.value.iata,L.value=P.value.interval,z.value=P.value.owner,B.value=P.value.email,V.value=P.value.brokers.map(E)),H.value=null,U.value=!1,W.value=null,F.value=!1,D.value=!1,P.value=null,k.value=``}async function oe(){if(H.value!==null){let e=G.value;if(!e.name.trim()||!e.host.trim()){k.value=`Please complete or cancel the open broker edit before saving.`;return}le()}O.value=!0,k.value=``;let e=await Z();O.value=!1,e.success?(D.value=!1,F.value=!1,P.value=null,M.value=!0):k.value=e.error}function se(){H.value!==null&&ce();let e=J();V.value.push(e),W.value=null,U.value=!0,G.value=E(e),H.value=e._id}function $(e){H.value!==null&&H.value!==e._id&&ce(),W.value=E(e),U.value=!1,G.value=E(e),H.value=e._id}function ce(){if(U.value&&H.value!==null)V.value=V.value.filter(e=>e._id!==H.value);else if(W.value){let e=V.value.findIndex(e=>e._id===W.value._id);e!==-1&&V.value.splice(e,1,E(W.value))}H.value=null,U.value=!1,W.value=null}function le(){let e=G.value,t=V.value.findIndex(t=>t._id===e._id);t!==-1&&V.value.splice(t,1,E(e)),H.value=null,U.value=!1,W.value=null}function ue(e){G.value=e,le()}function de(e){V.value=V.value.filter(t=>t._id!==e),H.value===e&&(H.value=null,U.value=!1,W.value=null)}function me(e){K.value=!1,T.value=null,H.value!==null&&ce(),e.brokers.forEach(e=>V.value.push(J(e)))}function he(e){K.value=!1,T.value=null,H.value!==null&&ce(),V.value.push(J(e))}function ge(e){T.value=T.value===e?null:e}async function _e(){m.value=!0,g.value=``;try{let e=await R.get(`/broker_presets`);e.success&&Array.isArray(e.data)?f.value=e.data:(f.value=[],g.value=e.error||`Failed to load broker presets`)}catch(e){f.value=[],e?.response?.status===404?g.value=``:g.value=`Could not reach repeater for broker presets`}finally{m.value=!1}}let ve=y(()=>{let e=G.value;return e.name.trim()!==``&&e.host.trim()!==``&&e.port>=1&&e.port<=65535&&(!e.use_jwt_auth||(e.audience?.trim()??``)!==``)});async function ye(){H.value!==null&&ve.value&&le(),O.value=!0,k.value=``;let e=await Z();return O.value=!1,e.success?(D.value=!1,F.value=!1,P.value=null,M.value=!0,!0):(k.value=e.error??`Save failed`,!1)}let{showUnsavedModal:be,requestLeave:xe,handleDiscard:Se,handleSave:Ce,handleCancel:we}=pe(D,O,ae,ye);s({requestLeave:xe,isEditing:D});let Te=null;return e(()=>{re(),_e(),Te=setInterval(re,5e3)}),w(()=>{Te&&clearInterval(Te)}),(e,n)=>(a(),C(x,null,[v(te,{modelValue:M.value,"onUpdate:modelValue":n[0]||=e=>M.value=e,message:`Broker settings have been saved. A service restart is required for the changes to take effect.`},null,8,[`modelValue`]),v(rl,{show:H.value!==null,broker:H.value===null?null:G.value,"is-new":U.value,onDone:ue,onCancel:ce},null,8,[`show`,`broker`,`is-new`]),v(fe,{show:c(be),"is-saving":O.value,label:`Broker settings`,onDiscard:c(Se),onSave:c(Ce),onCancel:c(we)},null,8,[`show`,`is-saving`,`onDiscard`,`onSave`,`onCancel`]),S(`div`,il,[S(`div`,al,[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`},` 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`,ol,[D.value?(a(),C(x,{key:1},[S(`button`,{onClick:ae,disabled:O.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,sl),S(`button`,{onClick:oe,disabled:O.value,class:`btn-primary`},l(O.value?`Saving…`:`Save Settings`),9,cl)],64)):(a(),C(`button`,{key:0,onClick:Q,class:`btn-primary`},` Edit Settings `))])]),k.value?(a(),C(`div`,ll,l(k.value),1)):_(``,!0),S(`div`,ul,[n[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),q.value?(a(),C(`div`,fl,[S(`div`,pl,[n[9]||=S(`span`,{class:`text-sm text-content-secondary dark:text-content-muted w-36`},`Handler`,-1),S(`span`,{class:p([`inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-medium`,q.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:p([`w-1.5 h-1.5 rounded-full`,q.value.handler_active?`bg-green-500`:`bg-gray-400`])},null,2),b(` `+l(q.value.handler_active?`Active`:`Inactive`),1)],2)]),q.value.brokers.length?(a(),C(`div`,ml,[(a(!0),C(x,null,t(q.value.brokers,e=>(a(),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},l(e.name),9,hl),S(`span`,{class:p([`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:p([`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(` `+l(e.status.connected?`Connected`:e.status.reconnecting?`Reconnecting…`:`Disconnected`),1)],2)]))),128))])):(a(),C(`div`,gl,`No broker connections configured.`))])):(a(),C(`div`,dl,` Status unavailable — service may not be running. `))]),S(`div`,_l,[n[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,[D.value?_(``,!0):(a(),C(`div`,vl,[S(`div`,yl,[n[11]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`IATA Code`,-1),S(`span`,bl,l(d.value.iata_code||`—`),1)]),S(`div`,xl,[n[12]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Status Interval`,-1),S(`span`,Sl,l(d.value.status_interval??300)+`s`,1)]),S(`div`,Cl,[n[13]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Owner`,-1),S(`span`,wl,l(d.value.owner||`—`),1)]),S(`div`,Tl,[n[14]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Email`,-1),S(`span`,El,l(d.value.email||`—`),1)])])),D.value?(a(),C(`div`,Dl,[S(`div`,Ol,[S(`div`,null,[n[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),i(S(`input`,{"onUpdate:modelValue":n[1]||=e=>I.value=e,type:`text`,maxlength:`10`,placeholder:`TEST`,class:`cfg-input font-mono`},null,512),[[j,I.value]])]),S(`div`,null,[n[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),i(S(`input`,{"onUpdate:modelValue":n[2]||=e=>L.value=e,type:`number`,min:`60`,max:`3600`,class:`cfg-input font-mono`},null,512),[[j,L.value,void 0,{number:!0}]])]),S(`div`,null,[n[17]||=S(`label`,{class:`block text-xs sm:text-sm text-content-secondary dark:text-content-muted mb-1`},`Owner Companion Pubkey`,-1),i(S(`input`,{"onUpdate:modelValue":n[3]||=e=>z.value=e,type:`text`,placeholder:`Optional`,class:`cfg-input`},null,512),[[j,z.value]])]),S(`div`,null,[n[18]||=S(`label`,{class:`block text-xs sm:text-sm text-content-secondary dark:text-content-muted mb-1`},`Email`,-1),i(S(`input`,{"onUpdate:modelValue":n[4]||=e=>B.value=e,type:`email`,placeholder:`Optional`,class:`cfg-input`},null,512),[[j,B.value]])])])])):_(``,!0)])]),S(`div`,kl,[S(`div`,Al,[n[27]||=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),D.value?(a(),C(`div`,jl,[S(`div`,Ml,[S(`button`,{onClick:n[5]||=e=>K.value=!K.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`},[n[21]||=b(` From Template `,-1),(a(),C(`svg`,{class:p([`w-3 h-3 transition-transform`,K.value?`rotate-180`:``]),fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[...n[20]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M19 9l-7 7-7-7`},null,-1)]],2))]),v(N,{name:`dropdown`},{default:r(()=>[K.value?(a(),C(`div`,Nl,[n[25]||=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),m.value?(a(),C(`div`,Pl,` Loading presets… `)):g.value?(a(),C(`div`,Fl,l(g.value),1)):f.value.length?(a(),C(`div`,Ll,[(a(!0),C(x,null,t(f.value,e=>(a(),C(`div`,{key:e.id,class:`border-b border-stroke-subtle dark:border-stroke/10 last:border-b-0`},[S(`div`,{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=>me(e)},[S(`div`,zl,[S(`p`,Bl,l(e.name),1),S(`p`,Vl,l(e.brokers.length)+` broker`+l(e.brokers.length===1?``:`s`),1)]),e.brokers.length>1?(a(),C(`button`,{key:0,onClick:A(t=>ge(e.id),[`stop`]),title:T.value===e.id?`Hide individual brokers`:`Pick individual brokers`,class:`flex-shrink-0 p-1 rounded hover:bg-primary/10 text-content-secondary dark:text-content-muted hover:text-primary transition-colors`},[(a(),C(`svg`,{class:p([`w-3.5 h-3.5 transition-transform`,T.value===e.id?`rotate-180`:``]),fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[...n[22]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M19 9l-7 7-7-7`},null,-1)]],2))],8,Hl)):_(``,!0),e.website?(a(),C(`a`,{key:1,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:n[6]||=A(()=>{},[`stop`])},[...n[23]||=[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,Ul)):_(``,!0)],8,Rl),T.value===e.id&&e.brokers.length>1?(a(),C(`div`,Wl,[(a(!0),C(x,null,t(e.brokers,(t,r)=>(a(),C(`div`,{key:`${e.id}-${r}`,class:`flex items-center gap-2 pl-6 pr-3 py-2 hover:bg-background-mute dark:hover:bg-background/30 cursor-pointer`,onClick:e=>he(t)},[S(`div`,Kl,[S(`p`,ql,l(t.name),1),S(`p`,Jl,l(t.host)+`:`+l(t.port),1)]),n[24]||=S(`span`,{class:`flex-shrink-0 inline-flex items-center justify-center w-5 h-5 rounded bg-primary/10 text-primary text-xs font-bold`,title:`Add only this broker`},`+`,-1)],8,Gl))),128))])):_(``,!0)]))),128))])):(a(),C(`div`,Il,` No bundled presets. Use "Add" to configure manually. `))])):_(``,!0)]),_:1}),K.value?(a(),C(`div`,{key:0,class:`fixed inset-0 z-10`,onClick:n[7]||=e=>K.value=!1})):_(``,!0)]),S(`button`,{onClick:se,class:`btn-primary inline-flex items-center gap-1.5`},[...n[26]||=[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)]])])):_(``,!0)]),V.value.length?(a(),C(`div`,Zl,[(a(!0),C(x,null,t(V.value,e=>(a(),C(`div`,{key:e._id,class:`cfg-card overflow-hidden`},[S(`div`,Ql,[S(`div`,$l,[S(`span`,{class:p([`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:p([`w-1.5 h-1.5 rounded-full`,e.enabled?`bg-green-500`:`bg-red-500`])},null,2),b(` `+l(e.enabled?`Enabled`:`Disabled`),1)],2),S(`span`,eu,l(e.name||`(unnamed)`),1),S(`span`,tu,l(e.host||`—`)+`:`+l(e.port),1)]),D.value?(a(),C(`div`,nu,[S(`button`,{onClick:t=>$(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,ru),S(`button`,{onClick:t=>de(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`},[...n[30]||=[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,iu)])):_(``,!0)])]))),128))])):(a(),C(`div`,Yl,[n[28]||=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),n[29]||=S(`p`,{class:`text-sm`},`No brokers configured`,-1),D.value?(a(),C(`p`,Xl,`Use Add or From Template above`)):_(``,!0)]))])])],64))}}),[[`__scopeId`,`data-v-45cb296d`]]),ou={class:`space-y-12`},su={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`},cu={class:`cfg-section`},lu=[`disabled`],uu={key:0,class:`flex items-center gap-2`},du={key:1,class:`flex items-center gap-2`},fu={key:0,class:`text-xs text-green-600 dark:text-green-400 mt-2`},pu={key:1,class:`text-xs text-red-500 dark:text-red-400 mt-2`},mu={class:`cfg-section`},hu={key:0},gu={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`},_u={class:`flex items-start gap-3`},vu={class:`flex-1`},yu={class:`text-xs text-red-600 dark:text-red-400/80 mt-1`},bu={class:`flex gap-2 mt-3`},xu=[`disabled`],Su=[`disabled`],Cu={key:2,class:`text-xs text-green-600 dark:text-green-400 mt-2`},wu={key:3,class:`text-xs text-red-500 dark:text-red-400 mt-2`},Tu={class:`cfg-section`},Eu={class:`space-y-3`},Du={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`},Ou={class:`text-sm text-content-secondary dark:text-content-muted`},ku={key:0,class:`bg-background-mute dark:bg-background/30 rounded-lg p-4 border border-stroke-subtle dark:border-stroke/10`},Au={key:0,class:`text-xs text-content-secondary dark:text-content-muted space-y-1 mb-3`},ju={class:`font-mono`},Mu={class:`font-mono`},Nu={key:0,class:`text-amber-600 dark:text-amber-400 font-medium`},Pu={key:1,class:`text-content-muted`},Fu={class:`text-xs text-content-secondary dark:text-content-muted`},Iu={class:`font-mono`},Lu={key:1},Ru={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`},zu={class:`flex items-start gap-3`},Bu={class:`flex-1`},Vu={class:`text-xs text-amber-700 dark:text-amber-300/80 mt-1`},Hu={class:`flex gap-2 mt-3`},Uu=[`disabled`],Wu=[`disabled`],Gu={key:3,class:`text-xs text-green-600 dark:text-green-400 mt-2`},Ku={key:4,class:`text-xs text-red-500 dark:text-red-400 mt-2`},qu={class:`cfg-section`},Ju={key:0},Yu={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`},Xu={class:`flex items-start gap-3`},Zu={class:`flex-1`},Qu={class:`text-xs text-red-600 dark:text-red-400/80 mt-1`},$u={class:`flex gap-2 mt-3`},ed=[`disabled`],td=[`disabled`],nd={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`},rd={class:`flex items-center justify-between`},id={class:`text-xs text-content-secondary dark:text-content-muted space-y-1`},ad={class:`font-mono`},od={key:0},sd={class:`font-mono`},cd={key:1},ld={class:`font-mono text-[10px] break-all`},ud={key:3,class:`text-xs text-red-500 dark:text-red-400 mt-2`},dd=f({__name:`BackupRestore`,setup(e){let t=y(()=>window.location.protocol===`http:`),n=o(!1),r=o(``),i=o(``);async function s(){n.value=!0,r.value=``,i.value=``;try{let e=await R.exportConfig(!1);if(!e.success||!e.data){i.value=e.error||`Export failed`;return}let t=new Blob([JSON.stringify(e.data,null,2)],{type:`application/json`}),n=URL.createObjectURL(t),a=document.createElement(`a`);a.href=n,a.download=`pymc-repeater-settings-${(e.data.meta?.exported_at||new Date().toISOString()).replace(/[:.]/g,`-`)}.json`,document.body.appendChild(a),a.click(),document.body.removeChild(a),URL.revokeObjectURL(n),r.value=`Settings exported successfully (secrets redacted).`}catch(e){i.value=e instanceof Error?e.message:`Export failed`}finally{n.value=!1}}let c=o(!1),u=o(!1),f=o(``),p=o(``);async function m(){u.value=!0,f.value=``,p.value=``;try{let e=await R.exportConfig(!0);if(!e.success||!e.data){p.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),f.value=`Full backup exported (includes all secrets).`,c.value=!1}catch(e){p.value=e instanceof Error?e.message:`Export failed`}finally{u.value=!1}}let h=o(null),g=o(null),w=o(!1),T=o(!1),E=o(``),D=o(``),O=o(null),k=y(()=>g.value?.config?Object.keys(g.value.config).join(`, `):``),A=y(()=>{let e=g.value?.meta?.includes_secrets;return e===!0||e===`true`});function j(e){let t=e.target.files?.[0];if(!t)return;h.value=t,g.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`?g.value={meta:t.meta,config:t.config}:typeof t==`object`&&!Array.isArray(t)?g.value={config:t}:D.value=`Invalid file format — expected a JSON config object.`}catch{D.value=`Invalid JSON file.`}},n.readAsText(t)}function M(){w.value=!1,g.value=null,h.value=null,O.value&&(O.value.value=``)}async function N(){if(g.value?.config){T.value=!0,E.value=``,D.value=``;try{let e=await R.importConfig(g.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,g.value=null,h.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 P=o(!1),F=o(!1),I=o(null),L=o(``);async function z(){F.value=!0,L.value=``;try{let e=await R.exportIdentityKey();if(!e.success||!e.data){L.value=e.error||`Export failed`;return}I.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){L.value=e instanceof Error?e.message:`Export failed`}finally{F.value=!1}}return(e,o)=>(a(),C(`div`,ou,[o[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),t.value?(a(),C(`div`,su,[...o[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)]])):_(``,!0),S(`div`,cu,[o[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:s,disabled:n.value,class:`cfg-btn-primary`},[n.value?(a(),C(`span`,uu,[v(W,{size:`sm`,color:`current`,class:`inline-block`}),o[7]||=b(` Exporting… `,-1)])):(a(),C(`span`,du,[...o[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,lu),r.value?(a(),C(`p`,fu,l(r.value),1)):_(``,!0),i.value?(a(),C(`p`,pu,l(i.value),1)):_(``,!0)]),S(`div`,mu,[o[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),c.value?_(``,!0):(a(),C(`div`,hu,[S(`button`,{onClick:o[0]||=e=>c.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`},[...o[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)]])])),c.value?(a(),C(`div`,gu,[S(`div`,_u,[o[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`,vu,[o[13]||=S(`h4`,{class:`text-sm font-semibold text-red-700 dark:text-red-400`},` Confirm Full Backup `,-1),S(`p`,yu,[o[11]||=b(` This will export `,-1),o[12]||=S(`strong`,null,`all secrets in plain text`,-1),b(` including admin/guest passwords, JWT secret, and your repeater's private identity key`+l(t.value?` over an unencrypted HTTP connection`:``)+`. `,1)]),S(`div`,bu,[S(`button`,{onClick:m,disabled:u.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`},l(u.value?`Exporting…`:`Yes, Export Full Backup`),9,xu),S(`button`,{onClick:o[1]||=e=>c.value=!1,disabled:u.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,Su)])])])])):_(``,!0),f.value?(a(),C(`p`,Cu,l(f.value),1)):_(``,!0),p.value?(a(),C(`p`,wu,l(p.value),1)):_(``,!0)]),S(`div`,Tu,[o[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`,Eu,[S(`label`,Du,[o[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`,Ou,l(h.value?h.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)]),g.value?(a(),C(`div`,ku,[o[20]||=S(`h4`,{class:`text-sm font-medium text-content-primary dark:text-content-primary mb-2`},` Import Preview `,-1),g.value.meta?(a(),C(`div`,Au,[S(`p`,null,[o[17]||=b(` Exported: `,-1),S(`span`,ju,l(g.value.meta.exported_at),1)]),S(`p`,null,[o[18]||=b(` Version: `,-1),S(`span`,Mu,l(g.value.meta.version),1)]),g.value.meta.includes_secrets===`true`||g.value.meta.includes_secrets===!0?(a(),C(`p`,Nu,` ⚠ Full backup — will restore passwords and identity keys `)):(a(),C(`p`,Pu,` Settings only — existing secrets will not be changed `))])):_(``,!0),S(`p`,Fu,[o[19]||=b(` Sections: `,-1),S(`span`,Iu,l(k.value),1)])])):_(``,!0),g.value&&!w.value?(a(),C(`div`,Lu,[S(`button`,{onClick:o[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 `)])):_(``,!0),w.value?(a(),C(`div`,Ru,[S(`div`,zu,[o[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`,Bu,[o[27]||=S(`h4`,{class:`text-sm font-semibold text-amber-800 dark:text-amber-300`},` Confirm Import `,-1),S(`p`,Vu,[o[24]||=b(` This will overwrite current settings for: `,-1),S(`strong`,null,l(k.value),1),o[25]||=b(`. `,-1),A.value?(a(),C(x,{key:0},[o[21]||=b(` This is a full backup — `,-1),o[22]||=S(`strong`,null,`passwords, JWT secrets, and identity keys will also be overwritten`,-1),o[23]||=b(`. `,-1)],64)):(a(),C(x,{key:1},[b(` Passwords and identity keys will not be changed. `)],64)),o[26]||=b(` Some changes (radio settings) require a service restart. `,-1)]),S(`div`,Hu,[S(`button`,{onClick:N,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`},l(T.value?`Importing…`:`Yes, Import`),9,Uu),S(`button`,{onClick:M,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,Wu)])])])])):_(``,!0),E.value?(a(),C(`p`,Gu,l(E.value),1)):_(``,!0),D.value?(a(),C(`p`,Ku,l(D.value),1)):_(``,!0)])]),S(`div`,qu,[o[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's private identity key for backup. This key determines the node'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's private key. Anyone with this key can impersonate your node. Store the exported file securely and never share it. </p></div>`,2),P.value?_(``,!0):(a(),C(`div`,Ju,[S(`button`,{onClick:o[3]||=e=>P.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`},[...o[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)]])])),P.value&&!I.value?(a(),C(`div`,Yu,[S(`div`,Xu,[o[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`,Zu,[o[31]||=S(`h4`,{class:`text-sm font-semibold text-red-700 dark:text-red-400`},`Are you sure?`,-1),S(`p`,Qu,` This will transmit your private key `+l(t.value?`over an unencrypted HTTP connection. `:``)+` and download it as a file. `,1),S(`div`,$u,[S(`button`,{onClick:z,disabled:F.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`},l(F.value?`Exporting…`:`Yes, Export Key`),9,ed),S(`button`,{onClick:o[4]||=e=>P.value=!1,disabled:F.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,td)])])])])):_(``,!0),I.value?(a(),C(`div`,nd,[S(`div`,rd,[o[33]||=S(`h4`,{class:`text-sm font-medium text-content-primary dark:text-content-primary`},` Key Exported `,-1),S(`button`,{onClick:o[5]||=e=>{I.value=null,P.value=!1},class:`text-xs text-content-muted hover:text-content-secondary transition-colors`},` Dismiss `)]),S(`div`,id,[S(`p`,null,[o[34]||=b(` Key length: `,-1),S(`span`,ad,l(I.value.key_length_bytes)+` bytes`,1)]),I.value.node_address?(a(),C(`p`,od,[o[35]||=b(` Node address: `,-1),S(`span`,sd,l(I.value.node_address),1)])):_(``,!0),I.value.public_key_hex?(a(),C(`p`,cd,[o[36]||=b(` Public key: `,-1),S(`span`,ld,l(I.value.public_key_hex),1)])):_(``,!0)]),o[37]||=S(`p`,{class:`text-xs text-green-600 dark:text-green-400`},`File downloaded successfully.`,-1)])):_(``,!0),L.value?(a(),C(`p`,ud,l(L.value),1)):_(``,!0)])]))}}),fd={class:`space-y-12`},pd={class:`cfg-page-heading flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},md={class:`flex items-center gap-2 flex-shrink-0`},hd={class:`cfg-section`},gd={class:`flex items-start justify-between mb-4`},_d=[`disabled`],vd={key:0,class:`flex items-center gap-1.5`},yd={key:1},bd={key:0,class:`grid grid-cols-2 sm:grid-cols-4 gap-3 mb-6`},xd={class:`bg-background-mute dark:bg-background/30 rounded-lg p-3 border border-stroke-subtle dark:border-stroke/10`},Sd={class:`text-lg font-semibold text-content-primary dark:text-content-primary font-mono`},Cd={class:`bg-background-mute dark:bg-background/30 rounded-lg p-3 border border-stroke-subtle dark:border-stroke/10`},wd={class:`text-lg font-semibold text-content-primary dark:text-content-primary font-mono`},Td={class:`bg-background-mute dark:bg-background/30 rounded-lg p-3 border border-stroke-subtle dark:border-stroke/10`},Ed={class:`text-lg font-semibold text-content-primary dark:text-content-primary font-mono`},Dd={class:`bg-background-mute dark:bg-background/30 rounded-lg p-3 border border-stroke-subtle dark:border-stroke/10`},Od={class:`text-lg font-semibold text-content-primary dark:text-content-primary font-mono`},kd={key:1,class:`flex items-center justify-center py-12`},Ad={class:`text-center`},jd={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`},Md={class:`text-xs text-red-700 dark:text-red-400`},Nd={key:3},Pd={class:`overflow-x-auto`},Fd={class:`w-full text-sm`},Id={class:`py-2.5 pr-4`},Ld={class:`font-mono text-content-primary dark:text-content-primary`},Rd={class:`py-2.5 pr-4 text-right`},zd={class:`font-mono text-content-secondary dark:text-content-muted`},Bd={class:`py-2.5 pr-4 text-right hidden sm:table-cell`},Vd={key:0,class:`text-xs text-content-muted`},Hd={class:`text-content-muted/60 ml-1`},Ud={key:1,class:`text-xs text-content-muted/50`},Wd={key:2,class:`text-xs text-content-muted/50`},Gd={class:`py-2.5 text-right`},Kd=[`onClick`,`disabled`],qd={key:0,class:`flex items-center gap-1`},Jd={key:1},Yd={key:1,class:`text-xs text-content-muted/50`},Xd={class:`flex items-start gap-3 mb-5`},Zd={class:`flex-1 min-w-0`},Qd={class:`text-lg font-semibold text-content-primary dark:text-content-primary`},$d={class:`text-sm text-content-secondary dark:text-content-muted mt-1`},ef={class:`text-content-primary dark:text-content-primary`},tf={class:`text-content-primary dark:text-content-primary font-mono`},nf={class:`flex gap-3`},rf=[`disabled`],af=[`disabled`],of={class:`cfg-section`},sf={class:`flex flex-wrap gap-3`},cf=[`disabled`],lf=[`disabled`],uf={class:`flex items-center gap-2`},df={key:0,class:`text-xs text-green-600 dark:text-green-400 mt-3`},ff={key:1,class:`text-xs text-green-600 dark:text-green-400 mt-3`},pf=f({__name:`DatabaseManagement`,setup(n){let r=new Set([`packets`,`adverts`,`noise_floor`,`crc_errors`,`room_messages`,`room_client_sync`,`companion_contacts`,`companion_channels`,`companion_messages`,`companion_prefs`]),i=o(!1),s=o(!1),d=o(``),f=o(null),p=o({}),h=o(null),g=o(``),w=o(!1),T=o(``),E=y(()=>f.value?f.value.tables.reduce((e,t)=>e+t.row_count,0):0);function D(e){return r.has(e)}function O(e,t){return!e||!t?0:Math.max(1,Math.round((t-e)/86400))}async function k(){s.value=!0,d.value=``;try{let e=await R.getDbStats();e.success&&e.data?f.value=e.data:d.value=e.error||`Failed to load database stats`}catch(e){d.value=e instanceof Error?e.message:`Failed to load database stats`}finally{s.value=!1}}function j(e,t){g.value=``,h.value={table:e,rowCount:t,executing:!1}}async function M(){if(!h.value)return;let{table:e}=h.value;h.value.executing=!0,g.value=``;try{let t=e===`all`?`all`:[e];e!==`all`&&(p.value[e]=!0);let n=await R.purgeTable(t);if(n.success){let t=n.data||{};g.value=`Deleted ${Object.values(t).reduce((e,t)=>e+(t.deleted||0),0).toLocaleString()} rows${e===`all`?` from all tables`:` from ${e}`}.`,h.value=null,await k()}else d.value=n.error||`Purge failed`,h.value=null}catch(e){d.value=e instanceof Error?e.message:`Purge failed`,h.value=null}finally{e!==`all`&&(p.value[e]=!1)}}async function N(){w.value=!0,T.value=``,d.value=``;try{let e=await R.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 d.value=e.error||`Vacuum failed`}catch(e){d.value=e instanceof Error?e.message:`Vacuum failed`}finally{w.value=!1}}return e(k),(e,n)=>(a(),C(`div`,fd,[S(`div`,pd,[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`,md,[S(`button`,{onClick:n[0]||=e=>i.value=!i.value,class:`cfg-btn-primary`},l(i.value?`Lock`:`Unlock`),1)])]),S(`div`,hd,[S(`div`,gd,[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:s.value,class:`cfg-btn-secondary`},[s.value?(a(),C(`span`,vd,[v(W,{size:`xs`,color:`current`,class:`inline-block`}),n[6]||=b(` Loading… `,-1)])):(a(),C(`span`,yd,`Refresh`))],8,_d)]),f.value?(a(),C(`div`,bd,[S(`div`,xd,[n[8]||=S(`p`,{class:`text-xs text-content-muted mb-1`},`Database Size`,-1),S(`p`,Sd,l(c(Q)(f.value.database_size_bytes)),1)]),S(`div`,Cd,[n[9]||=S(`p`,{class:`text-xs text-content-muted mb-1`},`RRD Metrics`,-1),S(`p`,wd,l(c(Q)(f.value.rrd_size_bytes)),1)]),S(`div`,Td,[n[10]||=S(`p`,{class:`text-xs text-content-muted mb-1`},`Total Size`,-1),S(`p`,Ed,l(c(Q)(f.value.database_size_bytes+f.value.rrd_size_bytes)),1)]),S(`div`,Dd,[n[11]||=S(`p`,{class:`text-xs text-content-muted mb-1`},`Total Rows`,-1),S(`p`,Od,l(E.value.toLocaleString()),1)])])):_(``,!0),s.value&&!f.value?(a(),C(`div`,kd,[S(`div`,Ad,[v(W,{class:`mx-auto mb-4`}),n[12]||=S(`div`,{class:`text-content-secondary dark:text-content-muted`},`Loading database info…`,-1)])])):_(``,!0),d.value?(a(),C(`div`,jd,[S(`p`,Md,l(d.value),1)])):_(``,!0),f.value&&f.value.tables.length>0?(a(),C(`div`,Nd,[S(`div`,Pd,[S(`table`,Fd,[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,[(a(!0),C(x,null,t(f.value.tables,e=>(a(),C(`tr`,{key:e.name,class:`border-b border-stroke-subtle/50 dark:border-stroke/5`},[S(`td`,Id,[S(`span`,Ld,l(e.name),1)]),S(`td`,Rd,[S(`span`,zd,l(e.row_count.toLocaleString()),1)]),S(`td`,Bd,[e.has_timestamp&&e.row_count>0?(a(),C(`span`,Vd,[b(l(c(Z)(e.oldest_timestamp))+` — `+l(c(Z)(e.newest_timestamp))+` `,1),S(`span`,Hd,`(`+l(O(e.oldest_timestamp,e.newest_timestamp))+`d)`,1)])):e.row_count===0?(a(),C(`span`,Ud,`—`)):(a(),C(`span`,Wd,`n/a`))]),S(`td`,Gd,[i.value&&D(e.name)&&e.row_count>0?(a(),C(`button`,{key:0,onClick:t=>j(e.name,e.row_count),disabled:p.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`},[p.value[e.name]?(a(),C(`span`,qd,[v(W,{size:`xs`,color:`current`,class:`inline-block`}),n[13]||=b(` Purging… `,-1)])):(a(),C(`span`,Jd,`Empty`))],8,Kd)):D(e.name)?_(``,!0):(a(),C(`span`,Yd,`—`))])]))),128))])])])])):_(``,!0)]),(a(),u(m,{to:`body`},[h.value?(a(),C(`div`,{key:0,class:`modal-backdrop-heavy`,onClick:n[3]||=A(e=>!h.value.executing&&(h.value=null),[`self`])},[S(`div`,{class:`modal-card max-w-lg`,onClick:n[2]||=A(()=>{},[`stop`])},[S(`div`,Xd,[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`,Zd,[S(`h3`,Qd,l(h.value.table===`all`?`Purge All Tables`:`Purge "${h.value.table}"`),1),S(`p`,$d,[h.value.table===`all`?(a(),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 (`+l(E.value.toLocaleString())+` rows total). This cannot be undone. `,1)],64)):(a(),C(x,{key:1},[n[17]||=b(` This will permanently delete `,-1),S(`strong`,ef,l(h.value.rowCount.toLocaleString())+` rows`,1),n[18]||=b(` from `,-1),S(`strong`,tf,l(h.value.table),1),n[19]||=b(`. This cannot be undone. `,-1)],64))])])]),S(`div`,nf,[S(`button`,{onClick:n[1]||=e=>h.value=null,disabled:h.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,rf),S(`button`,{onClick:M,disabled:h.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`},l(h.value.executing?`Purging…`:`Yes, Delete Data`),9,af)])])])):_(``,!0)])),S(`div`,of,[n[23]||=S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-4`},` Maintenance `,-1),S(`div`,sf,[S(`button`,{onClick:n[4]||=e=>j(`all`,E.value),disabled:!f.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,cf),S(`button`,{onClick:N,disabled:w.value||!f.value,class:`cfg-btn-primary`},[S(`span`,uf,[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(` `+l(w.value?`Compacting…`:`Compact Database`),1)])],8,lf)]),T.value?(a(),C(`p`,df,l(T.value),1)):_(``,!0),g.value?(a(),C(`p`,ff,l(g.value),1)):_(``,!0)])]))}}),mf={class:`space-y-12`},hf={class:`cfg-section`},gf={class:`flex items-start justify-between mb-4`},_f={class:`flex items-center gap-2`},vf=[`disabled`],yf={key:0,class:`flex items-center gap-1.5`},bf={key:1},xf=[`disabled`],Sf={key:0,class:`flex items-center gap-1.5`},Cf={key:1},wf={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`},Tf={key:1,class:`mb-4`},Ef={class:`bg-background-mute dark:bg-background/30 rounded-lg p-3 border border-stroke-subtle dark:border-stroke/10 inline-block`},Df={class:`text-lg font-semibold text-content-primary dark:text-content-primary font-mono`},Of={key:2,class:`p-4 rounded-lg bg-cyan-500/10 dark:bg-primary/10 border border-cyan-400/30 dark:border-primary/30`},kf={key:3},Af=[`innerHTML`],jf={class:`font-semibold text-sm`},Mf={class:`text-sm mt-0.5 opacity-80`},Nf={class:`grid grid-cols-2 sm:grid-cols-3 gap-3 mb-6`},Pf={key:0,class:`bg-background-mute dark:bg-background/30 rounded-lg p-3 border border-stroke-subtle dark:border-stroke/10`},Ff={class:`text-lg font-semibold text-content-primary dark:text-content-primary font-mono`},If={key:1,class:`bg-background-mute dark:bg-background/30 rounded-lg p-3 border border-stroke-subtle dark:border-stroke/10`},Lf={class:`text-lg font-semibold text-content-primary dark:text-content-primary font-mono`},Rf={key:2,class:`bg-background-mute dark:bg-background/30 rounded-lg p-3 border border-stroke-subtle dark:border-stroke/10`},zf={class:`text-lg font-semibold text-content-primary dark:text-content-primary font-mono`},Bf={key:0,class:`mb-6`},Vf={class:`space-y-2`},Hf={class:`flex items-start justify-between gap-3`},Uf={class:`flex items-center gap-2 min-w-0`},Wf={class:`shrink-0 text-xs font-medium text-content-muted w-5 text-right`},Gf={class:`text-right shrink-0`},Kf={class:`text-xs text-content-muted`},qf={class:`mt-1.5 ml-7`},Jf={class:`text-xs font-mono text-content-secondary dark:text-content-muted break-all`},Yf={key:0,class:`text-xs text-content-muted mt-0.5`},Xf={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`},Zf={key:2},Qf={key:0,class:`overflow-x-auto rounded-lg border border-stroke-subtle dark:border-stroke/10`},$f={class:`w-full text-sm`},ep={class:`px-3 py-2 text-content-muted font-mono text-xs`},tp={class:`px-3 py-2 text-content-primary dark:text-content-primary font-mono text-xs break-all`},np={class:`px-3 py-2 text-right font-mono text-xs text-content-secondary dark:text-content-muted whitespace-nowrap`},rp={class:`px-3 py-2 text-right font-mono text-xs text-content-secondary dark:text-content-muted`},ip={key:4,class:`py-8 text-center text-content-muted text-sm`},ap=K(f({__name:`MemoryDebug`,setup(n){let i=o(!1),s=o(!1),c=o(``),u=o(null),f=o(!1),m=o(null),h=o(!1),g=y(()=>u.value&&(u.value.current_top_20||u.value.growth_since_baseline));async function w(){i.value=!0,c.value=``;try{let e=await R.get(`memory_debug`);e.success&&e.data?(f.value=!!e.data.tracing,m.value=e.data.rss_mb??null,(e.data.current_top_20||e.data.growth_since_baseline)&&(u.value=e.data)):c.value=e.error||`Failed to fetch memory status`}catch(e){c.value=e instanceof Error?e.message:`Failed to fetch memory status`}finally{i.value=!1}}async function T(){s.value=!0,c.value=``;let e=f.value?`stop`:`start`;try{let t=await R.post(`memory_debug`,{action:e});t.success&&t.data?(f.value=!!t.data.tracing,e===`stop`&&(u.value=null,m.value=null)):c.value=t.error||`Failed to ${e} tracing`}catch(t){c.value=t instanceof Error?t.message:`Failed to ${e} tracing`}finally{s.value=!1,f.value&&await w()}}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 M(e){return e.replace(/.*\/site-packages\//,``).replace(/.*\/lib\/python[^/]*\//,``).replace(/.*\/repeater\//,`repeater/`)}let P=y(()=>u.value?.growth_since_baseline?u.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`),I=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`}),L=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 e(w),(e,n)=>(a(),C(`div`,mf,[n[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`,hf,[S(`div`,gf,[n[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`,_f,[f.value&&g.value?(a(),C(`button`,{key:0,onClick:w,disabled:i.value,class:`cfg-btn-secondary`},[i.value?(a(),C(`span`,yf,[v(W,{size:`xs`,color:`current`,class:`inline-block`}),n[1]||=b(` Checking… `,-1)])):(a(),C(`span`,bf,`Check Again`))],8,vf)):_(``,!0),S(`button`,{onClick:T,disabled:s.value,class:p([`px-3 py-1.5 rounded-lg border text-sm transition-colors disabled:opacity-50`,f.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`])},[s.value?(a(),C(`span`,Sf,[v(W,{size:`xs`,color:`current`,class:`inline-block`}),b(` `+l(f.value?`Stopping…`:`Starting…`),1)])):(a(),C(`span`,Cf,l(f.value?`Stop Tracing`:`Start Tracing`),1))],10,xf)])]),c.value?(a(),C(`div`,wf,l(c.value),1)):_(``,!0),!f.value&&m.value!==null&&!i.value?(a(),C(`div`,Tf,[S(`div`,Ef,[n[3]||=S(`p`,{class:`text-xs text-content-muted mb-1`},`Current Memory (RSS)`,-1),S(`p`,Df,l(m.value)+` MB`,1)])])):_(``,!0),f.value&&!g.value&&!i.value?(a(),C(`div`,Of,[...n[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)]])):_(``,!0),u.value&&g.value?(a(),C(`div`,kf,[S(`div`,{class:p([`mb-5 p-4 rounded-lg border flex items-start gap-3`,I.value])},[S(`div`,{class:`mt-0.5`,innerHTML:L.value},null,8,Af),S(`div`,null,[S(`p`,jf,l(z.value),1),S(`p`,Mf,l(B.value),1)])],2),S(`div`,Nf,[u.value.rss_mb===void 0?_(``,!0):(a(),C(`div`,Pf,[n[5]||=S(`p`,{class:`text-xs text-content-muted mb-1`},`Total Memory Used`,-1),S(`p`,Ff,l(u.value.rss_mb)+` MB`,1)])),u.value.traced_current_mb===void 0?_(``,!0):(a(),C(`div`,If,[n[6]||=S(`p`,{class:`text-xs text-content-muted mb-1`},`Tracked Now`,-1),S(`p`,Lf,l(u.value.traced_current_mb)+` MB`,1)])),u.value.traced_peak_mb===void 0?_(``,!0):(a(),C(`div`,Rf,[n[7]||=S(`p`,{class:`text-xs text-content-muted mb-1`},`Peak Tracked`,-1),S(`p`,zf,l(u.value.traced_peak_mb)+` MB`,1)]))]),u.value.growth_since_baseline&&u.value.growth_since_baseline.length>0?(a(),C(`div`,Bf,[n[8]||=S(`h4`,{class:`text-sm font-semibold text-content-primary dark:text-content-primary mb-1`},`Memory Growth Breakdown`,-1),n[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`,Vf,[(a(!0),C(x,null,t(u.value.growth_since_baseline,(e,t)=>(a(),C(`div`,{key:t,class:p([`rounded-lg border p-3 transition-colors`,k(e)])},[S(`div`,Hf,[S(`div`,Uf,[S(`span`,Wf,l(t+1),1),S(`span`,{class:p([`shrink-0 inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-semibold`,O(e)])},l(D(e)),3)]),S(`div`,Gf,[S(`span`,{class:p([`font-mono text-sm font-semibold`,A(e)])},`+`+l(j(e.size_diff_kb)),3),S(`p`,Kf,l(j(e.current_size_kb))+` total`,1)])]),S(`div`,qf,[S(`p`,Jf,l(M(e.file)),1),e.count_diff===0?_(``,!0):(a(),C(`p`,Yf,l(e.count_diff>0?`+`:``)+l(e.count_diff)+` new allocation`+l(Math.abs(e.count_diff)===1?``:`s`),1))])],2))),128))])])):u.value.growth_since_baseline&&u.value.growth_since_baseline.length===0?(a(),C(`div`,Xf,[...n[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)]])):_(``,!0),u.value.current_top_20&&u.value.current_top_20.length>0?(a(),C(`div`,Zf,[S(`button`,{onClick:n[0]||=e=>h.value=!h.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`},[(a(),C(`svg`,{class:p([`w-4 h-4 transition-transform`,{"rotate-90":h.value}]),fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[...n[11]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M9 5l7 7-7 7`},null,-1)]],2)),n[12]||=b(` Advanced: Current Top Allocations `,-1)]),v(N,{name:`expand`},{default:r(()=>[h.value?(a(),C(`div`,Qf,[S(`table`,$f,[n[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,[(a(!0),C(x,null,t(u.value.current_top_20,(e,t)=>(a(),C(`tr`,{key:t,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`,ep,l(t+1),1),S(`td`,tp,l(M(e.file)),1),S(`td`,np,l(j(e.size_kb)),1),S(`td`,rp,l(e.count),1)]))),128))])])])):_(``,!0)]),_:1})])):_(``,!0)])):_(``,!0),!i.value&&!s.value&&!f.value&&!g.value&&!c.value&&m.value===null?(a(),C(`div`,ip,[...n[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)]])):_(``,!0)])]))}}),[[`__scopeId`,`data-v-00e540ed`]]),op={class:`space-y-6`},sp={class:`cfg-page-heading flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},cp={class:`flex items-center gap-2 flex-shrink-0`},lp=[`disabled`],up=[`disabled`],dp=[`disabled`],fp={key:0,class:`bg-red-500/10 border border-red-500/30 rounded-lg p-3 text-red-600 dark:text-red-400 text-sm`},pp={key:1,class:`bg-emerald-500/10 border border-emerald-500/30 rounded-lg p-3 text-emerald-700 dark:text-emerald-400 text-sm`},mp={key:2,class:`bg-blue-500/10 border border-blue-500/30 rounded-lg p-3 text-blue-700 dark:text-blue-300 text-sm`},hp={key:3,class:`flex items-center justify-center py-10`},gp={class:`cfg-section`},_p={class:`flex flex-wrap items-center gap-2`},vp={key:0,class:`space-y-4`},yp={class:`cfg-section space-y-4`},bp={class:`grid grid-cols-1 xl:grid-cols-2 gap-4 items-stretch`},xp={class:`rounded-xl border border-stroke-subtle dark:border-stroke/20 bg-background-mute/50 dark:bg-white/5 px-4 py-4 flex items-center justify-between gap-4`},Sp={class:`inline-flex items-center gap-3 rounded-full border border-stroke-subtle dark:border-stroke/20 bg-background-main dark:bg-surface-900 px-3 py-2 text-sm font-medium text-content-primary dark:text-content-primary shadow-sm`},Cp=[`disabled`],wp={class:`rounded-xl border border-stroke-subtle dark:border-stroke/20 bg-background-mute/50 dark:bg-white/5 px-4 py-4 flex flex-col justify-between gap-3`},Tp=[`disabled`],Ep=[`value`],Dp={class:`space-y-3`},Op={class:`flex flex-wrap items-center justify-between gap-2`},kp={class:`flex items-center gap-2`},Ap=[`disabled`],jp=[`disabled`],Mp={class:`overflow-x-auto rounded-2xl border border-stroke-subtle dark:border-stroke/20 bg-background-main dark:bg-surface-900 shadow-sm`},Np={class:`w-full min-w-[980px] table-fixed text-sm`},Pp={class:`px-3 py-3 text-xs font-medium text-content-secondary dark:text-content-secondary`},Fp={class:`px-3 py-3`},Ip=[`title`],Lp={class:`px-3 py-3 text-content-primary dark:text-content-primary`},Rp=[`title`],zp={class:`px-3 py-3 text-xs text-content-secondary dark:text-content-secondary`},Bp=[`title`],Vp={class:`px-3 py-3`},Hp=[`title`],Up={class:`px-3 py-3 text-right`},Wp={class:`inline-flex flex-wrap items-center justify-end gap-1`},Gp=[`disabled`,`onClick`],Kp=[`disabled`,`onClick`],qp=[`disabled`,`onClick`],Jp=[`disabled`,`onClick`],Yp={key:0},Xp={key:0,class:`space-y-2`},Zp=[`disabled`],Qp={class:`flex justify-end`},$p=[`disabled`],em={class:`flex flex-wrap items-center gap-2 justify-end`},tm=[`disabled`],nm={key:1,class:`space-y-4`},rm={class:`cfg-section`},im={class:`flex flex-wrap items-center gap-2`},am={class:`grid grid-cols-1 lg:grid-cols-12 gap-4`},om={class:`cfg-section lg:col-span-4 space-y-4`},sm={class:`flex items-center justify-between`},cm={class:`text-xs text-content-muted dark:text-content-muted`},lm={class:`space-y-2 max-h-[360px] overflow-auto pr-1`},um=[`onClick`],dm={class:`flex items-start justify-between gap-2`},fm={class:`text-sm font-medium text-content-primary dark:text-content-primary`},pm={class:`text-xs text-content-muted dark:text-content-muted mt-1`},mm={class:`text-[11px] text-content-muted dark:text-content-muted`},hm={key:0,class:`text-xs text-content-muted dark:text-content-muted py-8 text-center border border-dashed border-stroke-subtle dark:border-stroke/30 rounded-lg`},gm={class:`pt-2 border-t border-stroke-subtle dark:border-stroke/20 space-y-2`},_m=[`disabled`],vm=[`disabled`],ym=[`disabled`],bm={class:`cfg-section lg:col-span-8 space-y-4`},xm={class:`flex items-center justify-between`},Sm={class:`text-sm font-semibold text-content-primary dark:text-content-primary`},Cm=[`disabled`],wm={key:0,class:`overflow-x-auto rounded-lg border border-stroke-subtle dark:border-stroke/20`},Tm={class:`w-full text-sm`},Em={class:`px-3 py-2 text-content-primary dark:text-content-primary`},Dm={class:`px-3 py-2 font-mono text-xs text-content-secondary dark:text-content-secondary`},Om={class:`px-3 py-2 text-right`},km=[`disabled`,`onClick`],Am={key:0},jm={key:1,class:`text-xs text-content-muted dark:text-content-muted py-8 text-center border border-dashed border-stroke-subtle dark:border-stroke/30 rounded-lg`},Mm={key:2,class:`pt-2 border-t border-stroke-subtle dark:border-stroke/20 space-y-2`},Nm={class:`grid grid-cols-1 md:grid-cols-2 gap-2`},Pm=[`disabled`],Fm=[`disabled`,`placeholder`],Im=[`disabled`],Lm={class:`bg-surface dark:bg-surface-elevated border border-stroke-subtle dark:border-stroke/20 rounded-[15px] p-5 max-w-5xl w-full max-h-[90vh] overflow-y-auto shadow-2xl space-y-4`},Rm={class:`flex items-start justify-between gap-3`},zm={class:`text-lg font-semibold text-content-primary dark:text-content-primary`},Bm={class:`text-xs text-content-muted dark:text-content-muted mt-1`},Vm={class:`flex items-center gap-2`},Hm={key:0,class:`rounded-lg border border-primary/30 bg-primary/5 p-3 space-y-2`},Um={class:`flex items-center justify-between`},Wm={class:`overflow-x-auto rounded-lg border border-stroke-subtle dark:border-stroke/20`},Gm={class:`w-full min-w-[840px] text-xs`},Km={class:`px-2 py-1.5`},qm={class:`px-2 py-1.5`},Jm={class:`px-2 py-1.5`},Ym={class:`px-2 py-1.5`},Xm={key:1,class:`bg-red-500/10 border border-red-500/30 rounded-lg p-2 text-red-600 dark:text-red-400 text-xs`},Zm={class:`grid grid-cols-1 md:grid-cols-4 gap-3`},Qm={class:`md:col-span-2`},$m=[`value`],eh={class:`inline-flex items-center gap-2 text-sm text-content-primary dark:text-content-primary`},th={class:`space-y-2`},nh={key:0,class:`rounded-lg border border-amber-500/30 bg-amber-500/10 px-3 py-2 text-xs text-amber-800 dark:text-amber-200`},rh={class:`overflow-x-auto rounded-lg border border-stroke-subtle dark:border-stroke/20`},ih={class:`w-full min-w-[980px] text-sm`},ah={class:`bg-background-mute dark:bg-white/5`},oh={key:0,class:`px-2 py-2 text-left text-xs font-semibold uppercase tracking-wide text-content-muted dark:text-content-muted`},sh=[`onDragover`],ch={class:`px-2 py-2 w-[58px]`},lh=[`onDragstart`],uh={class:`px-2 py-2 min-w-[170px]`},dh=[`onUpdate:modelValue`,`onChange`],fh=[`value`],ph={class:`px-2 py-2 min-w-[160px]`},mh=[`onUpdate:modelValue`],hh=[`value`],gh={key:0,class:`px-2 py-2 min-w-[140px]`},_h=[`onUpdate:modelValue`,`disabled`],vh={key:0,value:`group`},yh={class:`px-2 py-2 min-w-[230px]`},bh={key:0,class:`grid grid-cols-2 gap-1`},xh=[`onUpdate:modelValue`],Sh=[`value`],Ch=[`onUpdate:modelValue`],wh=[`value`],Th={key:1,class:`space-y-1`},Eh=[`onChange`],Dh=[`value`],Oh=[`onUpdate:modelValue`,`placeholder`],kh=[`onUpdate:modelValue`,`placeholder`],Ah={key:3,class:`text-[11px] text-slate-500 dark:text-slate-400`},jh={class:`px-2 py-2 min-w-[110px]`},Mh=[`onUpdate:modelValue`,`disabled`],Nh=[`value`],Ph={class:`px-2 py-2 text-right`},Fh={class:`inline-flex items-center gap-1`},Ih=[`disabled`,`onClick`],Lh=[`disabled`,`onClick`],Rh=[`onClick`],zh=[`colspan`],Bh=f({name:`PolicyEngineSettings`,__name:`PolicyEngineSettings`,setup(n,{expose:r}){let s=o(!1),u=o(!1),d=o(!1),f=o(null),m=o(null),g=null,w=o(`policy`),T=o({enabled:!1,default_action:`allow`,rules:[],objects:{}}),E=o({channel_hashes:[],pubkeys:[]}),O=o({enabled:!1,default_action:`allow`,rules:[],objects:{}}),k=o({channel_hashes:[],pubkeys:[]}),N=o(`[]`),P=o(!1),F=o([]),I=o(null),L=o(!1),z=o(null),B=o(null),ee=o(null),V=o(!1),H=o(null),U=o(null),G=o(`channel_hashes`),K=o(``),te=o({friendly_name:``,description:``}),q=o({friendly_name:``,value:``}),ne=[{label:`Allow`,value:`allow`},{label:`Drop`,value:`drop`},{label:`Log Only`,value:`log_only`}],re=[{label:`Equals`,value:`equals`},{label:`Not Equals`,value:`not_equals`},{label:`Greater Than`,value:`greater_than`},{label:`Greater or Equal`,value:`greater_or_equal`},{label:`Less Than`,value:`less_than`},{label:`Less or Equal`,value:`less_or_equal`},{label:`Contains`,value:`contains`},{label:`In List`,value:`in`},{label:`Intersects`,value:`intersects`},{label:`Starts With`,value:`starts_with`},{label:`Ends With`,value:`ends_with`}],ie=[{value:`route_type`,label:`Route Type`,valueTypes:[`number`],operators:[`equals`,`not_equals`,`greater_than`,`less_than`]},{value:`payload_type`,label:`Payload Type`,valueTypes:[`number`],operators:[`equals`,`not_equals`,`greater_than`,`less_than`]},{value:`payload_length`,label:`Payload Length`,valueTypes:[`number`],operators:[`equals`,`not_equals`,`greater_than`,`greater_or_equal`,`less_than`,`less_or_equal`]},{value:`path_hash_size`,label:`Path Hash Size`,valueTypes:[`number`],operators:[`equals`,`not_equals`,`greater_than`,`less_than`]},{value:`hop_count`,label:`Hop Count`,valueTypes:[`number`],operators:[`equals`,`not_equals`,`greater_than`,`greater_or_equal`,`less_than`,`less_or_equal`]},{value:`rssi`,label:`RSSI`,valueTypes:[`number`],operators:[`equals`,`not_equals`,`greater_than`,`greater_or_equal`,`less_than`,`less_or_equal`]},{value:`snr`,label:`SNR`,valueTypes:[`number`],operators:[`equals`,`not_equals`,`greater_than`,`greater_or_equal`,`less_than`,`less_or_equal`]},{value:`mode`,label:`Mode`,valueTypes:[`string`],operators:[`equals`,`not_equals`,`in`]},{value:`local_transmission`,label:`Local Transmission`,valueTypes:[`boolean`],operators:[`equals`,`not_equals`]},{value:`path_hashes`,label:`Path Hashes`,valueTypes:[`string`],operators:[`contains`,`intersects`]},{value:`channel_hash`,label:`Channel Hash`,valueTypes:[`string`],operators:[`equals`,`not_equals`,`in`],groupKinds:[`channel_hashes`]},{value:`channel_decryptable`,label:`Channel Decryptable`,valueTypes:[`boolean`],operators:[`equals`,`not_equals`]},{value:`channel_message_body`,label:`Channel Message Body`,valueTypes:[`string`],operators:[`contains`,`starts_with`,`ends_with`,`equals`,`not_equals`]},{value:`payload_hex`,label:`Payload Hex`,valueTypes:[`string`],operators:[`contains`,`starts_with`,`ends_with`,`equals`,`not_equals`]},{value:`transport_code_0`,label:`Transport Code 0`,valueTypes:[`number`],operators:[`equals`,`not_equals`,`greater_than`,`less_than`]},{value:`transport_code_1`,label:`Transport Code 1`,valueTypes:[`number`],operators:[`equals`,`not_equals`,`greater_than`,`less_than`]}],J=y(()=>{let e={};for(let t of ie)e[t.value]=t;return e}),Y=y(()=>ie.some(e=>Array.isArray(e.groupKinds)&&e.groupKinds.length>0)),X=y(()=>Y.value?8:7);function Z(e){return JSON.parse(JSON.stringify(e))}function Q(e,t){return e.trim().toLowerCase().replace(/[^a-z0-9]+/g,`_`).replace(/^_+|_+$/g,``)||t}function ae(e,t){if(!t.includes(e))return e;let n=2;for(;t.includes(`${e}_${n}`);)n+=1;return`${e}_${n}`}function oe(e){O.value=Z(e.policy_engine),k.value=Z(e.groups)}function se(){T.value=Z(O.value),E.value=Z(k.value),N.value=JSON.stringify(T.value.rules,null,2),F.value=T.value.rules.map((e,t)=>qe(e,t))}function $(){f.value=null,m.value=null,I.value=null,u.value=!0}function ce(e){f.value=e,g&&clearTimeout(g),g=setTimeout(()=>{f.value=null,g=null},3e3)}function le(){se(),u.value=!1,f.value=null,m.value=null,I.value=null,te.value={friendly_name:``,description:``},q.value={friendly_name:``,value:``},at()}function ue(e){return{channel_hash_groups:Object.fromEntries(e.channel_hashes.map(e=>[e.id,e.entries.map(e=>e.value)])),pubkey_groups:Object.fromEntries(e.pubkeys.map(e=>[e.id,e.entries.map(e=>e.value)]))}}function de(){return{...Z(T.value.objects||{}),...ue(E.value)}}let{showUnsavedModal:me,requestLeave:he,handleDiscard:ge,handleSave:_e,handleCancel:ve}=pe(u,d,le,async()=>xt());r({requestLeave:he,isEditing:u});function ye(e,t){let n=e instanceof Error?e.message:t;return n.includes(`404`)?`Policy API not available on the connected backend. Update/restart pyMC_Repeater so /api/policy, /api/policy_groups, and /api/policy_group_entries are exposed.`:n||t}let be=y(()=>E.value[G.value]??[]),xe=y(()=>be.value.find(e=>e.id===K.value)??null);h([G,be],()=>{if(!be.value.length){K.value=``;return}be.value.find(e=>e.id===K.value)||(K.value=be.value[0].id)});function Se(e){return J.value[e]?.label||e}function Ce(e){return re.find(t=>t.value===e)?.label||e}function we(e){return J.value[e]?.operators||[`equals`,`not_equals`]}function Te(e){return J.value[e]?.valueTypes||[`string`]}function Ee(e){return J.value[e]?.groupKinds||[]}function De(e){return e&&E.value[e]||[]}function Oe(e){return Ee(e).length>0}function ke(e){if(e.valueType===`boolean`)return[{label:`true`,value:`true`},{label:`false`,value:`false`}];switch(e.field){case`mode`:return[{label:`Forward`,value:`forward`},{label:`Monitor`,value:`monitor`},{label:`No TX`,value:`no_tx`}];case`route_type`:return[{label:`0 - Transport Flood`,value:`0`},{label:`1 - Flood`,value:`1`},{label:`2 - Direct`,value:`2`},{label:`3 - Transport Direct`,value:`3`}];case`path_hash_size`:return[{label:`1 byte`,value:`1`},{label:`2 bytes`,value:`2`},{label:`3 bytes`,value:`3`}];case`payload_type`:return[{label:`0 - REQ`,value:`0`},{label:`1 - RESPONSE`,value:`1`},{label:`2 - TXT_MSG`,value:`2`},{label:`3 - ACK`,value:`3`},{label:`4 - ADVERT`,value:`4`},{label:`5 - GRP_TXT`,value:`5`},{label:`6 - GRP_DATA`,value:`6`},{label:`7 - ANON_REQ`,value:`7`},{label:`8 - PATH`,value:`8`},{label:`9 - TRACE`,value:`9`},{label:`10 - MULTIPART`,value:`10`},{label:`15 - RAW_CUSTOM`,value:`15`}];default:return[]}}function Ae(e,t){t&&(e.value=t)}function je(e){return e===`path_hashes`}function Me(e){return e===`channel_hash`}function Ne(e){let t=e.trim();if(!t)throw Error(`Channel hash value is required`);let n=t.replace(/^0x/i,``);if(/^[0-9a-fA-F]+$/.test(n)){if(n.length%2!=0)throw Error(`Channel hash/secret must have an even number of hex characters.`);return n.length===32||n.length===64?`0x${n.toUpperCase()}`:n.length<=2?`0x${Number.parseInt(n,16).toString(16).toUpperCase().padStart(2,`0`)}`:`0x${n.toUpperCase()}`}let r;if(/^[0-9]+$/.test(t))r=Number.parseInt(t,10);else throw Error(`Invalid channel hash value: ${e}`);if(!Number.isFinite(r)||Number.isNaN(r)||r<0)throw Error(`Invalid channel hash value: ${e}`);if(r>255)throw Error(`Decimal channel hash must be within 0-255. Use hex secret key for full channel keys.`);return`0x${r.toString(16).toUpperCase().padStart(2,`0`)}`}function Pe(e){let t=e.trim();if(!t)throw Error(`Path hash value is required`);let n=t.replace(/^0x/i,``);if(!n)throw Error(`Path hash value is required`);if(!/^[0-9a-fA-F]+$/.test(n))throw Error(`Invalid path hash value: ${e}`);if(n.length%2!=0)throw Error(`Path hash must have an even number of hex characters: ${e}`);if(![2,4,6].includes(n.length))throw Error(`Path hash must be 1, 2, or 3 bytes: ${e}`);return`0x${n.toUpperCase()}`}function Fe(e){let t=e.split(/[\s,]+/).map(e=>e.trim()).filter(Boolean);if(!t.length)throw Error(`At least one path hash is required`);let n=t.map(Pe);if(new Set(n.map(e=>e.replace(/^0x/i,``).length)).size>1)throw Error(`Path hashes in one condition must all use the same byte length.`);return n}function Ie(e,t){return je(e)&&Array.isArray(t)?t.map(e=>Pe(String(e))).join(`
|
|
`):t==null?``:typeof t==`string`?t:typeof t==`number`||typeof t==`boolean`?String(t):JSON.stringify(t)}function Le(e){let t=e.value.trim();if(je(e.field)){let n=Fe(t);if(e.op===`contains`){if(n.length!==1)throw Error(`Path Hashes with Contains expects one hash. Use Intersects for multiple hashes.`);return n[0]}return n}return Me(e.field)?Ne(t):Ve(t,e.valueType)}function Re(e){return je(e.field)?e.op===`contains`?`Single hash, e.g. 0x42, 0x0042, or 0x000042`:`One hash per line or comma-separated; all must be the same size`:Me(e.field)?`1-byte channel hash (0x11) or full channel secret key`:e.valueType===`boolean`?`true/false`:`value`}function ze(e){return je(e.field)&&e.valueSource===`literal`}function Be(e){return typeof e==`number`?`number`:typeof e==`boolean`?`boolean`:`string`}function Ve(e,t){if(t===`number`){let t=Number(e);if(!Number.isFinite(t))throw Error(`Invalid numeric value: ${e}`);return t}if(t===`boolean`){let t=e.trim().toLowerCase();if(t===`true`)return!0;if(t===`false`)return!1;throw Error(`Invalid boolean value: ${e}. Use true or false.`)}return e}function He(e){return{id:e,field:`hop_count`,op:`greater_than`,valueType:`number`,valueSource:`literal`,value:`2`}}function Ue(e){return{id:e,name:`Rule ${e}`,enabled:!0,matchMode:`all`,conditions:[He(1)],action:`drop`}}function We(){return F.value.length?Math.max(...F.value.map(e=>Number(e.id)||0))+1:1}function Ge(e){return e.conditions.length?Math.max(...e.conditions.map(e=>e.id))+1:1}function Ke(e){let t=we(e.field);t.includes(e.op)||(e.op=t[0]);let n=Te(e.field);n.includes(e.valueType)||(e.valueType=n[0]);let r=Ee(e.field);if(!r.length){e.valueSource=`literal`,e.groupKind=void 0,e.groupId=void 0;return}if(e.valueSource===`group`){(!e.groupKind||!r.includes(e.groupKind))&&(e.groupKind=r[0]),Me(e.field)&&e.op!==`in`&&(e.op=`in`);let t=De(e.groupKind);t.find(t=>t.id===e.groupId)||(e.groupId=t[0]?.id)}}function qe(e,t){let n=e.if??{},r=`all`,i=[];Array.isArray(n.any)?(r=`any`,i=n.any):Array.isArray(n.all)?(r=`all`,i=n.all):`field`in n&&(i=[n]),i.length||(i=[{field:`hop_count`,op:`greater_than`,value:2}]);let a=i.map((e,t)=>{let n=String(e.field??`hop_count`),r=String(e.op??`equals`),i=we(n),a=i.includes(r)?r:i[0],o=e.value;if(typeof o==`string`&&o.startsWith(`@`)){let[e,r]=o.slice(1).split(`.`,2),i=e===`channel_hash_groups`?`channel_hashes`:e===`pubkey_groups`?`pubkeys`:void 0,s={id:t+1,field:n,op:a,valueType:`string`,valueSource:`group`,value:r||``,groupKind:i,groupId:r};return Ke(s),s}let s=Be(o),c={id:t+1,field:n,op:a,valueType:Te(n).includes(s)?s:Te(n)[0],valueSource:`literal`,value:Ie(n,o)};return Ke(c),c}),o=e.then??{},s=String(o.action??e.action??`allow`),c=ne.some(e=>e.value===s)?s:`allow`;return{id:Number(e.id??t+1),name:String(e.name??`Rule ${t+1}`),enabled:!!(e.enabled??!0),matchMode:r,conditions:a,action:c}}function Je(e,t){let n=e.conditions.map(t=>{let n;if(t.valueSource===`group`){if(!t.groupKind||!t.groupId)throw Error(`Condition ${t.id} in ${e.name} is missing group selection`);n=`@${t.groupKind===`channel_hashes`?`channel_hash_groups`:`pubkey_groups`}.${t.groupId}`}else n=Le(t);return{field:t.field,op:t.op,value:n}});return{id:Number(e.id)||t+1,name:e.name.trim()||`Rule ${t+1}`,enabled:!!e.enabled,if:{[e.matchMode]:n},then:{action:e.action}}}function Ye(){let e=F.value.map((e,t)=>Je(e,t));N.value=JSON.stringify(e,null,2)}function Xe(){let e=JSON.parse(N.value);if(!Array.isArray(e))throw Error(`Rules must be a JSON array`);return e}function Ze(){F.value=Xe().map((e,t)=>qe(e,t))}function Qe(){return P.value?Xe():F.value.map((e,t)=>Je(e,t))}function $e(e){if(e.valueSource===`group`)return`${Se(e.field)} ${Ce(e.op)} ${e.groupKind}:${e.groupId||`unset`}`;if(je(e.field)){let t=e.value.split(/[\s,]+/).map(e=>e.trim()).filter(Boolean).length;return`${Se(e.field)} ${Ce(e.op)} ${t} hash${t===1?``:`es`}`}return`${Se(e.field)} ${Ce(e.op)} ${e.value}`}function et(e){let t=e.matchMode===`all`?` AND `:` OR `;return e.conditions.map(e=>$e(e)).join(t)}function tt(e){return e===`log_only`?`Log Only`:e.charAt(0).toUpperCase()+e.slice(1)}function nt(e){return e===`drop`?`border-red-500/30 bg-red-500/10 text-red-600 dark:text-red-300`:e===`log_only`?`border-amber-500/30 bg-amber-500/10 text-amber-700 dark:text-amber-300`:`border-emerald-500/30 bg-emerald-500/10 text-emerald-700 dark:text-emerald-300`}function rt(){z.value=null,B.value=Ue(We()),ee.value=null,L.value=!0}function it(e){let t=F.value[e];t&&(z.value=e,B.value=JSON.parse(JSON.stringify(t)),ee.value=null,L.value=!0)}function at(){L.value=!1,B.value=null,z.value=null,ee.value=null,V.value=!1,H.value=null,U.value=null}function ot(){if(!B.value)return;let e=He(Ge(B.value));B.value.conditions.push(e)}function st(e){B.value&&(B.value.conditions.length<=1||B.value.conditions.splice(e,1))}function ct(e,t){if(!B.value)return;let n=e+t;if(n<0||n>=B.value.conditions.length)return;let r=B.value.conditions[e];B.value.conditions[e]=B.value.conditions[n],B.value.conditions[n]=r}function lt(e,t){H.value=e,U.value=e,t.dataTransfer&&(t.dataTransfer.effectAllowed=`move`,t.dataTransfer.setData(`text/plain`,String(e)))}function ut(e,t){if(H.value===null)return;t.preventDefault(),t.dataTransfer&&(t.dataTransfer.dropEffect=`move`);let n=t.currentTarget;if(!n)return;let r=n.getBoundingClientRect();U.value=t.clientY<r.top+r.height/2?e:e+1}function dt(e){if(e.preventDefault(),!B.value||H.value===null||U.value===null)return;let t=H.value,n=U.value;if(n>t&&--n,n===t){H.value=null,U.value=null;return}let r=B.value.conditions.splice(t,1)[0];if(!r){H.value=null,U.value=null;return}B.value.conditions.splice(n,0,r),H.value=null,U.value=null}function ft(){H.value=null,U.value=null}function pt(e){Ke(e)}function mt(e){if(!e.conditions.some(e=>e.field===`channel_message_body`))return null;let t=e.conditions.findIndex(e=>e.field===`channel_message_body`);return t<=0?`For best results, move Channel Message Body lower in the list. Put Channel Decryptable == true or Channel Hash above it.`:e.conditions.slice(0,t).some(e=>e.field===`channel_decryptable`&&e.op===`equals`?e.value.trim().toLowerCase()===`true`:e.field===`channel_hash`)?null:`Change the order: put Channel Decryptable == true or Channel Hash before Channel Message Body.`}function ht(){if(B.value){ee.value=null;try{if(!B.value.name.trim())throw Error(`Rule name is required`);if(!B.value.conditions.length)throw Error(`At least one condition is required`);for(let e of B.value.conditions)if(Ke(e),e.valueSource===`group`){if(!e.groupKind||!e.groupId)throw Error(`Select a group for ${Se(e.field)}`)}else{if(!e.value.trim())throw Error(`Condition value is required for ${Se(e.field)}`);Le(e)}let e=JSON.parse(JSON.stringify(B.value));z.value===null?F.value.push(e):F.value.splice(z.value,1,e),Ye(),at()}catch(e){ee.value=e instanceof Error?e.message:`Failed to save rule`}}}function gt(e){F.value.splice(e,1),Ye()}function _t(e,t){let n=e+t;if(n<0||n>=F.value.length)return;let r=F.value[e];F.value[e]=F.value[n],F.value[n]=r,Ye()}function vt(e){let t={policy_engine:{enabled:!1,default_action:`allow`,rules:[],objects:{}},groups:{channel_hashes:[],pubkeys:[]}};if(!e||typeof e!=`object`)return t;let n=e,r=n.policy_engine??{},i=n.groups??{},a={channel_hashes:Array.isArray(i.channel_hashes)?i.channel_hashes:[],pubkeys:Array.isArray(i.pubkeys)?i.pubkeys:[]};return{policy_file:typeof n.policy_file==`string`?n.policy_file:void 0,exists:!!n.exists,policy_engine:{enabled:!!r.enabled,default_action:typeof r.default_action==`string`?r.default_action:`allow`,rules:Array.isArray(r.rules)?r.rules:[],objects:r.objects&&typeof r.objects==`object`?r.objects:{}},groups:a}}async function yt(){s.value=!0,m.value=null,f.value=null;try{let e=await R.getPolicyDocument();if(!e.success||!e.data)throw Error(e.error||`Failed to load policy document`);oe(vt(e.data)),se()}catch(e){m.value=ye(e,`Failed to load policy`)}finally{s.value=!1}}async function bt(){m.value=null,f.value=null,I.value=null;try{let e=Qe(),t=await R.validatePolicyDocument({policy_engine:{enabled:T.value.enabled,default_action:T.value.default_action,rules:e,objects:de()}});if(!t.success||!t.data)throw Error(t.error||`Validation failed`);if(t.data.valid){let n=t.data.effective;I.value=`Valid policy. Enabled=${n?.enabled?`yes`:`no`}, default=${n?.default_action||T.value.default_action}, rules=${n?.rule_count??e.length}`;return}throw Error(t.data.error||`Invalid policy payload`)}catch(e){m.value=ye(e,`Validation failed`)}}async function xt(){d.value=!0,m.value=null,f.value=null,I.value=null;try{let e=Qe(),t={policy_engine:{enabled:T.value.enabled,default_action:T.value.default_action,rules:e,objects:de()},groups:E.value},n=await R.updatePolicyDocument(t);if(!n.success)throw Error(n.error||`Failed to save policy`);let r=n.message||`Settings saved successfully`;return await yt(),u.value=!1,ce(r),!0}catch(e){return m.value=ye(e,`Failed to save policy`),!1}finally{d.value=!1}}function St(){m.value=null,f.value=null;let e=te.value.friendly_name.trim();if(!e){m.value=`Group friendly name is required`;return}let t=E.value[G.value],n=ae(Q(e,`${G.value}_group`),t.map(e=>e.id));t.push({id:n,friendly_name:e,description:te.value.description.trim()||void 0,entries:[]}),K.value=n,te.value={friendly_name:``,description:``},I.value=null}function Ct(e){m.value=null,f.value=null,E.value[G.value]=E.value[G.value].filter(t=>t.id!==e),I.value=null}function wt(){if(m.value=null,f.value=null,!xe.value){m.value=`Select a group first`;return}let e=q.value.friendly_name.trim(),t=q.value.value.trim();if(!e||!t){m.value=`Entry friendly name and value are required`;return}let n=ae(Q(e||t,`entry`),xe.value.entries.map(e=>e.id));xe.value.entries.push({id:n,friendly_name:e,value:t}),q.value={friendly_name:``,value:``},I.value=null}function Tt(e){if(m.value=null,f.value=null,!xe.value){m.value=`Select a group first`;return}xe.value.entries=xe.value.entries.filter(t=>t.id!==e),I.value=null}return e(yt),(e,n)=>(a(),C(x,null,[v(fe,{show:c(me),"is-saving":d.value,label:`Policy Engine settings`,onDiscard:c(ge),onSave:c(_e),onCancel:c(ve)},null,8,[`show`,`is-saving`,`onDiscard`,`onSave`,`onCancel`]),S(`div`,op,[S(`div`,sp,[n[22]||=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`},` Policy Engine `),S(`p`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},` Policy and object management with chained rule conditions `)],-1),S(`div`,cp,[u.value?(a(),C(x,{key:1},[S(`button`,{class:`cfg-btn-secondary`,disabled:d.value,onClick:le},` Cancel `,8,up),S(`button`,{class:`cfg-btn-primary`,disabled:d.value,onClick:xt},l(d.value?`Saving…`:`Save Changes`),9,dp)],64)):(a(),C(`button`,{key:0,class:`cfg-btn-primary`,disabled:s.value,onClick:$},` Edit Settings `,8,lp))])]),m.value?(a(),C(`div`,fp,l(m.value),1)):_(``,!0),f.value?(a(),C(`div`,pp,l(f.value),1)):_(``,!0),I.value?(a(),C(`div`,mp,l(I.value),1)):_(``,!0),s.value?(a(),C(`div`,hp,[v(W),n[23]||=S(`span`,{class:`ml-2 text-content-secondary dark:text-content-muted`},`Loading policy…`,-1)])):(a(),C(x,{key:4},[S(`div`,gp,[S(`div`,_p,[S(`button`,{class:p([`px-3 py-1.5 text-xs sm:text-sm rounded-md border transition-colors`,w.value===`policy`?`border-primary/60 text-primary bg-primary/10`:`border-stroke-subtle dark:border-stroke/30 text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-primary`]),onClick:n[0]||=e=>w.value=`policy`},` Policy `,2),S(`button`,{class:p([`px-3 py-1.5 text-xs sm:text-sm rounded-md border transition-colors`,w.value===`objects`?`border-primary/60 text-primary bg-primary/10`:`border-stroke-subtle dark:border-stroke/30 text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-primary`]),onClick:n[1]||=e=>w.value=`objects`},` Objects `,2)])]),w.value===`policy`?(a(),C(`div`,vp,[S(`div`,yp,[S(`div`,bp,[S(`div`,xp,[n[25]||=S(`div`,null,[S(`label`,{class:`cfg-label`},`Policy Engine Enabled`),S(`p`,{class:`mt-1 text-xs text-content-muted dark:text-content-muted`},`Enable policy enforcement for incoming packets.`)],-1),S(`label`,Sp,[i(S(`input`,{"onUpdate:modelValue":n[2]||=e=>T.value.enabled=e,type:`checkbox`,disabled:!u.value||d.value,class:`h-4 w-4 rounded border-stroke-subtle dark:border-stroke/30 accent-primary`},null,8,Cp),[[M,T.value.enabled]]),n[24]||=S(`span`,null,`Enable policy enforcement`,-1)])]),S(`div`,wp,[n[26]||=S(`div`,null,[S(`label`,{class:`cfg-label`},`Default Action`),S(`p`,{class:`mt-1 text-xs text-content-muted dark:text-content-muted`},`Applied when no policy rule matches.`)],-1),i(S(`select`,{"onUpdate:modelValue":n[3]||=e=>T.value.default_action=e,class:`cfg-select w-full md:max-w-sm`,disabled:!u.value||d.value},[(a(),C(x,null,t(ne,e=>S(`option`,{key:e.value,value:e.value},l(e.label),9,Ep)),64))],8,Tp),[[D,T.value.default_action]])])]),S(`div`,Dp,[S(`div`,Op,[n[27]||=S(`label`,{class:`cfg-label`},`Policy Rules`,-1),S(`div`,kp,[S(`button`,{class:`cfg-btn-secondary text-xs`,disabled:!u.value||d.value,onClick:rt},`Add Rule`,8,Ap),S(`button`,{class:`cfg-btn-secondary text-xs`,disabled:d.value,onClick:n[4]||=e=>P.value=!P.value},l(P.value?`Hide JSON`:`Advanced JSON`),9,jp)])]),S(`div`,Mp,[S(`table`,Np,[n[29]||=S(`thead`,{class:`bg-background-mute/80 dark:bg-white/5 backdrop-blur`},[S(`tr`,null,[S(`th`,{class:`w-16 px-3 py-2 text-left text-[11px] font-semibold uppercase tracking-[0.18em] text-content-muted dark:text-content-muted`},`Order`),S(`th`,{class:`w-14 px-3 py-2 text-left text-[11px] font-semibold uppercase tracking-[0.18em] text-content-muted dark:text-content-muted`},`On`),S(`th`,{class:`w-44 px-3 py-2 text-left text-[11px] font-semibold uppercase tracking-[0.18em] text-content-muted dark:text-content-muted`},`Name`),S(`th`,{class:`px-3 py-2 text-left text-[11px] font-semibold uppercase tracking-[0.18em] text-content-muted dark:text-content-muted`},`Logic`),S(`th`,{class:`w-28 px-3 py-2 text-left text-[11px] font-semibold uppercase tracking-[0.18em] text-content-muted dark:text-content-muted`},`Action`),S(`th`,{class:`w-48 px-3 py-2 text-right text-[11px] font-semibold uppercase tracking-[0.18em] text-content-muted dark:text-content-muted`},`Controls`)])],-1),S(`tbody`,null,[(a(!0),C(x,null,t(F.value,(e,t)=>(a(),C(`tr`,{key:`${e.id}-${t}`,class:`border-t border-stroke-subtle/70 dark:border-stroke/15 odd:bg-background-mute/20 dark:odd:bg-white/[0.02] hover:bg-primary/5 dark:hover:bg-white/[0.04] transition-colors`},[S(`td`,Pp,l(t+1),1),S(`td`,Fp,[S(`span`,{class:p([`inline-flex h-5 w-5 items-center justify-center rounded-md border text-[10px] font-semibold`,e.enabled?`border-emerald-500/30 bg-emerald-500/10 text-emerald-600 dark:text-emerald-300`:`border-stroke-subtle/70 bg-background-mute text-content-muted dark:border-stroke/20 dark:bg-white/5 dark:text-content-muted`]),title:e.enabled?`Enabled`:`Disabled`},l(e.enabled?`✓`:`—`),11,Ip)]),S(`td`,Lp,[S(`span`,{class:`block truncate font-medium`,title:e.name},l(e.name),9,Rp)]),S(`td`,zp,[S(`span`,{class:`block truncate font-mono leading-5`,title:et(e)},l(et(e)),9,Bp)]),S(`td`,Vp,[S(`span`,{class:p([`inline-flex items-center rounded-full border px-2.5 py-1 text-xs font-semibold uppercase tracking-wide`,nt(e.action)]),title:e.action},l(tt(e.action)),11,Hp)]),S(`td`,Up,[S(`div`,Wp,[S(`button`,{class:`cfg-btn-secondary text-xs px-2 py-1`,disabled:!u.value||d.value,onClick:e=>_t(t,-1)},`▲`,8,Gp),S(`button`,{class:`cfg-btn-secondary text-xs px-2 py-1`,disabled:!u.value||d.value,onClick:e=>_t(t,1)},`▼`,8,Kp),S(`button`,{class:`cfg-btn-secondary text-xs px-2 py-1`,disabled:!u.value||d.value,onClick:e=>it(t)},`Edit`,8,qp),S(`button`,{class:`text-xs px-2 py-1 rounded border border-red-500/50 text-red-600 dark:text-red-400 hover:bg-red-500/10 disabled:opacity-40`,disabled:!u.value||d.value,onClick:e=>gt(t)},`Del`,8,Jp)])])]))),128)),F.value.length?_(``,!0):(a(),C(`tr`,Yp,[...n[28]||=[S(`td`,{colspan:`6`,class:`px-3 py-8 text-center text-xs text-content-muted dark:text-content-muted`},`No rules yet. Add your first rule.`,-1)]]))])])]),n[31]||=S(`p`,{class:`text-xs text-content-muted dark:text-content-muted`},` Rules are evaluated top to bottom. First matching rule wins. `,-1),P.value?(a(),C(`div`,Xp,[n[30]||=S(`label`,{class:`cfg-label`},`Advanced JSON Editor`,-1),i(S(`textarea`,{"onUpdate:modelValue":n[5]||=e=>N.value=e,rows:`12`,spellcheck:`false`,disabled:!u.value||d.value,class:`cfg-textarea font-mono text-xs`,placeholder:`[{"id":1,"if":{"all":[{"field":"hop_count","op":"greater_than","value":4}]},"then":{"action":"drop"}}]`},null,8,Zp),[[j,N.value]]),S(`div`,Qp,[S(`button`,{class:`cfg-btn-secondary text-xs`,disabled:!u.value||d.value,onClick:Ze},`Apply JSON To Table`,8,$p)])])):_(``,!0)]),S(`div`,em,[S(`button`,{class:`cfg-btn-secondary`,disabled:d.value||!u.value,onClick:bt},`Validate`,8,tm)])])])):(a(),C(`div`,nm,[S(`div`,rm,[S(`div`,im,[S(`button`,{class:p([`px-3 py-1.5 text-xs sm:text-sm rounded-md border transition-colors`,G.value===`channel_hashes`?`border-primary/60 text-primary bg-primary/10`:`border-stroke-subtle dark:border-stroke/30 text-content-secondary dark:text-content-muted`]),onClick:n[6]||=e=>G.value=`channel_hashes`},` Channel Hash Groups `,2),S(`button`,{class:p([`px-3 py-1.5 text-xs sm:text-sm rounded-md border transition-colors`,G.value===`pubkeys`?`border-primary/60 text-primary bg-primary/10`:`border-stroke-subtle dark:border-stroke/30 text-content-secondary dark:text-content-muted`]),onClick:n[7]||=e=>G.value=`pubkeys`},` Pubkey Groups `,2)])]),S(`div`,am,[S(`div`,om,[S(`div`,sm,[n[32]||=S(`h4`,{class:`text-sm font-semibold text-content-primary dark:text-content-primary`},`Groups`,-1),S(`span`,cm,l(be.value.length)+` total`,1)]),S(`div`,lm,[(a(!0),C(x,null,t(be.value,e=>(a(),C(`button`,{key:e.id,class:p([`w-full text-left rounded-lg border p-3 transition-colors`,K.value===e.id?`border-primary/60 bg-primary/10`:`border-stroke-subtle dark:border-stroke/20 bg-background-mute dark:bg-white/5 hover:bg-stroke-subtle dark:hover:bg-white/10`]),onClick:t=>K.value=e.id},[S(`div`,dm,[S(`div`,null,[S(`p`,fm,l(e.friendly_name),1),S(`p`,pm,l(e.id),1)]),S(`span`,mm,l(e.entries.length),1)])],10,um))),128)),be.value.length?_(``,!0):(a(),C(`div`,hm,` No groups yet `))]),S(`div`,gm,[n[33]||=S(`h5`,{class:`text-xs font-semibold uppercase tracking-wide text-content-muted dark:text-content-muted`},`Create Group`,-1),i(S(`input`,{"onUpdate:modelValue":n[8]||=e=>te.value.friendly_name=e,class:`cfg-input`,disabled:!u.value||d.value,placeholder:`Friendly name`},null,8,_m),[[j,te.value.friendly_name]]),i(S(`input`,{"onUpdate:modelValue":n[9]||=e=>te.value.description=e,class:`cfg-input`,disabled:!u.value||d.value,placeholder:`Description (optional)`},null,8,vm),[[j,te.value.description]]),S(`button`,{class:`cfg-btn-primary w-full`,disabled:!u.value||d.value,onClick:St},`Add Group`,8,ym)])]),S(`div`,bm,[S(`div`,xm,[S(`h4`,Sm,l(xe.value?xe.value.friendly_name:`Entries`),1),xe.value?(a(),C(`button`,{key:0,class:`text-xs px-2.5 py-1 rounded border border-red-500/50 text-red-600 dark:text-red-400 hover:bg-red-500/10`,disabled:!u.value||d.value,onClick:n[10]||=e=>Ct(xe.value.id)},` Delete Group `,8,Cm)):_(``,!0)]),xe.value?(a(),C(`div`,wm,[S(`table`,Tm,[n[35]||=S(`thead`,{class:`bg-background-mute dark:bg-white/5`},[S(`tr`,null,[S(`th`,{class:`text-left px-3 py-2 text-xs font-semibold uppercase tracking-wide text-content-muted dark:text-content-muted`},`Name`),S(`th`,{class:`text-left px-3 py-2 text-xs font-semibold uppercase tracking-wide text-content-muted dark:text-content-muted`},`Value`),S(`th`,{class:`text-right px-3 py-2 text-xs font-semibold uppercase tracking-wide text-content-muted dark:text-content-muted`},`Actions`)])],-1),S(`tbody`,null,[(a(!0),C(x,null,t(xe.value.entries,e=>(a(),C(`tr`,{key:e.id,class:`border-t border-stroke-subtle dark:border-stroke/15`},[S(`td`,Em,l(e.friendly_name),1),S(`td`,Dm,l(e.value),1),S(`td`,Om,[S(`button`,{class:`text-xs px-2.5 py-1 rounded border border-red-500/50 text-red-600 dark:text-red-400 hover:bg-red-500/10`,disabled:!u.value||d.value,onClick:t=>Tt(e.id)},` Remove `,8,km)])]))),128)),xe.value.entries.length?_(``,!0):(a(),C(`tr`,Am,[...n[34]||=[S(`td`,{colspan:`3`,class:`px-3 py-8 text-center text-xs text-content-muted dark:text-content-muted`},`No entries in this group`,-1)]]))])])])):(a(),C(`div`,jm,` Select a group to manage entries `)),xe.value?(a(),C(`div`,Mm,[n[36]||=S(`h5`,{class:`text-xs font-semibold uppercase tracking-wide text-content-muted dark:text-content-muted`},`Add Entry`,-1),S(`div`,Nm,[i(S(`input`,{"onUpdate:modelValue":n[11]||=e=>q.value.friendly_name=e,class:`cfg-input`,disabled:!u.value||d.value,placeholder:`Friendly name`},null,8,Pm),[[j,q.value.friendly_name]]),i(S(`input`,{"onUpdate:modelValue":n[12]||=e=>q.value.value=e,class:`cfg-input font-mono`,disabled:!u.value||d.value,placeholder:G.value===`channel_hashes`?`0x...`:`0xaabbccdd`},null,8,Fm),[[j,q.value.value]])]),S(`button`,{class:`cfg-btn-primary`,disabled:!u.value||d.value,onClick:wt},`Add Entry`,8,Im)])):_(``,!0)])])]))],64)),L.value&&B.value?(a(),C(`div`,{key:5,class:`fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm`,onClick:A(at,[`self`])},[S(`div`,Lm,[S(`div`,Rm,[S(`div`,null,[S(`h3`,zm,l(z.value===null?`Add Policy Rule`:`Edit Policy Rule`),1),S(`p`,Bm,` Choose match logic, then add one or more conditions. `+l(B.value.matchMode===`all`?`ALL`:`ANY`)+` conditions must match. `,1)]),S(`div`,Vm,[S(`button`,{class:p([`w-7 h-7 rounded-full border border-stroke-subtle dark:border-stroke/30 text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-primary hover:bg-background-mute dark:hover:bg-white/10 text-sm font-semibold`,V.value?`bg-primary/10 text-primary border-primary/50`:``]),title:`Match Field Logic Matrix`,onClick:n[13]||=e=>V.value=!V.value},` i `,2),S(`button`,{class:`cfg-btn-secondary text-xs`,onClick:at},`Close`)])]),V.value?(a(),C(`div`,Hm,[S(`div`,Um,[n[37]||=S(`h4`,{class:`text-sm font-semibold text-content-primary dark:text-content-primary`},`Match Field Logic Matrix`,-1),S(`button`,{class:`cfg-btn-secondary text-xs`,onClick:n[14]||=e=>V.value=!1},`Hide`)]),S(`div`,Wm,[S(`table`,Gm,[n[38]||=S(`thead`,{class:`bg-background-mute dark:bg-white/5`},[S(`tr`,null,[S(`th`,{class:`px-2 py-2 text-left font-semibold uppercase tracking-wide text-content-muted dark:text-content-muted`},`Field`),S(`th`,{class:`px-2 py-2 text-left font-semibold uppercase tracking-wide text-content-muted dark:text-content-muted`},`Value Types`),S(`th`,{class:`px-2 py-2 text-left font-semibold uppercase tracking-wide text-content-muted dark:text-content-muted`},`Operators`),S(`th`,{class:`px-2 py-2 text-left font-semibold uppercase tracking-wide text-content-muted dark:text-content-muted`},`Group Sources`)])],-1),S(`tbody`,null,[(a(),C(x,null,t(ie,e=>S(`tr`,{key:e.value,class:`border-t border-stroke-subtle dark:border-stroke/15`},[S(`td`,Km,l(e.label),1),S(`td`,qm,l(e.valueTypes.join(`, `)),1),S(`td`,Jm,l(e.operators.map(Ce).join(`, `)),1),S(`td`,Ym,l(e.groupKinds?.join(`, `)||`None`),1)])),64))])])])])):_(``,!0),ee.value?(a(),C(`div`,Xm,l(ee.value),1)):_(``,!0),S(`div`,Zm,[S(`div`,Qm,[n[39]||=S(`label`,{class:`cfg-label`},`Rule Name`,-1),i(S(`input`,{"onUpdate:modelValue":n[15]||=e=>B.value.name=e,class:`cfg-input mt-1`,placeholder:`Block noisy channel route`},null,512),[[j,B.value.name]])]),S(`div`,null,[n[41]||=S(`label`,{class:`cfg-label`},`Match Logic`,-1),i(S(`select`,{"onUpdate:modelValue":n[16]||=e=>B.value.matchMode=e,class:`cfg-select mt-1`},[...n[40]||=[S(`option`,{value:`all`},`ALL conditions (AND)`,-1),S(`option`,{value:`any`},`ANY condition (OR)`,-1)]],512),[[D,B.value.matchMode]])]),S(`div`,null,[n[42]||=S(`label`,{class:`cfg-label`},`Action`,-1),i(S(`select`,{"onUpdate:modelValue":n[17]||=e=>B.value.action=e,class:`cfg-select mt-1`},[(a(),C(x,null,t(ne,e=>S(`option`,{key:e.value,value:e.value},l(e.label),9,$m)),64))],512),[[D,B.value.action]])])]),S(`label`,eh,[i(S(`input`,{"onUpdate:modelValue":n[18]||=e=>B.value.enabled=e,type:`checkbox`},null,512),[[M,B.value.enabled]]),n[43]||=b(` Rule enabled `,-1)]),S(`div`,th,[S(`div`,{class:`flex items-center justify-between`},[n[44]||=S(`h4`,{class:`text-sm font-semibold text-content-primary dark:text-content-primary`},`Conditions`,-1),S(`button`,{class:`cfg-btn-secondary text-xs`,onClick:ot},`Add Condition`)]),mt(B.value)?(a(),C(`div`,nh,l(mt(B.value)),1)):_(``,!0),S(`div`,rh,[S(`table`,ih,[S(`thead`,ah,[S(`tr`,null,[n[45]||=S(`th`,{class:`px-2 py-2 text-left text-xs font-semibold uppercase tracking-wide text-content-muted dark:text-content-muted`},`Drag`,-1),n[46]||=S(`th`,{class:`px-2 py-2 text-left text-xs font-semibold uppercase tracking-wide text-content-muted dark:text-content-muted`},`Field`,-1),n[47]||=S(`th`,{class:`px-2 py-2 text-left text-xs font-semibold uppercase tracking-wide text-content-muted dark:text-content-muted`},`Operator`,-1),Y.value?(a(),C(`th`,oh,`Source`)):_(``,!0),n[48]||=S(`th`,{class:`px-2 py-2 text-left text-xs font-semibold uppercase tracking-wide text-content-muted dark:text-content-muted`},`Value`,-1),n[49]||=S(`th`,{class:`px-2 py-2 text-left text-xs font-semibold uppercase tracking-wide text-content-muted dark:text-content-muted`},`Type`,-1),n[50]||=S(`th`,{class:`px-2 py-2 text-right text-xs font-semibold uppercase tracking-wide text-content-muted dark:text-content-muted`},`Action`,-1)])]),S(`tbody`,null,[(a(!0),C(x,null,t(B.value.conditions,(e,r)=>(a(),C(`tr`,{key:e.id,class:p([`border-t border-stroke-subtle dark:border-stroke/15 transition-colors`,{"opacity-60":H.value===r,"!border-t-2 !border-primary":U.value===r&&H.value!==null}]),onDragover:e=>ut(r,e),onDrop:n[19]||=e=>dt(e)},[S(`td`,ch,[S(`button`,{type:`button`,draggable:`true`,class:`h-8 w-8 inline-flex items-center justify-center rounded border border-stroke-subtle dark:border-stroke/20 text-content-secondary dark:text-content-muted hover:bg-background-mute dark:hover:bg-white/10 cursor-grab active:cursor-grabbing`,title:`Drag to reorder`,onDragstart:e=>lt(r,e),onDragend:ft},` ☰ `,40,lh)]),S(`td`,uh,[i(S(`select`,{"onUpdate:modelValue":t=>e.field=t,class:`cfg-select h-8 text-xs`,onChange:t=>pt(e)},[(a(),C(x,null,t(ie,e=>S(`option`,{key:e.value,value:e.value},l(e.label),9,fh)),64))],40,dh),[[D,e.field]])]),S(`td`,ph,[i(S(`select`,{"onUpdate:modelValue":t=>e.op=t,class:`cfg-select h-8 text-xs`},[(a(!0),C(x,null,t(we(e.field),e=>(a(),C(`option`,{key:e,value:e},l(Ce(e)),9,hh))),128))],8,mh),[[D,e.op]])]),Y.value?(a(),C(`td`,gh,[i(S(`select`,{"onUpdate:modelValue":t=>e.valueSource=t,class:`cfg-select h-8 text-xs`,disabled:!Oe(e.field)},[n[51]||=S(`option`,{value:`literal`},`Literal`,-1),Oe(e.field)?(a(),C(`option`,vh,`Group`)):_(``,!0)],8,_h),[[D,e.valueSource]])])):_(``,!0),S(`td`,yh,[Y.value&&e.valueSource===`group`&&Oe(e.field)?(a(),C(`div`,bh,[i(S(`select`,{"onUpdate:modelValue":t=>e.groupKind=t,class:`cfg-select h-8 text-xs`},[(a(!0),C(x,null,t(Ee(e.field),e=>(a(),C(`option`,{key:e,value:e},l(e),9,Sh))),128))],8,xh),[[D,e.groupKind]]),i(S(`select`,{"onUpdate:modelValue":t=>e.groupId=t,class:`cfg-select h-8 text-xs`},[(a(!0),C(x,null,t(De(e.groupKind),e=>(a(),C(`option`,{key:e.id,value:e.id},l(e.friendly_name),9,wh))),128))],8,Ch),[[D,e.groupId]])])):(a(),C(`div`,Th,[ke(e).length?(a(),C(`select`,{key:0,class:`cfg-select h-8 text-xs`,onChange:t=>Ae(e,String(t.target.value))},[n[52]||=S(`option`,{value:``},`Lookup value...`,-1),(a(!0),C(x,null,t(ke(e),t=>(a(),C(`option`,{key:`${e.id}-${t.value}`,value:t.value},l(t.label),9,Dh))),128))],40,Eh)):_(``,!0),ze(e)?i((a(),C(`textarea`,{key:1,"onUpdate:modelValue":t=>e.value=t,class:`cfg-input min-h-[72px] text-xs font-mono py-2`,placeholder:Re(e)},null,8,Oh)),[[j,e.value]]):i((a(),C(`input`,{key:2,"onUpdate:modelValue":t=>e.value=t,class:`cfg-input h-8 text-xs font-mono`,placeholder:Re(e)},null,8,kh)),[[j,e.value]]),je(e.field)?(a(),C(`p`,Ah," Use hex only. All hashes in one condition must be the same width: 1 byte (`0x42`), 2 bytes (`0x0042`), or 3 bytes (`0x000042`). ")):_(``,!0)]))]),S(`td`,jh,[i(S(`select`,{"onUpdate:modelValue":t=>e.valueType=t,class:`cfg-select h-8 text-xs`,disabled:Y.value&&e.valueSource===`group`},[(a(!0),C(x,null,t(Te(e.field),e=>(a(),C(`option`,{key:e,value:e},l(e),9,Nh))),128))],8,Mh),[[D,e.valueType]])]),S(`td`,Ph,[S(`div`,Fh,[S(`button`,{class:`text-xs px-2 py-1 rounded border border-stroke-subtle dark:border-stroke/20 text-content-secondary dark:text-content-muted hover:bg-background-mute dark:hover:bg-white/10 disabled:opacity-40`,disabled:r===0,title:`Move condition up`,"aria-label":`Move condition up`,onClick:e=>ct(r,-1)},` ▲ `,8,Ih),S(`button`,{class:`text-xs px-2 py-1 rounded border border-stroke-subtle dark:border-stroke/20 text-content-secondary dark:text-content-muted hover:bg-background-mute dark:hover:bg-white/10 disabled:opacity-40`,disabled:r===B.value.conditions.length-1,title:`Move condition down`,"aria-label":`Move condition down`,onClick:e=>ct(r,1)},` ▼ `,8,Lh),S(`button`,{class:`text-xs px-2 py-1 rounded border border-red-500/50 text-red-600 dark:text-red-400 hover:bg-red-500/10`,onClick:e=>st(r)},`Del`,8,Rh)])])],42,sh))),128)),H.value!==null&&U.value===B.value.conditions.length?(a(),C(`tr`,{key:0,class:`border-t-2 border-primary`,onDragover:n[20]||=A(()=>{},[`prevent`]),onDrop:n[21]||=e=>dt(e)},[S(`td`,{colspan:X.value,class:`px-2 py-0`},[...n[53]||=[S(`div`,{class:`h-0`},null,-1)]],8,zh)],32)):_(``,!0)])])])]),S(`div`,{class:`flex justify-end gap-2`},[S(`button`,{class:`cfg-btn-secondary`,onClick:at},`Cancel`),S(`button`,{class:`cfg-btn-primary`,onClick:ht},`Save Rule`)])])])):_(``,!0)])],64))}}),Vh={class:`p-3 sm:p-6 space-y-4 sm:space-y-6`},Hh={class:`flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},Uh={class:`glass-card rounded-[15px] p-3 sm:p-6 mt-4 sm:mt-6`},Wh={key:0,class:`flex items-center justify-center py-12`},Gh={class:`text-center`},Kh={key:1,class:`flex items-center justify-center py-12`},qh={class:`text-center`},Jh={class:`text-content-secondary dark:text-content-muted text-sm mb-4`},Yh={key:2,class:`min-h-[400px]`},Xh=`radio`,Zh=f({name:`ConfigurationView`,__name:`Configuration`,setup(t){let n=F(),i=ee(),s=V(),d=o(q(`configuration_activeTab`,Xh)),f=o(!1),p=o(null),m=o(null),y=o(null),b=o(null),x=o(null),w=o(null),T=o(null),E=o(null),D={radio:p,"radio-hardware":m,repeater:y,advert:b,duty:x,delays:w,transport:T,observer:E};function O(){let e=D[d.value]?.value;if(!e)return!1;let t=e.isEditing;return typeof t==`boolean`?t:t.value}function k(e){let t=D[d.value]?.value;t?t.requestLeave(e):e()}let A=new Set([`radio`,`radio-hardware`,`repeater`,`duty`,`delays`,`advert`,`transport`,`api-tokens`,`web`,`observer`,`policy-engine`,`backup`,`database`,`memory`]);function j(e){return e&&A.has(e)?e:q(`configuration_activeTab`,Xh)}return d.value=j(n.query.tab),h(d,e=>G(`configuration_activeTab`,e)),I((e,t,n)=>{let r=j(e.query.tab);if(r===d.value){n();return}if(O()){k(()=>{d.value=r,n()});return}d.value=r,n()}),e(async()=>{if(i.stats)f.value=!0;else try{await s.ensure(`stats`)}catch(e){console.error(`Failed to load configuration data:`,e)}finally{f.value=!0}}),(e,t)=>{let n=g(`router-link`);return a(),C(`div`,Vh,[S(`div`,Hh,[t[2]||=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),f.value&&!(c(i).stats?.config?.radio)?.cad?.peak_threshold?(a(),u(n,{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:r(()=>[...t[1]||=[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})):_(``,!0)]),S(`div`,Uh,[!f.value&&c(i).isLoading?(a(),C(`div`,Wh,[S(`div`,Gh,[v(W,{class:`mx-auto mb-4`}),t[3]||=S(`div`,{class:`text-content-secondary dark:text-content-muted`},`Loading configuration...`,-1)])])):f.value&&!c(i).stats?(a(),C(`div`,Kh,[S(`div`,qh,[t[4]||=S(`div`,{class:`text-accent-red mb-2`},`Failed to load configuration`,-1),S(`div`,Jh,l(c(i).error),1),S(`button`,{onClick:t[0]||=e=>c(i).fetchStats(),class:`btn-primary`},`Retry`)])])):(a(),C(`div`,Yh,[d.value===`radio`?(a(),u(ct,{ref_key:`radioRef`,ref:p,key:`radio-settings`},null,512)):_(``,!0),d.value===`radio-hardware`?(a(),u(Vn,{ref_key:`radioHardwareRef`,ref:m,key:`radio-hardware-settings`},null,512)):_(``,!0),d.value===`repeater`?(a(),u(Vr,{ref_key:`repeaterRef`,ref:y,key:`repeater-settings`},null,512)):_(``,!0),d.value===`advert`?(a(),u(Ic,{ref_key:`advertRef`,ref:b,key:`advert-settings`},null,512)):_(``,!0),d.value===`duty`?(a(),u(ti,{ref_key:`dutyRef`,ref:x,key:`duty-cycle`},null,512)):_(``,!0),d.value===`delays`?(a(),u(mi,{ref_key:`delaysRef`,ref:w,key:`transmission-delays`},null,512)):_(``,!0),d.value===`transport`?(a(),u(yo,{ref_key:`transportRef`,ref:T,key:`transport-keys`},null,512)):_(``,!0),d.value===`api-tokens`?(a(),u(Xo,{key:`api-tokens`})):_(``,!0),d.value===`web`?(a(),u(ws,{key:`web-settings`})):_(``,!0),d.value===`observer`?(a(),u(au,{ref_key:`letsMeshRef`,ref:E,key:`letsmesh-settings`},null,512)):_(``,!0),d.value===`policy-engine`?(a(),u(Bh,{key:`policy-engine`})):_(``,!0),d.value===`backup`?(a(),u(dd,{key:`backup-restore`})):_(``,!0),d.value===`database`?(a(),u(pf,{key:`database-management`})):_(``,!0),d.value===`memory`?(a(),u(ap,{key:`memory-debug`})):_(``,!0)]))])])}}});export{Zh as default}; |