// ADS-B OSINT layer specs (Wave 3.1), rendered by createAdsbLayer. All feeds are // FREE via adsb.lol (proxy/adsb/) — no key, works forever. Emergency is on // by default (usually empty = cheap, dramatic when not); the hunters are off. // ICAO type designator → readable name (rare-type hunter). const TYPE_NAMES = { U2: 'U-2 Dragon Lady (spyplane)', GHWK: 'RQ-4 Global Hawk (drone)', E3TF: 'E-3 Sentry (AWACS)', E3CF: 'E-3 Sentry (AWACS)', E6: 'E-6 Mercury (TACAMO)', E4: 'E-4B Nightwatch ("doomsday")', RC135: 'RC-135 Rivet Joint (recon)', B52: 'B-52 Stratofortress', P8: 'P-8 Poseidon (sub-hunter)', }; const HUNT_TYPES = Object.keys(TYPE_NAMES); const SQUAWK_MEANING = { 7500: 'HIJACK', 7600: 'RADIO FAIL', 7700: 'EMERGENCY' }; const SQUAWK_COLOR = { 7500: '#ff2d95', 7600: '#ff9f40', 7700: '#ff453a' }; const ftRow = (id) => [ ['Type', id.t || '—'], ['Reg', id.reg || '—'], ['Altitude', `${Math.round(id.altFt || 0)} ft`], ['Speed', `${Math.round(id.gs || 0)} kt`], ]; export const ADSB_LAYERS = [ { id: 'emergency', name: 'Emergency squawks', category: 'Air', defaultOn: true, pollMs: 60000, alertOnHits: true, endpoints: ['sqk/7700', 'sqk/7600', 'sqk/7500'], color: (a) => SQUAWK_COLOR[a.squawk] || '#ff453a', scale: 1.15, pickTitle: (id) => `⚠ ${SQUAWK_MEANING[id.squawk] || 'SQUAWK'} ${id.flight || id.hex}`, describe: (id) => [['Status', SQUAWK_MEANING[id.squawk] || id.squawk || '—'], ...ftRow(id)], status: (n) => `${n} squawking emergency ⚠`, emptyStatus: () => 'clear — no emergencies', }, { id: 'rare-types', name: 'Rare-type hunter', category: 'Air', defaultOn: false, pollMs: 120000, // These are all military types, so filter the shared /v2/mil feed (one cached // call the military layer already warms) instead of 8 rate-limited /type calls. endpoints: ['mil'], filter: (a) => HUNT_TYPES.includes(a.t), color: () => '#35e0ff', scale: 0.95, pickTitle: (id) => `✈ ${TYPE_NAMES[id.t] || id.t || 'aircraft'}`, describe: (id) => [['Aircraft', TYPE_NAMES[id.t] || id.t || '—'], ['Callsign', id.flight || '—'], ['Reg', id.reg || '—'], ['Altitude', `${Math.round(id.altFt || 0)} ft`], ['Speed', `${Math.round(id.gs || 0)} kt`]], status: (n) => `${n} rare-type aircraft up`, emptyStatus: () => 'none of the tracked types airborne', }, { id: 'shadow', name: 'Blocked / shadow aircraft', category: 'Air', defaultOn: false, pollMs: 120000, endpoints: ['ladd', 'pia'], color: (a) => (a._src === 'pia' ? '#ff7bd5' : '#b57bff'), scale: 0.8, pickTitle: (id) => `👤 ${id.reg || id.flight || id.hex}`, describe: (id) => [ ['Program', id.src === 'pia' ? 'PIA (privacy address)' : 'LADD (FAA limited-display)'], ...ftRow(id), ], status: (n) => `${n} blocked/shadow aircraft`, }, ];