Commits vergleichen

...

2 Commits

Autor SHA1 Nachricht Datum
Claude Code
3872d32d8f fix: Unicode-Escapes in Navbar/Footer durch echte Umlaute ersetzt
Cyberangriffe- und Deepfakes-Seiten zeigten \u00dc statt Ü in der Navigation. Ursache: JSON-Encoding wurde auf HTML angewendet. Zusätzlich data-translate-Attribute und Language-Toggle ergänzt.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 18:18:38 +02:00
Claude Code
0a6ec07374 Karte: MarkerCluster mit Popups, Hero-CTAs scrollen zu Demos
Lagebild-Karte auf geclusterte Marker umgebaut (primary/secondary als Pulse, rest als CircleMarker). Popups zeigen jetzt Top-Artikel mit Links. Vorschau Hero-Buttons scrollen zum Demo-Karussell statt direkt zu den Lagen.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 18:18:31 +02:00
8 geänderte Dateien mit 179 neuen und 66 gelöschten Zeilen

Datei anzeigen

@@ -11,6 +11,8 @@
<link rel="stylesheet" href="/css/mobile.css"> <link rel="stylesheet" href="/css/mobile.css">
<link rel="stylesheet" href="/lagen/iran-konflikt/lagebild.css"> <link rel="stylesheet" href="/lagen/iran-konflikt/lagebild.css">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" /> <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.5.3/dist/MarkerCluster.css">
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.5.3/dist/MarkerCluster.Default.css">
</head> </head>
<body class="lagebild-page"> <body class="lagebild-page">
<div class="scroll-progress" id="scroll-progress"></div> <div class="scroll-progress" id="scroll-progress"></div>
@@ -20,27 +22,28 @@
<a href="/"><img src="/assets/images/logos/Logo+Schrift_Rechts.png" alt="AegisSight" class="logo-img"></a> <a href="/"><img src="/assets/images/logos/Logo+Schrift_Rechts.png" alt="AegisSight" class="logo-img"></a>
</div> </div>
<ul class="nav-menu"> <ul class="nav-menu">
<li><a href="/">Startseite</a></li> <li><a href="/" data-translate="navHome">Startseite</a></li>
<li><a href="/#about">\u00dcber uns</a></li> <li><a href="/#about" data-translate="navAbout">Über uns</a></li>
<li><a href="/#products">L\u00f6sungen</a></li> <li><a href="/#products" data-translate="navProducts">sungen</a></li>
<li><a href="mailto:info@aegis-sight.de">Kontakt</a></li> <li><a href="mailto:info@aegis-sight.de" data-translate="navContact">Kontakt</a></li>
</ul> </ul>
<div class="nav-extras"> <div class="nav-extras">
<button class="mobile-menu-toggle" aria-label="Men\u00fc \u00f6ffnen" aria-expanded="false"> <button class="lang-toggle" data-lang="de" aria-label="Sprache wechseln" data-translate="langSwitch">DE | EN</button>
<button class="mobile-menu-toggle" aria-label="Menü öffnen" aria-expanded="false">
<span class="hamburger"><span></span><span></span><span></span></span> <span class="hamburger"><span></span><span></span><span></span></span>
</button> </button>
</div> </div>
</div> </div>
</nav> </nav>
<div class="nav-menu-mobile" aria-hidden="true"> <div class="nav-menu-mobile" aria-hidden="true">
<button class="mobile-menu-close" aria-label="Men\u00fc schlie\u00dfen"> <button class="mobile-menu-close" aria-label="Menü schließen">
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M18 6L6 18M6 6l12 12" stroke="currentColor"/></svg> <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M18 6L6 18M6 6l12 12" stroke="currentColor"/></svg>
</button> </button>
<ul> <ul>
<li><a href="/">Startseite</a></li> <li><a href="/" data-translate="navHome">Startseite</a></li>
<li><a href="/#about">\u00dcber uns</a></li> <li><a href="/#about" data-translate="navAbout">Über uns</a></li>
<li><a href="/#products">L\u00f6sungen</a></li> <li><a href="/#products" data-translate="navProducts">sungen</a></li>
<li><a href="mailto:info@aegis-sight.de">Kontakt</a></li> <li><a href="mailto:info@aegis-sight.de" data-translate="navContact">Kontakt</a></li>
</ul> </ul>
</div> </div>
<div class="mobile-menu-overlay"></div> <div class="mobile-menu-overlay"></div>
@@ -84,7 +87,7 @@
</div> </div>
<div class="tab-panel" id="panel-quellen"> <div class="tab-panel" id="panel-quellen">
<section class="content-card"> <section class="content-card">
<div class="card-header"><h2>Quellen</h2><p class="card-description">Alle vom AegisSight Monitor \u00fcberwachten Quellen</p></div> <div class="card-header"><h2>Quellen</h2><p class="card-description">Alle vom AegisSight Monitor überwachten Quellen</p></div>
<div class="card-body" id="sources-grid-container"><div class="loading-skeleton"><div class="skeleton-line"></div><div class="skeleton-line short"></div></div></div> <div class="card-body" id="sources-grid-container"><div class="loading-skeleton"><div class="skeleton-line"></div><div class="skeleton-line short"></div></div></div>
</section> </section>
</div> </div>
@@ -96,7 +99,7 @@
</div> </div>
<div class="tab-panel" id="panel-faktenchecks"> <div class="tab-panel" id="panel-faktenchecks">
<section class="content-card"> <section class="content-card">
<div class="card-header"><h2>Faktenchecks</h2><p class="card-description">KI-gest\u00fctzte Verifizierung aller zentralen Aussagen gegen unabh\u00e4ngige Quellen.</p></div> <div class="card-header"><h2>Faktenchecks</h2><p class="card-description">KI-gestützte Verifizierung aller zentralen Aussagen gegen unabhängige Quellen.</p></div>
<div class="card-body" id="factchecks-content"></div> <div class="card-body" id="factchecks-content"></div>
</section> </section>
</div> </div>
@@ -105,18 +108,19 @@
<footer class="footer"> <footer class="footer">
<div class="container"> <div class="container">
<div class="footer-content"> <div class="footer-content">
<div class="footer-section"><h4>AegisSight UG (haftungsbeschr\u00e4nkt)</h4><p>Gladbacher Strasse 3-5</p><p>40764 Langenfeld</p></div> <div class="footer-section"><h4 data-translate="footerCompanyTitle">AegisSight UG (haftungsbeschränkt)</h4><p data-translate="footerCompanyAddress1">Gladbacher Strasse 3-5</p><p data-translate="footerCompanyAddress2">40764 Langenfeld</p></div>
<div class="footer-section"><h4>Navigation</h4><ul><li><a href="/">Startseite</a></li><li><a href="/#about">\u00dcber uns</a></li><li><a href="/#products">L\u00f6sungen</a></li></ul></div> <div class="footer-section"><h4 data-translate="footerNavTitle">Navigation</h4><ul><li><a href="/" data-translate="footerNavHome">Startseite</a></li><li><a href="/#about" data-translate="footerNavAbout">Über uns</a></li><li><a href="/#products" data-translate="footerNavProducts">sungen</a></li></ul></div>
<div class="footer-section"><h4>Rechtliches</h4><ul><li><a href="/impressum.html">Impressum</a></li><li><a href="/datenschutz.html">Datenschutz</a></li></ul></div> <div class="footer-section"><h4 data-translate="footerLegalTitle">Rechtliches</h4><ul><li><a href="/impressum.html" data-translate="footerImprint">Impressum</a></li><li><a href="/datenschutz.html" data-translate="footerPrivacy">Datenschutz</a></li></ul></div>
<div class="footer-section"><h4>Kontakt</h4><p>info@aegis-sight.de</p></div> <div class="footer-section"><h4 data-translate="footerContactTitle">Kontakt</h4><p>info@aegis-sight.de</p></div>
</div> </div>
<p class="copyright">&copy; 2026 AegisSight UG (haftungsbeschr\u00e4nkt). Alle Rechte vorbehalten.</p> <p class="copyright">&copy; 2026 AegisSight UG (haftungsbeschränkt). Alle Rechte vorbehalten.</p>
</div> </div>
</footer> </footer>
<script src="/js/config.js"></script> <script src="/js/config.js"></script>
<script src="/js/translations.js"></script> <script src="/js/translations.js"></script>
<script src="/js/mobile-nav.js"></script> <script src="/js/mobile-nav.js"></script>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script> <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script src="https://unpkg.com/leaflet.markercluster@1.5.3/dist/leaflet.markercluster.js"></script>
<script src="/lagen/iran-konflikt/lagebild.js"></script> <script src="/lagen/iran-konflikt/lagebild.js"></script>
</body> </body>
</html> </html>

Datei anzeigen

@@ -11,6 +11,8 @@
<link rel="stylesheet" href="/css/mobile.css"> <link rel="stylesheet" href="/css/mobile.css">
<link rel="stylesheet" href="/lagen/iran-konflikt/lagebild.css"> <link rel="stylesheet" href="/lagen/iran-konflikt/lagebild.css">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" /> <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.5.3/dist/MarkerCluster.css">
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.5.3/dist/MarkerCluster.Default.css">
</head> </head>
<body class="lagebild-page"> <body class="lagebild-page">
<!-- Scroll Progress Bar --> <!-- Scroll Progress Bar -->
@@ -23,13 +25,14 @@
<a href="/"><img src="/assets/images/logos/Logo+Schrift_Rechts.png" alt="AegisSight" class="logo-img"></a> <a href="/"><img src="/assets/images/logos/Logo+Schrift_Rechts.png" alt="AegisSight" class="logo-img"></a>
</div> </div>
<ul class="nav-menu"> <ul class="nav-menu">
<li><a href="/">Startseite</a></li> <li><a href="/" data-translate="navHome">Startseite</a></li>
<li><a href="/#about">\u00dcber uns</a></li> <li><a href="/#about" data-translate="navAbout">Über uns</a></li>
<li><a href="/#products">L\u00f6sungen</a></li> <li><a href="/#products" data-translate="navProducts">sungen</a></li>
<li><a href="mailto:info@aegis-sight.de">Kontakt</a></li> <li><a href="mailto:info@aegis-sight.de" data-translate="navContact">Kontakt</a></li>
</ul> </ul>
<div class="nav-extras"> <div class="nav-extras">
<button class="mobile-menu-toggle" aria-label="Men\u00fc \u00f6ffnen" aria-expanded="false"> <button class="lang-toggle" data-lang="de" aria-label="Sprache wechseln" data-translate="langSwitch">DE | EN</button>
<button class="mobile-menu-toggle" aria-label="Menü öffnen" aria-expanded="false">
<span class="hamburger"><span></span><span></span><span></span></span> <span class="hamburger"><span></span><span></span><span></span></span>
</button> </button>
</div> </div>
@@ -38,14 +41,14 @@
<!-- Mobile Navigation --> <!-- Mobile Navigation -->
<div class="nav-menu-mobile" aria-hidden="true"> <div class="nav-menu-mobile" aria-hidden="true">
<button class="mobile-menu-close" aria-label="Men\u00fc schlie\u00dfen"> <button class="mobile-menu-close" aria-label="Menü schließen">
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M18 6L6 18M6 6l12 12" stroke="currentColor"/></svg> <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M18 6L6 18M6 6l12 12" stroke="currentColor"/></svg>
</button> </button>
<ul> <ul>
<li><a href="/">Startseite</a></li> <li><a href="/" data-translate="navHome">Startseite</a></li>
<li><a href="/#about">\u00dcber uns</a></li> <li><a href="/#about" data-translate="navAbout">Über uns</a></li>
<li><a href="/#products">L\u00f6sungen</a></li> <li><a href="/#products" data-translate="navProducts">sungen</a></li>
<li><a href="mailto:info@aegis-sight.de">Kontakt</a></li> <li><a href="mailto:info@aegis-sight.de" data-translate="navContact">Kontakt</a></li>
</ul> </ul>
</div> </div>
<div class="mobile-menu-overlay"></div> <div class="mobile-menu-overlay"></div>
@@ -133,7 +136,7 @@
<section class="content-card"> <section class="content-card">
<div class="card-header"> <div class="card-header">
<h2>Faktenchecks</h2> <h2>Faktenchecks</h2>
<p class="card-description">KI-gest\u00fctzte Verifizierung aller zentralen Aussagen gegen unabh\u00e4ngige Quellen.</p> <p class="card-description">KI-gestützte Verifizierung aller zentralen Aussagen gegen unabhängige Quellen.</p>
</div> </div>
<div class="card-body" id="factchecks-content"></div> <div class="card-body" id="factchecks-content"></div>
</section> </section>
@@ -146,31 +149,31 @@
<div class="container"> <div class="container">
<div class="footer-content"> <div class="footer-content">
<div class="footer-section"> <div class="footer-section">
<h4>AegisSight UG (haftungsbeschr\u00e4nkt)</h4> <h4 data-translate="footerCompanyTitle">AegisSight UG (haftungsbeschränkt)</h4>
<p>Gladbacher Strasse 3-5</p> <p data-translate="footerCompanyAddress1">Gladbacher Strasse 3-5</p>
<p>40764 Langenfeld</p> <p data-translate="footerCompanyAddress2">40764 Langenfeld</p>
</div> </div>
<div class="footer-section"> <div class="footer-section">
<h4>Navigation</h4> <h4 data-translate="footerNavTitle">Navigation</h4>
<ul> <ul>
<li><a href="/">Startseite</a></li> <li><a href="/" data-translate="footerNavHome">Startseite</a></li>
<li><a href="/#about">\u00dcber uns</a></li> <li><a href="/#about" data-translate="footerNavAbout">Über uns</a></li>
<li><a href="/#products">L\u00f6sungen</a></li> <li><a href="/#products" data-translate="footerNavProducts">sungen</a></li>
</ul> </ul>
</div> </div>
<div class="footer-section"> <div class="footer-section">
<h4>Rechtliches</h4> <h4 data-translate="footerLegalTitle">Rechtliches</h4>
<ul> <ul>
<li><a href="/impressum.html">Impressum</a></li> <li><a href="/impressum.html" data-translate="footerImprint">Impressum</a></li>
<li><a href="/datenschutz.html">Datenschutz</a></li> <li><a href="/datenschutz.html" data-translate="footerPrivacy">Datenschutz</a></li>
</ul> </ul>
</div> </div>
<div class="footer-section"> <div class="footer-section">
<h4>Kontakt</h4> <h4 data-translate="footerContactTitle">Kontakt</h4>
<p>info@aegis-sight.de</p> <p>info@aegis-sight.de</p>
</div> </div>
</div> </div>
<p class="copyright">&copy; 2026 AegisSight UG (haftungsbeschr\u00e4nkt). Alle Rechte vorbehalten.</p> <p class="copyright">&copy; 2026 AegisSight UG (haftungsbeschränkt). Alle Rechte vorbehalten.</p>
</div> </div>
</footer> </footer>
@@ -179,6 +182,7 @@
<script src="/js/translations.js"></script> <script src="/js/translations.js"></script>
<script src="/js/mobile-nav.js"></script> <script src="/js/mobile-nav.js"></script>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script> <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script src="https://unpkg.com/leaflet.markercluster@1.5.3/dist/leaflet.markercluster.js"></script>
<script src="/lagen/iran-konflikt/lagebild.js"></script> <script src="/lagen/iran-konflikt/lagebild.js"></script>
</body> </body>
</html> </html>

Datei anzeigen

@@ -11,6 +11,8 @@
<link rel="stylesheet" href="/css/mobile.css"> <link rel="stylesheet" href="/css/mobile.css">
<link rel="stylesheet" href="lagebild.css"> <link rel="stylesheet" href="lagebild.css">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" /> <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.5.3/dist/MarkerCluster.css">
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.5.3/dist/MarkerCluster.Default.css">
</head> </head>
<body class="lagebild-page"> <body class="lagebild-page">
<!-- Scroll Progress Bar --> <!-- Scroll Progress Bar -->
@@ -186,6 +188,7 @@
<script src="/js/translations.js"></script> <script src="/js/translations.js"></script>
<script src="/js/mobile-nav.js"></script> <script src="/js/mobile-nav.js"></script>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script> <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script src="https://unpkg.com/leaflet.markercluster@1.5.3/dist/leaflet.markercluster.js"></script>
<script src="lagebild.js"></script> <script src="lagebild.js"></script>
</body> </body>
</html> </html>

Datei anzeigen

@@ -1553,3 +1553,17 @@ a.source-detail-article-title:hover {
margin-top: 1rem; margin-top: 1rem;
} }
} }
/* Marker-Cluster Dark Theme */
.marker-cluster-small,
.marker-cluster-medium,
.marker-cluster-large {
background: rgba(21, 29, 46, 0.8);
}
.marker-cluster-small div,
.marker-cluster-medium div,
.marker-cluster-large div {
background: rgba(200, 168, 81, 0.9);
color: #0A1832;
font-weight: 600;
}

Datei anzeigen

@@ -655,7 +655,7 @@ var Lagebild = {
renderArticlesTab: function() {}, renderArticlesTab: function() {},
/* ===== TAB: KARTE (Pulse Markers) ===== */ /* ===== TAB: KARTE (Clustered Pulse Markers) ===== */
renderMap: function() { renderMap: function() {
if (this.map) { this.map.remove(); this.map = null; } if (this.map) { this.map.remove(); this.map = null; }
this.map = L.map('map-container', { this.map = L.map('map-container', {
@@ -664,7 +664,6 @@ var Lagebild = {
maxBoundsViscosity: 1.0 maxBoundsViscosity: 1.0
}).setView([33.0, 48.0], 5); }).setView([33.0, 48.0], 5);
// Deutsche OSM-Kacheln
L.tileLayer('https://tile.openstreetmap.de/{z}/{x}/{y}.png', { L.tileLayer('https://tile.openstreetmap.de/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>', attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>',
maxZoom: 19, maxZoom: 19,
@@ -685,7 +684,6 @@ var Lagebild = {
}); });
} }
// Kategorie-Farben
var categoryColors = { var categoryColors = {
primary: '#ef4444', primary: '#ef4444',
secondary: '#f59e0b', secondary: '#f59e0b',
@@ -698,7 +696,6 @@ var Lagebild = {
tertiary: 'Beteiligte', tertiary: 'Beteiligte',
mentioned: 'Erwaehnt' mentioned: 'Erwaehnt'
}; };
// Dynamische Labels aus API verwenden (falls vorhanden)
var categoryLabels = {}; var categoryLabels = {};
if (this.data && this.data.category_labels) { if (this.data && this.data.category_labels) {
var apiLabels = this.data.category_labels; var apiLabels = this.data.category_labels;
@@ -710,7 +707,6 @@ var Lagebild = {
categoryLabels = defaultCategoryLabels; categoryLabels = defaultCategoryLabels;
} }
// Locations aus API-Daten laden
var locs = (this.data && this.data.locations) ? this.data.locations : []; var locs = (this.data && this.data.locations) ? this.data.locations : [];
if (locs.length === 0) { if (locs.length === 0) {
@@ -720,22 +716,60 @@ var Lagebild = {
document.getElementById('map-container').appendChild(emptyDiv); document.getElementById('map-container').appendChild(emptyDiv);
} }
var clusterGroup = L.markerClusterGroup({
maxClusterRadius: 50,
spiderfyOnMaxZoom: true,
showCoverageOnHover: false,
zoomToBoundsOnClick: true,
disableClusteringAtZoom: 10
});
var usedCategories = {}; var usedCategories = {};
var bounds = [];
for (var i = 0; i < locs.length; i++) { for (var i = 0; i < locs.length; i++) {
var l = locs[i]; var l = locs[i];
if (!l.lat || !l.lon) continue; if (!l.lat || !l.lon) continue;
var cat = l.category || 'mentioned'; var cat = l.category || 'mentioned';
var color = categoryColors[cat] || '#7b7b7b'; var color = categoryColors[cat] || '#7b7b7b';
usedCategories[cat] = true; usedCategories[cat] = true;
// Popup mit Artikel-Links
var popupText = '<strong style="color:#E8ECF4;">' + (l.name || '') + '</strong>'; var popupText = '<strong style="color:#E8ECF4;">' + (l.name || '') + '</strong>';
if (l.country_code) popupText += ' <span style="color:#8896AB;font-size:0.8rem;">(' + l.country_code + ')</span>'; if (l.country_code) popupText += ' <span style="color:#8896AB;font-size:0.8rem;">(' + l.country_code + ')</span>';
popupText += '<br><span style="font-size:0.85rem;color:#8896AB;">' + (l.article_count || 0) + ' Artikel</span>'; popupText += '<br><span style="font-size:0.85rem;color:#8896AB;">' + (l.article_count || 0) + ' Artikel</span>';
L.marker([l.lat, l.lon], { icon: pulseIcon(color) }) if (l.top_articles && l.top_articles.length > 0) {
.addTo(this.map) popupText += '<div style="margin-top:6px;border-top:1px solid #1E2D45;padding-top:6px;">';
.bindPopup(popupText); for (var j = 0; j < l.top_articles.length; j++) {
var a = l.top_articles[j];
var hl = (a.headline || '').replace(/\*\*/g, '');
if (hl.length > 60) hl = hl.substring(0, 60) + '\u2026';
if (a.url) {
popupText += '<a href="' + a.url + '" target="_blank" rel="noopener" style="color:#C8A851;font-size:0.8rem;display:block;margin-top:3px;text-decoration:none;">' + hl + '</a>';
} else {
popupText += '<span style="color:#8896AB;font-size:0.8rem;display:block;margin-top:3px;">' + hl + '</span>';
}
popupText += '<span style="color:#556B7A;font-size:0.7rem;">' + (a.source || '') + '</span>';
}
popupText += '</div>';
}
var marker;
if (cat === 'primary' || cat === 'secondary') {
marker = L.marker([l.lat, l.lon], { icon: pulseIcon(color) });
} else {
marker = L.circleMarker([l.lat, l.lon], {
radius: 5, fillColor: color, fillOpacity: 0.7,
color: color, weight: 1, opacity: 0.9
});
}
marker.bindPopup(popupText, { maxWidth: 300 });
clusterGroup.addLayer(marker);
bounds.push([l.lat, l.lon]);
} }
// Dark legend (dynamisch) this.map.addLayer(clusterGroup);
// Dark legend
var legend = L.control({ position: 'bottomright' }); var legend = L.control({ position: 'bottomright' });
legend.onAdd = function() { legend.onAdd = function() {
var div = L.DomUtil.create('div', 'map-legend'); var div = L.DomUtil.create('div', 'map-legend');
@@ -751,6 +785,10 @@ var Lagebild = {
}; };
legend.addTo(this.map); legend.addTo(this.map);
if (bounds.length > 0) {
this.map.fitBounds(bounds, { padding: [30, 30], maxZoom: 7 });
}
// Dark popup styling // Dark popup styling
if (!document.getElementById('leaflet-dark-style')) { if (!document.getElementById('leaflet-dark-style')) {
var style = document.createElement('style'); var style = document.createElement('style');

Datei anzeigen

@@ -372,3 +372,17 @@ a { color:inherit; text-decoration:none; }
.container { padding:0 16px; } .container { padding:0 16px; }
} }
/* Marker-Cluster Dark Theme */
.marker-cluster-small,
.marker-cluster-medium,
.marker-cluster-large {
background: rgba(21, 29, 46, 0.8);
}
.marker-cluster-small div,
.marker-cluster-medium div,
.marker-cluster-large div {
background: rgba(200, 168, 81, 0.9);
color: #0A1832;
font-weight: 600;
}

Datei anzeigen

@@ -8,6 +8,8 @@
<link rel="icon" type="image/svg+xml" href="/favicon.svg"> <link rel="icon" type="image/svg+xml" href="/favicon.svg">
<link rel="apple-touch-icon" href="/assets/images/logos/AegisSightLogo_NavyGold.svg"> <link rel="apple-touch-icon" href="/assets/images/logos/AegisSightLogo_NavyGold.svg">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"> <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css">
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.5.3/dist/MarkerCluster.css">
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.5.3/dist/MarkerCluster.Default.css">
<link rel="stylesheet" href="css/style.css"> <link rel="stylesheet" href="css/style.css">
</head> </head>
<body> <body>
@@ -95,7 +97,7 @@
<p class="hero-slide-text">Der AegisSight Monitor überwacht hunderte Quellen rund um die Uhr und erstellt strukturierte Lagebilder, ohne manuellen Aufwand. Neue Entwicklungen werden in Minuten erfasst, analysiert und eingeordnet. Sie entscheiden, was überwacht wird, der Monitor liefert das Lagebild.</p> <p class="hero-slide-text">Der AegisSight Monitor überwacht hunderte Quellen rund um die Uhr und erstellt strukturierte Lagebilder, ohne manuellen Aufwand. Neue Entwicklungen werden in Minuten erfasst, analysiert und eingeordnet. Sie entscheiden, was überwacht wird, der Monitor liefert das Lagebild.</p>
<p class="hero-slide-example">Live-Beispiel: Der Iran-Konflikt wird mit über 14.900 Artikeln aus 375 Quellen kontinuierlich überwacht.</p> <p class="hero-slide-example">Live-Beispiel: Der Iran-Konflikt wird mit über 14.900 Artikeln aus 375 Quellen kontinuierlich überwacht.</p>
<div class="hero-slide-cta"> <div class="hero-slide-cta">
<a href="/lagen/iran-konflikt/" class="btn btn-primary">Live-Beispiel ansehen</a> <a href="#demos" class="btn btn-primary" onclick="positionCards(0)">Live-Beispiel ansehen</a>
</div> </div>
</div> </div>
<div class="hero-slide-media-col"></div> <div class="hero-slide-media-col"></div>
@@ -125,7 +127,7 @@
<p class="hero-slide-text">Definieren Sie ein Thema, der Monitor recherchiert, strukturiert und belegt vollautomatisch. Quellenbasierte Analyse mit Faktenprüfung, kein Copy-Paste aus Suchmaschinen. Das Ergebnis: ein vollständiges Dossier mit Quellenbelegen und Faktenchecks.</p> <p class="hero-slide-text">Definieren Sie ein Thema, der Monitor recherchiert, strukturiert und belegt vollautomatisch. Quellenbasierte Analyse mit Faktenprüfung, kein Copy-Paste aus Suchmaschinen. Das Ergebnis: ein vollständiges Dossier mit Quellenbelegen und Faktenchecks.</p>
<p class="hero-slide-example">Beispiel: Ein Dossier zur rechtlichen Lage von Deepfakes in Deutschland, 121 Artikel aus 90 Quellen, automatisch erstellt.</p> <p class="hero-slide-example">Beispiel: Ein Dossier zur rechtlichen Lage von Deepfakes in Deutschland, 121 Artikel aus 90 Quellen, automatisch erstellt.</p>
<div class="hero-slide-cta"> <div class="hero-slide-cta">
<a href="/lagen/deepfakes/" class="btn btn-primary">Recherche-Beispiel ansehen</a> <a href="#demos" class="btn btn-primary" onclick="positionCards(2)">Recherche-Beispiel ansehen</a>
</div> </div>
</div> </div>
<div class="hero-slide-media-col"></div> <div class="hero-slide-media-col"></div>
@@ -141,7 +143,7 @@
<p class="hero-slide-text">Arabisch, Persisch, Hebräisch, Russisch, Chinesisch: Der Monitor verarbeitet Quellen, die den meisten Analystenteams sprachlich verschlossen bleiben. Automatische Übersetzung, Kontextanalyse und Einordnung. Globale Abdeckung ohne globale Personalkosten.</p> <p class="hero-slide-text">Arabisch, Persisch, Hebräisch, Russisch, Chinesisch: Der Monitor verarbeitet Quellen, die den meisten Analystenteams sprachlich verschlossen bleiben. Automatische Übersetzung, Kontextanalyse und Einordnung. Globale Abdeckung ohne globale Personalkosten.</p>
<p class="hero-slide-example">Im Iran-Konflikt werden Primärquellen in Farsi, Arabisch und Hebräisch direkt ausgewertet.</p> <p class="hero-slide-example">Im Iran-Konflikt werden Primärquellen in Farsi, Arabisch und Hebräisch direkt ausgewertet.</p>
<div class="hero-slide-cta"> <div class="hero-slide-cta">
<a href="/lagen/iran-konflikt/" class="btn btn-primary">Live-Beispiel ansehen</a> <a href="#demos" class="btn btn-primary" onclick="positionCards(0)">Live-Beispiel ansehen</a>
</div> </div>
</div> </div>
<div class="hero-slide-media-col"></div> <div class="hero-slide-media-col"></div>
@@ -157,7 +159,7 @@
<p class="hero-slide-text">Geopolitische Konflikte, Unternehmensrisiken, regionale Krisen oder Einzelpersonen: Der AegisSight Monitor skaliert mit Ihrem Bedarf. Definieren Sie Ihr Thema, wählen Sie Ihre Quellen, der Rest läuft automatisch. Jede Lage erhält ihr eigenes Lagebild mit Quellenbelegen, Karte und Faktencheck.</p> <p class="hero-slide-text">Geopolitische Konflikte, Unternehmensrisiken, regionale Krisen oder Einzelpersonen: Der AegisSight Monitor skaliert mit Ihrem Bedarf. Definieren Sie Ihr Thema, wählen Sie Ihre Quellen, der Rest läuft automatisch. Jede Lage erhält ihr eigenes Lagebild mit Quellenbelegen, Karte und Faktencheck.</p>
<p class="hero-slide-example">Beispiel: Cyberangriffe auf deutsche Infrastruktur, 93 Artikel aus 41 Quellen, automatisch überwacht.</p> <p class="hero-slide-example">Beispiel: Cyberangriffe auf deutsche Infrastruktur, 93 Artikel aus 41 Quellen, automatisch überwacht.</p>
<div class="hero-slide-cta"> <div class="hero-slide-cta">
<a href="/lagen/cyberangriffe/" class="btn btn-primary">Live-Beispiel ansehen</a> <a href="#demos" class="btn btn-primary" onclick="positionCards(1)">Live-Beispiel ansehen</a>
</div> </div>
</div> </div>
<div class="hero-slide-media-col"></div> <div class="hero-slide-media-col"></div>
@@ -478,6 +480,7 @@
</div> </div>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script> <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script src="https://unpkg.com/leaflet.markercluster@1.5.3/dist/leaflet.markercluster.js"></script>
<script src="js/app.js"></script> <script src="js/app.js"></script>
</body> </body>
</html> </html>

Datei anzeigen

@@ -292,7 +292,7 @@ function mdToHtml(md) {
/* ==================== LEAFLET MAP ==================== */ /* ==================== LEAFLET MAP ==================== */
function clearMarkers() { function clearMarkers() {
if (markerLayer) markerLayer.clearLayers(); if (markerLayer) { mapInstance.removeLayer(markerLayer); markerLayer = null; }
if (legendControl && mapInstance) { mapInstance.removeControl(legendControl); legendControl = null; } if (legendControl && mapInstance) { mapInstance.removeControl(legendControl); legendControl = null; }
} }
@@ -311,7 +311,6 @@ function mdToHtml(md) {
maxZoom: 19, noWrap: true maxZoom: 19, noWrap: true
}).addTo(mapInstance); }).addTo(mapInstance);
markerLayer = L.layerGroup().addTo(mapInstance);
setTimeout(function () { mapInstance.invalidateSize(); }, 500); setTimeout(function () { mapInstance.invalidateSize(); }, 500);
} }
@@ -327,11 +326,31 @@ function mdToHtml(md) {
}); });
} }
function buildPopup(loc) {
var html = '<strong style="color:#E8ECF4;">' + (loc.name || '') + '</strong>';
if (loc.country_code) html += ' <span style="color:#8896AB;font-size:0.8rem;">(' + loc.country_code + ')</span>';
html += '<br><span style="font-size:0.85rem;color:#8896AB;">' + (loc.article_count || 0) + ' Artikel</span>';
if (loc.top_articles && loc.top_articles.length > 0) {
html += '<div style="margin-top:6px;border-top:1px solid #1E2D45;padding-top:6px;">';
loc.top_articles.forEach(function (a) {
var hl = (a.headline || '').replace(/\*\*/g, '');
if (hl.length > 60) hl = hl.substring(0, 60) + '\u2026';
if (a.url) {
html += '<a href="' + a.url + '" target="_blank" rel="noopener" style="color:#C8A851;font-size:0.8rem;display:block;margin-top:3px;text-decoration:none;">' + hl + '</a>';
} else {
html += '<span style="color:#8896AB;font-size:0.8rem;display:block;margin-top:3px;">' + hl + '</span>';
}
html += '<span style="color:#556B7A;font-size:0.7rem;">' + (a.source || '') + '</span>';
});
html += '</div>';
}
return html;
}
function showMarkers(locations, apiLabels) { function showMarkers(locations, apiLabels) {
if (!mapInstance) createMap(); if (!mapInstance) createMap();
clearMarkers(); clearMarkers();
var categoryColors = { var categoryColors = {
primary: '#ef4444', primary: '#ef4444',
secondary: '#f59e0b', secondary: '#f59e0b',
@@ -343,7 +362,7 @@ function mdToHtml(md) {
primary: 'Hauptgeschehen', primary: 'Hauptgeschehen',
secondary: 'Reaktionen', secondary: 'Reaktionen',
tertiary: 'Beteiligte', tertiary: 'Beteiligte',
mentioned: 'Erwähnt' mentioned: 'Erw\u00e4hnt'
}; };
var categoryLabels = {}; var categoryLabels = {};
@@ -351,6 +370,14 @@ function mdToHtml(md) {
categoryLabels[k] = (apiLabels && apiLabels[k]) || defaultLabels[k]; categoryLabels[k] = (apiLabels && apiLabels[k]) || defaultLabels[k];
}); });
var clusterGroup = L.markerClusterGroup({
maxClusterRadius: 50,
spiderfyOnMaxZoom: true,
showCoverageOnHover: false,
zoomToBoundsOnClick: true,
disableClusteringAtZoom: 10
});
var usedCategories = {}; var usedCategories = {};
var bounds = []; var bounds = [];
@@ -360,17 +387,23 @@ function mdToHtml(md) {
var color = categoryColors[cat] || '#7b7b7b'; var color = categoryColors[cat] || '#7b7b7b';
usedCategories[cat] = true; usedCategories[cat] = true;
var popup = '<strong style="color:#E8ECF4;">' + (loc.name || '') + '</strong>'; var marker;
if (loc.country_code) popup += ' <span style="color:#8896AB;font-size:0.8rem;">(' + loc.country_code + ')</span>'; if (cat === 'primary' || cat === 'secondary') {
popup += '<br><span style="font-size:0.85rem;color:#8896AB;">' + (loc.article_count || 0) + ' Artikel</span>'; marker = L.marker([loc.lat, loc.lon], { icon: pulseIcon(color) });
} else {
L.marker([loc.lat, loc.lon], { icon: pulseIcon(color) }) marker = L.circleMarker([loc.lat, loc.lon], {
.addTo(markerLayer) radius: 5, fillColor: color, fillOpacity: 0.7,
.bindPopup(popup); color: color, weight: 1, opacity: 0.9
});
}
marker.bindPopup(buildPopup(loc), { maxWidth: 300 });
clusterGroup.addLayer(marker);
bounds.push([loc.lat, loc.lon]); bounds.push([loc.lat, loc.lon]);
}); });
// Dark legend (exact lagebild style) markerLayer = clusterGroup;
mapInstance.addLayer(markerLayer);
var legend = L.control({ position: 'bottomright' }); var legend = L.control({ position: 'bottomright' });
legend.onAdd = function () { legend.onAdd = function () {
var div = L.DomUtil.create('div'); var div = L.DomUtil.create('div');