Files
pyMC_Repeater/repeater/web/html/assets/Configuration-COSqDNV7.js
2026-03-27 12:36:25 +00:00

3 lines
208 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/leaflet-src-BtisrQHC.js","assets/_commonjsHelpers-CqkleIqs.js"])))=>i.map(i=>d[i]);
import{a as re,M as be,c as V,r as l,E as me,e as r,h as C,f as e,t as s,F as W,w as R,v as K,i as ee,s as pe,l as E,L as Q,q as t,P as Ee,x as le,H as fe,S as Ae,y as we,b as Be,g as X,N as Me,k as q,O as Le,z as ke,d as Ne,U as Ce,m as ge,V as Se,T as he,j as ae,W as ye,o as ve,u as ce,X as Pe,Q as ie}from"./index-xzvnOpJo.js";/* empty css */import{_ as Fe}from"./ConfirmDialog.vue_vue_type_script_setup_true_lang-7siCLFWH.js";import{g as Ie,s as Re}from"./preferences-DtwbSSgO.js";const ze={class:"space-y-4"},Ve={key:0,class:"bg-green-100 dark:bg-green-500/20 border border-green-500/50 rounded-lg p-3"},De={class:"text-green-600 dark:text-green-400 text-sm"},He={key:1,class:"bg-red-100 dark:bg-red-500/20 border border-red-500/50 rounded-lg p-3"},Ue={class:"text-red-600 dark:text-red-400 text-sm"},Oe={class:"flex justify-end gap-2"},Ke=["disabled"],qe=["disabled"],We={class:"bg-background-mute dark:bg-white/5 rounded-lg p-3 sm:p-4 space-y-3"},Ge={class:"flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1"},Je={key:0,class:"text-content-primary dark:text-content-primary font-mono text-sm"},Ye={key:1,class:"flex items-center gap-2"},Qe={class:"flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1"},Xe={key:0,class:"text-content-primary dark:text-content-primary font-mono text-sm"},Ze={key:1},et=["value"],tt={class:"flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1"},rt={key:0,class:"text-content-primary dark:text-content-primary font-mono text-sm"},ot={key:1},st=["value"],nt={class:"flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1"},at={key:0,class:"text-content-primary dark:text-content-primary font-mono text-sm"},lt={key:1,class:"flex items-center gap-2"},dt={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"},it={key:0,class:"text-content-primary dark:text-content-primary font-mono text-sm"},ut={key:1},ct={class:"flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 gap-1"},mt={class:"text-content-primary dark:text-content-primary font-mono text-sm"},pt={key:2,class:"bg-yellow-500/10 dark:bg-yellow-500/10 border border-yellow-500/30 rounded-lg p-3"},bt=re({__name:"RadioSettings",setup(G){const L=be(),m=V(()=>L.stats?.config?.radio||{}),g=l(!1),y=l(!1),v=l(null),x=l(null),u=l(0),k=l(0),A=l(0),j=l(0),T=l(0),c=l(0),F=[{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"}];me(m,N=>{N&&!g.value&&(u.value=N.frequency?Number((N.frequency/1e6).toFixed(3)):0,k.value=N.spreading_factor??0,A.value=N.bandwidth?Number((N.bandwidth/1e3).toFixed(1)):0,j.value=N.tx_power??0,T.value=N.coding_rate??0,c.value=N.preamble_length??0)},{immediate:!0});const n=V(()=>{const N=m.value.frequency;return N?(N/1e6).toFixed(3)+" MHz":"Not set"}),o=V(()=>{const N=m.value.bandwidth;return N?(N/1e3).toFixed(1)+" kHz":"Not set"}),d=V(()=>{const N=m.value.tx_power;return N!==void 0?N+" dBm":"Not set"}),P=V(()=>{const N=m.value.coding_rate;return N?"4/"+N:"Not set"}),_=V(()=>{const N=m.value.preamble_length;return N?N+" symbols":"Not set"}),a=V(()=>m.value.spreading_factor??"Not set"),i=()=>{g.value=!0,v.value=null,x.value=null},I=()=>{g.value=!1,v.value=null;const N=m.value;u.value=N.frequency?Number((N.frequency/1e6).toFixed(3)):0,k.value=N.spreading_factor??0,A.value=N.bandwidth?Number((N.bandwidth/1e3).toFixed(1)):0,j.value=N.tx_power??0,T.value=N.coding_rate??0,c.value=N.preamble_length??0},J=async()=>{y.value=!0,v.value=null,x.value=null;try{const N={};u.value&&(N.frequency=u.value*1e6),k.value&&(N.spreading_factor=k.value),A.value&&(N.bandwidth=A.value*1e3),j.value&&(N.tx_power=j.value),T.value&&(N.coding_rate=T.value);const H=(await Q.post("/update_radio_config",N)).data;H.message||H.persisted?(x.value=H.message||"Settings saved successfully",g.value=!1,await L.fetchStats(),setTimeout(()=>{x.value=null},3e3)):H.error?v.value=H.error:v.value="Unknown response from server"}catch(N){console.error("Failed to update radio settings:",N);const D=N;v.value=D.response?.data?.error||"Failed to update settings"}finally{y.value=!1}};return(N,D)=>(t(),r("div",ze,[x.value?(t(),r("div",Ve,[e("p",De,s(x.value),1)])):C("",!0),v.value?(t(),r("div",He,[e("p",Ue,s(v.value),1)])):C("",!0),e("div",Oe,[g.value?(t(),r(W,{key:1},[e("button",{onClick:I,disabled:y.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,Ke),e("button",{onClick:J,disabled:y.value,class:"px-3 sm:px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors text-sm disabled:opacity-50 disabled:cursor-not-allowed"},s(y.value?"Saving...":"Save Changes"),9,qe)],64)):(t(),r("button",{key:0,onClick:i,class:"px-3 sm:px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors text-sm"}," Edit Settings "))]),e("div",We,[e("div",Ge,[D[6]||(D[6]=e("span",{class:"text-content-secondary dark:text-content-muted text-xs sm:text-sm"},"Frequency",-1)),g.value?(t(),r("div",Ye,[R(e("input",{"onUpdate:modelValue":D[0]||(D[0]=H=>u.value=H),type:"number",step:"0.001",min:"100",max:"1000",class:"w-32 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary"},null,512),[[K,u.value,void 0,{number:!0}]]),D[5]||(D[5]=e("span",{class:"text-content-muted dark:text-content-muted text-sm"},"MHz",-1))])):(t(),r("div",Je,s(n.value),1))]),e("div",Qe,[D[7]||(D[7]=e("span",{class:"text-content-secondary dark:text-content-muted text-xs sm:text-sm"},"Spreading Factor",-1)),g.value?(t(),r("div",Ze,[R(e("select",{"onUpdate:modelValue":D[1]||(D[1]=H=>k.value=H),class:"px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary"},[(t(),r(W,null,ee([5,6,7,8,9,10,11,12],H=>e("option",{key:H,value:H},s(H),9,et)),64))],512),[[pe,k.value,void 0,{number:!0}]])])):(t(),r("div",Xe,s(a.value),1))]),e("div",tt,[D[8]||(D[8]=e("span",{class:"text-content-secondary dark:text-content-muted text-xs sm:text-sm"},"Bandwidth",-1)),g.value?(t(),r("div",ot,[R(e("select",{"onUpdate:modelValue":D[2]||(D[2]=H=>A.value=H),class:"px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary"},[(t(),r(W,null,ee(F,H=>e("option",{key:H.value,value:H.value},s(H.label),9,st)),64))],512),[[pe,A.value,void 0,{number:!0}]])])):(t(),r("div",rt,s(o.value),1))]),e("div",nt,[D[10]||(D[10]=e("span",{class:"text-content-secondary dark:text-content-muted text-xs sm:text-sm"},"TX Power",-1)),g.value?(t(),r("div",lt,[R(e("input",{"onUpdate:modelValue":D[3]||(D[3]=H=>j.value=H),type:"number",min:"2",max:"30",class:"w-20 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary"},null,512),[[K,j.value,void 0,{number:!0}]]),D[9]||(D[9]=e("span",{class:"text-content-muted dark:text-content-muted text-sm"},"dBm",-1))])):(t(),r("div",at,s(d.value),1))]),e("div",dt,[D[12]||(D[12]=e("span",{class:"text-content-secondary dark:text-content-muted text-xs sm:text-sm"},"Coding Rate",-1)),g.value?(t(),r("div",ut,[R(e("select",{"onUpdate:modelValue":D[4]||(D[4]=H=>T.value=H),class:"px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary"},D[11]||(D[11]=[e("option",{value:5},"4/5",-1),e("option",{value:6},"4/6",-1),e("option",{value:7},"4/7",-1),e("option",{value:8},"4/8",-1)]),512),[[pe,T.value,void 0,{number:!0}]])])):(t(),r("div",it,s(P.value),1))]),e("div",ct,[D[13]||(D[13]=e("span",{class:"text-content-secondary dark:text-content-muted text-xs sm:text-sm"},"Preamble Length",-1)),e("span",mt,s(_.value),1)])]),g.value?(t(),r("div",pt,D[14]||(D[14]=[e("p",{class:"text-yellow-700 dark:text-yellow-400 text-xs"},[e("strong",null,"Note:"),E(" Radio hardware changes (frequency, bandwidth, spreading factor, coding rate) may require a service restart to apply. ")],-1)]))):C("",!0)]))}}),xt={class:"glass-card border border-stroke-subtle dark:border-white/20 rounded-[15px] w-full max-w-3xl max-h-[90vh] flex flex-col shadow-2xl"},vt={class:"flex-1 relative min-h-[400px]"},kt={class:"p-6 border-t border-stroke-subtle dark:border-stroke/10 space-y-4"},gt={class:"grid grid-cols-2 gap-4"},yt=re({__name:"LocationPicker",props:{isOpen:{type:Boolean},latitude:{},longitude:{}},emits:["close","select"],setup(G,{emit:L}){const m=G,g=L,y=l(null),v=l(m.latitude||0),x=l(m.longitude||0);let u=null,k=null;const A=async()=>{if(y.value){j();try{const n=(await Ae(async()=>{const{default:_}=await import("./leaflet-src-BtisrQHC.js").then(a=>a.l);return{default:_}},__vite__mapDeps([0,1]))).default;delete n.Icon.Default.prototype._getIconUrl,n.Icon.Default.mergeOptions({iconRetinaUrl:"https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon-2x.png",iconUrl:"https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon.png",shadowUrl:"https://unpkg.com/leaflet@1.9.4/dist/images/marker-shadow.png"}),await fe();const o=v.value||0,d=x.value||0,P=o===0&&d===0?2:13;u=n.map(y.value).setView([o,d],P);try{const _=n.tileLayer("https://{s}.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}{r}.png",{maxZoom:19,attribution:'&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors &copy; <a href="https://carto.com/attributions">CARTO</a>',errorTileUrl:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=="}),a=n.tileLayer("https://{s}.basemaps.cartocdn.com/dark_only_labels/{z}/{x}/{y}{r}.png",{maxZoom:19,attribution:"",errorTileUrl:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=="});_.addTo(u),a.addTo(u)}catch(_){console.warn("Error loading tiles:",_)}(o!==0||d!==0)&&(k=n.marker([o,d]).addTo(u)),u.on("click",_=>{v.value=_.latlng.lat,x.value=_.latlng.lng,k?k.setLatLng(_.latlng):k=n.marker(_.latlng).addTo(u)}),setTimeout(()=>{u?.invalidateSize()},200)}catch(n){console.error("Failed to initialize map:",n)}}},j=()=>{u&&(u.remove(),u=null,k=null)};me(()=>m.isOpen,async n=>{n?(await fe(),await A()):j()}),me(()=>[m.latitude,m.longitude],([n,o])=>{v.value=n,x.value=o});const T=()=>{g("select",{latitude:v.value,longitude:x.value}),g("close")},c=()=>{g("close")},F=()=>{navigator.geolocation?navigator.geolocation.getCurrentPosition(async n=>{if(v.value=n.coords.latitude,x.value=n.coords.longitude,u){u.setView([v.value,x.value],13);const o=(await Ae(async()=>{const{default:d}=await import("./leaflet-src-BtisrQHC.js").then(P=>P.l);return{default:d}},__vite__mapDeps([0,1]))).default;k?k.setLatLng([v.value,x.value]):k=o.marker([v.value,x.value]).addTo(u)}},n=>{console.error("Error getting location:",n),alert("Unable to get current location. Please check browser permissions.")}):alert("Geolocation is not supported by this browser.")};return Ee(()=>{j()}),(n,o)=>n.isOpen?(t(),r("div",{key:0,class:"fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm",onClick:le(c,["self"])},[e("div",xt,[e("div",{class:"flex items-center justify-between p-6 border-b border-stroke-subtle dark:border-stroke/10"},[o[3]||(o[3]=e("h3",{class:"text-xl font-semibold text-content-primary dark:text-content-primary"},"Select Location",-1)),e("button",{onClick:c,class:"text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-primary transition-colors"},o[2]||(o[2]=[e("svg",{class:"w-6 h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M6 18L18 6M6 6l12 12"})],-1)]))]),e("div",vt,[e("div",{ref_key:"mapContainer",ref:y,class:"absolute inset-0 rounded-b-[15px] overflow-hidden"},null,512)]),e("div",kt,[e("div",gt,[e("div",null,[o[4]||(o[4]=e("label",{class:"block text-sm font-medium text-content-secondary dark:text-content-muted mb-2"},"Latitude",-1)),R(e("input",{"onUpdate:modelValue":o[0]||(o[0]=d=>v.value=d),type:"number",step:"0.000001",class:"w-full px-4 py-2 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary focus:outline-none focus:border-primary",readonly:""},null,512),[[K,v.value,void 0,{number:!0}]])]),e("div",null,[o[5]||(o[5]=e("label",{class:"block text-sm font-medium text-content-secondary dark:text-content-muted mb-2"},"Longitude",-1)),R(e("input",{"onUpdate:modelValue":o[1]||(o[1]=d=>x.value=d),type:"number",step:"0.000001",class:"w-full px-4 py-2 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary focus:outline-none focus:border-primary",readonly:""},null,512),[[K,x.value,void 0,{number:!0}]])])]),e("div",{class:"flex gap-3"},[e("button",{onClick:F,class:"flex-1 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 flex items-center justify-center gap-2"},o[6]||(o[6]=[e("svg",{class:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("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"}),e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M15 11a3 3 0 11-6 0 3 3 0 016 0z"})],-1),E(" Use Current Location ",-1)])),e("button",{onClick:c,class:"px-6 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"}," Cancel "),e("button",{onClick:T,class:"px-6 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors text-sm"}," Select Location ")]),o[7]||(o[7]=e("p",{class:"text-content-muted dark:text-content-muted text-xs text-center"},"Click on the map to select a location",-1))])])])):C("",!0)}}),ft=we(yt,[["__scopeId","data-v-186d3c86"]]),ht={class:"space-y-4"},wt={key:0,class:"bg-green-100 dark:bg-green-500/10 border border-green-300 dark:border-green-500/30 rounded-lg p-3"},_t={class:"text-green-700 dark:text-green-400 text-sm"},$t={key:1,class:"bg-red-100 dark:bg-red-500/10 border border-red-300 dark:border-red-500/30 rounded-lg p-3"},Ct={class:"text-red-700 dark:text-red-400 text-sm"},Mt={class:"flex justify-end gap-2"},At=["disabled"],St=["disabled"],jt={class:"bg-background-mute dark:bg-white/5 rounded-lg p-3 sm:p-4 space-y-3"},Tt={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"},Et={key:0,class:"text-content-primary dark:text-content-primary font-mono text-sm break-all"},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-1"},Lt={class:"text-content-primary dark:text-content-primary font-mono text-xs break-all"},Nt={class:"flex flex-col sm:flex-row sm:justify-between sm:items-start py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1"},Pt={class:"flex flex-col items-end gap-1"},Ft={class:"text-content-primary dark:text-content-primary font-mono text-xs break-all sm:text-right sm:max-w-xs"},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"},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-1"},Vt={key:0,class:"text-content-primary dark:text-content-primary font-mono text-sm"},Dt={key:0,class:"flex justify-end"},Ht={class:"flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1"},Ut={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 border-b border-stroke-subtle dark:border-stroke/10 gap-1"},Kt={key:0,class:"text-content-primary dark:text-content-primary font-mono text-sm"},qt={class:"flex flex-col py-2 gap-2"},Wt={class:"flex flex-col sm:flex-row sm:justify-between sm:items-start gap-1"},Gt={key:0,class:"text-content-primary dark:text-content-primary font-mono text-sm sm:ml-4"},Jt={key:1,class:"flex items-center gap-2"},Yt={class:"bg-surface dark:bg-surface-elevated border border-stroke-subtle dark:border-stroke/20 rounded-[15px] shadow-2xl w-full max-w-md p-6 space-y-4"},Qt={class:"block text-sm font-medium text-content-secondary dark:text-content-muted mb-2"},Xt=["maxlength","disabled"],Zt={key:0,class:"text-red-500 text-xs mt-1"},er={key:1,class:"text-content-muted dark:text-content-muted text-xs mt-1"},tr=["disabled"],rr={key:0,class:"mt-2 bg-amber-500/10 border border-amber-500/30 rounded-lg p-3"},or={key:0,class:"flex items-center gap-3 bg-blue-500/10 border border-blue-500/30 rounded-lg p-3"},sr={class:"text-blue-700 dark:text-blue-400 text-xs font-medium"},nr={class:"text-blue-600 dark:text-blue-500 text-xs mt-0.5"},ar={key:1,class:"bg-red-500/10 border border-red-500/30 rounded-lg p-3"},lr={class:"text-red-600 dark:text-red-400 text-sm"},dr={key:2,class:"bg-green-500/10 border border-green-600/40 dark:border-green-500/30 rounded-lg p-3 space-y-2"},ir={class:"text-green-600 dark:text-green-400 text-sm font-medium"},ur={class:"font-mono text-xs break-all text-content-primary dark:text-content-primary"},cr={key:3,class:"bg-amber-500/10 border border-amber-500/30 rounded-lg p-3"},mr={class:"flex gap-2 mt-3"},pr=["disabled"],br=["disabled"],xr={class:"flex justify-end gap-3 mt-6"},vr=["disabled"],kr=["disabled"],gr=re({__name:"RepeaterSettings",setup(G){const L=be(),m=V(()=>L.stats?.config||{}),g=V(()=>m.value.repeater||{}),y=V(()=>L.stats),v=l(!1),x=l(!1),u=l(null),k=l(null),A=l(!1),j=l(""),T=l(0),c=l(0),F=l(0),n=l(1),o=V(()=>m.value.mesh||{});me([m,g,o],()=>{if(!v.value){j.value=m.value.node_name||"",T.value=g.value.latitude||0,c.value=g.value.longitude||0,F.value=g.value.send_advert_interval_hours||0;const M=o.value.path_hash_mode;n.value=M===0||M===1||M===2?M+1:1}},{immediate:!0});const d=V(()=>m.value.node_name||"Not set"),P=V(()=>y.value?.local_hash||"Not available"),_=V(()=>{const M=y.value?.public_key;return!M||M==="Not set"?"Not set":M}),a=V(()=>{const M=g.value.latitude;return M&&M!==0?M.toFixed(6):"Not set"}),i=V(()=>{const M=g.value.longitude;return M&&M!==0?M.toFixed(6):"Not set"}),I=V(()=>{const M=g.value.mode;return M?M==="no_tx"?"No TX":M.charAt(0).toUpperCase()+M.slice(1):"Not set"}),J=V(()=>{const M=g.value.send_advert_interval_hours;return M===void 0?"Not set":M===0?"Disabled":M+" hour"+(M!==1?"s":"")}),N=V(()=>{const M=o.value.path_hash_mode;return M===0||M===1||M===2?M+1+(M===0?" byte":" bytes"):"Not set"}),D=()=>{v.value=!0,u.value=null,k.value=null},H=()=>{v.value=!1,u.value=null,j.value=m.value.node_name||"",T.value=g.value.latitude||0,c.value=g.value.longitude||0,F.value=g.value.send_advert_interval_hours||0;const M=o.value.path_hash_mode;n.value=M===0||M===1||M===2?M+1:1},se=async()=>{x.value=!0,u.value=null,k.value=null;try{const M={};j.value&&(M.node_name=j.value),M.latitude=T.value,M.longitude=c.value,M.flood_advert_interval_hours=F.value,M.path_hash_mode=n.value-1;const Y=(await Q.post("/update_radio_config",M)).data;Y.message||Y.persisted?(k.value=Y.message||"Settings saved successfully",v.value=!1,await L.fetchStats(),setTimeout(()=>{k.value=null},3e3)):Y.error?u.value=Y.error:u.value="Unknown response from server"}catch(M){console.error("Failed to update repeater settings:",M);const S=M;u.value=S.response?.data?.error||"Failed to update settings"}finally{x.value=!1}},oe=()=>{A.value=!0},z=M=>{T.value=M.latitude,c.value=M.longitude},f=l(!1),$=l(""),w=l(!1),U=l(null),O=l(null),ne=l(!1),ue=l(!1),de=l(!1),xe=l(0);let Z=null;const b=V(()=>de.value?8:4),h=V(()=>{const M=$.value.trim();return!M||M.length>b.value?!1:/^[0-9a-fA-F]+$/.test(M)}),p=V(()=>{const M=$.value.trim().length;return M===0?"":M===1?"Very fast — ~16 attempts on average":M===2?"Fast — ~256 attempts on average":M===3?"Moderate — ~4,096 attempts, a few seconds":M===4?"Slow — ~65,536 attempts, may take 10-30 seconds":M===5?"Very slow — ~1 million attempts, could take minutes":M===6?"Extremely slow — ~16 million attempts, could take a very long time":M===7?"Extreme — ~268 million attempts, may not complete":"Extreme — ~4 billion attempts, extremely unlikely to complete"}),B=()=>{xe.value=0,Z=setInterval(()=>{xe.value++},1e3)},te=()=>{Z&&(clearInterval(Z),Z=null)};Be(()=>te());const _e=()=>{$.value="",U.value=null,O.value=null,ne.value=!1,de.value=!1,f.value=!0},$e=async()=>{w.value=!0,O.value=null,U.value=null,B();try{const M=await Q.generateVanityKey($.value.trim());M.success&&M.data?U.value=M.data:O.value=M.error||"Generation failed"}catch(M){const S=M;O.value=S.response?.data?.error||S.message||"Generation failed"}finally{te(),w.value=!1}},Te=async()=>{if(U.value){ue.value=!0,O.value=null;try{const M=await Q.generateVanityKey($.value.trim(),!0);M.success&&M.data?(U.value=M.data,ne.value=!1,f.value=!1,k.value="New identity key applied. Restart the repeater for the change to take effect.",await L.fetchStats(),setTimeout(()=>{k.value=null},8e3)):O.value=M.error||"Failed to apply key"}catch(M){const S=M;O.value=S.response?.data?.error||S.message||"Failed to apply key"}finally{ue.value=!1}}};return(M,S)=>(t(),r("div",ht,[k.value?(t(),r("div",wt,[e("p",_t,s(k.value),1)])):C("",!0),u.value?(t(),r("div",$t,[e("p",Ct,s(u.value),1)])):C("",!0),e("div",Mt,[v.value?(t(),r(W,{key:1},[e("button",{onClick:H,disabled:x.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,At),e("button",{onClick:se,disabled:x.value,class:"px-3 sm:px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors text-sm disabled:opacity-50 disabled:cursor-not-allowed"},s(x.value?"Saving...":"Save Changes"),9,St)],64)):(t(),r("button",{key:0,onClick:D,class:"px-3 sm:px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors text-sm"}," Edit Settings "))]),e("div",jt,[e("div",Tt,[S[13]||(S[13]=e("span",{class:"text-content-secondary dark:text-content-muted text-xs sm:text-sm"},"Node Name",-1)),v.value?R((t(),r("input",{key:1,"onUpdate:modelValue":S[0]||(S[0]=Y=>j.value=Y),type:"text",maxlength:"50",class:"w-full sm:w-64 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary",placeholder:"Enter node name"},null,512)),[[K,j.value]]):(t(),r("div",Et,s(d.value),1))]),e("div",Bt,[S[14]||(S[14]=e("span",{class:"text-content-secondary dark:text-content-muted text-xs sm:text-sm"},"Local Hash",-1)),e("span",Lt,s(P.value),1)]),e("div",Nt,[S[15]||(S[15]=e("span",{class:"text-content-secondary dark:text-content-muted text-xs sm:text-sm flex-shrink-0"},"Public Key",-1)),e("div",Pt,[e("span",Ft,s(_.value),1),e("button",{onClick:_e,class:"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"}," Generate New Key ")])]),e("div",It,[S[16]||(S[16]=e("span",{class:"text-content-secondary dark:text-content-muted text-xs sm:text-sm"},"Latitude",-1)),v.value?R((t(),r("input",{key:1,"onUpdate:modelValue":S[1]||(S[1]=Y=>T.value=Y),type:"number",step:"0.000001",min:"-90",max:"90",class:"w-full sm:w-48 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary"},null,512)),[[K,T.value,void 0,{number:!0}]]):(t(),r("div",Rt,s(a.value),1))]),e("div",zt,[S[17]||(S[17]=e("span",{class:"text-content-secondary dark:text-content-muted text-xs sm:text-sm"},"Longitude",-1)),v.value?R((t(),r("input",{key:1,"onUpdate:modelValue":S[2]||(S[2]=Y=>c.value=Y),type:"number",step:"0.000001",min:"-180",max:"180",class:"w-full sm:w-48 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary"},null,512)),[[K,c.value,void 0,{number:!0}]]):(t(),r("div",Vt,s(i.value),1))]),v.value?(t(),r("div",Dt,[e("button",{onClick:oe,class:"px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors text-sm flex items-center gap-2",title:"Pick location on map"},S[18]||(S[18]=[e("svg",{class:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("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"}),e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M15 11a3 3 0 11-6 0 3 3 0 016 0z"})],-1),E(" Pick Location on Map ",-1)]))])):C("",!0),e("div",Ht,[S[19]||(S[19]=e("span",{class:"text-content-secondary dark:text-content-muted text-xs sm:text-sm"},"Mode",-1)),e("span",Ut,s(I.value),1)]),e("div",Ot,[S[21]||(S[21]=e("span",{class:"text-content-secondary dark:text-content-muted text-xs sm:text-sm"},"Path hash length",-1)),v.value?R((t(),r("select",{key:1,"onUpdate:modelValue":S[3]||(S[3]=Y=>n.value=Y),class:"w-full sm:w-32 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary"},S[20]||(S[20]=[e("option",{value:1},"1 byte",-1),e("option",{value:2},"2 bytes",-1),e("option",{value:3},"3 bytes",-1)]),512)),[[pe,n.value,void 0,{number:!0}]]):(t(),r("div",Kt,s(N.value),1))]),e("div",qt,[e("div",Wt,[S[23]||(S[23]=e("span",{class:"text-content-secondary dark:text-content-muted text-xs sm:text-sm"},"Periodic Advertisement Interval",-1)),v.value?(t(),r("div",Jt,[R(e("input",{"onUpdate:modelValue":S[4]||(S[4]=Y=>F.value=Y),type:"number",min:"0",max:"48",class:"w-20 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary"},null,512),[[K,F.value,void 0,{number:!0}]]),S[22]||(S[22]=e("span",{class:"text-content-muted dark:text-content-muted text-sm"},"hours",-1))])):(t(),r("div",Gt,s(J.value),1))]),S[24]||(S[24]=e("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))])]),X(ft,{"is-open":A.value,latitude:T.value,longitude:c.value,onClose:S[5]||(S[5]=Y=>A.value=!1),onSelect:z},null,8,["is-open","latitude","longitude"]),(t(),Me(Le,{to:"body"},[f.value?(t(),r("div",{key:0,class:"fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm",onClick:S[12]||(S[12]=le(Y=>f.value=!1,["self"]))},[e("div",Yt,[S[32]||(S[32]=e("h3",{class:"text-xl font-semibold text-content-primary dark:text-content-primary"},"Generate Vanity Identity Key",-1)),S[33]||(S[33]=e("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)),e("div",null,[e("label",Qt,"Hex Prefix (1-"+s(b.value)+" characters)",1),R(e("input",{"onUpdate:modelValue":S[6]||(S[6]=Y=>$.value=Y),type:"text",maxlength:b.value,placeholder:"e.g. F8A1",disabled:w.value,class:"w-full px-4 py-2 bg-background-mute dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary placeholder-gray-400 dark:placeholder-white/40 font-mono text-sm uppercase focus:outline-none focus:border-primary transition-colors disabled:opacity-50"},null,8,Xt),[[K,$.value]]),$.value&&!h.value?(t(),r("p",Zt,"Enter 1-"+s(b.value)+" valid hex characters (0-9, A-F)",1)):p.value?(t(),r("p",er,s(p.value),1)):C("",!0)]),e("div",null,[e("button",{onClick:S[7]||(S[7]=Y=>de.value=!de.value),disabled:w.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"},[(t(),r("svg",{class:q(["w-3 h-3 transition-transform",{"rotate-90":de.value}]),fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},S[25]||(S[25]=[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M9 5l7 7-7 7"},null,-1)]),2)),S[26]||(S[26]=E(" Advanced ",-1))],8,tr),de.value?(t(),r("div",rr,S[27]||(S[27]=[e("p",{class:"text-amber-600 dark:text-amber-400 text-xs font-medium"},"Extended prefix mode (up to 8 characters)",-1),e("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)]))):C("",!0)]),w.value?(t(),r("div",or,[S[28]||(S[28]=e("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"},[e("circle",{class:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor","stroke-width":"4"}),e("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)),e("div",null,[e("p",sr,'Searching for key with prefix "'+s($.value.toUpperCase())+'"...',1),e("p",nr,"Elapsed: "+s(xe.value)+"s",1)])])):C("",!0),O.value?(t(),r("div",ar,[e("p",lr,s(O.value),1)])):C("",!0),U.value?(t(),r("div",dr,[e("p",ir,"Key found in "+s(U.value.attempts.toLocaleString())+" attempts",1),e("div",null,[S[29]||(S[29]=e("span",{class:"text-xs text-content-muted dark:text-content-muted"},"Public Key:",-1)),e("p",ur,s(U.value.public_hex),1)])])):C("",!0),ne.value&&U.value?(t(),r("div",cr,[S[30]||(S[30]=e("p",{class:"text-amber-600 dark:text-amber-400 text-sm font-medium"},"Warning: This will replace your current identity key.",-1)),S[31]||(S[31]=e("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)),e("div",mr,[e("button",{onClick:Te,disabled:ue.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"},s(ue.value?"Applying...":"Confirm Replace Key"),9,pr),e("button",{onClick:S[8]||(S[8]=Y=>ne.value=!1),disabled:ue.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,br)])])):C("",!0),e("div",xr,[e("button",{onClick:S[9]||(S[9]=Y=>f.value=!1),disabled:w.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,vr),U.value?(t(),r(W,{key:1},[e("button",{onClick:S[10]||(S[10]=Y=>{U.value=null,O.value=null}),class:"px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 text-sm transition-colors"}," Try Again "),ne.value?C("",!0):(t(),r("button",{key:0,onClick:S[11]||(S[11]=Y=>ne.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)):(t(),r("button",{key:0,onClick:$e,disabled:!h.value||w.value,class:"px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 text-sm transition-colors disabled:opacity-50 disabled:cursor-not-allowed"},s(w.value?"Generating...":"Generate"),9,kr))])])])):C("",!0)]))]))}}),yr={class:"space-y-4"},fr={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"},hr={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"},wr={class:"flex justify-end gap-2"},_r=["disabled"],$r=["disabled"],Cr={class:"bg-background-mute dark:bg-white/5 rounded-lg p-3 sm:p-4 space-y-3"},Mr={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"},Ar={key:0,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 gap-1"},jr={key:0,class:"text-content-primary dark:text-content-primary font-mono text-sm"},Tr=re({__name:"DutyCycle",setup(G){const L=be(),m=V(()=>L.stats?.config?.duty_cycle||{}),g=V(()=>{const n=m.value.max_airtime_percent;return typeof n=="number"?n.toFixed(1)+"%":n&&typeof n=="object"&&"parsedValue"in n?(n.parsedValue||0).toFixed(1)+"%":"Not set"}),y=V(()=>m.value.enforcement_enabled?"Enabled":"Disabled"),v=l(!1),x=l(!1),u=l(""),k=l(""),A=l(0),j=l(!0),T=()=>{const n=m.value.max_airtime_percent;typeof n=="number"?A.value=n:n&&typeof n=="object"&&"parsedValue"in n?A.value=n.parsedValue||0:A.value=6,j.value=m.value.enforcement_enabled!==!1,v.value=!0,u.value="",k.value=""},c=()=>{v.value=!1,u.value="",k.value=""},F=async()=>{x.value=!0,k.value="",u.value="";try{const o=(await ke.post("/api/update_duty_cycle_config",{max_airtime_percent:A.value,enforcement_enabled:j.value})).data;o.message||o.persisted?(u.value=o.message||"Settings saved successfully",v.value=!1,await L.fetchStats(),setTimeout(()=>{u.value=""},3e3)):k.value="Failed to save settings"}catch(n){console.error("Failed to save duty cycle settings:",n),k.value=n.response?.data?.error||"Failed to save settings"}finally{x.value=!1}};return(n,o)=>(t(),r("div",yr,[u.value?(t(),r("div",fr,s(u.value),1)):C("",!0),k.value?(t(),r("div",hr,s(k.value),1)):C("",!0),e("div",wr,[v.value?(t(),r(W,{key:1},[e("button",{onClick:c,disabled:x.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,_r),e("button",{onClick:F,disabled:x.value,class:"px-3 sm:px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors text-sm disabled:opacity-50 disabled:cursor-not-allowed"},s(x.value?"Saving...":"Save Changes"),9,$r)],64)):(t(),r("button",{key:0,onClick:T,class:"px-3 sm:px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors text-sm"}," Edit Settings "))]),e("div",Cr,[e("div",Mr,[o[2]||(o[2]=e("span",{class:"text-content-secondary dark:text-content-muted text-xs sm:text-sm"},"Max Airtime %",-1)),v.value?R((t(),r("input",{key:1,"onUpdate:modelValue":o[0]||(o[0]=d=>A.value=d),type:"number",step:"0.1",min:"0.1",max:"100",class:"w-full sm:w-32 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary"},null,512)),[[K,A.value,void 0,{number:!0}]]):(t(),r("div",Ar,s(g.value),1))]),e("div",Sr,[o[4]||(o[4]=e("span",{class:"text-content-secondary dark:text-content-muted text-xs sm:text-sm"},"Enforcement",-1)),v.value?R((t(),r("select",{key:1,"onUpdate:modelValue":o[1]||(o[1]=d=>j.value=d),class:"w-full sm:w-32 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary"},o[3]||(o[3]=[e("option",{value:!0},"Enabled",-1),e("option",{value:!1},"Disabled",-1)]),512)),[[pe,j.value]]):(t(),r("div",jr,s(y.value),1))])])]))}}),Er={class:"space-y-4"},Br={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"},Lr={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"},Nr={class:"flex justify-end gap-2"},Pr=["disabled"],Fr=["disabled"],Ir={class:"bg-background-mute dark:bg-white/5 rounded-lg p-3 sm:p-4 space-y-3"},Rr={class:"flex flex-col py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-2"},zr={class:"flex flex-col sm:flex-row sm:justify-between sm:items-start gap-1"},Vr={key:0,class:"text-content-primary dark:text-content-primary font-mono text-sm sm:ml-4"},Dr={class:"flex flex-col py-2 gap-2"},Hr={class:"flex flex-col sm:flex-row sm:justify-between sm:items-start gap-1"},Ur={key:0,class:"text-content-primary dark:text-content-primary font-mono text-sm sm:ml-4"},Or=re({__name:"TransmissionDelays",setup(G){const L=be(),m=V(()=>L.stats?.config?.delays||{}),g=V(()=>{const n=m.value.tx_delay_factor;if(n&&typeof n=="object"&&n!==null&&"parsedValue"in n){const o=n.parsedValue;if(typeof o=="number")return o.toFixed(2)+"x"}return"Not set"}),y=V(()=>{const n=m.value.direct_tx_delay_factor;return typeof n=="number"?n.toFixed(2)+"s":"Not set"}),v=l(!1),x=l(!1),u=l(""),k=l(""),A=l(0),j=l(0),T=()=>{const n=m.value.tx_delay_factor;n&&typeof n=="object"&&"parsedValue"in n?A.value=n.parsedValue||1:typeof n=="number"?A.value=n:A.value=1;const o=m.value.direct_tx_delay_factor;j.value=typeof o=="number"?o:.5,v.value=!0,u.value="",k.value=""},c=()=>{v.value=!1,u.value="",k.value=""},F=async()=>{x.value=!0,k.value="",u.value="";try{const o=(await ke.post("/api/update_radio_config",{tx_delay_factor:A.value,direct_tx_delay_factor:j.value})).data;o.message||o.persisted?(u.value=o.message||"Settings saved successfully",v.value=!1,await L.fetchStats(),setTimeout(()=>{u.value=""},3e3)):k.value="Failed to save settings"}catch(n){console.error("Failed to save delay settings:",n),k.value=n.response?.data?.error||"Failed to save settings"}finally{x.value=!1}};return(n,o)=>(t(),r("div",Er,[u.value?(t(),r("div",Br,s(u.value),1)):C("",!0),k.value?(t(),r("div",Lr,s(k.value),1)):C("",!0),e("div",Nr,[v.value?(t(),r(W,{key:1},[e("button",{onClick:c,disabled:x.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,Pr),e("button",{onClick:F,disabled:x.value,class:"px-3 sm:px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors text-sm disabled:opacity-50 disabled:cursor-not-allowed"},s(x.value?"Saving...":"Save Changes"),9,Fr)],64)):(t(),r("button",{key:0,onClick:T,class:"px-3 sm:px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors text-sm"}," Edit Settings "))]),e("div",Ir,[e("div",Rr,[e("div",zr,[o[2]||(o[2]=e("span",{class:"text-content-secondary dark:text-content-muted text-xs sm:text-sm"},"Flood TX Delay Factor",-1)),v.value?R((t(),r("input",{key:1,"onUpdate:modelValue":o[0]||(o[0]=d=>A.value=d),type:"number",step:"0.1",min:"0",max:"5",class:"w-full sm:w-32 px-3 py-1.5 bg-background-mute dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary"},null,512)),[[K,A.value,void 0,{number:!0}]]):(t(),r("div",Vr,s(g.value),1))]),o[3]||(o[3]=e("span",{class:"text-content-muted dark:text-content-muted text-xs"},"Multiplier for flood packet transmission delays (collision avoidance)",-1))]),e("div",Dr,[e("div",Hr,[o[4]||(o[4]=e("span",{class:"text-content-secondary dark:text-content-muted text-xs sm:text-sm"},"Direct TX Delay Factor",-1)),v.value?R((t(),r("input",{key:1,"onUpdate:modelValue":o[1]||(o[1]=d=>j.value=d),type:"number",step:"0.1",min:"0",max:"5",class:"w-full sm:w-32 px-3 py-1.5 bg-background-mute dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary"},null,512)),[[K,j.value,void 0,{number:!0}]]):(t(),r("div",Ur,s(y.value),1))]),o[5]||(o[5]=e("span",{class:"text-content-muted dark:text-content-muted text-xs"},"Base delay for direct-routed packet transmission (seconds)",-1))])])]))}}),je=Ne("treeState",()=>{const G=Ce(new Set),L=Ce({value:null}),m=u=>{G.add(u)},g=u=>{G.delete(u)};return{expandedNodes:G,selectedNodeId:L,addExpandedNode:m,removeExpandedNode:g,isNodeExpanded:u=>G.has(u),setSelectedNode:u=>{L.value=u},toggleExpanded:u=>{G.has(u)?g(u):m(u)}}}),Kr={class:"select-none"},qr={class:"flex-shrink-0"},Wr={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"},Gr={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"},Jr={key:0,class:"hidden sm:flex items-center gap-1 ml-2"},Yr={class:"relative group"},Qr=["title"],Xr={key:0,class:"text-xs font-mono text-white/50 bg-white/5 px-1.5 py-0.5 rounded border border-white/10"},Zr={class:"flex justify-between items-start mb-4"},eo={class:"bg-black/20 border border-white/10 rounded-md p-4 mb-4"},to={class:"text-sm font-mono text-white/80 break-all leading-relaxed"},ro={class:"flex items-center gap-1 sm:gap-2 ml-auto flex-shrink-0"},oo={key:0,class:"hidden sm:flex items-center gap-1"},so=["title"],no={key:1,class:"hidden sm:flex items-center gap-1"},ao={key:2,class:"hidden sm:inline-block px-2 py-1 bg-white/10 text-white/60 text-xs rounded-full ml-1"},lo={key:0,class:"space-y-1"},io=re({__name:"TreeNode",props:{node:{},selectedNodeId:{},level:{},disabled:{type:Boolean}},emits:["select"],setup(G,{emit:L}){const m=G,g=L,y=je(),v=l(!1),x=V({get:()=>y.isNodeExpanded(m.node.id),set:o=>{o?y.addExpandedNode(m.node.id):y.removeExpandedNode(m.node.id)}}),u=V(()=>m.node.children.length>0);function k(o){if(!o)return"Never";const P=new Date().getTime()-o.getTime(),_=Math.floor(P/(1e3*60)),a=Math.floor(P/(1e3*60*60)),i=Math.floor(P/(1e3*60*60*24)),I=Math.floor(i/365);return _<60?`${_}m ago`:a<24?`${a}h ago`:i<365?`${i}d ago`:`${I}y ago`}function A(o){return o?o.length<=16?o:`${o.slice(0,8)}...${o.slice(-8)}`:"No key"}function j(){if(u.value){const o=!x.value;x.value=o}}function T(){g("select",m.node.id)}function c(o){g("select",o)}function F(o){o.stopPropagation(),v.value=!v.value}function n(o){o.stopPropagation(),m.node.transport_key&&window.navigator?.clipboard&&window.navigator.clipboard.writeText(m.node.transport_key)}return(o,d)=>{const P=Se("TreeNode",!0);return t(),r("div",Kr,[e("div",{class:q(["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 cursor-pointer transition-all duration-200",m.disabled?"opacity-50 cursor-not-allowed":"hover:bg-white/5",o.selectedNodeId===o.node.id&&!m.disabled?"bg-primary/20 text-primary":"text-white/80 hover:text-white",`ml-${o.level*4}`]),onClick:d[3]||(d[3]=_=>!m.disabled&&T())},[e("div",{class:"flex-shrink-0 w-3 h-3 sm:w-4 sm:h-4 flex items-center justify-center",onClick:le(j,["stop"])},[u.value?(t(),r("svg",{key:0,class:q(["w-2.5 h-2.5 sm:w-3 sm:h-3 transition-transform duration-200",x.value?"rotate-90":"rotate-0"]),fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},d[4]||(d[4]=[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M9 5l7 7-7 7"},null,-1)]),2)):C("",!0)]),e("div",qr,[m.node.name.startsWith("#")?(t(),r("svg",Wr,d[5]||(d[5]=[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M7 20l4-16m2 16l4-16M6 9h14M4 15h14"},null,-1)]))):(t(),r("svg",Gr,d[6]||(d[6]=[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z"},null,-1)])))]),e("span",{class:q(["font-mono text-xs sm:text-sm transition-colors duration-200 break-all",o.selectedNodeId===o.node.id?"text-primary font-medium":""])},s(o.node.name),3),o.node.transport_key?(t(),r("div",Jr,[e("div",Yr,[e("button",{onClick:F,class:"p-1 rounded hover:bg-white/10 transition-colors",title:v.value?"Hide full key":"Show full key"},d[7]||(d[7]=[e("svg",{class:"w-3 h-3 text-white/60 hover:text-white/80",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M15 12a3 3 0 11-6 0 3 3 0 016 0z"}),e("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,Qr),v.value?C("",!0):(t(),r("span",Xr,s(A(o.node.transport_key)),1)),v.value?(t(),r("div",{key:1,class:"fixed inset-0 z-[9998] flex items-center justify-center bg-black/70 backdrop-blur-md",onClick:d[2]||(d[2]=_=>v.value=!1)},[e("div",{class:"bg-black/20 border border-white/20 rounded-lg shadow-lg p-6 max-w-2xl w-full mx-4",onClick:d[1]||(d[1]=le(()=>{},["stop"]))},[e("div",Zr,[d[9]||(d[9]=e("h3",{class:"text-lg font-semibold text-white"},"Transport Key",-1)),e("button",{onClick:d[0]||(d[0]=_=>v.value=!1),class:"text-white/60 hover:text-white transition-colors"},d[8]||(d[8]=[e("svg",{class:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M6 18L18 6M6 6l12 12"})],-1)]))]),e("div",eo,[e("div",to,s(o.node.transport_key),1)]),e("div",{class:"flex justify-end"},[e("button",{onClick:n,class:"px-4 py-2 bg-accent-green/20 hover:bg-accent-green/30 border border-accent-green/50 text-accent-green rounded-lg transition-colors flex items-center gap-2",title:"Copy to clipboard"},d[10]||(d[10]=[e("svg",{class:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("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),E(" Copy Key ",-1)]))])])])):C("",!0)])])):C("",!0),e("div",ro,[o.node.last_used?(t(),r("div",oo,[d[11]||(d[11]=e("svg",{class:"w-3 h-3 text-white/40",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("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"})],-1)),e("span",{class:"text-xs text-white/50",title:o.node.last_used.toLocaleString()},s(k(o.node.last_used)),9,so)])):(t(),r("div",no,d[12]||(d[12]=[e("svg",{class:"w-3 h-3 text-white/30",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("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"})],-1),e("span",{class:"text-xs text-white/30 italic"},"Never",-1)]))),e("span",{class:q(["px-1.5 sm:px-2 py-0.5 text-[10px] sm:text-xs font-medium rounded-md transition-colors",o.node.floodPolicy==="allow"?"bg-accent-green/10 text-accent-green/90 border border-accent-green/20":"bg-accent-red/10 text-accent-red/90 border border-accent-red/20"])},s(o.node.floodPolicy==="allow"?"ALLOW":"DENY"),3),u.value?(t(),r("span",ao," > "+s(o.node.children.length),1)):C("",!0)])],2),X(he,{"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:ge(()=>[x.value&&o.node.children.length>0?(t(),r("div",lo,[(t(!0),r(W,null,ee(o.node.children,_=>(t(),Me(P,{key:_.id,node:_,"selected-node-id":o.selectedNodeId,level:o.level+1,disabled:m.disabled,onSelect:c},null,8,["node","selected-node-id","level","disabled"]))),128))])):C("",!0)]),_:1})])}}}),uo=we(io,[["__scopeId","data-v-59e9974c"]]),co={class:"flex items-center justify-between mb-6"},mo={class:"text-content-secondary dark:text-content-muted text-sm mt-1"},po={key:0},bo={class:"text-primary font-mono"},xo={key:1},vo={for:"keyName",class:"block text-sm font-medium text-white mb-2"},ko={class:"flex items-center gap-2"},go={key:0,class:"w-4 h-4 text-secondary",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},yo={key:1,class:"w-4 h-4 text-accent-green",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},fo={class:"bg-gray-50 dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg p-4"},ho={class:"flex items-center gap-3 mb-2"},wo={class:"flex items-center gap-2"},_o={key:0,class:"w-5 h-5 text-secondary",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},$o={key:1,class:"w-5 h-5 text-accent-green",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},Co={class:"text-content-secondary dark:text-content-muted text-sm"},Mo={class:"grid grid-cols-2 gap-3"},Ao={class:"relative cursor-pointer group"},So={class:"relative cursor-pointer group"},jo={class:"flex gap-3 pt-4"},To=["disabled"],Eo=re({__name:"AddKeyModal",props:{show:{type:Boolean},selectedNodeName:{},selectedNodeId:{}},emits:["close","add"],setup(G,{emit:L}){const m=G,g=L,y=l(""),v=l(""),x=l("allow"),u=V(()=>y.value.startsWith("#")),k=V(()=>({type:u.value?"Region":"Private Key",description:u.value?"Regional organizational key":"Individual assigned key"}));me(u,F=>{F?v.value="This will create a new region for organizing keys":v.value="This will create a new private key entry"},{immediate:!0});const A=V(()=>y.value.trim().length>0),j=()=>{A.value&&(g("add",{name:y.value.trim(),floodPolicy:x.value,parentId:m.selectedNodeId}),y.value="",v.value="",x.value="allow")},T=()=>{y.value="",v.value="",x.value="allow",g("close")},c=F=>{F.target===F.currentTarget&&T()};return(F,n)=>F.show?(t(),r("div",{key:0,onClick:c,class:"fixed inset-0 bg-black/40 backdrop-blur-lg z-[99999] flex items-center justify-center p-4",style:{"backdrop-filter":"blur(8px) saturate(180%)",position:"fixed",top:"0",left:"0",right:"0",bottom:"0"}},[e("div",{class:"bg-white dark:bg-surface-elevated backdrop-blur-xl rounded-[20px] p-6 w-full max-w-md border border-stroke-subtle dark:border-white/10",onClick:n[3]||(n[3]=le(()=>{},["stop"]))},[e("div",co,[e("div",null,[n[5]||(n[5]=e("h3",{class:"text-xl font-semibold text-content-primary dark:text-content-primary"},"Add New Entry",-1)),e("p",mo,[m.selectedNodeName?(t(),r("span",po,[n[4]||(n[4]=E(" Add to: ",-1)),e("span",bo,s(m.selectedNodeName),1)])):(t(),r("span",xo," Add to root level (#uk) "))])]),e("button",{onClick:T,class:"text-white/60 hover:text-white transition-colors"},n[6]||(n[6]=[e("svg",{class:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M6 18L18 6M6 6l12 12"})],-1)]))]),e("form",{onSubmit:le(j,["prevent"]),class:"space-y-4"},[e("div",null,[e("label",vo,[e("div",ko,[u.value?(t(),r("svg",go,n[7]||(n[7]=[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M7 20l4-16m2 16l4-16M6 9h14M4 15h14"},null,-1)]))):(t(),r("svg",yo,n[8]||(n[8]=[e("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)]))),n[9]||(n[9]=E(" Region/Key Name ",-1))])]),R(e("input",{id:"keyName","onUpdate:modelValue":n[0]||(n[0]=o=>y.value=o),type:"text",placeholder:"Enter name (prefix with # for regions)",class:"w-full px-4 py-3 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/20 rounded-lg text-content-primary dark:text-content-primary placeholder-gray-500 dark:placeholder-white/50 focus:outline-none focus:border-primary focus:ring-2 focus:ring-primary/20 transition-colors",autocomplete:"off"},null,512),[[K,y.value]])]),e("div",fo,[e("div",ho,[e("div",wo,[u.value?(t(),r("svg",_o,n[10]||(n[10]=[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M7 20l4-16m2 16l4-16M6 9h14M4 15h14"},null,-1)]))):(t(),r("svg",$o,n[11]||(n[11]=[e("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 1221 9z"},null,-1)]))),e("span",{class:q([u.value?"text-secondary":"text-accent-green","font-medium"])},s(k.value.type),3)]),e("div",{class:q(["flex-1 h-px",u.value?"bg-secondary/20":"bg-accent-green/20"])},null,2)]),e("p",Co,s(k.value.description),1)]),e("div",null,[n[14]||(n[14]=e("label",{class:"block text-sm font-medium text-content-primary dark:text-content-primary mb-3"},[e("div",{class:"flex items-center gap-2"},[e("svg",{class:"w-4 h-4 text-primary",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"})]),E(" Flood Policy ")])],-1)),e("div",Mo,[e("label",Ao,[R(e("input",{type:"radio","onUpdate:modelValue":n[1]||(n[1]=o=>x.value=o),value:"allow",class:"sr-only"},null,512),[[ye,x.value]]),n[12]||(n[12]=ae('<div class="flex items-center gap-3 p-3 bg-background-mute dark:bg-white/5 border border-stroke-subtle dark:border-stroke/20 rounded-lg group-has-[:checked]:border-accent-green/50 group-has-[:checked]:bg-accent-green/10 transition-colors"><div class="flex items-center justify-center w-4 h-4 border-2 border-stroke dark:border-stroke/30 rounded-full group-has-[:checked]:border-accent-green group-has-[:checked]:bg-accent-green transition-all"><div class="w-2 h-2 rounded-full bg-white scale-0 group-has-[:checked]:scale-100 transition-transform"></div></div><div class="flex-1"><div class="flex items-center gap-2"><svg class="w-4 h-4 text-accent-green" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path></svg><span class="font-medium text-accent-green text-sm">Allow</span></div><p class="text-content-secondary dark:text-content-muted text-xs mt-1">Permit flooding</p></div></div>',1))]),e("label",So,[R(e("input",{type:"radio","onUpdate:modelValue":n[2]||(n[2]=o=>x.value=o),value:"deny",class:"sr-only"},null,512),[[ye,x.value]]),n[13]||(n[13]=ae('<div class="flex items-center gap-3 p-3 bg-background-mute dark:bg-white/5 border border-stroke-subtle dark:border-stroke/20 rounded-lg group-has-[:checked]:border-accent-red/50 group-has-[:checked]:bg-accent-red/10 transition-colors"><div class="flex items-center justify-center w-4 h-4 border-2 border-stroke dark:border-stroke/30 rounded-full group-has-[:checked]:border-accent-red group-has-[:checked]:bg-accent-red transition-all"><div class="w-2 h-2 rounded-full bg-white scale-0 group-has-[:checked]:scale-100 transition-transform"></div></div><div class="flex-1"><div class="flex items-center gap-2"><svg class="w-4 h-4 text-accent-red" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path></svg><span class="font-medium text-accent-red text-sm">Deny</span></div><p class="text-content-secondary dark:text-content-muted text-xs mt-1">Block flooding</p></div></div>',1))])])]),e("div",jo,[e("button",{type:"button",onClick:T,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 "),e("button",{type:"submit",disabled:!A.value,class:q(["flex-1 px-4 py-3 rounded-lg transition-colors font-medium",A.value?"bg-accent-green/20 hover:bg-accent-green/30 border border-accent-green/50 text-accent-green":"bg-background-mute dark:bg-stroke/5 border border-stroke-subtle dark:border-stroke/20 text-content-muted dark:text-content-muted cursor-not-allowed"])}," Add "+s(k.value.type),11,To)])],32)])])):C("",!0)}}),Bo={class:"flex items-center justify-between mb-6"},Lo={class:"text-content-secondary dark:text-content-muted text-sm mt-1"},No={class:"text-primary font-mono"},Po={for:"keyName",class:"block text-sm font-medium text-content-secondary dark:text-content-primary mb-2"},Fo={class:"flex items-center gap-2"},Io={key:0,class:"w-4 h-4 text-secondary",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},Ro={key:1,class:"w-4 h-4 text-accent-green",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},zo={class:"bg-gray-50 dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg p-4"},Vo={class:"flex items-center gap-3 mb-2"},Do={class:"flex items-center gap-2"},Ho={key:0,class:"w-5 h-5 text-secondary",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},Uo={key:1,class:"w-5 h-5 text-accent-green",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},Oo={class:"text-content-secondary dark:text-content-muted text-sm"},Ko={key:0,class:"space-y-4"},qo={key:0,class:"bg-gray-50 dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg p-4"},Wo={class:"bg-background-mute dark:bg-black/20 border border-stroke-subtle dark:border-stroke/10 rounded-md p-3"},Go={class:"text-xs font-mono text-content-primary dark:text-content-primary/80 break-all"},Jo={key:1,class:"bg-gray-50 dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg p-4"},Yo={class:"flex items-center justify-between"},Qo={class:"text-sm text-content-secondary dark:text-content-muted"},Xo={class:"text-xs text-content-muted dark:text-content-muted"},Zo={class:"grid grid-cols-2 gap-3"},es={class:"relative cursor-pointer group"},ts={class:"relative cursor-pointer group"},rs={class:"flex gap-3 pt-4"},os=["disabled"],ss=re({__name:"EditKeyModal",props:{show:{type:Boolean},node:{}},emits:["close","save","request-delete"],setup(G,{emit:L}){const m=G,g=L,y=l(""),v=l("allow"),x=V(()=>y.value.startsWith("#")),u=V(()=>({type:x.value?"Region":"Private Key",description:x.value?"Regional organizational key":"Individual assigned key"}));me(()=>m.node,o=>{o?(y.value=o.name,v.value=o.floodPolicy):(y.value="",v.value="allow")},{immediate:!0});const k=V(()=>y.value.trim().length>0&&m.node),A=o=>{const P=new Date().getTime()-o.getTime(),_=Math.floor(P/(1e3*60)),a=Math.floor(P/(1e3*60*60)),i=Math.floor(P/(1e3*60*60*24)),I=Math.floor(i/365);return _<60?`${_}m ago`:a<24?`${a}h ago`:i<365?`${i}d ago`:`${I}y ago`},j=o=>{window.navigator?.clipboard&&window.navigator.clipboard.writeText(o)},T=()=>{!k.value||!m.node||(g("save",{id:m.node.id,name:y.value.trim(),floodPolicy:v.value}),F())},c=()=>{m.node&&(g("request-delete",m.node),F())},F=()=>{g("close")},n=o=>{o.target===o.currentTarget&&F()};return(o,d)=>o.show?(t(),r("div",{key:0,onClick:n,class:"fixed inset-0 bg-black/50 backdrop-blur-lg z-[99999] flex items-center justify-center p-4",style:{"backdrop-filter":"blur(8px) saturate(180%)",position:"fixed",top:"0",left:"0",right:"0",bottom:"0"}},[e("div",{class:"bg-white dark:bg-surface-elevated backdrop-blur-xl rounded-[20px] p-6 w-full max-w-lg border border-stroke-subtle dark:border-white/10",onClick:d[4]||(d[4]=le(()=>{},["stop"]))},[e("div",Bo,[e("div",null,[d[6]||(d[6]=e("h3",{class:"text-xl font-semibold text-content-primary dark:text-content-primary"},"Edit Entry",-1)),e("p",Lo,[d[5]||(d[5]=E(" Modify ",-1)),e("span",No,s(o.node?.name),1)])]),e("button",{onClick:F,class:"text-white/60 hover:text-white transition-colors"},d[7]||(d[7]=[e("svg",{class:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M6 18L18 6M6 6l12 12"})],-1)]))]),e("form",{onSubmit:le(T,["prevent"]),class:"space-y-4"},[e("div",null,[e("label",Po,[e("div",Fo,[x.value?(t(),r("svg",Io,d[8]||(d[8]=[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M7 20l4-16m2 16l4-16M6 9h14M4 15h14"},null,-1)]))):(t(),r("svg",Ro,d[9]||(d[9]=[e("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)]))),d[10]||(d[10]=E(" Region/Key Name ",-1))])]),R(e("input",{id:"keyName","onUpdate:modelValue":d[0]||(d[0]=P=>y.value=P),type:"text",placeholder:"Enter name (prefix with # for regions)",class:"w-full px-4 py-3 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/20 rounded-lg text-content-primary dark:text-content-primary placeholder-gray-500 dark:placeholder-white/50 focus:outline-none focus:border-primary focus:ring-2 focus:ring-primary/20 transition-colors",autocomplete:"off"},null,512),[[K,y.value]])]),e("div",zo,[e("div",Vo,[e("div",Do,[x.value?(t(),r("svg",Ho,d[11]||(d[11]=[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M7 20l4-16m2 16l4-16M6 9h14M4 15h14"},null,-1)]))):(t(),r("svg",Uo,d[12]||(d[12]=[e("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)]))),e("span",{class:q([x.value?"text-secondary":"text-accent-green","font-medium"])},s(u.value.type),3)]),e("div",{class:q(["flex-1 h-px",x.value?"bg-secondary/20":"bg-accent-green/20"])},null,2)]),e("p",Oo,s(u.value.description),1)]),o.node?(t(),r("div",Ko,[o.node.transport_key?(t(),r("div",qo,[d[14]||(d[14]=ae('<div class="flex items-center gap-2 mb-3"><svg class="w-4 h-4 text-primary" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path><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"></path></svg><span class="text-sm font-medium text-content-primary dark:text-content-primary">Transport Key</span></div>',1)),e("div",Wo,[e("div",Go,s(o.node.transport_key),1),e("button",{onClick:d[1]||(d[1]=P=>j(o.node.transport_key||"")),class:"mt-2 text-xs text-accent-green hover:text-accent-green/80 flex items-center gap-1",title:"Copy to clipboard"},d[13]||(d[13]=[e("svg",{class:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("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),E(" Copy Key ",-1)]))])])):C("",!0),o.node.last_used?(t(),r("div",Jo,[d[15]||(d[15]=e("div",{class:"flex items-center gap-2 mb-3"},[e("svg",{class:"w-4 h-4 text-primary",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("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"})]),e("span",{class:"text-sm font-medium text-content-primary dark:text-content-primary"},"Last Used")],-1)),e("div",Yo,[e("div",Qo,s(o.node.last_used.toLocaleDateString())+" at "+s(o.node.last_used.toLocaleTimeString()),1),e("div",Xo,s(A(o.node.last_used)),1)])])):C("",!0)])):C("",!0),e("div",null,[d[18]||(d[18]=e("label",{class:"block text-sm font-medium text-content-secondary dark:text-content-primary mb-3"},[e("div",{class:"flex items-center gap-2"},[e("svg",{class:"w-4 h-4 text-primary",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"})]),E(" Flood Policy ")])],-1)),e("div",Zo,[e("label",es,[R(e("input",{type:"radio","onUpdate:modelValue":d[2]||(d[2]=P=>v.value=P),value:"allow",class:"sr-only"},null,512),[[ye,v.value]]),d[16]||(d[16]=ae('<div class="flex items-center gap-3 p-3 bg-white/5 border border-white/20 rounded-lg group-has-[:checked]:border-accent-green/50 group-has-[:checked]:bg-accent-green/10 transition-colors"><div class="flex items-center justify-center w-4 h-4 border-2 border-white/30 rounded-full group-has-[:checked]:border-accent-green group-has-[:checked]:bg-accent-green transition-all"><div class="w-2 h-2 rounded-full bg-white scale-0 group-has-[:checked]:scale-100 transition-transform"></div></div><div class="flex-1"><div class="flex items-center gap-2"><svg class="w-4 h-4 text-accent-green" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path></svg><span class="font-medium text-accent-green text-sm">Allow</span></div><p class="text-content-muted dark:text-content-muted text-xs mt-1">Permit flooding</p></div></div>',1))]),e("label",ts,[R(e("input",{type:"radio","onUpdate:modelValue":d[3]||(d[3]=P=>v.value=P),value:"deny",class:"sr-only"},null,512),[[ye,v.value]]),d[17]||(d[17]=ae('<div class="flex items-center gap-3 p-3 bg-gray-50 dark:bg-white/5 border border-stroke-subtle dark:border-stroke/20 rounded-lg group-has-[:checked]:border-accent-red/50 group-has-[:checked]:bg-accent-red/10 transition-colors"><div class="flex items-center justify-center w-4 h-4 border-2 border-stroke dark:border-stroke/30 rounded-full group-has-[:checked]:border-accent-red group-has-[:checked]:bg-accent-red transition-all"><div class="w-2 h-2 rounded-full bg-white scale-0 group-has-[:checked]:scale-100 transition-transform"></div></div><div class="flex-1"><div class="flex items-center gap-2"><svg class="w-4 h-4 text-accent-red" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path></svg><span class="font-medium text-accent-red text-sm">Deny</span></div><p class="text-content-muted dark:text-content-muted text-xs mt-1">Block flooding</p></div></div>',1))])])]),e("div",rs,[e("button",{type:"button",onClick:c,class:"px-4 py-3 bg-accent-red/20 hover:bg-accent-red/30 border border-accent-red/50 text-accent-red rounded-lg transition-colors"}," Delete "),e("button",{type:"button",onClick:F,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 "),e("button",{type:"submit",disabled:!k.value,class:q(["flex-1 px-4 py-3 rounded-lg transition-colors font-medium",k.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"])}," Save Changes ",10,os)])],32)])])):C("",!0)}}),ns={class:"flex items-center gap-3 mb-6"},as={class:"text-content-secondary dark:text-content-muted text-sm mt-1"},ls={class:"text-accent-red font-mono"},ds={key:0,class:"bg-accent-red/10 border border-accent-red/30 rounded-lg p-4 mb-6"},is={class:"flex items-start gap-3"},us={class:"flex-1"},cs={class:"text-accent-red font-medium text-sm mb-2"},ms={class:"space-y-1 max-h-32 overflow-y-auto"},ps={key:0,class:"w-3 h-3 text-secondary",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},bs={key:1,class:"w-3 h-3 text-accent-green",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},xs={class:"font-mono"},vs={key:0,class:"text-content-secondary dark:text-content-muted text-xs"},ks={key:1,class:"mb-6"},gs={class:"mb-3"},ys={class:"relative"},fs={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"},hs={key:0,class:"text-center py-4 text-content-secondary dark:text-content-muted text-sm"},ws={class:"relative"},_s=["value"],$s={class:"flex items-center gap-2 flex-1"},Cs={class:"text-content-primary dark:text-content-primary font-mono text-sm"},Ms={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"},As={class:"flex gap-3"},Ss=re({__name:"DeleteConfirmModal",props:{show:{type:Boolean},node:{},allNodes:{}},emits:["close","delete-all","move-children"],setup(G,{emit:L}){const m=G,g=L,y=l(null),v=l(""),x=n=>{const o=[],d=P=>{for(const _ of P.children)o.push(_),d(_)};return d(n),o},u=V(()=>m.node?x(m.node):[]),k=V(()=>{if(!m.node)return[];const n=new Set([m.node.id,...u.value.map(d=>d.id)]),o=d=>{const P=[];for(const _ of d)_.name.startsWith("#")&&!n.has(_.id)&&P.push(_),_.children.length>0&&P.push(...o(_.children));return P};return o(m.allNodes)}),A=V(()=>{if(!v.value.trim())return k.value;const n=v.value.toLowerCase();return k.value.filter(o=>o.name.toLowerCase().includes(n))}),j=()=>{m.node&&(g("delete-all",m.node.id),c())},T=()=>{!m.node||!y.value||(g("move-children",{nodeId:m.node.id,targetParentId:y.value}),c())},c=()=>{y.value=null,v.value="",g("close")},F=n=>{n.target===n.currentTarget&&c()};return(n,o)=>n.show&&n.node?(t(),r("div",{key:0,onClick:F,class:"fixed inset-0 bg-black/80 backdrop-blur-lg z-[99999] flex items-center justify-center p-4",style:{"backdrop-filter":"blur(8px) saturate(180%)",position:"fixed",top:"0",left:"0",right:"0",bottom:"0"}},[e("div",{class:"bg-white dark:bg-surface-elevated backdrop-blur-xl rounded-[20px] p-6 w-full max-w-lg border border-stroke-subtle dark:border-white/10",onClick:o[2]||(o[2]=le(()=>{},["stop"]))},[e("div",ns,[o[6]||(o[6]=e("svg",{class:"w-6 h-6 text-accent-red",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("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)),e("div",null,[o[4]||(o[4]=e("h3",{class:"text-xl font-semibold text-content-primary dark:text-content-primary"},"Confirm Deletion",-1)),e("p",as,[o[3]||(o[3]=E(" Deleting ",-1)),e("span",ls,s(n.node?.name),1)])]),e("button",{onClick:c,class:"ml-auto text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-primary transition-colors"},o[5]||(o[5]=[e("svg",{class:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M6 18L18 6M6 6l12 12"})],-1)]))]),u.value.length>0?(t(),r("div",ds,[e("div",is,[o[9]||(o[9]=e("svg",{class:"w-5 h-5 text-accent-red flex-shrink-0 mt-0.5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("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)),e("div",us,[e("h4",cs," This will affect "+s(u.value.length)+" child "+s(u.value.length===1?"entry":"entries")+": ",1),e("div",ms,[(t(!0),r(W,null,ee(u.value.slice(0,10),d=>(t(),r("div",{key:d.id,class:"flex items-center gap-2 text-xs text-content-secondary dark:text-content-primary/80"},[d.name.startsWith("#")?(t(),r("svg",ps,o[7]||(o[7]=[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M7 20l4-16m2 16l4-16M6 9h14M4 15h14"},null,-1)]))):(t(),r("svg",bs,o[8]||(o[8]=[e("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)]))),e("span",xs,s(d.name),1),e("span",{class:q(["px-1 py-0.5 text-xs rounded",d.floodPolicy==="allow"?"bg-accent-green/20 text-accent-green":"bg-accent-red/20 text-accent-red"])},s(d.floodPolicy),3)]))),128)),u.value.length>10?(t(),r("div",vs," ...and "+s(u.value.length-10)+" more ",1)):C("",!0)])])])])):C("",!0),u.value.length>0&&k.value.length>0?(t(),r("div",ks,[o[13]||(o[13]=e("h4",{class:"text-content-primary dark:text-content-primary font-medium text-sm mb-3"},"Move children to another region:",-1)),e("div",gs,[e("div",ys,[o[10]||(o[10]=e("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"},[e("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)),R(e("input",{"onUpdate:modelValue":o[0]||(o[0]=d=>v.value=d),type:"text",placeholder:"Search regions...",class:"w-full pl-9 pr-4 py-2 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/20 rounded-lg text-content-primary dark:text-content-primary placeholder-gray-500 dark:placeholder-white/50 focus:outline-none focus:border-primary focus:ring-2 focus:ring-primary/20 transition-colors text-sm"},null,512),[[K,v.value]])])]),e("div",fs,[A.value.length===0?(t(),r("div",hs,s(v.value?"No regions match your search":"No available regions"),1)):C("",!0),(t(!0),r(W,null,ee(A.value,d=>(t(),r("label",{key:d.id,class:"flex items-center gap-3 p-2 rounded cursor-pointer hover:bg-stroke-subtle dark:hover:bg-white/10 transition-colors group"},[e("div",ws,[R(e("input",{type:"radio",value:d.id,"onUpdate:modelValue":o[1]||(o[1]=P=>y.value=P),class:"sr-only peer"},null,8,_s),[[ye,y.value]]),o[11]||(o[11]=e("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"},[e("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))]),e("div",$s,[o[12]||(o[12]=e("svg",{class:"w-4 h-4 text-secondary",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M7 20l4-16m2 16l4-16M6 9h14M4 15h14"})],-1)),e("span",Cs,s(d.name),1),d.children.length>0?(t(),r("span",Ms,s(d.children.length),1)):C("",!0)])]))),128))])])):C("",!0),e("div",As,[e("button",{onClick:c,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 "),u.value.length>0&&y.value?(t(),r("button",{key:0,onClick:T,class:"flex-1 px-4 py-3 bg-primary/20 hover:bg-primary/30 border border-primary/50 text-primary rounded-lg transition-colors"}," Move & Delete ")):C("",!0),e("button",{onClick:j,class:"flex-1 px-4 py-3 bg-accent-red/20 hover:bg-accent-red/30 border border-accent-red/50 text-accent-red rounded-lg transition-colors font-medium"},s(u.value.length>0?"Delete All":"Delete"),1)])])])):C("",!0)}}),js={class:"space-y-4 sm:space-y-6"},Ts={class:"flex flex-col sm:flex-row sm:justify-between sm:items-start gap-3"},Es={class:"flex gap-2 flex-wrap"},Bs=["disabled"],Ls=["disabled"],Ns={class:"glass-card rounded-[15px] p-3 sm:p-4 border border-stroke-subtle dark:border-stroke/10 bg-background-mute dark:bg-white/5"},Ps={class:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3"},Fs={class:"flex items-center gap-2 sm:gap-3"},Is={class:"flex bg-background-mute dark:bg-stroke/5 rounded-lg border border-stroke-subtle dark:border-stroke/20 p-0.5 sm:p-1"},Rs={class:"glass-card rounded-[15px] p-3 sm:p-6 border border-stroke-subtle dark:border-stroke/10"},zs={key:0,class:"flex items-center justify-center py-8"},Vs={key:1,class:"text-center py-8"},Ds={class:"text-content-secondary dark:text-content-muted text-sm"},Hs={key:2,class:"text-center py-8"},Us={key:3,class:"space-y-2"},Os=re({name:"TransportKeys",__name:"TransportKeys",setup(G){const L=je(),m=be(),g=l(!1),y=l(!1),v=l(!1),x=l(null),u=l(null),k=l("deny"),A=V(()=>m.stats?.config?.mesh?.global_flood_allow??null);me(A,$=>{$!==null&&(k.value=$?"allow":"deny")},{immediate:!0});const j=l([]),T=l(!1),c=l(null),F=$=>{const w=new Map,U=[];return $.forEach(O=>{const ne={id:O.id,name:O.name,floodPolicy:O.flood_policy,transport_key:O.transport_key,last_used:O.last_used?new Date(O.last_used*1e3):void 0,parent_id:O.parent_id,children:[]};w.set(O.id,ne)}),w.forEach(O=>{O.parent_id&&w.has(O.parent_id)?w.get(O.parent_id).children.push(O):U.push(O)}),U},n=async()=>{try{T.value=!0,c.value=null;const $=await Q.getTransportKeys();$.success&&$.data?j.value=F($.data):c.value=$.error||"Failed to load transport keys"}catch($){c.value=$ instanceof Error?$.message:"Unknown error occurred",console.error("Error loading transport keys:",$)}finally{T.value=!1}};ve(()=>{n()});function o($,w){for(const U of $){if(U.id===w)return U;if(U.children){const O=o(U.children,w);if(O)return O}}return null}function d(){const $=L.selectedNodeId.value;return $?o(j.value,$)?.name:void 0}function P($){L.setSelectedNode($)}function _(){g.value=!0}function a(){if(L.selectedNodeId.value){const $=o(j.value,L.selectedNodeId.value);$&&(u.value=$,v.value=!0)}}function i(){if(L.selectedNodeId.value){const $=o(j.value,L.selectedNodeId.value);$&&(x.value=$,y.value=!0)}}const I=async $=>{try{const w=await Q.createTransportKey($.name,$.floodPolicy,void 0,$.parentId,void 0);w.success?await n():(console.error("Failed to add transport key:",w.error),c.value=w.error||"Failed to add transport key")}catch(w){console.error("Error adding transport key:",w),c.value=w instanceof Error?w.message:"Unknown error occurred"}finally{g.value=!1}};function J(){g.value=!1}async function N($){try{const w=$==="allow",U=await Q.updateGlobalFloodPolicy(w);U.success?(k.value=$,await m.fetchStats()):(console.error("Failed to update global flood policy:",U.error),c.value=U.error||"Failed to update global flood policy")}catch(w){console.error("Error updating global flood policy:",w),c.value=w instanceof Error?w.message:"Failed to update global flood policy"}}function D(){y.value=!1,x.value=null}async function H($){try{const w=await Q.updateTransportKey($.id,$.name,$.floodPolicy);w.success?await n():(console.error("Failed to update transport key:",w.error),c.value=w.error||"Failed to update transport key")}catch(w){console.error("Error updating transport key:",w),c.value=w instanceof Error?w.message:"Unknown error occurred"}finally{D()}}function se($){y.value=!1,x.value=null,u.value=$,v.value=!0}function oe(){v.value=!1,u.value=null}async function z($){try{const w=await Q.deleteTransportKey($);w.success?(await n(),L.setSelectedNode(null)):(console.error("Failed to delete transport key:",w.error),c.value=w.error||"Failed to delete transport key")}catch(w){console.error("Error deleting transport key:",w),c.value=w instanceof Error?w.message:"Unknown error occurred"}finally{oe()}}async function f($){try{const w=await Q.deleteTransportKey($.nodeId);w.success?(await n(),L.setSelectedNode(null)):(console.error("Failed to delete transport key:",w.error),c.value=w.error||"Failed to delete transport key")}catch(w){console.error("Error deleting transport key:",w),c.value=w instanceof Error?w.message:"Unknown error occurred"}finally{oe()}}return($,w)=>(t(),r("div",js,[e("div",Ts,[w[3]||(w[3]=e("div",null,[e("h3",{class:"text-base sm:text-lg font-semibold text-content-primary dark:text-content-primary mb-1 sm:mb-2"},"Regions/Keys"),e("p",{class:"text-content-secondary dark:text-content-muted text-xs sm:text-sm"},"Manage regional key hierarchy")],-1)),e("div",Es,[e("button",{onClick:_,class:"flex items-center gap-1.5 sm:gap-2 px-2.5 sm:px-3 py-1.5 sm:py-2 rounded-lg border transition-colors text-xs sm:text-sm bg-accent-green/10 hover:bg-accent-green/20 text-accent-green border-accent-green/30"},w[2]||(w[2]=[e("svg",{class:"w-3.5 h-3.5 sm:w-4 sm:h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M12 4v16m8-8H4"})],-1),E(" Add ",-1)])),e("button",{onClick:i,disabled:!ce(L).selectedNodeId.value,class:q(["px-2.5 sm:px-4 py-1.5 sm:py-2 rounded-lg border transition-colors text-xs sm:text-sm",ce(L).selectedNodeId.value?"bg-accent-green/20 hover:bg-accent-green/30 text-accent-green border-accent-green/50":"bg-background-mute dark:bg-stroke/10 text-content-muted dark:text-content-muted/70 border-stroke-subtle dark:border-stroke/20 cursor-not-allowed"])}," Edit ",10,Bs),e("button",{onClick:a,disabled:!ce(L).selectedNodeId.value,class:q(["px-2.5 sm:px-4 py-1.5 sm:py-2 rounded-lg border transition-colors text-xs sm:text-sm",ce(L).selectedNodeId.value?"bg-accent-red/20 hover:bg-accent-red/30 text-accent-red border-accent-red/50":"bg-background-mute dark:bg-stroke/10 text-content-muted dark:text-content-muted/70 border-stroke-subtle dark:border-stroke/20 cursor-not-allowed"])}," Delete ",10,Ls)])]),e("div",Ns,[e("div",Ps,[w[4]||(w[4]=e("div",null,[e("h4",{class:"text-xs sm:text-sm font-medium text-content-primary dark:text-content-primary mb-1"},"Global Flood Policy (*)"),e("p",{class:"text-content-secondary dark:text-content-muted text-[10px] sm:text-xs"},"Master control for repeater flooding")],-1)),e("div",Fs,[e("div",Is,[e("button",{onClick:w[0]||(w[0]=U=>N("deny")),class:q(["px-2 sm:px-3 py-1 text-[10px] sm:text-xs font-medium rounded transition-colors",k.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),e("button",{onClick:w[1]||(w[1]=U=>N("allow")),class:q(["px-2 sm:px-3 py-1 text-[10px] sm:text-xs font-medium rounded transition-colors",k.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)])])])]),e("div",Rs,[T.value?(t(),r("div",zs,w[5]||(w[5]=[e("div",{class:"animate-spin rounded-full h-8 w-8 border-b-2 border-accent-green"},null,-1),e("span",{class:"ml-2 text-content-secondary dark:text-content-muted"},"Loading transport keys...",-1)]))):c.value?(t(),r("div",Vs,[w[6]||(w[6]=e("div",{class:"text-accent-red mb-2"},"⚠️ Error loading transport keys",-1)),e("div",Ds,s(c.value),1),e("button",{onClick:n,class:"mt-4 px-4 py-2 bg-accent-green/20 hover:bg-accent-green/30 text-accent-green border border-accent-green/50 rounded-lg transition-colors"}," Retry ")])):j.value.length===0?(t(),r("div",Hs,w[7]||(w[7]=[e("div",{class:"text-content-muted dark:text-content-muted mb-2"},"📝 No transport keys found",-1),e("div",{class:"text-content-muted dark:text-content-muted/60 text-sm"},"Add your first transport key to get started",-1)]))):(t(),r("div",Us,[(t(!0),r(W,null,ee(j.value,U=>(t(),Me(uo,{key:U.id,node:U,"selected-node-id":ce(L).selectedNodeId.value,level:0,onSelect:P},null,8,["node","selected-node-id"]))),128))]))]),X(Eo,{show:g.value,"selected-node-name":d(),"selected-node-id":ce(L).selectedNodeId.value||void 0,onClose:J,onAdd:I},null,8,["show","selected-node-name","selected-node-id"]),X(ss,{show:y.value,node:x.value,onClose:D,onSave:H,onRequestDelete:se},null,8,["show","node"]),X(Ss,{show:v.value,node:u.value,"all-nodes":j.value,onClose:oe,onDeleteAll:z,onMoveChildren:f},null,8,["show","node","all-nodes"])]))}}),Ks={class:"space-y-4 sm:space-y-6"},qs={class:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3"},Ws={key:0,class:"bg-red-500/10 border border-red-500/30 rounded-lg p-4"},Gs={class:"flex items-center gap-2 text-red-600 dark:text-red-400"},Js={key:1,class:"flex items-center justify-center py-12"},Ys={key:2,class:"space-y-3"},Qs={class:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3"},Xs={class:"flex-1"},Zs={class:"flex items-center gap-2 sm:gap-3"},en={class:"min-w-0 flex-1"},tn={class:"text-content-primary dark:text-content-primary font-medium text-sm sm:text-base break-all"},rn={class:"flex flex-col sm:flex-row sm:items-center sm:gap-4 mt-1 text-xs text-content-secondary dark:text-content-muted"},on={class:"truncate"},sn={class:"truncate"},nn=["onClick","disabled"],an={key:3,class:"text-center py-12"},ln={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"},dn={class:"space-y-4"},un={class:"flex justify-end gap-3 mt-6"},cn=["disabled"],mn=["disabled"],pn={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"},bn={class:"space-y-4"},xn={class:"flex gap-2"},vn=["value"],kn={class:"bg-blue-500/10 border border-blue-500/30 rounded-lg p-4"},gn={class:"block bg-blue-500/20 px-3 py-2 rounded text-xs text-blue-100 font-mono overflow-x-auto"},yn=re({name:"APITokens",__name:"APITokens",setup(G){const L=l([]),m=l(!1),g=l(null),y=l(!1),v=l(""),x=l(null),u=l(!1),k=l(!1),A=l(null),j=async()=>{m.value=!0,g.value=null;try{const a=await Q.get("/auth/tokens"),i=a.data||a;L.value=i.tokens||[]}catch(a){console.error("Failed to fetch API tokens:",a),g.value=a instanceof Error?a.message:"Failed to fetch tokens"}finally{m.value=!1}},T=async()=>{if(!v.value.trim()){g.value="Token name is required";return}m.value=!0,g.value=null;try{const a=await Q.post("/auth/tokens",{name:v.value.trim()}),i=a.data||a;x.value=i.token||null,y.value=!1,u.value=!0,v.value="",await j()}catch(a){console.error("Failed to create API token:",a),g.value=a instanceof Error?a.message:"Failed to create token"}finally{m.value=!1}},c=(a,i)=>{A.value={id:a,name:i},k.value=!0},F=async()=>{if(A.value){m.value=!0,g.value=null;try{await Q.delete(`/auth/tokens/${A.value.id}`),await j(),k.value=!1,A.value=null}catch(a){console.error("Failed to revoke API token:",a),g.value=a instanceof Error?a.message:"Failed to revoke token"}finally{m.value=!1}}},n=()=>{y.value=!1,v.value="",g.value=null},o=()=>{u.value=!1,x.value=null},d=()=>{x.value&&navigator.clipboard.writeText(x.value)},P=a=>a?new Date(a*1e3).toLocaleString():"Never",_=V(()=>`${window.location.origin}/api/stats`);return ve(()=>{j()}),(a,i)=>(t(),r(W,null,[e("div",Ks,[e("div",qs,[i[5]||(i[5]=e("div",null,[e("h2",{class:"text-lg sm:text-xl font-semibold text-content-primary dark:text-content-primary"},"API Tokens"),e("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)),e("button",{onClick:i[0]||(i[0]=I=>y.value=!0),class:"px-3 sm:px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors flex items-center justify-center gap-2 text-sm sm:text-base"},i[4]||(i[4]=[e("svg",{class:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M12 4v16m8-8H4"})],-1),E(" Create Token ",-1)]))]),i[20]||(i[20]=ae('<div class="bg-blue-500/10 border border-blue-500/30 rounded-lg p-3 sm:p-4"><div class="flex gap-2 sm:gap-3"><svg class="w-4 h-4 sm:w-5 sm:h-5 text-blue-600 dark:text-blue-400 flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg><div class="text-xs sm:text-sm text-blue-700 dark:text-blue-200"><p><strong>API tokens</strong> are used for machine-to-machine authentication. Include the token in the <code class="bg-blue-500/20 px-1 rounded">X-API-Key</code> header when making API requests.</p><p class="mt-2">Tokens are only shown once at creation. Store them securely.</p></div></div></div>',1)),g.value?(t(),r("div",Ws,[e("div",Gs,[i[6]||(i[6]=e("svg",{class:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("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)),E(" "+s(g.value),1)])])):C("",!0),m.value&&L.value.length===0?(t(),r("div",Js,i[7]||(i[7]=[e("div",{class:"text-center"},[e("div",{class:"animate-spin w-8 h-8 border-2 border-stroke-subtle dark:border-stroke/20 border-t-primary rounded-full mx-auto mb-4"}),e("div",{class:"text-content-secondary dark:text-content-muted"},"Loading tokens...")],-1)]))):L.value.length>0?(t(),r("div",Ys,[(t(!0),r(W,null,ee(L.value,I=>(t(),r("div",{key:I.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"},[e("div",Qs,[e("div",Xs,[e("div",Zs,[i[8]||(i[8]=e("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"},[e("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)),e("div",en,[e("h3",tn,s(I.name),1),e("div",rn,[e("span",on,"Created: "+s(P(I.created_at)),1),e("span",sn,"Last used: "+s(P(I.last_used)),1)])])])]),e("button",{onClick:J=>c(I.id,I.name),disabled:m.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,nn)])]))),128))])):(t(),r("div",an,[i[9]||(i[9]=e("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"},[e("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)),i[10]||(i[10]=e("h3",{class:"text-content-primary dark:text-content-primary font-medium mb-2"},"No API Tokens",-1)),i[11]||(i[11]=e("p",{class:"text-content-secondary dark:text-content-muted text-sm mb-4"},"Create a token to enable API access",-1)),e("button",{onClick:i[1]||(i[1]=I=>y.value=!0),class:"px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors"}," Create Your First Token ")])),y.value?(t(),r("div",{key:4,class:"fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm",onClick:le(n,["self"])},[e("div",ln,[i[14]||(i[14]=e("h3",{class:"text-xl font-semibold text-content-primary dark:text-content-primary mb-4"},"Create API Token",-1)),e("div",dn,[e("div",null,[i[12]||(i[12]=e("label",{class:"block text-sm font-medium text-content-secondary dark:text-content-muted mb-2"},"Token Name",-1)),R(e("input",{"onUpdate:modelValue":i[2]||(i[2]=I=>v.value=I),type:"text",placeholder:"e.g., Production Server, CI/CD Pipeline",class:"w-full px-4 py-2 bg-background-mute dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary placeholder-gray-400 dark:placeholder-white/40 focus:outline-none focus:border-primary transition-colors",onKeydown:Pe(T,["enter"])},null,544),[[K,v.value]]),i[13]||(i[13]=e("p",{class:"text-xs text-content-muted dark:text-content-muted mt-1"},"Give your token a descriptive name to identify its purpose",-1))]),e("div",un,[e("button",{onClick:n,disabled:m.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,cn),e("button",{onClick:T,disabled:m.value||!v.value.trim(),class:"px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors disabled:opacity-50"},s(m.value?"Creating...":"Create Token"),9,mn)])])])])):C("",!0),u.value&&x.value?(t(),r("div",{key:5,class:"fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm",onClick:le(o,["self"])},[e("div",pn,[i[19]||(i[19]=e("h3",{class:"text-xl font-semibold text-content-primary dark:text-content-primary mb-4"},"Token Created Successfully",-1)),e("div",bn,[i[18]||(i[18]=ae('<div class="bg-yellow-500/10 border border-yellow-500/30 rounded-lg p-4"><div class="flex gap-3"><svg class="w-5 h-5 text-yellow-600 dark:text-yellow-400 flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path></svg><div class="text-sm text-yellow-200"><strong>Save this token now!</strong> For security reasons, it will not be shown again. </div></div></div>',1)),e("div",null,[i[16]||(i[16]=e("label",{class:"block text-sm font-medium text-content-secondary dark:text-content-muted mb-2"},"Your API Token",-1)),e("div",xn,[e("input",{value:x.value,readonly:"",class:"flex-1 px-4 py-2 bg-background-mute dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary font-mono text-sm"},null,8,vn),e("button",{onClick:d,class:"px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors flex items-center gap-2",title:"Copy to clipboard"},i[15]||(i[15]=[e("svg",{class:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("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),E(" Copy ",-1)]))])]),e("div",kn,[i[17]||(i[17]=e("p",{class:"text-sm text-blue-200 mb-2"},[e("strong",null,"Usage Example:")],-1)),e("code",gn,' curl -H "X-API-Key: '+s(x.value)+'" '+s(_.value),1)]),e("div",{class:"flex justify-end mt-6"},[e("button",{onClick:o,class:"px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors"}," Done ")])])])])):C("",!0)]),X(Fe,{show:k.value,title:"Revoke API Token",message:`Are you sure you want to revoke the token '${A.value?.name}'? This action cannot be undone.`,"confirm-text":"Revoke","cancel-text":"Cancel",variant:"danger",onConfirm:F,onClose:i[3]||(i[3]=I=>k.value=!1)},null,8,["show","message"])],64))}}),fn={class:"space-y-6"},hn={class:"glass-card rounded-lg border border-stroke-subtle dark:border-stroke/10 p-6"},wn={class:"space-y-4"},_n={class:"flex items-center justify-between"},$n=["disabled"],Cn={class:"glass-card rounded-lg border border-stroke-subtle dark:border-stroke/10 p-6"},Mn={class:"space-y-4"},An={class:"space-y-3"},Sn=["checked","disabled"],jn=["checked","disabled"],Tn={class:"flex items-start gap-3"},En={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"},Bn={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"},Ln={class:"flex-1"},Nn={class:"text-sm font-medium text-content-primary dark:text-content-primary"},Pn={key:0,class:"text-xs text-green-600 dark:text-green-400 mt-1"},Fn={key:1,class:"p-4 bg-amber-500/10 border border-amber-500/30 rounded-lg"},In={class:"flex items-start justify-between gap-3"},Rn=["disabled"],zn={key:0,class:"animate-spin h-4 w-4",fill:"none",viewBox:"0 0 24 24"},Vn={key:1,class:"w-4 h-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor"},Dn={class:"flex items-center space-x-2"},Hn={key:0,class:"w-5 h-5 text-green-600 dark:text-green-400",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor"},Un={key:1,class:"w-5 h-5 text-red-600 dark:text-red-400",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor"},On=re({name:"WebSettings",__name:"WebSettings",setup(G){const L=l(!1),m=l(""),g=l(!1),y=l(!1),v=l(!1),x=l(!1),u=l(!0),k=Ce({cors_enabled:!1,use_default_frontend:!0}),A=V(()=>g.value?"bg-green-500/10 border-green-600/40 dark:border-green-500/30":"bg-red-500/10 border-red-500/30");async function j(){try{u.value=!0;const _=await Q.get("/check_pymc_console");_.success&&_.data&&(x.value=_.data.exists,console.log("PyMC Console exists:",x.value))}catch(_){console.error("Failed to check PyMC Console:",_),x.value=!1}finally{u.value=!1}}async function T(){try{const _=await Q.get("/stats");console.log("WebSettings: Full response:",_);let a=null;if(_.success&&_.data?a=_.data:_&&"version"in _&&(a=_),a){const i=a.config?.web||{};console.log("WebSettings: webConfig:",i),k.cors_enabled=i.cors_enabled===!0,console.log("WebSettings: Set cors_enabled to:",k.cors_enabled);const I=i.web_path;k.use_default_frontend=!I||I==="",console.log("WebSettings: Set use_default_frontend to:",k.use_default_frontend,"from web_path:",I)}}catch(_){console.error("Failed to load web settings:",_),d("Failed to load settings",!1)}}async function c(){L.value=!0,m.value="";try{const _={web:{cors_enabled:k.cors_enabled}};k.use_default_frontend?_.web.web_path=null:_.web.web_path="/opt/pymc_console/web/html";const a=await Q.post("/update_web_config",_);a.success?(d("Settings saved successfully",!0),y.value=!0):d(a.error||"Failed to save settings",!1)}catch(_){console.error("Failed to save web settings:",_),d(_.message||"Failed to save settings",!1)}finally{L.value=!1}}async function F(){k.cors_enabled=!k.cors_enabled,await c()}async function n(){k.use_default_frontend=!0,await c()}async function o(){k.use_default_frontend=!1,await c()}function d(_,a){m.value=_,g.value=a,setTimeout(()=>{m.value=""},5e3)}async function P(){v.value=!0,m.value="";try{const _=await Q.post("/restart_service",{});_.success?(d("Service restart initiated. Page will reload...",!0),y.value=!1,setTimeout(()=>{window.location.reload()},2e3)):d(_.error||"Failed to restart service",!1)}catch(_){_.code==="ERR_NETWORK"||_.message?.includes("Network error")?(d("Service restarting... Page will reload",!0),y.value=!1,setTimeout(()=>{window.location.reload()},3e3)):(console.error("Failed to restart service:",_),d(_.message||"Failed to restart service",!1))}finally{v.value=!1}}return ve(()=>{T(),j()}),(_,a)=>(t(),r("div",fn,[e("div",hn,[a[1]||(a[1]=e("div",{class:"flex items-start justify-between mb-4"},[e("div",null,[e("h3",{class:"text-lg font-semibold text-content-primary dark:text-content-primary mb-1"},"CORS Settings"),e("p",{class:"text-sm text-content-secondary dark:text-content-muted"},"Control cross-origin resource sharing for API access")])],-1)),e("div",wn,[e("div",_n,[a[0]||(a[0]=e("div",null,[e("label",{class:"text-sm font-medium text-content-primary dark:text-content-primary"},"Enable CORS"),e("p",{class:"text-xs text-content-secondary dark:text-content-muted mt-1"},"Allow web frontends from different origins to access the API")],-1)),e("button",{onClick:F,disabled:L.value,class:q(["relative inline-flex h-6 w-11 items-center rounded-full transition-colors border-2",k.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",L.value?"opacity-50 cursor-not-allowed":"cursor-pointer"])},[e("span",{class:q(["inline-block h-4 w-4 transform rounded-full bg-white transition-transform shadow-lg",k.cors_enabled?"translate-x-5":"translate-x-0.5"])},null,2)],10,$n)])])]),e("div",Cn,[a[11]||(a[11]=e("div",{class:"flex items-start justify-between mb-4"},[e("div",null,[e("h3",{class:"text-lg font-semibold text-content-primary dark:text-content-primary mb-1"},"Web Frontend"),e("p",{class:"text-sm text-content-secondary dark:text-content-muted"},"Choose which web interface to use")])],-1)),e("div",Mn,[e("div",An,[e("label",{class:q(["flex items-start space-x-3 p-4 bg-background-mute dark:bg-background/30 rounded-lg border-2 cursor-pointer transition-all",k.use_default_frontend?"border-accent-cyan bg-accent-cyan/10":"border-stroke-subtle dark:border-stroke/10 hover:border-accent-cyan/50"])},[e("input",{type:"radio",name:"frontend",checked:k.use_default_frontend,onChange:n,disabled:L.value,class:"mt-1 h-4 w-4 text-accent-cyan focus:ring-accent-cyan focus:ring-offset-background"},null,40,Sn),a[2]||(a[2]=e("div",{class:"flex-1"},[e("div",{class:"text-sm font-medium text-content-primary dark:text-content-primary"},"Default Frontend"),e("div",{class:"text-xs text-content-secondary dark:text-content-muted mt-1"},"Built-in pyMC Repeater web interface"),e("div",{class:"text-xs text-content-muted dark:text-content-muted/60 mt-1 font-mono"},"Built-in")],-1))],2),e("label",{class:q(["flex items-start space-x-3 p-4 bg-background-mute dark:bg-background/30 rounded-lg border-2 cursor-pointer transition-all",k.use_default_frontend?"border-stroke-subtle dark:border-stroke/10 hover:border-accent-cyan/50":"border-accent-cyan bg-accent-cyan/10"])},[e("input",{type:"radio",name:"frontend",checked:!k.use_default_frontend,onChange:o,disabled:L.value,class:"mt-1 h-4 w-4 text-accent-cyan focus:ring-accent-cyan focus:ring-offset-background"},null,40,jn),a[3]||(a[3]=ae('<div class="flex-1"><div class="flex items-center justify-between"><div class="text-sm font-medium text-content-primary dark:text-content-primary">PyMC Console</div><span class="text-xs bg-orange-100 dark:bg-orange-500/20 text-orange-600 dark:text-orange-400 px-2 py-0.5 rounded-full border border-orange-500/30 font-medium">@Treehouse⚡</span></div><div class="text-xs text-content-secondary dark:text-content-muted mt-1">Alternative web interface for pyMC Repeater</div><div class="text-xs text-content-muted dark:text-content-muted/60 mt-1 font-mono">/opt/pymc_console/web/html</div></div>',1))],2)]),u.value?C("",!0):(t(),r("div",{key:0,class:q(["p-4 rounded-lg border",x.value?"bg-green-500/5 border-green-500/20":"bg-accent-cyan/5 border-accent-cyan/20"])},[e("div",Tn,[x.value?(t(),r("svg",En,a[4]||(a[4]=[e("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)]))):(t(),r("svg",Bn,a[5]||(a[5]=[e("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)]))),e("div",Ln,[e("h4",Nn,s(x.value?"PyMC Console has been detected":"PyMC Console Not Installed"),1),x.value?(t(),r("p",Pn,a[6]||(a[6]=[E(" PyMC Console is installed at ",-1),e("code",{class:"text-green-700 dark:text-green-300"},"/opt/pymc_console/web/html",-1)]))):(t(),r(W,{key:1},[a[7]||(a[7]=ae('<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)),y.value?(t(),r("div",Fn,[e("div",In,[a[10]||(a[10]=ae('<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)),e("button",{onClick:P,disabled:v.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"},[v.value?(t(),r("svg",zn,a[8]||(a[8]=[e("circle",{class:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor","stroke-width":"4"},null,-1),e("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)]))):(t(),r("svg",Vn,a[9]||(a[9]=[e("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)]))),E(" "+s(v.value?"Restarting...":"Restart Now"),1)],8,Rn)])])):C("",!0)])]),m.value?(t(),r("div",{key:0,class:q(["p-4 rounded-lg border",A.value])},[e("div",Dn,[g.value?(t(),r("svg",Hn,a[12]||(a[12]=[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M5 13l4 4L19 7"},null,-1)]))):(t(),r("svg",Un,a[13]||(a[13]=[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M6 18L18 6M6 6l12 12"},null,-1)]))),e("span",{class:q(g.value?"text-green-600 dark:text-green-400":"text-red-600 dark:text-red-400")},s(m.value),3)])],2)):C("",!0)]))}}),Kn={class:"space-y-4"},qn={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"},Wn={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"},Gn={class:"flex justify-between items-center"},Jn={class:"flex gap-2"},Yn=["disabled"],Qn={class:"flex gap-2"},Xn=["disabled"],Zn=["disabled"],ea={class:"bg-background-mute dark:bg-white/5 rounded-lg p-3 sm:p-4 space-y-3"},ta={key:0,class:"flex items-center justify-center py-4"},ra={key:1,class:"text-center py-4"},oa={class:"grid grid-cols-2 sm:grid-cols-4 gap-3"},sa={class:"text-center p-2 bg-white dark:bg-white/5 rounded-lg"},na={class:"text-center p-2 bg-white dark:bg-white/5 rounded-lg"},aa={class:"text-lg font-mono text-content-primary dark:text-content-primary"},la={class:"text-center p-2 bg-white dark:bg-white/5 rounded-lg"},da={class:"text-lg font-mono text-green-600 dark:text-green-400"},ia={class:"text-center p-2 bg-white dark:bg-white/5 rounded-lg"},ua={class:"text-lg font-mono text-red-600 dark:text-red-400"},ca={key:0,class:"mt-2 p-2 bg-red-50 dark:bg-red-500/10 rounded-lg border border-red-200 dark:border-red-500/30"},ma={key:1,class:"mt-2 p-2 bg-orange-50 dark:bg-orange-500/10 rounded-lg border border-orange-200 dark:border-orange-500/30"},pa={class:"font-medium"},ba={class:"font-mono text-[10px] opacity-70"},xa={class:"text-[10px]"},va={class:"bg-background-mute dark:bg-white/5 rounded-lg p-3 sm:p-4 space-y-3"},ka={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"},ga={key:0,class:"text-content-primary dark:text-content-primary font-mono text-sm"},ya={class:"flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1"},fa={key:0,class:"text-content-primary dark:text-content-primary font-mono text-sm"},ha={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"},wa={key:0,class:"text-content-primary dark:text-content-primary font-mono text-sm"},_a={key:1,class:"flex items-center gap-2"},$a={class:"flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 gap-1"},Ca={key:0,class:"text-content-primary dark:text-content-primary font-mono text-sm"},Ma={key:1,class:"flex items-center gap-2"},Aa={class:"bg-background-mute dark:bg-white/5 rounded-lg p-3 sm:p-4 space-y-3"},Sa={class:"flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1"},ja={key:0,class:"text-content-primary dark:text-content-primary font-mono text-sm"},Ta={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"},Ea={key:0,class:"text-content-primary dark:text-content-primary font-mono text-sm"},Ba={class:"flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1"},La={key:0,class:"text-content-primary dark:text-content-primary font-mono text-sm"},Na={key:1,class:"flex items-center gap-2"},Pa={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"},Fa={key:0,class:"text-content-primary dark:text-content-primary font-mono text-sm"},Ia={key:1,class:"flex items-center gap-2"},Ra={class:"flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 gap-1"},za={key:0,class:"text-content-primary dark:text-content-primary font-mono text-sm"},Va={key:1,class:"flex items-center gap-2"},Da={class:"bg-background-mute dark:bg-white/5 rounded-lg p-3 sm:p-4 space-y-3"},Ha={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"},Ua={key:0,class:"text-content-primary dark:text-content-primary font-mono text-sm"},Oa={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"},Ka={key:0,class:"text-content-primary dark:text-content-primary font-mono text-sm"},qa={key:1,class:"flex items-center gap-2"},Wa={class:"py-2"},Ga={class:"grid grid-cols-3 gap-2 mt-2"},Ja={class:"text-center p-2 bg-white dark:bg-white/5 rounded-lg"},Ya={key:0,class:"font-mono text-sm text-content-primary dark:text-content-primary"},Qa={class:"text-center p-2 bg-white dark:bg-white/5 rounded-lg"},Xa={key:0,class:"font-mono text-sm text-content-primary dark:text-content-primary"},Za={class:"text-center p-2 bg-white dark:bg-white/5 rounded-lg"},el={key:0,class:"font-mono text-sm text-content-primary dark:text-content-primary"},tl={class:"p-6 space-y-4"},rl={class:"flex justify-between items-start"},ol={class:"flex justify-end pt-4 border-t border-stroke-subtle dark:border-stroke/20"},sl=re({__name:"AdvertSettings",setup(G){const L=be(),m=V(()=>L.stats?.config?.repeater||{}),g=V(()=>m.value.advert_rate_limit||{}),y=V(()=>m.value.advert_penalty_box||{}),v=V(()=>m.value.advert_adaptive||{}),x=V(()=>v.value.thresholds||{}),u=l(!1),k=l(!1),A=l(""),j=l(""),T=l(!1),c=l(!1),F=l(null),n=l(!0),o=l(2),d=l(1),P=l(10),_=l(60),a=l(!0),i=l(2),I=l(12),J=l(6),N=l(2),D=l(24),H=l(!0),se=l(.1),oe=l(5),z=l(.05),f=l(.2),$=l(.5),w=async()=>{c.value=!0;try{const Z=await ke.get("/api/advert_rate_limit_stats");Z.data?.success&&(F.value=Z.data.data)}catch(Z){console.error("Failed to fetch rate limit stats:",Z)}finally{c.value=!1}};me([g,y,v],()=>{console.log("[AdvertSettings] Watch triggered, isEditing:",u.value),u.value?console.log("[AdvertSettings] Watch skipped (editing mode)"):(console.log("[AdvertSettings] Watch loading values from store"),console.log("[AdvertSettings] rateLimitConfig:",g.value),console.log("[AdvertSettings] penaltyConfig:",y.value),console.log("[AdvertSettings] adaptiveConfig:",v.value),n.value=g.value.enabled??!1,o.value=g.value.bucket_capacity??2,d.value=g.value.refill_tokens??1,P.value=Math.round((g.value.refill_interval_seconds??36e3)/3600),_.value=Math.round((g.value.min_interval_seconds??0)/60),a.value=y.value.enabled??!1,i.value=y.value.violation_threshold??2,I.value=Math.round((y.value.violation_decay_seconds??43200)/3600),J.value=Math.round((y.value.base_penalty_seconds??21600)/3600),N.value=y.value.penalty_multiplier??2,D.value=Math.round((y.value.max_penalty_seconds??86400)/3600),H.value=v.value.enabled??!1,se.value=v.value.ewma_alpha??.1,oe.value=Math.round((v.value.hysteresis_seconds??300)/60),z.value=x.value.quiet_max??.05,f.value=x.value.normal_max??.2,$.value=x.value.busy_max??.5,console.log("[AdvertSettings] Watch loaded values:"),console.log(" rateLimitEnabled:",n.value),console.log(" minIntervalMinutes:",_.value))},{immediate:!0}),ve(()=>{w()});const U=()=>{console.log("[AdvertSettings] reloadFormValues called"),console.log("[AdvertSettings] rateLimitConfig:",g.value),console.log("[AdvertSettings] penaltyConfig:",y.value),console.log("[AdvertSettings] adaptiveConfig:",v.value),n.value=g.value.enabled??!1,o.value=g.value.bucket_capacity??2,d.value=g.value.refill_tokens??1,P.value=Math.round((g.value.refill_interval_seconds??36e3)/3600),_.value=Math.round((g.value.min_interval_seconds??0)/60),a.value=y.value.enabled??!1,i.value=y.value.violation_threshold??2,I.value=Math.round((y.value.violation_decay_seconds??43200)/3600),J.value=Math.round((y.value.base_penalty_seconds??21600)/3600),N.value=y.value.penalty_multiplier??2,D.value=Math.round((y.value.max_penalty_seconds??86400)/3600),H.value=v.value.enabled??!1,se.value=v.value.ewma_alpha??.1,oe.value=Math.round((v.value.hysteresis_seconds??300)/60),z.value=x.value.quiet_max??.05,f.value=x.value.normal_max??.2,$.value=x.value.busy_max??.5,console.log("[AdvertSettings] Form values after reload:"),console.log(" rateLimitEnabled:",n.value),console.log(" minIntervalMinutes:",_.value),console.log(" penaltyEnabled:",a.value),console.log(" adaptiveEnabled:",H.value)},O=()=>{u.value=!0,A.value="",j.value=""},ne=()=>{u.value=!1,A.value="",j.value="",U()},ue=async()=>{k.value=!0,j.value="",A.value="";try{const Z={rate_limit_enabled:n.value,bucket_capacity:o.value,refill_tokens:d.value,refill_interval_seconds:P.value*3600,min_interval_seconds:_.value*60,penalty_enabled:a.value,violation_threshold:i.value,violation_decay_seconds:I.value*3600,base_penalty_seconds:J.value*3600,penalty_multiplier:N.value,max_penalty_seconds:D.value*3600,adaptive_enabled:H.value,ewma_alpha:se.value,hysteresis_seconds:oe.value*60,quiet_max:z.value,normal_max:f.value,busy_max:$.value};console.log("[AdvertSettings] Sending save request with payload:",Z);const h=(await ke.post("/api/update_advert_rate_limit_config",Z)).data;console.log("[AdvertSettings] API response:",h),h.success?(A.value=h.data?.message||"Settings saved successfully",console.log("[AdvertSettings] Save successful, fetching updated config..."),await L.fetchStats(),console.log("[AdvertSettings] systemStore.fetchStats() complete"),console.log("[AdvertSettings] rateLimitConfig after fetchStats:",g.value),await w(),console.log("[AdvertSettings] fetchStats() complete"),await fe(),console.log("[AdvertSettings] nextTick() complete, calling reloadFormValues()"),U(),console.log("[AdvertSettings] reloadFormValues() complete, exiting edit mode"),u.value=!1,setTimeout(()=>{A.value=""},3e3)):(j.value=h.error||"Failed to save settings",console.error("[AdvertSettings] Save failed:",h.error))}catch(Z){console.error("Failed to save advert settings:",Z),j.value=Z.response?.data?.error||"Failed to save settings"}finally{k.value=!1}},de=V(()=>F.value?.adaptive?.current_tier||"unknown"),xe=V(()=>{switch(de.value){case"quiet":return"bg-green-100 dark:bg-green-500/20 text-green-700 dark:text-green-400 border-green-500";case"normal":return"bg-blue-100 dark:bg-blue-500/20 text-blue-700 dark:text-blue-400 border-blue-500";case"busy":return"bg-yellow-100 dark:bg-yellow-500/20 text-yellow-700 dark:text-yellow-400 border-yellow-500";case"congested":return"bg-red-100 dark:bg-red-500/20 text-red-700 dark:text-red-400 border-red-500";default:return"bg-gray-100 dark:bg-gray-500/20 text-gray-700 dark:text-gray-400 border-gray-500"}});return(Z,b)=>(t(),r("div",Kn,[A.value?(t(),r("div",qn,s(A.value),1)):C("",!0),j.value?(t(),r("div",Wn,s(j.value),1)):C("",!0),e("div",Gn,[e("div",Jn,[e("button",{onClick:w,disabled:c.value,class:"px-3 py-1.5 text-xs bg-background-mute dark:bg-white/5 hover:bg-stroke-subtle dark:hover:bg-white/10 text-content-secondary dark:text-content-muted rounded-lg border border-stroke-subtle dark:border-stroke/20 transition-colors disabled:opacity-50"},s(c.value?"Loading...":"Refresh Stats"),9,Yn),e("button",{onClick:b[0]||(b[0]=h=>T.value=!0),class:"px-3 py-1.5 text-xs bg-blue-100 dark:bg-blue-500/20 hover:bg-blue-200 dark:hover:bg-blue-500/30 text-blue-700 dark:text-blue-400 rounded-lg border border-blue-500/50 transition-colors",title:"How rate limiting works"},b[19]||(b[19]=[e("svg",{class:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"})],-1)]))]),e("div",Qn,[u.value?(t(),r(W,{key:1},[e("button",{onClick:ne,disabled:k.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,Xn),e("button",{onClick:ue,disabled:k.value,class:"px-3 sm:px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors text-sm disabled:opacity-50 disabled:cursor-not-allowed"},s(k.value?"Saving...":"Save Changes"),9,Zn)],64)):(t(),r("button",{key:0,onClick:O,class:"px-3 sm:px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors text-sm"}," Edit Settings "))])]),e("div",ea,[b[28]||(b[28]=e("h3",{class:"text-sm font-medium text-content-primary dark:text-content-primary"},"Current Status",-1)),c.value&&!F.value?(t(),r("div",ta,b[20]||(b[20]=[e("div",{class:"animate-spin w-5 h-5 border-2 border-stroke-subtle dark:border-stroke/20 border-t-cyan-500 dark:border-t-primary rounded-full"},null,-1),e("span",{class:"ml-2 text-sm text-content-muted"},"Loading stats...",-1)]))):F.value?(t(),r(W,{key:2},[e("div",oa,[e("div",sa,[b[22]||(b[22]=e("div",{class:"text-xs text-content-muted dark:text-content-muted"},"Mesh Tier",-1)),e("div",{class:q(["mt-1 px-2 py-0.5 rounded border text-xs font-medium inline-block",xe.value])},s(de.value.toUpperCase()),3)]),e("div",na,[b[23]||(b[23]=e("div",{class:"text-xs text-content-muted dark:text-content-muted"},"Adverts/min",-1)),e("div",aa,s(F.value.metrics?.adverts_per_min_ewma?.toFixed(2)||"0.00"),1)]),e("div",la,[b[24]||(b[24]=e("div",{class:"text-xs text-content-muted dark:text-content-muted"},"Allowed",-1)),e("div",da,s(F.value.stats?.adverts_allowed||0),1)]),e("div",ia,[b[25]||(b[25]=e("div",{class:"text-xs text-content-muted dark:text-content-muted"},"Dropped",-1)),e("div",ua,s(F.value.stats?.adverts_dropped||0),1)])]),Object.keys(F.value.active_penalties||{}).length>0?(t(),r("div",ca,[b[26]||(b[26]=e("div",{class:"text-xs font-medium text-red-700 dark:text-red-400 mb-1"},"Active Penalties",-1)),(t(!0),r(W,null,ee(F.value.active_penalties,(h,p)=>(t(),r("div",{key:p,class:"text-xs font-mono text-red-600 dark:text-red-400"},s(p)+"... - "+s(Math.round(h))+"s remaining ",1))),128))])):C("",!0),F.value.recent_drops&&F.value.recent_drops.length>0?(t(),r("div",ma,[b[27]||(b[27]=e("div",{class:"text-xs font-medium text-orange-700 dark:text-orange-400 mb-1"},"Recently Dropped Adverts",-1)),(t(!0),r(W,null,ee(F.value.recent_drops,(h,p)=>(t(),r("div",{key:p,class:"text-xs text-orange-600 dark:text-orange-400 py-0.5"},[e("span",pa,s(h.name),1),e("span",ba,"("+s(h.pubkey)+"...)",1),e("span",xa," - "+s(h.reason)+" ("+s(h.seconds_ago)+"s ago)",1)]))),128))])):C("",!0)],64)):(t(),r("div",ra,b[21]||(b[21]=[e("p",{class:"text-xs text-content-muted dark:text-content-muted"},' Stats not available. Click "Refresh Stats" to load. ',-1)])))]),e("div",va,[b[36]||(b[36]=e("h3",{class:"text-sm font-medium text-content-primary dark:text-content-primary flex items-center gap-2"},[e("svg",{class:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("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"})]),E(" Token Bucket Rate Limiting ")],-1)),b[37]||(b[37]=e("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)),e("div",ka,[b[30]||(b[30]=e("span",{class:"text-content-secondary dark:text-content-muted text-xs sm:text-sm"},"Rate Limiting",-1)),u.value?R((t(),r("select",{key:1,"onUpdate:modelValue":b[1]||(b[1]=h=>n.value=h),class:"w-full sm:w-32 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary"},b[29]||(b[29]=[e("option",{value:!0},"Enabled",-1),e("option",{value:!1},"Disabled",-1)]),512)),[[pe,n.value]]):(t(),r("div",ga,s(n.value?"Enabled":"Disabled"),1))]),e("div",ya,[b[31]||(b[31]=e("div",null,[e("span",{class:"text-content-secondary dark:text-content-muted text-xs sm:text-sm"},"Bucket Capacity"),e("p",{class:"text-xs text-content-muted dark:text-content-muted"},"Max burst size (adverts)")],-1)),u.value?R((t(),r("input",{key:1,"onUpdate:modelValue":b[2]||(b[2]=h=>o.value=h),type:"number",min:"1",max:"10",class:"w-full sm:w-24 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary"},null,512)),[[K,o.value,void 0,{number:!0}]]):(t(),r("div",fa,s(o.value),1))]),e("div",ha,[b[33]||(b[33]=e("div",null,[e("span",{class:"text-content-secondary dark:text-content-muted text-xs sm:text-sm"},"Refill Interval"),e("p",{class:"text-xs text-content-muted dark:text-content-muted"},"Time between token refills")],-1)),u.value?(t(),r("div",_a,[R(e("input",{"onUpdate:modelValue":b[3]||(b[3]=h=>P.value=h),type:"number",min:"1",max:"48",class:"w-20 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary"},null,512),[[K,P.value,void 0,{number:!0}]]),b[32]||(b[32]=e("span",{class:"text-content-muted text-sm"},"hours",-1))])):(t(),r("div",wa,s(P.value)+" hours",1))]),e("div",$a,[b[35]||(b[35]=e("div",null,[e("span",{class:"text-content-secondary dark:text-content-muted text-xs sm:text-sm"},"Minimum Interval"),e("p",{class:"text-xs text-content-muted dark:text-content-muted"},"Hard minimum between adverts")],-1)),u.value?(t(),r("div",Ma,[R(e("input",{"onUpdate:modelValue":b[4]||(b[4]=h=>_.value=h),type:"number",min:"0",max:"1440",class:"w-20 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary"},null,512),[[K,_.value,void 0,{number:!0}]]),b[34]||(b[34]=e("span",{class:"text-content-muted text-sm"},"min",-1))])):(t(),r("div",Ca,s(_.value)+" min",1))])]),e("div",Aa,[b[47]||(b[47]=e("h3",{class:"text-sm font-medium text-content-primary dark:text-content-primary flex items-center gap-2"},[e("svg",{class:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("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"})]),E(" Penalty Box (Repeat Offenders) ")],-1)),b[48]||(b[48]=e("p",{class:"text-xs text-content-muted dark:text-content-muted"},"Applies escalating cooldowns to pubkeys that repeatedly violate limits.",-1)),e("div",Sa,[b[39]||(b[39]=e("span",{class:"text-content-secondary dark:text-content-muted text-xs sm:text-sm"},"Penalty Box",-1)),u.value?R((t(),r("select",{key:1,"onUpdate:modelValue":b[5]||(b[5]=h=>a.value=h),class:"w-full sm:w-32 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary"},b[38]||(b[38]=[e("option",{value:!0},"Enabled",-1),e("option",{value:!1},"Disabled",-1)]),512)),[[pe,a.value]]):(t(),r("div",ja,s(a.value?"Enabled":"Disabled"),1))]),e("div",Ta,[b[40]||(b[40]=e("div",null,[e("span",{class:"text-content-secondary dark:text-content-muted text-xs sm:text-sm"},"Violation Threshold"),e("p",{class:"text-xs text-content-muted dark:text-content-muted"},"Violations before penalty")],-1)),u.value?R((t(),r("input",{key:1,"onUpdate:modelValue":b[6]||(b[6]=h=>i.value=h),type:"number",min:"1",max:"10",class:"w-full sm:w-24 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary"},null,512)),[[K,i.value,void 0,{number:!0}]]):(t(),r("div",Ea,s(i.value),1))]),e("div",Ba,[b[42]||(b[42]=e("div",null,[e("span",{class:"text-content-secondary dark:text-content-muted text-xs sm:text-sm"},"Base Penalty Duration"),e("p",{class:"text-xs text-content-muted dark:text-content-muted"},"First penalty duration")],-1)),u.value?(t(),r("div",Na,[R(e("input",{"onUpdate:modelValue":b[7]||(b[7]=h=>J.value=h),type:"number",min:"1",max:"48",class:"w-20 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary"},null,512),[[K,J.value,void 0,{number:!0}]]),b[41]||(b[41]=e("span",{class:"text-content-muted text-sm"},"hours",-1))])):(t(),r("div",La,s(J.value)+" hours",1))]),e("div",Pa,[b[44]||(b[44]=e("div",null,[e("span",{class:"text-content-secondary dark:text-content-muted text-xs sm:text-sm"},"Penalty Multiplier"),e("p",{class:"text-xs text-content-muted dark:text-content-muted"},"Escalation factor")],-1)),u.value?(t(),r("div",Ia,[R(e("input",{"onUpdate:modelValue":b[8]||(b[8]=h=>N.value=h),type:"number",min:"1",max:"5",step:"0.5",class:"w-20 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary"},null,512),[[K,N.value,void 0,{number:!0}]]),b[43]||(b[43]=e("span",{class:"text-content-muted text-sm"},"x",-1))])):(t(),r("div",Fa,s(N.value)+"x",1))]),e("div",Ra,[b[46]||(b[46]=e("div",null,[e("span",{class:"text-content-secondary dark:text-content-muted text-xs sm:text-sm"},"Max Penalty Duration"),e("p",{class:"text-xs text-content-muted dark:text-content-muted"},"Maximum cooldown cap")],-1)),u.value?(t(),r("div",Va,[R(e("input",{"onUpdate:modelValue":b[9]||(b[9]=h=>D.value=h),type:"number",min:"1",max:"168",class:"w-20 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary"},null,512),[[K,D.value,void 0,{number:!0}]]),b[45]||(b[45]=e("span",{class:"text-content-muted text-sm"},"hours",-1))])):(t(),r("div",za,s(D.value)+" hours",1))])]),e("div",Da,[b[58]||(b[58]=ae('<h3 class="text-sm font-medium text-content-primary dark:text-content-primary flex items-center gap-2"><svg class="w-4 h-4" 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 Rate Limiting </h3><div class="p-3 bg-cyan-50 dark:bg-cyan-500/10 border border-cyan-200 dark:border-cyan-500/30 rounded-lg"><p class="text-xs text-cyan-700 dark:text-cyan-300 leading-relaxed"><strong>How the three systems work together:</strong> Each layer can be enabled/disabled independently and the others will still function. </p><ul class="text-xs text-cyan-700 dark:text-cyan-300 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-cyan-700 dark:text-cyan-300 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-cyan-700 dark:text-cyan-300 mt-1"><strong>Activity tiers:</strong><span class="text-green-600 dark:text-green-400 font-medium">Quiet</span> (bypass limiting) → <span class="text-blue-600 dark:text-blue-400 font-medium">Normal</span> (lighter: 0.5x intervals) → <span class="text-yellow-600 dark:text-yellow-400 font-medium">Busy</span> (base: 1.0x intervals) → <span class="text-red-600 dark:text-red-400 font-medium">Congested</span> (stricter: 2.0x intervals) </p><p class="text-xs text-cyan-700 dark:text-cyan-300 mt-1"><strong>Note:</strong> Adaptive mode scales refill/min-interval timing; bucket capacity stays at the configured base value. </p></div>',2)),e("div",Ha,[b[50]||(b[50]=e("span",{class:"text-content-secondary dark:text-content-muted text-xs sm:text-sm"},"Adaptive Mode",-1)),u.value?R((t(),r("select",{key:1,"onUpdate:modelValue":b[10]||(b[10]=h=>H.value=h),class:"w-full sm:w-32 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary"},b[49]||(b[49]=[e("option",{value:!0},"Enabled",-1),e("option",{value:!1},"Disabled",-1)]),512)),[[pe,H.value]]):(t(),r("div",Ua,s(H.value?"Enabled":"Disabled"),1))]),e("div",Oa,[b[52]||(b[52]=e("div",null,[e("span",{class:"text-content-secondary dark:text-content-muted text-xs sm:text-sm"},"Tier Change Delay"),e("p",{class:"text-xs text-content-muted dark:text-content-muted"},"Prevents tier flapping")],-1)),u.value?(t(),r("div",qa,[R(e("input",{"onUpdate:modelValue":b[11]||(b[11]=h=>oe.value=h),type:"number",min:"0",max:"60",class:"w-20 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary"},null,512),[[K,oe.value,void 0,{number:!0}]]),b[51]||(b[51]=e("span",{class:"text-content-muted text-sm"},"min",-1))])):(t(),r("div",Ka,s(oe.value)+" min",1))]),e("div",Wa,[b[56]||(b[56]=e("span",{class:"text-content-secondary dark:text-content-muted text-xs sm:text-sm mb-2 block"},"Activity Tier Thresholds (adverts/min)",-1)),e("div",Ga,[e("div",Ja,[b[53]||(b[53]=e("div",{class:"text-xs text-green-600 dark:text-green-400 mb-1"},"Quiet Max",-1)),u.value?R((t(),r("input",{key:1,"onUpdate:modelValue":b[12]||(b[12]=h=>z.value=h),type:"number",min:"0",max:"1",step:"0.01",class:"w-full px-2 py-1 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded text-content-primary dark:text-content-primary text-sm text-center focus:outline-none focus:border-primary"},null,512)),[[K,z.value,void 0,{number:!0}]]):(t(),r("div",Ya,s(z.value),1))]),e("div",Qa,[b[54]||(b[54]=e("div",{class:"text-xs text-blue-600 dark:text-blue-400 mb-1"},"Normal Max",-1)),u.value?R((t(),r("input",{key:1,"onUpdate:modelValue":b[13]||(b[13]=h=>f.value=h),type:"number",min:"0",max:"5",step:"0.01",class:"w-full px-2 py-1 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded text-content-primary dark:text-content-primary text-sm text-center focus:outline-none focus:border-primary"},null,512)),[[K,f.value,void 0,{number:!0}]]):(t(),r("div",Xa,s(f.value),1))]),e("div",Za,[b[55]||(b[55]=e("div",{class:"text-xs text-yellow-600 dark:text-yellow-400 mb-1"},"Busy Max",-1)),u.value?R((t(),r("input",{key:1,"onUpdate:modelValue":b[14]||(b[14]=h=>$.value=h),type:"number",min:"0",max:"10",step:"0.01",class:"w-full px-2 py-1 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded text-content-primary dark:text-content-primary text-sm text-center focus:outline-none focus:border-primary"},null,512)),[[K,$.value,void 0,{number:!0}]]):(t(),r("div",el,s($.value),1))])]),b[57]||(b[57]=e("p",{class:"text-xs text-content-muted dark:text-content-muted mt-2"},"Above Busy Max = Congested tier (strictest limiting)",-1))])]),T.value?(t(),r("div",{key:2,class:"fixed inset-0 bg-black/50 flex items-start justify-center z-50 p-4 overflow-y-auto",onClick:b[18]||(b[18]=le(h=>T.value=!1,["self"]))},[e("div",{class:"bg-background dark:bg-background-dark rounded-lg shadow-xl max-w-3xl w-full my-8",onClick:b[17]||(b[17]=le(()=>{},["stop"]))},[e("div",tl,[e("div",rl,[b[60]||(b[60]=e("h2",{class:"text-xl font-semibold text-content-primary dark:text-content-primary"},"How Advert Rate Limiting Works",-1)),e("button",{onClick:b[15]||(b[15]=h=>T.value=!1),class:"text-content-muted hover:text-content-primary dark:text-content-muted dark:hover:text-content-primary"},b[59]||(b[59]=[e("svg",{class:"w-6 h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M6 18L18 6M6 6l12 12"})],-1)]))]),b[61]||(b[61]=ae('<div class="bg-blue-50 dark:bg-blue-500/10 rounded-lg p-4 border border-blue-200 dark:border-blue-500/30"><h3 class="font-semibold text-blue-900 dark:text-blue-400 mb-2">Why you may see the same advert more than once</h3><p class="text-sm text-blue-800 dark:text-blue-300 leading-relaxed"> Mesh traffic can reach your repeater through different paths, so duplicate advert packets are expected. </p><ul class="text-sm text-blue-800 dark:text-blue-300 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-blue-800 dark:text-blue-300 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-green-50 dark:bg-green-500/10 rounded border border-green-500/30"><div class="text-xs font-semibold text-green-700 dark:text-green-400">QUIET</div><div class="text-xs text-green-600 dark:text-green-500">Activity &lt; 0.05/min</div><div class="text-xs text-green-700 dark:text-green-400 font-medium mt-1">No rate limiting</div></div><div class="p-2 bg-blue-50 dark:bg-blue-500/10 rounded border border-blue-500/30"><div class="text-xs font-semibold text-blue-700 dark:text-blue-400">NORMAL</div><div class="text-xs text-blue-600 dark:text-blue-500">Activity 0.05-0.20/min</div><div class="text-xs text-blue-700 dark:text-blue-400 font-medium mt-1">Light limiting (50%)</div></div><div class="p-2 bg-yellow-50 dark:bg-yellow-500/10 rounded border border-yellow-500/30"><div class="text-xs font-semibold text-yellow-700 dark:text-yellow-400">BUSY</div><div class="text-xs text-yellow-600 dark:text-yellow-500">Activity 0.20-0.50/min</div><div class="text-xs text-yellow-700 dark:text-yellow-400 font-medium mt-1">Standard limiting (100%)</div></div><div class="p-2 bg-red-50 dark:bg-red-500/10 rounded border border-red-500/30"><div class="text-xs font-semibold text-red-700 dark:text-red-400">CONGESTED</div><div class="text-xs text-red-600 dark:text-red-500">Activity &gt; 0.50/min</div><div class="text-xs text-red-700 dark:text-red-400 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-green-600 dark:text-green-400 font-semibold">QUIET</span> (bypass)<br> - 0.35 adverts/min → <span class="text-yellow-600 dark:text-yellow-400 font-semibold">BUSY</span> (tighter limits)<br> - 0.68 adverts/min → <span class="text-red-600 dark:text-red-400 font-semibold">CONGESTED</span> (strict limits) </div></div><div class="bg-green-50 dark:bg-green-500/10 rounded-lg p-4 border border-green-200 dark:border-green-500/30"><h3 class="font-semibold text-green-900 dark:text-green-400 mb-2">Recommended starting settings</h3><ul class="text-sm text-green-800 dark:text-green-300 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)),e("div",ol,[e("button",{onClick:b[16]||(b[16]=h=>T.value=!1),class:"px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors"}," Got it! ")])])])])):C("",!0)]))}}),nl={class:"space-y-6"},al={class:"glass-card rounded-lg border border-stroke-subtle dark:border-stroke/10 p-6"},ll={class:"flex items-center justify-between mb-4"},dl=["disabled"],il={key:0},ul={key:1},cl={key:0,class:"text-sm text-content-secondary dark:text-content-muted"},ml={key:1,class:"space-y-3"},pl={class:"flex items-center gap-2"},bl={key:0,class:"space-y-2"},xl=["title"],vl={key:1,class:"text-sm text-content-muted dark:text-content-muted/60 italic"},kl={class:"glass-card rounded-lg border border-stroke-subtle dark:border-stroke/10 p-6"},gl={class:"flex items-start justify-between mb-6"},yl={key:0,class:"space-y-4"},fl={class:"grid grid-cols-1 sm:grid-cols-2 gap-x-8 gap-y-3"},hl={class:"mt-1 text-sm text-content-primary dark:text-content-primary"},wl={class:"mt-1 text-sm text-content-primary dark:text-content-primary font-mono"},_l={class:"mt-1 text-sm text-content-primary dark:text-content-primary"},$l={class:"mt-1 text-sm text-content-primary dark:text-content-primary"},Cl={class:"mt-1 text-sm text-content-primary dark:text-content-primary"},Ml={class:"mt-1 text-sm text-content-primary dark:text-content-primary"},Al={key:0,class:"mt-2 text-sm text-content-muted dark:text-content-muted/60 italic"},Sl={key:1,class:"mt-2 space-y-1.5"},jl={class:"min-w-0 flex-1"},Tl={class:"text-sm font-medium text-content-primary dark:text-content-primary"},El={class:"text-xs text-content-secondary dark:text-content-muted ml-2 font-mono"},Bl=["title"],Ll={class:"mt-2 flex flex-wrap gap-1.5"},Nl={key:0,class:"text-sm text-content-muted dark:text-content-muted/60 italic"},Pl={key:1,class:"space-y-5"},Fl={class:"flex items-center justify-between p-4 rounded-lg bg-background-mute dark:bg-background/30 border border-stroke-subtle dark:border-stroke/10"},Il={class:"grid grid-cols-1 sm:grid-cols-2 gap-4"},Rl=["value"],zl={class:"grid grid-cols-1 sm:grid-cols-2 gap-4"},Vl={class:"flex items-start justify-between mb-3 gap-3"},Dl={class:"flex items-center gap-2 flex-shrink-0"},Hl={class:"relative"},Ul={key:0,class:"absolute right-0 top-full mt-1 z-20 w-64 rounded-lg shadow-lg border border-stroke-subtle dark:border-stroke/20 bg-white dark:bg-[var(--color-surface)] overflow-hidden"},Ol={class:"py-1"},Kl=["onClick"],ql={class:"min-w-0 flex-1"},Wl={class:"text-sm font-medium text-content-primary dark:text-content-primary group-hover:text-cyan-700 dark:group-hover:text-primary transition-colors"},Gl={class:"text-xs text-content-secondary dark:text-content-muted"},Jl=["href"],Yl={key:0,class:"flex flex-col items-center justify-center py-7 rounded-lg border-2 border-dashed border-stroke-subtle dark:border-stroke/20 text-content-secondary dark:text-content-muted"},Ql={key:1,class:"space-y-2"},Xl={key:0,class:"flex items-center gap-3 px-4 py-2.5"},Zl={class:"min-w-0 flex-1"},ed={class:"text-sm font-medium text-content-primary dark:text-content-primary"},td={class:"text-xs font-mono text-content-secondary dark:text-content-muted ml-2"},rd={key:0,class:"ml-2 text-xs text-red-500 dark:text-red-400"},od={class:"flex items-center gap-0.5 flex-shrink-0"},sd=["onClick"],nd=["onClick"],ad={key:1,class:"p-4 space-y-3 bg-background-mute/60 dark:bg-background/20"},ld={class:"grid grid-cols-1 sm:grid-cols-2 gap-3"},dd={class:"flex items-center gap-2 pt-1"},id=["disabled"],ud=["onClick"],cd={class:"flex flex-wrap gap-2"},md=["onClick"],pd={key:0,class:"p-3 rounded-lg bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-700/30 text-green-700 dark:text-green-400 text-sm"},bd={key:1,class:"p-3 rounded-lg bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-700/30 text-red-700 dark:text-red-400 text-sm"},xd={class:"flex items-center gap-3 pt-2"},vd=["disabled"],kd={key:0},gd={key:1},yd=["disabled"],fd=re({__name:"LetsMeshSettings",setup(G){const L=be(),m=V(()=>L.stats?.config?.letsmesh||{}),g=["REQ","RESPONSE","TXT_MSG","ACK","ADVERT","GRP_TXT","GRP_DATA","ANON_REQ","PATH","TRACE","RAW_CUSTOM"],y=[{value:0,label:"Europe only (EU v1)"},{value:1,label:"US West only (US v1)"},{value:-1,label:"All built-in brokers (EU + US)"},{value:-2,label:"Custom brokers only"}],v=[{name:"MeshMapper",website:"https://meshmapper.net",brokers:[{name:"MeshMapper",host:"mqtt.meshmapper.cc",port:443,audience:"mqtt.meshmapper.cc"}]}],x=l(!1),u=l(!1),k=l(""),A=l(""),j=l(!1),T=l(""),c=l(0),F=l(300),n=l(""),o=l(""),d=l([]),P=l([]),_=l(null),a=l({_id:0,name:"",host:"",port:443,audience:""}),i=l(!1);function I(h){i.value=!1,_.value!==null&&z(),h.brokers.forEach(p=>{const B=N(p);P.value.push(B)})}let J=1;function N(h={}){return{_id:J++,name:h.name??"",host:h.host??"",port:h.port??443,audience:h.audience??""}}function D(){const h=N();P.value.push(h),a.value={...h},_.value=h._id}function H(h){P.value=P.value.filter(p=>p._id!==h),_.value===h&&(_.value=null)}function se(h){a.value={...h},_.value=h._id}function oe(){_.value=null}function z(){const h=a.value;if(!h.name.trim()||!h.host.trim()||!h.audience.trim())return;const p=P.value.findIndex(B=>B._id===h._id);p!==-1&&P.value.splice(p,1,{...h}),_.value=null}function f(){const h=a.value,p=P.value.find(B=>B._id===h._id);(!h.audience||h.audience===(p?.host??""))&&(h.audience=h.host)}const $=V(()=>{const h={};return P.value.forEach(p=>{p.name.trim()?p.host.trim()?p.audience.trim()?(p.port<1||p.port>65535)&&(h[p._id]="Port must be 165535"):h[p._id]="Audience required":h[p._id]="Host required":h[p._id]="Name required"}),h}),w=V(()=>Object.keys($.value).length>0),U=l(null),O=l(!1);async function ne(){O.value=!0;try{const h=await ke.get("/api/letsmesh_status");h.data?.success&&(U.value=h.data.data)}catch{}finally{O.value=!1}}function ue(){const h=m.value;j.value=h.enabled??!1,T.value=h.iata_code??"",c.value=h.broker_index??0,F.value=h.status_interval??300,n.value=h.owner??"",o.value=h.email??"",d.value=Array.isArray(h.disallowed_packet_types)?[...h.disallowed_packet_types]:[],P.value=Array.isArray(h.additional_brokers)?h.additional_brokers.map(p=>N(p)):[]}me(m,()=>{x.value||ue()},{immediate:!0});function de(){ue(),_.value=null,x.value=!0,k.value="",A.value=""}function xe(){_.value=null,x.value=!1,k.value="",A.value=""}function Z(h){const p=d.value.indexOf(h);p===-1?d.value.push(h):d.value.splice(p,1)}async function b(){if(_.value!==null&&z(),w.value){A.value="Please fix broker errors before saving.";return}u.value=!0,A.value="",k.value="";try{const p=(await ke.post("/api/update_letsmesh_config",{enabled:j.value,iata_code:T.value,broker_index:c.value,status_interval:F.value,owner:n.value,email:o.value,disallowed_packet_types:d.value,additional_brokers:P.value.map(({name:B,host:te,port:_e,audience:$e})=>({name:B,host:te,port:_e,audience:$e}))})).data;p?.success?(k.value=p.data?.message||"Settings saved",x.value=!1,await L.fetchStats(),await ne(),setTimeout(()=>{k.value=""},5e3)):A.value=p?.error||"Save failed"}catch(h){const p=h;A.value=p?.response?.data?.error||p?.message||"Request failed"}finally{u.value=!1}}return ve(ne),(h,p)=>(t(),r("div",nl,[e("div",al,[e("div",ll,[p[13]||(p[13]=e("div",null,[e("h3",{class:"text-lg font-semibold text-content-primary dark:text-content-primary mb-1"},"Observer Status"),e("p",{class:"text-sm text-content-secondary dark:text-content-muted"},"Live LetsMesh broker connection state")],-1)),e("button",{onClick:ne,disabled:O.value,class:"px-3 py-1.5 text-xs rounded-lg bg-cyan-500/10 dark:bg-primary/10 hover:bg-cyan-500/20 dark:hover:bg-primary/20 text-cyan-700 dark:text-primary border border-cyan-400/30 dark:border-primary/30 transition-colors disabled:opacity-50"},[O.value?(t(),r("span",il,"Refreshing…")):(t(),r("span",ul,"↻ Refresh"))],8,dl)]),U.value?(t(),r("div",ml,[e("div",pl,[p[14]||(p[14]=e("span",{class:"text-sm text-content-secondary dark:text-content-muted w-36"},"Handler",-1)),e("span",{class:q(["inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-medium",U.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"])},[e("span",{class:q(["w-1.5 h-1.5 rounded-full",U.value.handler_active?"bg-green-500":"bg-gray-400"])},null,2),E(" "+s(U.value.handler_active?"Active":"Inactive"),1)],2)]),U.value.brokers.length?(t(),r("div",bl,[(t(!0),r(W,null,ee(U.value.brokers,B=>(t(),r("div",{key:B.host,class:"flex items-center gap-2"},[e("span",{class:"text-sm text-content-secondary dark:text-content-muted w-36 truncate",title:B.name},s(B.name),9,xl),e("span",{class:q(["inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-medium",B.connected?"bg-green-100 dark:bg-green-900/30 text-green-700 dark:text-green-400":B.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"])},[e("span",{class:q(["w-1.5 h-1.5 rounded-full",B.connected?"bg-green-500":B.reconnecting?"bg-amber-500":"bg-red-500"])},null,2),E(" "+s(B.connected?"Connected":B.reconnecting?"Reconnecting…":"Disconnected"),1)],2)]))),128))])):(t(),r("div",vl," No broker connections configured. "))])):(t(),r("div",cl," Status unavailable — service may not be running. "))]),e("div",kl,[e("div",gl,[p[15]||(p[15]=e("div",null,[e("h3",{class:"text-lg font-semibold text-content-primary dark:text-content-primary mb-1"},"Observer Configuration"),e("p",{class:"text-sm text-content-secondary dark:text-content-muted"},"Configure LetsMesh MQTT observer settings")],-1)),x.value?C("",!0):(t(),r("button",{key:0,onClick:de,class:"px-4 py-2 text-sm rounded-lg bg-cyan-500/10 dark:bg-primary/10 hover:bg-cyan-500/20 dark:hover:bg-primary/20 text-cyan-700 dark:text-primary border border-cyan-400/30 dark:border-primary/30 transition-colors"}," Edit "))]),x.value?(t(),r("div",Pl,[e("div",Fl,[p[24]||(p[24]=e("div",null,[e("label",{class:"text-sm font-medium text-content-primary dark:text-content-primary"},"Enable LetsMesh Observer"),e("p",{class:"text-xs text-content-secondary dark:text-content-muted mt-0.5"},"Publish mesh packets to the LetsMesh MQTT network")],-1)),e("button",{onClick:p[0]||(p[0]=B=>j.value=!j.value),class:q(["relative inline-flex h-6 w-11 items-center rounded-full transition-colors border-2",j.value?"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"])},[e("span",{class:q(["inline-block h-4 w-4 transform rounded-full bg-white transition-transform shadow-lg",j.value?"translate-x-5":"translate-x-0.5"])},null,2)],2)]),e("div",Il,[e("div",null,[p[25]||(p[25]=e("label",{class:"block text-sm font-medium text-content-primary dark:text-content-primary mb-1.5"},[E(" IATA Code "),e("span",{class:"text-content-secondary dark:text-content-muted font-normal text-xs ml-1"},"(e.g. SFO, LHR)")],-1)),R(e("input",{"onUpdate:modelValue":p[1]||(p[1]=B=>T.value=B),type:"text",maxlength:"10",placeholder:"TEST",class:"w-full px-3 py-2 text-sm rounded-lg bg-background-mute dark:bg-background/30 border border-stroke-subtle dark:border-stroke/20 text-content-primary dark:text-content-primary placeholder-content-muted dark:placeholder-content-muted/50 focus:outline-none focus:ring-2 focus:ring-cyan-500/40 dark:focus:ring-primary/40 font-mono"},null,512),[[K,T.value]])]),e("div",null,[p[26]||(p[26]=e("label",{class:"block text-sm font-medium text-content-primary dark:text-content-primary mb-1.5"},"Broker Mode",-1)),R(e("select",{"onUpdate:modelValue":p[2]||(p[2]=B=>c.value=B),class:"w-full px-3 py-2 text-sm rounded-lg bg-background-mute dark:bg-background/30 border border-stroke-subtle dark:border-stroke/20 text-content-primary dark:text-content-primary focus:outline-none focus:ring-2 focus:ring-cyan-500/40 dark:focus:ring-primary/40"},[(t(),r(W,null,ee(y,B=>e("option",{key:B.value,value:B.value},s(B.label),9,Rl)),64))],512),[[pe,c.value,void 0,{number:!0}]])])]),e("div",zl,[e("div",null,[p[27]||(p[27]=e("label",{class:"block text-sm font-medium text-content-primary dark:text-content-primary mb-1.5"},"Owner / Callsign",-1)),R(e("input",{"onUpdate:modelValue":p[3]||(p[3]=B=>n.value=B),type:"text",placeholder:"Optional",class:"w-full px-3 py-2 text-sm rounded-lg bg-background-mute dark:bg-background/30 border border-stroke-subtle dark:border-stroke/20 text-content-primary dark:text-content-primary placeholder-content-muted dark:placeholder-content-muted/50 focus:outline-none focus:ring-2 focus:ring-cyan-500/40 dark:focus:ring-primary/40"},null,512),[[K,n.value]])]),e("div",null,[p[28]||(p[28]=e("label",{class:"block text-sm font-medium text-content-primary dark:text-content-primary mb-1.5"},"Email",-1)),R(e("input",{"onUpdate:modelValue":p[4]||(p[4]=B=>o.value=B),type:"email",placeholder:"Optional",class:"w-full px-3 py-2 text-sm rounded-lg bg-background-mute dark:bg-background/30 border border-stroke-subtle dark:border-stroke/20 text-content-primary dark:text-content-primary placeholder-content-muted dark:placeholder-content-muted/50 focus:outline-none focus:ring-2 focus:ring-cyan-500/40 dark:focus:ring-primary/40"},null,512),[[K,o.value]])])]),e("div",null,[p[29]||(p[29]=e("label",{class:"block text-sm font-medium text-content-primary dark:text-content-primary mb-1.5"},[E(" Status Heartbeat Interval "),e("span",{class:"text-content-secondary dark:text-content-muted font-normal text-xs ml-1"},"(seconds, min 60)")],-1)),R(e("input",{"onUpdate:modelValue":p[5]||(p[5]=B=>F.value=B),type:"number",min:"60",max:"3600",class:"w-32 px-3 py-2 text-sm rounded-lg bg-background-mute dark:bg-background/30 border border-stroke-subtle dark:border-stroke/20 text-content-primary dark:text-content-primary focus:outline-none focus:ring-2 focus:ring-cyan-500/40 dark:focus:ring-primary/40 font-mono"},null,512),[[K,F.value,void 0,{number:!0}]])]),e("div",null,[e("div",Vl,[p[36]||(p[36]=e("div",{class:"min-w-0"},[e("label",{class:"text-sm font-medium text-content-primary dark:text-content-primary"},"Custom Brokers"),e("p",{class:"text-xs text-content-secondary dark:text-content-muted mt-0.5"}," Additional MQTT/WebSocket brokers alongside or instead of built-in ones ")],-1)),e("div",Dl,[e("div",Hl,[e("button",{onClick:p[6]||(p[6]=B=>i.value=!i.value),class:"inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-lg bg-background-mute dark:bg-background/30 hover:bg-stroke-subtle dark:hover:bg-stroke/10 text-content-secondary dark:text-content-muted border border-stroke-subtle dark:border-stroke/20 transition-colors"},[p[31]||(p[31]=e("svg",{class:"w-3.5 h-3.5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M19 11H5m14 0l-4-4m4 4l-4 4"})],-1)),p[32]||(p[32]=E(" From Template ",-1)),(t(),r("svg",{class:q(["w-3 h-3 ml-0.5 transition-transform",i.value?"rotate-180":""]),fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},p[30]||(p[30]=[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M19 9l-7 7-7-7"},null,-1)]),2))]),X(he,{name:"dropdown"},{default:ge(()=>[i.value?(t(),r("div",Ul,[p[34]||(p[34]=e("div",{class:"px-3 py-2 border-b border-stroke-subtle dark:border-stroke/10"},[e("p",{class:"text-xs font-medium text-content-secondary dark:text-content-muted uppercase tracking-wide"},"Known Networks")],-1)),e("div",Ol,[(t(),r(W,null,ee(v,B=>e("div",{key:B.name,class:"flex items-center gap-2 px-3 py-2.5 hover:bg-background-mute dark:hover:bg-background/30 cursor-pointer group",onClick:te=>I(B)},[e("div",ql,[e("p",Wl,s(B.name),1),e("p",Gl,s(B.brokers.length)+" broker"+s(B.brokers.length!==1?"s":""),1)]),e("a",{href:B.website,target:"_blank",rel:"noopener noreferrer",title:"Visit website",class:"flex-shrink-0 p-1 rounded hover:bg-cyan-500/10 dark:hover:bg-primary/10 text-content-secondary dark:text-content-muted hover:text-cyan-700 dark:hover:text-primary transition-colors",onClick:p[7]||(p[7]=le(()=>{},["stop"]))},p[33]||(p[33]=[e("svg",{class:"w-3.5 h-3.5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("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,Jl)],8,Kl)),64))])])):C("",!0)]),_:1}),i.value?(t(),r("div",{key:0,class:"fixed inset-0 z-10",onClick:p[8]||(p[8]=B=>i.value=!1)})):C("",!0)]),e("button",{onClick:D,class:"inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-lg bg-cyan-500/10 dark:bg-primary/10 hover:bg-cyan-500/20 dark:hover:bg-primary/20 text-cyan-700 dark:text-primary border border-cyan-400/30 dark:border-primary/30 transition-colors"},p[35]||(p[35]=[e("svg",{class:"w-3.5 h-3.5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M12 4v16m8-8H4"})],-1),E(" Add ",-1)]))])]),P.value.length?(t(),r("div",Ql,[(t(!0),r(W,null,ee(P.value,B=>(t(),r("div",{key:B._id,class:q(["rounded-lg border overflow-hidden transition-colors",$.value[B._id]?"border-red-300 dark:border-red-700/50":"border-stroke-subtle dark:border-stroke/10"])},[_.value!==B._id?(t(),r("div",Xl,[e("div",Zl,[e("span",ed,s(B.name||"(unnamed)"),1),e("span",td,s(B.host||"—")+":"+s(B.port),1),$.value[B._id]?(t(),r("span",rd,s($.value[B._id]),1)):C("",!0)]),e("div",od,[e("button",{onClick:te=>se(B),title:"Edit",class:"p-1.5 rounded hover:bg-cyan-500/10 dark:hover:bg-primary/10 text-content-secondary dark:text-content-muted hover:text-cyan-700 dark:hover:text-primary transition-colors"},p[38]||(p[38]=[e("svg",{class:"w-3.5 h-3.5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"})],-1)]),8,sd),e("button",{onClick:te=>H(B._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"},p[39]||(p[39]=[e("svg",{class:"w-3.5 h-3.5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("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,nd)])])):(t(),r("div",ad,[e("div",ld,[e("div",null,[p[40]||(p[40]=e("label",{class:"block text-xs font-medium text-content-secondary dark:text-content-muted mb-1"},[E(" Name "),e("span",{class:"text-red-500"},"*")],-1)),R(e("input",{"onUpdate:modelValue":p[9]||(p[9]=te=>a.value.name=te),type:"text",placeholder:"My Private Broker",class:"w-full px-3 py-1.5 text-sm rounded-md bg-background-mute dark:bg-background/30 border border-stroke-subtle dark:border-stroke/20 text-content-primary dark:text-content-primary placeholder-content-muted dark:placeholder-content-muted/50 focus:outline-none focus:ring-2 focus:ring-cyan-500/40 dark:focus:ring-primary/40"},null,512),[[K,a.value.name]])]),e("div",null,[p[41]||(p[41]=e("label",{class:"block text-xs font-medium text-content-secondary dark:text-content-muted mb-1"},[E(" Port "),e("span",{class:"text-red-500"},"*")],-1)),R(e("input",{"onUpdate:modelValue":p[10]||(p[10]=te=>a.value.port=te),type:"number",min:"1",max:"65535",placeholder:"443",class:"w-full px-3 py-1.5 text-sm rounded-md bg-background-mute dark:bg-background/30 border border-stroke-subtle dark:border-stroke/20 text-content-primary dark:text-content-primary placeholder-content-muted dark:placeholder-content-muted/50 focus:outline-none focus:ring-2 focus:ring-cyan-500/40 dark:focus:ring-primary/40 font-mono"},null,512),[[K,a.value.port,void 0,{number:!0}]])]),e("div",null,[p[42]||(p[42]=e("label",{class:"block text-xs font-medium text-content-secondary dark:text-content-muted mb-1"},[E(" Host "),e("span",{class:"text-red-500"},"*")],-1)),R(e("input",{"onUpdate:modelValue":p[11]||(p[11]=te=>a.value.host=te),type:"text",placeholder:"mqtt.myserver.com",onInput:f,class:"w-full px-3 py-1.5 text-sm rounded-md bg-background-mute dark:bg-background/30 border border-stroke-subtle dark:border-stroke/20 text-content-primary dark:text-content-primary placeholder-content-muted dark:placeholder-content-muted/50 focus:outline-none focus:ring-2 focus:ring-cyan-500/40 dark:focus:ring-primary/40 font-mono"},null,544),[[K,a.value.host]])]),e("div",null,[p[43]||(p[43]=e("label",{class:"block text-xs font-medium text-content-secondary dark:text-content-muted mb-1"},[E(" Audience "),e("span",{class:"text-red-500"},"*"),e("span",{class:"font-normal text-content-muted dark:text-content-muted/60 ml-1"},"(JWT aud — usually same as host)")],-1)),R(e("input",{"onUpdate:modelValue":p[12]||(p[12]=te=>a.value.audience=te),type:"text",placeholder:"mqtt.myserver.com",class:"w-full px-3 py-1.5 text-sm rounded-md bg-background-mute dark:bg-background/30 border border-stroke-subtle dark:border-stroke/20 text-content-primary dark:text-content-primary placeholder-content-muted dark:placeholder-content-muted/50 focus:outline-none focus:ring-2 focus:ring-cyan-500/40 dark:focus:ring-primary/40 font-mono"},null,512),[[K,a.value.audience]])])]),e("div",dd,[e("button",{onClick:z,disabled:!a.value.name.trim()||!a.value.host.trim()||!a.value.audience.trim(),class:"px-3 py-1.5 text-xs font-medium rounded-md bg-cyan-600 dark:bg-teal-600 hover:bg-cyan-700 dark:hover:bg-teal-700 text-white transition-colors disabled:opacity-40 disabled:cursor-not-allowed"},"Done",8,id),e("button",{onClick:oe,class:"px-3 py-1.5 text-xs rounded-md border border-stroke-subtle dark:border-stroke/20 hover:bg-stroke-subtle dark:hover:bg-stroke/10 text-content-secondary dark:text-content-muted transition-colors"},"Cancel"),e("button",{onClick:te=>H(B._id),class:"ml-auto px-3 py-1.5 text-xs rounded-md border border-red-300/60 dark:border-red-700/30 hover:bg-red-50 dark:hover:bg-red-900/20 text-red-600 dark:text-red-400 transition-colors"},"Remove",8,ud)])]))],2))),128))])):(t(),r("div",Yl,p[37]||(p[37]=[e("svg",{class:"w-7 h-7 mb-2 opacity-40",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"1.5",d:"M5 12h14M5 12l4-4m-4 4l4 4"})],-1),e("p",{class:"text-sm"},"No custom brokers",-1),e("p",{class:"text-xs mt-0.5 opacity-70"},"Built-in brokers will be used based on the mode above",-1)]))),p[44]||(p[44]=e("p",{class:"mt-2 text-xs text-content-secondary dark:text-content-muted"},[E(" Set "),e("span",{class:"font-medium"},"Broker Mode"),E(" to "),e("em",null,"Custom brokers only"),E(" to use exclusively these servers, or leave it on any other mode to use them alongside the built-in ones. ")],-1))]),e("div",null,[p[45]||(p[45]=e("label",{class:"block text-sm font-medium text-content-primary dark:text-content-primary mb-2"},[E(" Block Packet Types "),e("span",{class:"text-content-secondary dark:text-content-muted font-normal text-xs ml-1"},"(prevent publishing to LetsMesh)")],-1)),e("div",cd,[(t(),r(W,null,ee(g,B=>e("button",{key:B,onClick:te=>Z(B),class:q(["px-2.5 py-1 rounded text-xs font-mono font-medium border transition-colors",d.value.includes(B)?"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-background/30 border-stroke-subtle dark:border-stroke/20 text-content-secondary dark:text-content-muted hover:border-cyan-400/50 dark:hover:border-primary/40"])},s(B),11,md)),64))]),p[46]||(p[46]=e("p",{class:"mt-1.5 text-xs text-content-secondary dark:text-content-muted"},[e("span",{class:"text-red-600 dark:text-red-400 font-medium"},"Red = blocked."),E(" Leave all unselected to publish all packet types. ")],-1))]),p[47]||(p[47]=e("div",{class:"flex items-start gap-2 p-3 rounded-lg bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-700/30 text-amber-700 dark:text-amber-400 text-xs"},[e("svg",{class:"w-4 h-4 mt-0.5 flex-shrink-0",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("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"})]),E(" A service restart is required for LetsMesh changes to take effect. ")],-1)),k.value?(t(),r("div",pd,s(k.value),1)):C("",!0),A.value?(t(),r("div",bd,s(A.value),1)):C("",!0),e("div",xd,[e("button",{onClick:b,disabled:u.value||w.value,class:"px-5 py-2 text-sm font-medium rounded-lg bg-cyan-600 dark:bg-teal-600 hover:bg-cyan-700 dark:hover:bg-teal-700 text-white transition-colors disabled:opacity-50 disabled:cursor-not-allowed"},[u.value?(t(),r("span",kd,"Saving…")):(t(),r("span",gd,"Save Settings"))],8,vd),e("button",{onClick:xe,disabled:u.value,class:"px-4 py-2 text-sm rounded-lg bg-background-mute dark:bg-background/30 hover:bg-stroke-subtle dark:hover:bg-stroke/10 text-content-secondary dark:text-content-muted border border-stroke-subtle dark:border-stroke/20 transition-colors disabled:opacity-50"}," Cancel ",8,yd)])])):(t(),r("div",yl,[e("div",fl,[e("div",null,[p[16]||(p[16]=e("span",{class:"text-xs font-medium text-content-secondary dark:text-content-muted uppercase tracking-wide"},"Enabled",-1)),e("p",hl,[e("span",{class:q(["inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-medium",m.value.enabled?"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(m.value.enabled?"Yes":"No"),3)])]),e("div",null,[p[17]||(p[17]=e("span",{class:"text-xs font-medium text-content-secondary dark:text-content-muted uppercase tracking-wide"},"IATA Code",-1)),e("p",wl,s(m.value.iata_code||"—"),1)]),e("div",null,[p[18]||(p[18]=e("span",{class:"text-xs font-medium text-content-secondary dark:text-content-muted uppercase tracking-wide"},"Broker Mode",-1)),e("p",_l,s(y.find(B=>B.value===m.value.broker_index)?.label??`Index ${m.value.broker_index??0}`),1)]),e("div",null,[p[19]||(p[19]=e("span",{class:"text-xs font-medium text-content-secondary dark:text-content-muted uppercase tracking-wide"},"Status Interval",-1)),e("p",$l,s(m.value.status_interval??300)+"s",1)]),e("div",null,[p[20]||(p[20]=e("span",{class:"text-xs font-medium text-content-secondary dark:text-content-muted uppercase tracking-wide"},"Owner",-1)),e("p",Cl,s(m.value.owner||"—"),1)]),e("div",null,[p[21]||(p[21]=e("span",{class:"text-xs font-medium text-content-secondary dark:text-content-muted uppercase tracking-wide"},"Email",-1)),e("p",Ml,s(m.value.email||"—"),1)])]),e("div",null,[p[22]||(p[22]=e("span",{class:"text-xs font-medium text-content-secondary dark:text-content-muted uppercase tracking-wide"},"Custom Brokers",-1)),m.value.additional_brokers?.length?(t(),r("div",Sl,[(t(!0),r(W,null,ee(m.value.additional_brokers,B=>(t(),r("div",{key:B.host,class:"flex items-center gap-3 px-3 py-2 rounded-lg bg-background-mute dark:bg-background/30 border border-stroke-subtle dark:border-stroke/10"},[e("div",jl,[e("span",Tl,s(B.name),1),e("span",El,s(B.host)+":"+s(B.port),1)]),e("span",{class:"text-xs text-content-secondary dark:text-content-muted font-mono truncate max-w-[140px]",title:B.audience},s(B.audience),9,Bl)]))),128))])):(t(),r("div",Al,"None configured"))]),e("div",null,[p[23]||(p[23]=e("span",{class:"text-xs font-medium text-content-secondary dark:text-content-muted uppercase tracking-wide"},"Blocked Packet Types",-1)),e("div",Ll,[m.value.disallowed_packet_types?.length?C("",!0):(t(),r("span",Nl,"All types allowed")),(t(!0),r(W,null,ee(m.value.disallowed_packet_types,B=>(t(),r("span",{key:B,class:"px-2 py-0.5 rounded text-xs font-mono bg-red-100 dark:bg-red-900/30 text-red-700 dark:text-red-400"},s(B),1))),128))])])]))])]))}}),hd=we(fd,[["__scopeId","data-v-ae27fe35"]]),wd={class:"space-y-6"},_d={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"},$d={class:"glass-card rounded-lg border border-stroke-subtle dark:border-stroke/10 p-6"},Cd=["disabled"],Md={key:0,class:"flex items-center gap-2"},Ad={key:1,class:"flex items-center gap-2"},Sd={key:0,class:"text-xs text-green-600 dark:text-green-400 mt-2"},jd={key:1,class:"text-xs text-red-500 dark:text-red-400 mt-2"},Td={class:"glass-card rounded-lg border border-stroke-subtle dark:border-stroke/10 p-6"},Ed={key:0},Bd={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"},Ld={class:"flex items-start gap-3"},Nd={class:"flex-1"},Pd={class:"text-xs text-red-600 dark:text-red-400/80 mt-1"},Fd={class:"flex gap-2 mt-3"},Id=["disabled"],Rd=["disabled"],zd={key:2,class:"text-xs text-green-600 dark:text-green-400 mt-2"},Vd={key:3,class:"text-xs text-red-500 dark:text-red-400 mt-2"},Dd={class:"glass-card rounded-lg border border-stroke-subtle dark:border-stroke/10 p-6"},Hd={class:"space-y-3"},Ud={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"},Od={class:"text-sm text-content-secondary dark:text-content-muted"},Kd={key:0,class:"bg-background-mute dark:bg-background/30 rounded-lg p-4 border border-stroke-subtle dark:border-stroke/10"},qd={key:0,class:"text-xs text-content-secondary dark:text-content-muted space-y-1 mb-3"},Wd={class:"font-mono"},Gd={class:"font-mono"},Jd={key:0,class:"text-amber-600 dark:text-amber-400 font-medium"},Yd={key:1,class:"text-content-muted"},Qd={class:"text-xs text-content-secondary dark:text-content-muted"},Xd={class:"font-mono"},Zd={key:1},ei={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"},ti={class:"flex items-start gap-3"},ri={class:"flex-1"},oi={class:"text-xs text-amber-700 dark:text-amber-300/80 mt-1"},si={class:"flex gap-2 mt-3"},ni=["disabled"],ai=["disabled"],li={key:3,class:"text-xs text-green-600 dark:text-green-400 mt-2"},di={key:4,class:"text-xs text-red-500 dark:text-red-400 mt-2"},ii={class:"glass-card rounded-lg border border-stroke-subtle dark:border-stroke/10 p-6"},ui={key:0},ci={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"},mi={class:"flex items-start gap-3"},pi={class:"flex-1"},bi={class:"text-xs text-red-600 dark:text-red-400/80 mt-1"},xi={class:"flex gap-2 mt-3"},vi=["disabled"],ki=["disabled"],gi={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"},yi={class:"flex items-center justify-between"},fi={class:"text-xs text-content-secondary dark:text-content-muted space-y-1"},hi={class:"font-mono"},wi={key:0},_i={class:"font-mono"},$i={key:1},Ci={class:"font-mono text-[10px] break-all"},Mi={key:3,class:"text-xs text-red-500 dark:text-red-400 mt-2"},Ai=re({__name:"BackupRestore",setup(G){const L=V(()=>window.location.protocol==="http:"),m=l(!1),g=l(""),y=l("");async function v(){m.value=!0,g.value="",y.value="";try{const z=await Q.exportConfig(!1);if(!z.success||!z.data){y.value=z.error||"Export failed";return}const f=new Blob([JSON.stringify(z.data,null,2)],{type:"application/json"}),$=URL.createObjectURL(f),w=document.createElement("a");w.href=$;const U=(z.data.meta?.exported_at||new Date().toISOString()).replace(/[:.]/g,"-");w.download=`pymc-repeater-settings-${U}.json`,document.body.appendChild(w),w.click(),document.body.removeChild(w),URL.revokeObjectURL($),g.value="Settings exported successfully (secrets redacted)."}catch(z){y.value=z instanceof Error?z.message:"Export failed"}finally{m.value=!1}}const x=l(!1),u=l(!1),k=l(""),A=l("");async function j(){u.value=!0,k.value="",A.value="";try{const z=await Q.exportConfig(!0);if(!z.success||!z.data){A.value=z.error||"Export failed";return}const f=new Blob([JSON.stringify(z.data,null,2)],{type:"application/json"}),$=URL.createObjectURL(f),w=document.createElement("a");w.href=$;const U=(z.data.meta?.exported_at||new Date().toISOString()).replace(/[:.]/g,"-");w.download=`pymc-repeater-full-backup-${U}.json`,document.body.appendChild(w),w.click(),document.body.removeChild(w),URL.revokeObjectURL($),k.value="Full backup exported (includes all secrets).",x.value=!1}catch(z){A.value=z instanceof Error?z.message:"Export failed"}finally{u.value=!1}}const T=l(null),c=l(null),F=l(!1),n=l(!1),o=l(""),d=l(""),P=l(null),_=V(()=>c.value?.config?Object.keys(c.value.config).join(", "):""),a=V(()=>{const z=c.value?.meta?.includes_secrets;return z===!0||z==="true"});function i(z){const $=z.target.files?.[0];if(!$)return;T.value=$,c.value=null,F.value=!1,o.value="",d.value="";const w=new FileReader;w.onload=U=>{try{const O=JSON.parse(U.target?.result);O.config&&typeof O.config=="object"?c.value={meta:O.meta,config:O.config}:typeof O=="object"&&!Array.isArray(O)?c.value={config:O}:d.value="Invalid file format — expected a JSON config object."}catch{d.value="Invalid JSON file."}},w.readAsText($)}function I(){F.value=!1,c.value=null,T.value=null,P.value&&(P.value.value="")}async function J(){if(c.value?.config){n.value=!0,o.value="",d.value="";try{const z=await Q.importConfig(c.value.config);if(z.success){const f=z.data;let $=z.message||f?.message||"Configuration imported.";f?.restart_required&&($+=" A service restart is required for radio changes to take effect."),o.value=$,F.value=!1,c.value=null,T.value=null,P.value&&(P.value.value="")}else d.value=z.error||"Import failed"}catch(z){d.value=z instanceof Error?z.message:"Import failed"}finally{n.value=!1}}}const N=l(!1),D=l(!1),H=l(null),se=l("");async function oe(){D.value=!0,se.value="";try{const z=await Q.exportIdentityKey();if(!z.success||!z.data){se.value=z.error||"Export failed";return}H.value=z.data;const f=new Blob([z.data.identity_key_hex],{type:"text/plain"}),$=URL.createObjectURL(f),w=document.createElement("a");w.href=$,w.download=`pymc-identity-${z.data.node_address||"key"}.hex`,document.body.appendChild(w),w.click(),document.body.removeChild(w),URL.revokeObjectURL($)}catch(z){se.value=z instanceof Error?z.message:"Export failed"}finally{D.value=!1}}return(z,f)=>(t(),r("div",wd,[L.value?(t(),r("div",_d,f[6]||(f[6]=[ae('<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)]))):C("",!0),e("div",$d,[f[9]||(f[9]=e("div",{class:"flex items-start justify-between mb-4"},[e("div",null,[e("h3",{class:"text-lg font-semibold text-content-primary dark:text-content-primary mb-1"},"Export Settings"),e("p",{class:"text-sm text-content-secondary dark:text-content-muted"},[E(" Download the current configuration as a JSON file. Passwords, JWT secrets, and identity keys are "),e("strong",null,"redacted"),E(". Safe to share or use as a template for other devices. ")])])],-1)),e("button",{onClick:v,disabled:m.value,class:"px-4 py-2 bg-cyan-500/20 dark:bg-primary/20 hover:bg-cyan-500/30 dark:hover:bg-primary/30 text-cyan-900 dark:text-white rounded-lg border border-cyan-500/50 dark:border-primary/50 transition-colors disabled:opacity-50 disabled:cursor-not-allowed text-sm"},[m.value?(t(),r("span",Md,f[7]||(f[7]=[e("span",{class:"animate-spin w-4 h-4 border-2 border-current border-t-transparent rounded-full inline-block"},null,-1),E(" Exporting… ",-1)]))):(t(),r("span",Ad,f[8]||(f[8]=[e("svg",{class:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("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),E(" Export Settings ",-1)])))],8,Cd),g.value?(t(),r("p",Sd,s(g.value),1)):C("",!0),y.value?(t(),r("p",jd,s(y.value),1)):C("",!0)]),e("div",Td,[f[15]||(f[15]=ae('<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)),x.value?C("",!0):(t(),r("div",Ed,[e("button",{onClick:f[0]||(f[0]=$=>x.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"},f[10]||(f[10]=[e("span",{class:"flex items-center gap-2"},[e("svg",{class:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("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"})]),E(" Full Backup ")],-1)]))])),x.value?(t(),r("div",Bd,[e("div",Ld,[f[14]||(f[14]=e("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"},[e("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)),e("div",Nd,[f[13]||(f[13]=e("h4",{class:"text-sm font-semibold text-red-700 dark:text-red-400"},"Confirm Full Backup",-1)),e("p",Pd,[f[11]||(f[11]=E(" This will export ",-1)),f[12]||(f[12]=e("strong",null,"all secrets in plain text",-1)),E(" including admin/guest passwords, JWT secret, and your repeater's private identity key"+s(L.value?" over an unencrypted HTTP connection":"")+". ",1)]),e("div",Fd,[e("button",{onClick:j,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"},s(u.value?"Exporting…":"Yes, Export Full Backup"),9,Id),e("button",{onClick:f[1]||(f[1]=$=>x.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,Rd)])])])])):C("",!0),k.value?(t(),r("p",zd,s(k.value),1)):C("",!0),A.value?(t(),r("p",Vd,s(A.value),1)):C("",!0)]),e("div",Dd,[f[29]||(f[29]=e("div",{class:"flex items-start justify-between mb-4"},[e("div",null,[e("h3",{class:"text-lg font-semibold text-content-primary dark:text-content-primary mb-1"},"Import Configuration"),e("p",{class:"text-sm text-content-secondary dark:text-content-muted"},[E(" Restore configuration from a previously exported JSON file. Importing a "),e("strong",null,"full backup"),E(" will also restore passwords and identity keys. Importing a "),e("strong",null,"settings export"),E(" will only update non-sensitive settings. ")])])],-1)),e("div",Hd,[e("label",Ud,[f[16]||(f[16]=e("svg",{class:"w-5 h-5 text-content-secondary dark:text-content-muted",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("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)),e("span",Od,s(T.value?T.value.name:"Choose a config JSON file…"),1),e("input",{ref_key:"fileInputRef",ref:P,type:"file",accept:".json,application/json",class:"hidden",onChange:i},null,544)]),c.value?(t(),r("div",Kd,[f[20]||(f[20]=e("h4",{class:"text-sm font-medium text-content-primary dark:text-content-primary mb-2"},"Import Preview",-1)),c.value.meta?(t(),r("div",qd,[e("p",null,[f[17]||(f[17]=E("Exported: ",-1)),e("span",Wd,s(c.value.meta.exported_at),1)]),e("p",null,[f[18]||(f[18]=E("Version: ",-1)),e("span",Gd,s(c.value.meta.version),1)]),c.value.meta.includes_secrets==="true"||c.value.meta.includes_secrets===!0?(t(),r("p",Jd," ⚠ Full backup — will restore passwords and identity keys ")):(t(),r("p",Yd," Settings only — existing secrets will not be changed "))])):C("",!0),e("p",Qd,[f[19]||(f[19]=E(" Sections: ",-1)),e("span",Xd,s(_.value),1)])])):C("",!0),c.value&&!F.value?(t(),r("div",Zd,[e("button",{onClick:f[2]||(f[2]=$=>F.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 ")])):C("",!0),F.value?(t(),r("div",ei,[e("div",ti,[f[28]||(f[28]=e("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"},[e("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)),e("div",ri,[f[27]||(f[27]=e("h4",{class:"text-sm font-semibold text-amber-800 dark:text-amber-300"},"Confirm Import",-1)),e("p",oi,[f[24]||(f[24]=E(" This will overwrite current settings for: ",-1)),e("strong",null,s(_.value),1),f[25]||(f[25]=E(". ",-1)),a.value?(t(),r(W,{key:0},[f[21]||(f[21]=E(" This is a full backup — ",-1)),f[22]||(f[22]=e("strong",null,"passwords, JWT secrets, and identity keys will also be overwritten",-1)),f[23]||(f[23]=E(". ",-1))],64)):(t(),r(W,{key:1},[E(" Passwords and identity keys will not be changed. ")],64)),f[26]||(f[26]=E(" Some changes (radio settings) require a service restart. ",-1))]),e("div",si,[e("button",{onClick:J,disabled:n.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"},s(n.value?"Importing…":"Yes, Import"),9,ni),e("button",{onClick:I,disabled:n.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,ai)])])])])):C("",!0),o.value?(t(),r("p",li,s(o.value),1)):C("",!0),d.value?(t(),r("p",di,s(d.value),1)):C("",!0)])]),e("div",ii,[f[38]||(f[38]=ae('<div class="flex items-start justify-between mb-4"><div><h3 class="text-lg font-semibold text-content-primary dark:text-content-primary mb-1">Export Identity Key</h3><p class="text-sm text-content-secondary dark:text-content-muted"> Download the repeater&#39;s private identity key for backup. This key determines the node&#39;s address and cryptographic identity on the mesh. </p></div></div><div class="rounded-lg border border-red-500/30 dark:border-red-400/30 bg-red-50 dark:bg-red-500/10 p-3 mb-4"><p class="text-xs text-red-700 dark:text-red-400"><strong>Sensitive data.</strong> The identity key is the repeater&#39;s private key. Anyone with this key can impersonate your node. Store the exported file securely and never share it. </p></div>',2)),N.value?C("",!0):(t(),r("div",ui,[e("button",{onClick:f[3]||(f[3]=$=>N.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"},f[30]||(f[30]=[e("span",{class:"flex items-center gap-2"},[e("svg",{class:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("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"})]),E(" Export Identity Key ")],-1)]))])),N.value&&!H.value?(t(),r("div",ci,[e("div",mi,[f[32]||(f[32]=e("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"},[e("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)),e("div",pi,[f[31]||(f[31]=e("h4",{class:"text-sm font-semibold text-red-700 dark:text-red-400"},"Are you sure?",-1)),e("p",bi," This will transmit your private key "+s(L.value?"over an unencrypted HTTP connection. ":"")+" and download it as a file. ",1),e("div",xi,[e("button",{onClick:oe,disabled:D.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"},s(D.value?"Exporting…":"Yes, Export Key"),9,vi),e("button",{onClick:f[4]||(f[4]=$=>N.value=!1),disabled:D.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,ki)])])])])):C("",!0),H.value?(t(),r("div",gi,[e("div",yi,[f[33]||(f[33]=e("h4",{class:"text-sm font-medium text-content-primary dark:text-content-primary"},"Key Exported",-1)),e("button",{onClick:f[5]||(f[5]=$=>{H.value=null,N.value=!1}),class:"text-xs text-content-muted hover:text-content-secondary transition-colors"}," Dismiss ")]),e("div",fi,[e("p",null,[f[34]||(f[34]=E("Key length: ",-1)),e("span",hi,s(H.value.key_length_bytes)+" bytes",1)]),H.value.node_address?(t(),r("p",wi,[f[35]||(f[35]=E("Node address: ",-1)),e("span",_i,s(H.value.node_address),1)])):C("",!0),H.value.public_key_hex?(t(),r("p",$i,[f[36]||(f[36]=E("Public key: ",-1)),e("span",Ci,s(H.value.public_key_hex),1)])):C("",!0)]),f[37]||(f[37]=e("p",{class:"text-xs text-green-600 dark:text-green-400"},"File downloaded successfully.",-1))])):C("",!0),se.value?(t(),r("p",Mi,s(se.value),1)):C("",!0)])]))}}),Si={class:"space-y-6"},ji={class:"glass-card rounded-lg border border-stroke-subtle dark:border-stroke/10 p-6"},Ti={class:"flex items-start justify-between mb-4"},Ei=["disabled"],Bi={key:0,class:"flex items-center gap-1.5"},Li={key:1},Ni={key:0,class:"grid grid-cols-2 sm:grid-cols-4 gap-3 mb-6"},Pi={class:"bg-background-mute dark:bg-background/30 rounded-lg p-3 border border-stroke-subtle dark:border-stroke/10"},Fi={class:"text-lg font-semibold text-content-primary dark:text-content-primary font-mono"},Ii={class:"bg-background-mute dark:bg-background/30 rounded-lg p-3 border border-stroke-subtle dark:border-stroke/10"},Ri={class:"text-lg font-semibold text-content-primary dark:text-content-primary font-mono"},zi={class:"bg-background-mute dark:bg-background/30 rounded-lg p-3 border border-stroke-subtle dark:border-stroke/10"},Vi={class:"text-lg font-semibold text-content-primary dark:text-content-primary font-mono"},Di={class:"bg-background-mute dark:bg-background/30 rounded-lg p-3 border border-stroke-subtle dark:border-stroke/10"},Hi={class:"text-lg font-semibold text-content-primary dark:text-content-primary font-mono"},Ui={key:1,class:"flex items-center justify-center py-12"},Oi={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"},Ki={class:"text-xs text-red-700 dark:text-red-400"},qi={key:3},Wi={class:"overflow-x-auto"},Gi={class:"w-full text-sm"},Ji={class:"py-2.5 pr-4"},Yi={class:"font-mono text-content-primary dark:text-content-primary"},Qi={class:"py-2.5 pr-4 text-right"},Xi={class:"font-mono text-content-secondary dark:text-content-muted"},Zi={class:"py-2.5 pr-4 text-right hidden sm:table-cell"},eu={key:0,class:"text-xs text-content-muted"},tu={class:"text-content-muted/60 ml-1"},ru={key:1,class:"text-xs text-content-muted/50"},ou={key:2,class:"text-xs text-content-muted/50"},su={class:"py-2.5 text-right"},nu=["onClick","disabled"],au={key:0,class:"flex items-center gap-1"},lu={key:1},du={key:1,class:"text-xs text-content-muted/50"},iu={key:0,class:"glass-card rounded-lg border-2 border-red-500/50 dark:border-red-400/40 bg-red-50 dark:bg-red-500/10 p-6"},uu={class:"flex items-start gap-3"},cu={class:"flex-1"},mu={class:"text-sm font-semibold text-red-700 dark:text-red-400"},pu={class:"text-xs text-red-600 dark:text-red-400/80 mt-1"},bu={class:"flex gap-2 mt-3"},xu=["disabled"],vu=["disabled"],ku={class:"glass-card rounded-lg border border-stroke-subtle dark:border-stroke/10 p-6"},gu={class:"flex flex-wrap gap-3"},yu=["disabled"],fu=["disabled"],hu={class:"flex items-center gap-2"},wu={key:0,class:"text-xs text-green-600 dark:text-green-400 mt-3"},_u={key:1,class:"text-xs text-green-600 dark:text-green-400 mt-3"},$u=re({__name:"DatabaseManagement",setup(G){const L=new Set(["packets","adverts","noise_floor","crc_errors","room_messages","room_client_sync","companion_contacts","companion_channels","companion_messages","companion_prefs"]),m=l(!1),g=l(""),y=l(null),v=l({}),x=l(null),u=l(""),k=l(!1),A=l(""),j=V(()=>y.value?y.value.tables.reduce((a,i)=>a+i.row_count,0):0);function T(a){return L.has(a)}function c(a){if(a===0)return"0 B";const i=["B","KB","MB","GB"],I=Math.min(Math.floor(Math.log(a)/Math.log(1024)),i.length-1),J=a/Math.pow(1024,I);return`${J<10?J.toFixed(1):Math.round(J)} ${i[I]}`}function F(a){return a?new Date(a*1e3).toLocaleDateString(void 0,{month:"short",day:"numeric",year:"numeric"}):"—"}function n(a,i){return!a||!i?0:Math.max(1,Math.round((i-a)/86400))}async function o(){m.value=!0,g.value="";try{const a=await Q.getDbStats();a.success&&a.data?y.value=a.data:g.value=a.error||"Failed to load database stats"}catch(a){g.value=a instanceof Error?a.message:"Failed to load database stats"}finally{m.value=!1}}function d(a,i){u.value="",x.value={table:a,rowCount:i,executing:!1}}async function P(){if(!x.value)return;const{table:a}=x.value;x.value.executing=!0,u.value="";try{const i=a==="all"?"all":[a];a!=="all"&&(v.value[a]=!0);const I=await Q.purgeTable(i);if(I.success){const J=I.data||{},N=Object.values(J).reduce((D,H)=>D+(H.deleted||0),0);u.value=`Deleted ${N.toLocaleString()} rows${a==="all"?" from all tables":` from ${a}`}.`,x.value=null,await o()}else g.value=I.error||"Purge failed",x.value=null}catch(i){g.value=i instanceof Error?i.message:"Purge failed",x.value=null}finally{a!=="all"&&(v.value[a]=!1)}}async function _(){k.value=!0,A.value="",g.value="";try{const a=await Q.vacuumDb();if(a.success&&a.data){const i=a.data.freed_bytes;A.value=i>0?`Compacted database — freed ${c(i)} (${c(a.data.size_before)}${c(a.data.size_after)}).`:`Database already compact (${c(a.data.size_after)}).`,await o()}else g.value=a.error||"Vacuum failed"}catch(a){g.value=a instanceof Error?a.message:"Vacuum failed"}finally{k.value=!1}}return ve(o),(a,i)=>(t(),r("div",Si,[e("div",ji,[e("div",Ti,[i[3]||(i[3]=e("div",null,[e("h3",{class:"text-lg font-semibold text-content-primary dark:text-content-primary mb-1"},"Database Overview"),e("p",{class:"text-sm text-content-secondary dark:text-content-muted"}," Storage usage and table statistics for the repeater database. ")],-1)),e("button",{onClick:o,disabled:m.value,class:"px-3 py-1.5 bg-cyan-500/20 dark:bg-primary/20 hover:bg-cyan-500/30 dark:hover:bg-primary/30 text-cyan-900 dark:text-white rounded-lg border border-cyan-500/50 dark:border-primary/50 transition-colors text-sm disabled:opacity-50"},[m.value?(t(),r("span",Bi,i[2]||(i[2]=[e("span",{class:"animate-spin w-3.5 h-3.5 border-2 border-current border-t-transparent rounded-full inline-block"},null,-1),E(" Loading… ",-1)]))):(t(),r("span",Li,"Refresh"))],8,Ei)]),y.value?(t(),r("div",Ni,[e("div",Pi,[i[4]||(i[4]=e("p",{class:"text-xs text-content-muted mb-1"},"Database Size",-1)),e("p",Fi,s(c(y.value.database_size_bytes)),1)]),e("div",Ii,[i[5]||(i[5]=e("p",{class:"text-xs text-content-muted mb-1"},"RRD Metrics",-1)),e("p",Ri,s(c(y.value.rrd_size_bytes)),1)]),e("div",zi,[i[6]||(i[6]=e("p",{class:"text-xs text-content-muted mb-1"},"Total Size",-1)),e("p",Vi,s(c(y.value.database_size_bytes+y.value.rrd_size_bytes)),1)]),e("div",Di,[i[7]||(i[7]=e("p",{class:"text-xs text-content-muted mb-1"},"Total Rows",-1)),e("p",Hi,s(j.value.toLocaleString()),1)])])):C("",!0),m.value&&!y.value?(t(),r("div",Ui,i[8]||(i[8]=[e("div",{class:"text-center"},[e("div",{class:"animate-spin w-8 h-8 border-2 border-stroke-subtle dark:border-stroke/20 border-t-cyan-500 dark:border-t-primary rounded-full mx-auto mb-4"}),e("div",{class:"text-content-secondary dark:text-content-muted"},"Loading database info…")],-1)]))):C("",!0),g.value?(t(),r("div",Oi,[e("p",Ki,s(g.value),1)])):C("",!0),y.value&&y.value.tables.length>0?(t(),r("div",qi,[e("div",Wi,[e("table",Gi,[i[10]||(i[10]=e("thead",null,[e("tr",{class:"border-b border-stroke-subtle dark:border-stroke/10"},[e("th",{class:"text-left py-2 pr-4 text-xs font-medium text-content-muted uppercase tracking-wider"},"Table"),e("th",{class:"text-right py-2 pr-4 text-xs font-medium text-content-muted uppercase tracking-wider"},"Rows"),e("th",{class:"text-right py-2 pr-4 text-xs font-medium text-content-muted uppercase tracking-wider hidden sm:table-cell"},"Date Range"),e("th",{class:"text-right py-2 text-xs font-medium text-content-muted uppercase tracking-wider"},"Actions")])],-1)),e("tbody",null,[(t(!0),r(W,null,ee(y.value.tables,I=>(t(),r("tr",{key:I.name,class:"border-b border-stroke-subtle/50 dark:border-stroke/5"},[e("td",Ji,[e("span",Yi,s(I.name),1)]),e("td",Qi,[e("span",Xi,s(I.row_count.toLocaleString()),1)]),e("td",Zi,[I.has_timestamp&&I.row_count>0?(t(),r("span",eu,[E(s(F(I.oldest_timestamp))+" — "+s(F(I.newest_timestamp))+" ",1),e("span",tu,"("+s(n(I.oldest_timestamp,I.newest_timestamp))+"d)",1)])):I.row_count===0?(t(),r("span",ru,"—")):(t(),r("span",ou,"n/a"))]),e("td",su,[T(I.name)&&I.row_count>0?(t(),r("button",{key:0,onClick:J=>d(I.name,I.row_count),disabled:v.value[I.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"},[v.value[I.name]?(t(),r("span",au,i[9]||(i[9]=[e("span",{class:"animate-spin w-3 h-3 border border-current border-t-transparent rounded-full inline-block"},null,-1),E(" Purging… ",-1)]))):(t(),r("span",lu,"Empty"))],8,nu)):T(I.name)?C("",!0):(t(),r("span",du,"—"))])]))),128))])])])])):C("",!0)]),x.value?(t(),r("div",iu,[e("div",uu,[i[16]||(i[16]=e("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"},[e("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)),e("div",cu,[e("h4",mu,s(x.value.table==="all"?"Confirm Purge All Tables":`Confirm Purge "${x.value.table}"`),1),e("p",pu,[x.value.table==="all"?(t(),r(W,{key:0},[i[11]||(i[11]=E(" This will permanently delete ",-1)),i[12]||(i[12]=e("strong",null,"all data",-1)),E(" from every data table ("+s(j.value.toLocaleString())+" rows total). This cannot be undone. ",1)],64)):(t(),r(W,{key:1},[i[13]||(i[13]=E(" This will permanently delete ",-1)),e("strong",null,s(x.value.rowCount.toLocaleString())+" rows",1),i[14]||(i[14]=E(" from ",-1)),e("strong",null,s(x.value.table),1),i[15]||(i[15]=E(". This cannot be undone. ",-1))],64))]),e("div",bu,[e("button",{onClick:P,disabled:x.value.executing,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"},s(x.value.executing?"Purging…":"Yes, Delete Data"),9,xu),e("button",{onClick:i[0]||(i[0]=I=>x.value=null),disabled:x.value.executing,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,vu)])])])])):C("",!0),e("div",ku,[i[19]||(i[19]=e("h3",{class:"text-lg font-semibold text-content-primary dark:text-content-primary mb-4"},"Maintenance",-1)),e("div",gu,[e("button",{onClick:i[1]||(i[1]=I=>d("all",j.value)),disabled:!y.value||j.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 disabled:opacity-50 disabled:cursor-not-allowed"},i[17]||(i[17]=[e("span",{class:"flex items-center gap-2"},[e("svg",{class:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("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"})]),E(" Purge All Data ")],-1)]),8,yu),e("button",{onClick:_,disabled:k.value||!y.value,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 disabled:opacity-50 disabled:cursor-not-allowed"},[e("span",hu,[i[18]||(i[18]=e("svg",{class:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("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)),E(" "+s(k.value?"Compacting…":"Compact Database"),1)])],8,fu)]),A.value?(t(),r("p",wu,s(A.value),1)):C("",!0),u.value?(t(),r("p",_u,s(u.value),1)):C("",!0)])]))}}),Cu={class:"p-3 sm:p-6 space-y-4 sm:space-y-6"},Mu={class:"glass-card rounded-[15px] z-10 p-3 sm:p-4 border border-cyan-400 dark:border-primary/30 bg-cyan-500/10 dark:bg-primary/10"},Au={class:"text-cyan-700 dark:text-primary text-sm sm:text-base"},Su={class:"mt-1 sm:mt-2 text-cyan-600 dark:text-primary/80"},ju={class:"glass-card rounded-[15px] p-3 sm:p-6"},Tu={class:"relative -mx-3 sm:mx-0 mb-4 sm:mb-6"},Eu={key:0,class:"absolute left-0 top-0 bottom-[1px] w-12 z-10 flex items-center"},Bu={key:0,class:"absolute right-0 top-0 bottom-[1px] w-12 z-10 flex items-center justify-end"},Lu=["onClick"],Nu={class:"flex items-center gap-1 sm:gap-2"},Pu={key:0,class:"w-3.5 h-3.5 sm:w-4 sm:h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},Fu={key:1,class:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},Iu={key:2,class:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},Ru={key:3,class:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},zu={key:4,class:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},Vu={key:5,class:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},Du={key:6,class:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},Hu={key:7,class:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},Uu={key:8,class:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},Ou={key:9,class:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},Ku={key:10,class:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},qu={class:"min-h-[400px]"},Wu={key:0,class:"flex items-center justify-center py-12"},Gu={key:1,class:"flex items-center justify-center py-12"},Ju={class:"text-center"},Yu={class:"text-content-secondary dark:text-content-muted text-sm mb-4"},Qu={key:2},Xu=re({name:"ConfigurationView",__name:"Configuration",setup(G){const L=be(),m=l(Ie("configuration_activeTab","radio")),g=l(!1),y=l(null),v=l(!1),x=l(!1);function u(){if(!y.value)return;const T=y.value;x.value=T.scrollLeft>4,v.value=T.scrollLeft<T.scrollWidth-T.clientWidth-4}function k(T){y.value&&y.value.scrollBy({left:T==="right"?150:-150,behavior:"smooth"})}me(m,T=>Re("configuration_activeTab",T));const A=[{id:"radio",label:"Radio Settings",icon:"radio"},{id:"repeater",label:"Repeater Settings",icon:"repeater"},{id:"advert",label:"Advert Limits",icon:"advert"},{id:"duty",label:"Duty Cycle",icon:"duty"},{id:"delays",label:"TX Delays",icon:"delays"},{id:"transport",label:"Regions/Keys",icon:"keys"},{id:"api-tokens",label:"API Tokens",icon:"tokens"},{id:"web",label:"Web Options",icon:"web"},{id:"observer",label:"Observer",icon:"observer"},{id:"backup",label:"Backup",icon:"backup"},{id:"database",label:"Database",icon:"database"}];ve(async()=>{try{await L.fetchStats(),g.value=!0}catch(T){console.error("Failed to load configuration data:",T),g.value=!0}fe(()=>u())});function j(T){m.value=T}return(T,c)=>{const F=Se("router-link");return t(),r("div",Cu,[c[23]||(c[23]=e("div",null,[e("h1",{class:"text-xl sm:text-2xl font-bold text-content-primary dark:text-content-primary"},"Configuration"),e("p",{class:"text-content-secondary dark:text-content-muted mt-1 sm:mt-2 text-sm sm:text-base"},"System configuration and settings")],-1)),e("div",Mu,[e("div",Au,[c[5]||(c[5]=e("strong",null,"CAD Calibration Tool Available",-1)),e("p",Su,[c[4]||(c[4]=E(" Optimize your Channel Activity Detection settings. ",-1)),X(F,{to:"/cad-calibration",class:"underline hover:text-cyan-800 dark:hover:text-primary transition-colors"},{default:ge(()=>c[3]||(c[3]=[E(" Launch CAD Calibration Tool → ",-1)])),_:1,__:[3]})])])]),e("div",ju,[e("div",Tu,[X(he,{name:"tab-fade"},{default:ge(()=>[x.value?(t(),r("div",Eu,[c[7]||(c[7]=e("div",{class:"tab-fade-left absolute inset-0 pointer-events-none"},null,-1)),e("button",{onClick:c[0]||(c[0]=n=>k("left")),class:"relative z-10 ml-1.5 w-6 h-6 flex items-center justify-center rounded-full bg-white dark:bg-zinc-900 shadow-md border border-gray-200 dark:border-white/10 text-gray-500 dark:text-gray-300"},c[6]||(c[6]=[e("svg",{class:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2.5",d:"M15 19l-7-7 7-7"})],-1)]))])):C("",!0)]),_:1}),X(he,{name:"tab-fade"},{default:ge(()=>[v.value?(t(),r("div",Bu,[c[9]||(c[9]=e("div",{class:"tab-fade-right absolute inset-0 pointer-events-none"},null,-1)),e("button",{onClick:c[1]||(c[1]=n=>k("right")),class:"relative z-10 mr-1.5 w-6 h-6 flex items-center justify-center rounded-full bg-white dark:bg-zinc-900 shadow-md border border-gray-200 dark:border-white/10 text-gray-500 dark:text-gray-300"},c[8]||(c[8]=[e("svg",{class:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2.5",d:"M9 5l7 7-7 7"})],-1)]))])):C("",!0)]),_:1}),e("div",{ref_key:"tabsContainer",ref:y,onScroll:u,class:"flex overflow-x-auto border-b border-stroke-subtle dark:border-stroke/10 px-3 sm:px-0 scrollbar-hide"},[(t(),r(W,null,ee(A,n=>e("button",{key:n.id,onClick:o=>j(n.id),class:q(["px-3 sm:px-4 py-2 text-xs sm:text-sm font-medium transition-colors duration-200 border-b-2 mr-3 sm:mr-6 whitespace-nowrap flex-shrink-0",m.value===n.id?"text-cyan-500 dark:text-primary border-cyan-500 dark:border-primary":"text-content-secondary dark:text-content-muted border-transparent hover:text-content-primary dark:hover:text-content-primary hover:border-stroke-subtle dark:hover:border-stroke/30"])},[e("div",Nu,[n.icon==="radio"?(t(),r("svg",Pu,c[10]||(c[10]=[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M8.111 16.404a5.5 5.5 0 017.778 0M12 20h.01m-7.08-7.071c3.904-3.905 10.236-3.905 14.141 0M1.394 9.822c5.716-5.716 14.976-5.716 20.692 0"},null,-1)]))):n.icon==="repeater"?(t(),r("svg",Fu,c[11]||(c[11]=[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M5 12h14M5 12l4-4m-4 4l4 4"},null,-1)]))):n.icon==="advert"?(t(),r("svg",Iu,c[12]||(c[12]=[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"},null,-1)]))):n.icon==="duty"?(t(),r("svg",Ru,c[13]||(c[13]=[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"},null,-1)]))):n.icon==="delays"?(t(),r("svg",zu,c[14]||(c[14]=[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"},null,-1)]))):n.icon==="keys"?(t(),r("svg",Vu,c[15]||(c[15]=[e("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)]))):n.icon==="tokens"?(t(),r("svg",Du,c[16]||(c[16]=[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"},null,-1)]))):n.icon==="web"?(t(),r("svg",Hu,c[17]||(c[17]=[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9"},null,-1)]))):n.icon==="observer"?(t(),r("svg",Uu,c[18]||(c[18]=[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M3.055 11H5a2 2 0 012 2v1a2 2 0 002 2 2 2 0 012 2v2.945M8 3.935V5.5A2.5 2.5 0 0010.5 8h.5a2 2 0 012 2 2 2 0 104 0 2 2 0 012-2h1.064M15 20.488V18a2 2 0 012-2h3.064M21 12a9 9 0 11-18 0 9 9 0 0118 0z"},null,-1)]))):n.icon==="backup"?(t(),r("svg",Ou,c[19]||(c[19]=[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M8 7H5a2 2 0 00-2 2v9a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-3m-1 4l-3 3m0 0l-3-3m3 3V4"},null,-1)]))):n.icon==="database"?(t(),r("svg",Ku,c[20]||(c[20]=[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4m0 5c0 2.21-3.582 4-8 4s-8-1.79-8-4"},null,-1)]))):C("",!0),E(" "+s(n.label),1)])],10,Lu)),64))],544)]),e("div",qu,[!g.value&&ce(L).isLoading?(t(),r("div",Wu,c[21]||(c[21]=[e("div",{class:"text-center"},[e("div",{class:"animate-spin w-8 h-8 border-2 border-stroke-subtle dark:border-stroke/20 border-t-cyan-500 dark:border-t-primary rounded-full mx-auto mb-4"}),e("div",{class:"text-content-secondary dark:text-content-muted"},"Loading configuration...")],-1)]))):ce(L).error&&!g.value?(t(),r("div",Gu,[e("div",Ju,[c[22]||(c[22]=e("div",{class:"text-red-500 dark:text-red-400 mb-2"},"Failed to load configuration",-1)),e("div",Yu,s(ce(L).error),1),e("button",{onClick:c[2]||(c[2]=n=>ce(L).fetchStats()),class:"px-4 py-2 bg-cyan-500/20 dark:bg-primary/20 hover:bg-cyan-500/30 dark:hover:bg-primary/30 text-cyan-900 dark:text-white rounded-lg border border-cyan-500/50 dark:border-primary/50 transition-colors"}," Retry ")])])):(t(),r("div",Qu,[R(e("div",null,[X(bt,{key:"radio-settings"})],512),[[ie,m.value==="radio"]]),R(e("div",null,[X(gr,{key:"repeater-settings"})],512),[[ie,m.value==="repeater"]]),R(e("div",null,[X(sl,{key:"advert-settings"})],512),[[ie,m.value==="advert"]]),R(e("div",null,[X(Tr,{key:"duty-cycle"})],512),[[ie,m.value==="duty"]]),R(e("div",null,[X(Or,{key:"transmission-delays"})],512),[[ie,m.value==="delays"]]),R(e("div",null,[X(Os,{key:"transport-keys"})],512),[[ie,m.value==="transport"]]),R(e("div",null,[X(yn,{key:"api-tokens"})],512),[[ie,m.value==="api-tokens"]]),R(e("div",null,[X(On,{key:"web-settings"})],512),[[ie,m.value==="web"]]),R(e("div",null,[X(hd,{key:"letsmesh-settings"})],512),[[ie,m.value==="observer"]]),R(e("div",null,[X(Ai,{key:"backup-restore"})],512),[[ie,m.value==="backup"]]),R(e("div",null,[X($u,{key:"database-management"})],512),[[ie,m.value==="database"]])]))])])])}}}),oc=we(Xu,[["__scopeId","data-v-06241a19"]]);export{oc as default};