/* ─── RADAR: Live Intelligence Feed + .GOV Domain Tracker ─── */ (function() { 'use strict'; // ═══════════════════════════════════════════════════ // SHARED UTILITIES // ═══════════════════════════════════════════════════ function esc(s) { const d = document.createElement('div'); d.textContent = s || ''; return d.innerHTML; } function timeAgo(dateStr) { if (!dateStr) return ''; const now = new Date(); const then = new Date(dateStr); const diff = Math.floor((now - then) / 1000); if (diff < 60) return diff + 's ago'; if (diff < 3600) return Math.floor(diff / 60) + 'm ago'; if (diff < 86400) return Math.floor(diff / 3600) + 'h ago'; if (diff < 604800) return Math.floor(diff / 86400) + 'd ago'; return Math.floor(diff / 604800) + 'w ago'; } function extractDomain(url) { try { return new URL(url).hostname.replace('www.', ''); } catch(e) { return ''; } } // ═══════════════════════════════════════════════════ // NEWS FEED MODULE // ═══════════════════════════════════════════════════ const NewsFeed = { API: '/api/radar', REFRESH_INTERVAL: 15 * 60 * 1000, currentSource: 'all', allItems: [], refreshTimer: null, renderFeed: function(items) { const feed = document.getElementById('radarFeed'); if (!items || items.length === 0) { feed.innerHTML = '
NO SIGNALS DETECTED ON CURRENT FREQUENCY
'; return; } let html = ''; items.forEach(function(item) { const domain = extractDomain(item.url); const ago = timeAgo(item.published); const sourceClass = 'source-' + item.source_id; const sourceLabel = item.source || 'UNKNOWN'; html += '
'; html += '
' + esc(ago) + '
'; html += '
' + esc(sourceLabel) + '
'; html += '
'; html += ' ' + esc(item.title) + ''; html += '
'; if (domain) html += '' + esc(domain) + ''; if (item.comments_url) html += 'COMMENTS'; html += '
'; }); feed.innerHTML = html; }, applyFilters: function() { var q = document.getElementById('radarSearch').value.trim().toLowerCase(); var filtered = this.allItems; if (this.currentSource !== 'all') { filtered = filtered.filter(function(i) { return i.source_id === NewsFeed.currentSource; }); } if (q) { filtered = filtered.filter(function(i) { return (i.title || '').toLowerCase().includes(q) || (i.summary || '').toLowerCase().includes(q); }); } document.getElementById('statTotal').textContent = filtered.length; this.renderFeed(filtered); }, fetch: function(forceRefresh) { var self = this; var feed = document.getElementById('radarFeed'); feed.innerHTML = '
SCANNING FREQUENCIES...
'; var chain = forceRefresh ? fetch(this.API + '/refresh', { method: 'POST' }).then(function() { return fetch(self.API); }) : fetch(this.API); chain.then(function(res) { return res.json(); }) .then(function(data) { self.allItems = data.items || []; document.getElementById('statTotal').textContent = self.allItems.length; if (data.last_updated) { var d = new Date(data.last_updated); var pad = function(n) { return String(n).padStart(2, '0'); }; document.getElementById('statUpdated').textContent = pad(d.getHours()) + ':' + pad(d.getMinutes()) + ':' + pad(d.getSeconds()) + ' UTC'; } self.applyFilters(); }) .catch(function(err) { console.error('RADAR fetch error:', err); feed.innerHTML = '
⚠ SIGNAL LOST — UNABLE TO REACH FEED API
'; }); }, init: function() { var self = this; // Source filters document.querySelectorAll('#viewNewsfeed .radar-filter').forEach(function(btn) { btn.addEventListener('click', function(e) { e.preventDefault(); document.querySelectorAll('#viewNewsfeed .radar-filter').forEach(function(b) { b.classList.remove('active'); }); this.classList.add('active'); self.currentSource = this.dataset.source; self.applyFilters(); }); }); // Search var searchTimeout; document.getElementById('radarSearch').addEventListener('input', function() { clearTimeout(searchTimeout); searchTimeout = setTimeout(function() { self.applyFilters(); }, 200); }); // Refresh document.getElementById('radarRefresh').addEventListener('click', function(e) { e.preventDefault(); this.classList.add('spinning'); var btn = this; self.fetch(true).then(function() { setTimeout(function() { btn.classList.remove('spinning'); }, 500); }); }); // Initial fetch this.fetch(false); // Auto-refresh this.refreshTimer = setInterval(function() { self.fetch(false); }, this.REFRESH_INTERVAL); } }; // ═══════════════════════════════════════════════════ // .GOV TRACKER MODULE // ═══════════════════════════════════════════════════ const GovTracker = { API: '/api/govdomains', STATS_API: '/api/govdomains/stats', currentRange: 'all', currentType: '', currentSearch: '', allDomains: [], statsData: null, loaded: false, TYPE_COLORS: { 'Federal': { color: '#ff4444', bg: 'rgba(255,68,68,0.08)', border: 'rgba(255,68,68,0.35)' }, 'Executive': { color: '#ff4444', bg: 'rgba(255,68,68,0.08)', border: 'rgba(255,68,68,0.35)' }, 'Judicial': { color: '#ff6b6b', bg: 'rgba(255,107,107,0.08)', border: 'rgba(255,107,107,0.3)' }, 'Legislative': { color: '#ff6b6b', bg: 'rgba(255,107,107,0.08)', border: 'rgba(255,107,107,0.3)' }, 'State': { color: '#4488ff', bg: 'rgba(68,136,255,0.08)', border: 'rgba(68,136,255,0.35)' }, 'Interstate': { color: '#44aaff', bg: 'rgba(68,170,255,0.08)', border: 'rgba(68,170,255,0.3)' }, 'City': { color: '#00cc44', bg: 'rgba(0,204,68,0.08)', border: 'rgba(0,204,68,0.35)' }, 'County': { color: '#ffaa00', bg: 'rgba(255,170,0,0.08)', border: 'rgba(255,170,0,0.35)' }, 'Independent Intrastate': { color: '#bb88ff', bg: 'rgba(187,136,255,0.08)', border: 'rgba(187,136,255,0.3)' }, 'Native Sovereign Nation': { color: '#ff8844', bg: 'rgba(255,136,68,0.08)', border: 'rgba(255,136,68,0.3)' } }, getTypeStyle: function(type) { return this.TYPE_COLORS[type] || { color: '#888', bg: 'rgba(136,136,136,0.08)', border: 'rgba(136,136,136,0.3)' }; }, renderDomains: function(domains) { var feed = document.getElementById('govFeed'); if (!domains || domains.length === 0) { feed.innerHTML = '
NO .GOV DOMAINS MATCH CURRENT FILTERS
'; document.getElementById('govResultCount').textContent = '0 RESULTS'; return; } // Show count document.getElementById('govResultCount').textContent = domains.length.toLocaleString() + ' DOMAIN' + (domains.length !== 1 ? 'S' : '') + ' FOUND'; // Only render first 200 for performance var visible = domains.slice(0, 200); var html = ''; visible.forEach(function(d) { var style = GovTracker.getTypeStyle(d.type); var isNew = d.is_new; var itemClass = 'gov-domain-item' + (isNew ? ' gov-new' : ''); html += '
'; // Domain name + link html += '
'; html += ' '; html += esc(d.domain); html += ' '; if (isNew) html += ' NEW'; html += '
'; // Type badge html += '
'; html += esc(d.type || 'UNKNOWN'); html += '
'; // Details html += '
'; if (d.agency) html += 'AGENCY: ' + esc(d.agency) + ''; if (d.organization) html += 'ORG: ' + esc(d.organization) + ''; if (d.city || d.state) { var loc = [d.city, d.state].filter(Boolean).join(', '); html += 'LOC: ' + esc(loc) + ''; } html += '
'; // First seen html += '
' + esc(d.first_seen || '—') + '
'; html += '
'; }); if (domains.length > 200) { html += '
SHOWING 200 OF ' + domains.length.toLocaleString() + ' — REFINE SEARCH TO SEE MORE
'; } feed.innerHTML = html; }, fetchStats: function() { var self = this; return fetch(this.STATS_API) .then(function(res) { return res.json(); }) .then(function(stats) { self.statsData = stats; document.getElementById('govStatTotal').textContent = (stats.total || 0).toLocaleString(); document.getElementById('govStatNew24').textContent = (stats.new_24h || 0).toLocaleString(); // Aggregate related types var byType = stats.by_type || {}; var fedCount = 0, stateCount = 0; Object.keys(byType).forEach(function(k) { if (k.toLowerCase().indexOf('federal') === 0) fedCount += byType[k]; if (k.toLowerCase().indexOf('state') === 0) stateCount += byType[k]; }); document.getElementById('govStatFederal').textContent = fedCount.toLocaleString(); document.getElementById('govStatState').textContent = stateCount.toLocaleString(); if (stats.last_sync) { var d = new Date(stats.last_sync); var pad = function(n) { return String(n).padStart(2, '0'); }; document.getElementById('govStatSync').textContent = pad(d.getHours()) + ':' + pad(d.getMinutes()) + ' UTC'; } // Populate type filter dropdown var select = document.getElementById('govTypeFilter'); var currentVal = select.value; // Clear existing options except first while (select.options.length > 1) select.remove(1); (stats.types_list || []).forEach(function(t) { var opt = document.createElement('option'); opt.value = t; opt.textContent = t.toUpperCase() + ' (' + ((stats.by_type || {})[t] || 0) + ')'; select.appendChild(opt); }); if (currentVal) select.value = currentVal; }) .catch(function(err) { console.error('Gov stats error:', err); }); }, fetchDomains: function() { var self = this; var feed = document.getElementById('govFeed'); feed.innerHTML = '
QUERYING .GOV REGISTRY...
'; // Build query params var params = new URLSearchParams(); if (this.currentRange !== 'all') params.set('range', this.currentRange); if (this.currentType) params.set('type', this.currentType); if (this.currentSearch) params.set('search', this.currentSearch); params.set('limit', '2000'); var url = this.API + '?' + params.toString(); return fetch(url) .then(function(res) { return res.json(); }) .then(function(data) { self.allDomains = data.domains || []; self.renderDomains(self.allDomains); }) .catch(function(err) { console.error('Gov domains error:', err); feed.innerHTML = '
⚠ UNABLE TO QUERY .GOV REGISTRY
'; }); }, loadAll: function() { var self = this; return Promise.all([this.fetchStats(), this.fetchDomains()]).then(function() { self.loaded = true; }); }, init: function() { var self = this; // Range filters document.querySelectorAll('.gov-range').forEach(function(btn) { btn.addEventListener('click', function(e) { e.preventDefault(); document.querySelectorAll('.gov-range').forEach(function(b) { b.classList.remove('active'); }); this.classList.add('active'); self.currentRange = this.dataset.range; self.fetchDomains(); }); }); // Type filter document.getElementById('govTypeFilter').addEventListener('change', function() { self.currentType = this.value; self.fetchDomains(); }); // Search var searchTimeout; document.getElementById('govSearch').addEventListener('input', function() { clearTimeout(searchTimeout); var val = this.value.trim(); searchTimeout = setTimeout(function() { self.currentSearch = val; self.fetchDomains(); }, 300); }); // Refresh document.getElementById('govRefresh').addEventListener('click', function(e) { e.preventDefault(); this.classList.add('spinning'); var btn = this; self.loadAll().then(function() { setTimeout(function() { btn.classList.remove('spinning'); }, 500); }); }); } }; // ═══════════════════════════════════════════════════ // VIEW TOGGLE CONTROLLER // ═══════════════════════════════════════════════════ function initViewToggle() { var subtitles = { newsfeed: '> Live intelligence feed — intercepted from Hacker News, Reddit, and Lobste.rs', govtracker: '> .GOV domain intelligence — tracking U.S. government infrastructure registry' }; function switchToView(view) { // Toggle button states document.querySelectorAll('.radar-view-btn').forEach(function(b) { b.classList.remove('active'); }); var activeBtn = document.querySelector('.radar-view-btn[data-view="' + view + '"]'); if (activeBtn) activeBtn.classList.add('active'); // Toggle views document.getElementById('viewNewsfeed').classList.toggle('hidden', view !== 'newsfeed'); document.getElementById('viewGovtracker').classList.toggle('hidden', view !== 'govtracker'); // Update subtitle document.getElementById('radarSubtitle').innerHTML = subtitles[view] || ''; // Update URL hash without scrolling history.replaceState(null, '', '#' + view); // Lazy-load gov tracker data on first switch if (view === 'govtracker' && !GovTracker.loaded) { GovTracker.loadAll(); } } document.querySelectorAll('.radar-view-btn').forEach(function(btn) { btn.addEventListener('click', function(e) { e.preventDefault(); switchToView(this.dataset.view); }); }); // Check URL hash on load var hash = window.location.hash.replace('#', ''); if (hash === 'govtracker' || hash === 'newsfeed') { switchToView(hash); } // Handle browser back/forward window.addEventListener('hashchange', function() { var h = window.location.hash.replace('#', ''); if (h === 'govtracker' || h === 'newsfeed') { switchToView(h); } }); } // ═══════════════════════════════════════════════════ // BOOT // ═══════════════════════════════════════════════════ function init() { initViewToggle(); NewsFeed.init(); GovTracker.init(); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();