Files
pymc_console-dist/frontend/dist/assets/Dashboard-Bbh9RnDT.js
GitHub Actions Bot c8c3f164ee Sync build v0.9.286
Automated sync from private repository.
Commit: fad7f9633de61427bfc2c672b7ddecaa0952d717
2026-02-27 07:48:08 +00:00

2 lines
53 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import{r as e,j as s}from"./vendor-react-alRNW2nb.js";import{u as t,U as a,S as n,c as l,d as i,e as o,f as r,h as c,j as d,k as m,m as u,n as x,o as h,p as f,q as p,T as g,L as b,B as j,r as v,t as y,v as N,D as w,w as k,x as M,y as C,z as S,A as L,E as T,F as B,G as F,H as _,J as R,K as D,M as $,N as H,O as P,P as A,Q as I,R as z,V as E,W,X as q,Y as O,_ as G,$ as V,a0 as U,a1 as J,a2 as K}from"./index-CkRTgHHA.js";import{C as X,P as Q,a as Y,B as Z}from"./PageLayout-BWMUVZgC.js";import{u as ee,r as se,h as te,a as ae,b as ne,i as le}from"./consumer-registry-BUFl6buY.js";import{A as ie,m as oe}from"./vendor-motion-DNp0Qg4F.js";import{c as re,d as ce,q as de,a as me,o as ue,L as xe,r as he,s as fe,A as pe,R as ge,t as be,u as je,v as ve,w as ye,x as Ne,y as we,z as ke,Z as Me,g as Ce,B as Se,D as Le,C as Te,H as Be,J as Fe,K as _e,N as Re,O as De,Q as $e}from"./vendor-icons-TO0PZKGR.js";import{u as He}from"./vendor-charts-C916_-gs.js";import{A as Pe}from"./AnimatedNumber-DACuG-ay.js";import{c as Ae}from"./node-types-DRVunROD.js";import{b as Ie,c as ze,a as Ee,d as We,F as qe}from"./meshcore-tx-constants-BDLT5LMb.js";import{u as Oe,P as Ge,C as Ve}from"./PacketList-BJFBF77t.js";import{u as Ue,a as Je}from"./usePipelineStore-CLEA3Bev.js";import{T as Ke}from"./TimeRangeStepper-CsLZzi5t.js";import{L as Xe}from"./LightSparkline-BAD3v4m9.js";import{c as Qe}from"./link-scoring-C0BjaK96.js";import{b as Ye,c as Ze}from"./vendor-core-FtpmsTnh.js";import{N as es}from"./NodeInformationCard-tOZNdmfP.js";import{g as ss,e as ts,a as as,f as ns}from"./chat-utils-mqGCinix.js";import{C as ls}from"./ChatBubble-OmHlf-X1.js";import{R as is,C as os}from"./Grid-m53vqd2Y.js";import"./vendor-virt-BytWoLhu.js";import"./cosmograph-DqYT4sUA.js";import"./vendor-fonts-CRZaZSFf.js";import"./primitives-Bgn6Ik6L.js";import"./payload-decoders-_TRhCJrs.js";import"./badge-colors-BxLppqaF.js";import"./SignalIndicator-Bdj3-1hL.js";import"./DataBox-DpDXI-WX.js";import"./useMapViewStore-sFZdb1_p.js";import"./geo-utils-DJn8DnxF.js";const rs=[{target:"ReceivedChart",fn:"type",minStage:1},{target:"ReceivedChart",fn:"airtime",minStage:1,when:te}];function cs({packets:l,rangeMinutes:i,bucketCount:o}){ee(rs);const r=t(),[c,d]=e.useState(null),[m,u]=e.useState(null),[x,h]=e.useState(null),{buckets:f,activeTypes:p,totalByType:g}=e.useMemo(()=>function(e,s,t){const a=Date.now()/1e3,n=60*s,l=a-n,i=n/t,o=[];for(let c=0;c<t;c++)o.push({start:l+c*i,end:l+(c+1)*i,bytesByType:{},totalBytes:0});const r={};for(const c of e){if(c.transmitted)continue;const e=c.timestamp;if(e<l||e>a)continue;const s=Math.min(t-1,Math.floor((e-l)/i)),n=c.type??c.payload_type??0,d=c.length??c.payload_length??0,m=o[s];m.bytesByType[n]=(m.bytesByType[n]??0)+d,m.totalBytes+=d,r[n]=(r[n]??0)+d}return{buckets:o,activeTypes:Object.keys(r).map(e=>parseInt(e,10)).filter(e=>r[e]>0).sort((e,s)=>r[s]-r[e]),totalByType:r}}(l,i,o),[l,i,o]),b=e.useCallback((e,s,t)=>{d(s),u(t)},[]),j=f.length>0&&p.length>0,v=c?function(e){const s=new Date(1e3*e).getHours();return s>=6&&s<18}(c.start):null,y=c?(N=c.start,new Date(1e3*N).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",hour12:!1})):"";var N;const w=null!==x&&null!==v&&x!==v;return v!==x&&h(v),s.jsxs("div",{className:"flex flex-col h-full relative",children:[s.jsx("div",{className:"h-5 relative mb-1 shrink-0",children:c&&null!==m&&s.jsxs("div",{className:"absolute flex items-center gap-1.5 type-data-sm -translate-x-1/2",style:{left:`calc(48px + ${100*m}% * (1 - 48px / 100%))`},children:[s.jsx(ie,{mode:"wait",children:s.jsx(oe.span,{initial:!!w&&{opacity:0,scale:.5,rotate:-90},animate:{opacity:1,scale:1,rotate:0},exit:{opacity:0,scale:.5,rotate:90},transition:{duration:.25,ease:"easeOut"},children:v?s.jsx(re,{className:"w-4 h-4 text-sys-amber"}):s.jsx(ce,{className:"w-4 h-4 text-sys-blue"})},v?"sun":"moon")}),s.jsx("span",{className:"text-fg-secondary",children:y})]})}),s.jsx("div",{className:"flex-1 min-h-0",children:j&&s.jsx(a,{buckets:f,activeTypes:p,gridColor:r.grid,axisTickColor:r.axisTick,onHover:b})}),s.jsx("div",{className:"pt-2 px-1 pb-2 shrink-0",children:j&&s.jsx(n,{activeTypes:p,totalByType:g})})]})}se(rs);const ds=e.memo(function({buckets:t,activeTypes:a}){const n=e.useRef(null),o=e.useRef(t),r=e.useRef(a);o.current=t,r.current=a;const c=e.useMemo(()=>[t.map(e=>e.start),t.map(()=>1)],[t]);return e.useEffect(()=>{if(!n.current||0===t.length)return;const e=n.current,s=e.getBoundingClientRect(),a=Math.floor(s.width)||200,d=Math.floor(s.height)||60,m=new He({width:a,height:d,padding:[0,0,0,0],cursor:{show:!1},scales:{x:{time:!1},y:{range:[0,1]}},axes:[{show:!1},{show:!1}],series:[{},{show:!1}],legend:{show:!1},hooks:{draw:[e=>{const s=e.ctx,{left:t,top:a,width:n,height:c}=e.bbox;!function(e,s,t,a,n,o,r){if(0===s.length)return;const c=function(e,s,t){var a,n;if(e.length<=t)return e;const l=e.length/t,i=[];for(let o=0;o<t;o++){const t=Math.floor(o*l),r=Math.floor((o+1)*l),c=e.slice(t,r),d={start:(null==(a=c[0])?void 0:a.start)??0,end:(null==(n=c.at(-1))?void 0:n.end)??0,bytesByType:{},totalBytes:0};for(const e of c){d.totalBytes+=e.totalBytes;for(const t of s){const s=e.bytesByType[t]??0;s>0&&(d.bytesByType[t]=(d.bytesByType[t]??0)+s)}}i.push(d)}return i}(s,t,i.statsCard),d=c.length,m=o/d,u=c.map(e=>e.totalBytes),x=Math.max(...u);if(0!==x){for(let s=0;s<d;s++){const i=c[s],o=a+s*m,d=i.totalBytes;if(0===d)continue;const u=d/x*r;let h=n+r-u+u;for(const s of t){const t=i.bytesByType[s]??0;if(0===t)continue;const a=t/d*u,n=h-a;e.fillStyle=l(s),e.globalAlpha=.85,e.fillRect(o,n,m,a),h=n}}e.globalAlpha=1}}(s,o.current,r.current,t,a,n,c)}]}},c,e),u=new ResizeObserver(()=>{const s=e.getBoundingClientRect();s.width>0&&s.height>0&&m.setSize({width:Math.floor(s.width),height:Math.floor(s.height)})});return u.observe(e),()=>{u.disconnect(),m.destroy()}},[c,t.length]),0===t.length?s.jsx("div",{className:"h-full flex items-center justify-center",children:s.jsx("div",{className:"w-full h-0.5 rounded-full bg-fg-muted/15"})}):s.jsx("div",{ref:n,className:"w-full h-full"})}),ms=[{target:"ForwardedCard",fn:"type",minStage:1}];function us({value:t,receivedCount:a,packets:n,rangeMinutes:l,bucketCount:i,timeRangeLabel:d,icon:m,isLoaded:u=!0}){ee(ms);const{buckets:x,activeTypes:h,ratePerHour:f}=e.useMemo(()=>function(e,s,t){const a=Date.now()/1e3,n=60*s,l=a-n,i=n/t,o=[];for(let m=0;m<t;m++)o.push({start:l+m*i,end:l+(m+1)*i,bytesByType:{},totalBytes:0});const r={};let c=0;for(const m of e){if(!("tx_forward"===m.packet_origin||m.transmitted&&"tx_local"!==m.packet_origin))continue;const e=m.timestamp;if(e<l||e>a)continue;const s=Math.min(t-1,Math.floor((e-l)/i)),n=m.type??m.payload_type??0,d=m.length??m.payload_length??0,u=o[s];u.bytesByType[n]=(u.bytesByType[n]??0)+d,u.totalBytes+=d,r[n]=(r[n]??0)+d,c++}const d=s/60;return{buckets:o,activeTypes:Object.keys(r).map(e=>parseInt(e,10)).filter(e=>r[e]>0).sort((e,s)=>r[s]-r[e]),ratePerHour:d>0?Math.round(c/d):0}}(n,l,i),[n,l,i]),p=a>0?(t/a*100).toFixed(1):null;return u?s.jsxs(o,{children:[s.jsxs("div",{className:"flex items-center gap-1.5 sm:gap-2 mb-2 sm:mb-3",children:[m&&s.jsx("span",{className:"icon-sm text-icon-card-title",children:m}),s.jsx("span",{className:"type-micro",children:"FORWARDED"}),d&&s.jsx(c,{color:"zinc",className:"hidden sm:inline-flex",children:d})]}),s.jsx("div",{className:"type-data-xl text-fg-primary",children:s.jsx(Pe,{value:t,className:"font-mono tabular-nums",priority:"high"})}),s.jsx("div",{className:"flex-1 mt-1 overflow-hidden min-h-[40px] sm:min-h-[60px]",children:h.length>0?s.jsx(ds,{buckets:x,activeTypes:h}):s.jsx("div",{className:"w-full h-full flex items-center justify-center",children:s.jsx("div",{className:"w-full h-0.5 rounded-full bg-fg-muted/15"})})}),s.jsx("div",{className:"pt-1.5 sm:pt-2 mt-1",children:s.jsxs("div",{className:"flex gap-2 sm:gap-3",children:[s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsx("div",{className:"data-box-label",children:"Rate"}),s.jsxs("div",{className:"data-box data-box-fill data-box-left",children:[f,"/hr"]})]}),null!==p&&s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsx("div",{className:"data-box-label",children:"Ratio"}),s.jsxs("div",{className:"data-box data-box-fill data-box-left",children:[p,"%"]})]})]})})]}):s.jsx(o,{children:s.jsx(r,{})})}se(ms);const xs=[{target:"DroppedCard",fn:"type",minStage:1}];function hs({value:t,receivedCount:a,packets:n,rangeMinutes:l,bucketCount:i,timeRangeLabel:d,icon:m,isLoaded:u=!0}){ee(xs);const{buckets:x,activeTypes:h,ratePerHour:f}=e.useMemo(()=>function(e,s,t){const a=Date.now()/1e3,n=60*s,l=a-n,i=n/t,o=[];for(let m=0;m<t;m++)o.push({start:l+m*i,end:l+(m+1)*i,bytesByType:{},totalBytes:0});const r={};let c=0;for(const m of e){if(!m.drop_reason)continue;const e=m.timestamp;if(e<l||e>a)continue;const s=Math.min(t-1,Math.floor((e-l)/i)),n=m.type??m.payload_type??0,d=m.length??m.payload_length??0,u=o[s];u.bytesByType[n]=(u.bytesByType[n]??0)+d,u.totalBytes+=d,r[n]=(r[n]??0)+d,c++}const d=s/60;return{buckets:o,activeTypes:Object.keys(r).map(e=>parseInt(e,10)).filter(e=>r[e]>0).sort((e,s)=>r[s]-r[e]),ratePerHour:d>0?Math.round(c/d):0}}(n,l,i),[n,l,i]),p=a>0?(t/a*100).toFixed(1):null;return u?s.jsxs(o,{children:[s.jsxs("div",{className:"flex items-center gap-1.5 sm:gap-2 mb-2 sm:mb-3",children:[m&&s.jsx("span",{className:"icon-sm text-icon-card-title",children:m}),s.jsx("span",{className:"type-micro",children:"DROPPED"}),d&&s.jsx(c,{color:"zinc",className:"hidden sm:inline-flex",children:d})]}),s.jsx("div",{className:"type-data-xl text-fg-primary",children:s.jsx(Pe,{value:t,className:"font-mono tabular-nums",priority:"high"})}),s.jsx("div",{className:"flex-1 mt-1 overflow-hidden min-h-[40px] sm:min-h-[60px]",children:h.length>0?s.jsx(ds,{buckets:x,activeTypes:h}):s.jsx("div",{className:"w-full h-full flex items-center justify-center",children:s.jsx("div",{className:"w-full h-0.5 rounded-full bg-fg-muted/15"})})}),s.jsx("div",{className:"pt-1.5 sm:pt-2 mt-1",children:s.jsxs("div",{className:"flex gap-2 sm:gap-3",children:[s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsx("div",{className:"data-box-label",children:"Rate"}),s.jsxs("div",{className:"data-box data-box-fill data-box-left",children:[f,"/hr"]})]}),null!==p&&s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsx("div",{className:"data-box-label",children:"Drop %"}),s.jsxs("div",{className:"data-box data-box-fill data-box-left",children:[p,"%"]})]})]})})]}):s.jsx(o,{children:s.jsx(r,{})})}se(xs);const fs={",":"punc",".":"punc-period",":":"punc-colon","/":"punc-slash"},ps=/([,\.:\/])/g,gs=e.memo(function({children:t,className:a="",as:n="span"}){const l=e.useMemo(()=>{let e;return e="number"==typeof t?t.toLocaleString():Array.isArray(t)?t.join(""):String(t??""),ps.test(e)?(ps.lastIndex=0,e.split(ps).map((e,t)=>{const a=fs[e];return a?s.jsx("span",{className:a,children:e},t):e})):e},[t]);return s.jsx(n,{className:`data-tight ${a}`.trim(),children:l})});function bs(e,s,t){return Ee(Math.max(s,Math.min(t,e)))}function js({stats:t,receivedBuckets:a,droppedBuckets:n,forwardedBuckets:l,bucketDurationSeconds:i,timeRangeLabel:u,isLoaded:x=!0}){var h,f,p,g;const[b,j]=e.useState(!1),[v,y]=e.useState("idle"),N=d(),w=e.useCallback(async(e,s)=>{if("applying"!==v){y("applying");try{const t=await m({tx_delay_factor:e,direct_tx_delay_factor:s});(null==t?void 0:t.success)?(y("success"),setTimeout(()=>y("idle"),2e3)):(y("error"),setTimeout(()=>y("idle"),2500))}catch{y("error"),setTimeout(()=>y("idle"),2500)}}},[v]);if(!x)return s.jsx(o,{children:s.jsx(r,{})});const k=Math.floor(Date.now()/1e3)-604800,M=Object.values((null==t?void 0:t.neighbors)??{}).filter(e=>e.zero_hop&&e.last_seen>=k&&Ae(e).isRepeater).length,C=N.filter(e=>"active"===e.status||e.lastSeen>=k).length,S=Math.max(M,C),L=function(e,s,t){const a=e=>(null==e?void 0:e.reduce((e,s)=>e+s.count,0))??0,n=a(s),l=a(t),i=n||(null==e?void 0:e.rx_count)||1,o=l||(null==e?void 0:e.dropped_count)||0;return i>0?o/(i+o)*100:0}(t,a,n),T=function(e,s,t){if((null==s?void 0:s.length)&&t){const e=100;return((null==(a=s)?void 0:a.reduce((e,s)=>e+s.count,0))??0)*e/(s.length*t*1e3)*100}var a;if(e){const s=1e3*(e.uptime_seconds||1);return(e.total_airtime_ms||e.airtime_used_ms||0)/s*100}return 0}(t,l,i),B=(null==(f=null==(h=null==t?void 0:t.config)?void 0:h.delays)?void 0:f.tx_delay_factor)??null,F=(null==(g=null==(p=null==t?void 0:t.config)?void 0:p.delays)?void 0:g.direct_tx_delay_factor)??null,_=function(e,s,t,a){let n=Ie(e);s>20?n+=2*qe:s>12&&(n+=qe),t>8&&(n+=qe);const l=bs(n,0,2);let i=We(e);t>8&&(i+=qe);const o=bs(i,0,1),r=ze(l),c=ze(o),d=null!==a?ze(a):null;let m="stable";return null!==d&&(r>d?m="increase":r<d&&(m="decrease")),{floodFactor:l,directFactor:o,floodSlots:r,directSlots:c,adjustment:m,duplicateRate:Math.round(100*s)/100,txUtilization:Math.round(1e3*t)/1e3,zeroHopCount:e}}(S,L,T,B),R=1!==S,D=Ie(S),$=[`${S} repeater${R?"s":""} heard in the last 7 days (base ×${D.toFixed(1)}).`];_.floodFactor===D&&L<=12&&T<=8?$.push("No modifiers applied — network looks healthy."):(L>20?$.push(`High duplicate rate (${L.toFixed(1)}%) suggests frequent collisions — window widened.`):L>12&&$.push(`Elevated duplicate rate (${L.toFixed(1)}%) — window widened one step.`),T>8&&$.push(`Channel is busy (${T.toFixed(1)}% TX util) — extra spacing added.`));const H=[`Direct uses one forwarder — ×${_.directFactor.toFixed(1)} backoff for channel contention.`];T>8&&H.push("Busy channel — small extra backoff.");const P=[`Flood ×${_.floodFactor.toFixed(1)} (${_.floodSlots} slot${1!==_.floodSlots?"s":""})`,...$,"",`Direct ×${_.directFactor.toFixed(1)}`,...H,"","Click to copy CLI commands"].join("\n"),A=null!==B?ze(B):null,I=null!==F?ze(F):null,z=null!==A&&_.floodSlots!==A,E=null!==I&&_.directSlots!==I,W=z||E;return s.jsxs(o,{children:[s.jsxs("div",{className:"flex items-center gap-1.5 sm:gap-2 mb-2 sm:mb-3 flex-wrap",children:[s.jsx(de,{className:"w-4 h-4 text-icon-card-title flex-shrink-0"}),s.jsx("span",{className:"type-micro",children:"DELAY DOCTOR"}),u&&s.jsx(c,{color:"zinc",className:"hidden sm:inline-flex",children:u})]}),s.jsxs("button",{onClick:async()=>{const e=`set txdelay ${_.floodFactor.toFixed(1)}\nset direct.txdelay ${_.directFactor.toFixed(1)}`;try{await navigator.clipboard.writeText(e),j(!0),setTimeout(()=>j(!1),1500)}catch{const s=document.createElement("textarea");s.value=e,s.style.position="fixed",s.style.opacity="0",document.body.appendChild(s),s.select();try{document.execCommand("copy"),j(!0),setTimeout(()=>j(!1),1500)}catch{console.error("Failed to copy commands")}document.body.removeChild(s)}},className:"flex gap-3 mb-2 sm:mb-3 w-full text-left hover:bg-subtle-fill radius-inner transition-base p-1 -m-1 group",title:P,children:[s.jsxs("div",{className:"flex-1 flex flex-col",children:[s.jsx("span",{className:"type-data-xl text-fg-primary",children:s.jsxs(gs,{children:["×",_.floodFactor.toFixed(1)]})}),s.jsx("span",{className:"type-micro text-fg-muted mt-0.5 sm:mt-1",children:"Flood"})]}),s.jsxs("div",{className:"flex-1 flex flex-col",children:[s.jsx("span",{className:"type-data-xl text-sys-blue",children:s.jsxs(gs,{children:["×",_.directFactor.toFixed(1)]})}),s.jsx("span",{className:"type-micro text-fg-muted mt-0.5 sm:mt-1",children:"Direct"})]}),s.jsx("div",{className:"flex items-center self-center opacity-0 group-hover:opacity-100 transition-opacity",children:b?s.jsx(me,{className:"w-4 h-4 text-sys-green"}):s.jsx(ue,{className:"w-4 h-4 text-fg-muted"})})]}),s.jsx("div",{className:"flex-1 py-2",children:s.jsxs("div",{className:"flex gap-3",children:[s.jsxs("div",{className:"flex-1",children:[s.jsx("div",{className:"data-box-label",children:"Dupe"}),s.jsxs("div",{className:"data-box data-box-fill data-box-left "+(_.duplicateRate>8?"text-status-warning":""),children:[_.duplicateRate.toFixed(1),"%"]})]}),s.jsxs("div",{className:"flex-1",children:[s.jsx("div",{className:"data-box-label",children:"TX Util"}),s.jsxs("div",{className:"data-box data-box-fill data-box-left",children:[_.txUtilization.toFixed(2),"%"]})]})]})}),s.jsx("div",{className:"pt-2 mt-auto",children:s.jsxs("div",{className:"flex items-end justify-between gap-2",children:[s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsx("div",{className:"data-box-label",children:"Current"}),s.jsx("div",{className:"flex gap-2",children:null!==B?s.jsxs(s.Fragment,{children:[s.jsxs("div",{className:"data-box",children:["×",B.toFixed(2)]}),s.jsxs("div",{className:"data-box",style:{color:"var(--sys-blue)"},children:["×",(null==F?void 0:F.toFixed(2))??"—"]})]}):s.jsx("span",{className:"text-sm text-fg-muted",children:"No config"})})]}),W&&s.jsxs("button",{onClick:()=>w(_.floodFactor,_.directFactor),disabled:"applying"===v||"success"===v,className:"flex items-center gap-1.5 px-2.5 py-1.5 radius-inner type-micro font-medium transition-base\n "+("success"===v?"bg-sys-green/15 text-sys-green":"error"===v?"bg-sys-red/15 text-sys-red":"applying"===v?"bg-subtle-fill text-fg-muted":"bg-sys-blue/10 text-sys-blue hover:bg-sys-blue/20"),title:`Apply ×${_.floodFactor.toFixed(1)} flood, ×${_.directFactor.toFixed(1)} direct`,children:["success"===v?"Rx'd":"error"===v?"Failed":"Apply","applying"===v?s.jsx(xe,{className:"w-3.5 h-3.5 animate-spin"}):"success"===v?s.jsx(me,{className:"w-3.5 h-3.5"}):s.jsxs("span",{className:"relative inline-flex items-end w-6 h-3.5",children:[s.jsx(he,{className:"w-3.5 h-3.5 absolute left-0 bottom-0"}),s.jsx(fe,{className:"w-3 h-3 absolute right-0 bottom-0"})]})]})]})})]})}const vs=[{target:"RecentPackets",fn:"rssi",minStage:1},{target:"RecentPackets",fn:"snr",minStage:1}];function ys(){ee(vs);const t=u(),a=x(),n=h(),l=f(),i=Ue(),r=Oe(e=>e.requestChannel),[c,d]=e.useState(!0),m=e.useCallback(e=>d(e),[]),v=e.useMemo(()=>[...t.length<=100?t:t.slice(-100)].sort((e,s)=>(s.timestamp??0)-(e.timestamp??0)),[t]),y=null==l?void 0:l.local_hash,N=null==l?void 0:l.neighbors,w=Je();return s.jsxs(o,{noPadding:!0,className:"!overflow-visible",children:[s.jsx(p,{listHeader:!0,icon:s.jsx(ge,{}),title:"Recent Packets",actions:s.jsxs("div",{className:"flex items-center gap-3",children:[s.jsx(g,{enabled:c,onChange:m,label:"Hide Dupes",size:"sm"}),n&&s.jsx(b,{showLabel:!0}),s.jsxs(j,{color:"primary",outline:!0,href:"/packets",children:["View all",s.jsx(pe,{"data-slot":"icon"})]})]})}),s.jsx("div",{className:"flex-1 min-h-0 overflow-y-auto px-1",children:s.jsx(Ge,{packets:v,allPackets:t,localHash:y,neighbors:N,resolveSource:w,getDecodedContent:i,onChannelClick:r,loading:a,maxPackets:25,showPagination:!1,flashNewest:!0,hideDupes:c,emptyMessage:"No packets received",footerAction:s.jsxs(j,{color:"primary",outline:!0,href:"/packets",children:["View all",s.jsx(pe,{"data-slot":"icon"})]})})})]})}se(vs);const Ns={stable:"M5 12h14",up:"M5 15l7-7 7 7",down:"M19 9l-7 7-7-7"};function ws({trend:e}){return s.jsx("span",{className:`mini-widget-trend ${e}`,children:s.jsx("svg",{className:"w-3 h-3",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:Ns[e]})})})}function ks(){return s.jsx("div",{className:"mini-widget-loading",children:s.jsx("div",{className:"mini-widget-loading-spinner"})})}function Ms({message:e}){return s.jsx("div",{className:"mini-widget-error",children:s.jsx("span",{title:e,children:"No data"})})}function Cs({title:e,icon:t,value:a,unit:n,valueSize:l="md",status:i,subtitle:r,trend:c,children:d,isLoading:m=!1,error:u,className:x="",onClick:h}){const f=["mini-widget-value","lg"===l&&"mini-widget-value-lg","sm"===l&&"mini-widget-value-sm"].filter(Boolean).join(" "),p=["mini-widget",x].filter(Boolean).join(" ");return s.jsxs(o,{noPadding:!0,className:p,onClick:h,children:[s.jsxs("div",{className:"mini-widget-header",children:[t,s.jsx("span",{className:"mini-widget-title",children:e}),i&&"unknown"!==i&&s.jsx("div",{className:`mini-widget-status-dot ${i}`}),c&&s.jsx(ws,{trend:c})]}),m?s.jsx(ks,{}):u?s.jsx(Ms,{message:u}):s.jsxs(s.Fragment,{children:[void 0!==a&&s.jsxs("div",{className:f,children:["number"==typeof a?s.jsx(Pe,{value:a,className:"font-mono tabular-nums",priority:"medium",format:Number.isInteger(a)?void 0:{minimumFractionDigits:1,maximumFractionDigits:1}}):s.jsx(gs,{children:a}),n&&s.jsx("span",{className:"mini-widget-unit",children:n})]}),r&&s.jsx("div",{className:"mini-widget-subtitle",children:r}),d]})]})}const Ss={DELTA_CRITICAL:10,SLOPE_CRITICAL:4,JITTER_CRITICAL:6,DELTA_WARNING:5,SLOPE_WARNING:2,JITTER_WARNING:4},Ls={baselineMedian:null,baselineP10:null,baselineP90:null,currentMedian:null,currentSampleCount:0,delta:0,slope:0,jitter:0,penalty:0,penaltyReason:null,computedAt:0,isReliable:!1};function Ts(e,s){if(0===e.length)return null;const t=[...e].sort((e,s)=>e-s),a=s/100*(t.length-1),n=Math.floor(a),l=Math.ceil(a);return n===l?t[n]:t[n]+(t[l]-t[n])*(a-n)}function Bs(e){return Ts(e,50)}const Fs={lbtStats:null,noiseFloor:null,sparklineNoiseFloor:[],noiseFloorWindowHistory:[],linkQuality:null,channelHealth:null,nfTrend:Ls,radioConfig:null,trends:null,stats:null,recentPackets:[],quickNeighbors:[],isLoading:!0,error:null,refresh:async()=>{}},_s=e.createContext(Fs);function Rs({children:t}){var a;const n=f(),l=u(),i=v(),o=y(),r=N(),c=w[r],d=Math.max(1,c.minutes/60),m=null===n,x=e.useMemo(()=>k(l,d),[l,d]),h=(null==n?void 0:n.noise_floor_dbm)??null,p=e.useMemo(()=>M(h)?h:null,[h]),g=e.useMemo(()=>{var e;const s=null==(e=null==n?void 0:n.config)?void 0:e.radio;return s?{sf:s.spreading_factor??7,bwHz:s.bandwidth??125e3}:null},[null==(a=null==n?void 0:n.config)?void 0:a.radio]),b=C(d),j=S(d),F=null==n?void 0:n.neighbors,_=e.useMemo(()=>{const e=F??{};return Object.fromEntries(Object.entries(e).filter(([e])=>!o.has(e)))},[F,o]),R=e.useMemo(()=>i.filter(e=>!o.has(e.hash)),[i,o]),D=e.useMemo(()=>function(e){if(0===e.length)return{...Ls,computedAt:Math.floor(Date.now()/1e3)};const s=Math.floor(Date.now()/1e3),t=e.filter(e=>Number.isFinite(e)),a=e.length>0?[e[e.length-1]]:[],n=e.slice(-4).filter(e=>Number.isFinite(e)),l=Bs(t),i=Ts(t,10),o=Ts(t,90),r=Bs(a),c=null!==r&&null!==i?r-i:0,d=function(e){if(e.length<2)return 0;const s=e.length;let t=0,a=0,n=0,l=0;const i=e[0].timestamp;for(const r of e){const e=(r.timestamp-i)/3600,s=r.value;t+=e,a+=s,n+=e*s,l+=e*e}const o=s*l-t*t;return Math.abs(o)<1e-4?0:(s*n-t*a)/o}(n.map((e,t)=>({timestamp:s-3600*(n.length-1-t),value:e}))),m=function(e){if(e.length<2)return 0;const s=e.reduce((e,s)=>e+s,0)/e.length,t=e.map(e=>Math.pow(e-s,2)).reduce((e,s)=>e+s,0)/e.length;return Math.sqrt(t)}(n),u=t.length>=12,[x,h]=u?function(e,s,t){const a=Ss;return e>=a.DELTA_CRITICAL?[2,`Noise floor ${e.toFixed(1)} dB above baseline`]:s>=a.SLOPE_CRITICAL?[2,`Noise floor rising ${s.toFixed(1)} dB/hour`]:t>=a.JITTER_CRITICAL?[2,`Noise floor unstable (±${t.toFixed(1)} dB)`]:e>=a.DELTA_WARNING?[1,`Noise floor ${e.toFixed(1)} dB above baseline`]:s>=a.SLOPE_WARNING?[1,`Noise floor rising ${s.toFixed(1)} dB/hour`]:t>=a.JITTER_WARNING?[1,`Noise floor variable (±${t.toFixed(1)} dB)`]:[0,null]}(c,d,m):[0,null];return{baselineMedian:l,baselineP10:i,baselineP90:o,currentMedian:r,currentSampleCount:a.length,delta:c,slope:d,jitter:m,penalty:x,penaltyReason:h,computedAt:s,isReliable:u}}(b),[b]),$=e.useMemo(()=>L(R,_,g),[R,_,g]),H=e.useMemo(()=>T(x,p,$),[x,p,$]),[P,A]=e.useState({noiseFloor:null,networkScore:null,channelHealth:null}),I=e.useRef(0);e.useEffect(()=>{const e=()=>{const e=Date.now();e-I.current>3e4&&(I.current=e,A({noiseFloor:p,networkScore:(null==$?void 0:$.networkScore)??null,channelHealth:(null==H?void 0:H.score)??null}))};e();const s=setInterval(e,5e3);return()=>clearInterval(s)},[p,null==$?void 0:$.networkScore,null==H?void 0:H.score]);const z=e.useMemo(()=>({noiseFloor:{current:p,previous:P.noiseFloor,trend:null!==p?B(p,P.noiseFloor,2,!0):"stable"},networkScore:{current:(null==$?void 0:$.networkScore)??0,previous:P.networkScore,trend:B((null==$?void 0:$.networkScore)??0,P.networkScore,3,!1)},channelHealth:{current:(null==H?void 0:H.score)??0,previous:P.channelHealth,trend:B((null==H?void 0:H.score)??0,P.channelHealth,3,!1)}}),[p,null==$?void 0:$.networkScore,null==H?void 0:H.score,P]),E={lbtStats:x,noiseFloor:p,sparklineNoiseFloor:b,noiseFloorWindowHistory:j,linkQuality:$,channelHealth:H,nfTrend:D,radioConfig:g,trends:z,stats:n,recentPackets:l,quickNeighbors:i,isLoading:m,error:null,refresh:async()=>{}};return s.jsx(_s.Provider,{value:E,children:t})}function Ds(){const s=e.useContext(_s);if(void 0===s)throw new Error("useLBTData must be used within an LBTDataProvider");return s}function $s(e,s){return 0===e?"No backoffs":`${s.toFixed(0)}% retry rate`}function Hs(){const{lbtStats:t,isLoading:a,error:n}=Ds(),l=Ye(),i=(null==t?void 0:t.avgBackoffMs)??0,o=(null==t?void 0:t.retryRate)??0,r=t?(c=i)<100?"excellent":c<250?"good":c<500?"fair":c<1e3?"congested":"critical":"unknown";var c;const d=null==t?void 0:t.sparklineBackoff,m=e.useMemo(()=>!d||d.length<2?[]:d.map((e,s)=>({timestamp:Date.now()-36e5*(d.length-1-s),count:e})),[d]);return s.jsx(Cs,{title:"LBT Backoff",icon:s.jsx(be,{className:"mini-widget-icon"}),value:Math.round(i),unit:"ms",status:r,subtitle:t?$s(i,o):void 0,isLoading:a,error:n,onClick:()=>l("/packets"),children:s.jsx("div",{className:"mini-widget-sparkline w-full",children:s.jsx(Xe,{data:m,width:9999,height:24,color:"var(--sys-blue)",isLoading:a,className:"w-full"})})})}function Ps(e){return 0===e?"—":e<1?"<1":Math.round(e).toString()}function As(){const{lbtStats:e,isLoading:t,error:a}=Ds(),n=Ye(),l=(null==e?void 0:e.channelBusyCount)??0,i=(null==e?void 0:e.totalPacketsWithLBT)??0,o=(null==e?void 0:e.channelBusyRate)??0,r=(null==e?void 0:e.retryRate)??0,c=(null==e?void 0:e.avgBackoffMs)??0,d=(null==e?void 0:e.minBackoffMs)??0,m=(null==e?void 0:e.maxBackoffMs)??0,u=r>0?Math.max(0,(r-o)/r*100):100;return s.jsx(Cs,{title:"Ch. Busy",icon:s.jsx(je,{className:"mini-widget-icon"}),isLoading:t,error:a,onClick:()=>n("/packets"),children:s.jsx("div",{className:"flex-1 flex items-end",children:s.jsxs("div",{className:"grid grid-cols-[auto_minmax(0,1fr)] sm:grid-cols-[auto_minmax(0,1fr)_auto_minmax(0,1fr)] gap-x-2 gap-y-1 sm:gap-y-2 w-full items-baseline",children:[s.jsx("span",{className:"data-box-label mb-0 text-[10px] sm:text-sm",title:`${l} packets exceeded max CAD attempts (5) out of ${i} total transmissions.`,children:"Failed:"}),s.jsxs("div",{className:"data-box data-box-compact sm:data-box justify-self-start",title:`${l} packets exceeded max CAD attempts (5) out of ${i} total transmissions.`,children:[s.jsx(gs,{children:l}),s.jsx("span",{className:"text-fg-muted punc-slash",children:"/"}),s.jsx(gs,{children:i})]}),s.jsx("span",{className:"data-box-label mb-0 text-[10px] sm:text-sm",title:`${u.toFixed(1)}% of packets that needed LBT retries were sent successfully.`,children:"Sent:"}),s.jsx("div",{className:"data-box data-box-compact sm:data-box justify-self-start",title:`${u.toFixed(1)}% of packets that needed LBT retries were sent successfully.`,children:s.jsxs(gs,{children:[u.toFixed(0),"%"]})}),s.jsx("span",{className:"data-box-label mb-0 text-[10px] sm:text-sm",title:`Average LBT backoff delay: ${c.toFixed(0)}ms.`,children:"Mean:"}),s.jsxs("div",{className:"data-box data-box-compact sm:data-box justify-self-start",title:`Average LBT backoff delay: ${c.toFixed(0)}ms.`,children:[s.jsx(gs,{children:Ps(c)}),s.jsx("span",{className:"text-fg-muted text-xs",children:"ms"})]}),s.jsx("span",{className:"data-box-label mb-0 text-[10px] sm:text-sm",title:`Backoff range: ${d.toFixed(0)}ms min, ${m.toFixed(0)}ms max.`,children:"Range:"}),s.jsxs("div",{className:"data-box data-box-compact sm:data-box justify-self-start",title:`Backoff range: ${d.toFixed(0)}ms min, ${m.toFixed(0)}ms max.`,children:[s.jsx(gs,{children:Ps(d)}),s.jsx("span",{className:"text-fg-muted punc-slash",children:"/"}),s.jsx(gs,{children:Ps(m)})]})]})})})}function Is(e){return null===e?"No reading":e<-115?"Very quiet":e<-105?"Quiet":e<-95?"Moderate":e<-85?"Elevated":"High interference"}function zs(){const{noiseFloor:t,noiseFloorWindowHistory:a,trends:n,isLoading:l,error:i}=Ds(),o=null===(r=t)||r<-110?"excellent":r<-100?"good":r<-90?"fair":r<-80?"congested":"critical";var r;const c=null==n?void 0:n.noiseFloor.trend,d=e.useMemo(()=>{if(!a||a.length<2)return[];return function(e,s,t,a){const n=e.length;if(0===n)return[];if(1===n)return new Array(a).fill(s[0]);if(2===n){const e=new Array(a);for(let t=0;t<a;t++)e[t]=s[0]+(s[1]-s[0])*(t/47);return e}const l=Math.max(2,Math.ceil(.25*n)),i=e[0],o=e[n-1]-i||1,r=new Array(a),c=new Array(n);for(let d=0;d<a;d++){const t=i+d/47*o;for(let s=0;s<n;s++)c[s]=Math.abs(e[s]-t);const a=c.slice().sort((e,s)=>e-s),m=Math.max(a[l-1],1e-10);let u=0,x=0,h=0,f=0,p=0;for(let l=0;l<n;l++){const a=c[l]/m;if(a>=1)continue;const n=a*a*a,i=(1-n)*(1-n)*(1-n),o=e[l]-t;u+=i,x+=i*o,h+=i*s[l],f+=i*o*o,p+=i*o*s[l]}if(0===u){r[d]=s[Math.round(d/47*(n-1))];continue}const g=u*f-x*x;r[d]=Math.abs(g)<1e-10?h/u:(f*h-x*p)/g}return r}(a.map(e=>e.timestamp),a.map(e=>-e.noise_floor_dbm),0,48).map((e,s)=>({timestamp:Date.now()-36e5*(47-s),count:e}))},[a]),m=null!==t?Math.round(t):"—";return s.jsx(Cs,{title:"Noise Floor",icon:s.jsx(ve,{className:"mini-widget-icon"}),value:m,unit:null!==t?"dBm":void 0,status:o,trend:c,subtitle:Is(t),isLoading:l,error:i,children:s.jsx("div",{className:"mini-widget-sparkline w-full",children:s.jsx(Xe,{data:d,width:9999,height:22,color:"var(--sys-blue)",isLoading:l,className:"w-full"})})})}const Es=[{target:"LinkLeaders",fn:"path",minStage:1,when:ae},{target:"LinkLeaders",fn:"src_hash",minStage:1,when:ne}];function Ws(){ee(Es);const t=Ye(),a=v(),n=u(),l=f(),i=N(),o=60*w[i].minutes,r=F(),c=e.useMemo(()=>{if(0===r)return n;const e=r-o;return n.filter(s=>s.timestamp>=e)},[n,o,r]),d=null===l,m=(null==l?void 0:l.local_hash)?_(l.local_hash):"",x=(null==l?void 0:l.neighbors)??{},{neighborHashes:h,neighborNames:p}=e.useMemo(()=>{const e=new Set,s=new Map;for(const t of a){e.add(t.hash);const a=x[t.hash],n=(null==a?void 0:a.name)||(null==a?void 0:a.node_name)||t.prefix;s.set(t.hash,n)}return{neighborHashes:e,neighborNames:s}},[a,x]),g=e.useMemo(()=>{if(0===h.size||0===c.length||!m)return{champion:null,listener:null,loudest:null};const{scores:e}=Qe(c,h,m),s=[];for(const[l,i]of e)0!==i.blendedScore&&s.push({...i,name:p.get(l)??_(l)});let t=null,a=null,n=null;for(const l of s)(!t||l.blendedScore>t.blendedScore)&&(t=l),(!a||l.listenerScore>a.listenerScore)&&(a=l),(!n||l.loudScore>n.loudScore)&&(n=l);return{champion:t,listener:a,loudest:n}},[c,h,m,p]),{champion:b,listener:j,loudest:y}=g,k=b||j||y?s.jsxs("div",{className:"flex flex-col gap-0 sm:gap-0.5 mt-auto",children:[b&&s.jsx(R,{content:(M=b,s.jsxs("div",{className:"max-w-[220px]",children:[s.jsxs("div",{className:"font-semibold mb-1",children:["🏆 Champion: ",M.name]}),s.jsxs("div",{className:"text-fg-muted mb-1",children:["Blended Score: ",M.blendedScore,s.jsx("span",{className:"text-fg-muted/60 ml-1",children:"(Listener + Loud)"})]}),s.jsxs("div",{className:"border-t border-edge-subtle pt-1 mt-1 space-y-0.5",children:[s.jsxs("div",{children:["Listener: ",M.listenerScore,"/100 (",M.listenerCount," shared paths)"]}),s.jsxs("div",{children:["Loud: ",M.loudScore,"/100 (",M.loudCount," packets relayed)"]})]})]})),children:s.jsxs("div",{className:"flex items-center gap-1 text-xs sm:text-sm radius-badge px-1 -mx-1 hover-bg transition-base cursor-default",children:[s.jsx(ye,{className:"w-2.5 h-2.5 sm:w-3 sm:h-3 text-map-neighbor-color flex-shrink-0"}),s.jsx("span",{className:"font-semibold text-map-neighbor-color font-mono truncate flex-1 min-w-0",children:b.name}),s.jsx("span",{className:"text-map-neighbor-color pl-1 sm:pl-2 tabular-nums flex-shrink-0 w-7 sm:w-9 text-right",children:b.blendedScore})]})}),j&&s.jsx(R,{content:(e=>s.jsxs("div",{className:"max-w-[220px]",children:[s.jsxs("div",{className:"font-semibold mb-1",children:["👂 Best Listener: ",e.name]}),s.jsxs("div",{className:"text-fg-muted mb-1",children:["Score: ",e.listenerScore,"/100"]}),s.jsx("div",{className:"border-t border-edge-subtle pt-1 mt-1",children:s.jsxs("div",{children:[e.listenerCount," packets where they heard your transmissions"]})})]}))(j),children:s.jsxs("div",{className:"flex items-center gap-1 text-xs sm:text-sm radius-badge px-1 -mx-1 hover-bg transition-base cursor-default",children:[s.jsx(Ne,{className:"w-2.5 h-2.5 sm:w-3 sm:h-3 text-fg-muted flex-shrink-0"}),s.jsx("span",{className:"text-fg-muted font-mono truncate flex-1 min-w-0",children:j.name}),s.jsx("span",{className:"text-fg-muted pl-1 sm:pl-2 tabular-nums flex-shrink-0 w-7 sm:w-9 text-right",children:j.listenerScore})]})}),y&&s.jsx(R,{content:(e=>s.jsxs("div",{className:"max-w-[220px]",children:[s.jsxs("div",{className:"font-semibold mb-1",children:["📢 Loudest: ",e.name]}),s.jsxs("div",{className:"text-fg-muted mb-1",children:["Score: ",e.loudScore,"/100"]}),s.jsx("div",{className:"border-t border-edge-subtle pt-1 mt-1",children:s.jsxs("div",{children:[e.loudCount," packets they relayed directly to you"]})})]}))(y),children:s.jsxs("div",{className:"flex items-center gap-1 text-xs sm:text-sm radius-badge px-1 -mx-1 hover-bg transition-base cursor-default",children:[s.jsx(we,{className:"w-2.5 h-2.5 sm:w-3 sm:h-3 text-fg-muted flex-shrink-0"}),s.jsx("span",{className:"text-fg-muted font-mono truncate flex-1 min-w-0",children:y.name}),s.jsx("span",{className:"text-fg-muted pl-1 sm:pl-2 tabular-nums flex-shrink-0 w-7 sm:w-9 text-right",children:y.loudScore})]})})]}):0===a.length?s.jsx("div",{className:"flex items-center justify-center text-xs sm:text-sm text-fg-muted mt-auto",children:"No direct neighbors"}):s.jsx("div",{className:"flex items-center justify-center text-xs sm:text-sm text-fg-muted mt-auto",children:"No routing data yet"});var M;return s.jsx(Cs,{title:"Link Leaders",icon:s.jsx(ke,{className:"mini-widget-icon"}),isLoading:d,onClick:()=>t("/contacts"),children:k})}function qs(){const{lbtStats:t,isLoading:a,error:n}=Ds(),l=t?function(e){const{retryRate:s,channelBusyCount:t,totalPacketsWithLBT:a,avgBackoffMs:n,maxBackoffMs:l}=e;if(0===a)return 0;const i=Math.min(a/10,1),o=Math.log(1+.15*s)/Math.log(16)*40,r=t/a*100,c=Math.min(.5*r,25);let d=0;n>100&&(d=Math.min(8*Math.log10(n/100),15));let m=0;l>500&&n>0&&l>2*n&&(m=Math.min((l-500)/200,5));const u=(o+c+d+m)*i;return Math.min(u,85)}(t):0,i=t?(o=l)<15?"excellent":o<30?"good":o<45?"fair":o<60?"congested":"critical":"unknown";var o;const r=(null==t?void 0:t.maxBackoffMs)??0,c=t?r>200?`Max backoff: ${Math.round(r)}ms`:function(e){return e<15?"Clear channel":e<30?"Light traffic":e<45?"Moderate traffic":e<60?"Heavy traffic":e<75?"Congested":"Severe congestion"}(l):void 0,d=null==t?void 0:t.sparklineCollisionRisk,m=e.useMemo(()=>!d||d.length<2?[]:d.map((e,s)=>({timestamp:Date.now()-36e5*(d.length-1-s),count:e})),[d]),u=Math.round(10*l)/10;return s.jsx(Cs,{title:"Collision Risk",icon:s.jsx(Me,{className:"mini-widget-icon"}),value:u,unit:"%",status:i,subtitle:c,isLoading:a,error:n,children:s.jsx("div",{className:"mini-widget-sparkline w-full",children:s.jsx(Xe,{data:m,width:9999,height:24,color:"var(--sys-blue)",isLoading:a,className:"w-full"})})})}function Os(){const[t,a]=e.useState(!1),[n]=e.useState(0),{stats:l,lbtStats:i,isLoading:o}=Ds(),r=e.useMemo(()=>{if(!l)return null;const e=l.airtime_used_ms??0,s=l.max_airtime_ms??1;return{usedMs:e,maxMs:s,remainingMs:l.airtime_remaining_ms??0,utilizationPercent:l.utilization_percent??(s>0?e/s*100:0)}},[l]),c=e.useMemo(()=>i&&0!==i.totalPacketsWithLBT?(i.totalPacketsWithLBT-i.packetsWithRetries)/i.totalPacketsWithLBT*100:100,[i]),d=(null==r?void 0:r.utilizationPercent)??0,m=(u=d)<30?"excellent":u<50?"good":u<70?"fair":u<90?"congested":"critical";var u;const x=(null==r?void 0:r.remainingMs)??0,h=c<95?`${c.toFixed(0)}% clean TX`:((f=x)<1e3?`${Math.round(f)}ms`:f<6e4?`${(f/1e3).toFixed(1)}s`:`${(f/6e4).toFixed(1)}m`)+" remaining";var f;const p=r?s.jsx("div",{className:"mini-widget-progress mt-auto",children:s.jsx("div",{className:`mini-widget-progress-bar ${m}`,style:{width:`${Math.min(d,100)}%`}})}):null;return s.jsx(Cs,{title:"Duty Cycle",icon:s.jsx(ge,{className:"mini-widget-icon"}),value:d.toFixed(1),unit:"%",status:m,subtitle:h,isLoading:o,children:p})}function Gs(){return s.jsxs("div",{className:"mini-widget",children:[s.jsxs("div",{className:"mini-widget-header",children:[s.jsx(D,{className:"w-4 h-4"}),s.jsx(D,{className:"h-3 w-16"})]}),s.jsx(D,{className:"h-7 w-12 mt-2"}),s.jsx(D,{className:"h-3 w-20 mt-2"})]})}function Vs(){return s.jsx("div",{className:"widget-row",children:Array.from({length:6}).map((e,t)=>s.jsx(Gs,{},t))})}se(Es);const Us=[{target:"MeshHealth",fn:"type",minStage:1}];function Js({className:e="",isLoaded:t=!0}){return ee(Us),s.jsxs("div",{className:`mesh-health-container relative ${e}`,children:[s.jsxs("div",{className:"mesh-health-header",children:[s.jsx(Ce,{className:"w-4 h-4 text-sys-blue"}),s.jsx("span",{className:"type-label text-fg-muted",children:"MESH HEALTH"})]}),t?s.jsx(Rs,{children:s.jsxs("div",{className:"widget-row",children:[s.jsx(Hs,{}),s.jsx(qs,{}),s.jsx(zs,{}),s.jsx(Os,{}),s.jsx(As,{}),s.jsx(Ws,{})]})}):s.jsx(Vs,{})]})}se(Us);const Ks=[{target:"PublicChannel",fn:"decrypt",minStage:2,when:le}];se(Ks);let Xs="",Qs="",Ys="";function Zs(e){!function(){const e=new Date,s=e.toDateString();if(s!==Ys){Ys=s,Xs=s;const t=new Date(e);t.setDate(t.getDate()-1),Qs=t.toDateString()}}();const s=new Date(1e3*e).toDateString();return s===Xs?"Today":s===Qs?"Yesterday":new Date(1e3*e).toLocaleDateString([],{weekday:"short",month:"short",day:"numeric"})}function et(e,s,t){return`${e||""}|${s}|${t}`}const st=e.memo(function({message:e,onChannelClick:t,isChannelSelected:a}){const n=e.channelName||e.channelHash.slice(0,6);return s.jsx("div",{style:{transform:"translateZ(0)",willChange:"transform"},children:s.jsx(ls,{senderName:e.senderName||"Unknown",text:e.text,timestamp:e.timestamp,nameAccessory:s.jsx(Ve,{channelName:n,active:a,onClick:()=>null==t?void 0:t(e.channelHash)})})})},function(e,s){const t=e.message,a=s.message;return t.timestamp===a.timestamp&&t.text===a.text&&t.senderName===a.senderName&&t.channelHash===a.channelHash&&t.channelName===a.channelName&&e.isChannelSelected===s.isChannelSelected&&e.onChannelClick===s.onChannelClick});function tt({open:t,onClose:a,messages:n,onLoadMore:l,hasMoreToLoad:i,isDecoding:o,initialChannel:r}){const c=e.useRef(null),d=e.useRef(!0),m=N(),u=W(),x=e.useRef(!1);e.useEffect(()=>{t?(x.current=!0,q.resume()):x.current&&q.pause()},[t]);const h=e.useMemo(()=>{const e=Date.now()/1e3-60*w[m].minutes;return[...n].filter(s=>s.timestamp>=e).sort((e,s)=>e.timestamp-s.timestamp)},[n,m]),f=e.useCallback(()=>{const e=c.current;e&&(d.current=e.scrollTop>=-50)},[]),p=e.useMemo(()=>{const e=new Map;for(const s of h){const t=s.channelHash,a=e.get(t);a?a.count++:e.set(t,{name:s.channelName||s.channelHash.slice(0,6),hash:s.channelHash,count:1})}return Array.from(e.values()).sort((e,s)=>s.count-e.count)},[h]),g=p.length,[b,j]=e.useState(null),[v,y]=e.useState(!1);e.useEffect(()=>{t&&r&&j(r)},[t,r]);const k=e.useCallback(()=>{l(b,p)},[l,b,p]),M=e.useMemo(()=>b?h.filter(e=>e.channelHash===b):h,[h,b]),C=e.useMemo(()=>{const e=[];let s="";for(const t of M){const a=Zs(t.timestamp);a!==s&&(e.push({type:"date",date:a}),s=a),e.push({type:"message",message:t})}return e},[M]);e.useLayoutEffect(()=>{const e=c.current;e&&d.current&&(e.scrollTop=0)},[M.length]);const S=p.slice(0,19),L=p.slice(19),T=L.length>0;return s.jsx(O,{open:t,onClose:a,size:"lg",motionPlus:!0,solid:!0,children:s.jsxs(G,{className:"p-0 flex flex-col h-[80vh] max-h-[700px] rounded-2xl",children:[s.jsx("div",{className:"flex-shrink-0 px-4 sm:px-5 py-3 sm:py-4",children:s.jsxs("div",{className:"flex items-center justify-between gap-3",children:[s.jsxs("div",{className:"flex items-center gap-3",children:[s.jsx(Se,{className:"size-5 text-icon-card-title flex-shrink-0"}),s.jsx("h2",{className:"type-micro",children:"Public Channels"})]}),s.jsxs("div",{className:"flex items-center gap-2",children:[s.jsx(Ke,{ranges:w,selectedIndex:m,onSelect:u,size:"sm"}),s.jsx("button",{onClick:a,className:"sm:hidden min-h-[44px] min-w-[44px] px-3 flex items-center justify-center text-[15px] font-medium text-sys-blue active:text-sys-blue/70 transition-base radius-inner active:bg-subtle-fill",children:"Done"}),s.jsx("button",{onClick:a,className:"hidden sm:flex items-center justify-center p-2 text-fg-muted hover:text-fg-primary transition-base radius-inner hover:bg-subtle","aria-label":"Close",children:s.jsx("svg",{className:"w-5 h-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M6 18L18 6M6 6l12 12"})})})]})]})}),s.jsx("div",{className:"flex-shrink-0 px-3 pb-2 relative z-10 isolate",style:{minHeight:g>0?void 0:0},children:g>0&&s.jsxs("div",{className:"flex flex-wrap gap-1",children:[s.jsxs("button",{onClick:()=>j(null),className:Ze("px-2 py-0.5 rounded text-xs font-medium transition-all","ring-1 ring-inset",null===b?"bg-sys-blue/20 text-sys-blue ring-sys-blue/30":"bg-subtle-fill text-fg-secondary ring-edge-subtle hover:bg-subtle-fill-strong"),children:["All ",g]}),S.map(e=>s.jsx("button",{onClick:()=>j(e.hash),className:Ze("flex items-center gap-1 px-2 py-0.5 rounded text-xs font-medium transition-all","ring-1 ring-inset",b===e.hash?"bg-sys-blue/20 text-sys-blue ring-sys-blue/30":"bg-subtle-fill text-fg-secondary ring-edge-subtle hover:bg-subtle-fill-strong"),children:s.jsx("span",{className:"truncate max-w-[80px]",children:e.name})},e.hash)),T&&s.jsxs("div",{className:"relative",children:[s.jsxs("button",{onClick:()=>y(!v),className:Ze("flex items-center gap-0.5 px-2 py-0.5 rounded text-xs font-medium transition-all","ring-1 ring-inset",v||L.some(e=>e.hash===b)?"bg-sys-blue/20 text-sys-blue ring-sys-blue/30":"bg-subtle-fill text-fg-secondary ring-edge-subtle hover:bg-subtle-fill-strong"),children:["+",L.length,s.jsx(Te,{className:Ze("size-3 transition-transform",v&&"rotate-180")})]}),v&&s.jsx("div",{className:Ze("absolute top-full left-0 mt-1 z-50","min-w-[140px] max-h-[200px] overflow-y-auto","p-1 rounded-lg","bg-elevated backdrop-blur-xl","ring-1 ring-edge-subtle shadow-xl"),children:L.map(e=>s.jsxs("button",{onClick:()=>{j(e.hash),y(!1)},className:Ze("w-full flex items-center gap-1.5 px-2 py-1 rounded text-xs font-medium transition-all text-left",b===e.hash?"bg-sys-blue/20 text-sys-blue":"text-fg-secondary hover:bg-subtle-fill-strong"),children:[s.jsx(Be,{className:"size-2.5 opacity-60 flex-shrink-0"}),s.jsx("span",{className:"truncate",children:e.name}),s.jsxs("span",{className:"opacity-60 ml-auto",children:["(",e.count,")"]})]},e.hash))})]})]})}),s.jsx("div",{ref:c,onScroll:f,className:Ze("flex-1 overflow-y-auto overflow-x-hidden","mx-3 mb-3 rounded-md","bg-body","ring-1 ring-inset ring-edge-subtle","flex flex-col-reverse"),children:o&&0===M.length?s.jsxs("div",{className:"flex flex-col items-center justify-center h-full min-h-[300px] text-fg-muted px-4 py-4",children:[s.jsx(xe,{className:"size-12 mb-4 text-sys-indigo animate-spin"}),s.jsx("p",{className:"text-lg font-medium",children:"Loading messages..."})]}):0===M.length?s.jsxs("div",{className:"flex flex-col items-center justify-center h-full min-h-[300px] text-fg-muted px-4 py-4",children:[s.jsx(Fe,{className:"size-16 mb-4 opacity-20"}),s.jsx("p",{className:"text-lg font-medium",children:"No messages yet"}),s.jsx("p",{className:"text-sm mt-1 opacity-70",children:b?"No messages in this channel":"Public channel messages will appear here"})]}):s.jsxs("div",{className:"px-4 py-4",children:[i&&s.jsx("div",{className:"flex justify-center mb-4",children:s.jsx("button",{onClick:k,disabled:o,className:Ze("px-4 py-1.5 rounded-full","text-[11px] font-medium","ring-1 ring-inset",o?"bg-subtle-fill text-fg-muted ring-edge-subtle cursor-wait":"bg-sys-blue/10 text-sys-blue ring-sys-blue/20 hover:bg-sys-blue/20 hover:ring-sys-blue/30"),children:o?s.jsxs("span",{className:"flex items-center gap-1.5",children:[s.jsx(xe,{className:"size-3 animate-spin"}),"Loading..."]}):"Load older messages"})}),C.map((e,t)=>{if("date"===e.type)return s.jsx("div",{className:"flex justify-center my-4",children:s.jsx("span",{className:Ze("px-3.5 py-1.5 rounded-full","bg-subtle-fill backdrop-blur-sm","text-[11px] text-fg-muted/80 font-medium","ring-1 ring-edge-subtle"),children:e.date})},`date-${e.date}-${t}`);const a=`msg-${e.message.timestamp}-${e.message.senderName||"anon"}-${e.message.channelHash}`;return s.jsx("div",{className:"mb-3",children:s.jsx(st,{message:e.message,onChannelClick:j,isChannelSelected:b===e.message.channelHash})},a)})]})}),s.jsx("div",{className:"flex-shrink-0 px-5 py-2 text-center",children:s.jsxs("p",{className:"text-[11px] text-fg-muted",children:[M.length," messages · ",g," ",1===g?"channel":"channels",o&&s.jsxs("span",{className:"ml-2 text-sys-indigo",children:[s.jsx(xe,{className:"inline size-3 animate-spin mr-1"}),"Decrypting..."]})]})})]})})}function at({isLoaded:t=!0}){ee(Ks);const a=u(),[n,l]=e.useState(!1),[i,o]=e.useState(null),r=N(),c=e.useCallback(()=>{o(null),l(!0),$.getState().queueDecryption(a)},[a]),d=Oe(e=>e.requestedHash),m=Oe(e=>e.clearRequest);e.useEffect(()=>{d&&(o(d),l(!0),$.getState().queueDecryption(a),m())},[d,m,a]);const x=H(),h=P(),f=A(),p=e.useMemo(()=>function(e){const s=[],t=new Set;for(const a of e.values()){const e=a.decoded;if(!e||!e.decrypted||e.macCorrupted||!e.text)continue;const n=et(e.senderName,e.channelHash,e.text);t.has(n)||(t.add(n),s.push({timestamp:a.timestamp,channelName:e.channelName,channelHash:e.channelHash,senderName:e.senderName,text:e.text,rssi:a.rssi,snr:a.snr}))}return s}(x),[x]),g=e.useMemo(()=>{const e=Date.now()/1e3-60*w[r].minutes;return p.filter(s=>s.timestamp>=e)},[p,r]),b=e.useMemo(()=>0===g.length?null:g.reduce((e,s)=>s.timestamp>e.timestamp?s:e),[g]),j=h.isDecoding,v=e.useMemo(()=>{const e=Date.now()/1e3-60*w[r].minutes,s=new Set;let t=0;for(const n of a)(n.type??n.payload_type)===I.GRP_TXT&&((n.timestamp??0)<e||s.has(n.packet_hash)||(s.add(n.packet_hash),t++));return t},[a,r]),y=z(),k=e.useMemo(()=>{const e=Date.now()/1e3-60*w[r].minutes;for(const s of a)if((s.type??s.payload_type)===I.GRP_TXT&&!((s.timestamp??0)<e||y.has(s.packet_hash)))return!0;return!1},[a,y,r]),M=e.useCallback((e,s)=>{if(!j){if(e){const t=s.find(s=>s.hash===e);if(t)return t.name,void $.getState().queueChannelDecryption(a,t.name)}$.getState().queueDecryption(a)}},[a,j]);return t?s.jsxs(s.Fragment,{children:[s.jsx("div",{onClick:c,className:Ze("group cursor-pointer rounded-2xl transition-all duration-150","bg-surface/80 backdrop-blur-lg depth-raised","hover:bg-subtle-fill","px-3 py-2.5 sm:px-4 sm:py-3"),children:s.jsxs("div",{className:"flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between",children:[s.jsxs("div",{className:"flex items-center gap-2 sm:gap-3 flex-shrink-0",children:[s.jsx(Se,{className:"size-4 text-icon-card-title flex-shrink-0"}),s.jsx("span",{className:"type-micro",children:"CHAT ACTIVITY"}),v>0&&s.jsx("span",{className:"inline-flex items-center px-2 py-1 rounded-md bg-subtle-fill ring-1 ring-inset ring-edge-subtle text-sm tabular-nums text-fg-secondary",children:v}),s.jsx(Le,{className:"size-4 text-fg-muted group-hover:text-sys-indigo transition-colors ml-auto sm:hidden"})]}),s.jsxs("div",{className:"flex items-center gap-2 sm:gap-1.5 min-w-0 overflow-hidden",children:[s.jsx(ie,{mode:"wait",initial:!1,children:b?s.jsxs(oe.div,{initial:{opacity:0,y:16},animate:{opacity:1,y:0},exit:{opacity:0,y:-16},transition:{duration:.2,ease:[.4,0,.2,1]},className:"flex items-center gap-2 sm:gap-1.5 min-w-0",children:[b.channelName&&s.jsx("span",{className:"hidden sm:inline-flex",children:s.jsx(Ve,{channelName:b.channelName})}),s.jsx("div",{className:"hidden sm:flex w-[30px] h-[30px] rounded-full items-center justify-center flex-shrink-0 ring-1 ring-edge-subtle",style:{backgroundColor:ss(ts(b.senderName||"").cleanName)},children:ts(b.senderName||"").emoji?s.jsx("span",{className:"text-base",children:ts(b.senderName||"").emoji}):s.jsx("span",{className:"text-white text-xs font-bold tracking-tighter",children:as(b.senderName||"")})}),s.jsx("div",{className:"inline-flex items-center px-3 py-1.5 rounded-2xl rounded-tr-md bg-[#007AFF] shadow-sm min-w-0 flex-1 sm:flex-initial sm:max-w-xs sm:-ml-px",children:s.jsx("span",{className:"text-sm text-white truncate tracking-wide",children:ns(b.text)})}),s.jsx("span",{className:"inline-flex items-center px-2 py-1 rounded-md bg-subtle-fill ring-1 ring-inset ring-edge-subtle text-sm tabular-nums text-fg-secondary flex-shrink-0",children:E(b.timestamp)})]},`msg-${b.timestamp}-${b.senderName}-${b.channelHash}`):f?s.jsx(oe.span,{initial:{opacity:0},animate:{opacity:1},className:"text-sm text-fg-muted italic",children:"No messages yet"},"empty"):s.jsxs(oe.div,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0,y:-16},transition:{duration:.15},className:"flex items-center gap-2 sm:gap-1.5",children:[s.jsx("div",{className:"hidden sm:block w-8 h-4 rounded bg-subtle-fill-strong animate-pulse"}),s.jsx("div",{className:"hidden sm:block w-[30px] h-[30px] rounded-full bg-subtle-fill-strong animate-pulse"}),s.jsx("div",{className:"h-8 w-32 sm:w-48 rounded-2xl bg-subtle-fill-strong animate-pulse"}),s.jsx("div",{className:"w-12 h-6 rounded-md bg-subtle-fill-strong animate-pulse"})]},"skeleton")}),s.jsx(Le,{className:"size-4 text-fg-muted group-hover:text-sys-indigo transition-colors flex-shrink-0 hidden sm:block ml-1"})]})]})}),s.jsx(tt,{open:n,onClose:()=>l(!1),messages:p,onLoadMore:M,hasMoreToLoad:k,isDecoding:j,initialChannel:i})]}):s.jsx("div",{className:"h-14 rounded-xl bg-elevated/50 animate-pulse"})}function nt(){var t,a;const n=f(),l=V(),i=u(),o=U(),r=e.useRef(!1);o&&!r.current&&(r.current=!0);const d=r.current,m=N(),x=W(),h=J(),g=w[m]??w[4],b=h.isBackgroundLoading&&m>=5,j=null==(t=null==n?void 0:n.config)?void 0:t.radio,v=e.useMemo(()=>j?{sf:j.spreading_factor??10,bw:j.bandwidth??25e4,cr:j.coding_rate??5,preamble:j.preamble_length??8}:null,[j]),y=i.length,k=e.useMemo(()=>y?K(g.minutes,g.buckets,i,n):null,[y,g.minutes,g.buckets,v]),M=e.useMemo(()=>{const e=e=>(null==e?void 0:e.reduce((e,s)=>e+s.count,0))??0,s=e(null==k?void 0:k.received),t=e(null==k?void 0:k.unique_received),a=e(null==k?void 0:k.forwarded),n=e(null==k?void 0:k.dropped),l=e(null==k?void 0:k.transmitted),i=((null==k?void 0:k.time_range_minutes)??g.minutes)/60;return{received:s,uniqueReceived:t,forwarded:a,dropped:n,transmitted:l,rxPerHour:i>0?Math.round(s/i):0,fwdPerHour:i>0?Math.round(a/i):0}},[k,g.minutes]),C=e.useMemo(()=>{if(!i.length)return{totalBytes:0,kbPerHour:0};const e=Date.now()/1e3,s=e-60*g.minutes;let t=0;for(const n of i)n.transmitted||n.timestamp<s||n.timestamp>e||(t+=n.length??n.payload_length??0);const a=g.minutes/60;return{totalBytes:t,kbPerHour:a>0?Math.round(t/1024/a):0}},[i,g.minutes]),S=(null==n?void 0:n.node_name)??(null==(a=null==n?void 0:n.config)?void 0:a.node_name)??"Unknown Node";return e.useEffect(()=>{S&&"Unknown Node"!==S&&(document.title=`pyMC: ${S}`)},[S]),l?s.jsxs(X,{neomorphic:!0,className:"p-8 text-center",children:[s.jsx("p",{className:"type-subheading text-sys-red mb-2",children:"Failed to connect to backend"}),s.jsx("p",{className:"type-body text-fg-muted",children:l}),s.jsx("p",{className:"type-data-sm text-fg-muted mt-4",children:"Make sure the backend is running on port 8000"})]}):s.jsxs(Q,{children:[s.jsx(Y,{title:S,icon:s.jsx(_e,{}),controls:s.jsx(Ke,{ranges:w,selectedIndex:m,onSelect:x,isPending:b})}),s.jsxs(Z,{children:[s.jsx(at,{isLoaded:d}),s.jsx(is,{template:"hero-auto",children:s.jsxs(X,{neomorphic:!0,children:[s.jsx(p,{icon:s.jsx(Re,{}),title:"PACKETS RECEIVED",badge:g.label,badgeColor:"zinc",actions:d?s.jsxs("div",{className:"data-box",children:[C.kbPerHour," KB/hr"]}):s.jsx("div",{className:"data-box opacity-0",children:"0 KB/hr"})}),s.jsxs("div",{className:"flex flex-wrap gap-4 sm:gap-8",children:[s.jsxs("div",{className:"flex items-end gap-2",children:[s.jsx("div",{className:"type-data-xl text-fg-primary",children:d?s.jsx(Pe,{value:M.received,className:"font-mono tabular-nums",priority:"high"}):s.jsx("span",{className:"opacity-30",children:"—"})}),s.jsx(c,{color:"zinc",className:"mb-0.5 sm:mb-1",children:"Total Rx"})]}),s.jsxs("div",{className:"flex items-end gap-2",children:[s.jsx("div",{className:"type-data-xl text-fg-primary",children:d?s.jsx(Pe,{value:M.uniqueReceived,className:"font-mono tabular-nums",priority:"high"}):s.jsx("span",{className:"opacity-30",children:"—"})}),s.jsx(c,{color:"zinc",className:"mb-0.5 sm:mb-1",children:"Unique"})]})]}),s.jsxs("div",{className:"mt-2 flex-1 min-h-0 relative",children:[s.jsx("div",{className:"absolute inset-0 flex items-end gap-1 transition-opacity duration-300 "+(d?"opacity-0 pointer-events-none":"opacity-100"),"aria-hidden":d,children:[45,72,33,58,80,42,65,28,55,75,38,62].map((e,t)=>s.jsx("div",{className:"flex-1 bg-subtle-fill rounded-sm animate-pulse",style:{height:`${e}%`}},t))}),s.jsx("div",{className:"h-full transition-opacity duration-300 "+(d?"opacity-100":"opacity-0"),children:s.jsx(cs,{packets:i,rangeMinutes:g.minutes,bucketCount:g.buckets})})]})]})}),s.jsxs(is,{template:"compact",children:[s.jsx(os,{span:6,lg:4,children:s.jsx(us,{value:M.forwarded,receivedCount:M.received,packets:i,rangeMinutes:g.minutes,bucketCount:g.buckets,timeRangeLabel:g.label,icon:s.jsx(De,{className:"w-4 h-4"}),isLoaded:d})}),s.jsx(os,{span:6,lg:4,children:s.jsx(hs,{value:M.dropped,receivedCount:M.received,packets:i,rangeMinutes:g.minutes,bucketCount:g.buckets,timeRangeLabel:g.label,icon:s.jsx($e,{className:"w-4 h-4"}),isLoaded:d})}),s.jsx(os,{span:12,lg:4,children:s.jsx(js,{stats:n,localHash:null==n?void 0:n.local_hash,receivedBuckets:null==k?void 0:k.received,droppedBuckets:null==k?void 0:k.dropped,forwardedBuckets:null==k?void 0:k.forwarded,bucketDurationSeconds:null==k?void 0:k.bucket_duration_seconds,timeRangeLabel:g.label,isLoaded:d})})]}),s.jsx(Js,{isLoaded:d}),s.jsx(ys,{}),n&&s.jsx(is,{template:"auto",children:s.jsx(es,{nodeName:S,repeaterVersion:n.version,coreVersion:n.core_version,localHash:n.local_hash,publicKey:n.public_key})})]})]})}export{nt as default};