From fc4c5394dc989497481ea3dab5d0e09fb361b73e Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot Date: Wed, 31 Dec 2025 19:37:38 +0000 Subject: [PATCH] Sync build v0.8.0 Automated sync from private repository. Commit: 9822b27b2549eda51975ce9d5c7350d2abbe3f1a --- frontend/dist/VERSION | 2 +- frontend/dist/assets/Contacts-D6vZzdXY.js | 2 -- frontend/dist/assets/Contacts-D_vTGYlD.js | 2 ++ frontend/dist/assets/ContactsMapMapLibre-BG6tbEVu.js | 1 + frontend/dist/assets/ContactsMapMapLibre-BVXSoZJb.js | 1 - frontend/dist/assets/Dashboard-DuQsYlvL.js | 1 - frontend/dist/assets/Dashboard-eZ7DEoKT.js | 1 + frontend/dist/assets/{Grid-CWWSogEX.js => Grid-DdJ9Z5-6.js} | 2 +- .../assets/{HashBadge-lGexd78S.js => HashBadge-C9wBwTs9.js} | 2 +- frontend/dist/assets/{Logs-jLA3dK2J.js => Logs-Bbq71dRc.js} | 2 +- frontend/dist/assets/PacketDetailModal-b5dydJdT.js | 2 ++ frontend/dist/assets/PacketDetailModal-lDJaZ0EH.js | 2 -- frontend/dist/assets/Packets-B99to2gr.js | 1 + frontend/dist/assets/Packets-wwz2e-UA.js | 1 - .../assets/{PageLayout-DX-kEdsY.js => PageLayout-Bo02yEFi.js} | 2 +- ...athMapMapLibre-p5aTyqdp.js => PathMapMapLibre-B13Fr94x.js} | 2 +- .../assets/{Settings-Xez00HAR.js => Settings-DMT_dXde.js} | 2 +- ...ignalIndicator-CTCsDXIU.js => SignalIndicator-Dsxq994J.js} | 2 +- .../assets/{Statistics-BiMhRHz3.js => Statistics-BwaEbIq-.js} | 2 +- .../dist/assets/{System-BD1Ow4sE.js => System-Bp6gNI-e.js} | 2 +- .../assets/{Terminal-C66pW-cr.js => Terminal-C3eAB6BT.js} | 2 +- ...angeSelector-DFiSI7-m.js => TimeRangeSelector-DfsvDo3s.js} | 2 +- .../assets/{activity-zgFimRtU.js => activity-Bw-7kQZI.js} | 2 +- frontend/dist/assets/circle-BYfeFf1_.js | 1 - frontend/dist/assets/circle-izCaSEiI.js | 1 + frontend/dist/assets/{house-C7F060l_.js => house-Bm0hez83.js} | 2 +- frontend/dist/assets/index--3scPUpk.js | 2 -- frontend/dist/assets/index-BJveXym2.js | 2 ++ frontend/dist/assets/index-DRIJpMsz.css | 1 + frontend/dist/assets/index-LXTO-BSp.css | 1 - frontend/dist/assets/{info-DOF-21eC.js => info-CrsYI7df.js} | 2 +- .../{loader-circle-BFWvLhiI.js => loader-circle-D2VmbXOw.js} | 2 +- frontend/dist/assets/map-BrPyYvjH.js | 1 + .../{maplibre-gl-C9yo4KKq.js => maplibre-gl-VvZVTf3N.js} | 2 +- .../assets/{refresh-cw-BwX1e8z9.js => refresh-cw-B7_ETcHC.js} | 2 +- .../{trending-up-JG-dRR26.js => trending-up-D3G9fnzg.js} | 2 +- ...{triangle-alert-BfoUmJBY.js => triangle-alert-DoYB0rUo.js} | 2 +- frontend/dist/assets/{users-CO3RvsS7.js => users-CVDQWeBL.js} | 2 +- frontend/dist/assets/{zap-BCKTLl58.js => zap-BuJA7oRW.js} | 2 +- frontend/dist/index.html | 4 ++-- frontend/package.json | 2 +- 41 files changed, 37 insertions(+), 36 deletions(-) delete mode 100644 frontend/dist/assets/Contacts-D6vZzdXY.js create mode 100644 frontend/dist/assets/Contacts-D_vTGYlD.js create mode 100644 frontend/dist/assets/ContactsMapMapLibre-BG6tbEVu.js delete mode 100644 frontend/dist/assets/ContactsMapMapLibre-BVXSoZJb.js delete mode 100644 frontend/dist/assets/Dashboard-DuQsYlvL.js create mode 100644 frontend/dist/assets/Dashboard-eZ7DEoKT.js rename frontend/dist/assets/{Grid-CWWSogEX.js => Grid-DdJ9Z5-6.js} (94%) rename frontend/dist/assets/{HashBadge-lGexd78S.js => HashBadge-C9wBwTs9.js} (97%) rename frontend/dist/assets/{Logs-jLA3dK2J.js => Logs-Bbq71dRc.js} (95%) create mode 100644 frontend/dist/assets/PacketDetailModal-b5dydJdT.js delete mode 100644 frontend/dist/assets/PacketDetailModal-lDJaZ0EH.js create mode 100644 frontend/dist/assets/Packets-B99to2gr.js delete mode 100644 frontend/dist/assets/Packets-wwz2e-UA.js rename frontend/dist/assets/{PageLayout-DX-kEdsY.js => PageLayout-Bo02yEFi.js} (96%) rename frontend/dist/assets/{PathMapMapLibre-p5aTyqdp.js => PathMapMapLibre-B13Fr94x.js} (97%) rename frontend/dist/assets/{Settings-Xez00HAR.js => Settings-DMT_dXde.js} (97%) rename frontend/dist/assets/{SignalIndicator-CTCsDXIU.js => SignalIndicator-Dsxq994J.js} (97%) rename frontend/dist/assets/{Statistics-BiMhRHz3.js => Statistics-BwaEbIq-.js} (98%) rename frontend/dist/assets/{System-BD1Ow4sE.js => System-Bp6gNI-e.js} (97%) rename frontend/dist/assets/{Terminal-C66pW-cr.js => Terminal-C3eAB6BT.js} (99%) rename frontend/dist/assets/{TimeRangeSelector-DFiSI7-m.js => TimeRangeSelector-DfsvDo3s.js} (87%) rename frontend/dist/assets/{activity-zgFimRtU.js => activity-Bw-7kQZI.js} (72%) delete mode 100644 frontend/dist/assets/circle-BYfeFf1_.js create mode 100644 frontend/dist/assets/circle-izCaSEiI.js rename frontend/dist/assets/{house-C7F060l_.js => house-Bm0hez83.js} (76%) delete mode 100644 frontend/dist/assets/index--3scPUpk.js create mode 100644 frontend/dist/assets/index-BJveXym2.js create mode 100644 frontend/dist/assets/index-DRIJpMsz.css delete mode 100644 frontend/dist/assets/index-LXTO-BSp.css rename frontend/dist/assets/{info-DOF-21eC.js => info-CrsYI7df.js} (68%) rename frontend/dist/assets/{loader-circle-BFWvLhiI.js => loader-circle-D2VmbXOw.js} (54%) create mode 100644 frontend/dist/assets/map-BrPyYvjH.js rename frontend/dist/assets/{maplibre-gl-C9yo4KKq.js => maplibre-gl-VvZVTf3N.js} (99%) rename frontend/dist/assets/{refresh-cw-BwX1e8z9.js => refresh-cw-B7_ETcHC.js} (79%) rename frontend/dist/assets/{trending-up-JG-dRR26.js => trending-up-D3G9fnzg.js} (87%) rename frontend/dist/assets/{triangle-alert-BfoUmJBY.js => triangle-alert-DoYB0rUo.js} (75%) rename frontend/dist/assets/{users-CO3RvsS7.js => users-CVDQWeBL.js} (78%) rename frontend/dist/assets/{zap-BCKTLl58.js => zap-BuJA7oRW.js} (85%) diff --git a/frontend/dist/VERSION b/frontend/dist/VERSION index a6b176fb..a3df0a69 100644 --- a/frontend/dist/VERSION +++ b/frontend/dist/VERSION @@ -1 +1 @@ -0.7.54 +0.8.0 diff --git a/frontend/dist/assets/Contacts-D6vZzdXY.js b/frontend/dist/assets/Contacts-D6vZzdXY.js deleted file mode 100644 index 0c0adf15..00000000 --- a/frontend/dist/assets/Contacts-D6vZzdXY.js +++ /dev/null @@ -1,2 +0,0 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/ContactsMapMapLibre-BVXSoZJb.js","assets/index--3scPUpk.js","assets/recharts-bmHCCfxU.js","assets/maplibre-gl-CFO9X1Ek.js","assets/index-LXTO-BSp.css","assets/maplibre-gl-C9yo4KKq.js","assets/maplibre-gl-B1CfjdFi.css","assets/HashBadge-lGexd78S.js","assets/loader-circle-BFWvLhiI.js","assets/info-DOF-21eC.js","assets/house-C7F060l_.js","assets/refresh-cw-BwX1e8z9.js","assets/trending-up-JG-dRR26.js","assets/SignalIndicator-CTCsDXIU.js","assets/triangle-alert-BfoUmJBY.js","assets/zap-BCKTLl58.js","assets/activity-zgFimRtU.js","assets/PageLayout-DX-kEdsY.js","assets/users-CO3RvsS7.js"])))=>i.map(i=>d[i]); -import{c as e,j as t,_ as s,z as a,y as n,X as r,A as l,B as i,E as o,g as c,F as d,G as h,H as m,f as x,R as u,C as p,I as g}from"./index--3scPUpk.js";import{b,g as j,c as y,d as v,h as f,T as N,f as w,e as k,L as C}from"./recharts-bmHCCfxU.js";import{a as M}from"./SignalIndicator-CTCsDXIU.js";import{T as S}from"./triangle-alert-BfoUmJBY.js";import{T as H,Z as L,M as _}from"./zap-BCKTLl58.js";import{A as E}from"./activity-zgFimRtU.js";import{T as $,N as R}from"./trending-up-JG-dRR26.js";import{M as A,H as P}from"./HashBadge-lGexd78S.js";import{P as T,a as O,C as q,b as z}from"./PageLayout-DX-kEdsY.js";import{U as F}from"./users-CO3RvsS7.js";const K=e("arrow-left-right",[["path",{d:"M8 3 4 7l4 4",key:"9rb6wj"}],["path",{d:"M4 7h16",key:"6tx8e3"}],["path",{d:"m16 21 4-4-4-4",key:"siv7j2"}],["path",{d:"M20 17H4",key:"h6l3hr"}]]),D=e("arrow-up-down",[["path",{d:"m21 16-4 4-4-4",key:"f6ql7i"}],["path",{d:"M17 20V4",key:"1ejh1v"}],["path",{d:"m3 8 4-4 4 4",key:"11wl7u"}],["path",{d:"M7 4v16",key:"1glfcx"}]]),B=e("chevron-up",[["path",{d:"m18 15-6-6-6 6",key:"153udz"}]]),I=e("git-branch",[["line",{x1:"6",x2:"6",y1:"3",y2:"15",key:"17qcm7"}],["circle",{cx:"18",cy:"6",r:"3",key:"1h7g24"}],["circle",{cx:"6",cy:"18",r:"3",key:"fqmcym"}],["path",{d:"M18 9a9 9 0 0 1-9 9",key:"n2h4wq"}]]),W=e("messages-square",[["path",{d:"M16 10a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 14.286V4a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z",key:"1n2ejm"}],["path",{d:"M20 9a2 2 0 0 1 2 2v10.286a.71.71 0 0 1-1.212.502l-2.202-2.202A2 2 0 0 0 17.172 19H10a2 2 0 0 1-2-2v-1",key:"1qfcsi"}]]),V=e("monitor-smartphone",[["path",{d:"M18 8V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h8",key:"10dyio"}],["path",{d:"M10 19v-3.96 3.15",key:"1irgej"}],["path",{d:"M7 19h5",key:"qswx4l"}],["rect",{width:"6",height:"10",x:"16",y:"12",rx:"2",key:"1egngj"}]]),U=e("ruler",[["path",{d:"M21.3 15.3a2.4 2.4 0 0 1 0 3.4l-2.6 2.6a2.4 2.4 0 0 1-3.4 0L2.7 8.7a2.41 2.41 0 0 1 0-3.4l2.6-2.6a2.41 2.41 0 0 1 3.4 0Z",key:"icamh8"}],["path",{d:"m14.5 12.5 2-2",key:"inckbg"}],["path",{d:"m11.5 9.5 2-2",key:"fmmyf7"}],["path",{d:"m8.5 6.5 2-2",key:"vc6u1g"}],["path",{d:"m17.5 15.5 2-2",key:"wo5hmg"}]]),G=e("search",[["path",{d:"m21 21-4.34-4.34",key:"14j7rj"}],["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}]]),Z=e("share-2",[["circle",{cx:"18",cy:"5",r:"3",key:"gq8acd"}],["circle",{cx:"6",cy:"12",r:"3",key:"w7nqdw"}],["circle",{cx:"18",cy:"19",r:"3",key:"1xt0gg"}],["line",{x1:"8.59",x2:"15.42",y1:"13.51",y2:"17.49",key:"47mynk"}],["line",{x1:"15.41",x2:"8.59",y1:"6.51",y2:"10.49",key:"1n3mei"}]]),Y=e("trash-2",[["path",{d:"M10 11v6",key:"nco0om"}],["path",{d:"M14 11v6",key:"outv1u"}],["path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6",key:"miytrc"}],["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2",key:"e791ji"}]]);class J extends b.Component{constructor(e){super(e),this.state={hasError:!1}}static getDerivedStateFromError(e){return{hasError:!0,error:e}}render(){var e;return this.state.hasError?t.jsx("div",{className:"glass-card h-[400px] flex items-center justify-center",children:t.jsxs("div",{className:"text-center text-white/50 p-4",children:[t.jsx("p",{className:"text-lg mb-2",children:"Map failed to load"}),t.jsx("p",{className:"text-sm text-white/30",children:(null==(e=this.state.error)?void 0:e.message)||"Unknown error"})]})}):this.props.children}}const Q=b.lazy(()=>s(()=>import("./ContactsMapMapLibre-BVXSoZJb.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18])));function X({neighbors:e,localNode:s,localHash:a,onRemoveNode:n,selectedNodeHash:r,onNodeSelected:l,highlightedEdgeKey:i}){return t.jsx(J,{children:t.jsx(b.Suspense,{fallback:t.jsx("div",{className:"glass-card h-[500px] flex items-center justify-center",children:t.jsx("div",{className:"text-white/50",children:"Loading map..."})}),children:t.jsx(Q,{neighbors:e,localNode:s,localHash:a,onRemoveNode:n,selectedNodeHash:r,onNodeSelected:l,highlightedEdgeKey:i})})})}function ee(e){return e>=.7?"text-accent-success":e>=.5?"text-accent-secondary":e>=.3?"text-signal-poor":"text-accent-danger"}function te(e){return`${Math.round(100*e)}%`}const se=b.memo(function({path:e,isHighlighted:s,onHighlight:a}){const n=function(e){return e>.2?{icon:t.jsx($,{className:"w-3 h-3"}),color:"text-accent-success"}:e<-.2?{icon:t.jsx(H,{className:"w-3 h-3"}),color:"text-accent-danger"}:{icon:t.jsx(_,{className:"w-3 h-3"}),color:"text-text-muted"}}(e.observationTrend),r=e.weakestLinkKey&&e.weakestLinkConfidence<.5;return t.jsxs("div",{className:"flex items-center gap-3 p-2 rounded-md transition-colors cursor-pointer "+(s?"bg-accent-primary/20 border border-accent-primary/40":"hover:bg-white/5"),onClick:()=>a(s?null:e.weakestLinkKey),children:[t.jsx("div",{className:"flex-shrink-0 w-12 text-center py-1 rounded-md "+(l=e.healthScore,l>=.7?"bg-accent-success/10":l>=.5?"bg-accent-secondary/10":l>=.3?"bg-signal-poor/10":"bg-accent-danger/10"),children:t.jsx("span",{className:`text-xs font-semibold tabular-nums ${ee(e.healthScore)}`,children:te(e.healthScore)})}),t.jsx("div",{className:"flex-1 flex items-center gap-0.5 overflow-x-auto min-w-0",children:e.hops.map((s,a)=>{var n;return t.jsxs("span",{className:"flex items-center",children:[t.jsx("span",{className:"text-[10px] font-mono px-1.5 py-0.5 rounded "+(r&&(null==(n=e.weakestLinkKey)?void 0:n.includes(s))?"bg-accent-danger/20 text-accent-danger":"bg-white/10 text-text-secondary"),children:s}),al.slice(0,e),[l,e]),d=b.useMemo(()=>0===l.length?null:{avgHealth:l.reduce((e,t)=>e+t.healthScore,0)/l.length,declining:l.filter(e=>e.observationTrend<-.2).length,weakLinks:l.filter(e=>e.weakestLinkConfidence<.5).length},[l]),h=e=>{null==s||s(e)};return 0===l.length?null:t.jsxs("div",{className:"chart-container",children:[t.jsxs("button",{onClick:()=>o(!i),className:"w-full chart-header hover:bg-white/5 transition-colors rounded-t-lg cursor-pointer",children:[t.jsxs("div",{className:"chart-title",children:[t.jsx(I,{className:"chart-title-icon"}),"Path Health",t.jsxs("span",{className:"ml-2 text-[10px] font-normal text-text-muted",children:["(",l.length," paths)"]})]}),t.jsxs("div",{className:"flex items-center gap-3",children:[d&&t.jsxs("div",{className:"flex items-center gap-3 text-[10px]",children:[t.jsxs("span",{className:`tabular-nums ${ee(d.avgHealth)}`,children:["Avg: ",te(d.avgHealth)]}),d.weakLinks>0&&t.jsxs("span",{className:"text-accent-danger flex items-center gap-1",children:[t.jsx(S,{className:"w-3 h-3"}),d.weakLinks," weak"]}),d.declining>0&&t.jsxs("span",{className:"text-signal-poor flex items-center gap-1",children:[t.jsx(H,{className:"w-3 h-3"}),d.declining," declining"]})]}),i?t.jsx(B,{className:"w-4 h-4 text-text-muted"}):t.jsx(n,{className:"w-4 h-4 text-text-muted"})]})]}),i&&t.jsxs("div",{className:"p-3 pt-0 space-y-1",children:[t.jsxs("div",{className:"flex items-center gap-4 text-[10px] text-text-muted pb-2 border-b border-white/5",children:[t.jsxs("span",{className:"flex items-center gap-1",children:[t.jsx("span",{className:"w-2 h-2 rounded-full bg-accent-success"})," Healthy (≥70%)"]}),t.jsxs("span",{className:"flex items-center gap-1",children:[t.jsx("span",{className:"w-2 h-2 rounded-full bg-accent-secondary"})," Fair (50-70%)"]}),t.jsxs("span",{className:"flex items-center gap-1",children:[t.jsx("span",{className:"w-2 h-2 rounded-full bg-signal-poor"})," Weak (30-50%)"]}),t.jsxs("span",{className:"flex items-center gap-1",children:[t.jsx("span",{className:"w-2 h-2 rounded-full bg-accent-danger"})," Critical (<30%)"]})]}),t.jsx("div",{className:"space-y-1 max-h-64 overflow-y-auto",children:c.map(e=>t.jsx(se,{path:e,isHighlighted:r===e.weakestLinkKey,onHighlight:h},e.pathKey))}),l.length>e&&t.jsxs("div",{className:"text-center text-[10px] text-text-muted pt-2",children:["Showing top ",e," of ",l.length," paths"]})]})]})}),ne=b.memo(function({isOpen:e,title:s="Confirm",message:a,confirmLabel:n="Confirm",cancelLabel:l="Cancel",variant:i="default",onConfirm:o,onCancel:c}){if(b.useEffect(()=>{if(!e)return;const t=e=>{"Escape"===e.key&&c()};window.addEventListener("keydown",t);const s=document.body.style.overflow,a=document.body.style.position,n=document.body.style.width,r=document.body.style.top,l=window.scrollY;return document.body.style.overflow="hidden",document.body.style.position="fixed",document.body.style.width="100%",document.body.style.top=`-${l}px`,()=>{window.removeEventListener("keydown",t),document.body.style.overflow=s,document.body.style.position=a,document.body.style.width=n,document.body.style.top=r,window.scrollTo(0,l)}},[e,c]),!e)return null;const d={danger:{icon:"text-accent-danger",button:"bg-accent-danger hover:bg-red-600"},warning:{icon:"text-accent-secondary",button:"bg-accent-secondary hover:bg-yellow-600 text-bg-body"},default:{icon:"text-accent-primary",button:"bg-accent-primary hover:bg-violet-500 text-bg-body"}}[i];return j.createPortal(t.jsx("div",{className:"fixed inset-0 bg-black/40 backdrop-blur-md z-[10010] flex items-end sm:items-center justify-center",onClick:c,role:"dialog","aria-modal":"true","aria-labelledby":"confirm-modal-title",children:t.jsxs("div",{className:y("glass-card w-full max-w-sm overflow-hidden","sm:mx-4 sm:rounded-xl","rounded-t-2xl rounded-b-none sm:rounded-b-xl","pb-safe"),onClick:e=>e.stopPropagation(),children:[t.jsxs("div",{className:"flex items-center justify-between p-4 border-b border-border-subtle",children:[t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsx("div",{className:y("p-2 rounded-lg bg-bg-subtle",d.icon),children:t.jsx(S,{className:"w-5 h-5"})}),t.jsx("h3",{id:"confirm-modal-title",className:"text-base font-semibold text-text-primary",children:s})]}),t.jsx("button",{onClick:c,className:"p-2 rounded-lg text-text-muted hover:text-text-primary hover:bg-bg-subtle transition-colors",children:t.jsx(r,{className:"w-5 h-5"})})]}),t.jsx("div",{className:"p-4",children:t.jsx("p",{className:"text-sm text-text-secondary",children:a})}),t.jsxs("div",{className:"flex gap-3 p-4 pt-0",children:[t.jsx("button",{onClick:c,className:"flex-1 px-4 py-2.5 rounded-lg text-sm font-medium text-text-secondary bg-bg-subtle hover:bg-bg-elevated border border-border-subtle transition-colors",children:l}),t.jsx("button",{onClick:o,className:y("flex-1 px-4 py-2.5 rounded-lg text-sm font-medium text-text-primary transition-colors",d.button),children:n})]})]})}),document.body)}),re="var(--signal-critical)",le="var(--signal-poor)",ie="var(--signal-fair)",oe="var(--signal-good)",ce="var(--signal-excellent)",de="var(--text-muted)";function he({active:e,payload:s}){if(!e||!s||!s.length)return null;const a=s[0].payload,n=new Date(a.timestamp),r=`${(n.getMonth()+1).toString().padStart(2,"0")}/${n.getDate().toString().padStart(2,"0")}`;return t.jsxs("div",{className:"bg-tooltip-bg border border-border-subtle rounded px-1.5 py-0.5 text-[10px] shadow-xl",children:[t.jsx("span",{className:"text-text-muted",children:r}),t.jsx("span",{className:"ml-1.5 font-semibold tabular-nums",children:a.count})]})}const me=b.memo(function({nodeHash:e,width:s=60,height:a=20,color:n,showArea:r=!0,showTooltip:o=!1,className:c=""}){const d=l(e),h=i(),m=n??(d.length>0?function(e){if(0===e.length)return re;const t=e.slice(-4),s=t.reduce((e,t)=>e+t.count,0),a=s/t.length,n=e.reduce((e,t)=>e+t.count,0)/e.length;if(0===s)return re;if(n>0){const e=a/n;return e>=1.2?ce:e>=.8?oe:e>=.4?ie:e>=.1?le:re}return s>=10?ce:s>=5?oe:s>=2?ie:s>=1?le:re}(d):de),x={width:s,height:a};if(d.length<2){const e="number"==typeof s?s:60,n=h?de:re;return t.jsx("div",{className:`flex items-center justify-center ${c}`,style:{...x,color:n},children:t.jsx("svg",{width:"100%",height:a,viewBox:`0 0 ${e} ${a}`,preserveAspectRatio:"none",children:t.jsx("line",{x1:4,y1:a/2,x2:e-4,y2:a/2,stroke:"currentColor",strokeWidth:1.5,strokeDasharray:"3,2",className:h?"animate-pulse":""})})})}const u=`sparkline-gradient-${e.slice(-6)}`;return t.jsx("div",{className:c,style:x,children:t.jsx(v,{width:"100%",height:"100%",children:r?t.jsxs(f,{data:d,margin:{top:1,right:1,bottom:1,left:1},children:[t.jsx("defs",{children:t.jsxs("linearGradient",{id:u,x1:"0",y1:"0",x2:"0",y2:"1",children:[t.jsx("stop",{offset:"0%",stopColor:m,stopOpacity:.35}),t.jsx("stop",{offset:"100%",stopColor:m,stopOpacity:.05})]})}),o&&t.jsx(N,{content:t.jsx(he,{}),cursor:{stroke:"rgba(255,255,255,0.2)",strokeWidth:1}}),t.jsx(w,{type:"monotone",dataKey:"count",stroke:"none",fill:`url(#${u})`,isAnimationActive:!1}),t.jsx(k,{type:"monotone",dataKey:"count",stroke:m,strokeWidth:1.5,dot:!1,isAnimationActive:!1})]}):t.jsxs(C,{data:d,margin:{top:1,right:1,bottom:1,left:1},children:[o&&t.jsx(N,{content:t.jsx(he,{}),cursor:{stroke:"rgba(255,255,255,0.2)",strokeWidth:1}}),t.jsx(k,{type:"monotone",dataKey:"count",stroke:m,strokeWidth:1.5,dot:!1,isAnimationActive:!1})]})})})});function xe(e,t,s,a){const n=(s-e)*Math.PI/180,r=(a-t)*Math.PI/180,l=Math.sin(n/2)*Math.sin(n/2)+Math.cos(e*Math.PI/180)*Math.cos(s*Math.PI/180)*Math.sin(r/2)*Math.sin(r/2);return 2*Math.atan2(Math.sqrt(l),Math.sqrt(1-l))*6371e3}const ue=Object.freeze(Object.defineProperty({__proto__:null,default:function(){const{stats:e}=o(),s=c(),a=d(),n=h(),l=m(),i=x(),[j,y]=b.useState(null),[v,f]=b.useState("lastHeard"),[N,w]=b.useState("desc"),[k,C]=b.useState(""),[S,H]=b.useState(!1),[L,_]=b.useState(null),[$,B]=b.useState(null),I=b.useMemo(()=>(null==e?void 0:e.neighbors)??{},[null==e?void 0:e.neighbors]),J=b.useMemo(()=>Object.fromEntries(Object.entries(I).filter(([e])=>!s.has(e))),[I,s]),Q=b.useMemo(()=>{var t;return(null==(t=null==e?void 0:e.config)?void 0:t.repeater)?{latitude:e.config.repeater.latitude,longitude:e.config.repeater.longitude,name:e.config.node_name||"Local Node"}:void 0},[e]),ee=null==e?void 0:e.local_hash,te=b.useMemo(()=>{const e=new Map;if(!(null==Q?void 0:Q.latitude)||!(null==Q?void 0:Q.longitude))return e;for(const[t,s]of Object.entries(J))s.latitude&&s.longitude&&0!==s.latitude&&0!==s.longitude?e.set(t,xe(Q.latitude,Q.longitude,s.latitude,s.longitude)):e.set(t,null);return e},[J,Q]),{neighborHashSet:se,neighborSignalMap:re}=b.useMemo(()=>{const e=new Set,t=new Map;for(const s of i)e.add(s.hash),t.set(s.hash,{avgRssi:s.avgRssi,avgSnr:s.avgSnr});return{neighborHashSet:e,neighborSignalMap:t}},[i]),le=b.useMemo(()=>{const e=k.toLowerCase().trim(),t="neighbor"===e||"neighbors"===e,s=S||t;return Object.fromEntries(Object.entries(J).filter(([a,n])=>{if(s&&!se.has(a))return!1;if(t)return!0;if(!e)return!0;const r=(n.node_name||n.name||"").toLowerCase(),l=a.slice(2,4).toLowerCase();return r.includes(e)||l.includes(e)||a.toLowerCase().includes(e)}))},[J,k,S,se]),ie=b.useMemo(()=>Object.entries(le).sort(([e,t],[s,a])=>{let n=0;switch(v){case"lastHeard":n=(t.last_seen||0)-(a.last_seen||0);break;case"distance":{const t=te.get(e)??null,a=te.get(s)??null;n=null===t&&null===a?0:null===t?1:null===a?-1:t-a;break}case"centrality":n=(l.get(e)||0)-(l.get(s)||0)}return"desc"===N?-n:n}),[le,v,N,te,l]),oe=ie.filter(([,e])=>e.latitude&&e.longitude&&0!==e.latitude&&0!==e.longitude).length,ce=b.useMemo(()=>new Set(n),[n]),de=b.useCallback(e=>{v===e?w(e=>"desc"===e?"asc":"desc"):(f(e),w("desc"))},[v]),he=b.useCallback(e=>{const t=J[e];(null==t?void 0:t.latitude)&&(null==t?void 0:t.longitude)&&0!==t.latitude&&0!==t.longitude&&_(e)},[J]),ue=b.useCallback(()=>{_(null)},[]);return t.jsxs(T,{children:[t.jsx(O,{title:"Contacts",icon:t.jsx(F,{}),controls:t.jsxs("div",{className:"flex items-baseline gap-3 sm:gap-4",children:[t.jsxs("span",{className:"roster-title tabular-nums",children:[ie.length," node",1!==ie.length?"s":""]}),oe>0&&t.jsxs("span",{className:"roster-title flex items-baseline gap-1.5 tabular-nums",children:[t.jsx(A,{className:"w-3.5 h-3.5 relative top-[2px]"}),oe," with location"]})]})}),t.jsx("div",{className:"relative",children:t.jsx(X,{neighbors:J,localNode:Q,localHash:ee,onRemoveNode:a,selectedNodeHash:L,onNodeSelected:ue,highlightedEdgeKey:$})}),t.jsx(ae,{maxPaths:10,highlightedEdge:$,onHighlightEdge:B}),t.jsxs(q,{noPadding:!0,children:[t.jsx(z,{listHeader:!0,icon:t.jsx(F,{className:"icon-sm"}),title:"Discovered Contacts",actions:t.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[se.size>0&&t.jsxs("button",{onClick:()=>H(!S),className:"flex items-center gap-1.5 px-2.5 py-1.5 text-xs rounded-lg transition-colors min-h-[32px] order-1 sm:order-1 "+(S?"bg-accent-success/20 text-accent-success border border-accent-success/30":"text-text-muted hover:text-text-secondary hover:bg-white/5 border border-transparent"),title:S?"Show all contacts":"Show only MeshCore neighbors (direct RF contact)",children:[t.jsx(u,{className:"w-3.5 h-3.5"}),t.jsx("span",{className:"hidden sm:inline",children:"Neighbors"}),t.jsx("span",{className:"sm:hidden",children:se.size}),S&&t.jsx("span",{className:"text-[10px] font-semibold tabular-nums",children:se.size})]}),t.jsxs("div",{className:"relative order-2 sm:order-2",children:[t.jsx(G,{className:"absolute left-2.5 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-text-muted"}),t.jsx("input",{type:"text",value:k,onChange:e=>C(e.target.value),placeholder:"Search...",className:"w-28 sm:w-32 pl-7 pr-7 py-1.5 text-xs bg-white/5 border border-white/10 rounded-lg text-text-primary placeholder:text-text-muted focus:outline-none focus:border-accent-primary/50"}),k&&t.jsx("button",{onClick:()=>{C(""),"neighbor"!==k.toLowerCase().trim()&&"neighbors"!==k.toLowerCase().trim()||H(!1)},className:"absolute right-2 top-1/2 -translate-y-1/2 text-text-muted hover:text-text-secondary p-0.5",children:t.jsx(r,{className:"w-3.5 h-3.5"})})]}),t.jsxs("div",{className:"flex items-center gap-1 order-1 sm:order-2",children:[t.jsxs("button",{onClick:()=>de("lastHeard"),className:"flex items-center gap-1 px-2.5 py-1.5 text-xs rounded-lg transition-colors min-h-[32px] "+("lastHeard"===v?"bg-accent-primary/20 text-accent-primary":"text-text-muted hover:text-text-secondary hover:bg-white/5"),title:"Sort by last heard",children:[t.jsx(p,{className:"w-3.5 h-3.5"}),t.jsx("span",{className:"hidden sm:inline",children:"Recent"}),"lastHeard"===v&&t.jsx(D,{className:"w-3 h-3 "+("asc"===N?"rotate-180":"")})]}),t.jsxs("button",{onClick:()=>de("distance"),className:"flex items-center gap-1 px-2.5 py-1.5 text-xs rounded-lg transition-colors min-h-[32px] "+("distance"===v?"bg-accent-primary/20 text-accent-primary":"text-text-muted hover:text-text-secondary hover:bg-white/5"),title:"Sort by distance",children:[t.jsx(U,{className:"w-3.5 h-3.5"}),t.jsx("span",{className:"hidden sm:inline",children:"Distance"}),"distance"===v&&t.jsx(D,{className:"w-3 h-3 "+("asc"===N?"rotate-180":"")})]}),t.jsxs("button",{onClick:()=>de("centrality"),className:"flex items-center gap-1 px-2.5 py-1.5 text-xs rounded-lg transition-colors min-h-[32px] "+("centrality"===v?"bg-accent-primary/20 text-accent-primary":"text-text-muted hover:text-text-secondary hover:bg-white/5"),title:"Sort by network centrality",children:[t.jsx(E,{className:"w-3.5 h-3.5"}),t.jsx("span",{className:"hidden sm:inline",children:"Centrality"}),"centrality"===v&&t.jsx(D,{className:"w-3 h-3 "+("asc"===N?"rotate-180":"")})]})]})]})}),ie.length>0?t.jsx("div",{className:"roster-list",children:ie.map(([e,s],a)=>{var n,r;const i=s.latitude&&s.longitude&&0!==s.latitude&&0!==s.longitude,o=s.node_name||s.name||"Unknown",c=ce.has(e),d=se.has(e),h=te.get(e),m=l.get(e)||0,x=d?re.get(e):void 0,u=d&&x;return t.jsxs("div",{children:[t.jsxs("div",{className:`roster-row ${c?"bg-amber-500/5 border-l-2 border-l-amber-400":""} ${i?"cursor-pointer hover:bg-white/[0.02]":""}`,onClick:()=>he(e),children:[t.jsxs("div",{className:"relative flex-shrink-0",children:[t.jsx("div",{className:"roster-icon",children:(()=>{var e;const a=null==(e=s.contact_type)?void 0:e.toLowerCase(),n="room server"===a||"room_server"===a||"room"===a||"server"===a,r="companion"===a||"client"===a||"cli"===a,l=s.is_repeater||"repeater"===a||"rep"===a,i="#4338CA",o="#F59E0B";return n&&l?t.jsxs("div",{className:"relative w-5 h-5",children:[t.jsx(W,{className:"w-5 h-5 absolute inset-0",style:{color:o}}),t.jsx(Z,{className:"w-2.5 h-2.5 absolute -bottom-0.5 -right-0.5",style:{color:i}})]}):n?t.jsx(W,{className:"w-5 h-5",style:{color:o}}):r?t.jsx(V,{className:"w-5 h-5 text-text-muted"}):l?d?t.jsx(K,{className:"w-5 h-5 text-accent-success"}):t.jsx(Z,{className:"w-5 h-5",style:{color:i}}):t.jsx(V,{className:"w-5 h-5 text-text-muted"})})()}),u&&null!==(null==x?void 0:x.avgSnr)&&t.jsx("div",{className:`absolute -top-0.5 -right-0.5 w-2.5 h-2.5 rounded-full ${b=x.avgSnr,void 0===b?"bg-[var(--signal-unknown)]":b>=5?"bg-[var(--signal-excellent)]":b>=0?"bg-[var(--signal-good)]":b>=-5?"bg-[var(--signal-fair)]":b>=-10?"bg-[var(--signal-poor)]":"bg-[var(--signal-critical)]"} border-2 border-bg-surface`})]}),t.jsxs("div",{className:"roster-content min-w-0 flex-1",children:[t.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[t.jsx("span",{className:"roster-title",children:o}),d&&t.jsx("span",{className:"type-badge px-1.5 py-0.5 rounded",style:{backgroundColor:"rgba(57, 217, 138, 0.2)",color:"#39D98A"},children:"NBR"}),c&&t.jsxs("span",{className:"type-badge px-1.5 py-0.5 rounded flex items-center gap-1",style:{backgroundColor:"rgba(251, 191, 36, 0.2)",color:"#FBBF24"},children:[t.jsx(R,{className:"w-3 h-3"}),"HUB"]}),(s.is_repeater||"repeater"===(null==(n=s.contact_type)?void 0:n.toLowerCase())||"rep"===(null==(r=s.contact_type)?void 0:r.toLowerCase()))&&t.jsx("span",{className:"pill-tag",children:"RPT"})]}),t.jsx("div",{className:"hidden md:block",children:t.jsx(P,{hash:e,size:"sm",full:!0})}),t.jsx("div",{className:"md:hidden",children:t.jsx(P,{hash:e,size:"sm",prefixLength:8,suffixLength:6})})]}),t.jsxs("div",{className:"roster-metrics flex-shrink-0",children:[u&&null!==(null==x?void 0:x.avgRssi)&&t.jsxs("div",{className:"flex items-center gap-1.5",children:[t.jsx(M,{rssi:x.avgRssi,className:"w-3.5 h-3.5"}),t.jsx("span",{className:"type-data-xs tabular-nums",children:Math.round(x.avgRssi)})]}),u&&null!==(null==x?void 0:x.avgSnr)&&t.jsx("div",{className:"flex items-center gap-1.5",children:t.jsxs("span",{className:"type-data-xs tabular-nums",children:[x.avgSnr.toFixed(1)," dB"]})}),null!=h&&t.jsxs("div",{className:"flex items-center gap-1 text-accent-tertiary",children:[t.jsx(U,{className:"w-3 h-3"}),t.jsx("span",{className:"type-data-xs tabular-nums",children:(p=h,p<1e3?`${Math.round(p)}m`:`${(p/1e3).toFixed(1)}km`)})]}),m>0&&t.jsxs("div",{className:"flex items-center gap-1 text-amber-400/70",children:[t.jsx(E,{className:"w-3 h-3"}),t.jsxs("span",{className:"type-data-xs tabular-nums",children:[(100*m).toFixed(0),"%"]})]}),t.jsx("div",{className:"hidden sm:block",children:t.jsx(me,{nodeHash:e,width:48,height:16})})]}),t.jsx("div",{className:"roster-metric flex-shrink-0",children:s.last_seen?g(s.last_seen):"—"}),t.jsx("button",{onClick:t=>{t.stopPropagation(),y({hash:e,name:o})},className:"ml-2 p-1.5 rounded-lg text-text-muted/50 hover:text-red-400 hover:bg-red-500/10 transition-colors flex-shrink-0",title:"Remove contact",children:t.jsx(Y,{className:"w-4 h-4"})})]}),a{j&&a(j.hash),y(null)},onCancel:()=>y(null)})]})}},Symbol.toStringTag,{value:"Module"}));export{ne as C,I as G,W as M,me as N,Y as T,ue as a}; diff --git a/frontend/dist/assets/Contacts-D_vTGYlD.js b/frontend/dist/assets/Contacts-D_vTGYlD.js new file mode 100644 index 00000000..ea76d026 --- /dev/null +++ b/frontend/dist/assets/Contacts-D_vTGYlD.js @@ -0,0 +1,2 @@ +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/ContactsMapMapLibre-BG6tbEVu.js","assets/index-BJveXym2.js","assets/recharts-bmHCCfxU.js","assets/maplibre-gl-CFO9X1Ek.js","assets/index-DRIJpMsz.css","assets/maplibre-gl-VvZVTf3N.js","assets/maplibre-gl-B1CfjdFi.css","assets/HashBadge-C9wBwTs9.js","assets/loader-circle-D2VmbXOw.js","assets/info-CrsYI7df.js","assets/house-Bm0hez83.js","assets/refresh-cw-B7_ETcHC.js","assets/trending-up-D3G9fnzg.js","assets/map-BrPyYvjH.js","assets/SignalIndicator-Dsxq994J.js","assets/triangle-alert-DoYB0rUo.js","assets/zap-BuJA7oRW.js","assets/activity-Bw-7kQZI.js","assets/PageLayout-Bo02yEFi.js","assets/users-CVDQWeBL.js"])))=>i.map(i=>d[i]); +import{c as e,j as t,_ as s,z as a,y as n,X as r,A as l,B as i,E as o,g as c,F as d,G as h,H as m,f as x,R as u,C as p,I as g}from"./index-BJveXym2.js";import{b,g as j,c as y,d as v,h as f,T as N,f as w,e as k,L as C}from"./recharts-bmHCCfxU.js";import{a as M}from"./SignalIndicator-Dsxq994J.js";import{T as S}from"./triangle-alert-DoYB0rUo.js";import{T as H,Z as L,M as _}from"./zap-BuJA7oRW.js";import{A as E}from"./activity-Bw-7kQZI.js";import{T as $,N as R}from"./trending-up-D3G9fnzg.js";import{M as A,H as P}from"./HashBadge-C9wBwTs9.js";import{P as T,a as O,C as z,b as F}from"./PageLayout-Bo02yEFi.js";import{U as q}from"./users-CVDQWeBL.js";const K=e("arrow-left-right",[["path",{d:"M8 3 4 7l4 4",key:"9rb6wj"}],["path",{d:"M4 7h16",key:"6tx8e3"}],["path",{d:"m16 21 4-4-4-4",key:"siv7j2"}],["path",{d:"M20 17H4",key:"h6l3hr"}]]),D=e("arrow-up-down",[["path",{d:"m21 16-4 4-4-4",key:"f6ql7i"}],["path",{d:"M17 20V4",key:"1ejh1v"}],["path",{d:"m3 8 4-4 4 4",key:"11wl7u"}],["path",{d:"M7 4v16",key:"1glfcx"}]]),B=e("chevron-up",[["path",{d:"m18 15-6-6-6 6",key:"153udz"}]]),I=e("git-branch",[["line",{x1:"6",x2:"6",y1:"3",y2:"15",key:"17qcm7"}],["circle",{cx:"18",cy:"6",r:"3",key:"1h7g24"}],["circle",{cx:"6",cy:"18",r:"3",key:"fqmcym"}],["path",{d:"M18 9a9 9 0 0 1-9 9",key:"n2h4wq"}]]),W=e("messages-square",[["path",{d:"M16 10a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 14.286V4a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z",key:"1n2ejm"}],["path",{d:"M20 9a2 2 0 0 1 2 2v10.286a.71.71 0 0 1-1.212.502l-2.202-2.202A2 2 0 0 0 17.172 19H10a2 2 0 0 1-2-2v-1",key:"1qfcsi"}]]),V=e("monitor-smartphone",[["path",{d:"M18 8V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h8",key:"10dyio"}],["path",{d:"M10 19v-3.96 3.15",key:"1irgej"}],["path",{d:"M7 19h5",key:"qswx4l"}],["rect",{width:"6",height:"10",x:"16",y:"12",rx:"2",key:"1egngj"}]]),U=e("ruler",[["path",{d:"M21.3 15.3a2.4 2.4 0 0 1 0 3.4l-2.6 2.6a2.4 2.4 0 0 1-3.4 0L2.7 8.7a2.41 2.41 0 0 1 0-3.4l2.6-2.6a2.41 2.41 0 0 1 3.4 0Z",key:"icamh8"}],["path",{d:"m14.5 12.5 2-2",key:"inckbg"}],["path",{d:"m11.5 9.5 2-2",key:"fmmyf7"}],["path",{d:"m8.5 6.5 2-2",key:"vc6u1g"}],["path",{d:"m17.5 15.5 2-2",key:"wo5hmg"}]]),G=e("search",[["path",{d:"m21 21-4.34-4.34",key:"14j7rj"}],["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}]]),Z=e("share-2",[["circle",{cx:"18",cy:"5",r:"3",key:"gq8acd"}],["circle",{cx:"6",cy:"12",r:"3",key:"w7nqdw"}],["circle",{cx:"18",cy:"19",r:"3",key:"1xt0gg"}],["line",{x1:"8.59",x2:"15.42",y1:"13.51",y2:"17.49",key:"47mynk"}],["line",{x1:"15.41",x2:"8.59",y1:"6.51",y2:"10.49",key:"1n3mei"}]]),Y=e("trash-2",[["path",{d:"M10 11v6",key:"nco0om"}],["path",{d:"M14 11v6",key:"outv1u"}],["path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6",key:"miytrc"}],["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2",key:"e791ji"}]]);class J extends b.Component{constructor(e){super(e),this.state={hasError:!1}}static getDerivedStateFromError(e){return{hasError:!0,error:e}}render(){var e;return this.state.hasError?t.jsx("div",{className:"glass-card h-[400px] flex items-center justify-center",children:t.jsxs("div",{className:"text-center text-white/50 p-4",children:[t.jsx("p",{className:"text-lg mb-2",children:"Map failed to load"}),t.jsx("p",{className:"text-sm text-white/30",children:(null==(e=this.state.error)?void 0:e.message)||"Unknown error"})]})}):this.props.children}}const Q=b.lazy(()=>s(()=>import("./ContactsMapMapLibre-BG6tbEVu.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19])));function X({neighbors:e,localNode:s,localHash:a,onRemoveNode:n,selectedNodeHash:r,onNodeSelected:l,highlightedEdgeKey:i}){return t.jsx(J,{children:t.jsx(b.Suspense,{fallback:t.jsx("div",{className:"glass-card h-[500px] flex items-center justify-center",children:t.jsx("div",{className:"text-white/50",children:"Loading map..."})}),children:t.jsx(Q,{neighbors:e,localNode:s,localHash:a,onRemoveNode:n,selectedNodeHash:r,onNodeSelected:l,highlightedEdgeKey:i})})})}function ee(e){return e>=.7?"text-accent-success":e>=.5?"text-accent-secondary":e>=.3?"text-signal-poor":"text-accent-danger"}function te(e){return`${Math.round(100*e)}%`}const se=b.memo(function({path:e,isHighlighted:s,onHighlight:a}){const n=function(e){return e>.2?{icon:t.jsx($,{className:"w-3 h-3"}),color:"text-accent-success"}:e<-.2?{icon:t.jsx(H,{className:"w-3 h-3"}),color:"text-accent-danger"}:{icon:t.jsx(_,{className:"w-3 h-3"}),color:"text-text-muted"}}(e.observationTrend),r=e.weakestLinkKey&&e.weakestLinkConfidence<.5;return t.jsxs("div",{className:"flex items-center gap-3 p-2 rounded-md transition-colors cursor-pointer "+(s?"bg-accent-primary/20 border border-accent-primary/40":"hover:bg-white/5"),onClick:()=>a(s?null:e.weakestLinkKey),children:[t.jsx("div",{className:"flex-shrink-0 w-12 text-center py-1 rounded-md "+(l=e.healthScore,l>=.7?"bg-accent-success/10":l>=.5?"bg-accent-secondary/10":l>=.3?"bg-signal-poor/10":"bg-accent-danger/10"),children:t.jsx("span",{className:`text-xs font-semibold tabular-nums ${ee(e.healthScore)}`,children:te(e.healthScore)})}),t.jsx("div",{className:"flex-1 flex items-center gap-0.5 overflow-x-auto min-w-0",children:e.hops.map((s,a)=>{var n;return t.jsxs("span",{className:"flex items-center",children:[t.jsx("span",{className:"text-[10px] font-mono px-1.5 py-0.5 rounded "+(r&&(null==(n=e.weakestLinkKey)?void 0:n.includes(s))?"bg-accent-danger/20 text-accent-danger":"bg-white/10 text-text-secondary"),children:s}),al.slice(0,e),[l,e]),d=b.useMemo(()=>0===l.length?null:{avgHealth:l.reduce((e,t)=>e+t.healthScore,0)/l.length,declining:l.filter(e=>e.observationTrend<-.2).length,weakLinks:l.filter(e=>e.weakestLinkConfidence<.5).length},[l]),h=e=>{null==s||s(e)};return 0===l.length?null:t.jsxs("div",{className:"chart-container",children:[t.jsxs("button",{onClick:()=>o(!i),className:"w-full chart-header hover:bg-white/5 transition-colors rounded-t-lg cursor-pointer",children:[t.jsxs("div",{className:"chart-title",children:[t.jsx(I,{className:"chart-title-icon"}),"Path Health",t.jsxs("span",{className:"ml-2 text-[10px] font-normal text-text-muted",children:["(",l.length," paths)"]})]}),t.jsxs("div",{className:"flex items-center gap-3",children:[d&&t.jsxs("div",{className:"flex items-center gap-3 text-[10px]",children:[t.jsxs("span",{className:`tabular-nums ${ee(d.avgHealth)}`,children:["Avg: ",te(d.avgHealth)]}),d.weakLinks>0&&t.jsxs("span",{className:"text-accent-danger flex items-center gap-1",children:[t.jsx(S,{className:"w-3 h-3"}),d.weakLinks," weak"]}),d.declining>0&&t.jsxs("span",{className:"text-signal-poor flex items-center gap-1",children:[t.jsx(H,{className:"w-3 h-3"}),d.declining," declining"]})]}),i?t.jsx(B,{className:"w-4 h-4 text-text-muted"}):t.jsx(n,{className:"w-4 h-4 text-text-muted"})]})]}),i&&t.jsxs("div",{className:"p-3 pt-0 space-y-1",children:[t.jsxs("div",{className:"flex items-center gap-4 text-[10px] text-text-muted pb-2 border-b border-white/5",children:[t.jsxs("span",{className:"flex items-center gap-1",children:[t.jsx("span",{className:"w-2 h-2 rounded-full bg-accent-success"})," Healthy (≥70%)"]}),t.jsxs("span",{className:"flex items-center gap-1",children:[t.jsx("span",{className:"w-2 h-2 rounded-full bg-accent-secondary"})," Fair (50-70%)"]}),t.jsxs("span",{className:"flex items-center gap-1",children:[t.jsx("span",{className:"w-2 h-2 rounded-full bg-signal-poor"})," Weak (30-50%)"]}),t.jsxs("span",{className:"flex items-center gap-1",children:[t.jsx("span",{className:"w-2 h-2 rounded-full bg-accent-danger"})," Critical (<30%)"]})]}),t.jsx("div",{className:"space-y-1 max-h-64 overflow-y-auto",children:c.map(e=>t.jsx(se,{path:e,isHighlighted:r===e.weakestLinkKey,onHighlight:h},e.pathKey))}),l.length>e&&t.jsxs("div",{className:"text-center text-[10px] text-text-muted pt-2",children:["Showing top ",e," of ",l.length," paths"]})]})]})}),ne=b.memo(function({isOpen:e,title:s="Confirm",message:a,confirmLabel:n="Confirm",cancelLabel:l="Cancel",variant:i="default",onConfirm:o,onCancel:c}){if(b.useEffect(()=>{if(!e)return;const t=e=>{"Escape"===e.key&&c()};window.addEventListener("keydown",t);const s=document.body.style.overflow,a=document.body.style.position,n=document.body.style.width,r=document.body.style.top,l=window.scrollY;return document.body.style.overflow="hidden",document.body.style.position="fixed",document.body.style.width="100%",document.body.style.top=`-${l}px`,()=>{window.removeEventListener("keydown",t),document.body.style.overflow=s,document.body.style.position=a,document.body.style.width=n,document.body.style.top=r,window.scrollTo(0,l)}},[e,c]),!e)return null;const d={danger:{icon:"text-accent-danger",button:"bg-accent-danger hover:bg-red-600"},warning:{icon:"text-accent-secondary",button:"bg-accent-secondary hover:bg-yellow-600 text-bg-body"},default:{icon:"text-accent-primary",button:"bg-accent-primary hover:bg-violet-500 text-bg-body"}}[i];return j.createPortal(t.jsx("div",{className:"fixed inset-0 bg-black/40 backdrop-blur-md z-[10010] flex items-end sm:items-center justify-center",onClick:c,role:"dialog","aria-modal":"true","aria-labelledby":"confirm-modal-title",children:t.jsxs("div",{className:y("glass-card w-full max-w-sm overflow-hidden","sm:mx-4 sm:rounded-xl","rounded-t-2xl rounded-b-none sm:rounded-b-xl","pb-safe"),onClick:e=>e.stopPropagation(),children:[t.jsxs("div",{className:"flex items-center justify-between p-4 border-b border-border-subtle",children:[t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsx("div",{className:y("p-2 rounded-lg bg-bg-subtle",d.icon),children:t.jsx(S,{className:"w-5 h-5"})}),t.jsx("h3",{id:"confirm-modal-title",className:"text-base font-semibold text-text-primary",children:s})]}),t.jsx("button",{onClick:c,className:"p-2 rounded-lg text-text-muted hover:text-text-primary hover:bg-bg-subtle transition-colors",children:t.jsx(r,{className:"w-5 h-5"})})]}),t.jsx("div",{className:"p-4",children:t.jsx("p",{className:"text-sm text-text-secondary",children:a})}),t.jsxs("div",{className:"flex gap-3 p-4 pt-0",children:[t.jsx("button",{onClick:c,className:"flex-1 px-4 py-2.5 rounded-lg text-sm font-medium text-text-secondary bg-bg-subtle hover:bg-bg-elevated border border-border-subtle transition-colors",children:l}),t.jsx("button",{onClick:o,className:y("flex-1 px-4 py-2.5 rounded-lg text-sm font-medium text-text-primary transition-colors",d.button),children:n})]})]})}),document.body)}),re="var(--signal-critical)",le="var(--signal-poor)",ie="var(--signal-fair)",oe="var(--signal-good)",ce="var(--signal-excellent)",de="var(--text-muted)";function he({active:e,payload:s}){if(!e||!s||!s.length)return null;const a=s[0].payload,n=new Date(a.timestamp),r=`${(n.getMonth()+1).toString().padStart(2,"0")}/${n.getDate().toString().padStart(2,"0")}`;return t.jsxs("div",{className:"bg-tooltip-bg border border-border-subtle rounded px-1.5 py-0.5 text-[10px] shadow-xl",children:[t.jsx("span",{className:"text-text-muted",children:r}),t.jsx("span",{className:"ml-1.5 font-semibold tabular-nums",children:a.count})]})}const me=b.memo(function({nodeHash:e,width:s=60,height:a=20,color:n,showArea:r=!0,showTooltip:o=!1,className:c=""}){const d=l(e),h=i(),m=n??(d.length>0?function(e){if(0===e.length)return re;const t=e.slice(-4),s=t.reduce((e,t)=>e+t.count,0),a=s/t.length,n=e.reduce((e,t)=>e+t.count,0)/e.length;if(0===s)return re;if(n>0){const e=a/n;return e>=1.2?ce:e>=.8?oe:e>=.4?ie:e>=.1?le:re}return s>=10?ce:s>=5?oe:s>=2?ie:s>=1?le:re}(d):de),x={width:s,height:a};if(d.length<2){const e="number"==typeof s?s:60,n=h?de:re;return t.jsx("div",{className:`flex items-center justify-center ${c}`,style:{...x,color:n},children:t.jsx("svg",{width:"100%",height:a,viewBox:`0 0 ${e} ${a}`,preserveAspectRatio:"none",children:t.jsx("line",{x1:4,y1:a/2,x2:e-4,y2:a/2,stroke:"currentColor",strokeWidth:1.5,strokeDasharray:"3,2",className:h?"animate-pulse":""})})})}const u=`sparkline-gradient-${e.slice(-6)}`;return t.jsx("div",{className:c,style:x,children:t.jsx(v,{width:"100%",height:"100%",children:r?t.jsxs(f,{data:d,margin:{top:1,right:1,bottom:1,left:1},children:[t.jsx("defs",{children:t.jsxs("linearGradient",{id:u,x1:"0",y1:"0",x2:"0",y2:"1",children:[t.jsx("stop",{offset:"0%",stopColor:m,stopOpacity:.35}),t.jsx("stop",{offset:"100%",stopColor:m,stopOpacity:.05})]})}),o&&t.jsx(N,{content:t.jsx(he,{}),cursor:{stroke:"rgba(255,255,255,0.2)",strokeWidth:1}}),t.jsx(w,{type:"monotone",dataKey:"count",stroke:"none",fill:`url(#${u})`,isAnimationActive:!1}),t.jsx(k,{type:"monotone",dataKey:"count",stroke:m,strokeWidth:1.5,dot:!1,isAnimationActive:!1})]}):t.jsxs(C,{data:d,margin:{top:1,right:1,bottom:1,left:1},children:[o&&t.jsx(N,{content:t.jsx(he,{}),cursor:{stroke:"rgba(255,255,255,0.2)",strokeWidth:1}}),t.jsx(k,{type:"monotone",dataKey:"count",stroke:m,strokeWidth:1.5,dot:!1,isAnimationActive:!1})]})})})});function xe(e,t,s,a){const n=(s-e)*Math.PI/180,r=(a-t)*Math.PI/180,l=Math.sin(n/2)*Math.sin(n/2)+Math.cos(e*Math.PI/180)*Math.cos(s*Math.PI/180)*Math.sin(r/2)*Math.sin(r/2);return 2*Math.atan2(Math.sqrt(l),Math.sqrt(1-l))*6371e3}const ue=Object.freeze(Object.defineProperty({__proto__:null,default:function(){const{stats:e}=o(),s=c(),a=d(),n=h(),l=m(),i=x(),[j,y]=b.useState(null),[v,f]=b.useState("lastHeard"),[N,w]=b.useState("desc"),[k,C]=b.useState(""),[S,H]=b.useState(!1),[L,_]=b.useState(null),[$,B]=b.useState(null),I=b.useMemo(()=>(null==e?void 0:e.neighbors)??{},[null==e?void 0:e.neighbors]),J=b.useMemo(()=>Object.fromEntries(Object.entries(I).filter(([e])=>!s.has(e))),[I,s]),Q=b.useMemo(()=>{var t;return(null==(t=null==e?void 0:e.config)?void 0:t.repeater)?{latitude:e.config.repeater.latitude,longitude:e.config.repeater.longitude,name:e.config.node_name||"Local Node"}:void 0},[e]),ee=null==e?void 0:e.local_hash,te=b.useMemo(()=>{const e=new Map;if(!(null==Q?void 0:Q.latitude)||!(null==Q?void 0:Q.longitude))return e;for(const[t,s]of Object.entries(J))s.latitude&&s.longitude&&0!==s.latitude&&0!==s.longitude?e.set(t,xe(Q.latitude,Q.longitude,s.latitude,s.longitude)):e.set(t,null);return e},[J,Q]),{neighborHashSet:se,neighborSignalMap:re}=b.useMemo(()=>{const e=new Set,t=new Map;for(const s of i)e.add(s.hash),t.set(s.hash,{avgRssi:s.avgRssi,avgSnr:s.avgSnr});return{neighborHashSet:e,neighborSignalMap:t}},[i]),le=b.useMemo(()=>{const e=k.toLowerCase().trim(),t="neighbor"===e||"neighbors"===e,s=S||t;return Object.fromEntries(Object.entries(J).filter(([a,n])=>{if(s&&!se.has(a))return!1;if(t)return!0;if(!e)return!0;const r=(n.node_name||n.name||"").toLowerCase(),l=a.slice(2,4).toLowerCase();return r.includes(e)||l.includes(e)||a.toLowerCase().includes(e)}))},[J,k,S,se]),ie=b.useMemo(()=>Object.entries(le).sort(([e,t],[s,a])=>{let n=0;switch(v){case"lastHeard":n=(t.last_seen||0)-(a.last_seen||0);break;case"distance":{const t=te.get(e)??null,a=te.get(s)??null;n=null===t&&null===a?0:null===t?1:null===a?-1:t-a;break}case"centrality":n=(l.get(e)||0)-(l.get(s)||0)}return"desc"===N?-n:n}),[le,v,N,te,l]),oe=ie.filter(([,e])=>e.latitude&&e.longitude&&0!==e.latitude&&0!==e.longitude).length,ce=b.useMemo(()=>new Set(n),[n]),de=b.useCallback(e=>{v===e?w(e=>"desc"===e?"asc":"desc"):(f(e),w("desc"))},[v]),he=b.useCallback(e=>{const t=J[e];(null==t?void 0:t.latitude)&&(null==t?void 0:t.longitude)&&0!==t.latitude&&0!==t.longitude&&_(e)},[J]),ue=b.useCallback(()=>{_(null)},[]);return t.jsxs(T,{children:[t.jsx(O,{title:"Contacts",icon:t.jsx(q,{}),controls:t.jsxs("div",{className:"flex items-baseline gap-3 sm:gap-4",children:[t.jsxs("span",{className:"roster-title tabular-nums",children:[ie.length," node",1!==ie.length?"s":""]}),oe>0&&t.jsxs("span",{className:"roster-title flex items-baseline gap-1.5 tabular-nums",children:[t.jsx(A,{className:"w-3.5 h-3.5 relative top-[2px]"}),oe," with location"]})]})}),t.jsx("div",{className:"relative",children:t.jsx(X,{neighbors:J,localNode:Q,localHash:ee,onRemoveNode:a,selectedNodeHash:L,onNodeSelected:ue,highlightedEdgeKey:$})}),t.jsx(ae,{maxPaths:10,highlightedEdge:$,onHighlightEdge:B}),t.jsxs(z,{noPadding:!0,children:[t.jsx(F,{listHeader:!0,icon:t.jsx(q,{className:"icon-sm"}),title:"Discovered Contacts",actions:t.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[se.size>0&&t.jsxs("button",{onClick:()=>H(!S),className:"flex items-center gap-1.5 px-2.5 py-1.5 text-xs rounded-lg transition-colors min-h-[32px] order-1 sm:order-1 "+(S?"bg-accent-success/20 text-accent-success border border-accent-success/30":"text-text-muted hover:text-text-secondary hover:bg-white/5 border border-transparent"),title:S?"Show all contacts":"Show only MeshCore neighbors (direct RF contact)",children:[t.jsx(u,{className:"w-3.5 h-3.5"}),t.jsx("span",{className:"hidden sm:inline",children:"Neighbors"}),t.jsx("span",{className:"sm:hidden",children:se.size}),S&&t.jsx("span",{className:"text-[10px] font-semibold tabular-nums",children:se.size})]}),t.jsxs("div",{className:"relative order-2 sm:order-2",children:[t.jsx(G,{className:"absolute left-2.5 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-text-muted"}),t.jsx("input",{type:"text",value:k,onChange:e=>C(e.target.value),placeholder:"Search...",className:"w-28 sm:w-32 pl-7 pr-7 py-1.5 text-xs bg-white/5 border border-white/10 rounded-lg text-text-primary placeholder:text-text-muted focus:outline-none focus:border-accent-primary/50"}),k&&t.jsx("button",{onClick:()=>{C(""),"neighbor"!==k.toLowerCase().trim()&&"neighbors"!==k.toLowerCase().trim()||H(!1)},className:"absolute right-2 top-1/2 -translate-y-1/2 text-text-muted hover:text-text-secondary p-0.5",children:t.jsx(r,{className:"w-3.5 h-3.5"})})]}),t.jsxs("div",{className:"flex items-center gap-1 order-1 sm:order-2",children:[t.jsxs("button",{onClick:()=>de("lastHeard"),className:"flex items-center gap-1 px-2.5 py-1.5 text-xs rounded-lg transition-colors min-h-[32px] "+("lastHeard"===v?"bg-accent-primary/20 text-accent-primary":"text-text-muted hover:text-text-secondary hover:bg-white/5"),title:"Sort by last heard",children:[t.jsx(p,{className:"w-3.5 h-3.5"}),t.jsx("span",{className:"hidden sm:inline",children:"Recent"}),"lastHeard"===v&&t.jsx(D,{className:"w-3 h-3 "+("asc"===N?"rotate-180":"")})]}),t.jsxs("button",{onClick:()=>de("distance"),className:"flex items-center gap-1 px-2.5 py-1.5 text-xs rounded-lg transition-colors min-h-[32px] "+("distance"===v?"bg-accent-primary/20 text-accent-primary":"text-text-muted hover:text-text-secondary hover:bg-white/5"),title:"Sort by distance",children:[t.jsx(U,{className:"w-3.5 h-3.5"}),t.jsx("span",{className:"hidden sm:inline",children:"Distance"}),"distance"===v&&t.jsx(D,{className:"w-3 h-3 "+("asc"===N?"rotate-180":"")})]}),t.jsxs("button",{onClick:()=>de("centrality"),className:"flex items-center gap-1 px-2.5 py-1.5 text-xs rounded-lg transition-colors min-h-[32px] "+("centrality"===v?"bg-accent-primary/20 text-accent-primary":"text-text-muted hover:text-text-secondary hover:bg-white/5"),title:"Sort by network centrality",children:[t.jsx(E,{className:"w-3.5 h-3.5"}),t.jsx("span",{className:"hidden sm:inline",children:"Centrality"}),"centrality"===v&&t.jsx(D,{className:"w-3 h-3 "+("asc"===N?"rotate-180":"")})]})]})]})}),ie.length>0?t.jsx("div",{className:"roster-list",children:ie.map(([e,s],a)=>{var n,r;const i=s.latitude&&s.longitude&&0!==s.latitude&&0!==s.longitude,o=s.node_name||s.name||"Unknown",c=ce.has(e),d=se.has(e),h=te.get(e),m=l.get(e)||0,x=d?re.get(e):void 0,u=d&&x;return t.jsxs("div",{children:[t.jsxs("div",{className:`roster-row ${c?"bg-amber-500/5 border-l-2 border-l-amber-400":""} ${i?"cursor-pointer hover:bg-white/[0.02]":""}`,onClick:()=>he(e),children:[t.jsxs("div",{className:"relative flex-shrink-0",children:[t.jsx("div",{className:"roster-icon",children:(()=>{var e;const a=null==(e=s.contact_type)?void 0:e.toLowerCase(),n="room server"===a||"room_server"===a||"room"===a||"server"===a,r="companion"===a||"client"===a||"cli"===a,l=s.is_repeater||"repeater"===a||"rep"===a,i="#4338CA",o="#F59E0B";return n&&l?t.jsxs("div",{className:"relative w-5 h-5",children:[t.jsx(W,{className:"w-5 h-5 absolute inset-0",style:{color:o}}),t.jsx(Z,{className:"w-2.5 h-2.5 absolute -bottom-0.5 -right-0.5",style:{color:i}})]}):n?t.jsx(W,{className:"w-5 h-5",style:{color:o}}):r?t.jsx(V,{className:"w-5 h-5 text-text-muted"}):l?d?t.jsx(K,{className:"w-5 h-5 text-accent-success"}):t.jsx(Z,{className:"w-5 h-5",style:{color:i}}):t.jsx(V,{className:"w-5 h-5 text-text-muted"})})()}),u&&null!==(null==x?void 0:x.avgSnr)&&t.jsx("div",{className:`absolute -top-0.5 -right-0.5 w-2.5 h-2.5 rounded-full ${b=x.avgSnr,void 0===b?"bg-[var(--signal-unknown)]":b>=5?"bg-[var(--signal-excellent)]":b>=0?"bg-[var(--signal-good)]":b>=-5?"bg-[var(--signal-fair)]":b>=-10?"bg-[var(--signal-poor)]":"bg-[var(--signal-critical)]"} border-2 border-bg-surface`})]}),t.jsxs("div",{className:"roster-content min-w-0 flex-1",children:[t.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[t.jsx("span",{className:"roster-title",children:o}),d&&t.jsx("span",{className:"type-badge px-1.5 py-0.5 rounded",style:{backgroundColor:"rgba(57, 217, 138, 0.2)",color:"#39D98A"},children:"NBR"}),c&&t.jsxs("span",{className:"type-badge px-1.5 py-0.5 rounded flex items-center gap-1",style:{backgroundColor:"rgba(251, 191, 36, 0.2)",color:"#FBBF24"},children:[t.jsx(R,{className:"w-3 h-3"}),"HUB"]}),(s.is_repeater||"repeater"===(null==(n=s.contact_type)?void 0:n.toLowerCase())||"rep"===(null==(r=s.contact_type)?void 0:r.toLowerCase()))&&t.jsx("span",{className:"pill-tag",children:"RPT"})]}),t.jsx("div",{className:"hidden md:block",children:t.jsx(P,{hash:e,size:"sm",full:!0})}),t.jsx("div",{className:"md:hidden",children:t.jsx(P,{hash:e,size:"sm",prefixLength:8,suffixLength:6})})]}),t.jsxs("div",{className:"roster-metrics flex-shrink-0",children:[u&&null!==(null==x?void 0:x.avgRssi)&&t.jsxs("div",{className:"flex items-center gap-1.5",children:[t.jsx(M,{rssi:x.avgRssi,className:"w-3.5 h-3.5"}),t.jsx("span",{className:"type-data-xs tabular-nums",children:Math.round(x.avgRssi)})]}),u&&null!==(null==x?void 0:x.avgSnr)&&t.jsx("div",{className:"flex items-center gap-1.5",children:t.jsxs("span",{className:"type-data-xs tabular-nums",children:[x.avgSnr.toFixed(1)," dB"]})}),null!=h&&t.jsxs("div",{className:"flex items-center gap-1 text-accent-tertiary",children:[t.jsx(U,{className:"w-3 h-3"}),t.jsx("span",{className:"type-data-xs tabular-nums",children:(p=h,p<1e3?`${Math.round(p)}m`:`${(p/1e3).toFixed(1)}km`)})]}),m>0&&t.jsxs("div",{className:"flex items-center gap-1 text-amber-400/70",children:[t.jsx(E,{className:"w-3 h-3"}),t.jsxs("span",{className:"type-data-xs tabular-nums",children:[(100*m).toFixed(0),"%"]})]}),t.jsx("div",{className:"hidden sm:block",children:t.jsx(me,{nodeHash:e,width:48,height:16})})]}),t.jsx("div",{className:"roster-metric flex-shrink-0",children:s.last_seen?g(s.last_seen):"—"}),t.jsx("button",{onClick:t=>{t.stopPropagation(),y({hash:e,name:o})},className:"ml-2 p-1.5 rounded-lg text-text-muted/50 hover:text-red-400 hover:bg-red-500/10 transition-colors flex-shrink-0",title:"Remove contact",children:t.jsx(Y,{className:"w-4 h-4"})})]}),a{j&&a(j.hash),y(null)},onCancel:()=>y(null)})]})}},Symbol.toStringTag,{value:"Module"}));export{ne as C,I as G,W as M,me as N,Y as T,ue as a}; diff --git a/frontend/dist/assets/ContactsMapMapLibre-BG6tbEVu.js b/frontend/dist/assets/ContactsMapMapLibre-BG6tbEVu.js new file mode 100644 index 00000000..cd72e785 --- /dev/null +++ b/frontend/dist/assets/ContactsMapMapLibre-BG6tbEVu.js @@ -0,0 +1 @@ +var e,t,n=Object.defineProperty,r=(e,t,r)=>((e,t,r)=>t in e?n(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r)(e,"symbol"!=typeof t?t+"":t,r);import{c as s,j as i,I as o,X as a,_ as l,ag as c,ah as u,f as h,ai as d}from"./index-BJveXym2.js";import{b as f,g as p,c as g,r as m}from"./recharts-bmHCCfxU.js";import{u as _,S as y,L as b,a as v,P as x,M as w,N as E,b as T}from"./maplibre-gl-VvZVTf3N.js";import{G as S,N as A,T as R,M as C,C as k}from"./Contacts-D_vTGYlD.js";import{a as P,C as I}from"./HashBadge-C9wBwTs9.js";import{L as M}from"./loader-circle-D2VmbXOw.js";import{I as N}from"./info-CrsYI7df.js";import{H as L}from"./house-Bm0hez83.js";import{R as O}from"./refresh-cw-B7_ETcHC.js";import{N as F}from"./trending-up-D3G9fnzg.js";import{M as D}from"./map-BrPyYvjH.js";import"./maplibre-gl-CFO9X1Ek.js";import"./SignalIndicator-Dsxq994J.js";import"./triangle-alert-DoYB0rUo.js";import"./zap-BuJA7oRW.js";import"./activity-Bw-7kQZI.js";import"./PageLayout-Bo02yEFi.js";import"./users-CVDQWeBL.js";const B=s("car",[["path",{d:"M19 17h2c.6 0 1-.4 1-1v-3c0-.9-.7-1.7-1.5-1.9C18.7 10.6 16 10 16 10s-1.3-1.4-2.2-2.3c-.5-.4-1.1-.7-1.8-.7H5c-.6 0-1.1.4-1.4.9l-1.4 2.9A3.7 3.7 0 0 0 2 12v4c0 .6.4 1 1 1h2",key:"5owen"}],["circle",{cx:"7",cy:"17",r:"2",key:"u2ysq9"}],["path",{d:"M9 17h6",key:"r8uit2"}],["circle",{cx:"17",cy:"17",r:"2",key:"axvx0g"}]]),U=s("chart-no-axes-column",[["path",{d:"M5 21v-6",key:"1hz6c0"}],["path",{d:"M12 21V3",key:"1lcnhd"}],["path",{d:"M19 21V9",key:"unv183"}]]),j=s("chevrons-left-right-ellipsis",[["path",{d:"M12 12h.01",key:"1mp3jc"}],["path",{d:"M16 12h.01",key:"1l6xoz"}],["path",{d:"m17 7 5 5-5 5",key:"1xlxn0"}],["path",{d:"m7 7-5 5 5 5",key:"19njba"}],["path",{d:"M8 12h.01",key:"czm47f"}]]),G=s("circle-alert",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["line",{x1:"12",x2:"12",y1:"8",y2:"12",key:"1pkeuh"}],["line",{x1:"12",x2:"12.01",y1:"16",y2:"16",key:"4dfq90"}]]),V=s("database",[["ellipse",{cx:"12",cy:"5",rx:"9",ry:"3",key:"msslwz"}],["path",{d:"M3 5V19A9 3 0 0 0 21 19V5",key:"1wlel7"}],["path",{d:"M3 12A9 3 0 0 0 21 12",key:"mv7ke4"}]]),z=s("download",[["path",{d:"M12 15V3",key:"m9g1x1"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["path",{d:"m7 10 5 5 5-5",key:"brsn70"}]]),W=s("external-link",[["path",{d:"M15 3h6v6",key:"1q9fwt"}],["path",{d:"M10 14 21 3",key:"gplh6r"}],["path",{d:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6",key:"a6xqqp"}]]),H=s("eye-off",[["path",{d:"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49",key:"ct8e1f"}],["path",{d:"M14.084 14.158a3 3 0 0 1-4.242-4.242",key:"151rxh"}],["path",{d:"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143",key:"13bj9a"}],["path",{d:"m2 2 20 20",key:"1ooewy"}]]),$=s("eye",[["path",{d:"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0",key:"1nclc0"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]]),X=s("maximize-2",[["path",{d:"M15 3h6v6",key:"1q9fwt"}],["path",{d:"m21 3-7 7",key:"1l2asr"}],["path",{d:"m3 21 7-7",key:"tjx5ai"}],["path",{d:"M9 21H3v-6",key:"wtvkvv"}]]),q=s("minimize-2",[["path",{d:"m14 10 7-7",key:"oa77jy"}],["path",{d:"M20 10h-6V4",key:"mjg0md"}],["path",{d:"m3 21 7-7",key:"tjx5ai"}],["path",{d:"M4 14h6v6",key:"rmj7iw"}]]);function Y(e,t){const n=Math.max(5,Math.min(e,300)),r=Math.log(5),s=Math.log(300);return 1+(Math.log(n)-r)/(s-r)*5}const K="#4338CA";function Z({label:e,icon:t,status:n,detail:r}){return i.jsxs("div",{className:g("flex items-center gap-3 py-3 px-4 rounded-xl transition-all duration-300","active"===n&&"bg-[#4338CA]/10","complete"===n&&"bg-accent-success/10","pending"===n&&"opacity-40"),children:[i.jsx("div",{className:g("w-8 h-8 rounded-full flex items-center justify-center flex-shrink-0 transition-all duration-300","active"===n&&"bg-[#4338CA]/20","complete"===n&&"bg-accent-success/20","pending"===n&&"bg-white/5"),children:"complete"===n?i.jsx(P,{className:"w-4 h-4 text-accent-success"}):"active"===n?i.jsx(M,{className:"w-4 h-4 animate-spin",style:{color:K}}):i.jsx("span",{className:"text-text-muted",children:t})}),i.jsxs("div",{className:"flex-1 min-w-0",children:[i.jsx("div",{className:g("text-sm font-medium transition-colors","active"===n&&"text-[#4338CA]","complete"===n&&"text-accent-success","pending"===n&&"text-text-muted"),children:e}),r&&"pending"!==n&&i.jsx("div",{className:"text-xs text-text-muted mt-0.5 truncate",children:r})]})]})}const Q=f.memo(function({isOpen:e,currentStep:t,packetCount:n,onClose:r}){if(f.useEffect(()=>{if(!e)return;const t=e=>{"Escape"===e.key&&r&&r()};window.addEventListener("keydown",t);const n=document.body.style.overflow,s=document.body.style.position,i=document.body.style.width,o=document.body.style.top,a=window.scrollY;return document.body.style.overflow="hidden",document.body.style.position="fixed",document.body.style.width="100%",document.body.style.top=`-${a}px`,()=>{window.removeEventListener("keydown",t),document.body.style.overflow=n,document.body.style.position=s,document.body.style.width=i,document.body.style.top=o,window.scrollTo(0,a)}},[e,r]),!e)return null;const s="complete"===t,o=e=>{const n=["fetching","analyzing","building","complete"],r=n.indexOf(t),s=n.indexOf(e);return s0?`${n.toLocaleString()} packets`:"Loading database..."}),i.jsx(Z,{label:"Analyzing Database",icon:i.jsx(V,{className:"w-4 h-4"}),status:o("analyzing"),detail:"Processing packet paths"}),i.jsx(Z,{label:"Building Topology",icon:i.jsx(S,{className:"w-4 h-4"}),status:o("building"),detail:"Computing mesh edges"})]}),i.jsx("p",{className:"text-xs text-text-muted text-center mt-5",children:"This may take a few seconds..."})]})})]}),document.body)}),J="#4338CA",ee="#FBBF24",te="#6366F1",ne="#F97316",re="#F59E0B",se="#FBBF24",ie="#4B5563",oe="#6B7280",ae="#374151",le="#5EEAD4",ce="#6366F1",ue="#9CA3AF",he="#6B7280",de="#FBBF24",fe=2e3;function pe({text:e}){return i.jsxs("span",{className:"group relative cursor-help",children:[i.jsx(N,{className:"w-3 h-3 text-text-muted"}),i.jsx("div",{className:"absolute bottom-full left-0 mb-1 hidden group-hover:block w-44 p-2 text-[10px] leading-tight rounded-lg z-10",style:{background:"rgba(20, 20, 22, 0.98)",border:"1px solid rgba(140, 160, 200, 0.3)"},children:e})]})}function ge(e){const t=new Date(1e3*e);return`${(t.getMonth()+1).toString().padStart(2,"0")}/${t.getDate().toString().padStart(2,"0")}`}function me({hash:e,hashPrefix:t,name:n,isHub:r,isZeroHop:s,isMobile:a,isRoomServer:l,isStale:c,lastSeenTimestamp:u,centrality:h,affinity:d,meanSnr:p,meanRssi:g,neighbor:m,onRemove:_,txDelayRec:y}){const[b,v]=f.useState(!1),x=s?"Direct":(null==d?void 0:d.typicalHopPosition)?`${d.typicalHopPosition}-hop`:null,w=[{label:"Packets",value:(null==d?void 0:d.frequency)||0},{label:"Adverts",value:m.advert_count||0}];s&&void 0!==p&&w.push({label:"SNR",value:`${p.toFixed(1)} dB`}),s&&void 0!==g&&w.push({label:"RSSI",value:`${Math.round(g)} dBm`});const E=y&&!y.insufficientData,T={hub:{bg:"bg-amber-500/20",text:"text-amber-400",title:"Hub: High-connectivity node (4+ neighbors) that bridges many paths"},backbone:{bg:"bg-purple-500/20",text:"text-purple-400",title:"Backbone: Critical relay with 4+ neighbors and high traffic"},relay:{bg:"bg-cyan-500/20",text:"text-cyan-400",title:"Relay: Standard forwarding node with symmetric traffic"},edge:{bg:"bg-gray-500/20",text:"text-gray-400",title:"Edge: Peripheral node with few connections"}},S={high:{bg:"bg-green-500/20",text:"text-green-400",title:"1000+ packets observed"},medium:{bg:"bg-amber-500/20",text:"text-amber-400",title:"500-999 packets observed"},low:{bg:"bg-red-500/20",text:"text-red-400",title:"100-499 packets observed"},insufficient:{bg:"bg-gray-500/20",text:"text-gray-400",title:"Insufficient data for analysis"}};return i.jsxs("div",{className:"w-[220px] pr-3",children:[i.jsx("div",{className:"text-[14px] font-semibold text-text-primary leading-snug truncate mb-0.5",children:n}),i.jsxs("div",{className:"flex items-center gap-1 flex-wrap mb-1.5",children:[i.jsx("code",{className:"font-mono text-[10px] text-text-muted/70 bg-white/5 px-1 py-px rounded",children:t}),i.jsx("button",{onClick:()=>{navigator.clipboard.writeText(e),v(!0),setTimeout(()=>v(!1),1500)},className:"p-0.5 hover:bg-white/10 rounded transition-colors",title:"Copy full hash",children:b?i.jsx(P,{className:"w-2.5 h-2.5 text-accent-success"}):i.jsx(I,{className:"w-2.5 h-2.5 text-text-muted/50"})}),r&&i.jsx("span",{className:"px-1 py-px text-[8px] font-bold uppercase rounded",style:{backgroundColor:"#FBBF24",color:"#000"},children:"Hub"}),x&&i.jsx("span",{className:"px-1 py-px text-[8px] font-bold uppercase rounded",style:{backgroundColor:s?se:"rgba(255,255,255,0.08)",color:s?"#000":"rgba(255,255,255,0.5)"},children:x}),a&&i.jsx("span",{className:"px-1 py-px text-[8px] font-bold uppercase rounded bg-orange-500/25 text-orange-300",children:"Mobile"}),m.is_repeater&&i.jsx("span",{className:"px-1 py-px text-[8px] font-bold uppercase rounded bg-cyan-500/20 text-cyan-400",children:"Rptr"}),l&&i.jsx("span",{className:"px-1 py-px text-[8px] font-bold uppercase rounded bg-amber-500/25 text-amber-400",children:"Room"}),c&&u&&i.jsxs("span",{className:"px-1 py-px text-[8px] font-medium rounded bg-gray-500/30 text-gray-300",title:"Neighbor not heard in 7+ days",children:["Idle ",ge(u)]})]}),i.jsxs("div",{className:"text-[10px] text-text-muted/60 mb-2 leading-tight",children:[i.jsx("span",{children:o(m.last_seen)}),(null==d?void 0:d.distanceMeters)&&i.jsxs("span",{className:"font-medium text-text-muted/80",children:[" · ",(C=d.distanceMeters,null===C?"—":C<1e3?`${Math.round(C)}m`:`${(C/1e3).toFixed(1)}km`)]}),m.latitude&&m.longitude&&0!==m.latitude&&0!==m.longitude&&i.jsxs("span",{className:"font-mono text-[9px]",children:[" · ",m.latitude.toFixed(4),", ",m.longitude.toFixed(4)]})]}),i.jsx("div",{className:"mb-2",children:i.jsx(A,{nodeHash:e,width:"100%",height:28,showArea:!0,showTooltip:!0})}),i.jsxs("div",{className:"grid grid-cols-2 gap-x-4 gap-y-0.5 text-[11px] mb-2",children:[w.map((e,t)=>i.jsxs("div",{className:"flex justify-between",children:[i.jsx("span",{className:"text-text-muted/50",children:e.label}),i.jsx("span",{className:"font-semibold tabular-nums "+("highlight"in e&&e.highlight?"text-amber-400":""),children:e.value})]},t)),E&&y.networkRole&&i.jsx(i.Fragment,{children:i.jsxs("div",{className:"flex items-center justify-between col-span-2 mt-1 pt-1 border-t border-white/5",children:[i.jsxs("div",{className:"flex items-center gap-1",children:[i.jsx("span",{className:"text-text-muted/50",children:"Role"}),i.jsx("span",{className:`px-1.5 py-px text-[8px] font-bold uppercase rounded ${T[y.networkRole].bg} ${T[y.networkRole].text}`,title:T[y.networkRole].title,children:y.networkRole})]}),y.dataConfidence&&i.jsxs("div",{className:"flex items-center gap-1",children:[i.jsx("span",{className:"text-text-muted/50",children:"Data"}),i.jsx("span",{className:`px-1.5 py-px text-[8px] font-bold uppercase rounded ${S[y.dataConfidence].bg} ${S[y.dataConfidence].text}`,title:S[y.dataConfidence].title,children:y.dataConfidence})]})]})})]}),(E||_)&&i.jsxs("div",{className:"pt-1.5 border-t border-white/5",children:[E&&i.jsxs("div",{className:"flex items-center gap-2 text-[10px]",children:[i.jsx("span",{className:"text-text-muted/50",children:"TX Delay"}),i.jsxs("span",{className:"font-semibold tabular-nums text-amber-400",children:["×",(y.floodFactor??y.txDelayFactor).toFixed(1)]}),i.jsx("span",{className:"text-text-muted/30",children:"flood"}),i.jsxs("span",{className:"font-semibold tabular-nums text-amber-400",children:["×",(y.directFactor??y.directTxDelayFactor).toFixed(1)]}),i.jsx("span",{className:"text-text-muted/30",children:"direct"})]}),_&&i.jsx("div",{className:"flex justify-end "+(E?"mt-1.5":""),children:i.jsx("button",{onClick:_,className:"flex items-center gap-0.5 p-1 text-[10px] text-text-muted/30 hover:text-red-400 hover:bg-red-500/10 rounded transition-colors",title:"Remove from contacts",children:i.jsx(R,{className:"w-3 h-3"})})})]})]});var C}function _e({showTopology:e,validatedPolylineCount:t,filteredNeighborCount:n,hasLocalNode:r,meshTopology:s,zeroHopNeighbors:o,neighborsWithLocation:a}){return i.jsxs("div",{className:"absolute bottom-4 left-4 z-[600] text-xs",style:{background:"rgba(20, 20, 22, 0.95)",borderRadius:"0.75rem",padding:"0.625rem",border:"1px solid rgba(140, 160, 200, 0.2)",maxWidth:"150px"},children:[i.jsxs("div",{className:"text-text-secondary font-medium mb-1.5 flex items-center gap-1",children:["Nodes",i.jsx(pe,{text:"Node type shown by shape/color. Yellow outer ring = direct RF neighbor."})]}),i.jsxs("div",{className:"flex flex-col gap-1",children:[i.jsxs("div",{className:"flex items-center gap-1.5",children:[i.jsx("div",{className:"rounded-full flex-shrink-0",style:{width:"12px",height:"12px",background:"transparent",border:`4px solid ${J}`,boxSizing:"border-box"}}),i.jsx("span",{className:"text-text-muted",children:"Node"}),i.jsx(pe,{text:"Standard mesh node. Can be a repeater, client, or companion device."})]}),s.gatewayNodes.length>0&&i.jsxs("div",{className:"flex items-center gap-1.5",children:[i.jsx("div",{className:"rounded-full flex-shrink-0",style:{width:"12px",height:"12px",backgroundColor:J}}),i.jsx("span",{className:"text-text-muted",children:"Gateway"}),i.jsx(pe,{text:"Significant traffic forwarder (7-10% of last-hop traffic). Gateways relay substantial traffic to the local node."})]}),i.jsxs("div",{className:"flex items-center gap-1.5",children:[i.jsx("div",{className:"rounded-full flex-shrink-0",style:{width:"12px",height:"12px",backgroundColor:te}}),i.jsx("span",{className:"text-text-muted",children:"Hub"}),i.jsx(pe,{text:"Network hub (≥10% of last-hop traffic). Hubs are central to mesh traffic flow and may use higher TX delays."})]}),i.jsxs("div",{className:"flex items-center gap-1.5",children:[i.jsx(L,{className:"w-3 h-3 flex-shrink-0",style:{color:ee},strokeWidth:2.5}),i.jsx("span",{className:"text-text-muted",children:"Local"}),i.jsx(pe,{text:"Your repeater. This is the node running pyMC_Repeater that you're connected to."})]}),(l=a,l.some(([,e])=>{var t;const n=null==(t=e.contact_type)?void 0:t.toLowerCase();return"room server"===n||"room_server"===n||"room"===n||"server"===n})&&i.jsxs("div",{className:"flex items-center gap-1.5",children:[i.jsx(C,{className:"w-3 h-3 flex-shrink-0",style:{color:re},strokeWidth:2.5}),i.jsx("span",{className:"text-text-muted",children:"Room"}),i.jsx(pe,{text:"Room Server identity. Hosts a chat room that clients can sync messages with."})]})),s.mobileNodes.length>0&&i.jsxs("div",{className:"flex items-center gap-1.5",children:[i.jsx("div",{className:"rounded-full flex-shrink-0",style:{width:"12px",height:"12px",background:"transparent",border:`4px solid ${ne}`,boxSizing:"border-box"}}),i.jsx("span",{className:"text-text-muted",children:"Mobile"}),i.jsx(pe,{text:"Volatile node that frequently appears/disappears from paths. Likely a portable or vehicle-mounted device."})]}),o.size>0&&i.jsxs("div",{className:"flex items-center gap-1.5",children:[i.jsxs("div",{className:"relative flex-shrink-0",style:{width:"14px",height:"14px"},children:[i.jsx("div",{className:"absolute rounded-full",style:{top:"-2px",left:"-2px",width:"18px",height:"18px",background:"transparent",border:`2px solid ${se}`,boxSizing:"border-box",opacity:.85}}),i.jsx("div",{className:"absolute rounded-full",style:{top:"1px",left:"1px",width:"12px",height:"12px",background:"transparent",border:`4px solid ${J}`,boxSizing:"border-box"}})]}),i.jsx("span",{className:"text-text-muted",children:"Neighbor"}),i.jsx(pe,{text:"Zero-hop direct RF contact. We receive their ADVERTs directly without any relay hops."})]})]}),o.size>0&&i.jsx("div",{className:"mt-1.5 pt-1.5 border-t border-white/10",children:i.jsxs("div",{className:"flex items-center gap-1.5",children:[i.jsx("div",{className:"flex-shrink-0",style:{width:"14px",height:"2px",backgroundImage:`repeating-linear-gradient(90deg, ${he} 0, ${he} 3px, transparent 3px, transparent 5px)`,borderRadius:"1px"}}),i.jsx("span",{className:"text-text-muted",children:"Neighbor"}),i.jsx(pe,{text:"Dashed gray → yellow on hover. Direct RF contact with local."})]})}),e&&t>0&&i.jsxs(i.Fragment,{children:[i.jsxs("div",{className:"text-text-secondary font-medium mt-2 pt-2 border-t border-white/10 mb-1 flex items-center gap-1",children:["Topology",i.jsx(pe,{text:"Links with 5+ validations. Thickness = relative strength."})]}),i.jsxs("div",{className:"flex flex-col gap-0.5 text-text-muted",children:[i.jsxs("div",{className:"flex justify-between tabular-nums",children:[i.jsx("span",{children:"Nodes"}),i.jsx("span",{className:"text-text-secondary",children:n+(r?1:0)})]}),i.jsxs("div",{className:"flex justify-between tabular-nums",children:[i.jsx("span",{children:"Links"}),i.jsx("span",{className:"text-text-secondary",children:t})]}),s.hubNodes.length>0&&i.jsxs("div",{className:"flex justify-between tabular-nums",children:[i.jsx("span",{children:"Hubs"}),i.jsx("span",{style:{color:te},children:s.hubNodes.length})]})]}),i.jsxs("div",{className:"flex flex-col gap-1 mt-1.5 pt-1.5 border-t border-white/10",children:[i.jsxs("div",{className:"flex items-center gap-1.5",children:[i.jsx("div",{className:"flex-shrink-0",style:{width:"14px",height:"3px",backgroundColor:ie,borderRadius:"1px"}}),i.jsx("span",{className:"text-text-muted",children:"Link"}),i.jsx(pe,{text:"Gray at rest. Hover to reveal type (teal=direct, indigo=loop)."})]}),s.loops.length>0&&i.jsxs("div",{className:"flex items-center gap-1.5",children:[i.jsxs("div",{className:"flex-shrink-0 flex flex-col gap-0.5",style:{width:"14px"},children:[i.jsx("div",{style:{height:"2px",backgroundColor:ie,borderRadius:"1px"}}),i.jsx("div",{style:{height:"2px",backgroundColor:ie,borderRadius:"1px"}})]}),i.jsx("span",{className:"text-text-muted",children:"Redundant"})]})]}),s.loops.length>0&&i.jsx("div",{className:"mt-1.5 pt-1.5 border-t border-white/10",children:i.jsxs("div",{className:"flex items-center gap-1.5",children:[i.jsx(O,{className:"w-3 h-3 flex-shrink-0",style:{color:ce}}),i.jsxs("div",{className:"flex flex-col",children:[i.jsxs("span",{style:{color:ce},className:"font-medium",children:[s.loops.length," ",1===s.loops.length?"Loop":"Loops"]}),i.jsx("span",{className:"text-text-muted text-[10px] leading-tight",children:"Redundant paths"})]})]})})]})]});var l}const ye={background:"rgba(20, 20, 22, 0.95)",borderRadius:"0.75rem",border:"1px solid rgba(140, 160, 200, 0.2)"},be=(e,t=.4)=>({background:e,borderRadius:"0.75rem",border:`1px solid ${e.replace(/[\d.]+\)$/,`${t})`)}`});function ve({isDeepLoading:e,showDeepAnalysisModal:t,onDeepAnalysis:n,showTopology:r,onToggleTopology:s,hasValidatedPolylines:o,soloHubs:a,onToggleSoloHubs:l,hasHubNodes:c,soloDirect:u,onToggleSoloDirect:h,hasZeroHopNeighbors:d,isFullscreen:f,onToggleFullscreen:p}){return i.jsxs("div",{className:"absolute top-4 right-4 z-[600] flex gap-2",children:[i.jsxs("button",{onClick:n,disabled:e||t,className:"px-3 py-2 flex items-center gap-2 transition-colors hover:bg-white/10 disabled:opacity-50 disabled:cursor-not-allowed",style:ye,title:"Deep Analysis - Load full packet history and rebuild topology",children:[i.jsx("span",{className:"text-xs font-medium text-text-primary",children:"Deep Analysis"}),i.jsx(U,{className:"w-4 h-4 text-accent-primary"})]}),o&&i.jsx("button",{onClick:s,className:"p-2 transition-colors hover:bg-white/10",style:r?be("rgba(74, 222, 128, 0.2)"):ye,title:r?"Hide topology lines":"Show topology lines",children:r?i.jsx(S,{className:"w-4 h-4 text-green-400"}):i.jsx(H,{className:"w-4 h-4 text-text-secondary"})}),c&&i.jsx("button",{onClick:l,className:"p-2 transition-colors hover:bg-white/10",style:a?{...ye,background:"rgba(251, 191, 36, 0.25)",border:"1px solid rgba(251, 191, 36, 0.5)"}:ye,title:a?"Show all nodes":"Solo hubs & connections",children:i.jsx(F,{className:"w-4 h-4 "+(a?"text-amber-400":"text-text-secondary")})}),d&&i.jsx("button",{onClick:h,className:"p-2 transition-colors hover:bg-white/10",style:u?{...ye,background:"rgba(67, 56, 202, 0.35)",border:"1px solid rgba(67, 56, 202, 0.6)"}:ye,title:u?"Show all nodes":"Solo direct (0-hop) nodes",children:i.jsx(j,{className:"w-4 h-4 "+(u?"text-indigo-400":"text-text-secondary")})}),i.jsx("button",{onClick:p,className:"p-2 transition-colors hover:bg-white/10",style:ye,title:f?"Exit fullscreen":"Fullscreen",children:f?i.jsx(q,{className:"w-4 h-4 text-text-secondary"}):i.jsx(X,{className:"w-4 h-4 text-text-secondary"})})]})}const xe={background:"rgba(20, 20, 22, 0.95)",borderRadius:"0.75rem",border:"1px solid rgba(140, 160, 200, 0.2)"},we={background:"rgba(245, 158, 11, 0.25)",borderRadius:"0.75rem",border:"1px solid rgba(245, 158, 11, 0.5)"};function Ee({isActive:e,onClick:t}){return i.jsx("div",{className:"absolute bottom-8 right-4 z-[600]",children:i.jsx("button",{onClick:t,className:"p-2 transition-colors hover:bg-white/10",style:e?we:xe,title:e?"Configure wardriving coverage":"Show wardriving coverage",children:i.jsx(B,{className:"w-4 h-4 "+(e?"text-amber-400":"text-text-secondary")})})})}function Te({status:e,isLoading:t}){if(!t)return null;const n={idle:"",connecting:"Connecting to server...",loading:"Fetching coverage data...",processing:"Processing coverage points...",success:"",error:""}[e];return n?i.jsxs("div",{className:"flex items-center gap-3 p-4 bg-amber-500/10 border border-amber-500/30 rounded-xl",children:[i.jsx("div",{className:"relative",children:i.jsx(M,{className:"w-5 h-5 text-amber-400 animate-spin"})}),i.jsxs("div",{className:"flex-1",children:[i.jsx("p",{className:"text-sm text-amber-400 font-medium",children:n}),i.jsx("div",{className:"mt-2 h-1 bg-amber-500/20 rounded-full overflow-hidden",children:i.jsx("div",{className:"h-full bg-amber-400 rounded-full transition-all duration-300",style:{width:"connecting"===e?"30%":"loading"===e?"60%":"90%"}})})]})]}):null}function Se({isOpen:e,onClose:t,state:n,isLoading:r,onLoadCoverage:s,onClearCoverage:o,onToggleVisibility:l,onSetUrl:c}){const[u,h]=f.useState(n.url),d=f.useCallback(async()=>{await s(u)},[u,s]),p=f.useCallback(()=>{h(""),o()},[o]),g=f.useCallback(e=>{"Enter"!==e.key||e.shiftKey||r||(e.preventDefault(),d())},[d,r]),m=f.useCallback(e=>{const t=e.target.value;h(t),c(t)},[c]);if(!e)return null;const _=n.stats.coverageCount>0,y=u.trim().length>0&&!r;return i.jsxs("div",{className:"fixed inset-0 z-[1000] flex items-center justify-center",children:[i.jsx("div",{className:"absolute inset-0 bg-black/60 backdrop-blur-sm",onClick:r?void 0:t}),i.jsxs("div",{className:"relative bg-surface border border-border rounded-2xl shadow-2xl w-full max-w-md mx-4 overflow-hidden",children:[i.jsxs("div",{className:"flex items-center justify-between p-4 border-b border-border",children:[i.jsxs("div",{className:"flex items-center gap-3",children:[i.jsx("div",{className:"p-2 rounded-lg bg-amber-500/20",children:i.jsx(B,{className:"w-5 h-5 text-amber-400"})}),i.jsxs("div",{children:[i.jsx("h2",{className:"text-lg font-semibold text-text-primary",children:"Wardriving Coverage"}),i.jsx("p",{className:"text-xs text-text-muted",children:"Overlay RF coverage heatmap"})]})]}),i.jsx("button",{onClick:t,disabled:r,className:"p-2 rounded-lg hover:bg-white/10 transition-colors disabled:opacity-50",children:i.jsx(a,{className:"w-5 h-5 text-text-secondary"})})]}),i.jsxs("div",{className:"p-4 space-y-4",children:[i.jsxs("div",{children:[i.jsx("label",{className:"block text-sm font-medium text-text-secondary mb-2",children:"Coverage Server URL"}),i.jsx("input",{type:"url",value:u,onChange:m,onKeyDown:g,placeholder:"https://coverage.wcmesh.com",className:"w-full px-4 py-3 bg-black/30 border border-border rounded-xl text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-amber-500/50 focus:border-amber-500/50 transition-all disabled:opacity-50",disabled:r}),i.jsx("p",{className:"mt-1.5 text-xs text-text-muted",children:"Enter the base URL of a wardriving coverage server (e.g., coverage.wcmesh.com)"})]}),i.jsx(Te,{status:n.status,isLoading:r}),"error"===n.status&&n.error&&i.jsxs("div",{className:"flex items-start gap-3 p-3 bg-red-500/10 border border-red-500/30 rounded-xl",children:[i.jsx(G,{className:"w-5 h-5 text-red-400 flex-shrink-0 mt-0.5"}),i.jsxs("div",{children:[i.jsx("p",{className:"text-sm text-red-400 font-medium",children:"Connection Failed"}),i.jsx("p",{className:"text-xs text-red-400/80 mt-0.5",children:n.error})]})]}),"success"===n.status&&_&&i.jsxs("div",{className:"flex items-start gap-3 p-3 bg-green-500/10 border border-green-500/30 rounded-xl",children:[i.jsx(P,{className:"w-5 h-5 text-green-400 flex-shrink-0 mt-0.5"}),i.jsxs("div",{className:"flex-1",children:[i.jsx("p",{className:"text-sm text-green-400 font-medium",children:"Data Loaded Successfully"}),i.jsxs("p",{className:"text-xs text-green-400/80 mt-0.5",children:[n.stats.coverageCount.toLocaleString()," coverage points • ",n.stats.repeaterCount.toLocaleString()," repeaters"]})]})]}),_&&!r&&"success"!==n.status&&i.jsxs("div",{className:"flex items-start gap-3 p-3 bg-amber-500/10 border border-amber-500/30 rounded-xl",children:[i.jsx(D,{className:"w-5 h-5 text-amber-400 flex-shrink-0 mt-0.5"}),i.jsxs("div",{className:"flex-1",children:[i.jsx("p",{className:"text-sm text-amber-400 font-medium",children:"Coverage Data Loaded"}),i.jsxs("p",{className:"text-xs text-amber-400/80 mt-0.5",children:[n.stats.coverageCount.toLocaleString()," points •",n.stats.lastUpdated&&` Last updated ${n.stats.lastUpdated.toLocaleTimeString()}`]})]})]})]}),i.jsxs("div",{className:"flex items-center justify-between gap-3 p-4 border-t border-border bg-black/20",children:[i.jsx("div",{className:"flex items-center gap-2",children:_&&i.jsxs(i.Fragment,{children:[i.jsx("button",{onClick:l,disabled:r,className:"flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium text-text-secondary hover:text-text-primary hover:bg-white/5 rounded-lg transition-colors disabled:opacity-50",title:n.isVisible?"Hide heatmap":"Show heatmap",children:n.isVisible?i.jsxs(i.Fragment,{children:[i.jsx(H,{className:"w-3.5 h-3.5"})," Hide"]}):i.jsxs(i.Fragment,{children:[i.jsx($,{className:"w-3.5 h-3.5"})," Show"]})}),i.jsxs("button",{onClick:p,disabled:r,className:"flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium text-red-400/80 hover:text-red-400 hover:bg-red-500/10 rounded-lg transition-colors disabled:opacity-50",title:"Clear coverage data",children:[i.jsx(R,{className:"w-3.5 h-3.5"})," Clear"]})]})}),i.jsxs("div",{className:"flex items-center gap-2",children:[i.jsx("button",{onClick:t,disabled:r,className:"px-4 py-2 text-sm font-medium text-text-secondary hover:bg-white/10 rounded-lg transition-colors disabled:opacity-50",children:_?"Done":"Cancel"}),i.jsx("button",{onClick:d,disabled:!y,className:"flex items-center gap-2 px-4 py-2 text-sm font-medium bg-amber-500 hover:bg-amber-400 text-black rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed",children:r?i.jsxs(i.Fragment,{children:[i.jsx(M,{className:"w-4 h-4 animate-spin"}),"Loading..."]}):_?i.jsxs(i.Fragment,{children:[i.jsx(z,{className:"w-4 h-4"}),"Refresh"]}):i.jsxs(i.Fragment,{children:[i.jsx(W,{className:"w-4 h-4"}),"Connect"]})})]})]})]})]})}function Ae(e){let t=!0,n=-90,r=90,s=-180,i=180;for(const o of e.toLowerCase()){const e="0123456789bcdefghjkmnpqrstuvwxyz".indexOf(o);if(-1!==e)for(let o=4;o>=0;o--){const a=e>>o&1;if(t){const e=(s+i)/2;a?s=e:i=e}else{const e=(n+r)/2;a?n=e:r=e}t=!t}}return{lat:(n+r)/2,lon:(s+i)/2}}function Re(e){const t=function(e){return new Date(6e4*e)}(e);return((new Date).getTime()-t.getTime())/864e5}function Ce(e){return Math.exp(-e*Math.LN2/7)}const ke="pymc-wardriving-url",Pe="pymc-wardriving-enabled";function Ie(e){"undefined"!=typeof localStorage&&(e?localStorage.setItem(ke,e):localStorage.removeItem(ke))}function Me(e){"undefined"!=typeof localStorage&&localStorage.setItem(Pe,String(e))}const Ne="wardriving-heatmap",Le={type:"heatmap",paint:{"heatmap-weight":["interpolate",["linear"],["coalesce",["get","weight"],.5],0,0,.5,.5,1,1],"heatmap-intensity":["interpolate",["linear"],["zoom"],0,.5,9,1,15,2],"heatmap-color":["interpolate",["linear"],["heatmap-density"],0,"rgba(0, 0, 0, 0)",.1,"rgba(65, 105, 225, 0.4)",.3,"rgba(0, 191, 255, 0.5)",.5,"rgba(50, 205, 50, 0.6)",.7,"rgba(255, 215, 0, 0.7)",.85,"rgba(255, 140, 0, 0.8)",1,"rgba(255, 69, 0, 0.9)"],"heatmap-radius":["interpolate",["linear"],["zoom"],0,2,5,10,10,25,15,50],"heatmap-opacity":["interpolate",["linear"],["zoom"],12,.8,15,.6,18,.3]}},Oe={type:"FeatureCollection",features:[]};function Fe(e){return"number"==typeof e.lat&&"number"==typeof e.lon&&!isNaN(e.lat)&&!isNaN(e.lon)&&e.lat>=-90&&e.lat<=90&&e.lon>=-180&&e.lon<=180}function De({coveragePoints:e,visible:t,opacity:n=1}){const{current:r}=_(),s=f.useMemo(()=>{if(!e||!Array.isArray(e)||0===e.length)return Oe;const t=e.filter(Fe);if(0===t.length)return Oe;try{return{type:"FeatureCollection",features:t.map(e=>({type:"Feature",geometry:{type:"Point",coordinates:[e.lon,e.lat]},properties:{weight:e.weight,successRate:e.successRate,totalSamples:e.totalSamples,ageDays:e.ageDays,geohash:e.geohash,repeaters:e.repeaters.join(", ")}}))}}catch(n){return Oe}},[e]),o=f.useCallback(()=>{if(r)try{const e=r.getMap();if(!e)return;if(!e.getLayer(Ne))return;const s=t?n:0;e.setPaintProperty(Ne,"heatmap-opacity",["interpolate",["linear"],["zoom"],12,.8*s,15,.6*s,18,.3*s])}catch(e){}},[r,t,n]);return f.useEffect(()=>{o()},[o]),s.features.length>0?i.jsx(y,{id:"wardriving-coverage",type:"geojson",data:s,children:i.jsx(b,{id:Ne,...Le,layout:{visibility:t?"visible":"none"}})}):null}function Be(e){return e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2}function Ue(e){return e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2}var je,Ge={},Ve={};var ze,We,He={};var $e,Xe,qe=(We||(We=1,$e=function(){if(je)return Ve;je=1;var e=m();function t(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n