{
 "format": "leader.earth/earth-sources v1",
 "_what": "The template for the State of the Earth: one row per source. The visitor's browser fetches each source directly (every one listed as cors:true sends Access-Control-Allow-Origin: *), normalises it to one event shape, and caches it in localStorage for refresh_s, so no server renders or relays anything and no source is asked more often than its own limits allow. Add a source by adding a row and a normaliser in earth.js named by `normalise`. Verified 2026-10-14.",
 "event_shape": {"id": "source:id", "kind": "seismic | volcanic | wildfire | storm | flood | ice | dust | launch | other",
                 "title": "", "time": "ISO-8601 UTC", "lat": 0, "lon": 0, "magnitude": "number or null", "unit": "", "level": "", "url": "", "source": ""},
 "sources": [
  {"id": "usgs-quakes", "org": "USGS", "name": "Earthquakes M2.5+, past day", "kind": "seismic", "cors": true, "refresh_s": 300,
   "url": "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_day.geojson", "normalise": "usgsQuakes",
   "attribution": "U.S. Geological Survey", "licence": "public domain (U.S. Government work)",
   "note": "Seismic. The server sends Cache-Control max-age=60; we ask at most every 5 minutes."},
  {"id": "usgs-volcanoes", "org": "USGS", "name": "Elevated volcanoes (U.S. observatories)", "kind": "volcanic", "cors": true, "refresh_s": 900,
   "url": "https://volcanoes.usgs.gov/hans-public/api/volcano/getElevatedVolcanoes", "normalise": "usgsVolcanoes",
   "attribution": "USGS Volcano Hazards Program", "licence": "public domain (U.S. Government work)",
   "note": "Volcanic alert level and aviation colour code. U.S. observatories only (AVO, CVO, HVO, YVO, CalVO); no coordinates in this feed."},
  {"id": "nasa-eonet", "org": "NASA", "name": "EONET open natural events", "kind": "mixed", "cors": true, "refresh_s": 900,
   "url": "https://eonet.gsfc.nasa.gov/api/v3/events?status=open&days=14", "normalise": "nasaEonet",
   "attribution": "NASA Earth Observatory Natural Event Tracker (EONET)", "licence": "NASA open data",
   "note": "Volcanoes, wildfires, severe storms, floods, sea and lake ice, dust and haze, worldwide."},
  {"id": "spacex-launches", "org": "SpaceX (via Launch Library 2)", "name": "Upcoming SpaceX launches", "kind": "launch", "cors": true, "refresh_s": 3600,
   "url": "https://ll.thespacedevs.com/2.2.0/launch/upcoming/?limit=6&lsp__name=SpaceX&mode=list", "normalise": "ll2Launches",
   "attribution": "The Space Devs, Launch Library 2", "licence": "free tier, 15 requests per hour per IP",
   "note": "SpaceX's own public API (api.spacexdata.com) returned 522 on 2026-10-14, so launches come from Launch Library 2, filtered to SpaceX. Cached an hour to stay well inside the free limit."},
  {"id": "google-earth", "org": "Google", "name": "Google Earth / Maps layer", "kind": "map", "cors": false, "enabled": false,
   "url": null, "normalise": null,
   "note": "TODO (see TODO.md): Google has no keyless public feed of live earth events. The integration is a map, not a feed: Google Maps JavaScript API (key, billing account, referrer-restricted to leader.earth) to plot every event above; Google Earth Engine (service account, server-side, cached to static files) for imagery layers. Not wired."}
 ]
}
