Add the news report model, markers and source

The pure half of a news layer: validated records for a news server's
`/api/news/hotspots|feed|outline` contract, a presentation model and canvas
markers and picture cards, and a fetch client.

- Colour carries severity only (0 no physical event, 1 minor, 2 significant,
  3 major), never a side; the category is the icon, the rim is attestation
  (confirmed, a claim, one side's own press), size grows with sources and
  markers fade with age.
- Cards say "Reported by {side} sources" and mark official channels; a
  machine-read English headline is labelled as such.
- `createNewsSource` reads same-origin routes with a 15 s timeout, a 4 MiB cap
  and record-by-record validation; `NEWS_API_PATHS` and `newsQueryAllowed`
  let a host proxy exactly what the client sends. A 503 marked unavailable
  means "not configured": no retries.
- Exported as `./layers/news/source`, with its own package boundary.
This commit is contained in:
Denis Groshev committed 2026-11-06 00:45:22 +01:00
1 parent dd83812a21
commit 2d9d518946
21 files changed
+2653

No files matched your search

+52
View File
@@ -1,4 +1,56 @@
{
"News feed unavailable": "Nachrichtenfeed nicht verfügbar",
"Disputed: {name}": "Umstritten: {name}",
"Administered by {holder} · claimed by {claimant}": "Verwaltet von {holder} · beansprucht von {claimant}",
"Self-administered · claimed by {claimant}": "Selbstverwaltet · beansprucht von {claimant}",
"UN-patrolled zone": "Von der UNO überwachte Zone",
"Claimed by neither neighbour": "Von keinem Nachbarn beansprucht",
"Video": "Video",
"Photos": "Fotos",
"Claimed by {who}": "Behauptet von {who}",
"Claimed": "Behauptung",
"Not yet confirmed by others": "Noch nicht von anderen bestätigt",
"Reported by {side} sources": "Gemeldet von Quellen aus {side}",
"Reported by {sides}": "Gemeldet von {sides}",
"{side} sources": "Quellen aus {side}",
"Official": "Offiziell",
"Reported by both sides": "Von beiden Seiten gemeldet",
"Independently reported": "Unabhängig gemeldet",
"Single source": "Einzelne Quelle",
"International": "International",
"Independent": "Unabhängig",
"Unattributed": "Ohne Zuordnung",
"Outside party": "Außenstehende Partei",
"Ukraine–Russia": "Ukraine–Russland",
"Israel–Gaza–Lebanon": "Israel–Gaza–Libanon",
"Iran–Hormuz": "Iran–Hormus",
"Yemen–Red Sea": "Jemen–Rotes Meer",
"Sudan": "Sudan",
"Sahel": "Sahel",
"Elsewhere": "Anderswo",
"Strike": "Angriff",
"Alert": "Warnung",
"Air defence": "Luftabwehr",
"Ground fighting": "Bodenkämpfe",
"Casualties": "Opfer",
"Humanitarian": "Humanitär",
"Disaster": "Katastrophe",
"Protest": "Protest",
"Political": "Politik",
"No physical event": "Kein physisches Ereignis",
"Minor incident": "Kleiner Vorfall",
"Significant": "Erheblich",
"Major": "Schwer",
"age|now": "jetzt",
"{minutes} min": "{minutes} Min.",
"{hours} h": "{hours} Std.",
"{count} sources": {
"one": "{count} Quelle",
"other": "{count} Quellen"
},
"News feed not configured on this server": "Nachrichtenfeed auf diesem Server nicht eingerichtet",
"Malformed news hotspots response": "Fehlerhafte Antwort zu Nachrichten-Brennpunkten",
"Malformed news feed response": "Fehlerhafte Antwort des Nachrichtenfeeds",
"Flying to Austin, TX...": "Flug nach Austin, TX...",
"Restoring shared view...": "Geteilte Ansicht wird wiederhergestellt...",
"Configuring viewer...": "Viewer wird konfiguriert...",