mirror of
https://github.com/rightup/pyMC_Repeater.git
synced 2026-03-28 17:43:06 +01:00
3 lines
208 KiB
JavaScript
3 lines
208 KiB
JavaScript
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:'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <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 < 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 > 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 1–65535"):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's private identity key for backup. This key determines the node's address and cryptographic identity on the mesh. </p></div></div><div class="rounded-lg border border-red-500/30 dark:border-red-400/30 bg-red-50 dark:bg-red-500/10 p-3 mb-4"><p class="text-xs text-red-700 dark:text-red-400"><strong>Sensitive data.</strong> The identity key is the repeater's private key. Anyone with this key can impersonate your node. Store the exported file securely and never share it. </p></div>',2)),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};
|