What's Changed
- feat(map): native mobile map experience with location detection and full feature parity (#619)
- feat(oref): show history waves timeline with translation and NaN fix (#618)
- fix(aviation): increase cache TTL from 30min to 2h to reduce API quota usage (#617)
- docs(changelog): add v2.5.21 entry covering 86 merged PRs (#616)
- fix(api): harden cache-control headers for polymarket and rss-proxy (#613)
- perf(rss): raise news refresh interval to 10min and cache TTL to 20min (#612)
- Expand country brief and CII signal coverage (#611)
- fix(docs): add blank lines after CHANGELOG headings for markdownlint (#608)
- fix: RT channel HLS-only recovery, test shim, and LiveNOW fallback (#610)
- fix(relay): increase OREF curl maxBuffer to prevent ENOBUFS (#609)
- fix(aviation): invalidate stale IndexedDB cache + reduce CDN TTL (#607)
- chore: bump version to 2.5.21 (#605)
- docs(readme): comprehensive update for Telegram, OREF, GPS jamming, airports, and more (#606)
- fix(webcams): fix broken live news channels — eNCA handle, remove VTC NOW, fix CTI News (#604)
- fix(aviation): always show all monitored airports on flight delays map (#603)
- fix(sentry): guard YT player methods + filter GM/InvalidState noise (#602)
- chore(telegram): update channel list — remove nexta_live, air_alert_ua; add wfwitness (#600)
- fix(aviation): route NOTAM through relay + improve intl logging (#599)
- fix(webcams): add 4th Iran Attacks feed to fill 2x2 grid (#601)
- fix(polymarket): add queue backpressure and response limit slicing (#593)
- fix(relay): stop Polymarket cache stampede from concurrent limit + CDN bypass (#592)
- fix(aviation): replace broken lock mechanism with direct cache, add cancellation tiers (#591)
- fix(telegram): add missing relay auth headers to telegram-feed edge function (#590)
- feat(live-news): add RT channel via HLS + enable HLS on web (#586)
- feat(feeds): add RT (Russia Today) RSS feeds (#585)
- fix(relay): delay Telegram connect 60s on startup to prevent AUTH_KEY_DUPLICATED (#587)
- feat(risk): wire theater posture + breaking news into strategic risk score (#584)
- feat(aviation): add NOTAM closure detection via ICAO API (#583)
- feat: add GPS/GNSS jamming map layer + CII integration (#570)
- feat(aviation): add comprehensive logging to flight delay pipeline (#581)
- feat(relay): bootstrap OREF 24h history on startup (#582)
- fix(sentry): guard setView against invalid preset + filter translateNotifyError (#580)
- feat(cii): hook security advisories into CII scoring & country briefs (#579)
- fix(relay): add timeouts and logging to Telegram poll loop (#578)
- feat(scripts): add Iran events seed script and latest data (#575)
- fix(webcams): replace duplicate Tehran feed with Tel Aviv, rename Iran tab (#572)
- fix(relay): replace nixpacks.toml with railpack.json for curl (#571)
- feat(webcams): add Iran tab to live webcams panel (#569)
- fix(relay): increase Polymarket cache TTL to 10 minutes (#568)
- fix(relay): install curl in Railway container for OREF polling (#567)
- fix(relay): upstreamWs → upstreamSocket in graceful shutdown (#565)
- fix(cii): resolve Gulf country strike misattribution via multi-match bbox disambiguation (#564)
- fix(relay): replace smart quotes crashing relay on startup (#563)
- fix(aviation): query all airports instead of rotating batch (#557)
- fix(relay): add graceful shutdown + poll concurrency guard for Telegram (#562)
- feat(cii): wire OREF sirens into CII score & country brief (#559)
- fix(sentry): add noise filters and fix beforeSend null-filename leak (#561)
- fix(live-news): annotate empty catches and sanitize error output (#560)
- fix(i18n): rename OREF Sirens panel to Israel Sirens (#556)
- fix(live-news): align YouTube edge function with relay auth pattern (#555)
- fix(live-news): use correct relay auth header for YouTube proxy (#554)
- feat(settings): add AVIATIONSTACK_API to desktop settings page (#553)
- feat(live-news): move YouTube proxy scraping to Railway relay
- feat(aviation): integrate AviationStack API for non-US airport delays (#552)
- fix(live-news): lazy-load node modules + proxy fallback to direct fetch
- fix(live-news): set explicit runtime: 'nodejs' for proxy support
- debug(live-news): add debug param to diagnose proxy env var on Vercel
- feat(live-news): add residential proxy + gzip decompression for YouTube detection (#551)
- feat(telegram): add Telegram Intel panel (#550)
- feat(conflict): enhance Iran events popup with severity badge and related events (#549)
- fix(alerts): add compound escalation for military action + geopolitical target (#548)
- feat(cii): integrate Iran strike events into CII scoring, country brief & timeline (#547)
- gave the user freedom to resize panels "fixes issue #426" (#489)
- fix(relay): use execFileSync for OREF curl to avoid shell injection (#546)
- feat(oref): add OREF sirens panel with Hebrew-to-English translation (#545)
- fix(live-news): fix broken Europe channel handles + add fallback video IDs (#541)
- fix(telegram): latch AUTH_KEY_DUPLICATED to stop retry spam (#543)
- fix(telegram): fix ESM import path in session-auth script (#542)
- fix(iran): bump CDN cache-bust to v4 for fresh event data (#544)
- fix(live-news): add fallback video ID for LiveNOW from FOX channel (#538)
- fix(relay): auto-reconnect on Telegram AUTH_KEY_DUPLICATED and fix IranIntl handle (#539)
- feat: add day/night solar terminator overlay to map (#529)
- Revert "Revert "fix(relay): fix telegram ESM import path and broaden latch regex"" (#537)
- Revert "fix(relay): fix telegram ESM import path and broaden latch regex"
- fix(ui): move download banner to bottom-right (#536)
- fix(relay): fix telegram ESM import path and broaden latch regex
- fix(live-news): replace 7 stale YouTube fallback video IDs (#535)
- fix(relay): Telegram + OOM + memory cleanup (#531)
- fix(alerts): remove SESSION_START gate that blocked pre-existing breaking news (#533)
- fix(iran): bust CDN cache to serve updated Gulf-geocoded events (#532)
- fix(geo): expand geo hub index with 60+ missing world locations (#528)
- feat(map): prioritize Iran Attacks layer (#527)
- fix(relay): block rsshub.app requests with 410 Gone (#526)
- fix(focal-points): attribute theater military activity to target nations (#525)
- fix(iran): bypass stale CDN cache for iran-events endpoint (#524)
- fix(relay): regenerate package-lock.json with telegram dependency (#522)
- fix(breaking-news): fill keyword gaps missing real Iran attack headlines (#521)
- fix(relay): add POLYMARKET_ENABLED env flag kill switch (#523)
- Revert "fix(relay): regenerate package-lock.json with telegram dependency"
- chore: trigger deploy to flush CDN cache for iran-events endpoint
- fix(relay): regenerate package-lock.json with telegram dependency
- fix(threat-classifier): stagger AI classification requests to avoid Groq 429 (#520)
- fix(relay): Polymarket circuit breaker + concurrency limiter (OOM fix) (#519)
- fix: make iran-events handler read-only from Redis (#518)
- fix(breaking-news): fix fake pubDate fallback and filter noisy think-tank alerts (#517)
- fix(rate-limit): increase sliding window to 300 req/min (#515)
- fix(breaking-news): let critical alerts bypass global cooldown and replace HIGH alerts (#516)
- fix(threat-classifier): add military/conflict keyword gaps and news-to-conflict bridge (#514)
- fix(relay): prevent Polymarket OOM via request deduplication (#513)
- fix: resolve bootstrap 401 and 429 rate limiting on page init (#512)
- feat(conflict): add Iran Attacks map layer + strip debug logs (#511)
- chore: add validated telegram channels list (global + ME + Iran + cyber) (#249)
- fix(sentry): filter Android OEM WebView bridge injection errors (#510)
- feat(breaking-news): add active alert banner with audio for critical/high RSS items (#508)
- fix(relay): guard proxy handlers against ERR_HTTP_HEADERS_SENT crash (#509)
- fix(prediction): filter stale/expired markets from Polymarket panel (#507)
- fix: generalize Vercel preview origin regex + include filters in bases cache key (#506)
- chore: strip 61 debug console.log calls from 20 service files (#501)
- fix(geo): tokenization-based keyword matching to prevent false positives (#503)
- fix(bootstrap): harden hydration cache + polling review fixes (#504)
- feat(live-news): add CBC News to optional North America channels (#502)
- fix: use cross-env for Windows-compatible npm scripts (#499)
- fix(cyber): make GeoIP centroid fallback jitter deterministic (#498)
- perf(military): debounce base fetches + upgrade edge cache to static tier (#497)
- feat(military): server-side military bases 125K + rate limiting (#496)
- perf: bootstrap endpoint + polling optimization (#495)
- feat(rss): add Axios (api.axios.com/feed) as US news source (#494)
- feat: add Polish tv livestreams (#488)
- feat(i18n): add Korean (한국어) localization (#487)
- fix(rss): remove stale indianewsnetwork.com from proxy allowlist (#486)
Full Changelog: v2.5.20...v2.5.21