- Replace inline onclick on <tr> elements with data-action/data-value attributes
- Add tabindex="0" and role="row" to all clickable rows
- Add delegated click and keydown (Enter/Space) listeners on containers
- Remove window._pktSelect, _pktToggleGroup, _pktSelectHash, _nodeSelect globals
- Convert to local functions referenced by delegated handlers
Affected files: packets.js, nodes.js, analytics.js
(channels.js and observers.js had no interactive <tr> elements)
- max-width 900px → 1600px for analytics page
- Added analytics-grid CSS class for auto-fit columns
- Hash Stats: distribution + timeline side-by-side, adopters + top hops side-by-side
- RF, Topology, Channels already used analytics-row flex layout
- Cards now fill available screen width instead of being squished
Each cell displays the hex prefix (AB, C3, etc). Color meaning:
- Dark: unused prefix (no known nodes)
- Green: 1 node using it (safe, no collision)
- Yellow→Red: 2+ nodes sharing prefix (collision risk)
Legend added below matrix.
1-byte collision table now shows:
- Max pairwise distance between colliding nodes
- Classification: Local (<50km, true collision), Regional (50-200km,
possible atmospheric), Distant (>200km, internet bridge/MQTT/separate mesh)
- Coordinates for each node
- Legend explaining each classification
- Sorted: distant first (most interesting)
VCR: playhead now stays where you drag it — updateTimelinePlayhead()
skips during drag (VCR.dragging flag). Always update playhead visually
via direct DOM during scrub instead of relying on buffer position calc.
Packets: replay button compact, inline next to View Route button.
Analytics: channel links now navigate to specific channel hash.
- Detail sidebar starts collapsed, expands on click (420px, max 50vw)
- Route column allows word wrap instead of forced nowrap
- Tables use auto layout for breathing room
- List panel has min-width:0 to prevent flex overflow
- Smoother transitions on sidebar open
Click any route in Route Patterns to open detail sidebar showing:
- Minimap with nodes and route line (green=origin, red=dest, amber=hops)
- Signal quality (avg SNR/RSSI)
- Activity by hour (UTC) bar chart
- First/last seen timestamps
- Observers that captured this route
- Full parent paths containing this subpath
Split layout with scrollable list + fixed sidebar, responsive on mobile.
Each hop now displays as 'NodeName [ab]' with the hex prefix visible.
Makes prefix collisions obvious — e.g. same prefix resolving to same
name confirms it's a collision, different prefixes confirm real route.
New 'Route Patterns' analytics tab showing most common subpaths in the
mesh, broken down by length (pairs, triples, quads, long chains).
Reveals backbone routes, bottlenecks, and preferred relay chains.
Each subpath shows occurrence count, % of all paths, and frequency bar.