[
  {
    "version": "2.7.0",
    "date": "2026-06-10",
    "category": "feature",
    "scope": "parking-map",
    "summary": "BKF-Routing um Via-Punkte, ETA-Uhrzeit, Standortvalidierung und Tageslenkzeit-Warnlogik erweitert",
    "details": [
      "Routenplanung unterstuetzt bis zu 5 Zwischenziele inklusive Reihenfolge-Steuerung (hoch/runter) und Entfernen einzelner Via-Punkte",
      "Nicht-fatale Via-Geocodierung: unklare Zwischenziele blockieren die Route nicht und werden je Feld mit Praezisierungs-Hinweis markiert",
      "Standortvalidierung: Geolocation nur bei Browser-Support, Startfeld im Standortmodus optional, Ziel weiterhin verpflichtend",
      "Standortabruf mit Fehlerbehandlung (z. B. Ablehnung/Timeout) und Uebernahme nur gueltiger numerischer Koordinaten aus dem Geocoding",
      "Statusausgabe erweitert um voraussichtliche Ankunftszeit (HH:MM Uhr) sowie BKF-rechtlichen Hinweis bei Ueberschreitung der Tageslenkzeit",
      "Optionales Uebernehmen empfohlener Rastanlagen als Zwischenziel direkt aus der aktuellen Route",
      "Shortcode- und CSS-Anpassungen fuer Via-UI, mobile Bedienbarkeit und robuste Script-Einbindung",
      "Derzeit noch ohne harte Plausibilitaetsgrenzen wie Deutschland-Bounding-Box oder Mindest-GPS-Genauigkeit als Sperrregel"
    ],
    "files": [
      "assets/js/bkf-router/route-engine.js",
      "assets/js/bkf-router/routing-mode.js",
      "layouts/_shortcodes/lkw-parkplatzkarte.html",
      "static/css/lkw-livekarte.css"
    ]
  },
  {
    "version": "2.6.0",
    "date": "2026-06-05",
    "category": "feature",
    "scope": "parking-map",
    "summary": "SID-Parkplatzkarte auf serverseitiges merged.json und automatische Zertifikatspfaderkennung umgestellt",
    "details": [
      "static/update.php erkennt ../privat/mobilithek/ automatisch ueber die Script-Hierarchie und unterstuetzt certificate.p12 sowie cert.pem/key.pem",
      "Statische und Live-SID-XML werden serverseitig verarbeitet und als static.xml, live.xml und merged.json atomar geschrieben",
      "merged.json ist die Primaerquelle fuer die Parkplatzkarte; XML bleibt als Fallback fuer lokale Entwicklung erhalten",
      "Debug-Ausgabe meldet statische Datensaetze, Live-Datensaetze, gematchte IDs, ungepaarte Datensaetze und letztes Update",
      "Keine Zertifikate innerhalb des Hugo-Projekts; weiterhin kein direkter Browserzugriff auf Mobilithek"
    ],
    "files": [
      "static/update.php",
      "assets/js/map/providers/parking.js",
      "assets/js/map/config/parking-config.js",
      "layouts/_shortcodes/lkw-parkplatzkarte.html",
      "static/data/parking/merged.json"
    ]
  },
  {
    "version": "2.5.0",
    "date": "2026-06-05",
    "category": "feature",
    "scope": "parking-map",
    "summary": "SID-Parkplatzkarte auf statische und Live-Mobilithek-Quellen umgestellt",
    "details": [
      "Serverseitiger Abruf via static/update.php mit Client-Zertifikat; Browser lädt keine Mobilithek-URLs direkt",
      "Zwei Quellen: /data/parking/static.xml fuer Stammdaten und /data/parking/live.xml fuer Live-Belegung",
      "Parser trennt statische und Live-XML, matched ueber Parkplatz-ID und rendert nur einen Marker pro Parkplatz",
      "Koordinaten-Normalisierung mit Plausibilitaetspruefung und Debug-Logging fuer statische/live Datensaetze und Matches",
      "Neuer Shortcode lkw-parkplatzkarte mit Startansicht fuer Deutschland und Sidebar-Statusbereich"
    ],
    "files": [
      "static/update.php",
      "assets/js/map/parsers/parking-parser.js",
      "assets/js/map/providers/parking.js",
      "assets/js/map/config/parking-config.js",
      "layouts/_shortcodes/lkw-parkplatzkarte.html",
      "layouts/_partials/map/engine.html",
      "content/post/parkplatz/parkplatz.md",
      "static/data/parking/static.xml",
      "static/data/parking/live.xml"
    ]
  },
  {
    "version": "2.4.0",
    "date": "2026-06-05",
    "category": "feature",
    "scope": "parking-map",
    "summary": "Neue LKW-Parkplatzkarte (SID/Mobilithek) implementiert",
    "details": [
      "Neuer Shortcode {{< lkw-parkplatzkarte >}} mit Statistikbereich (Parkplaetze gesamt, freie/belegte Stellplaetze, Aktualisierungszeitstempel)",
      "DATEX II XML-Parser (assets/js/map/parsers/parking-parser.js) fuer Mobilithek-SID-Daten",
      "Parkplatz-Provider (assets/js/map/providers/parking.js) mit XML- und JSON-Fallback-Pfad",
      "Parkplatz-Konfiguration ausgelagert nach assets/js/map/config/parking-config.js",
      "Marker-Design: L.marker mit divIcon, farbkodiert nach Belegungsstatus (frei=gruen, teilweise=orange, voll=rot, unbekannt=grau)",
      "Popup-Inhalte: Parkplatzname, Autobahn/Standort, freie Plaetze, Betreiber, Typ, Aktualisierung, Detail-Link",
      "Statistik-UI per data-parking-role-Attributen an Karte gebunden",
      "Darkmode-kompatibles CSS in static/css/lkw-livekarte.css",
      "Testdaten unter static/data/parking/sid-sample.xml",
      "Hugo-Partial engine.html um optionale mapId-Unterstuetzung erweitert (rueckwaertskompatibel)"
    ],
    "files": [
      "assets/js/map/parsers/parking-parser.js",
      "assets/js/map/config/parking-config.js",
      "assets/js/map/providers/parking.js",
      "layouts/_shortcodes/lkw-parkplatzkarte.html",
      "layouts/_partials/map/engine.html",
      "static/css/lkw-livekarte.css",
      "static/data/parking/sid-sample.xml",
      "content/post/parkplatz/parkplatz.md"
    ]
  },
  {
    "version": "2.3.2",
    "date": "2026-06-05",
    "category": "fix",
    "scope": "map-engine",
    "summary": "Null-Werte aus data-*-Attributen ueberschreiben Provider-Defaults nicht mehr",
    "details": [
      "assets/js/map-engine.js: dropNilValues() filtert null/undefined aus config.map und config.cluster vor dem Merge",
      "Verhindert, dass fehlende data-map-cluster-radius-Attribute den disableClusteringAtZoom- und maxClusterRadius-Default des Providers auf null setzen",
      "Behebt unsichtbare Ladepunkte nach vorangegangenem Refactor"
    ],
    "files": [
      "assets/js/map-engine.js"
    ]
  },
  {
    "version": "2.3.1",
    "date": "2026-06-05",
    "category": "fix",
    "scope": "charging-map",
    "summary": "Debug-Logging fuer Cluster-Diagnose eingebaut",
    "details": [
      "logClusterDebugState() loggt Cluster-Layer-Anzahl und direkte CircleMarker-Layer bei jedem applyStationTypeFilter-Aufruf",
      "Diagnose bestaetigt: keine doppelten CircleMarker-Pfade gefunden"
    ],
    "files": [
      "static/js/leafletplanner.js"
    ]
  },
  {
    "version": "2.3.0",
    "date": "2026-06-05",
    "category": "fix",
    "scope": "charging-map",
    "summary": "Charging-Marker auf L.marker mit divIcon umgestellt",
    "details": [
      "Charging-Punkte werden jetzt als echte L.marker mit divIcon erstellt statt als L.circleMarker",
      "Markerfarben beibehalten: PKW=#e53935, LKW=#8e24aa",
      "disableClusteringAtZoom auf 11 gesetzt (charging provider + legacy fallback)",
      "Popup-Logik unveraendert"
    ],
    "files": [
      "static/js/leafletplanner.js",
      "assets/js/map/providers/charging.js"
    ]
  },
  {
    "version": "2.2.0",
    "date": "2026-06-05",
    "category": "fix",
    "scope": "charging-map",
    "summary": "Filter-Regression behoben: Cluster-Inhalt schrumpfte nach Filterwechseln",
    "details": [
      "Umstieg von wiederverwendeten stationLayerCar/stationLayerTruck (L.geoJSON) auf Rohdaten-Arrays carStationFeatures/truckStationFeatures",
      "buildChargingMarkers() erzeugt bei jedem applyStationTypeFilter frische L.marker-Instanzen",
      "clusterGroup.addLayers() statt clusterGroup.addLayer() fuer Batch-Performance"
    ],
    "files": [
      "static/js/leafletplanner.js"
    ]
  },
  {
    "version": "2.1.0",
    "date": "2026-06-05",
    "category": "feature",
    "scope": "map-engine",
    "summary": "Zentrale Kartenengine (map-engine.js) eingefuehrt",
    "details": [
      "assets/js/map-engine.js bootstrapped Leaflet-Map per data-map-type-Attribut",
      "assets/js/map/map-core.js: createMapRuntime(), createLeafletMap(), zoomToLayer()",
      "assets/js/map/clustering.js: createClusterGroup() mit chunkedLoading, removeOutsideVisibleBounds",
      "assets/js/map/utils.js: escapeHtml, formatNumber, fetchJson, parseJsonAttribute, normalizeFeatureCollection",
      "assets/js/map/popups.js: buildPopupTable, parkingPopup, chargingPopup",
      "assets/js/map/icons.js: pointColorForKind, pointStyleForKind",
      "assets/js/map/providers/charging.js: Bootstrap-Shim fuer bestehendes leafletplanner.js",
      "Shared runtime wird via window.__mapRuntime an leafletplanner.js uebergeben",
      "layouts/_partials/map/engine.html und layouts/_shortcodes/map.html eingefuehrt"
    ],
    "files": [
      "assets/js/map-engine.js",
      "assets/js/map/map-core.js",
      "assets/js/map/clustering.js",
      "assets/js/map/utils.js",
      "assets/js/map/popups.js",
      "assets/js/map/icons.js",
      "assets/js/map/providers/charging.js",
      "layouts/_partials/map/engine.html",
      "layouts/_shortcodes/map.html"
    ]
  },
  {
    "version": "2.0.1",
    "date": "2026-06-05",
    "category": "fix",
    "scope": "deploy",
    "summary": "Deploy-Skript haertet: Livereload-Referenz-Check und FTP-Overwrite",
    "details": [
      "deploy.sh prueft public/ auf livereload.js?port=1313 und localhost-Referenzen vor dem Deploy",
      "FTP-Mirror nutzt --overwrite statt --only-newer um Stale-Asset-Probleme zu verhindern"
    ],
    "files": [
      "deploy.sh"
    ]
  },
  {
    "version": "2.0.0",
    "date": "2026-05-30",
    "category": "fix",
    "scope": "avatar",
    "summary": "Avatar-Darstellung bereinigt und Email-Soziallink auf interne Seite umgestellt",
    "details": [
      "Logo bleibt rund (border-radius: 100%), weisser Ring entfernt",
      "object-fit: cover ohne weissen Hintergrund/Padding",
      "Email-Soziallink von mailto: auf /about/ umgestellt (verhindert Browser-App-Prompt)"
    ],
    "files": [
      "assets/scss/partials/sidebar.scss",
      "config/_default/menu.toml"
    ]
  }
]
