feat: recon surveys with OUI/vendor lookup and report views

Reconnaissance surveys (GPSD-tethered scan recording), OUI vendor
lookup for client/AP tables, survey/report pages, and the matching
test_recon.py suite. Co-authored with the recon-feature agent whose
work was finished in this checkout.
This commit is contained in:
2026-08-18 08:35:22 -05:00
parent f5cddb335a
commit 251b1f6261
7 changed files with 2095 additions and 45 deletions
@@ -30,5 +30,11 @@ window.PineappleIcons = {
help: '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12,2A10,10 0 1,0 22,12A10,10 0 0,0 12,2M13,19H11V17H13V19M15.07,11.25L14.17,12.17C13.45,12.9 13,13.5 13,15H11V14.5C11,13.4 11.45,12.4 12.17,11.67L13.41,10.41C13.78,10.05 14,9.55 14,9A2,2 0 0,0 10,9H8A4,4 0 0,1 16,9C16,9.88 15.64,10.68 15.07,11.25Z"/></svg>',
update: '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M21,10.12H14.22L16.96,7.3C14.23,4.6 9.81,4.5 7.08,7.2A6.85,6.85 0 0,0 7.08,17C9.81,19.7 14.23,19.7 16.96,17C18.32,15.65 19,14.08 19,12.1H21C21,14.08 20.18,16.4 18.36,18.2C14.85,21.7 9.15,21.7 5.64,18.2C2.14,14.72 2.14,9.05 5.64,5.57C9.15,2.08 14.85,2.08 18.36,5.57L21,2.88V10.12M12.5,8V12.25L16,14.33L15.28,15.54L11,13V8H12.5Z"/></svg>',
logout: '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M14.08,15.59L16.67,13H7V11H16.67L14.08,8.41L15.5,7L20.5,12L15.5,17L14.08,15.59M5,3H13A2,2 0 0,1 15,5V8H13V5H5V19H13V16H15V19A2,2 0 0,1 13,21H5A2,2 0 0,1 3,19V5A2,2 0 0,1 5,3Z"/></svg>',
reboot: '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M13,3H11V13H13V3M17.83,5.17L16.42,6.58A7,7 0 1,1 7.58,6.58L6.17,5.17A9,9 0 1,0 17.83,5.17Z"/></svg>'
reboot: '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M13,3H11V13H13V3M17.83,5.17L16.42,6.58A7,7 0 1,1 7.58,6.58L6.17,5.17A9,9 0 1,0 17.83,5.17Z"/></svg>',
table_chart: '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12,20H9V4H12V20M19,20H16V10H19V20M5,20H2V14H5V20Z"/></svg>',
description: '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M14,2H6C4.9,2 4,2.9 4,4V20C4,21.1 4.9,22 6,22H18C19.1,22 20,21.1 20,20V8L14,2M18,20H6V4H13V9H18V20M16,18H8V16H16V18M16,14H8V12H16V14Z"/></svg>',
record: '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z"/></svg>',
place: '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12,2A7,7 0 0,0 5,9C5,14.25 12,22 12,22C12,22 19,14.25 19,9A7,7 0 0,0 12,2M12,11.5A2.5,2.5 0 0,1 9.5,9A2.5,2.5 0 0,1 12,6.5A2.5,2.5 0 0,1 14.5,9A2.5,2.5 0 0,1 12,11.5Z"/></svg>',
play_arrow: '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M8,5.14V19.14L19,12.14L8,5.14Z"/></svg>',
stop: '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M18,18H6V6H18V18Z"/></svg>'
};