'use client'; import { useEffect, useRef, useState, useCallback, memo } from 'react'; import maplibregl from 'maplibre-gl'; import 'maplibre-gl/dist/maplibre-gl.css'; interface OsirisMapProps { data: any; activeLayers: Record; onEntityClick?: (entity: any) => void; onMouseCoords?: (coords: { lat: number; lng: number }) => void; onRightClick?: (coords: { lat: number; lng: number }) => void; onViewStateChange?: (vs: { zoom: number; latitude: number }) => void; flyToLocation?: { lat: number; lng: number; zoom?: number; ts: number } | null; projection?: 'mercator' | 'globe'; mapStyle?: string; sweepData?: any; scanTargets?: any[]; demoMode?: boolean; theme?: 'core' | 'ghost'; } function computeSolarTerminator(): [number, number][] { const now = new Date(); const dayOfYear = Math.floor((now.getTime() - new Date(now.getFullYear(), 0, 0).getTime()) / 86400000); const declination = -23.44 * Math.cos((2 * Math.PI / 365) * (dayOfYear + 10)); const decRad = declination * Math.PI / 180; const utcHours = now.getUTCHours() + now.getUTCMinutes() / 60; const subsolarLng = (12 - utcHours) * 15; const points: [number, number][] = []; for (let lng = -180; lng <= 180; lng += 2) { const lngRad = (lng - subsolarLng) * Math.PI / 180; const lat = Math.atan(-Math.cos(lngRad) / Math.tan(decRad)) * 180 / Math.PI; points.push([lng, lat]); } const darkSide = declination >= 0 ? -90 : 90; points.push([180, darkSide]); points.push([-180, darkSide]); points.push(points[0]); return points; } const EMPTY_FC = { type: 'FeatureCollection' as const, features: [] }; function OsirisMap({ data, activeLayers, onEntityClick, onMouseCoords, onRightClick, onViewStateChange, flyToLocation, projection = 'globe', mapStyle = 'dark', sweepData, scanTargets = [], demoMode = false, theme = 'core' }: OsirisMapProps) { const containerRef = useRef(null); const mapRef = useRef(null); const popupRef = useRef(null); const [mapReady, setMapReady] = useState(false); const prevStyleRef = useRef(mapStyle); // Create aircraft icon on canvas (for WebGL symbol layer) const createIcon = useCallback((map: maplibregl.Map, id: string, color: string, size: number) => { if (map.hasImage(id)) return; const canvas = document.createElement('canvas'); canvas.width = size; canvas.height = size; const ctx = canvas.getContext('2d')!; const cx = size / 2, cy = size / 2; ctx.fillStyle = color; ctx.beginPath(); ctx.moveTo(cx, cy - size * 0.4); ctx.lineTo(cx - size * 0.12, cy + size * 0.1); ctx.lineTo(cx - size * 0.4, cy + size * 0.2); ctx.lineTo(cx - size * 0.4, cy + size * 0.3); ctx.lineTo(cx - size * 0.12, cy + size * 0.15); ctx.lineTo(cx, cy + size * 0.35); ctx.lineTo(cx + size * 0.12, cy + size * 0.15); ctx.lineTo(cx + size * 0.4, cy + size * 0.3); ctx.lineTo(cx + size * 0.4, cy + size * 0.2); ctx.lineTo(cx + size * 0.12, cy + size * 0.1); ctx.closePath(); ctx.fill(); map.addImage(id, { width: size, height: size, data: new Uint8Array(ctx.getImageData(0, 0, size, size).data) }); }, []); const createDot = useCallback((map: maplibregl.Map, id: string, color: string, size: number) => { if (map.hasImage(id)) return; const canvas = document.createElement('canvas'); canvas.width = size; canvas.height = size; const ctx = canvas.getContext('2d')!; ctx.fillStyle = color; ctx.beginPath(); ctx.arc(size/2, size/2, size/2 - 1, 0, Math.PI * 2); ctx.fill(); map.addImage(id, { width: size, height: size, data: new Uint8Array(ctx.getImageData(0, 0, size, size).data) }); }, []); useEffect(() => { if (!mapRef.current) return; const map = mapRef.current; // ── DEMO MODE SPINNING ── let spinReq: number | undefined = undefined; let isSpinning = false; const startSpinning = () => { if (!map) return; isSpinning = true; let lastTime = performance.now(); const frame = (time: number) => { if (!isSpinning) return; // Only spin if the user is not actively dragging or zooming the map if (!map.isMoving() && !map.isZooming()) { const dt = time - lastTime; const center = map.getCenter(); // Adjust spin speed: 0.5 degrees per second center.lng += (0.5 * dt) / 1000; map.setCenter(center); } lastTime = time; spinReq = requestAnimationFrame(frame); }; spinReq = requestAnimationFrame(frame); }; if (demoMode) { startSpinning(); } else { isSpinning = false; if (spinReq) cancelAnimationFrame(spinReq); } return () => { isSpinning = false; if (spinReq) cancelAnimationFrame(spinReq); if (typeof window !== 'undefined' && (window as any)._globeSpinTimer) { clearInterval((window as any)._globeSpinTimer); } }; }, [mapReady, demoMode]); useEffect(() => { if (!containerRef.current || mapRef.current) return; // Select basemap style const styleUrl = 'https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json'; const map = new maplibregl.Map({ container: containerRef.current, style: styleUrl, center: [25.48, 42.70], zoom: 6.5, minZoom: 1.5, maxZoom: 18, attributionControl: false, maxPitch: 85, transformRequest: (url: string) => { // Route all CARTO CDN requests through the internal Next.js proxy API if (url.includes('cartocdn.com')) { const baseUrl = typeof window !== 'undefined' ? window.location.origin : ''; return { url: `${baseUrl}/api/proxy-tiles?url=${encodeURIComponent(url)}` }; } return { url }; }, }); map.on('load', () => { mapRef.current = map; // Theme colors const isGhost = theme === 'ghost'; const phantomPurple = '#B388FF'; const phantomDark = '#1A0040'; const cameraColor = isGhost ? '#B388FF' : '#00E676'; const flightCom = isGhost ? phantomPurple : '#00E5FF'; const flightPriv = isGhost ? phantomPurple : '#FFD700'; const flightGov = isGhost ? phantomPurple : '#FF9500'; const flightMil = isGhost ? phantomPurple : '#FF3D3D'; // Create icons — OSIRIS Unified Palette createIcon(map, 'plane-cyan', flightCom, 24); createIcon(map, 'plane-green', flightPriv, 24); createIcon(map, 'plane-pink', flightGov, 24); createIcon(map, 'plane-red', flightMil, 24); createIcon(map, 'plane-grey', isGhost ? phantomPurple : '#546E7A', 24); createDot(map, 'dot-gold', isGhost ? phantomPurple : '#D4AF37', 8); createDot(map, 'dot-red', isGhost ? phantomPurple : '#D32F2F', 10); createDot(map, 'dot-orange', isGhost ? phantomPurple : '#E65100', 10); createDot(map, 'dot-green', isGhost ? phantomPurple : '#26A69A', 10); createDot(map, 'dot-fire', isGhost ? phantomPurple : '#E65100', 10); createDot(map, 'dot-cctv', cameraColor, 10); const sources = ['flights','military','jets','private-fl','satellites','earthquakes','gdelt','gps-jamming','day-night','cctv','fires','weather','infrastructure','maritime','maritime-choke','maritime-ships','live-news','sigint-news','conflict-zones', 'war-alerts-targets', 'war-alerts-lines', 'balloons', 'radiation', 'ip-sweep-devices', 'ip-sweep-pulse', 'ip-sweep-connections', 'scan-targets', 'sdk-entities', 'sdk-links', 'malware-nodes', 'network-mesh', 'mining-sites', 'ram-sites']; sources.forEach(s => map.addSource(s, { type: 'geojson', data: EMPTY_FC })); // Warning icon generator (parameterized — eliminates 3x copy-paste) const createWarningIcon = (id: string, color: string) => { const s = 20; const c = document.createElement('canvas'); c.width = s; c.height = s; const ctx = c.getContext('2d')!; ctx.fillStyle = color; ctx.beginPath(); ctx.moveTo(s/2, 1); ctx.lineTo(s - 1, s - 1); ctx.lineTo(1, s - 1); ctx.closePath(); ctx.fill(); ctx.fillStyle = '#000'; ctx.font = 'bold 11px sans-serif'; ctx.textAlign = 'center'; ctx.fillText('!', s/2, s - 4); map.addImage(id, { width: s, height: s, data: new Uint8Array(ctx.getImageData(0, 0, s, s).data) }); }; createWarningIcon('warn-icon', '#D32F2F'); createWarningIcon('warn-orange', '#E65100'); createWarningIcon('warn-yellow', '#F9A825'); map.addLayer({ id: 'conflict-icons', type: 'symbol', source: 'conflict-zones', layout: { 'icon-image': ['match', ['get','severity'], 'war','warn-icon', 'high','warn-orange', 'warn-yellow'], 'icon-size': ['interpolate',['linear'],['zoom'], 1,0.6, 4,0.8, 8,1], 'icon-allow-overlap': true, 'text-field': ['get','label'], 'text-size': ['interpolate',['linear'],['zoom'], 1,7, 4,9, 8,11], 'text-font': ['Open Sans Bold'], 'text-offset': [0, 1.4], 'text-allow-overlap': false, }, paint: { 'text-color': ['match', ['get','severity'], 'war','#D32F2F', 'high','#E65100', '#F9A825'], 'text-halo-color': '#000', 'text-halo-width': 1.5, 'text-opacity': 0.9, }}); // Day/Night map.addLayer({ id: 'day-night-fill', type: 'fill', source: 'day-night', paint: { 'fill-color': isGhost ? '#0D0030' : '#000022', 'fill-opacity': 0.35 }}); // Earthquakes — amber threat spectrum map.addLayer({ id: 'eq-circles', type: 'circle', source: 'earthquakes', paint: { 'circle-radius': ['interpolate',['linear'],['get','magnitude'], 2.5,4, 5,12, 7,24], 'circle-color': ['interpolate',['linear'],['get','magnitude'], 2.5,'#F9A825', 4,'#E65100', 6,'#D32F2F'], 'circle-opacity': 0.55, 'circle-blur': 0.3, 'circle-stroke-width': 1, 'circle-stroke-color': '#F9A825', 'circle-stroke-opacity': 0.25, }}); map.addLayer({ id: 'eq-label', type: 'symbol', source: 'earthquakes', filter: ['>=',['get','magnitude'],4.5], layout: { 'text-field': ['concat','M',['to-string',['get','magnitude']]], 'text-size': 9, 'text-font': ['Open Sans Regular'], 'text-offset': [0,1.5], }, paint: { 'text-color': '#F9A825', 'text-halo-color': '#000', 'text-halo-width': 1 }}); // Fires — burnt sienna map.addLayer({ id: 'fires-heat', type: 'circle', source: 'fires', paint: { 'circle-radius': ['interpolate',['linear'],['zoom'], 1,2, 5,4, 10,8], 'circle-color': '#E65100', 'circle-opacity': 0.45, 'circle-blur': 0.5, }}); // CCTV — outer glow ring (black/white depending on theme) map.addLayer({ id: 'cctv-glow', type: 'circle', source: 'cctv', paint: { 'circle-radius': ['interpolate',['linear'],['zoom'], 1,5, 5,8, 10,14, 14,20], 'circle-color': '#000000', 'circle-opacity': 0.35, 'circle-blur': 1, }}); // CCTV — main dot map.addLayer({ id: 'cctv-dots', type: 'circle', source: 'cctv', paint: { 'circle-radius': ['interpolate',['linear'],['zoom'], 1,3, 5,5, 10,8, 14,12], 'circle-color': cameraColor, 'circle-opacity': 0.9, 'circle-stroke-width': 2.5, 'circle-stroke-color': '#000000', 'circle-stroke-opacity': 0.9, }}); // CCTV — labels at zoom 10+ map.addLayer({ id: 'cctv-label', type: 'symbol', source: 'cctv', minzoom: 10, layout: { 'text-field': ['get','name'], 'text-size': 9, 'text-font': ['Open Sans Regular'], 'text-offset': [0, 1.8], 'text-max-width': 12, 'text-allow-overlap': false, }, paint: { 'text-color': cameraColor, 'text-halo-color': '#000000', 'text-halo-width': 1.5, 'text-opacity': 0.8 }}); // GDELT // ══ NETWORK INTEL — Live Malware (abuse.ch) — crimson threat ══ map.addLayer({ id: 'malware-glow', type: 'circle', source: 'malware-nodes', paint: { 'circle-radius': ['interpolate',['linear'],['zoom'], 1,6, 5,12, 10,20], 'circle-color': '#D32F2F', 'circle-opacity': 0.06, 'circle-blur': 0.5, }}); map.addLayer({ id: 'malware-dots', type: 'circle', source: 'malware-nodes', paint: { 'circle-radius': ['interpolate',['linear'],['zoom'], 1,2, 5,4, 10,6], 'circle-color': '#D32F2F', 'circle-opacity': 0.9, 'circle-stroke-width': 1, 'circle-stroke-color': '#000000', 'circle-stroke-opacity': 0.8, }}); map.addLayer({ id: 'malware-label', type: 'symbol', source: 'malware-nodes', minzoom: 5, layout: { 'text-field': ['get','malware'], 'text-size': 8, 'text-font': ['JetBrains Mono Bold', 'Open Sans Bold'], 'text-offset': [0, 1.5], 'text-max-width': 10, 'text-allow-overlap': false, }, paint: { 'text-color': '#D32F2F', 'text-halo-color': '#111', 'text-halo-width': 1.5, 'text-opacity': 0.85 }}); // ── NETWORK INTEL MESH (SDK STYLE) ── map.addLayer({ id: 'network-mesh-atmo', type: 'line', source: 'network-mesh', paint: { 'line-width': ['interpolate',['linear'],['zoom'], 1, 2, 5, 4, 10, 8], 'line-opacity': 0.08, 'line-blur': 4, }}); map.addLayer({ id: 'network-mesh-glow', type: 'line', source: 'network-mesh', paint: { 'line-width': ['interpolate',['linear'],['zoom'], 1, 1, 5, 2, 10, 4], 'line-opacity': 0.2, 'line-blur': 1.5, }}); map.addLayer({ id: 'network-mesh-core', type: 'line', source: 'network-mesh', paint: { 'line-width': ['interpolate',['linear'],['zoom'], 1, 0.2, 5, 0.5, 10, 1.5], 'line-opacity': 0.4, }}); map.addLayer({ id: 'gdelt-dots', type: 'circle', source: 'gdelt', paint: { 'circle-radius': 4, 'circle-color': '#D32F2F', 'circle-opacity': 0.5, 'circle-stroke-width': 1, 'circle-stroke-color': '#D32F2F', 'circle-stroke-opacity': 0.25, }}); // GPS Jamming — crimson map.addLayer({ id: 'jam-fill', type: 'circle', source: 'gps-jamming', paint: { 'circle-radius': 30, 'circle-color': '#D32F2F', 'circle-opacity': 0.12, 'circle-blur': 1 }}); map.addLayer({ id: 'jam-label', type: 'symbol', source: 'gps-jamming', layout: { 'text-field': ['concat','GPS JAM ',['to-string',['get','severity']],'%'], 'text-size': 10, 'text-font': ['Open Sans Bold'], 'text-allow-overlap': true, }, paint: { 'text-color': '#D32F2F', 'text-halo-color': '#000', 'text-halo-width': 1 }}); // Weather Events (NASA EONET) — deep violet map.addLayer({ id: 'weather-glow', type: 'circle', source: 'weather', paint: { 'circle-radius': ['interpolate',['linear'],['zoom'], 1,12, 5,20, 10,30], 'circle-color': '#7E57C2', 'circle-opacity': 0.08, 'circle-blur': 1, }}); map.addLayer({ id: 'weather-dots', type: 'circle', source: 'weather', paint: { 'circle-radius': ['interpolate',['linear'],['zoom'], 1,5, 5,8, 10,14], 'circle-color': ['match', ['get','icon'], 'cyclone','#7E57C2', 'volcano','#D32F2F', '#7E57C2'], 'circle-opacity': 0.75, 'circle-stroke-width': 1.5, 'circle-stroke-color': '#7E57C2', 'circle-stroke-opacity': 0.35, }}); map.addLayer({ id: 'weather-label', type: 'symbol', source: 'weather', layout: { 'text-field': ['get','title'], 'text-size': 9, 'text-font': ['Open Sans Regular'], 'text-offset': [0, 2], 'text-max-width': 14, 'text-allow-overlap': false, }, paint: { 'text-color': '#7E57C2', 'text-halo-color': '#000', 'text-halo-width': 1, 'text-opacity': 0.8 }}); // Nuclear Infrastructure — teal / amber risk map.addLayer({ id: 'infra-glow', type: 'circle', source: 'infrastructure', paint: { 'circle-radius': ['interpolate',['linear'],['zoom'], 1,8, 5,14, 10,22], 'circle-color': ['case', ['in', 'SEISMIC RISK', ['get', 'status']], '#E65100', '#26A69A'], 'circle-opacity': 0.08, 'circle-blur': 1, }}); map.addLayer({ id: 'infra-dots', type: 'circle', source: 'infrastructure', paint: { 'circle-radius': ['interpolate',['linear'],['zoom'], 1,4, 5,6, 10,10], 'circle-color': ['case', ['in', 'SEISMIC RISK', ['get', 'status']], '#E65100', ['==', ['get','status'], 'Active Conflict Zone'], '#D32F2F', ['==', ['get','status'], 'Destroyed / Decommissioning'], '#546E7A', '#26A69A' ], 'circle-opacity': 0.75, 'circle-stroke-width': 1.5, 'circle-stroke-color': ['case', ['in', 'SEISMIC RISK', ['get', 'status']], '#E65100', '#26A69A'], 'circle-stroke-opacity': 0.35, }}); map.addLayer({ id: 'infra-label', type: 'symbol', source: 'infrastructure', minzoom: 5, layout: { 'text-field': ['get','name'], 'text-size': 9, 'text-font': ['Open Sans Regular'], 'text-offset': [0, 2], 'text-max-width': 14, 'text-allow-overlap': false, }, paint: { 'text-color': ['case', ['in', 'SEISMIC RISK', ['get', 'status']], '#E65100', '#26A69A'], 'text-halo-color': '#000', 'text-halo-width': 1, 'text-opacity': 0.7 }}); // Mining Companies — colored by commodity category const miningColor: any = ['match', ['get','category'], 'copper','#FF8A65', 'gold','#FFD54F', 'silver','#CFD8DC', 'pgm','#4DB6AC', 'rare_earth','#BA68C8', '#FFB74D']; map.addLayer({ id: 'mining-glow', type: 'circle', source: 'mining-sites', paint: { 'circle-radius': ['interpolate',['linear'],['zoom'], 1,8, 5,14, 10,22], 'circle-color': miningColor, 'circle-opacity': 0.08, 'circle-blur': 1, }}); map.addLayer({ id: 'mining-dots', type: 'circle', source: 'mining-sites', paint: { 'circle-radius': ['interpolate',['linear'],['zoom'], 1,4, 5,6, 10,10], 'circle-color': miningColor, 'circle-opacity': 0.8, 'circle-stroke-width': 1.5, 'circle-stroke-color': miningColor, 'circle-stroke-opacity': 0.35, }}); map.addLayer({ id: 'mining-label', type: 'symbol', source: 'mining-sites', minzoom: 4, layout: { 'text-field': ['get','site'], 'text-size': 9, 'text-font': ['Open Sans Regular'], 'text-offset': [0, 2], 'text-max-width': 14, 'text-allow-overlap': false, }, paint: { 'text-color': miningColor, 'text-halo-color': '#000', 'text-halo-width': 1, 'text-opacity': 0.75 }}); // Memory / RAM Fabs — colored by ecosystem role const ramColor: any = ['match', ['get','category'], 'dram_hbm','#4FC3F7', 'nand','#81C784', 'controller_ip','#FFF176', 'module_maker','#90A4AE', 'packaging_test','#F06292', 'equipment','#9575CD', '#4FC3F7']; map.addLayer({ id: 'ram-glow', type: 'circle', source: 'ram-sites', paint: { 'circle-radius': ['interpolate',['linear'],['zoom'], 1,8, 5,14, 10,22], 'circle-color': ramColor, 'circle-opacity': 0.08, 'circle-blur': 1, }}); map.addLayer({ id: 'ram-dots', type: 'circle', source: 'ram-sites', paint: { 'circle-radius': ['interpolate',['linear'],['zoom'], 1,4, 5,6, 10,10], 'circle-color': ramColor, 'circle-opacity': 0.8, 'circle-stroke-width': 1.5, 'circle-stroke-color': ramColor, 'circle-stroke-opacity': 0.35, }}); map.addLayer({ id: 'ram-label', type: 'symbol', source: 'ram-sites', minzoom: 4, layout: { 'text-field': ['get','company'], 'text-size': 9, 'text-font': ['Open Sans Regular'], 'text-offset': [0, 2], 'text-max-width': 14, 'text-allow-overlap': false, }, paint: { 'text-color': ramColor, 'text-halo-color': '#000', 'text-halo-width': 1, 'text-opacity': 0.75 }}); // Satellites map.addLayer({ id: 'sat-glow', type: 'circle', source: 'satellites', paint: { 'circle-radius': ['interpolate',['linear'],['zoom'], 1,3, 5,6], 'circle-color': ['get','color'], 'circle-opacity': 0.3, 'circle-blur': 1, }}); map.addLayer({ id: 'sat-dots', type: 'circle', source: 'satellites', paint: { 'circle-radius': ['interpolate',['linear'],['zoom'], 1,1.5, 5,3], 'circle-color': ['get','color'], 'circle-opacity': 1.0, }}); // Maritime — ports & naval bases — ocean teal map.addLayer({ id: 'maritime-glow', type: 'circle', source: 'maritime', paint: { 'circle-radius': ['interpolate',['linear'],['zoom'], 1,6, 5,12, 10,20], 'circle-color': ['match', ['get','type'], 'naval','#D32F2F', 'energy','#E65100', '#26C6DA'], 'circle-opacity': 0.08, 'circle-blur': 1, }}); map.addLayer({ id: 'maritime-dots', type: 'circle', source: 'maritime', paint: { 'circle-radius': ['interpolate',['linear'],['zoom'], 1,3, 5,5, 10,9], 'circle-color': ['match', ['get','type'], 'naval','#D32F2F', 'energy','#E65100', '#26C6DA'], 'circle-opacity': 0.8, 'circle-stroke-width': 1.5, 'circle-stroke-color': ['match', ['get','type'], 'naval','#D32F2F', 'energy','#E65100', '#26C6DA'], 'circle-stroke-opacity': 0.35, }}); map.addLayer({ id: 'maritime-label', type: 'symbol', source: 'maritime', minzoom: 4, layout: { 'text-field': ['get','name'], 'text-size': 9, 'text-font': ['Open Sans Regular'], 'text-offset': [0, 1.8], 'text-max-width': 12, 'text-allow-overlap': false, }, paint: { 'text-color': '#26C6DA', 'text-halo-color': '#000', 'text-halo-width': 1, 'text-opacity': 0.7 }}); // Maritime chokepoints — amber threat spectrum map.addLayer({ id: 'choke-glow', type: 'circle', source: 'maritime-choke', paint: { 'circle-radius': ['interpolate',['linear'],['zoom'], 1,10, 5,18, 10,28], 'circle-color': '#E65100', 'circle-opacity': 0.1, 'circle-blur': 1, }}); map.addLayer({ id: 'choke-dots', type: 'circle', source: 'maritime-choke', paint: { 'circle-radius': ['interpolate',['linear'],['zoom'], 1,4, 5,7, 10,12], 'circle-color': ['match', ['get','risk'], 'CRITICAL','#D32F2F', 'HIGH','#E65100', 'ELEVATED','#F9A825', '#26A69A'], 'circle-opacity': 0.85, 'circle-stroke-width': 1.5, 'circle-stroke-color': '#E65100', 'circle-stroke-opacity': 0.4, }}); map.addLayer({ id: 'choke-label', type: 'symbol', source: 'maritime-choke', minzoom: 3, layout: { 'text-field': ['get','name'], 'text-size': 10, 'text-font': ['Open Sans Bold'], 'text-offset': [0, 2], 'text-max-width': 14, 'text-allow-overlap': false, }, paint: { 'text-color': '#E65100', 'text-halo-color': '#000', 'text-halo-width': 1, 'text-opacity': 0.9 }}); // Live News — muted rose map.addLayer({ id: 'news-glow', type: 'circle', source: 'live-news', paint: { 'circle-radius': ['interpolate',['linear'],['zoom'], 1,8, 5,14, 10,22], 'circle-color': '#EC407A', 'circle-opacity': 0.08, 'circle-blur': 1, }}); map.addLayer({ id: 'news-dots', type: 'circle', source: 'live-news', paint: { 'circle-radius': ['interpolate',['linear'],['zoom'], 1,4, 5,6, 10,10], 'circle-color': '#EC407A', 'circle-opacity': 0.8, 'circle-stroke-width': 1.5, 'circle-stroke-color': '#EC407A', 'circle-stroke-opacity': 0.4, }}); map.addLayer({ id: 'news-label', type: 'symbol', source: 'live-news', minzoom: 4, layout: { 'text-field': ['get','name'], 'text-size': 9, 'text-font': ['Open Sans Regular'], 'text-offset': [0, 1.8], 'text-max-width': 12, 'text-allow-overlap': false, }, paint: { 'text-color': '#EC407A', 'text-halo-color': '#000', 'text-halo-width': 1, 'text-opacity': 0.8 }}); // SIGINT RSS news - gold markers map.addLayer({ id: 'sigint-news-glow', type: 'circle', source: 'sigint-news', paint: { 'circle-radius': ['interpolate',['linear'],['zoom'], 1,6, 5,10, 10,18], 'circle-color': '#D4AF37', 'circle-opacity': 0.12, 'circle-blur': 1, }}); map.addLayer({ id: 'sigint-news-dots', type: 'circle', source: 'sigint-news', paint: { 'circle-radius': ['interpolate',['linear'],['zoom'], 1,3, 5,5, 10,8], 'circle-color': '#D4AF37', 'circle-opacity': 0.9, 'circle-stroke-width': 1.5, 'circle-stroke-color': '#FFF8DC', 'circle-stroke-opacity': 0.6, }}); map.addLayer({ id: 'sigint-news-label', type: 'symbol', source: 'sigint-news', minzoom: 5, layout: { 'text-field': ['get','source'], 'text-size': 9, 'text-font': ['Open Sans Regular'], 'text-offset': [0, 1.6], 'text-max-width': 10, 'text-allow-overlap': false, }, paint: { 'text-color': '#D4AF37', 'text-halo-color': '#000', 'text-halo-width': 1, 'text-opacity': 0.85 }}); // ══ IP SWEEP — Neighborhood device visualization ══ map.addLayer({ id: 'sweep-connections', type: 'line', source: 'ip-sweep-connections', paint: { 'line-color': ['get', 'color'], 'line-width': 1, 'line-opacity': 0.3, 'line-dasharray': [2, 4], }}); map.addLayer({ id: 'sweep-pulse-ring', type: 'circle', source: 'ip-sweep-pulse', paint: { 'circle-radius': ['interpolate',['linear'],['zoom'], 8,40, 12,80, 16,160], 'circle-color': 'transparent', 'circle-opacity': 0.6, 'circle-stroke-width': 2, 'circle-stroke-color': '#FF3D3D', 'circle-stroke-opacity': 0.4, }}); map.addLayer({ id: 'sweep-device-glow', type: 'circle', source: 'ip-sweep-devices', paint: { 'circle-radius': ['interpolate',['linear'],['zoom'], 8,8, 12,16, 16,30], 'circle-color': ['get', 'color'], 'circle-opacity': 0.15, 'circle-blur': 1, }}); map.addLayer({ id: 'sweep-device-dots', type: 'circle', source: 'ip-sweep-devices', paint: { 'circle-radius': ['interpolate',['linear'],['zoom'], 8,3, 12,6, 16,10], 'circle-color': ['get', 'color'], 'circle-opacity': 0.95, 'circle-stroke-width': 1.5, 'circle-stroke-color': '#FFFFFF', 'circle-stroke-opacity': 0.6, }}); map.addLayer({ id: 'sweep-device-labels', type: 'symbol', source: 'ip-sweep-devices', minzoom: 13, layout: { 'text-field': ['concat', ['get', 'device_type'], '\n', ['get', 'ip']], 'text-size': 9, 'text-font': ['Open Sans Regular'], 'text-offset': [0, 2.2], 'text-max-width': 12, 'text-allow-overlap': false, }, paint: { 'text-color': ['get', 'color'], 'text-halo-color': '#000', 'text-halo-width': 1.5, 'text-opacity': 0.9, }}); // ══ SCAN TARGETS — Geolocated individual scans ══ map.addLayer({ id: 'scan-targets-glow', type: 'circle', source: 'scan-targets', paint: { 'circle-radius': ['interpolate',['linear'],['zoom'], 1,12, 5,25, 10,40], 'circle-color': '#D32F2F', 'circle-opacity': 0.15, 'circle-blur': 1, }}); map.addLayer({ id: 'scan-targets-dots', type: 'circle', source: 'scan-targets', paint: { 'circle-radius': ['interpolate',['linear'],['zoom'], 1,5, 5,8, 10,12], 'circle-color': '#D32F2F', 'circle-opacity': 0.9, 'circle-stroke-width': 1.5, 'circle-stroke-color': '#ECEFF1', 'circle-stroke-opacity': 0.7, }}); map.addLayer({ id: 'scan-targets-label', type: 'symbol', source: 'scan-targets', layout: { 'text-field': ['get', 'id'], 'text-size': 11, 'text-font': ['Open Sans Bold'], 'text-offset': [0, 2], 'text-max-width': 14, 'text-allow-overlap': false, }, paint: { 'text-color': '#D32F2F', 'text-halo-color': '#000', 'text-halo-width': 1.5, 'text-opacity': 0.9 }}); // Flight layers (WebGL symbol — GPU rendered, handles 50K+ smooth) const flightLayers = [ { id: 'fl-commercial', src: 'flights', icon: 'plane-cyan' }, { id: 'fl-private', src: 'private-fl', icon: 'plane-green' }, { id: 'fl-jets', src: 'jets', icon: 'plane-pink' }, { id: 'fl-military', src: 'military', icon: 'plane-red' }, ]; flightLayers.forEach(l => { map.addLayer({ id: l.id, type: 'symbol', source: l.src, layout: { 'icon-image': l.icon, 'icon-size': ['interpolate',['linear'],['zoom'], 1,0.4, 5,0.7, 10,1], 'icon-rotate': ['get','heading'], 'icon-rotation-alignment': 'map', 'icon-allow-overlap': true, 'icon-ignore-placement': true, }, paint: { 'icon-opacity': 0.85 }}); }); // Balloons (moving entities) map.addLayer({ id: 'balloon-dots', type: 'circle', source: 'balloons', paint: { 'circle-radius': ['interpolate',['linear'],['zoom'], 1,3, 5,5, 10,7], 'circle-color': ['get', 'color'], 'circle-opacity': 0.8, 'circle-stroke-width': 1, 'circle-stroke-color': '#fff', 'circle-stroke-opacity': 0.5, }}); map.addLayer({ id: 'balloon-label', type: 'symbol', source: 'balloons', minzoom: 4, layout: { 'text-field': ['get','callsign'], 'text-size': 9, 'text-font': ['Open Sans Regular'], 'text-offset': [0, 1.2], 'text-max-width': 12, 'text-allow-overlap': false, }, paint: { 'text-color': ['get', 'color'], 'text-halo-color': '#000', 'text-halo-width': 1 }}); // Radiation — violet base, threat spectrum for danger/warning map.addLayer({ id: 'rad-glow', type: 'circle', source: 'radiation', paint: { 'circle-radius': ['interpolate',['linear'],['zoom'], 1,10, 5,20, 10,40], 'circle-color': ['match', ['get','status'], 'DANGER','#D32F2F', 'WARNING','#E65100', '#7E57C2'], 'circle-opacity': 0.12, 'circle-blur': 1, }}); map.addLayer({ id: 'rad-dots', type: 'circle', source: 'radiation', paint: { 'circle-radius': ['interpolate',['linear'],['zoom'], 1,4, 5,6, 10,8], 'circle-color': ['match', ['get','status'], 'DANGER','#D32F2F', 'WARNING','#E65100', '#7E57C2'], 'circle-opacity': 0.85, 'circle-stroke-width': 1.5, 'circle-stroke-color': ['match', ['get','status'], 'DANGER','#D32F2F', 'WARNING','#E65100', '#7E57C2'], 'circle-stroke-opacity': 0.35, }}); map.addLayer({ id: 'rad-label', type: 'symbol', source: 'radiation', minzoom: 5, layout: { 'text-field': ['concat', ['to-string', ['get','reading']], ' nSv/h'], 'text-size': 9, 'text-font': ['Open Sans Bold'], 'text-offset': [0, 1.5], 'text-allow-overlap': false, }, paint: { 'text-color': ['match', ['get','status'], 'DANGER','#D32F2F', 'WARNING','#E65100', '#7E57C2'], 'text-halo-color': '#000', 'text-halo-width': 1 }}); // ══ OSIRIS SDK — Lattice Intelligence Mesh ══ // Polybolos Style: Delicate, translucent, steel-blue splined mesh // ── SEA domain (Distinct Solid Lines) ── // Removed glow to match the clean, diagrammatic look of submarinecablemap.com map.addLayer({ id: 'sdk-sea', type: 'line', source: 'sdk-links', filter: ['==',['get','domain'],'SEA'], paint: { 'line-color': ['coalesce', ['get', 'color'], '#1976D2'], // Single solid color from properties 'line-width': ['interpolate',['linear'],['zoom'], 1, 0.8, 5, 1.5, 10, 2.5], 'line-opacity': ['interpolate',['linear'],['zoom'], 1, 0.3, 5, 0.5, 10, 0.7], }}); // ── AIR domain (Steel Gray / Cyan) ── map.addLayer({ id: 'sdk-air-atmo', type: 'line', source: 'sdk-links', filter: ['==',['get','domain'],'AIR'], paint: { 'line-color': '#4DD0E1', 'line-width': ['interpolate',['linear'],['zoom'], 1, 1.5, 5, 5, 10, 8], 'line-opacity': 0.04, 'line-blur': 3, }}); map.addLayer({ id: 'sdk-air-glow', type: 'line', source: 'sdk-links', filter: ['==',['get','domain'],'AIR'], paint: { 'line-color': '#80DEEA', 'line-width': ['interpolate',['linear'],['zoom'], 1, 0.8, 5, 2, 10, 4], 'line-opacity': ['interpolate',['linear'],['zoom'], 1, 0.08, 5, 0.12, 10, 0.18], 'line-blur': 1, }}); map.addLayer({ id: 'sdk-air', type: 'line', source: 'sdk-links', filter: ['==',['get','domain'],'AIR'], paint: { 'line-color': '#B2EBF2', 'line-width': ['interpolate',['linear'],['zoom'], 1, 0.15, 5, 0.6, 10, 1.2], 'line-opacity': ['interpolate',['linear'],['zoom'], 1, 0.2, 5, 0.35, 10, 0.5], }}); // ── INTEL domain (Deep Steel / Violet) ── map.addLayer({ id: 'sdk-intel-atmo', type: 'line', source: 'sdk-links', filter: ['==',['get','domain'],'INTEL'], paint: { 'line-color': '#7986CB', 'line-width': ['interpolate',['linear'],['zoom'], 1, 2.5, 5, 7, 10, 12], 'line-opacity': 0.06, 'line-blur': 5, }}); map.addLayer({ id: 'sdk-intel-glow', type: 'line', source: 'sdk-links', filter: ['==',['get','domain'],'INTEL'], paint: { 'line-color': '#9FA8DA', 'line-width': ['interpolate',['linear'],['zoom'], 1, 1.2, 5, 3, 10, 6], 'line-opacity': ['interpolate',['linear'],['zoom'], 1, 0.12, 5, 0.18, 10, 0.25], 'line-blur': 2, }}); map.addLayer({ id: 'sdk-intel', type: 'line', source: 'sdk-links', filter: ['==',['get','domain'],'INTEL'], paint: { 'line-color': '#C5CAE9', 'line-width': ['interpolate',['linear'],['zoom'], 1, 0.3, 5, 1, 10, 2], 'line-opacity': ['interpolate',['linear'],['zoom'], 1, 0.3, 5, 0.45, 10, 0.7], }}); // Maritime Ships (moving entities) — ocean teal family map.addLayer({ id: 'ship-dots', type: 'circle', source: 'maritime-ships', paint: { 'circle-radius': ['interpolate',['linear'],['zoom'], 1,2, 5,4, 10,6], 'circle-color': ['match', ['get','type'], 'military','#D32F2F', 'tanker','#E65100', 'cargo','#26C6DA', '#B0BEC5'], 'circle-opacity': 0.75, }}); map.addLayer({ id: 'ship-label', type: 'symbol', source: 'maritime-ships', minzoom: 5, layout: { 'text-field': ['get','name'], 'text-size': 9, 'text-font': ['Open Sans Regular'], 'text-offset': [0, 1.2], 'text-allow-overlap': false, }, paint: { 'text-color': ['match', ['get','type'], 'military','#D32F2F', 'tanker','#E65100', 'cargo','#26C6DA', '#B0BEC5'], 'text-halo-color': '#000', 'text-halo-width': 1 }}); setMapReady(true); }); // Events let lastMove = 0; map.on('mousemove', e => { const now = Date.now(); if (now - lastMove > 100) { lastMove = now; onMouseCoords?.({ lat: e.lngLat.lat, lng: e.lngLat.lng }); } }); map.on('contextmenu', e => { e.preventDefault(); onRightClick?.({ lat: e.lngLat.lat, lng: e.lngLat.lng }); }); map.on('moveend', () => { const c = map.getCenter(); onViewStateChange?.({ zoom: map.getZoom(), latitude: c.lat }); }); // ── POPUP HELPER ── const popup = (coords: any, html: string) => { popupRef.current?.remove(); popupRef.current = new maplibregl.Popup({ closeButton: true, maxWidth: '420px', offset: 14 }).setLngLat(coords).setHTML(html).addTo(map); }; const pStyle = `background:rgba(12,14,26,0.95);backdrop-filter:blur(16px);border-radius:10px;padding:16px;font-family:'JetBrains Mono',monospace;`; const linkStyle = `display:inline-block;margin-top:8px;padding:5px 12px;font-size:10px;letter-spacing:0.12em;text-decoration:none;border-radius:5px;font-family:'JetBrains Mono',monospace;`; // ── XSS PROTECTION HELPERS ── const htmlEsc = (s: any): string => String(s ?? '').replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"').replace(/'/g,'''); const idSafe = (s: any): string => String(s ?? '').replace(/[^a-zA-Z0-9_\.\-]/g, ''); const urlSafe = (s: any): string => { const u = String(s ?? ''); return /^https?:\/\//i.test(u) ? u : '#'; }; const colorSafe = (s: any): string => /^#[0-9a-fA-F]{3,8}$/.test(String(s ?? '')) ? String(s) : '#aaa'; // ── Flights (with FlightAware + ADS-B Exchange links) ── ['fl-commercial','fl-private','fl-jets','fl-military'].forEach(layer => { map.on('click', layer, e => { if (!e.features?.length) return; const p = e.features[0].properties as any; const coords = (e.features[0].geometry as any).coordinates; const cs = (p.callsign||'').trim(); popup(coords, `
${htmlEsc(cs)} ${htmlEsc(p.icao24||'')}
MODEL
${htmlEsc(p.model||'—')}
ALT
${p.alt?Math.round(p.alt)+'m':'—'}
SPEED
${p.speed_knots||'—'}kt
HDG
${Math.round(p.heading||0)}°
REG
${htmlEsc(p.registration||'—')}
POS
${coords[1].toFixed(2)},${coords[0].toFixed(2)}
`); }); map.on('mouseenter', layer, () => { map.getCanvas().style.cursor = 'pointer'; }); map.on('mouseleave', layer, () => { map.getCanvas().style.cursor = ''; }); }); // ── CCTV (opens CameraViewer panel) ── map.on('click', 'cctv-dots', e => { if (!e.features?.length) return; const p = e.features[0].properties as any; const coords = (e.features[0].geometry as any).coordinates; // Emit the camera data so the CameraViewer opens onEntityClick?.({ type: 'cctv', id: p.id, name: p.name, city: p.city, country: p.country, source: p.source, feed_url: p.feed_url, stream_url: p.stream_url, stream_type: p.stream_type, external_url: p.external_url, lat: coords[1], lng: coords[0], }); // Also fly to the camera map.flyTo({ center: coords, zoom: Math.max(map.getZoom(), 13), duration: 1000 }); }); // ── Earthquakes (with USGS link) ── map.on('click', 'eq-circles', e => { if (!e.features?.length) return; const p = e.features[0].properties as any; const coords = (e.features[0].geometry as any).coordinates; popup(coords, `
M${p.magnitude} EARTHQUAKE
${htmlEsc(p.place||'Unknown location')}
DEPTH
${p.depth||'—'}km
COORDS
${coords[1].toFixed(3)}, ${coords[0].toFixed(3)}
📊 ${p.source === 'NIGGG-BAS' ? 'NIGGG-BAS' : 'USGS DETAILS'}
`); }); // ── Satellites (SatNOGS powered) ── map.on('click', 'sat-dots', e => { if (!e.features?.length) return; const p = e.features[0].properties as any; const coords = (e.features[0].geometry as any).coordinates; popup(coords, `
🛰️ ${htmlEsc(p.name)}
MISSION
${htmlEsc(p.mission||'Unknown')}
ALT
${p.alt ? p.alt+' km' : '—'}
POS
${coords[1].toFixed(2)}°, ${coords[0].toFixed(2)}°
${p.noradId ? `📡 TRACK ON N2YO` : ''}
`); }); // ── Fires (with NASA FIRMS link) ── map.on('click', 'fires-heat', e => { if (!e.features?.length) return; const p = e.features[0].properties as any; const coords = (e.features[0].geometry as any).coordinates; popup(coords, `
🔥 ACTIVE FIRE DETECTED
BRIGHTNESS
${p.brightness||'—'}K
COORDS
${coords[1].toFixed(3)}°, ${coords[0].toFixed(3)}°
🛰️ NASA FIRMS MAP
`); }); // ── Malware Threats (Abuse.ch) ── map.on('click', 'malware-dots', e => { if (!e.features?.length) return; const p = e.features[0].properties as any; const coords = (e.features[0].geometry as any).coordinates; const tType = (p.threat_type || 'MALWARE').toUpperCase(); const statusColor = p.status === 'online' ? '#39FF14' : '#FF1744'; popup(coords, `
[ ${htmlEsc(tType)} ]
${htmlEsc(p.country || 'UNKNOWN')}
${htmlEsc(p.malware || 'Unidentified Threat Payload')}
TARGET IP
${htmlEsc(p.ip)}
STATUS
${(p.status||'UNKNOWN').toUpperCase()}
`); }); // ── GDELT Conflicts (with source article) ── map.on('click', 'gdelt-dots', e => { if (!e.features?.length) return; const p = e.features[0].properties as any; const coords = (e.features[0].geometry as any).coordinates; // Map coordinates to Liveuamap regions let sourceUrl = p.url || ''; if (!sourceUrl || sourceUrl.includes('google.com')) { const [lng, lat] = coords; if (lat > 44 && lat < 53 && lng > 22 && lng < 40) sourceUrl = 'https://liveuamap.com/'; // Ukraine else if (lat > 30 && lat < 33 && lng > 34 && lng < 36) sourceUrl = 'https://israelpalestine.liveuamap.com/'; // Gaza else if (lat > 33 && lat < 34.5 && lng > 35 && lng < 36.5) sourceUrl = 'https://lebanon.liveuamap.com/'; // Lebanon else if (lat > 32 && lat < 37 && lng > 35 && lng < 42) sourceUrl = 'https://syria.liveuamap.com/'; // Syria else if (lat > 10 && lat < 22 && lng > 22 && lng < 38) sourceUrl = 'https://sudan.liveuamap.com/'; // Sudan else if (lat > 12 && lat < 20 && lng > 42 && lng < 55) sourceUrl = 'https://yemen.liveuamap.com/'; // Yemen else sourceUrl = 'https://liveuamap.com/'; // Global fallback } popup(coords, `
⚠️ CONFLICT EVENT
${htmlEsc(p.name||'Unclassified incident')}
[ OPEN SOURCE ↗ ]
`); }); // ── Global Event / Conflict Markers ── map.on('click', 'conflict-icons', e => { if (!e.features?.length) return; const p = e.features[0].properties as any; const coords = (e.features[0].geometry as any).coordinates; const color = p.severity === 'war' ? '#FF1744' : p.severity === 'high' ? '#FF9500' : '#FFD500'; popup(coords, `
⚠️ ${htmlEsc(p.label || 'WARNING EVENT')}
${htmlEsc(p.description || 'Global event detected at this location.')}
SEVERITY
${(p.severity||'unknown').toUpperCase()}
COORDS
${coords[1].toFixed(3)}°, ${coords[0].toFixed(3)}°
${p.sourceUrl ? `[ OPEN SOURCE ↗ ]` : ''}
`); }); // ── OSIRIS SDK link click ── const SDK_SOURCE_URLS: Record = { 'AIS Maritime': 'https://www.marinetraffic.com', 'AIS Stream': 'https://aisstream.io', 'AIS → Lattice': 'https://aisstream.io', 'ADS-B / OpenSky': 'https://opensky-network.org', 'ADS-B → Lattice': 'https://opensky-network.org', 'Naval Intelligence': 'https://www.odni.gov', }; ['sdk-sea','sdk-sea-glow','sdk-air','sdk-air-glow','sdk-intel','sdk-intel-glow'].forEach(layer => { map.on('click', layer, e => { if (!e.features?.length) return; const p = e.features[0].properties as any; const coords = e.lngLat; const srcUrl = p.url || SDK_SOURCE_URLS[p.source] || 'https://osirisai.live'; const domainLabel = p.domain === 'SEA' ? '⚓ MARITIME' : p.domain === 'AIR' ? '✈ AIR CORRIDOR' : '🛡 NAVAL INTEL'; const domainColor = p.domain === 'SEA' ? '#4FC3F7' : p.domain === 'AIR' ? '#B3E5FC' : '#81D4FA'; const linkStyle = 'text-decoration:none;padding:3px 8px;border-radius:4px;font-size:9px;font-weight:700;letter-spacing:0.05em;'; popup([coords.lng, coords.lat], `
${domainLabel}
FROM
${htmlEsc(p.fromName || 'Origin')}
TO
${htmlEsc(p.toName || 'Destination')}
DOMAIN
${p.domain}
OPEN SOURCE ↗
`); }); }); // ── Generic hover for clickables ── ['conflict-icons','cctv-dots','eq-circles','sat-dots','fires-heat','gdelt-dots','weather-dots','infra-dots','maritime-dots','choke-dots','news-dots','sigint-news-dots','balloon-dots','rad-dots','ship-dots','sweep-device-dots','scan-targets-dots','sdk-sea','sdk-sea-glow','sdk-sea-atmo','sdk-air','sdk-air-glow','sdk-air-atmo','sdk-intel','sdk-intel-glow','sdk-intel-atmo','malware-dots','mining-dots','ram-dots'].forEach(layer => { map.on('mouseenter', layer, () => { map.getCanvas().style.cursor = 'pointer'; }); map.on('mouseleave', layer, () => { map.getCanvas().style.cursor = ''; }); }); // ── Scan Targets click ── map.on('click', 'scan-targets-dots', (e: any) => { const p = e.features?.[0]?.properties; if (!p) return; const coords = e.features[0].geometry.coordinates.slice(); popup(coords, `
🎯 TARGET: ${htmlEsc(p.id)}
${htmlEsc(p.city || 'Unknown')}, ${htmlEsc(p.country || 'Unknown')} — ${htmlEsc(p.isp || 'Unknown ISP')}
TYPE
${(p.type || 'UNKNOWN').toUpperCase()}
COORDS
${coords[1].toFixed(3)}°, ${coords[0].toFixed(3)}°
`); }); // ── SCM Suppliers ── map.on('click', 'scm-dots', e => { if (!e.features?.length) return; const p = e.features[0].properties as any; const coords = (e.features[0].geometry as any).coordinates; const color = p.risk_level === 'CRITICAL' ? '#FF1744' : p.risk_level === 'HIGH' ? '#FF9500' : '#00BCD4'; const activeThreats = p.active_threats ? JSON.parse(p.active_threats) : []; let threatsHtml = ''; if (activeThreats.length > 0) { threatsHtml = `
ACTIVE THREATS:
${activeThreats.map((t: string) => `⚠ ${htmlEsc(t)}`).join('
')}
`; } popup(coords, `
🏢 ${htmlEsc(p.name)}
${htmlEsc(p.category)} | ${htmlEsc(p.city)}, ${htmlEsc(p.country)}
SCM RISK LEVEL
${p.risk_level}
${threatsHtml}
`); }); // ── Mining Companies ── const MINING_COLORS: Record = { copper: '#FF8A65', gold: '#FFD54F', silver: '#CFD8DC', pgm: '#4DB6AC', rare_earth: '#BA68C8', specialty: '#FFB74D' }; map.on('click', 'mining-dots', e => { if (!e.features?.length) return; const p = e.features[0].properties as any; const coords = (e.features[0].geometry as any).coordinates; const color = MINING_COLORS[p.category] || '#FFB74D'; const commodities = p.commodities ? JSON.parse(p.commodities) : []; popup(coords, `
⛏️ ${htmlEsc(p.company)}
${htmlEsc(p.site)} — ${htmlEsc(p.country)}
CATEGORY
${htmlEsc((p.category || '').toUpperCase().replace('_',' '))}
TICKER
${htmlEsc(p.ticker || '—')}${p.exchange ? ' · ' + htmlEsc(p.exchange) : ''}
SITE TYPE
${htmlEsc((p.site_type || 'mine').toUpperCase())}
HQ
${htmlEsc(p.hq || '—')}
COMMODITIES: ${commodities.map((c: string) => htmlEsc(c)).join(', ')}
${p.notes ? `
${htmlEsc(p.notes)}
` : ''} SATELLITE VIEW
`); }); // ── Memory / RAM Fabs ── const RAM_COLORS: Record = { dram_hbm: '#4FC3F7', nand: '#81C784', controller_ip: '#FFF176', module_maker: '#90A4AE', packaging_test: '#F06292', equipment: '#9575CD' }; map.on('click', 'ram-dots', e => { if (!e.features?.length) return; const p = e.features[0].properties as any; const coords = (e.features[0].geometry as any).coordinates; const color = RAM_COLORS[p.category] || '#4FC3F7'; popup(coords, `
💾 ${htmlEsc(p.company)}
${htmlEsc(p.site)} — ${htmlEsc(p.country)}
ROLE
${htmlEsc((p.category || '').toUpperCase().replace(/_/g,' '))}
TICKER
${htmlEsc(p.ticker || '—')}${p.exchange ? ' · ' + htmlEsc(p.exchange) : ''}
SITE TYPE
${htmlEsc((p.site_type || 'fab').toUpperCase())}
HQ
${htmlEsc(p.hq || '—')}
${p.notes ? `
${htmlEsc(p.notes)}
` : ''}
`); }); // ── IP Sweep device click ── map.on('click', 'sweep-device-dots', (e: any) => { const p = e.features?.[0]?.properties; if (!p) return; const coords = e.features[0].geometry.coordinates.slice(); const ports = JSON.parse(p.ports || '[]'); const vulns = JSON.parse(p.vulns || '[]'); const hostnames = JSON.parse(p.hostnames || '[]'); const riskColors: Record = { CRITICAL: '#FF3D3D', HIGH: '#FF6B00', MEDIUM: '#FFD700', LOW: '#76FF03', INFO: '#5C5A54' }; popup(coords, `
${p.device_type}
${p.ip}
${hostnames.length > 0 ? `
${hostnames.join(', ')}
` : ''}
PORTS
${ports.length}
RISK
${p.risk_level}
Open: ${ports.slice(0, 12).join(', ')}${ports.length > 12 ? ' ...' : ''}
${vulns.length > 0 ? `
⚠ CVEs: ${vulns.slice(0, 5).join(', ')}${vulns.length > 5 ? ` +${vulns.length - 5} more` : ''}
` : ''}
`); }); // ── Balloons / Sondes ── map.on('click', 'balloon-dots', e => { if (!e.features?.length) return; const p = e.features[0].properties as any; const coords = (e.features[0].geometry as any).coordinates; popup(coords, `
🎈 ${p.callsign}
${p.type.toUpperCase()} / STATUS: ${p.status.toUpperCase()}
ALTITUDE
${p.altitude} m
SPEED
${Math.round(p.speed)} km/h
VERT RATE
${p.verticalRate.toFixed(1)} m/s
TEMP
${p.temperature}°C
`); }); // ── Radiation ── map.on('click', 'rad-dots', e => { if (!e.features?.length) return; const p = e.features[0].properties as any; const coords = (e.features[0].geometry as any).coordinates; const color = p.status === 'DANGER' ? '#FF1744' : p.status === 'WARNING' ? '#FF9500' : '#AB47BC'; popup(coords, `
☢️ ${p.name}
${p.city}, ${p.country}
READING
${p.reading} nSv/h
STATUS
${p.status}
NETWORK
${p.network}
`); }); // ── Maritime Ships ── map.on('click', 'ship-dots', e => { if (!e.features?.length) return; const p = e.features[0].properties as any; const coords = (e.features[0].geometry as any).coordinates; const color = p.type === 'military' ? '#FF1744' : p.type === 'tanker' ? '#FF9500' : '#00E5FF'; const icon = p.type === 'military' ? '⚔️' : p.type === 'tanker' ? '🛢️' : '🚢'; popup(coords, `
${icon} [ ${(p.type||'VESSEL').toUpperCase()} ]
FLAG: ${p.flag||'UNK'}
${p.name || 'UNIDENTIFIED VESSEL'}
SPEED
${Number(p.speed).toFixed(1)} kn
HEADING
${Number(p.heading).toFixed(0)}°
LATITUDE
${coords[1].toFixed(4)}°
LONGITUDE
${coords[0].toFixed(4)}°
DESTINATION: ${p.destination || 'UNKNOWN'}
[ OPEN SOURCE ↗ ]
`); }); // ── Weather Events (NASA EONET + NOAA/NWS + GDACS) ── map.on('click', 'weather-dots', e => { if (!e.features?.length) return; const p = e.features[0].properties as any; const coords = (e.features[0].geometry as any).coordinates; const iconEmoji = p.icon === 'cyclone' ? '🌀' : p.icon === 'volcano' ? '🌋' : p.icon === 'flood' ? '🌊' : p.icon === 'drought' ? '🏜️' : p.icon === 'ice' ? '🧊' : p.icon === 'weather' ? '⚠️' : '⚡'; popup(coords, `
${iconEmoji} ${p.type || 'Weather Event'}
${p.title || 'Unknown event'}
SEVERITY
${(p.severity||'low').toUpperCase()}
COORDS
${coords[1].toFixed(3)}°, ${coords[0].toFixed(3)}°
${p.source ? `📡 SOURCE` : ''}
`); }); // ── Nuclear Infrastructure ── map.on('click', 'infra-dots', e => { if (!e.features?.length) return; const p = e.features[0].properties as any; const coords = (e.features[0].geometry as any).coordinates; const statusColor = p.status.includes('SEISMIC RISK') ? '#FF9500' : p.status === 'Active Conflict Zone' ? '#FF1744' : p.status === 'Operational' ? '#76FF03' : '#757575'; popup(coords, `
☢️ ${p.name || 'Nuclear Facility'}
STATUS
${p.status || '—'}
CITY
${p.city || '—'}, ${p.country || ''}
REACTORS
${p.reactors || '—'}
CAPACITY
${p.capacityMW ? p.capacityMW.toLocaleString() + ' MW' : '—'}
OWNER
${p.owner || '—'}
COORDS
${coords[1].toFixed(3)}°, ${coords[0].toFixed(3)}°
SATELLITE VIEW
`); }); // ── Maritime Ports & Naval Bases ── map.on('click', 'maritime-dots', e => { const p = e.features?.[0]?.properties; if (!p) return; const coords = (e.features![0].geometry as any).coordinates; const typeColor = p.type === 'naval' ? '#FF3D3D' : p.type === 'energy' ? '#FF9500' : '#00BCD4'; const typeLabel = p.type === 'naval' ? 'NAVAL BASE' : p.type === 'energy' ? 'ENERGY PORT' : 'CONTAINER PORT'; const congestionHtml = p.congestion ? `
CONGESTION
${p.congestion}
EST. DWELL TIME
${p.dwell_time || 'Unknown'}
` : ''; popup(coords, `
${p.name}
${typeLabel} — ${p.country}
${p.volume ? `
Volume: ${p.volume}
` : ''} ${p.fleet ? `
Fleet: ${p.fleet}
` : ''} ${p.rank ? `
Global Rank: #${p.rank}
` : ''} ${congestionHtml}
`); }); // ── Maritime Chokepoints ── map.on('click', 'choke-dots', e => { const p = e.features?.[0]?.properties; if (!p) return; const coords = (e.features![0].geometry as any).coordinates; const riskCol = p.risk === 'CRITICAL' ? '#FF1744' : p.risk === 'HIGH' ? '#FF9500' : p.risk === 'ELEVATED' ? '#FFD700' : '#00E676'; popup(coords, `
${p.name}
Traffic: ${p.traffic}
Risk: ${p.risk}
`); }); // ── Live News (opens feed viewer) ── map.on('click', 'news-dots', e => { const p = e.features?.[0]?.properties; if (!p) return; onEntityClick?.({ type: 'live_news', name: p.name, city: p.city, country: p.country, url: p.url, category: p.category, embed_allowed: p.embed_allowed !== false && p.embed_allowed !== 'false', }); }); return () => { map.remove(); mapRef.current = null; }; }, []); // Day/Night useEffect(() => { if (!mapReady || !mapRef.current) return; const map = mapRef.current; const update = () => { const src = map.getSource('day-night') as any; if (!src) return; if (!activeLayers.day_night) { src.setData(EMPTY_FC); return; } src.setData({ type: 'FeatureCollection', features: [{ type: 'Feature', geometry: { type: 'Polygon', coordinates: [computeSolarTerminator()] }, properties: {} }] }); }; update(); const iv = setInterval(update, 300000); // 5 min (was 1 min — shadow barely moves) return () => clearInterval(iv); }, [mapReady, activeLayers.day_night]); // Helper to set GeoJSON const setGeo = useCallback((source: string, features: any[]) => { const src = mapRef.current?.getSource(source) as any; if (src) src.setData({ type: 'FeatureCollection', features }); }, []); const setVis = useCallback((ids: string[], visible: boolean) => { const map = mapRef.current; if (!map) return; ids.forEach(id => { if (map.getLayer(id)) map.setLayoutProperty(id, 'visibility', visible ? 'visible' : 'none'); }); }, []); // Flight data → GeoJSON (GPU rendered) useEffect(() => { if (!mapReady) return; const toFeatures = (arr: any[], decimate: number = 1) => { let filtered = arr || []; if (decimate > 1) { filtered = filtered.filter((_, i) => i % decimate === 0); } return filtered.map((f: any) => ({ type: 'Feature' as const, geometry: { type: 'Point' as const, coordinates: [f.lng, f.lat] }, properties: { callsign: f.callsign, heading: f.heading || 0, alt: f.alt, model: f.model, speed_knots: f.speed_knots, registration: f.registration, icao24: f.icao24 }, })); }; setGeo('flights', activeLayers.flights ? toFeatures(data.commercial_flights, 10) : []); setGeo('private-fl', activeLayers.private ? toFeatures(data.private_flights, 2) : []); setGeo('jets', activeLayers.jets ? toFeatures(data.private_jets, 2) : []); setGeo('military', activeLayers.military ? toFeatures(data.military_flights) : []); }, [mapReady, data.commercial_flights, data.private_flights, data.private_jets, data.military_flights, activeLayers.flights, activeLayers.private, activeLayers.jets, activeLayers.military]); // Update aircraft icon colors dynamically on theme switch useEffect(() => { if (!mapReady || !mapRef.current) return; const map = mapRef.current; const isGhost = theme === 'ghost'; const phantomPurple = '#B388FF'; const ghostPriv = '#CE93D8'; const ghostGov = '#D500F9'; const flightCom = isGhost ? phantomPurple : '#00E5FF'; const flightPriv = isGhost ? ghostPriv : '#FFD700'; const flightGov = isGhost ? ghostGov : '#FF9500'; const flightMil = '#FF0000'; const updateMapIcon = (id: string, color: string, size: number) => { if (!map.hasImage(id)) return; const canvas = document.createElement('canvas'); canvas.width = size; canvas.height = size; const ctx = canvas.getContext('2d')!; const cx = size / 2, cy = size / 2; ctx.fillStyle = color; ctx.beginPath(); ctx.moveTo(cx, cy - size * 0.4); ctx.lineTo(cx - size * 0.12, cy + size * 0.1); ctx.lineTo(cx - size * 0.4, cy + size * 0.2); ctx.lineTo(cx - size * 0.4, cy + size * 0.3); ctx.lineTo(cx - size * 0.12, cy + size * 0.15); ctx.lineTo(cx, cy + size * 0.35); ctx.lineTo(cx + size * 0.12, cy + size * 0.15); ctx.lineTo(cx + size * 0.4, cy + size * 0.3); ctx.lineTo(cx + size * 0.4, cy + size * 0.2); ctx.lineTo(cx + size * 0.12, cy + size * 0.1); ctx.closePath(); ctx.fill(); map.updateImage(id, { width: size, height: size, data: new Uint8Array(ctx.getImageData(0, 0, size, size).data) }); }; updateMapIcon('plane-cyan', flightCom, 24); updateMapIcon('plane-green', flightPriv, 24); updateMapIcon('plane-pink', flightGov, 24); updateMapIcon('plane-red', flightMil, 24); updateMapIcon('plane-grey', isGhost ? phantomPurple : '#546E7A', 24); }, [mapReady, theme]); // ── DECOUPLED LAYER RENDERERS (Performance Optimized) ── useEffect(() => { if (!mapReady) return; setGeo('earthquakes', activeLayers.earthquakes && data.earthquakes ? data.earthquakes.map((eq: any) => ({ type: 'Feature', geometry: { type: 'Point', coordinates: [eq.lng, eq.lat] }, properties: { magnitude: eq.magnitude, place: eq.place } })) : []); }, [mapReady, data.earthquakes, activeLayers.earthquakes, setGeo]); useEffect(() => { if (!mapReady) return; const sats = data.satellites || []; const al = activeLayers as any; // If 'All Satellites' is on, show everything if (al.satellites) { setGeo('satellites', sats.map((s: any) => ({ type: 'Feature', geometry: { type: 'Point', coordinates: [s.lng, s.lat] }, properties: { name: s.name, color: s.color, mission: s.mission, alt: s.alt, noradId: s.noradId, category: s.category } }))); return; } // Otherwise filter by enabled sub-layers const enabledCategories: string[] = []; if (al.sat_comms) enabledCategories.push('comms'); if (al.sat_military) enabledCategories.push('military'); if (al.sat_navigation) enabledCategories.push('navigation'); if (al.sat_earth) enabledCategories.push('earth_obs'); if (al.sat_science) enabledCategories.push('science'); if (enabledCategories.length === 0) { setGeo('satellites', []); return; } const filtered = sats.filter((s: any) => enabledCategories.includes(s.category)); setGeo('satellites', filtered.map((s: any) => ({ type: 'Feature', geometry: { type: 'Point', coordinates: [s.lng, s.lat] }, properties: { name: s.name, color: s.color, mission: s.mission, alt: s.alt, noradId: s.noradId, category: s.category } }))); }, [mapReady, data.satellites, activeLayers.satellites, (activeLayers as any).sat_comms, (activeLayers as any).sat_military, (activeLayers as any).sat_navigation, (activeLayers as any).sat_earth, (activeLayers as any).sat_science, setGeo]); useEffect(() => { if (!mapReady) return; setGeo('gdelt', activeLayers.global_incidents && data.gdelt ? data.gdelt.map((e: any) => ({ type: 'Feature', geometry: { type: 'Point', coordinates: [e.lng, e.lat] }, properties: { name: e.name } })) : []); }, [mapReady, data.gdelt, activeLayers.global_incidents, setGeo]); // Malware Threats useEffect(() => { if (!mapReady) return; setGeo('malware-nodes', activeLayers.malware && data.malware_threats ? data.malware_threats.map((t: any) => ({ type: 'Feature', geometry: { type: 'Point', coordinates: [t.lng, t.lat] }, properties: { ip: t.ip, malware: t.malware, status: t.status, threat_type: t.threat_type, country: t.country } })) : []); }, [mapReady, data.malware_threats, activeLayers.malware, setGeo]); // Network Mesh Generation (Nearest Neighbor Lattice) useEffect(() => { if (!mapReady) return; const meshLinks: any[] = []; // Generate Malware Botnet Mesh if (activeLayers.malware && data.malware_threats && data.malware_threats.length > 1) { const nodes = data.malware_threats; for (let i = 0; i < nodes.length; i++) { // Connect each to next 2 for a global web for (let j = 1; j <= 2; j++) { const target = nodes[(i + j) % nodes.length]; meshLinks.push({ type: 'Feature', geometry: { type: 'LineString', coordinates: [[nodes[i].lng, nodes[i].lat], [target.lng, target.lat]] }, properties: { threat_type: 'malware' } }); } } } setGeo('network-mesh', meshLinks); }, [mapReady, activeLayers.malware, data.malware_threats, setGeo]); useEffect(() => { if (!mapReady) return; setGeo('gps-jamming', activeLayers.gps_jamming && data.gps_jamming ? data.gps_jamming.map((z: any) => ({ type: 'Feature', geometry: { type: 'Point', coordinates: [z.lng, z.lat] }, properties: { severity: z.severity } })) : []); }, [mapReady, data.gps_jamming, activeLayers.gps_jamming, setGeo]); useEffect(() => { if (!mapReady) return; setGeo('cctv', activeLayers.cctv && data.cameras ? data.cameras.map((c: any) => ({ type: 'Feature', geometry: { type: 'Point', coordinates: [c.lng, c.lat] }, properties: { id: c.id, name: c.name, city: c.city, country: c.country, source: c.source, feed_url: c.feed_url, stream_url: c.stream_url, stream_type: c.stream_type, external_url: c.external_url } })) : []); }, [mapReady, data.cameras, activeLayers.cctv, setGeo]); useEffect(() => { if (!mapReady) return; setGeo('fires', activeLayers.fires && data.fires ? data.fires.map((f: any) => ({ type: 'Feature', geometry: { type: 'Point', coordinates: [f.lng, f.lat] }, properties: { brightness: f.brightness } })) : []); }, [mapReady, data.fires, activeLayers.fires, setGeo]); useEffect(() => { if (!mapReady) return; setGeo('weather', activeLayers.weather && data.weather_events ? data.weather_events.map((w: any) => ({ type: 'Feature', geometry: { type: 'Point', coordinates: [w.lng, w.lat] }, properties: { title: w.title, type: w.type, icon: w.icon, severity: w.severity, source: w.source, id: w.id } })) : []); }, [mapReady, data.weather_events, activeLayers.weather, setGeo]); useEffect(() => { if (!mapReady) return; setGeo('infrastructure', activeLayers.infrastructure && data.infrastructure ? data.infrastructure.map((i: any) => ({ type: 'Feature', geometry: { type: 'Point', coordinates: [i.lng, i.lat] }, properties: { name: i.name, city: i.city, country: i.country, status: i.status, reactors: i.reactors, capacityMW: i.capacityMW, owner: i.owner } })) : []); }, [mapReady, data.infrastructure, activeLayers.infrastructure, setGeo]); useEffect(() => { if (!mapReady) return; setGeo('mining-sites', activeLayers.mining && data.mining_companies ? data.mining_companies.map((m: any) => ({ type: 'Feature', geometry: { type: 'Point', coordinates: [m.lng, m.lat] }, properties: { company: m.company, site: m.site, site_type: m.site_type, country: m.country, category: m.category, commodities: m.commodities, ticker: m.ticker, exchange: m.exchange, hq: m.hq, notes: m.notes } })) : []); }, [mapReady, data.mining_companies, activeLayers.mining, setGeo]); useEffect(() => { if (!mapReady) return; setGeo('ram-sites', activeLayers.ram_fabs && data.ram_companies ? data.ram_companies.map((m: any) => ({ type: 'Feature', geometry: { type: 'Point', coordinates: [m.lng, m.lat] }, properties: { company: m.company, site: m.site, site_type: m.site_type, country: m.country, category: m.category, commodities: m.commodities, ticker: m.ticker, exchange: m.exchange, hq: m.hq, notes: m.notes } })) : []); }, [mapReady, data.ram_companies, activeLayers.ram_fabs, setGeo]); useEffect(() => { if (!mapReady) return; setGeo('maritime', activeLayers.maritime && data.maritime_ports ? data.maritime_ports.map((p: any) => ({ type: 'Feature', geometry: { type: 'Point', coordinates: [p.lng, p.lat] }, properties: { name: p.name, country: p.country, type: p.type, volume: p.volume, fleet: p.fleet, rank: p.rank } })) : []); setGeo('maritime-choke', activeLayers.maritime && data.maritime_chokepoints ? data.maritime_chokepoints.map((c: any) => ({ type: 'Feature', geometry: { type: 'Point', coordinates: [c.lng, c.lat] }, properties: { name: c.name, traffic: c.traffic, risk: c.risk } })) : []); setGeo('maritime-ships', activeLayers.maritime && data.maritime_ships ? data.maritime_ships.map((s: any) => ({ type: 'Feature', geometry: { type: 'Point', coordinates: [s.lng, s.lat] }, properties: { name: s.name || s.mmsi?.toString(), type: s.type || 'cargo', speed: s.speed, heading: s.heading, destination: s.destination, flag: s.flag } })) : []); }, [mapReady, data.maritime_ports, data.maritime_chokepoints, data.maritime_ships, activeLayers.maritime, setGeo]); useEffect(() => { if (!mapReady) return; setGeo('balloons', activeLayers.balloons && data.balloons ? data.balloons.map((b: any) => ({ type: 'Feature', geometry: { type: 'Point', coordinates: [b.lng, b.lat] }, properties: { callsign: b.callsign, type: b.type, status: b.status, altitude: b.altitude, speed: b.speed, verticalRate: b.verticalRate, temperature: b.temperature, color: b.color } })) : []); }, [mapReady, data.balloons, activeLayers.balloons, setGeo]); useEffect(() => { if (!mapReady) return; setGeo('radiation', activeLayers.radiation && data.radiation ? data.radiation.map((r: any) => ({ type: 'Feature', geometry: { type: 'Point', coordinates: [r.lng, r.lat] }, properties: { name: r.name, city: r.city, country: r.country, reading: r.reading, status: r.status, network: r.network } })) : []); }, [mapReady, data.radiation, activeLayers.radiation, setGeo]); // ══ OSIRIS SDK — Lattice Sensor Mesh ══ // Uses real submarine cable data for SEA domain, curated routes for AIR/INTEL useEffect(() => { if (!mapReady) return; setGeo('sdk-entities', []); const anySDK = activeLayers.sdk_sea || activeLayers.sdk_air || activeLayers.sdk_naval; if (!anySDK) { setGeo('sdk-links', []); return; } const links: any[] = []; // ── SEA DOMAIN: Real submarine cable data (1-for-1 Match) ── if (activeLayers.sdk_sea && data.submarine_cables) { const ignoredColors = new Set(['#9BB5CC', '#A0B8CD', '#8EABC2', '#9bb5cc', '#a0b8cd', '#8eabc2']); for (const cable of data.submarine_cables) { if (!cable.geometry) continue; // Remove the light blue background arcs if (cable.properties?.color && ignoredColors.has(cable.properties.color)) continue; links.push({ type: 'Feature', geometry: cable.geometry, // Raw topographic paths exactly from Submarine Map properties: { domain: 'SEA', fromName: cable.properties?.name || 'Submarine Cable', toName: cable.properties?.landing_points || '', source: 'Global Subsea Cable Network', url: 'https://www.submarinecablemap.com/', ...cable.properties, color: '#1976D2', // Darker blue as requested, more transparent in layer paint }, }); } } setGeo('sdk-links', links); }, [mapReady, activeLayers.sdk_sea, activeLayers.sdk_air, activeLayers.sdk_naval, data.submarine_cables, setGeo]); useEffect(() => { if (!mapReady) return; setGeo('live-news', activeLayers.live_news && data.live_feeds ? data.live_feeds.map((f: any) => ({ type: 'Feature', geometry: { type: 'Point', coordinates: [f.lng, f.lat] }, properties: { name: f.name, city: f.city, country: f.country, url: f.url, category: f.category, embed_allowed: f.embed_allowed !== false } })) : []); }, [mapReady, data.live_feeds, activeLayers.live_news, setGeo]); useEffect(() => { if (!mapReady) return; const items = data.news || []; setGeo('sigint-news', activeLayers.news_intel && items.length > 0 ? items.filter((n: any) => n.coords?.length === 2).map((n: any) => ({ type: 'Feature', geometry: { type: 'Point', coordinates: [n.coords[1], n.coords[0]] }, properties: { title: n.title, source: n.source, risk_score: n.risk_score, link: n.link } })) : []); }, [mapReady, data.news, activeLayers.news_intel, setGeo]); useEffect(() => { if (!mapReady) return; // 🔴 CONFLICT ZONES - Live from /api/conflicts 🔴 let cancelled = false; (async () => { try { const res = await fetch('/api/conflicts'); if (cancelled) return; if (!res.ok) throw new Error(`HTTP error! status: ${res.status}`); const conflictData = await res.json(); if (cancelled) return; // Zone anchor markers (war/high/elevated labels) const zoneFeatures = (conflictData.zones || []).map((z: any) => ({ type: 'Feature' as const, geometry: { type: 'Point' as const, coordinates: [z.lng, z.lat] }, properties: { label: z.label, severity: z.severity, description: `${z.description}${z.eventCount > 0 ? ` [${z.eventCount} live events detected]` : ''}`, sourceUrl: z.sourceUrl, eventCount: z.eventCount, }, })); // Individual live conflict events (scatter dots across conflict zones) const eventFeatures = (conflictData.liveEvents || []) .filter((e: any) => e.lat && e.lng) .map((e: any) => ({ type: 'Feature' as const, geometry: { type: 'Point' as const, coordinates: [e.lng, e.lat] }, properties: { label: (e.title || 'CONFLICT EVENT').substring(0, 60).toUpperCase(), severity: 'war', description: e.title || 'Live conflict event detected by GDELT.', sourceUrl: e.url || '', }, })); setGeo('conflict-zones', [...zoneFeatures, ...eventFeatures]); } catch (e) { // Fallback: if API fails, use minimal known zones const FALLBACK_ZONES = [ { label: 'UKRAINE WAR', severity: 'war', lat: 48.5, lng: 31.2, description: 'Ongoing Russian invasion of Ukraine.', sourceUrl: 'https://liveuamap.com/' }, { label: 'GAZA CONFLICT', severity: 'war', lat: 31.35, lng: 34.35, description: 'Active military operations in Gaza.', sourceUrl: 'https://israelpalestine.liveuamap.com/' }, { label: 'SUDAN CIVIL WAR', severity: 'war', lat: 15.0, lng: 30.0, description: 'SAF vs RSF armed conflict.', sourceUrl: 'https://sudan.liveuamap.com/' }, { label: 'YEMEN WAR', severity: 'war', lat: 15.5, lng: 48.0, description: 'Houthi operations and Red Sea threats.', sourceUrl: 'https://yemen.liveuamap.com/' }, { label: 'MYANMAR CONFLICT', severity: 'war', lat: 19.5, lng: 96.5, description: 'Military junta vs opposition forces.', sourceUrl: 'https://myanmar.liveuamap.com/' }, { label: 'SYRIA', severity: 'high', lat: 35.0, lng: 38.5, description: 'Ongoing civil conflict.', sourceUrl: 'https://syria.liveuamap.com/' }, ]; const fallbackFeatures = FALLBACK_ZONES.map(z => ({ type: 'Feature' as const, geometry: { type: 'Point' as const, coordinates: [z.lng, z.lat] }, properties: { label: z.label, severity: z.severity, description: z.description, sourceUrl: z.sourceUrl }, })); setGeo('conflict-zones', fallbackFeatures); } })(); return () => { cancelled = true; }; }, [mapReady, setGeo]); // Visibility useEffect(() => { if (!mapReady) return; setVis(['eq-circles','eq-label'], activeLayers.earthquakes); const anySat = activeLayers.satellites || (activeLayers as any).sat_comms || (activeLayers as any).sat_military || (activeLayers as any).sat_navigation || (activeLayers as any).sat_earth || (activeLayers as any).sat_science; setVis(['sat-glow','sat-dots'], anySat); setVis(['gdelt-dots'], activeLayers.global_incidents); setVis(['malware-glow','malware-dots','malware-label'], activeLayers.malware); setVis(['network-mesh-atmo', 'network-mesh-glow', 'network-mesh-core'], activeLayers.internet_outages || activeLayers.malware); setVis(['jam-fill','jam-label'], activeLayers.gps_jamming); setVis(['day-night-fill'], activeLayers.day_night); setVis(['fl-commercial'], activeLayers.flights); setVis(['fl-private'], activeLayers.private); setVis(['fl-jets'], activeLayers.jets); setVis(['fl-military'], activeLayers.military); setVis(['cctv-glow','cctv-dots','cctv-label'], activeLayers.cctv); setVis(['fires-heat'], activeLayers.fires); setVis(['weather-glow','weather-dots','weather-label'], activeLayers.weather); setVis(['infra-glow','infra-dots','infra-label'], activeLayers.infrastructure); setVis(['mining-glow','mining-dots','mining-label'], activeLayers.mining); setVis(['ram-glow','ram-dots','ram-label'], activeLayers.ram_fabs); setVis(['maritime-glow','maritime-dots','maritime-label'], activeLayers.maritime); setVis(['choke-glow','choke-dots','choke-label'], activeLayers.maritime); setVis(['ship-dots','ship-label'], activeLayers.maritime); setVis(['news-glow','news-dots','news-label'], activeLayers.live_news); setVis(['sigint-news-glow','sigint-news-dots','sigint-news-label'], activeLayers.news_intel); setVis(['conflict-icons'], activeLayers.conflict_zones !== false); setVis(['balloon-dots','balloon-label'], activeLayers.balloons); setVis(['rad-glow','rad-dots','rad-label'], activeLayers.radiation); setVis(['sdk-sea','sdk-sea-glow','sdk-sea-atmo'], activeLayers.sdk_sea !== false); setVis(['sdk-air','sdk-air-glow','sdk-air-atmo'], activeLayers.sdk_air !== false); setVis(['sdk-intel','sdk-intel-glow','sdk-intel-atmo'], activeLayers.sdk_naval !== false); // Sweep layers always visible when data is present (controlled by useEffect) setVis(['sweep-connections','sweep-pulse-ring','sweep-device-glow','sweep-device-dots','sweep-device-labels'], true); }, [mapReady, activeLayers, setVis]); // IP Sweep visualization useEffect(() => { if (!mapReady) return; if (!sweepData?.devices?.length) { setGeo('ip-sweep-devices', []); setGeo('ip-sweep-pulse', []); setGeo('ip-sweep-connections', []); return; } const map = mapRef.current; if (!map) return; const { center, devices } = sweepData; const centerCoord: [number, number] = [center.lng, center.lat]; // Switch to globe and fly to the sweep location try { (map as any).setProjection({ type: 'globe' }); map.setSky({ 'sky-color': '#0A0A0F', 'sky-horizon-blend': 0.02, 'horizon-color': '#0A0A0F', 'horizon-fog-blend': 0.02 }); } catch { /* projection may not be supported */ } map.flyTo({ center: centerCoord, zoom: 14, pitch: 50, bearing: -20, duration: 3000, essential: true }); // Set center pulse setGeo('ip-sweep-pulse', [{ type: 'Feature' as const, geometry: { type: 'Point' as const, coordinates: centerCoord }, properties: { ip: sweepData.target_ip }, }]); // Build device features spread in a circle around center const allDeviceFeatures = devices.map((d: any, i: number) => { const angle = (i / devices.length) * Math.PI * 2; const radius = 0.001 + ((i % 7 + 1) * 0.0004); const dLng = centerCoord[0] + Math.cos(angle) * radius * (1 / Math.cos(center.lat * Math.PI / 180)); const dLat = centerCoord[1] + Math.sin(angle) * radius; return { type: 'Feature' as const, geometry: { type: 'Point' as const, coordinates: [dLng, dLat] }, properties: { ip: d.ip, device_type: d.device_type, device_icon: d.device_icon, color: d.device_color, risk_level: d.risk_level, ports: JSON.stringify(d.ports), hostnames: JSON.stringify(d.hostnames), vulns: JSON.stringify(d.vulns), cpes: JSON.stringify(d.cpes), tags: JSON.stringify(d.tags), }, }; }); // Connection lines from center to each device const connectionFeatures = allDeviceFeatures.map((f: any) => ({ type: 'Feature' as const, geometry: { type: 'LineString' as const, coordinates: [centerCoord, f.geometry.coordinates] }, properties: { color: f.properties.color }, })); // Stagger the appearance after 3s flyTo completes const timer = setTimeout(() => { setGeo('ip-sweep-connections', connectionFeatures); const batchSize = 5; const batches = Math.ceil(allDeviceFeatures.length / batchSize); for (let b = 0; b < batches; b++) { setTimeout(() => { setGeo('ip-sweep-devices', allDeviceFeatures.slice(0, (b + 1) * batchSize)); }, b * 100); } }, 3000); return () => clearTimeout(timer); }, [mapReady, sweepData, setGeo]); // Scan Targets visualization useEffect(() => { if (!mapReady || !mapRef.current || !scanTargets) return; const map = mapRef.current; const features = scanTargets.map(t => ({ type: 'Feature' as const, geometry: { type: 'Point' as const, coordinates: [t.lng, t.lat] }, properties: { ...t } })); const src = map.getSource('scan-targets') as maplibregl.GeoJSONSource; if (src) src.setData({ type: 'FeatureCollection', features }); }, [scanTargets, mapReady]); // Fly-to useEffect(() => { if (!mapReady || !mapRef.current || !flyToLocation) return; mapRef.current.flyTo({ center: [flyToLocation.lng, flyToLocation.lat], zoom: flyToLocation.zoom || 8, duration: 2000 }); }, [mapReady, flyToLocation]); // Dynamic projection switching (lightweight — no terrain DEM) useEffect(() => { if (!mapReady || !mapRef.current) return; const map = mapRef.current; try { (map as any).setProjection({ type: projection }); if (projection === 'globe') { map.easeTo({ pitch: 20, duration: 1200 }); try { (map as any).setSky({ 'sky-color': '#04040A', 'sky-horizon-blend': 0.5, 'horizon-color': '#0a0a1a', 'horizon-fog-blend': 0.3, 'fog-color': '#04040A', 'fog-ground-blend': 0.9, }); } catch (e) { console.warn('[OSIRIS] Suppressed error:', e instanceof Error ? e.message : e); } } else { map.easeTo({ pitch: 0, duration: 800 }); } } catch (e) { console.warn('Projection switch failed:', e); } }, [mapReady, projection]); // 3D Terrain & Buildings layer useEffect(() => { if (!mapReady || !mapRef.current) return; const map = mapRef.current; const enabled = activeLayers.terrain_3d; try { if (enabled) { // ── 3D BUILDINGS SOURCE (OpenFreeMap CDN — no API key, globally cached) ── if (!map.getSource('osiris-buildings')) { map.addSource('osiris-buildings', { type: 'vector', url: 'https://tiles.openfreemap.org/planet', }); } // ── 3D BUILDING EXTRUSION LAYER ── if (!map.getLayer('osiris-3d-buildings')) { map.addLayer({ id: 'osiris-3d-buildings', source: 'osiris-buildings', 'source-layer': 'building', type: 'fill-extrusion', minzoom: 14.5, paint: { 'fill-extrusion-color': [ 'interpolate', ['linear'], ['get', 'render_height'], 0, '#1a1a2e', 20, '#16213e', 50, '#0f3460', 120, '#533483', 300, '#e94560', ], 'fill-extrusion-height': [ 'interpolate', ['linear'], ['zoom'], 14.5, 0, 15.5, ['get', 'render_height'] ], 'fill-extrusion-base': [ 'interpolate', ['linear'], ['zoom'], 14.5, 0, 15.5, ['get', 'render_min_height'] ], 'fill-extrusion-opacity': [ 'interpolate', ['linear'], ['zoom'], 14.5, 0, 15, 0.7, ], }, }); } // Pitch the camera to reveal the 3D skyline if (map.getPitch() < 40) { map.easeTo({ pitch: 50, duration: 1200 }); } } else { // ── DISABLE 3D ── if (map.getLayer('osiris-3d-buildings')) map.removeLayer('osiris-3d-buildings'); } } catch (e) { console.warn('[OSIRIS] 3D terrain toggle error:', e); } }, [mapReady, activeLayers.terrain_3d]); // Satellite / Dark style switching useEffect(() => { if (!mapReady || !mapRef.current) return; if (mapStyle === prevStyleRef.current) return; prevStyleRef.current = mapStyle; const map = mapRef.current; try { if (mapStyle !== 'dark') { // Add satellite raster tiles if (!map.getSource('satellite-tiles')) { map.addSource('satellite-tiles', { type: 'raster', tiles: ['https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}'], tileSize: 256, maxzoom: 18, }); map.addLayer({ id: 'satellite-layer', type: 'raster', source: 'satellite-tiles', paint: { 'raster-opacity': 0.85 } }, 'day-night-fill'); } else { map.setLayoutProperty('satellite-layer', 'visibility', 'visible'); } } else { if (map.getLayer('satellite-layer')) { map.setLayoutProperty('satellite-layer', 'visibility', 'none'); } } } catch (e) { console.warn('Style switch failed:', e); } }, [mapReady, mapStyle]); return
; } export default memo(OsirisMap);