Files
pyMC_Repeater/repeater/web/html/assets/Neighbors-k5GXWLBO.js
T
agessaman 3725d6eb21 Add path hash mode configuration and management
- Introduced `path_hash_mode` setting in `config.yaml.example` to specify the hash size for flood packets.
- Updated `ConfigManager` to re-apply the path hash mode when the mesh section changes, with validation for acceptable values (0, 1, 2).
- Enhanced `RepeaterDaemon` to set the default path hash mode during initialization, ensuring consistent handling of flood packets.
2026-03-07 13:57:46 -08:00

66 lines
87 KiB
JavaScript

import{a as bt,b as $,g as D,e as t,t as C,s as Lt,p as f,M as Yt,r as F,c as J,D as ht,N as Rt,f as it,T as Ft,l as Dt,O as jt,j as M,F as ct,h as gt,x as It,k as tt,o as Xt,P as te,i as ft,E as Pt,n as At,w as wt,Q as ie,q as Wt,v as le,L as Et}from"./index-BABkwxNn.js";import{u as Ut}from"./useSignalQuality-Cfqa_MPL.js";import{L as W}from"./leaflet-src-BtisrQHC.js";/* empty css */import{g as _t,s as Ct}from"./preferences-DtwbSSgO.js";import"./_commonjsHelpers-CqkleIqs.js";const de={class:"bg-gray-50 dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg p-4 mb-6"},ce={class:"flex items-center gap-3"},ue={class:"flex-1 min-w-0"},pe={class:"text-content-primary dark:text-content-primary font-medium truncate"},ge={class:"text-content-secondary dark:text-content-muted text-sm font-mono"},me={key:0,class:"text-white/50 text-xs"},he={key:1,class:"text-white/50 text-xs"},be=bt({__name:"DeleteNeighborModal",props:{show:{type:Boolean},neighbor:{}},emits:["close","delete"],setup(A,{emit:o}){const r=A,i=o,e=()=>{r.neighbor&&(i("delete",r.neighbor.id),d())},d=()=>{i("close")},g=s=>{s.target===s.currentTarget&&d()};return(s,a)=>s.show&&s.neighbor?(f(),$("div",{key:0,onClick:g,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"}},[t("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:a[0]||(a[0]=Lt(()=>{},["stop"]))},[t("div",{class:"flex items-center gap-3 mb-6"},[a[2]||(a[2]=t("svg",{class:"w-6 h-6 text-accent-red",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[t("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)),a[3]||(a[3]=t("div",null,[t("h3",{class:"text-xl font-semibold text-content-primary dark:text-content-primary"},"Delete Neighbor"),t("p",{class:"text-content-secondary dark:text-content-muted text-sm mt-1"}," Are you sure you want to delete this neighbor? ")],-1)),t("button",{onClick:d,class:"ml-auto text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-primary transition-colors"},a[1]||(a[1]=[t("svg",{class:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[t("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M6 18L18 6M6 6l12 12"})],-1)]))]),t("div",de,[t("div",ce,[t("div",ue,[t("div",pe,C(s.neighbor?.node_name||s.neighbor?.long_name||s.neighbor?.short_name||"Unknown"),1),t("div",ge," ID: "+C(s.neighbor?.node_num_hex||s.neighbor?.node_num||s.neighbor?.id||"N/A"),1),s.neighbor?.contact_type?(f(),$("div",me,C(s.neighbor.contact_type),1)):D("",!0),s.neighbor?.hw_model?(f(),$("div",he,C(s.neighbor.hw_model),1)):D("",!0)])])]),a[4]||(a[4]=t("div",{class:"bg-accent-red/10 border border-accent-red/30 rounded-lg p-4 mb-6"},[t("div",{class:"flex items-center gap-2 text-accent-red text-sm"},[t("svg",{class:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[t("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"})]),t("span",null,"This action cannot be undone")])],-1)),t("div",{class:"flex gap-3"},[t("button",{onClick:d,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 "),t("button",{onClick:e,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"}," Delete ")])])])):D("",!0)}}),xe={class:"bg-gradient-to-r from-primary/20 to-accent-cyan/20 border-b border-stroke-subtle dark:border-stroke/10 px-6 py-4"},ye={class:"flex items-center justify-between"},ve={class:"flex items-center gap-3"},ke={key:0,class:"text-sm text-content-secondary dark:text-content-muted"},fe={class:"p-6"},we={key:0,class:"text-center py-8"},_e={key:1,class:"text-center py-8"},Ce={class:"text-content-secondary dark:text-content-muted text-sm"},$e={key:2,class:"space-y-4"},Me={class:"bg-background-mute dark:bg-background/50 border border-stroke-subtle dark:border-stroke/10 rounded-[15px] p-4"},Ae={class:"flex items-center justify-between mb-2"},Le={class:"flex items-baseline gap-2"},Te={class:"text-3xl font-bold text-content-primary dark:text-content-primary"},Ee={class:"grid grid-cols-2 gap-3"},Se={class:"bg-background-mute dark:bg-background/50 border border-stroke-subtle dark:border-stroke/10 rounded-[15px] p-4"},Be={class:"flex items-center gap-2 mb-2"},Ne={class:"flex gap-0.5"},Fe={class:"flex items-baseline gap-1"},De={class:"text-xl font-bold text-content-primary dark:text-content-primary"},Pe={class:"bg-background-mute dark:bg-background/50 border border-stroke-subtle dark:border-stroke/10 rounded-[15px] p-4"},ze={class:"flex items-baseline gap-1"},Re={class:"text-xl font-bold text-content-primary dark:text-content-primary"},je={class:"bg-background-mute dark:bg-background/50 border border-stroke-subtle dark:border-stroke/10 rounded-[15px] p-4"},Ie={class:"relative"},Ue={class:"flex items-center gap-2 overflow-x-auto pb-2"},Oe={key:0,class:"relative flex items-center"},Ve={key:0,class:"absolute left-1/2 -translate-x-1/2 animate-pulse"},He={class:"text-content-muted dark:text-content-muted text-xs mt-2 flex items-center justify-between"},Ze={key:0,class:"text-cyan-500 dark:text-primary animate-pulse"},We={class:"flex items-center justify-between text-xs text-content-muted dark:text-content-muted pt-2"},Qe=bt({__name:"PingResultModal",props:{show:{type:Boolean},nodeName:{default:null},result:{default:null},error:{default:null},loading:{type:Boolean,default:!1}},emits:["close"],setup(A,{emit:o}){const r=A,i=o,e=Yt(),{getSignalQuality:d}=Ut(),g=F(0),s=F(!1),a=J(()=>{const x=e.stats?.config?.radio?.spreading_factor??7,b=e.stats?.config?.radio?.bandwidth??125,L=e.stats?.config?.radio?.coding_rate??5,_=Math.pow(2,x)/b,k=8+4.25*(L-4)+20;return _*k}),w=J(()=>{if(!r.result)return{color:"text-gray-400",label:"Unknown"};const x=r.result.rtt_ms,b=a.value,L=r.result.path.length,k=2*b*L+500*L;return x<k*2.5?{color:"text-green-600 dark:text-green-400",label:"Excellent"}:x<k*4?{color:"text-yellow-600 dark:text-yellow-400",label:"Good"}:x<k*7?{color:"text-orange-600 dark:text-orange-400",label:"Fair"}:{color:"text-red-600 dark:text-red-400",label:"Poor"}}),m=J(()=>{if(!r.result)return{bars:0,color:"text-gray-400"};const x=d(r.result.rssi);return{bars:x.bars,color:x.color}});ht(()=>r.result,x=>{if(x&&!s.value){s.value=!0,g.value=0;const b=x.path.length,_=1500/(b*2);let k=0;const P=b*2-2,I=()=>{k<=P?(g.value=k/P,k++,setTimeout(I,_)):(s.value=!1,g.value=1)};setTimeout(I,100)}},{immediate:!0});const v=J(()=>{if(!r.result||!s.value)return-1;const x=r.result.path.length;if(x<=1)return-1;const b=g.value,L=.5;if(b<=L)return b/L*(x-1);{const _=(b-L)/L;return(x-1)*(1-_)}}),S=()=>{i("close")};return(x,b)=>(f(),Rt(jt,{to:"body"},[it(Ft,{name:"modal"},{default:Dt(()=>[x.show?(f(),$("div",{key:0,class:"fixed inset-0 bg-black/60 backdrop-blur-sm flex items-center justify-center z-[99999] p-4",onClick:Lt(S,["self"])},[t("div",{class:"glass-card backdrop-blur-xl border border-stroke-subtle dark:border-white/20 rounded-[20px] shadow-2xl w-full max-w-md overflow-hidden",onClick:b[0]||(b[0]=Lt(()=>{},["stop"]))},[t("div",xe,[t("div",ye,[t("div",ve,[b[2]||(b[2]=t("div",{class:"p-2 bg-cyan-400/20 dark:bg-primary/20 rounded-lg"},[t("svg",{class:"w-5 h-5 text-cyan-500 dark:text-primary",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[t("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.393c5.857-5.857 15.355-5.857 21.213 0"})])],-1)),t("div",null,[b[1]||(b[1]=t("h2",{class:"text-xl font-bold text-content-primary dark:text-content-primary"},"Ping Result",-1)),x.nodeName?(f(),$("p",ke,C(x.nodeName),1)):D("",!0)])]),t("button",{onClick:S,class:"p-2 hover:bg-stroke-subtle dark:hover:bg-white/10 rounded-lg transition-colors text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-primary"},b[3]||(b[3]=[t("svg",{class:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[t("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M6 18L18 6M6 6l12 12"})],-1)]))])]),t("div",fe,[x.loading?(f(),$("div",we,b[4]||(b[4]=[t("div",{class:"animate-spin rounded-full h-12 w-12 border-b-2 border-primary mx-auto mb-4"},null,-1),t("p",{class:"text-content-secondary dark:text-content-muted"},"Sending ping...",-1),t("p",{class:"text-content-muted dark:text-content-muted text-sm mt-1"},"Waiting for response...",-1)]))):x.error?(f(),$("div",_e,[b[5]||(b[5]=t("div",{class:"p-3 bg-accent-red/10 rounded-full w-16 h-16 mx-auto mb-4 flex items-center justify-center"},[t("svg",{class:"w-8 h-8 text-accent-red",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[t("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-1.964-1.333-2.732 0L3.268 16c-.77 1.333.192 3 1.732 3z"})])],-1)),b[6]||(b[6]=t("h3",{class:"text-accent-red font-semibold mb-2"},"Ping Failed",-1)),t("p",Ce,C(x.error),1)])):x.result?(f(),$("div",$e,[t("div",Me,[t("div",Ae,[b[7]||(b[7]=t("span",{class:"text-content-secondary dark:text-content-muted text-sm"},"Round-Trip Time",-1)),t("span",{class:M(["text-xs font-medium px-2 py-1 rounded-full",w.value.color,"bg-current/10"])},C(w.value.label),3)]),t("div",Le,[t("span",Te,C(x.result.rtt_ms.toFixed(2)),1),b[8]||(b[8]=t("span",{class:"text-content-secondary dark:text-content-muted"},"ms",-1))])]),t("div",Ee,[t("div",Se,[t("div",Be,[b[9]||(b[9]=t("span",{class:"text-content-secondary dark:text-content-muted text-sm"},"RSSI",-1)),t("div",Ne,[(f(),$(ct,null,gt(5,L=>t("div",{key:L,class:M(["w-1 h-3 rounded-sm",L<=m.value.bars?m.value.color:"bg-stroke-subtle dark:bg-stroke/10"])},null,2)),64))])]),t("div",Fe,[t("span",De,C(x.result.rssi),1),b[10]||(b[10]=t("span",{class:"text-content-secondary dark:text-content-muted text-xs"},"dBm",-1))])]),t("div",Pe,[b[12]||(b[12]=t("div",{class:"text-content-secondary dark:text-content-muted text-sm mb-2"},"SNR",-1)),t("div",ze,[t("span",Re,C(x.result.snr_db),1),b[11]||(b[11]=t("span",{class:"text-content-secondary dark:text-content-muted text-xs"},"dB",-1))])])]),t("div",je,[b[15]||(b[15]=t("div",{class:"text-content-secondary dark:text-content-muted text-sm mb-3"},"Network Path",-1)),t("div",Ie,[t("div",Ue,[(f(!0),$(ct,null,gt(x.result.path,(L,_)=>(f(),$("div",{key:_,class:"flex items-center gap-2 flex-shrink-0 relative"},[t("div",{class:M(["bg-cyan-400/20 dark:bg-primary/20 text-cyan-600 dark:text-primary border border-cyan-400/40 dark:border-primary/30 px-3 py-1.5 rounded-lg text-sm font-mono transition-all duration-300",s.value&&Math.floor(v.value)===_?"ring-2 ring-cyan-400/50 dark:ring-primary/50 scale-105":""])},C(L),3),_<x.result.path.length-1?(f(),$("div",Oe,[b[14]||(b[14]=t("svg",{class:"w-4 h-4 text-white/40 flex-shrink-0",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[t("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M9 5l7 7-7 7"})],-1)),it(Ft,{name:"packet"},{default:Dt(()=>[s.value&&v.value>=_&&v.value<_+1?(f(),$("div",Ve,b[13]||(b[13]=[t("svg",{class:"w-3 h-3 text-cyan-500 dark:text-primary drop-shadow-[0_0_6px_rgba(6,182,212,0.8)] dark:drop-shadow-[0_0_6px_rgba(59,130,246,0.8)]",fill:"currentColor",viewBox:"0 0 24 24"},[t("circle",{cx:"12",cy:"12",r:"8"})],-1)]))):D("",!0)]),_:2},1024)])):D("",!0)]))),128))])]),t("div",He,[t("span",null,C(x.result.path.length)+" hop"+C(x.result.path.length!==1?"s":""),1),s.value?(f(),$("span",Ze,"● Tracing route...")):D("",!0)])]),t("div",We,[t("span",null,"Target: "+C(x.result.target_id),1),t("span",null,"Tag: #"+C(x.result.tag),1)])])):D("",!0)]),t("div",{class:"border-t border-stroke-subtle dark:border-stroke/10 px-6 py-4"},[t("button",{onClick:S,class:"w-full py-2.5 bg-gradient-to-r from-cyan-400 to-cyan-500 text-white hover:from-cyan-500 hover:to-cyan-600 dark:bg-primary/20 dark:text-primary dark:border dark:border-primary/30 dark:hover:bg-primary/30 dark:from-transparent dark:to-transparent rounded-lg font-medium transition-all shadow-[0_2px_12px_rgba(6,182,212,0.3)] dark:shadow-none"}," Close ")])])])):D("",!0)]),_:1})]))}}),qe=It(Qe,[["__scopeId","data-v-b206e10a"]]),Ke={class:"bg-white dark:bg-surface-elevated backdrop-blur-xl rounded-[20px] shadow-2xl border border-stroke-subtle dark:border-white/20 flex flex-col h-full overflow-hidden"},Ge={class:"flex items-center justify-between p-8 pb-4 flex-shrink-0"},Je={class:"flex-1 min-w-0"},Ye={class:"text-2xl font-bold text-content-primary dark:text-content-primary mb-1"},Xe={class:"text-content-secondary dark:text-content-muted text-sm font-mono break-all"},to={class:"flex items-center gap-2"},eo={class:"flex-1 overflow-y-auto custom-scrollbar px-8"},oo={class:"mb-6"},ro={class:"grid grid-cols-1 md:grid-cols-2 gap-4"},no={class:"glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]"},so={class:"glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]"},ao={class:"text-content-primary dark:text-content-primary font-medium"},io={class:"glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]"},lo={class:"glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]"},co={class:"text-content-primary dark:text-content-primary font-medium"},uo={class:"mb-6"},po={class:"grid grid-cols-1 md:grid-cols-3 gap-4"},go={class:"glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]"},mo={class:"text-content-primary dark:text-content-primary font-medium"},ho={class:"glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]"},bo={class:"text-content-primary dark:text-content-primary font-medium"},xo={key:0,class:"glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]"},yo={class:"flex items-center gap-2"},vo={class:"flex gap-0.5"},ko={class:"mb-6"},fo={class:"grid grid-cols-1 md:grid-cols-2 gap-4"},wo={class:"glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]"},_o={class:"text-content-primary dark:text-content-primary text-sm"},Co={class:"glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]"},$o={class:"text-content-primary dark:text-content-primary text-sm"},Mo={key:0,class:"mb-6"},Ao={class:"grid grid-cols-1 md:grid-cols-3 gap-4 mb-4"},Lo={class:"glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]"},To={class:"text-content-primary dark:text-content-primary font-mono text-sm"},Eo={class:"glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]"},So={class:"text-content-primary dark:text-content-primary font-mono text-sm"},Bo={class:"glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]"},No={class:"text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1"},Fo={key:0,class:"text-content-primary dark:text-content-primary font-medium"},Do={class:"p-8 pt-4 border-t border-stroke-subtle dark:border-white/10 flex-shrink-0"},Po=bt({name:"NeighborDetailsModal",__name:"NeighborDetailsModal",props:{neighbor:{},isOpen:{type:Boolean},baseLatitude:{default:null},baseLongitude:{default:null}},emits:["close"],setup(A,{emit:o}){const{getSignalQuality:r}=Ut(),i=F("Copy"),e=A,d=o,g=F();let s=null;const a=y=>new Date(y*1e3).toLocaleString(),w=y=>y?`${y} dBm`:"N/A",m=y=>y?`${y.toFixed(1)} dB`:"N/A",v=y=>({0:"Transport Flood",1:"Flood",2:"Direct",3:"Transport Direct"})[y||0]||"Unknown",S=y=>({Unknown:"Unknown","Chat Node":"Chat Node",Repeater:"Repeater","Room Server":"Room Server","Hybrid Node":"Hybrid Node"})[y]||y,x=y=>({Unknown:"text-gray-600 dark:text-gray-400","Chat Node":"text-blue-600 dark:text-blue-400",Repeater:"text-emerald-600 dark:text-emerald-400","Room Server":"text-purple-600 dark:text-purple-400","Hybrid Node":"text-amber-600 dark:text-amber-400"})[y]||"text-gray-600 dark:text-gray-400",b=async()=>{if(!e.neighbor?.latitude||!e.neighbor?.longitude)return;const y=e.neighbor.latitude.toFixed(6),u=e.neighbor.longitude.toFixed(6),j=`${y}, ${u}`;try{await navigator.clipboard.writeText(j),i.value="Copied!",setTimeout(()=>{i.value="Copy"},2e3)}catch(K){console.error("Failed to copy coordinates:",K),i.value="Failed",setTimeout(()=>{i.value="Copy"},2e3)}},L=J(()=>{if(!e.neighbor?.latitude||!e.neighbor?.longitude||!e.baseLatitude||!e.baseLongitude)return null;const y=6371,u=(e.neighbor.latitude-e.baseLatitude)*Math.PI/180,j=(e.neighbor.longitude-e.baseLongitude)*Math.PI/180,K=Math.sin(u/2)*Math.sin(u/2)+Math.cos(e.baseLatitude*Math.PI/180)*Math.cos(e.neighbor.latitude*Math.PI/180)*Math.sin(j/2)*Math.sin(j/2),et=2*Math.atan2(Math.sqrt(K),Math.sqrt(1-K));return y*et}),_=J(()=>e.neighbor?.latitude!==null&&e.neighbor?.longitude!==null&&e.neighbor?.latitude!==0&&e.neighbor?.longitude!==0&&Math.abs(e.neighbor?.latitude??0)<=90&&Math.abs(e.neighbor?.longitude??0)<=180),k=()=>{if(!g.value||!e.neighbor||!_.value)return;s&&(s.remove(),s=null);const y=document.documentElement.classList.contains("dark");s=W.map(g.value,{center:[e.neighbor.latitude,e.neighbor.longitude],zoom:13,zoomControl:!0,attributionControl:!1});const u=y?"https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png":"https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png";W.tileLayer(u,{maxZoom:19,attribution:"© OpenStreetMap © CARTO"}).addTo(s);const j=W.divIcon({className:"custom-marker",html:`<div class="w-8 h-8 rounded-full bg-blue-500 border-2 border-white shadow-lg flex items-center justify-center text-white font-bold text-xs">${e.neighbor.node_name?.charAt(0)||"?"}</div>`,iconSize:[32,32],iconAnchor:[16,16]});if(W.marker([e.neighbor.latitude,e.neighbor.longitude],{icon:j}).addTo(s).bindPopup(`<b>${e.neighbor.node_name||"Unknown"}</b><br>${e.neighbor.pubkey.slice(0,8)}...`),e.baseLatitude!==null&&e.baseLongitude!==null&&e.baseLatitude!==0&&e.baseLongitude!==0&&Math.abs(e.baseLatitude)<=90&&Math.abs(e.baseLongitude)<=180){const et=W.divIcon({className:"custom-marker",html:'<div class="w-8 h-8 rounded-full bg-green-500 border-2 border-white shadow-lg flex items-center justify-center text-white font-bold text-xs">B</div>',iconSize:[32,32],iconAnchor:[16,16]});W.marker([e.baseLatitude,e.baseLongitude],{icon:et}).addTo(s).bindPopup("<b>Base Station</b>"),W.polyline([[e.baseLatitude,e.baseLongitude],[e.neighbor.latitude,e.neighbor.longitude]],{color:"#3b82f6",weight:2,opacity:.6,dashArray:"5, 10"}).addTo(s);const lt=W.latLngBounds([e.baseLatitude,e.baseLongitude],[e.neighbor.latitude,e.neighbor.longitude]);s.fitBounds(lt,{padding:[50,50]})}},P=y=>{y.key==="Escape"&&d("close")},I=y=>{y.target===y.currentTarget&&d("close")};ht(()=>e.isOpen,y=>{y?(document.body.style.overflow="hidden",setTimeout(()=>{_.value&&k()},100)):(document.body.style.overflow="",s&&(s.remove(),s=null))},{immediate:!0});const Z=J(()=>e.neighbor?.rssi?r(e.neighbor.rssi):null);return(y,u)=>(f(),Rt(jt,{to:"body"},[it(Ft,{name:"modal",appear:""},{default:Dt(()=>[y.isOpen&&y.neighbor?(f(),$("div",{key:0,class:"fixed inset-0 z-50 flex items-center justify-center p-4 overflow-hidden",onClick:I,onKeydown:P,tabindex:"0"},[u[20]||(u[20]=t("div",{class:"absolute inset-0 bg-black/60 backdrop-blur-md pointer-events-none"},null,-1)),t("div",{class:"relative w-full max-w-4xl max-h-[90vh] flex flex-col",onClick:u[2]||(u[2]=Lt(()=>{},["stop"]))},[t("div",Ke,[t("div",Ge,[t("div",Je,[t("h2",Ye,C(y.neighbor.node_name||"Unknown Node"),1),t("p",Xe,C(y.neighbor.pubkey),1)]),t("div",to,[t("button",{onClick:u[0]||(u[0]=j=>d("close")),class:"w-8 h-8 flex items-center justify-center rounded-full bg-gray-200 dark:bg-gray-700 hover:bg-gray-300 dark:hover:bg-gray-600 transition-colors duration-200 text-gray-700 dark:text-white hover:text-gray-900 dark:hover:text-white"},u[3]||(u[3]=[t("svg",{class:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[t("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M6 18L18 6M6 6l12 12"})],-1)]))])]),t("div",eo,[t("div",oo,[u[8]||(u[8]=t("h3",{class:"text-lg font-semibold text-content-primary dark:text-content-primary mb-4"},"Basic Information",-1)),t("div",ro,[t("div",no,[u[4]||(u[4]=t("div",{class:"text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1"},"Contact Type",-1)),t("div",{class:M(["font-medium",x(y.neighbor.contact_type)])},C(S(y.neighbor.contact_type)),3)]),t("div",so,[u[5]||(u[5]=t("div",{class:"text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1"},"Route Type",-1)),t("div",ao,C(v(y.neighbor.route_type)),1)]),t("div",io,[u[6]||(u[6]=t("div",{class:"text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1"},"Zero Hop",-1)),t("div",{class:M(["font-medium",y.neighbor.zero_hop?"text-green-600 dark:text-green-400":"text-gray-600 dark:text-gray-400"])},C(y.neighbor.zero_hop?"Yes":"No"),3)]),t("div",lo,[u[7]||(u[7]=t("div",{class:"text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1"},"Advert Count",-1)),t("div",co,C(y.neighbor.advert_count.toLocaleString()),1)])])]),t("div",uo,[u[12]||(u[12]=t("h3",{class:"text-lg font-semibold text-content-primary dark:text-content-primary mb-4"},"Signal Quality",-1)),t("div",po,[t("div",go,[u[9]||(u[9]=t("div",{class:"text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1"},"RSSI",-1)),t("div",mo,C(w(y.neighbor.rssi)),1)]),t("div",ho,[u[10]||(u[10]=t("div",{class:"text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1"},"SNR",-1)),t("div",bo,C(m(y.neighbor.snr)),1)]),Z.value?(f(),$("div",xo,[u[11]||(u[11]=t("div",{class:"text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1"},"Signal Strength",-1)),t("div",yo,[t("div",vo,[(f(),$(ct,null,gt(4,j=>t("div",{key:j,class:M(["w-1 h-3 rounded-sm",j<=Z.value.bars?Z.value.color:"bg-gray-300 dark:bg-gray-700"])},null,2)),64))]),t("span",{class:M(["text-sm font-medium",Z.value.color])},C(Z.value.quality),3)])])):D("",!0)])]),t("div",ko,[u[15]||(u[15]=t("h3",{class:"text-lg font-semibold text-content-primary dark:text-content-primary mb-4"},"Timeline",-1)),t("div",fo,[t("div",wo,[u[13]||(u[13]=t("div",{class:"text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1"},"First Seen",-1)),t("div",_o,C(a(y.neighbor.first_seen)),1)]),t("div",Co,[u[14]||(u[14]=t("div",{class:"text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1"},"Last Seen",-1)),t("div",$o,C(a(y.neighbor.last_seen)),1)])])]),_.value?(f(),$("div",Mo,[u[19]||(u[19]=t("h3",{class:"text-lg font-semibold text-content-primary dark:text-content-primary mb-4"},"Location",-1)),t("div",Ao,[t("div",Lo,[u[16]||(u[16]=t("div",{class:"text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1"},"Latitude",-1)),t("div",To,C(y.neighbor.latitude?.toFixed(6)),1)]),t("div",Eo,[u[17]||(u[17]=t("div",{class:"text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1"},"Longitude",-1)),t("div",So,C(y.neighbor.longitude?.toFixed(6)),1)]),t("div",Bo,[t("div",No,C(L.value!==null?"Distance":"Coordinates"),1),L.value!==null?(f(),$("div",Fo,C(L.value.toFixed(2))+" km ",1)):(f(),$("button",{key:1,onClick:b,class:"w-full px-3 py-1.5 bg-primary hover:bg-primary/90 dark:bg-gray-700 dark:hover:bg-gray-600 text-white text-sm font-medium rounded-lg transition-colors flex items-center justify-center gap-1.5"},[u[18]||(u[18]=t("svg",{class:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[t("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)),tt(" "+C(i.value),1)]))])]),t("div",{ref_key:"mapContainer",ref:g,class:"w-full h-96 rounded-[12px] overflow-hidden border border-stroke-subtle dark:border-white/10"},null,512)])):D("",!0)]),t("div",Do,[t("button",{onClick:u[1]||(u[1]=j=>d("close")),class:"w-full px-4 py-2.5 bg-primary hover:bg-primary/90 dark:bg-gray-700 dark:hover:bg-gray-600 text-white font-medium rounded-lg transition-colors"}," Close ")])])])],32)):D("",!0)]),_:1})]))}}),zo=It(Po,[["__scopeId","data-v-5669a05a"]]),Qt=[Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array],St=1,vt=8;class Ot{static from(o){if(!(o instanceof ArrayBuffer))throw new Error("Data must be an instance of ArrayBuffer.");const[r,i]=new Uint8Array(o,0,2);if(r!==219)throw new Error("Data does not appear to be in a KDBush format.");const e=i>>4;if(e!==St)throw new Error(`Got v${e} data when expected v${St}.`);const d=Qt[i&15];if(!d)throw new Error("Unrecognized array type.");const[g]=new Uint16Array(o,2,1),[s]=new Uint32Array(o,4,1);return new Ot(s,g,d,o)}constructor(o,r=64,i=Float64Array,e){if(isNaN(o)||o<0)throw new Error(`Unpexpected numItems value: ${o}.`);this.numItems=+o,this.nodeSize=Math.min(Math.max(+r,2),65535),this.ArrayType=i,this.IndexArrayType=o<65536?Uint16Array:Uint32Array;const d=Qt.indexOf(this.ArrayType),g=o*2*this.ArrayType.BYTES_PER_ELEMENT,s=o*this.IndexArrayType.BYTES_PER_ELEMENT,a=(8-s%8)%8;if(d<0)throw new Error(`Unexpected typed array class: ${i}.`);e&&e instanceof ArrayBuffer?(this.data=e,this.ids=new this.IndexArrayType(this.data,vt,o),this.coords=new this.ArrayType(this.data,vt+s+a,o*2),this._pos=o*2,this._finished=!0):(this.data=new ArrayBuffer(vt+g+s+a),this.ids=new this.IndexArrayType(this.data,vt,o),this.coords=new this.ArrayType(this.data,vt+s+a,o*2),this._pos=0,this._finished=!1,new Uint8Array(this.data,0,2).set([219,(St<<4)+d]),new Uint16Array(this.data,2,1)[0]=r,new Uint32Array(this.data,4,1)[0]=o)}add(o,r){const i=this._pos>>1;return this.ids[i]=i,this.coords[this._pos++]=o,this.coords[this._pos++]=r,i}finish(){const o=this._pos>>1;if(o!==this.numItems)throw new Error(`Added ${o} items when expected ${this.numItems}.`);return zt(this.ids,this.coords,this.nodeSize,0,this.numItems-1,0),this._finished=!0,this}range(o,r,i,e){if(!this._finished)throw new Error("Data not yet indexed - call index.finish().");const{ids:d,coords:g,nodeSize:s}=this,a=[0,d.length-1,0],w=[];for(;a.length;){const m=a.pop()||0,v=a.pop()||0,S=a.pop()||0;if(v-S<=s){for(let _=S;_<=v;_++){const k=g[2*_],P=g[2*_+1];k>=o&&k<=i&&P>=r&&P<=e&&w.push(d[_])}continue}const x=S+v>>1,b=g[2*x],L=g[2*x+1];b>=o&&b<=i&&L>=r&&L<=e&&w.push(d[x]),(m===0?o<=b:r<=L)&&(a.push(S),a.push(x-1),a.push(1-m)),(m===0?i>=b:e>=L)&&(a.push(x+1),a.push(v),a.push(1-m))}return w}within(o,r,i){if(!this._finished)throw new Error("Data not yet indexed - call index.finish().");const{ids:e,coords:d,nodeSize:g}=this,s=[0,e.length-1,0],a=[],w=i*i;for(;s.length;){const m=s.pop()||0,v=s.pop()||0,S=s.pop()||0;if(v-S<=g){for(let _=S;_<=v;_++)qt(d[2*_],d[2*_+1],o,r)<=w&&a.push(e[_]);continue}const x=S+v>>1,b=d[2*x],L=d[2*x+1];qt(b,L,o,r)<=w&&a.push(e[x]),(m===0?o-i<=b:r-i<=L)&&(s.push(S),s.push(x-1),s.push(1-m)),(m===0?o+i>=b:r+i>=L)&&(s.push(x+1),s.push(v),s.push(1-m))}return a}}function zt(A,o,r,i,e,d){if(e-i<=r)return;const g=i+e>>1;ee(A,o,g,i,e,d),zt(A,o,r,i,g-1,1-d),zt(A,o,r,g+1,e,1-d)}function ee(A,o,r,i,e,d){for(;e>i;){if(e-i>600){const w=e-i+1,m=r-i+1,v=Math.log(w),S=.5*Math.exp(2*v/3),x=.5*Math.sqrt(v*S*(w-S)/w)*(m-w/2<0?-1:1),b=Math.max(i,Math.floor(r-m*S/w+x)),L=Math.min(e,Math.floor(r+(w-m)*S/w+x));ee(A,o,r,b,L,d)}const g=o[2*r+d];let s=i,a=e;for(kt(A,o,i,r),o[2*e+d]>g&&kt(A,o,i,e);s<a;){for(kt(A,o,s,a),s++,a--;o[2*s+d]<g;)s++;for(;o[2*a+d]>g;)a--}o[2*i+d]===g?kt(A,o,i,a):(a++,kt(A,o,a,e)),a<=r&&(i=a+1),r<=a&&(e=a-1)}}function kt(A,o,r,i){Bt(A,r,i),Bt(o,2*r,2*i),Bt(o,2*r+1,2*i+1)}function Bt(A,o,r){const i=A[o];A[o]=A[r],A[r]=i}function qt(A,o,r,i){const e=A-r,d=o-i;return e*e+d*d}const Ro={minZoom:0,maxZoom:16,minPoints:2,radius:40,extent:512,nodeSize:64,log:!1,generateId:!1,reduce:null,map:A=>A},Kt=Math.fround||(A=>o=>(A[0]=+o,A[0]))(new Float32Array(1)),mt=2,pt=3,Nt=4,ut=5,oe=6;class jo{constructor(o){this.options=Object.assign(Object.create(Ro),o),this.trees=new Array(this.options.maxZoom+1),this.stride=this.options.reduce?7:6,this.clusterProps=[]}load(o){const{log:r,minZoom:i,maxZoom:e}=this.options;r&&console.time("total time");const d=`prepare ${o.length} points`;r&&console.time(d),this.points=o;const g=[];for(let a=0;a<o.length;a++){const w=o[a];if(!w.geometry)continue;const[m,v]=w.geometry.coordinates,S=Kt($t(m)),x=Kt(Mt(v));g.push(S,x,1/0,a,-1,1),this.options.reduce&&g.push(0)}let s=this.trees[e+1]=this._createTree(g);r&&console.timeEnd(d);for(let a=e;a>=i;a--){const w=+Date.now();s=this.trees[a]=this._createTree(this._cluster(s,a)),r&&console.log("z%d: %d clusters in %dms",a,s.numItems,+Date.now()-w)}return r&&console.timeEnd("total time"),this}getClusters(o,r){let i=((o[0]+180)%360+360)%360-180;const e=Math.max(-90,Math.min(90,o[1]));let d=o[2]===180?180:((o[2]+180)%360+360)%360-180;const g=Math.max(-90,Math.min(90,o[3]));if(o[2]-o[0]>=360)i=-180,d=180;else if(i>d){const v=this.getClusters([i,e,180,g],r),S=this.getClusters([-180,e,d,g],r);return v.concat(S)}const s=this.trees[this._limitZoom(r)],a=s.range($t(i),Mt(g),$t(d),Mt(e)),w=s.data,m=[];for(const v of a){const S=this.stride*v;m.push(w[S+ut]>1?Gt(w,S,this.clusterProps):this.points[w[S+pt]])}return m}getChildren(o){const r=this._getOriginId(o),i=this._getOriginZoom(o),e="No cluster with the specified id.",d=this.trees[i];if(!d)throw new Error(e);const g=d.data;if(r*this.stride>=g.length)throw new Error(e);const s=this.options.radius/(this.options.extent*Math.pow(2,i-1)),a=g[r*this.stride],w=g[r*this.stride+1],m=d.within(a,w,s),v=[];for(const S of m){const x=S*this.stride;g[x+Nt]===o&&v.push(g[x+ut]>1?Gt(g,x,this.clusterProps):this.points[g[x+pt]])}if(v.length===0)throw new Error(e);return v}getLeaves(o,r,i){r=r||10,i=i||0;const e=[];return this._appendLeaves(e,o,r,i,0),e}getTile(o,r,i){const e=this.trees[this._limitZoom(o)],d=Math.pow(2,o),{extent:g,radius:s}=this.options,a=s/g,w=(i-a)/d,m=(i+1+a)/d,v={features:[]};return this._addTileFeatures(e.range((r-a)/d,w,(r+1+a)/d,m),e.data,r,i,d,v),r===0&&this._addTileFeatures(e.range(1-a/d,w,1,m),e.data,d,i,d,v),r===d-1&&this._addTileFeatures(e.range(0,w,a/d,m),e.data,-1,i,d,v),v.features.length?v:null}getClusterExpansionZoom(o){let r=this._getOriginZoom(o)-1;for(;r<=this.options.maxZoom;){const i=this.getChildren(o);if(r++,i.length!==1)break;o=i[0].properties.cluster_id}return r}_appendLeaves(o,r,i,e,d){const g=this.getChildren(r);for(const s of g){const a=s.properties;if(a&&a.cluster?d+a.point_count<=e?d+=a.point_count:d=this._appendLeaves(o,a.cluster_id,i,e,d):d<e?d++:o.push(s),o.length===i)break}return d}_createTree(o){const r=new Ot(o.length/this.stride|0,this.options.nodeSize,Float32Array);for(let i=0;i<o.length;i+=this.stride)r.add(o[i],o[i+1]);return r.finish(),r.data=o,r}_addTileFeatures(o,r,i,e,d,g){for(const s of o){const a=s*this.stride,w=r[a+ut]>1;let m,v,S;if(w)m=re(r,a,this.clusterProps),v=r[a],S=r[a+1];else{const L=this.points[r[a+pt]];m=L.properties;const[_,k]=L.geometry.coordinates;v=$t(_),S=Mt(k)}const x={type:1,geometry:[[Math.round(this.options.extent*(v*d-i)),Math.round(this.options.extent*(S*d-e))]],tags:m};let b;w||this.options.generateId?b=r[a+pt]:b=this.points[r[a+pt]].id,b!==void 0&&(x.id=b),g.features.push(x)}}_limitZoom(o){return Math.max(this.options.minZoom,Math.min(Math.floor(+o),this.options.maxZoom+1))}_cluster(o,r){const{radius:i,extent:e,reduce:d,minPoints:g}=this.options,s=i/(e*Math.pow(2,r)),a=o.data,w=[],m=this.stride;for(let v=0;v<a.length;v+=m){if(a[v+mt]<=r)continue;a[v+mt]=r;const S=a[v],x=a[v+1],b=o.within(a[v],a[v+1],s),L=a[v+ut];let _=L;for(const k of b){const P=k*m;a[P+mt]>r&&(_+=a[P+ut])}if(_>L&&_>=g){let k=S*L,P=x*L,I,Z=-1;const y=((v/m|0)<<5)+(r+1)+this.points.length;for(const u of b){const j=u*m;if(a[j+mt]<=r)continue;a[j+mt]=r;const K=a[j+ut];k+=a[j]*K,P+=a[j+1]*K,a[j+Nt]=y,d&&(I||(I=this._map(a,v,!0),Z=this.clusterProps.length,this.clusterProps.push(I)),d(I,this._map(a,j)))}a[v+Nt]=y,w.push(k/_,P/_,1/0,y,-1,_),d&&w.push(Z)}else{for(let k=0;k<m;k++)w.push(a[v+k]);if(_>1)for(const k of b){const P=k*m;if(!(a[P+mt]<=r)){a[P+mt]=r;for(let I=0;I<m;I++)w.push(a[P+I])}}}}return w}_getOriginId(o){return o-this.points.length>>5}_getOriginZoom(o){return(o-this.points.length)%32}_map(o,r,i){if(o[r+ut]>1){const g=this.clusterProps[o[r+oe]];return i?Object.assign({},g):g}const e=this.points[o[r+pt]].properties,d=this.options.map(e);return i&&d===e?Object.assign({},d):d}}function Gt(A,o,r){return{type:"Feature",id:A[o+pt],properties:re(A,o,r),geometry:{type:"Point",coordinates:[Io(A[o]),Uo(A[o+1])]}}}function re(A,o,r){const i=A[o+ut],e=i>=1e4?`${Math.round(i/1e3)}k`:i>=1e3?`${Math.round(i/100)/10}k`:i,d=A[o+oe],g=d===-1?{}:Object.assign({},r[d]);return Object.assign(g,{cluster:!0,cluster_id:A[o+pt],point_count:i,point_count_abbreviated:e})}function $t(A){return A/360+.5}function Mt(A){const o=Math.sin(A*Math.PI/180),r=.5-.25*Math.log((1+o)/(1-o))/Math.PI;return r<0?0:r>1?1:r}function Io(A){return(A-.5)*360}function Uo(A){const o=(180-A*360)*Math.PI/180;return 360*Math.atan(Math.exp(o))/Math.PI-90}const Oo={class:"map-container"},Vo={key:0,class:"flex items-center justify-center h-96 glass-card backdrop-blur border border-black/6 dark:border-white/10 rounded-[12px] shadow-sm dark:shadow-none"},Ho={class:"hidden sm:inline"},Zo={key:3,class:"map-legend"},Wo={class:"legend-footer"},Qo={key:4,class:"map-attribution"},qo=bt({__name:"NetworkMap",props:{adverts:{},baseLatitude:{default:null},baseLongitude:{default:null},showLegend:{type:Boolean,default:!0}},emits:["update:showLegend"],setup(A,{expose:o,emit:r}){typeof window<"u"&&!window.chrome&&(window.chrome={runtime:{}});const i=A,e=r,d=()=>{e("update:showLegend",!i.showLegend)},g=F();let s=null;const a=F(new Map);let w=null;const m=F(new Map),v=F([]),S=F(!0),x=F(60),b=F(14),L=F(document.documentElement.classList.contains("dark")),_=new MutationObserver(()=>{const E=document.documentElement.classList.contains("dark");E!==L.value&&(L.value=E,s&&K())}),k=J(()=>i.baseLatitude!==null&&i.baseLongitude!==null&&typeof i.baseLatitude=="number"&&typeof i.baseLongitude=="number"&&i.baseLatitude!==0&&i.baseLongitude!==0&&Math.abs(i.baseLatitude)<=90&&Math.abs(i.baseLongitude)<=180),P=E=>new Date(E*1e3).toLocaleString(),I=E=>E?`${E} dBm`:"N/A",Z=E=>E?`${E} dB`:"N/A",y=E=>({0:"Transport Flood",1:"Flood",2:"Direct",3:"Transport Direct"})[E||0]||"Unknown",u=(E,c,n,l)=>{const R=(n-E)*Math.PI/180,V=(l-c)*Math.PI/180,G=Math.sin(R/2)*Math.sin(R/2)+Math.cos(E*Math.PI/180)*Math.cos(n*Math.PI/180)*Math.sin(V/2)*Math.sin(V/2);return 6371*(2*Math.atan2(Math.sqrt(G),Math.sqrt(1-G)))},j=()=>{s&&(v.value.forEach(E=>{s&&E.remove()}),v.value.length=0,s.remove(),s=null),a.value.clear(),m.value.clear(),w=null},K=async()=>{const E=s?.getZoom()||11,c=s?.getCenter()||(k.value?[i.baseLatitude,i.baseLongitude]:[0,0]);j(),await Pt(),await at(),s&&s.setView(c,E)},et=E=>{const c=new Map;return E.filter(n=>n.latitude!==null&&n.longitude!==null).map(n=>{let l=n.latitude,B=n.longitude;const R=`${l.toFixed(6)}_${B.toFixed(6)}`,V=c.get(R)||0;if(c.set(R,V+1),V>0){const X=V*60*(Math.PI/180);l+=Math.sin(X)*.001*(V*.5),B+=Math.cos(X)*.001*(V*.5)}return{type:"Feature",properties:{advert:{...n,jittered_latitude:l,jittered_longitude:B}},geometry:{type:"Point",coordinates:[B,l]}}})},lt=E=>{w=new jo({radius:x.value,maxZoom:b.value,minPoints:2}),w.load(E)},at=async()=>{if(!g.value||!k.value){console.warn("Cannot initialize map: missing container or coordinates");return}j(),await Pt();const E=i.baseLatitude,c=i.baseLongitude;s=W.map(g.value,{center:[E,c],zoom:11,zoomControl:!0,attributionControl:!1,preferCanvas:!1});try{const n=L.value?"https://{s}.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}{r}.png":"https://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}{r}.png",l=L.value?"https://{s}.basemaps.cartocdn.com/dark_only_labels/{z}/{x}/{y}{r}.png":"https://{s}.basemaps.cartocdn.com/light_only_labels/{z}/{x}/{y}{r}.png",B=W.tileLayer(n,{maxZoom:19,attribution:'&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors &copy; <a href="https://carto.com/attributions">CARTO</a>',errorTileUrl:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=="}),R=W.tileLayer(l,{maxZoom:19,attribution:"",errorTileUrl:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=="});B.addTo(s),R.addTo(s)}catch(n){console.warn("Error loading tiles:",n)}try{const n=(z,H=!1)=>{const h=H?16:12;return W.divIcon({className:"custom-div-icon",html:`<div style="background-color: ${z}; width: ${h}px; height: ${h}px; border-radius: 50%; border: 2px solid white; box-shadow: 0 2px 4px rgba(0,0,0,0.5);"></div>`,iconSize:[h+4,h+4],iconAnchor:[(h+4)/2,(h+4)/2]})},l=z=>{const H=z<10?30:z<100?40:50;return W.divIcon({className:"custom-cluster-icon",html:`
<div style="
width: ${H}px;
height: ${H}px;
background: rgba(170, 232, 232, 0.2);
border: 2px solid #AAE8E8;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
backdrop-filter: blur(10px);
box-shadow: 0 4px 12px rgba(170, 232, 232, 0.3);
color: #ffffff;
font-size: ${H<35?"11px":"13px"};
font-weight: bold;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
">
${z}
</div>
`,iconSize:[H,H],iconAnchor:[H/2,H/2]})},B=n("#ef4444",!0);W.marker([E,c],{icon:B}).addTo(s).bindPopup(`
<div class="p-2">
<strong style="color: #ef4444;">Base Station</strong><br>
<span class="text-sm" style="color: #9CA3AF;">Base Station</span><br>
<span class="text-xs" style="color: #6B7280;">${E.toFixed(6)}, ${c.toFixed(6)}</span>
</div>
`);const R={Unknown:"#9CA3AF","Chat Node":"#60A5FA",Repeater:"#A5E5B6","Room Server":"#EBA0FC","Hybrid Node":"#FFC246"},V=(z,H,h,p,T=0)=>{if(!s)return;const N=z.jittered_latitude||z.latitude,U=z.jittered_longitude||z.longitude;if(N===null||U===null)return;const O=z.route_type||0;let Y=p,ot=3,Q=.7,q;O===2?(Y="#A5E5B6",ot=4,Q=.9):O===1?(Y="#FFC246",q="10, 5",Q=.8):O===3?(Y="#059669",ot=5,Q=.95):O===0?(Y="#ea580c",q="12, 6",Q=.8):(Y="#9CA3AF",q="2, 5",Q=.6);const rt=[H,h],st=[N,U],dt=W.polyline([rt,st],{color:Y,weight:ot,opacity:0,dashArray:q,className:"connection-line"}).addTo(s),xt=W.polyline([rt,rt],{color:Y,weight:ot,opacity:0,dashArray:q,className:"connection-line animated-line"}).addTo(s);setTimeout(()=>{let Tt=0;const Vt=30;xt.setStyle({opacity:Q+.2});const Ht=()=>{Tt++;const Zt=Tt/Vt,ne=rt[0]+(st[0]-rt[0])*Zt,se=rt[1]+(st[1]-rt[1])*Zt;xt.setLatLngs([rt,[ne,se]]),Tt<Vt?setTimeout(Ht,30):setTimeout(()=>{s&&xt&&xt.remove(),dt.setStyle({opacity:Q}),dt.on("mouseover",()=>{dt.setStyle({weight:ot+2,opacity:Math.min(Q+.3,1)})}),dt.on("mouseout",()=>{dt.setStyle({weight:ot,opacity:Q})});const ae=u(H,h,N,U);dt.bindPopup(`
<div class="p-2">
<strong style="color: ${p}">Connection to ${z.node_name||"Unknown Node"}</strong><br>
<span class="text-sm" style="color: #E5E7EB;">Distance: ${ae.toFixed(2)} km</span><br>
<span class="text-sm" style="color: #E5E7EB;">Route: ${y(z.route_type)}</span><br>
<span class="text-sm" style="color: #E5E7EB;">Signal: ${I(z.rssi)} / ${Z(z.snr)}</span>
</div>
`),v.value.push(dt)},200)};Ht()},T)},G=()=>{if(!s||!w)return;const z=s.getBounds(),H=Math.floor(s.getZoom());m.value.forEach(p=>{s&&p.remove()}),m.value.clear(),v.value.forEach(p=>{s&&p.remove()}),v.value.length=0,w.getClusters([z.getWest(),z.getSouth(),z.getEast(),z.getNorth()],H).forEach(p=>{const[T,N]=p.geometry.coordinates,U=p.properties;if(U.cluster){const O=W.marker([N,T],{icon:l(U.point_count||0)}).addTo(s);O.on("click",()=>{if(s&&w){const st=w.getClusterExpansionZoom(U.cluster_id);s.setView([N,T],st)}});const ot=w.getLeaves(U.cluster_id,1/0).map(st=>`<div style="margin: 2px 0; color: ${R[st.properties.advert.contact_type]||R.Unknown};">
${st.properties.advert.node_name||"Unknown Node"} (${st.properties.advert.contact_type})
</div>`).join("");O.bindPopup(`
<div class="p-2">
<strong style="color: #AAE8E8;">Cluster: ${U.point_count} nodes</strong><br>
<div style="max-height: 200px; overflow-y: auto; margin-top: 8px;">
${ot}
</div>
<div style="margin-top: 8px; font-size: 11px; color: #ffffff99;">
Click to zoom in and separate nodes
</div>
</div>
`),m.value.set(`cluster-${U.cluster_id}`,O);const Q=u(E,c,N,T),q=Math.min(Math.floor(Q*5),200),rt={node_name:`Cluster of ${U.point_count} nodes`,contact_type:"Cluster",route_type:2,rssi:null,snr:null,jittered_latitude:N,jittered_longitude:T,latitude:N,longitude:T};V(rt,E,c,"#AAE8E8",q)}else{const O=U.advert,Y=R[O.contact_type]||R.Unknown,ot=n(Y),Q=N,q=T,rt=u(E,c,Q,q),st=W.marker([Q,q],{icon:ot}).addTo(s).bindPopup(`
<div class="p-2">
<strong style="color: ${Y}">${O.node_name||"Unknown Node"}</strong><br>
<span class="text-sm" style="color: #E5E7EB;">Type: ${O.contact_type}</span><br>
<span class="text-sm" style="color: #E5E7EB;">Distance: ${rt.toFixed(2)} km</span><br>
<span class="text-sm" style="color: #E5E7EB;">Signal: ${I(O.rssi)} / ${Z(O.snr)}</span><br>
<span class="text-sm" style="color: #E5E7EB;">Route: ${y(O.route_type)}</span><br>
<span class="text-sm" style="color: #E5E7EB;">Last Seen: ${P(O.last_seen)}</span>
${O.jittered_latitude?'<br><span class="text-xs" style="color: #9CA3AF;">Position adjusted to separate overlapping nodes</span>':""}
</div>
`);a.value.set(O.pubkey,st),m.value.set(`node-${O.pubkey}`,st);const dt=Math.min(Math.floor(rt*5),200),xt={...O,jittered_latitude:Q,jittered_longitude:q};V(xt,E,c,Y,dt)}})},X=(z,H)=>{let h=0;et(i.adverts).forEach(T=>{const N=T.properties.advert;if(N.latitude!==null&&N.longitude!==null){const U=R[N.contact_type]||R.Unknown,O=n(U),Y=N.jittered_latitude||N.latitude,ot=N.jittered_longitude||N.longitude,Q=W.marker([Y,ot],{icon:O}).addTo(s).bindPopup(`
<div class="p-2">
<strong style="color: ${U}">${N.node_name||"Unknown Node"}</strong><br>
<span class="text-sm" style="color: #E5E7EB;">Type: ${N.contact_type}</span><br>
<span class="text-sm" style="color: #E5E7EB;">Distance: ${u(z,H,Y,ot).toFixed(2)} km</span><br>
<span class="text-sm" style="color: #E5E7EB;">Signal: ${I(N.rssi)} / ${Z(N.snr)}</span><br>
<span class="text-sm" style="color: #E5E7EB;">Route: ${y(N.route_type)}</span><br>
<span class="text-sm" style="color: #E5E7EB;">Last Seen: ${P(N.last_seen)}</span>
${N.jittered_latitude?'<br><span class="text-xs" style="color: #9CA3AF;">Position adjusted to separate overlapping nodes</span>':""}
</div>
`);a.value.set(N.pubkey,Q);const q=Q.getElement();q&&(q.style.opacity="0",q.style.transition="opacity 0.5s ease-out"),V(N,z,H,U,h),setTimeout(()=>{q&&(q.style.opacity="1")},h+1e3),h+=100}})};if(S.value&&i.adverts.length>0)try{const z=et(i.adverts);lt(z);const H=Math.min(14,s.getZoom());s.setZoom(H),setTimeout(()=>{try{G()}catch(h){console.warn("Error updating clusters:",h),X(E,c)}},100),s.on("moveend",()=>{try{G()}catch(h){console.warn("Error updating clusters on move:",h)}}),s.on("zoomend",()=>{try{G()}catch(h){console.warn("Error updating clusters on zoom:",h)}})}catch(z){console.warn("Error initializing clustering:",z),X(E,c)}else X(E,c);setTimeout(()=>{s&&s.invalidateSize()},1e3)}catch(n){console.error("Error initializing map:",n)}};return o({highlightNode:E=>{const c=a.value.get(E);if(c){const n=c.getElement();if(n){const l=n.querySelector("div");l&&l.classList.add("marker-highlight")}}},unhighlightNode:E=>{const c=a.value.get(E);if(c){const n=c.getElement();if(n){const l=n.querySelector("div");l&&l.classList.remove("marker-highlight")}}},initializeOpenStreetMap:at}),ht(()=>i.adverts,()=>{s&&k.value&&setTimeout(()=>{at()},100)},{immediate:!1}),Xt(()=>{_.observe(document.documentElement,{attributes:!0,attributeFilter:["class"]}),k.value&&i.adverts.length>0&&setTimeout(()=>{at()},300)}),te(()=>{_.disconnect(),j()}),(E,c)=>(f(),$("div",Oo,[k.value?(f(),$("div",{key:1,ref_key:"mapContainer",ref:g,class:"leaflet-map-container h-96 w-full glass-card backdrop-blur border border-black/6 dark:border-white/10 rounded-[12px] overflow-hidden shadow-sm dark:shadow-none",style:{"min-height":"384px",position:"relative"}},null,512)):(f(),$("div",Vo,c[0]||(c[0]=[ft('<div class="text-center text-content-primary dark:text-content-primary" data-v-a6a23e33><svg class="w-8 h-8 mx-auto mb-2 text-content-muted dark:text-content-muted" fill="currentColor" viewBox="0 0 20 20" data-v-a6a23e33><path d="M5.05 4.05a7 7 0 119.9 9.9L10 18.9l-4.95-4.95a7 7 0 010-9.9zM10 11a2 2 0 100-4 2 2 0 000 4z" data-v-a6a23e33></path></svg><p class="text-sm text-content-primary dark:text-content-primary" data-v-a6a23e33>No valid coordinates available</p><p class="text-xs text-content-secondary dark:text-content-muted" data-v-a6a23e33>Configure base station location to view map</p></div>',1)]))),k.value&&E.adverts.length>0?(f(),$("button",{key:2,onClick:d,class:"absolute bottom-3 right-3 z-[1001] flex items-center gap-2 px-3 py-2 bg-black/40 border border-white/10 rounded-lg text-white/80 hover:bg-white/10 hover:text-white transition-colors text-sm backdrop-blur-sm"},[c[1]||(c[1]=t("svg",{class:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[t("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"})],-1)),t("span",Ho,C(E.showLegend?"Hide":"Show"),1)])):D("",!0),k.value&&E.adverts.length>0&&E.showLegend?(f(),$("div",Zo,[c[2]||(c[2]=ft('<div class="legend-section" data-v-a6a23e33><div class="legend-subtitle" data-v-a6a23e33>Node Types</div><div class="legend-items" data-v-a6a23e33><div class="legend-item" data-v-a6a23e33><div class="legend-icon" style="background-color:#ef4444;" data-v-a6a23e33></div><span data-v-a6a23e33>Base Station</span></div><div class="legend-item" data-v-a6a23e33><div class="legend-icon" style="background-color:#60A5FA;" data-v-a6a23e33></div><span data-v-a6a23e33>Chat Node</span></div><div class="legend-item" data-v-a6a23e33><div class="legend-icon" style="background-color:#A5E5B6;" data-v-a6a23e33></div><span data-v-a6a23e33>Repeater</span></div><div class="legend-item" data-v-a6a23e33><div class="legend-icon" style="background-color:#EBA0FC;" data-v-a6a23e33></div><span data-v-a6a23e33>Room Server</span></div><div class="legend-item" data-v-a6a23e33><div class="legend-icon" style="background-color:#FFC246;" data-v-a6a23e33></div><span data-v-a6a23e33>Hybrid Node</span></div></div></div><div class="legend-section" data-v-a6a23e33><div class="legend-subtitle" data-v-a6a23e33>Route Types</div><div class="legend-items" data-v-a6a23e33><div class="legend-item" data-v-a6a23e33><div class="legend-line" style="background:#A5E5B6;height:3px;" data-v-a6a23e33></div><span data-v-a6a23e33>Direct</span></div><div class="legend-item" data-v-a6a23e33><div class="legend-line" style="background:#059669;height:4px;" data-v-a6a23e33></div><span data-v-a6a23e33>Transport Direct</span></div><div class="legend-item" data-v-a6a23e33><div class="legend-line legend-line-dashed" style="background:#FFC246;" data-v-a6a23e33></div><span data-v-a6a23e33>Flood</span></div><div class="legend-item" data-v-a6a23e33><div class="legend-line legend-line-dashed" style="background:#ea580c;" data-v-a6a23e33></div><span data-v-a6a23e33>Transport Flood</span></div></div></div>',2)),t("div",Wo,C(E.adverts.length)+" node"+C(E.adverts.length!==1?"s":"")+" visible ",1)])):D("",!0),k.value?(f(),$("div",Qo," © OpenStreetMap contributors © CARTO ")):D("",!0)]))}}),Ko=It(qo,[["__scopeId","data-v-a6a23e33"]]),Go={class:"relative","data-menu-container":""},Jt=bt({__name:"NeighborMenu",props:{neighbor:{},canPing:{type:Boolean}},emits:["ping","delete","show-details"],setup(A,{emit:o}){const r=window.__neighborMenuManager||{activeMenu:null,setActiveMenu:_=>{if(r.activeMenu&&r.activeMenu!==_)try{r.activeMenu.closeMenu()}catch(k){console.warn("Error closing previous menu:",k)}r.activeMenu=_}};window.__neighborMenuManager=r;const i=A,e=o,d=F(!1),g=F(),s=F({top:0,left:0}),a=()=>{d.value=!1,document.removeEventListener("click",x,!0),document.removeEventListener("keydown",b),r.activeMenu===w&&(r.activeMenu=null)},w={closeMenu:a},m=()=>{a(),e("ping",i.neighbor)},v=()=>{a(),e("show-details",i.neighbor)},S=()=>{a(),e("delete",i.neighbor)},x=_=>{_.target.closest("[data-menu-container]")||a()},b=_=>{_.key==="Escape"&&a()},L=async()=>{if(!d.value&&g.value){r.setActiveMenu(w);const _=g.value.getBoundingClientRect(),k=window.innerWidth,P=144,I=k<1024,Z=_.left+P>k-16;let y=_.left;I&&Z&&(y=_.right-P),y=Math.max(8,y),s.value={top:_.bottom+4,left:y},d.value=!0,await Pt(),document.addEventListener("click",x,!0),document.addEventListener("keydown",b)}else a()};return te(()=>{a()}),(_,k)=>(f(),$("div",Go,[t("button",{ref_key:"buttonRef",ref:g,onClick:L,class:M(["p-1 rounded hover:bg-stroke-subtle dark:hover:bg-white/10 transition-colors text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-primary/80",{"bg-background-mute dark:bg-stroke/10 text-content-primary dark:text-content-primary/80":d.value}]),"data-menu-container":""},k[0]||(k[0]=[t("svg",{class:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[t("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M12 5v.01M12 12v.01M12 19v.01M12 6a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2z"})],-1)]),2),(f(),Rt(jt,{to:"body"},[d.value?(f(),$("div",{key:0,class:"fixed w-36 bg-white dark:bg-surface-elevated backdrop-blur-lg border border-stroke-subtle dark:border-white/20 rounded-[15px] shadow-2xl z-[999999]",style:At({top:s.value.top+"px",left:s.value.left+"px"}),"data-menu-container":""},[t("div",{class:"py-2"},[t("button",{onClick:v,class:"flex items-center gap-3 w-full px-4 py-3 text-sm text-content-primary dark:text-content-primary hover:bg-primary/10 transition-colors border-b border-stroke-subtle dark:border-white/10"},k[1]||(k[1]=[t("svg",{class:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[t("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"})],-1),t("span",{class:"font-medium"},"Details",-1)])),t("button",{onClick:m,class:"flex items-center gap-3 w-full px-4 py-3 text-sm text-content-primary dark:text-content-primary hover:bg-primary/10 transition-colors border-b border-stroke-subtle dark:border-white/10"},k[2]||(k[2]=[t("svg",{class:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[t("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.393c5.857-5.857 15.355-5.857 21.213 0"})],-1),t("span",{class:"font-medium"},"Ping",-1)])),t("button",{onClick:S,class:"flex items-center gap-3 w-full px-4 py-3 text-sm text-accent-red hover:bg-accent-red/10 transition-colors"},k[3]||(k[3]=[t("svg",{class:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[t("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),t("span",{class:"font-medium"},"Delete",-1)]))])],4)):D("",!0)]))]))}}),Jo={class:"glass-card/30 backdrop-blur border border-stroke-subtle dark:border-white/10 rounded-[12px] p-6 shadow-sm dark:shadow-none"},Yo={class:"flex items-center justify-between mb-4"},Xo={class:"flex items-center gap-3"},tr={class:"text-content-primary dark:text-content-primary text-lg font-semibold"},er={class:"bg-background-mute dark:bg-white/10 text-content-secondary dark:text-content-primary text-xs px-2 py-1 rounded-full"},or={key:0,class:"text-content-muted dark:text-content-muted"},rr={key:0,class:"hidden lg:flex bg-background-mute dark:bg-surface-elevated/30 backdrop-blur rounded-lg border border-stroke-subtle dark:border-stroke/10 p-1"},nr={class:"hidden lg:block overflow-x-auto"},sr={class:"w-full"},ar={class:"bg-background-mute dark:bg-transparent"},ir={class:"flex items-center gap-1"},lr={class:"flex items-center gap-1"},dr={class:"flex items-center gap-1"},cr={class:"flex items-center gap-1"},ur={class:"flex items-center gap-1"},pr={class:"flex items-center gap-1"},gr={class:"flex items-center gap-1"},mr={class:"flex items-center gap-1"},hr={class:"flex items-center gap-1"},br={class:"bg-surface/50 dark:bg-transparent"},xr=["onMouseenter","onMouseleave"],yr=["onClick","title"],vr={key:0,class:"ml-1 text-xs"},kr={key:0,class:"flex items-center gap-3"},fr={class:"text-content-secondary dark:text-content-muted"},wr={class:"flex gap-1"},_r=["onClick"],Cr=["onClick"],$r={key:1,class:"text-content-muted"},Mr={class:"flex items-center gap-2"},Ar={class:"flex items-end gap-0.5"},Lr={class:"flex items-center gap-2"},Tr=["title"],Er=["title"],Sr={class:"lg:hidden space-y-3"},Br=["onClick"],Nr={class:"flex items-center justify-between mb-3"},Fr={class:"flex items-center gap-3"},Dr={class:"text-content-primary dark:text-content-primary font-medium text-base"},Pr={class:"flex items-center gap-2"},zr={class:"grid grid-cols-1 gap-3"},Rr={class:"grid grid-cols-2 gap-4"},jr=["onClick","title"],Ir={key:0,class:"ml-1 text-xs"},Ur={class:"flex items-center gap-2 justify-end"},Or={class:"flex items-end gap-0.5"},Vr={class:"grid grid-cols-2 gap-4"},Hr={class:"flex items-center gap-2"},Zr=["title"],Wr={class:"text-content-primary dark:text-content-primary text-sm block text-right"},Qr={key:0,class:"border-t border-white/10 pt-3"},qr={class:"flex items-center justify-between"},Kr={class:"text-content-secondary dark:text-content-muted text-sm font-mono"},Gr={class:"flex gap-2"},Jr=["onClick"],Yr=["onClick"],Xr={class:"grid grid-cols-3 gap-4 pt-3 border-t border-white/10"},tn={class:"text-center"},en={class:"text-content-primary dark:text-content-primary text-sm font-medium"},on={class:"text-center"},rn={class:"text-content-primary dark:text-content-primary text-sm font-medium"},nn={class:"text-center"},sn=["title"],an=bt({__name:"NeighborTable",props:{contactType:{},contactTypeKey:{},adverts:{},originalCount:{default:0},color:{},baseLatitude:{default:null},baseLongitude:{default:null},isCompactView:{type:Boolean,default:!1},isFirstTable:{type:Boolean,default:!1},showViewToggle:{type:Boolean,default:!1}},emits:["highlight-node","unhighlight-node","menu-ping","menu-delete","show-details","toggle-view"],setup(A,{emit:o}){const r=F(null),{getSignalQuality:i}=Ut(),e=F("advert_count"),d=F("desc"),g=A,s=o,a=c=>new Date(c*1e3).toLocaleString(),w=c=>`${c.slice(0,4)}...${c.slice(-4)}`,m=c=>{switch(c){case 2:return{text:"Direct",bgColor:"bg-green-100 dark:bg-green-500/20",borderColor:"border-green-500 dark:border-green-400/30",textColor:"text-green-600 dark:text-green-400"};case 3:return{text:"Transport Direct",bgColor:"bg-green-100 dark:bg-green-600/20",borderColor:"border-green-600/40 dark:border-green-500/30",textColor:"text-green-700 dark:text-green-500"};case 1:return{text:"Flood",bgColor:"bg-yellow-100 dark:bg-yellow-500/20",borderColor:"border-yellow-500 dark:border-yellow-400/30",textColor:"text-yellow-600 dark:text-yellow-400"};case 0:return{text:"Transport Flood",bgColor:"bg-orange-100 dark:bg-orange-500/20",borderColor:"border-orange-500 dark:border-orange-400/30",textColor:"text-orange-600 dark:text-orange-400"};default:return{text:"Unknown",bgColor:"bg-gray-500/20",borderColor:"border-gray-400/30",textColor:"text-gray-400"}}},v=c=>c?`${c} dBm`:"N/A",S=c=>c?`${c} dB`:"N/A",x=(c,n,l,B)=>{const V=(l-c)*Math.PI/180,G=(B-n)*Math.PI/180,X=Math.sin(V/2)*Math.sin(V/2)+Math.cos(c*Math.PI/180)*Math.cos(l*Math.PI/180)*Math.sin(G/2)*Math.sin(G/2);return 6371*(2*Math.atan2(Math.sqrt(X),Math.sqrt(1-X)))},b=c=>g.baseLatitude===null||g.baseLongitude===null||c.latitude===null||c.longitude===null?"N/A":`${x(g.baseLatitude,g.baseLongitude,c.latitude,c.longitude).toFixed(1)} km`,L=async c=>{try{return await navigator.clipboard.writeText(c),!0}catch{const n=document.createElement("textarea");return n.value=c,document.body.appendChild(n),n.select(),document.execCommand("copy"),document.body.removeChild(n),!0}},_=c=>{const n=Date.now(),l=c*1e3,B=n-l,R=Math.floor(B/1e3),V=Math.floor(R/60),G=Math.floor(V/60),X=Math.floor(G/24);return R<60?`${R}s ago`:V<60?`${V}m ago`:G<24?`${G}h ago`:`${X}d ago`},k=c=>{const n=Date.now(),l=c*1e3,B=n-l,R=Math.floor(B/(1e3*60*60));return R<1?{color:"text-green-600 dark:text-green-400"}:R<26?{color:"text-yellow-600 dark:text-yellow-400"}:{color:"text-red-600 dark:text-red-400"}},P=async(c,n)=>{const l=`${c.toFixed(6)}, ${n.toFixed(6)}`;await L(l)},I=(c,n)=>{const l=`https://www.google.com/maps?q=${c},${n}`;window.open(l,"_blank")},Z=async c=>{await L(c),r.value=c,setTimeout(()=>{r.value=null},2e3)},y=c=>{const n=i(c);return{bars:n.bars,color:n.color}},u=()=>g.isCompactView?"py-2 px-2":"py-4 px-3",j=()=>{s("toggle-view")},K=c=>{s("highlight-node",c)},et=c=>{s("unhighlight-node",c)},lt=c=>{s("menu-ping",c)},at=c=>{s("show-details",c)},yt=c=>{s("menu-delete",c)},nt=c=>{e.value===c?d.value=d.value==="asc"?"desc":"asc":(e.value=c,d.value=typeof g.adverts[0]?.[c]=="number"?"desc":"asc")},E=J(()=>e.value?[...g.adverts].sort((c,n)=>{const l=c[e.value],B=n[e.value];if(l==null)return 1;if(B==null)return-1;let R=0;return typeof l=="string"&&typeof B=="string"?R=l.localeCompare(B):typeof l=="number"&&typeof B=="number"?R=l-B:typeof l=="boolean"&&typeof B=="boolean"&&(R=l===B?0:l?1:-1),d.value==="asc"?R:-R}):g.adverts);return(c,n)=>(f(),$("div",Jo,[t("div",Yo,[t("div",Xo,[t("div",{class:"w-3 h-3 rounded-full border border-white/20",style:At({backgroundColor:c.color})},null,4),t("h3",tr,C(c.contactType),1),t("span",er,[tt(C(c.adverts.length)+" ",1),c.originalCount>0&&c.adverts.length<c.originalCount?(f(),$("span",or," / "+C(c.originalCount),1)):D("",!0)])]),c.isFirstTable&&c.showViewToggle?(f(),$("div",rr,[t("button",{onClick:j,class:M(["p-2 rounded-md transition-colors",c.isCompactView?"text-content-secondary dark:text-content-muted hover:text-primary hover:bg-primary/10":"bg-primary/20 text-primary border border-primary/30"]),title:"Comfortable view"},n[9]||(n[9]=[t("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"},[t("rect",{x:"3",y:"3",width:"18",height:"6",rx:"2",stroke:"currentColor","stroke-width":"2"}),t("rect",{x:"3",y:"12",width:"18",height:"6",rx:"2",stroke:"currentColor","stroke-width":"2"})],-1)]),2),t("button",{onClick:j,class:M(["p-2 rounded-md transition-colors",c.isCompactView?"bg-primary/20 text-primary border border-primary/30":"text-content-secondary dark:text-content-muted hover:text-primary hover:bg-primary/10"]),title:"Compact view"},n[10]||(n[10]=[t("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"},[t("rect",{x:"3",y:"3",width:"18",height:"4",rx:"2",stroke:"currentColor","stroke-width":"2"}),t("rect",{x:"3",y:"10",width:"18",height:"4",rx:"2",stroke:"currentColor","stroke-width":"2"}),t("rect",{x:"3",y:"17",width:"18",height:"4",rx:"2",stroke:"currentColor","stroke-width":"2"})],-1)]),2)])):D("",!0)]),t("div",nr,[t("table",sr,[t("thead",null,[t("tr",ar,[t("th",{class:M(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${u().split(" ")[1]} border-b border-stroke-subtle dark:border-white/5`)},null,2),t("th",{onClick:n[0]||(n[0]=l=>nt("node_name")),class:M(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${u().split(" ")[1]} border-b border-stroke-subtle dark:border-white/5 cursor-pointer hover:text-primary transition-colors select-none`)},[t("div",ir,[n[12]||(n[12]=tt(" Node Name ",-1)),e.value==="node_name"?(f(),$("svg",{key:0,class:M(["w-3 h-3",d.value==="asc"?"":"rotate-180"]),fill:"currentColor",viewBox:"0 0 20 20"},n[11]||(n[11]=[t("path",{"fill-rule":"evenodd",d:"M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z","clip-rule":"evenodd"},null,-1)]),2)):D("",!0)])],2),t("th",{onClick:n[1]||(n[1]=l=>nt("pubkey")),class:M(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${u().split(" ")[1]} border-b border-stroke-subtle dark:border-white/5 cursor-pointer hover:text-primary transition-colors select-none`)},[t("div",lr,[n[14]||(n[14]=tt(" Public Key ",-1)),e.value==="pubkey"?(f(),$("svg",{key:0,class:M(["w-3 h-3",d.value==="asc"?"":"rotate-180"]),fill:"currentColor",viewBox:"0 0 20 20"},n[13]||(n[13]=[t("path",{"fill-rule":"evenodd",d:"M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z","clip-rule":"evenodd"},null,-1)]),2)):D("",!0)])],2),t("th",{class:M(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${u().split(" ")[1]} border-b border-stroke-subtle dark:border-white/5`)},"Location",2),t("th",{class:M(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${u().split(" ")[1]} border-b border-stroke-subtle dark:border-white/5`)},"Distance",2),t("th",{onClick:n[2]||(n[2]=l=>nt("route_type")),class:M(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${u().split(" ")[1]} border-b border-stroke-subtle dark:border-white/5 cursor-pointer hover:text-primary transition-colors select-none`)},[t("div",dr,[n[16]||(n[16]=tt(" Route Type ",-1)),e.value==="route_type"?(f(),$("svg",{key:0,class:M(["w-3 h-3",d.value==="asc"?"":"rotate-180"]),fill:"currentColor",viewBox:"0 0 20 20"},n[15]||(n[15]=[t("path",{"fill-rule":"evenodd",d:"M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z","clip-rule":"evenodd"},null,-1)]),2)):D("",!0)])],2),t("th",{onClick:n[3]||(n[3]=l=>nt("zero_hop")),class:M(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${u().split(" ")[1]} border-b border-stroke-subtle dark:border-white/5 cursor-pointer hover:text-primary transition-colors select-none`)},[t("div",cr,[n[18]||(n[18]=tt(" Zero Hop ",-1)),e.value==="zero_hop"?(f(),$("svg",{key:0,class:M(["w-3 h-3",d.value==="asc"?"":"rotate-180"]),fill:"currentColor",viewBox:"0 0 20 20"},n[17]||(n[17]=[t("path",{"fill-rule":"evenodd",d:"M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z","clip-rule":"evenodd"},null,-1)]),2)):D("",!0)])],2),t("th",{onClick:n[4]||(n[4]=l=>nt("rssi")),class:M(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${u().split(" ")[1]} border-b border-stroke-subtle dark:border-white/5 cursor-pointer hover:text-primary transition-colors select-none`)},[t("div",ur,[n[20]||(n[20]=tt(" RSSI ",-1)),e.value==="rssi"?(f(),$("svg",{key:0,class:M(["w-3 h-3",d.value==="asc"?"":"rotate-180"]),fill:"currentColor",viewBox:"0 0 20 20"},n[19]||(n[19]=[t("path",{"fill-rule":"evenodd",d:"M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z","clip-rule":"evenodd"},null,-1)]),2)):D("",!0)])],2),t("th",{onClick:n[5]||(n[5]=l=>nt("snr")),class:M(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${u().split(" ")[1]} border-b border-stroke-subtle dark:border-white/5 cursor-pointer hover:text-primary transition-colors select-none`)},[t("div",pr,[n[22]||(n[22]=tt(" SNR ",-1)),e.value==="snr"?(f(),$("svg",{key:0,class:M(["w-3 h-3",d.value==="asc"?"":"rotate-180"]),fill:"currentColor",viewBox:"0 0 20 20"},n[21]||(n[21]=[t("path",{"fill-rule":"evenodd",d:"M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z","clip-rule":"evenodd"},null,-1)]),2)):D("",!0)])],2),t("th",{onClick:n[6]||(n[6]=l=>nt("last_seen")),class:M(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${u().split(" ")[1]} border-b border-stroke-subtle dark:border-white/5 cursor-pointer hover:text-primary transition-colors select-none`)},[t("div",gr,[n[24]||(n[24]=tt(" Last Seen ",-1)),e.value==="last_seen"?(f(),$("svg",{key:0,class:M(["w-3 h-3",d.value==="asc"?"":"rotate-180"]),fill:"currentColor",viewBox:"0 0 20 20"},n[23]||(n[23]=[t("path",{"fill-rule":"evenodd",d:"M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z","clip-rule":"evenodd"},null,-1)]),2)):D("",!0)])],2),t("th",{onClick:n[7]||(n[7]=l=>nt("first_seen")),class:M(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${u().split(" ")[1]} border-b border-stroke-subtle dark:border-white/5 cursor-pointer hover:text-primary transition-colors select-none`)},[t("div",mr,[n[26]||(n[26]=tt(" First Seen ",-1)),e.value==="first_seen"?(f(),$("svg",{key:0,class:M(["w-3 h-3",d.value==="asc"?"":"rotate-180"]),fill:"currentColor",viewBox:"0 0 20 20"},n[25]||(n[25]=[t("path",{"fill-rule":"evenodd",d:"M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z","clip-rule":"evenodd"},null,-1)]),2)):D("",!0)])],2),t("th",{onClick:n[8]||(n[8]=l=>nt("advert_count")),class:M(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${u().split(" ")[1]} border-b border-stroke-subtle dark:border-white/5 cursor-pointer hover:text-primary transition-colors select-none`)},[t("div",hr,[n[28]||(n[28]=tt(" Advert Count ",-1)),e.value==="advert_count"?(f(),$("svg",{key:0,class:M(["w-3 h-3",d.value==="asc"?"":"rotate-180"]),fill:"currentColor",viewBox:"0 0 20 20"},n[27]||(n[27]=[t("path",{"fill-rule":"evenodd",d:"M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z","clip-rule":"evenodd"},null,-1)]),2)):D("",!0)])],2)])]),t("tbody",br,[(f(!0),$(ct,null,gt(E.value,l=>(f(),$("tr",{key:l.id,class:"hover:bg-background-mute/50 dark:hover:bg-white/5 transition-colors",onMouseenter:B=>K(l.pubkey),onMouseleave:B=>et(l.pubkey)},[t("td",{class:M(u())},[it(Jt,{neighbor:l,onPing:lt,onShowDetails:at,onDelete:yt},null,8,["neighbor"])],2),t("td",{class:M(`${u()} text-content-primary dark:text-content-primary text-sm`)},C(l.node_name||"Unknown"),3),t("td",{class:M(`${u()} text-content-primary dark:text-content-primary text-sm font-mono`)},[t("button",{onClick:B=>Z(l.pubkey),class:M(["text-content-primary dark:text-content-primary hover:text-primary-light transition-colors cursor-pointer underline underline-offset-2 decoration-gray-400 dark:decoration-white/30 hover:decoration-primary-light/60",r.value===l.pubkey?"text-green-600 dark:text-green-400 decoration-green-400/60":""]),title:r.value===l.pubkey?"Copied!":"Click to copy full public key"},[tt(C(w(l.pubkey))+" ",1),r.value===l.pubkey?(f(),$("span",vr,"✓")):D("",!0)],10,yr)],2),t("td",{class:M(`${u()} text-content-primary dark:text-content-primary text-sm`)},[l.latitude!==null&&l.longitude!==null?(f(),$("div",kr,[t("span",fr,C(l.latitude.toFixed(4))+", "+C(l.longitude.toFixed(4)),1),t("div",wr,[t("button",{onClick:B=>P(l.latitude,l.longitude),class:"text-content-muted dark:text-content-muted hover:text-content-primary dark:hover:text-content-primary transition-colors cursor-pointer",title:"Copy coordinates to clipboard"},n[29]||(n[29]=[t("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"},[t("rect",{x:"9",y:"9",width:"13",height:"13",rx:"2",ry:"2",stroke:"currentColor","stroke-width":"2"}),t("path",{d:"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1",stroke:"currentColor","stroke-width":"2"})],-1)]),8,_r),t("button",{onClick:B=>I(l.latitude,l.longitude),class:"text-white/60 hover:text-blue-600 dark:text-blue-400 transition-colors cursor-pointer",title:"Open in Google Maps"},n[30]||(n[30]=[t("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"},[t("path",{d:"M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z",stroke:"currentColor","stroke-width":"2"}),t("circle",{cx:"12",cy:"10",r:"3",stroke:"currentColor","stroke-width":"2"})],-1)]),8,Cr)])])):(f(),$("span",$r,"Unknown"))],2),t("td",{class:M(`${u()} text-content-primary dark:text-content-primary text-sm`)},C(b(l)),3),t("td",{class:M(`${u()} text-content-primary dark:text-content-primary text-sm`)},[t("span",{class:M(["inline-block px-2 py-1 rounded-full text-xs border transition-colors",m(l.route_type).bgColor,m(l.route_type).borderColor,m(l.route_type).textColor])},C(m(l.route_type).text),3)],2),t("td",{class:M(`${u()} text-content-primary dark:text-content-primary text-sm`)},[t("span",{class:M(["inline-block px-2 py-1 rounded-full text-xs border transition-colors",l.zero_hop?"bg-green-100 dark:bg-green-500/20 border-green-500 dark:border-green-400/30 text-green-600 dark:text-green-400":"bg-orange-100 dark:bg-orange-500/20 border-orange-500 dark:border-orange-400/30 text-orange-600 dark:text-orange-400"])},C(l.zero_hop?"Zero Hop":"Multi-Hop"),3)],2),t("td",{class:M(`${u()} text-content-primary dark:text-content-primary text-sm`)},[t("div",Mr,[t("div",Ar,[(f(),$(ct,null,gt(5,B=>t("div",{key:B,class:M(["w-1 transition-colors",B<=y(l.rssi).bars?y(l.rssi).color:"text-gray-600"]),style:At({height:`${4+B*2}px`})},n[31]||(n[31]=[t("div",{class:"w-full h-full bg-current rounded-sm"},null,-1)]),6)),64))]),t("span",{class:M(y(l.rssi).color)},C(v(l.rssi)),3)])],2),t("td",{class:M(`${u()} text-content-primary dark:text-content-primary text-sm`)},C(S(l.snr)),3),t("td",{class:M(`${u()} text-content-primary dark:text-content-primary text-sm`)},[t("div",Lr,[t("div",{class:M(["w-2 h-2 rounded-full",k(l.last_seen).color==="text-green-600 dark:text-green-400"?"bg-green-400":"",k(l.last_seen).color==="text-yellow-600 dark:text-yellow-400"?"bg-yellow-400":"",k(l.last_seen).color==="text-red-600 dark:text-red-400"?"bg-red-400":""])},null,2),t("span",{class:M([k(l.last_seen).color,"cursor-help"]),title:a(l.last_seen)},C(_(l.last_seen)),11,Tr)])],2),t("td",{class:M(`${u()} text-content-primary dark:text-content-primary text-sm`)},[t("span",{title:a(l.first_seen),class:"cursor-help"},C(_(l.first_seen)),9,Er)],2),t("td",{class:M(`${u()} text-content-primary dark:text-content-primary text-sm text-center`)},C(l.advert_count),3)],40,xr))),128))])])]),t("div",Sr,[(f(!0),$(ct,null,gt(E.value,l=>(f(),$("div",{key:l.id,class:"bg-surface/50 dark:bg-transparent border border-stroke-subtle dark:border-white/10 rounded-lg p-4 hover:bg-background-mute/50 dark:hover:bg-white/5 transition-colors",onClick:B=>K(l.pubkey)},[t("div",Nr,[t("div",Fr,[t("h4",Dr,C(l.node_name||"Unknown Node"),1),t("div",Pr,[t("span",{class:M(["inline-block px-2 py-1 rounded-full text-xs border",m(l.route_type).bgColor,m(l.route_type).borderColor,m(l.route_type).textColor])},C(m(l.route_type).text),3),t("span",{class:M(["inline-block px-2 py-1 rounded-full text-xs border",l.zero_hop?"bg-green-100 dark:bg-green-500/20 border-green-500 dark:border-green-400/30 text-green-600 dark:text-green-400":"bg-orange-100 dark:bg-orange-500/20 border-orange-500 dark:border-orange-400/30 text-orange-600 dark:text-orange-400"])},C(l.zero_hop?"Zero Hop":"Multi-Hop"),3)])]),it(Jt,{neighbor:l,onPing:lt,onShowDetails:at,onDelete:yt},null,8,["neighbor"])]),t("div",zr,[t("div",Rr,[t("div",null,[n[32]||(n[32]=t("div",{class:"text-content-muted text-xs mb-1"},"Public Key",-1)),t("button",{onClick:B=>Z(l.pubkey),class:M(["text-content-primary dark:text-content-primary hover:text-primary-light transition-colors cursor-pointer font-mono text-sm underline underline-offset-2 decoration-gray-400 dark:decoration-white/30 hover:decoration-primary-light/60 break-all",r.value===l.pubkey?"text-green-600 dark:text-green-400 decoration-green-400/60":""]),title:r.value===l.pubkey?"Copied!":"Click to copy full public key"},[tt(C(w(l.pubkey))+" ",1),r.value===l.pubkey?(f(),$("span",Ir,"✓")):D("",!0)],10,jr)]),t("div",null,[n[34]||(n[34]=t("div",{class:"text-content-muted text-xs mb-1"},"Signal",-1)),t("div",Ur,[t("div",Or,[(f(),$(ct,null,gt(5,B=>t("div",{key:B,class:M(["w-1.5 transition-colors",B<=y(l.rssi).bars?y(l.rssi).color:"text-gray-600"]),style:At({height:`${6+B*2}px`})},n[33]||(n[33]=[t("div",{class:"w-full h-full bg-current rounded-sm"},null,-1)]),6)),64))]),t("span",{class:M(`${y(l.rssi).color} text-sm font-medium`)},C(v(l.rssi)),3)])])]),t("div",Vr,[t("div",null,[n[35]||(n[35]=t("div",{class:"text-content-muted text-xs mb-1"},"Last Seen",-1)),t("div",Hr,[t("div",{class:M(["w-2 h-2 rounded-full",k(l.last_seen).color==="text-green-600 dark:text-green-400"?"bg-green-400":"",k(l.last_seen).color==="text-yellow-600 dark:text-yellow-400"?"bg-yellow-400":"",k(l.last_seen).color==="text-red-600 dark:text-red-400"?"bg-red-400":""])},null,2),t("span",{class:M(`${k(l.last_seen).color} text-sm`),title:a(l.last_seen)},C(_(l.last_seen)),11,Zr)])]),t("div",null,[n[36]||(n[36]=t("div",{class:"text-content-muted text-xs mb-1"},"Distance",-1)),t("span",Wr,C(b(l)),1)])]),l.latitude!==null&&l.longitude!==null?(f(),$("div",Qr,[n[39]||(n[39]=t("div",{class:"text-content-muted text-xs mb-1"},"Location",-1)),t("div",qr,[t("span",Kr,C(l.latitude.toFixed(4))+", "+C(l.longitude.toFixed(4)),1),t("div",Gr,[t("button",{onClick:B=>P(l.latitude,l.longitude),class:"text-content-muted dark:text-content-muted hover:text-content-primary dark:hover:text-content-primary transition-colors p-2 hover:bg-stroke-subtle dark:hover:bg-white/10 rounded-lg",title:"Copy coordinates"},n[37]||(n[37]=[t("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"},[t("rect",{x:"9",y:"9",width:"13",height:"13",rx:"2",ry:"2",stroke:"currentColor","stroke-width":"2"}),t("path",{d:"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1",stroke:"currentColor","stroke-width":"2"})],-1)]),8,Jr),t("button",{onClick:B=>I(l.latitude,l.longitude),class:"text-white/60 hover:text-blue-600 dark:text-blue-400 transition-colors p-2 hover:bg-white/10 rounded-lg",title:"Open in Maps"},n[38]||(n[38]=[t("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"},[t("path",{d:"M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z",stroke:"currentColor","stroke-width":"2"}),t("circle",{cx:"12",cy:"10",r:"3",stroke:"currentColor","stroke-width":"2"})],-1)]),8,Yr)])])])):D("",!0),t("div",Xr,[t("div",tn,[n[40]||(n[40]=t("div",{class:"text-content-muted text-xs mb-1"},"SNR",-1)),t("span",en,C(S(l.snr)),1)]),t("div",on,[n[41]||(n[41]=t("div",{class:"text-content-muted text-xs mb-1"},"Adverts",-1)),t("span",rn,C(l.advert_count),1)]),t("div",nn,[n[42]||(n[42]=t("div",{class:"text-content-muted text-xs mb-1"},"First Seen",-1)),t("span",{class:"text-content-primary dark:text-content-primary text-sm",title:a(l.first_seen)},C(_(l.first_seen)),9,sn)])])])],8,Br))),128))])]))}}),ln={class:"space-y-6"},dn={key:0,class:"flex items-center justify-center py-12"},cn={key:1,class:"bg-red-50 dark:bg-accent-red/10 border border-red-300 dark:border-accent-red/20 rounded-[15px] p-6"},un={class:"flex items-center gap-3"},pn={class:"text-red-500 dark:text-accent-red/80 text-sm"},gn={key:0,class:""},mn={class:"flex items-center justify-between"},hn={class:"flex items-center gap-3"},bn={class:"hidden lg:flex bg-background-mute dark:bg-surface-elevated/30 backdrop-blur rounded-lg border border-stroke-subtle dark:border-stroke/10 mb p-1"},xn={class:"flex items-center gap-2"},yn={key:0,class:"ml-1 bg-accent-cyan/20 text-accent-cyan border border-accent-cyan/30 text-xs px-1.5 py-0.5 rounded-full font-medium"},vn={class:"bg-background dark:bg-background/30 border border-stroke-subtle dark:border-stroke/10 rounded-lg p-4 mt-4 space-y-4"},kn={class:"grid grid-cols-1 md:grid-cols-3 gap-4"},fn={key:1,class:"text-center py-12"},wn={key:2,class:"text-center py-12"},Tn=bt({name:"NeighborsView",__name:"Neighbors",setup(A){const o=Yt(),r={0:"Unknown",1:"Chat Node",2:"Repeater",3:"Room Server",4:"Hybrid Node"},i={0:"#6b7280",1:"#60a5fa",2:"#34d399",3:"#a855f7",4:"#f59e0b"},e=F({}),d=F(!0),g=F(null),s=F(_t("neighbors_compactView",!1)),a=F(_t("neighbors_showMapLegend",typeof window<"u"?window.innerWidth>=1024:!0)),w=F(_t("neighbors_showFilters",!1)),m=F(_t("neighbors_filters",{zeroHop:"all",routeType:"all",searchText:""}));ht(s,h=>Ct("neighbors_compactView",h)),ht(a,h=>Ct("neighbors_showMapLegend",h)),ht(w,h=>Ct("neighbors_showFilters",h)),ht(m,h=>Ct("neighbors_filters",h),{deep:!0});const v=F(!1),S=F(!1),x=F(!1),b=F(null),L=F(null),_=F(null),k=F(null),P=F(!1),I=F(null),Z=J(()=>{if(!k.value)return null;const h=k.value;return{id:h.id,pubkey:h.pubkey,node_name:h.node_name,contact_type:h.contact_type,latitude:h.latitude,longitude:h.longitude,rssi:h.rssi,snr:h.snr,route_type:h.route_type,last_seen:h.last_seen,first_seen:h.first_seen,advert_count:h.advert_count,timestamp:h.timestamp,is_repeater:h.is_repeater,is_new_neighbor:h.is_new_neighbor,zero_hop:h.zero_hop}}),y=J(()=>o.stats?.config?.repeater?.latitude),u=J(()=>o.stats?.config?.repeater?.longitude),j=h=>h.filter(p=>{if(m.value.zeroHop!=="all"){const T=p.zero_hop;if(m.value.zeroHop==="true"&&!T||m.value.zeroHop==="false"&&T)return!1}if(m.value.routeType!=="all"){const T=p.route_type;if(m.value.routeType==="direct"&&T!==2||m.value.routeType==="transport_direct"&&T!==3||m.value.routeType==="flood"&&T!==1||m.value.routeType==="transport_flood"&&T!==0)return!1}if(m.value.searchText){const T=m.value.searchText.toLowerCase(),N=p.node_name?.toLowerCase()||"",U=p.pubkey.toLowerCase();if(!N.includes(T)&&!U.includes(T))return!1}return!0}),K=()=>{m.value={zeroHop:"all",routeType:"all",searchText:""}},et=J(()=>m.value.zeroHop!=="all"||m.value.routeType!=="all"||m.value.searchText!==""),lt=J(()=>{const h={};for(const[p,T]of Object.entries(e.value))h[p]=j(T);return h}),at=J(()=>Object.entries(r).filter(([h])=>lt.value[h]?.length>0).sort(([h],[p])=>parseInt(h)-parseInt(p))),yt=J(()=>Object.values(e.value).flat().filter(h=>{const p=h.latitude,T=h.longitude;return p!=null&&p!==0&&T!==null&&T!==void 0&&T!==0&&typeof p=="number"&&typeof T=="number"&&!isNaN(p)&&!isNaN(T)&&h.zero_hop===!0})),nt=async h=>{try{const p=await Et.get(`/adverts_by_contact_type?contact_type=${encodeURIComponent(h)}&hours=168`);return p.success&&Array.isArray(p.data)?p.data:[]}catch(p){return console.error(`Error fetching adverts for contact type ${h}:`,p),[]}},E=async()=>{d.value=!0,g.value=null;try{e.value={};for(const[h,p]of Object.entries(r)){const T=await nt(p);T.length>0&&(e.value[h]=T)}}catch(h){console.error("Error loading adverts:",h),g.value=h instanceof Error?h.message:"Failed to load neighbor data"}finally{d.value=!1}},c=F(),n=h=>{c.value?.highlightNode(h)},l=h=>{c.value?.unhighlightNode(h)},B=async h=>{const p=h;b.value=null,L.value=null,x.value=!0,_.value=p.node_name||"Unknown Node",S.value=!0;try{const N=`0x${parseInt(p.pubkey.substring(0,2),16).toString(16).padStart(2,"0")}`;console.log(`Pinging neighbor ${p.node_name||"Unknown"} (${N})...`);const U=await Et.pingNeighbor(N,10);U.success&&U.data?(b.value=U.data,console.log("Ping successful:",U.data)):(L.value=U.error||"Unknown error occurred",console.error("Failed to ping neighbor:",U.error))}catch(T){console.error("Error pinging neighbor:",T),L.value=T instanceof Error?T.message:"Unknown error occurred"}finally{x.value=!1}},R=()=>{S.value=!1,b.value=null,L.value=null,_.value=null},V=h=>{k.value=h,v.value=!0},G=h=>{I.value=h,P.value=!0},X=()=>{P.value=!1,I.value=null},z=()=>{v.value=!1,k.value=null},H=async h=>{try{await Et.deleteAdvert(h),await E(),z()}catch(p){console.error("Error deleting neighbor:",p)}};return Xt(async()=>{await E()}),(h,p)=>(f(),$("div",ln,[d.value?(f(),$("div",dn,p[7]||(p[7]=[t("div",{class:"text-center"},[t("div",{class:"animate-spin rounded-full h-12 w-12 border-b-2 border-primary mx-auto mb-4"}),t("p",{class:"text-content-secondary dark:text-content-muted"},"Loading neighbor data...")],-1)]))):g.value?(f(),$("div",cn,[t("div",un,[p[9]||(p[9]=t("svg",{class:"w-5 h-5 text-red-600 dark:text-accent-red",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[t("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)),t("div",null,[p[8]||(p[8]=t("h3",{class:"text-red-600 dark:text-accent-red font-medium"},"Error Loading Neighbors",-1)),t("p",pn,C(g.value),1)])])])):(f(),$(ct,{key:2},[it(Ko,{ref_key:"networkMapRef",ref:c,adverts:yt.value,"base-latitude":y.value,"base-longitude":u.value,"show-legend":a.value,"onUpdate:showLegend":p[0]||(p[0]=T=>a.value=T)},null,8,["adverts","base-latitude","base-longitude","show-legend"]),Object.keys(e.value).length>0?(f(),$("div",gn,[t("div",mn,[p[14]||(p[14]=t("span",{class:"text-content-primary dark:text-content-primary text-lg font-semibold"},null,-1)),t("div",hn,[t("div",bn,[t("button",{onClick:p[1]||(p[1]=T=>s.value=!1),class:M(["p-2 rounded-md transition-colors",s.value?"text-content-secondary dark:text-content-muted hover:text-primary hover:bg-primary/10":"bg-primary/20 text-primary border border-primary/30"]),title:"Comfortable view"},p[10]||(p[10]=[t("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"},[t("rect",{x:"3",y:"3",width:"18",height:"6",rx:"2",stroke:"currentColor","stroke-width":"2"}),t("rect",{x:"3",y:"12",width:"18",height:"6",rx:"2",stroke:"currentColor","stroke-width":"2"})],-1)]),2),t("button",{onClick:p[2]||(p[2]=T=>s.value=!0),class:M(["p-2 rounded-md transition-colors",s.value?"bg-primary/20 text-primary border border-primary/30":"text-content-secondary dark:text-content-muted hover:text-primary hover:bg-primary/10"]),title:"Compact view"},p[11]||(p[11]=[t("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"},[t("rect",{x:"3",y:"3",width:"18",height:"4",rx:"2",stroke:"currentColor","stroke-width":"2"}),t("rect",{x:"3",y:"10",width:"18",height:"4",rx:"2",stroke:"currentColor","stroke-width":"2"}),t("rect",{x:"3",y:"17",width:"18",height:"4",rx:"2",stroke:"currentColor","stroke-width":"2"})],-1)]),2)]),t("div",xn,[t("button",{onClick:p[3]||(p[3]=T=>w.value=!w.value),class:M(["px-3 py-1.5 text-xs rounded-lg transition-colors border",et.value?"bg-primary/20 text-primary border-primary/30":"bg-background-mute dark:bg-white/10 text-content-secondary dark:text-content-primary border-stroke-subtle dark:border-stroke/20 hover:bg-stroke-subtle dark:hover:bg-white/20"])},[p[12]||(p[12]=t("svg",{class:"w-4 h-4 inline mr-1",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[t("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707v6.586a1 1 0 01-1.447.894l-4-2A1 1 0 717 18.586V13.414a1 1 0 00-.293-.707L.293 6.293A1 1 0 010 5.586V3a1 1 0 011-1z"})],-1)),p[13]||(p[13]=tt(" Filters ",-1)),et.value?(f(),$("span",yn," Active ")):D("",!0)],2),et.value?(f(),$("button",{key:0,onClick:K,class:"px-3 py-1.5 text-xs rounded-lg bg-background-mute dark:bg-white/10 text-content-secondary dark:text-content-primary border border-stroke-subtle dark:border-stroke/20 hover:bg-stroke-subtle dark:hover:bg-white/20 transition-colors"}," Clear Filters ")):D("",!0)])])]),wt(t("div",vn,[t("div",kn,[t("div",null,[p[16]||(p[16]=t("label",{class:"block text-xs font-medium text-content-secondary dark:text-content-muted mb-1"},"Zero Hop",-1)),wt(t("select",{"onUpdate:modelValue":p[4]||(p[4]=T=>m.value.zeroHop=T),class:"w-full bg-surface dark:bg-surface/50 border border-stroke-subtle dark:border-stroke/20 rounded-lg px-3 py-2 text-content-primary dark:text-content-primary text-sm focus:border-primary/50 focus:outline-none"},p[15]||(p[15]=[t("option",{value:"all"},"All Nodes",-1),t("option",{value:"true"},"Zero Hop Only",-1),t("option",{value:"false"},"Multi-Hop Only",-1)]),512),[[Wt,m.value.zeroHop]])]),t("div",null,[p[18]||(p[18]=t("label",{class:"block text-xs font-medium text-content-secondary dark:text-content-muted mb-1"},"Route Type",-1)),wt(t("select",{"onUpdate:modelValue":p[5]||(p[5]=T=>m.value.routeType=T),class:"w-full bg-surface dark:bg-surface/50 border border-stroke-subtle dark:border-stroke/20 rounded-lg px-3 py-2 text-content-primary dark:text-content-primary text-sm focus:border-primary/50 focus:outline-none"},p[17]||(p[17]=[ft('<option value="all">All Types</option><option value="direct">Direct</option><option value="transport_direct">Transport Direct</option><option value="flood">Flood</option><option value="transport_flood">Transport Flood</option>',5)]),512),[[Wt,m.value.routeType]])]),t("div",null,[p[19]||(p[19]=t("label",{class:"block text-xs font-medium text-content-secondary dark:text-content-muted mb-1"},"Search",-1)),wt(t("input",{"onUpdate:modelValue":p[6]||(p[6]=T=>m.value.searchText=T),type:"text",placeholder:"Node name or pubkey...",class:"w-full bg-surface dark:bg-surface/50 border border-stroke-subtle dark:border-stroke/20 rounded-lg px-3 py-2 text-content-primary dark:text-content-primary text-sm focus:border-primary/50 focus:outline-none placeholder-gray-400 dark:placeholder-white/40"},null,512),[[le,m.value.searchText]])])])],512),[[ie,w.value]])])):D("",!0),(f(!0),$(ct,null,gt(at.value,([T,N])=>(f(),$("div",{key:T,class:"space-y-6"},[it(an,{"contact-type":N,"contact-type-key":T,adverts:lt.value[T],"original-count":e.value[T]?.length||0,color:i[parseInt(T)],"base-latitude":y.value,"base-longitude":u.value,"is-compact-view":s.value,"is-first-table":!1,"show-view-toggle":!1,onHighlightNode:n,onUnhighlightNode:l,onMenuPing:B,onMenuDelete:V,onShowDetails:G},null,8,["contact-type","contact-type-key","adverts","original-count","color","base-latitude","base-longitude","is-compact-view"])]))),128)),at.value.length===0&&Object.keys(e.value).length===0?(f(),$("div",fn,[p[20]||(p[20]=ft('<div class="text-content-secondary dark:text-content-muted mb-4"><svg class="w-16 h-16 mx-auto mb-4 opacity-50" fill="none" stroke="currentColor" viewBox="0 0 24 24"><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"></path></svg></div><h3 class="text-content-primary dark:text-content-primary text-lg font-medium mb-2">No Neighbors Found</h3><p class="text-content-secondary dark:text-content-muted">No mesh neighbors have been discovered in your area yet.</p>',3)),t("button",{onClick:E,class:"mt-4 px-4 py-2 bg-primary/20 text-primary border border-primary/30 rounded-lg hover:bg-primary/30 transition-colors"}," Refresh ")])):at.value.length===0&&et.value?(f(),$("div",wn,[p[21]||(p[21]=ft('<div class="text-content-secondary dark:text-content-muted mb-4"><svg class="w-16 h-16 mx-auto mb-4 opacity-50" fill="none" stroke="currentColor" viewBox="0 0 24 24"><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"></path></svg></div><h3 class="text-content-primary dark:text-content-primary text-lg font-medium mb-2">No neighbors match your filters</h3><p class="text-content-secondary dark:text-content-muted mb-4">Try adjusting your filter criteria to see more results.</p>',3)),t("button",{onClick:K,class:"px-4 py-2 bg-primary/20 text-primary border border-primary/30 rounded-lg hover:bg-primary/30 transition-colors"}," Clear Filters ")])):D("",!0)],64)),it(be,{show:v.value,neighbor:Z.value,onClose:z,onDelete:H},null,8,["show","neighbor"]),it(qe,{show:S.value,"node-name":_.value,result:b.value,error:L.value,loading:x.value,onClose:R},null,8,["show","node-name","result","error","loading"]),it(zo,{"is-open":P.value,neighbor:I.value,"base-latitude":y.value,"base-longitude":u.value,onClose:X},null,8,["is-open","neighbor","base-latitude","base-longitude"])]))}});export{Tn as default};