Analyse: Cyberangriffe auf Kritische Infrastruktur 2026
'
- + '
8 Artikel · demo-user
'
- + '
'
- + '
',
-
- _DEMO_SUMMARY: '
Am Morgen des 16. März 2026 kam es im Hamburger Hafen zu einer schweren Explosion '
- + 'in einem Containerterminal am Burchardkai. Nach übereinstimmenden Berichten von '
- + 'dpa [1], '
- + 'Reuters [2] und '
- + 'NDR [3] '
- + 'ereignete sich die Detonation gegen 06:45 Uhr Ortszeit in einem Lagerbereich für Gefahrgut.
'
- + '
Die Hamburger Feuerwehr ist mit einem Großaufgebot vor Ort. Laut '
- + 'Hamburger Abendblatt [4] '
- + 'wurden mindestens 12 Personen verletzt, davon 3 schwer. Die Ursache der Explosion ist noch unklar. '
- + 'Die Polizei Hamburg hat den Bereich weiträumig abgesperrt.
'
- + '
Der Hamburger Hafen, Europas drittgrößter Seehafen, hat den Betrieb im betroffenen Terminal vorübergehend '
- + 'eingestellt. Auswirkungen auf den Schiffsverkehr werden derzeit geprüft '
- + 'HPA [5].
',
-
- _DEMO_FACTCHECKS: [
- { status: 'confirmed', icon: '✓', claim: 'Eine Explosion ereignete sich am 16.03.2026 gegen 06:45 Uhr im Hamburger Hafen.', sources: 5 },
- { status: 'confirmed', icon: '✓', claim: 'Mindestens 12 Personen wurden bei dem Vorfall verletzt.', sources: 3 },
- { status: 'established', icon: '✓', claim: 'Die Explosion fand im Bereich des Burchardkai-Terminals statt.', sources: 4 },
- { status: 'unconfirmed', icon: '?', claim: 'Es soll sich um eine Fehlfunktion in einem Gefahrgutcontainer handeln.', sources: 1 },
- { status: 'disputed', icon: '⚠', claim: 'Die Rauchwolke soll gesundheitsgefährdende Stoffe enthalten.', sources: 2 },
- { status: 'contradicted', icon: '✗', claim: 'Der gesamte Hamburger Hafen wurde geschlossen.', sources: 2 },
- ],
-
- _DEMO_SOURCES_STATS: '5 Kategorien · 14 Quellen · 14 Artikel',
-
- _DEMO_TIMELINE: [
- { time: '06:45', title: 'Explosion im Containerterminal Burchardkai', source: 'dpa', type: 'article' },
- { time: '07:02', title: 'Hamburger Feuerwehr rückt mit Großaufgebot aus', source: 'NDR', type: 'article' },
- { time: '07:15', title: 'Polizei sperrt Hafengebiet weiträumig ab', source: 'Hamburger Abendblatt', type: 'article' },
- { time: '07:30', title: 'Erste Meldungen über Verletzte', source: 'Reuters', type: 'article' },
- { time: '08:00', title: 'Hamburg Port Authority stoppt Betrieb im Terminal', source: 'HPA', type: 'article' },
- { time: '08:22', title: 'Lagebericht: Erster Überblick zum Vorfall', source: 'AegisSight', type: 'snapshot' },
- { time: '09:10', title: 'Gefahrgut-Spezialisten am Einsatzort eingetroffen', source: 'tagesschau.de', type: 'article' },
- ],
-
- // -----------------------------------------------------------------------
- // Demo-View injizieren / entfernen
- // -----------------------------------------------------------------------
- _injectDemoView() {
- // Zustand sichern
- var incidentView = document.getElementById('incident-view');
- var emptyState = document.getElementById('empty-state');
- this._savedState = {
- incidentViewDisplay: incidentView ? incidentView.style.display : 'none',
- emptyStateDisplay: emptyState ? emptyState.style.display : '',
- incidentTitle: document.getElementById('incident-title') ? document.getElementById('incident-title').textContent : '',
- summaryText: document.getElementById('summary-text') ? document.getElementById('summary-text').innerHTML : '',
- factcheckList: document.getElementById('factcheck-list') ? document.getElementById('factcheck-list').innerHTML : '',
- sourceStats: document.getElementById('source-overview-header-stats') ? document.getElementById('source-overview-header-stats').innerHTML : '',
- timeline: document.getElementById('timeline') ? document.getElementById('timeline').innerHTML : '',
- mapEmpty: document.getElementById('map-empty') ? document.getElementById('map-empty').style.display : '',
- layoutToolbar: document.getElementById('layout-toolbar') ? document.getElementById('layout-toolbar').style.display : 'none',
- typeBadge: document.getElementById('incident-type-badge') ? document.getElementById('incident-type-badge').innerHTML : '',
- refreshMode: document.getElementById('meta-refresh-mode') ? document.getElementById('meta-refresh-mode').innerHTML : '',
- headerStrip: document.getElementById('incident-header-strip') ? document.getElementById('incident-header-strip').style.display : '',
- fcFilters: document.getElementById('fc-filters') ? document.getElementById('fc-filters').innerHTML : '',
- mapStats: document.getElementById('map-stats') ? document.getElementById('map-stats').innerHTML : '',
- sidebarItems: null,
- };
-
- // Sidebar: Demo-Einträge hinzufügen
- var activeList = document.getElementById('active-incidents');
- if (activeList) {
- this._savedState.sidebarItems = activeList.innerHTML;
- activeList.insertAdjacentHTML('afterbegin', this._DEMO_SIDEBAR_ITEM);
- }
-
- // Empty-State verstecken, Incident-View anzeigen
- if (emptyState) emptyState.style.display = 'none';
- if (incidentView) incidentView.style.display = '';
-
- // Header
- var title = document.getElementById('incident-title');
- if (title) title.textContent = 'Explosion in Hamburger Hafen';
- var badge = document.getElementById('incident-type-badge');
- if (badge) { badge.textContent = 'Live-Monitoring'; badge.className = 'incident-type-badge type-adhoc'; }
- var refreshMode = document.getElementById('meta-refresh-mode');
- if (refreshMode) refreshMode.innerHTML = 'Auto-Refresh: 15 Min';
- var creator = document.getElementById('incident-creator');
- if (creator) creator.textContent = 'demo-user';
- var desc = document.getElementById('incident-description');
- if (desc) desc.textContent = 'Schwere Explosion im Hamburger Hafengebiet, Burchardkai-Terminal';
-
- // Layout-Toolbar
- var toolbar = document.getElementById('layout-toolbar');
- if (toolbar) toolbar.style.display = '';
-
- // Lagebild
- var summaryText = document.getElementById('summary-text');
- if (summaryText) summaryText.innerHTML = this._DEMO_SUMMARY;
-
- // Timestamp
- var ts = document.getElementById('lagebild-timestamp');
- if (ts) ts.textContent = '16.03.2026, 08:22';
-
- // Faktencheck
- var fcList = document.getElementById('factcheck-list');
- if (fcList) {
- var fcHtml = '';
- this._DEMO_FACTCHECKS.forEach(function(fc) {
- fcHtml += '
';
- mapContainer.appendChild(mapPlaceholder);
- }
- var mapStats = document.getElementById('map-stats');
- if (mapStats) mapStats.textContent = '3 Orte';
-
- // Meta
- var metaUpdated = document.getElementById('meta-updated');
- if (metaUpdated) metaUpdated.textContent = 'Aktualisiert: 16.03.2026, 09:10';
- },
-
- _removeDemoView() {
- if (!this._savedState) return;
- var s = this._savedState;
-
- // Sidebar Demo-Einträge entfernen
- document.querySelectorAll('.tutorial-demo').forEach(function(el) { el.remove(); });
-
- // Sidebar wiederherstellen
- var activeList = document.getElementById('active-incidents');
- if (activeList && s.sidebarItems !== null) activeList.innerHTML = s.sidebarItems;
-
- // Views wiederherstellen
- var incidentView = document.getElementById('incident-view');
- if (incidentView) incidentView.style.display = s.incidentViewDisplay;
- var emptyState = document.getElementById('empty-state');
- if (emptyState) emptyState.style.display = s.emptyStateDisplay;
-
- // Inhalte wiederherstellen
- var title = document.getElementById('incident-title');
- if (title) title.textContent = s.incidentTitle;
- var summaryText = document.getElementById('summary-text');
- if (summaryText) summaryText.innerHTML = s.summaryText;
- var fcList = document.getElementById('factcheck-list');
- if (fcList) fcList.innerHTML = s.factcheckList;
- var sourceStats = document.getElementById('source-overview-header-stats');
- if (sourceStats) sourceStats.innerHTML = s.sourceStats;
- var timeline = document.getElementById('timeline');
- if (timeline) timeline.innerHTML = s.timeline;
- var mapEmpty = document.getElementById('map-empty');
- if (mapEmpty) mapEmpty.style.display = s.mapEmpty;
- var toolbar = document.getElementById('layout-toolbar');
- if (toolbar) toolbar.style.display = s.layoutToolbar;
- var badge = document.getElementById('incident-type-badge');
- if (badge) badge.innerHTML = s.typeBadge;
- var refreshMode = document.getElementById('meta-refresh-mode');
- if (refreshMode) refreshMode.innerHTML = s.refreshMode;
- var fcFilters = document.getElementById('fc-filters');
- if (fcFilters) fcFilters.innerHTML = s.fcFilters;
- var mapStats = document.getElementById('map-stats');
- if (mapStats) mapStats.innerHTML = s.mapStats;
-
- // Map-Platzhalter entfernen
- var mapPlaceholder = document.querySelector('.tutorial-map-placeholder');
- if (mapPlaceholder) mapPlaceholder.remove();
-
- // Meta
- var metaUpdated = document.getElementById('meta-updated');
- if (metaUpdated) metaUpdated.textContent = '';
- var creator = document.getElementById('incident-creator');
- if (creator) creator.textContent = '';
- var desc = document.getElementById('incident-description');
- if (desc) desc.textContent = '';
- var ts = document.getElementById('lagebild-timestamp');
- if (ts) ts.textContent = '';
-
- this._savedState = null;
- },
-
- // -----------------------------------------------------------------------
- // Highlight-Helfer: Einzelnes Sub-Element innerhalb einer Kachel markieren
- // -----------------------------------------------------------------------
- _highlightSub(selector) {
- var el = document.querySelector(selector);
- if (!el) return;
- el.classList.add('tutorial-sub-highlight');
- this._cleanupFns.push(function() {
- el.classList.remove('tutorial-sub-highlight');
- });
- },
-
- _clearSubHighlights() {
- document.querySelectorAll('.tutorial-sub-highlight').forEach(function(el) {
- el.classList.remove('tutorial-sub-highlight');
- });
- },
-
- _cleanupFns: [],
-
- // -----------------------------------------------------------------------
- // Scroll-Helfer: Element in den sichtbaren Bereich scrollen
- // -----------------------------------------------------------------------
- _scrollToTarget(selector) {
- return new Promise(function(resolve) {
- var el = document.querySelector(selector);
- if (!el) { resolve(); return; }
- var rect = el.getBoundingClientRect();
- var vh = window.innerHeight;
- if (rect.top >= 0 && rect.bottom <= vh) {
- resolve();
- return;
- }
- el.scrollIntoView({ behavior: 'smooth', block: 'center' });
- setTimeout(resolve, 500);
- });
- },
-
- // -----------------------------------------------------------------------
- // Step-Definitionen
- // -----------------------------------------------------------------------
- _defineSteps() {
- this._steps = [
- // 0 - Welcome
- {
- id: 'welcome',
- target: '#main-content',
- title: 'Willkommen im AegisSight Monitor',
- text: 'Dieser interaktive Rundgang führt Sie durch alle Funktionen des OSINT-Monitors. '
- + 'Wir werden gemeinsam eine Demo-Lage anlegen und alle Bereiche des Dashboards erkunden.
'
- + 'Navigieren Sie mit den Pfeiltasten oder den Buttons. Mit Escape können Sie jederzeit abbrechen.',
- position: 'center',
- },
- // 1 - Sidebar
- {
- id: 'sidebar',
- target: '.sidebar',
- title: 'Seitenleiste: Ihre Lagen',
- text: 'Die Seitenleiste zeigt all Ihre Lagen in drei Bereichen:
'
- + 'Live-Monitoring - Laufende Ereignisbeobachtung mit automatischer Aktualisierung '
- + 'Recherchen - Themenanalysen ohne Echtzeit-Updates '
- + 'Archiv - Abgeschlossene Lagen zur späteren Einsicht
'
- + 'Klicken Sie auf eine Lage, um sie im Hauptbereich zu öffnen.',
- position: 'right',
- },
- // 2 - Neue Lage Button
- {
- id: 'new-incident-btn',
- target: '#new-incident-btn',
- title: 'Neue Lage anlegen',
- text: 'Hier starten Sie die Erstellung einer neuen Lage. Im nächsten Schritt zeigen wir Ihnen das Formular dazu.',
- position: 'right',
- onEnter: function() {
- setTimeout(function() {
- var overlay = document.getElementById('modal-new');
- if (overlay && !overlay.classList.contains('active')) {
- overlay.classList.add('active');
- }
- }, 1500);
- },
- onExit: function() {
- var overlay = document.getElementById('modal-new');
- if (overlay) overlay.classList.remove('active');
- },
- },
- // 3 - Neue Lage Modal: Überblick
- {
- id: 'new-incident-modal',
- target: '#modal-new .modal',
- title: 'Lage konfigurieren',
- text: 'Das Formular zur Lage-Erstellung. Hier legen Sie fest:
'
- + 'Titel - Kurze Bezeichnung des Vorfalls '
- + 'Beschreibung - Kontext und Hintergrundinformationen '
- + 'Art der Lage - Live-Monitoring oder Analyse/Recherche '
- + 'Quellen - Internationale und Telegram-Quellen ein/aus '
- + 'Sichtbarkeit - Öffentlich oder privat für Ihr Team '
- + 'Aktualisierung - Manuell oder automatisch mit Intervall',
- position: 'left',
- onEnter: function() {
- var overlay = document.getElementById('modal-new');
- if (overlay && !overlay.classList.contains('active')) {
- overlay.classList.add('active');
- }
- if (overlay) overlay.style.zIndex = '9002';
- // Demo: Titel vorausfüllen
- var titleInput = document.getElementById('inc-title');
- if (titleInput) titleInput.value = 'Explosion in Hamburger Hafen';
- var descInput = document.getElementById('inc-description');
- if (descInput) descInput.value = 'Schwere Explosion im Hamburger Hafengebiet, Burchardkai-Terminal';
- },
- onExit: function() {
- var overlay = document.getElementById('modal-new');
- if (overlay) {
- overlay.classList.remove('active');
- overlay.style.zIndex = '';
- }
- var titleInput = document.getElementById('inc-title');
- if (titleInput) titleInput.value = '';
- var descInput = document.getElementById('inc-description');
- if (descInput) descInput.value = '';
- },
- },
- // 4 - Lage-Typ: Live vs Recherche
- {
- id: 'incident-type',
- target: '#modal-new .modal',
- title: 'Live-Monitoring vs. Recherche',
- text: 'Live-Monitoring beobachtet ein Ereignis in Echtzeit. '
- + 'Hunderte Nachrichtenquellen werden automatisch durchsucht. '
- + 'Ideal für aktuelle Vorfälle, Krisen oder sich entwickelnde Lagen.
'
- + 'Analyse/Recherche untersucht ein Thema tiefergehend. '
- + 'Keine automatischen Updates, stattdessen gezielte Recherche mit eigenen Suchbegriffen. '
- + 'Ideal für Hintergrundanalysen und Lageberichte.',
- position: 'left',
- onEnter: function() {
- var overlay = document.getElementById('modal-new');
- if (overlay && !overlay.classList.contains('active')) {
- overlay.classList.add('active');
- }
- if (overlay) overlay.style.zIndex = '9002';
- Tutorial._highlightSub('#inc-type');
- },
- onExit: function() {
- var overlay = document.getElementById('modal-new');
- if (overlay) {
- overlay.classList.remove('active');
- overlay.style.zIndex = '';
- }
- Tutorial._clearSubHighlights();
- },
- },
- // 5 - Sidebar Filter
- {
- id: 'sidebar-filters',
- target: '.sidebar-filter',
- title: 'Lagen filtern',
- text: 'Mit diesen Filtern steuern Sie, welche Lagen angezeigt werden:
'
- + 'Alle - Zeigt sämtliche Lagen Ihrer Organisation '
- + 'Eigene - Nur Lagen, die Sie selbst erstellt haben
'
- + 'Bei vielen Lagen hilft dies, den Überblick zu behalten.',
- position: 'right',
- },
- // 6 - Demo-Lage einführen
- {
- id: 'demo-intro',
- target: '.incident-item.active.tutorial-demo',
- title: 'Unsere Demo-Lage',
- text: 'Für diesen Rundgang haben wir eine Demo-Lage erstellt: '
- + '"Explosion in Hamburger Hafen". Sie sehen sie hier in der Seitenleiste '
- + 'als aktive Lage mit Auto-Refresh.
'
- + 'In den folgenden Schritten erkunden wir alle Bereiche, '
- + 'die nach dem Öffnen einer Lage im Hauptbereich erscheinen.',
- position: 'right',
- onEnter: function() {
- Tutorial._injectDemoView();
- },
- },
- // 7 - Header-Bereich
- {
- id: 'incident-header',
- target: '#incident-header-strip',
- title: 'Lage-Kopfbereich',
- text: 'Der Kopfbereich zeigt alle wichtigen Informationen auf einen Blick:
'
- + 'Typ-Badge - Live-Monitoring oder Recherche '
- + 'Auto-Refresh - Zeigt das Aktualisierungsintervall '
- + 'Aktionsleiste - Aktualisieren, Bearbeiten, Exportieren, Archivieren und Löschen
'
- + 'Der Zeitstempel zeigt, wann die letzte Aktualisierung stattfand.',
- position: 'bottom',
- },
- // 8 - Refresh-Button
- {
- id: 'refresh',
- target: '#refresh-btn',
- title: 'Manuelle Aktualisierung',
- text: 'Mit diesem Button starten Sie eine sofortige Aktualisierung der Lage. '
- + 'Der Monitor durchsucht dann alle konfigurierten Quellen nach neuen Meldungen, '
- + 'erstellt ein aktualisiertes Lagebild und führt einen neuen Faktencheck durch.
'
- + 'Bei Live-Monitoring-Lagen mit Auto-Refresh geschieht dies zusätzlich automatisch im eingestellten Intervall.',
- position: 'bottom',
- onEnter: function() {
- Tutorial._highlightSub('#refresh-btn');
- },
- onExit: function() {
- Tutorial._clearSubHighlights();
- },
- },
- // 9 - Export
- {
- id: 'export',
- target: '#export-dropdown',
- title: 'Lagebericht exportieren',
- text: 'Exportieren Sie Ihre Lage in verschiedenen Formaten:
'
- + 'Lagebericht (Markdown/JSON) - Kompakte Zusammenfassung mit Faktencheck '
- + 'Vollexport - Alle Daten inklusive Artikel und Quellen '
- + 'Drucken / PDF - Druckoptimierte Ansicht für Berichte
'
- + 'Ideal, um Ergebnisse mit Kollegen zu teilen, die keinen Monitor-Zugang haben.',
- position: 'bottom',
- onEnter: function() {
- Tutorial._highlightSub('#export-dropdown');
- },
- onExit: function() {
- Tutorial._clearSubHighlights();
- },
- },
- // 10 - Layout Toolbar
- {
- id: 'layout-toolbar',
- target: '#layout-toolbar',
- title: 'Layout-Steuerung',
- text: 'Mit der Layout-Steuerung passen Sie Ihr Dashboard individuell an:
'
- + 'Jeder Button steht für eine Kachel: Lagebild, Faktencheck, '
- + 'Quellen, Timeline und Karte.
'
- + 'Klicken Sie auf einen Button, um die entsprechende Kachel ein- oder auszublenden. '
- + 'Mit "Layout zurücksetzen" stellen Sie die Standardansicht wieder her.',
- position: 'bottom',
- },
- // 11 - Lagebild (detailliert)
- {
- id: 'lagebild',
- target: '[gs-id="lagebild"]',
- title: 'Lagebild',
- text: 'Das Lagebild ist das Herzstück jeder Lage. Es wird automatisch aus allen gesammelten '
- + 'Quellen erstellt und bei jeder Aktualisierung neu generiert.
'
- + 'Quellenverweise - Die nummerierten Verweise [1], [2] etc. verlinken '
- + 'direkt zu den Originalartikeln. So können Sie jede Aussage nachprüfen. '
- + 'Vollansicht - Klicken Sie auf "Lagebild" in der Kopfzeile für eine '
- + 'große Darstellung mit mehr Platz zum Lesen. '
- + 'Zeitstempel - Zeigt, wann dieses Lagebild zuletzt generiert wurde.',
- position: 'right',
- onEnter: function() {
- Tutorial._highlightSub('[gs-id="lagebild"] .card-title');
- },
- onExit: function() {
- Tutorial._clearSubHighlights();
- },
- },
- // 12 - Quellenverweise im Lagebild
- {
- id: 'lagebild-sources',
- target: '#summary-text',
- title: 'Quellenverweise im Detail',
- text: 'Die farbigen Nummern im Text sind Quellenverweise. Wenn Sie mit der Maus darüberfahren, '
- + 'sehen Sie den Namen der Quelle. Ein Klick öffnet den Originalartikel.
'
- + 'So können Sie jede Behauptung im Lagebild direkt an der Originalquelle überprüfen. '
- + 'Je mehr unabhängige Quellen eine Information stützen, desto verlässlicher ist sie.',
- position: 'right',
- onEnter: function() {
- Tutorial._highlightSub('.source-ref[data-index="1"]');
- },
- onExit: function() {
- Tutorial._clearSubHighlights();
- },
- },
- // 13 - Faktencheck (detailliert)
- {
- id: 'faktencheck',
- target: '[gs-id="faktencheck"]',
- title: 'Faktencheck',
- text: 'Der Faktencheck prüft automatisch die wichtigsten Behauptungen anhand aller verfügbaren Quellen. '
- + 'Jeder Eintrag erhält einen Status:
'
- + '✓ Bestätigt/Gesichert - Durch mehrere unabhängige Quellen belegt '
- + '? Unbestätigt - Nur aus einer Quelle bekannt '
- + '⚠ Umstritten - Quellen widersprechen sich '
- + '✗ Widerlegt - Zuverlässige Quellen widersprechen',
- position: 'left',
- onEnter: function() {
- Tutorial._highlightSub('#factcheck-card');
- },
- onExit: function() {
- Tutorial._clearSubHighlights();
- },
- },
- // 14 - Faktencheck: Einzelner Eintrag
- {
- id: 'faktencheck-detail',
- target: '.factcheck-item[data-fc-status="confirmed"]',
- title: 'Faktencheck-Eintrag',
- text: 'Jeder Faktencheck-Eintrag besteht aus:
'
- + 'Status-Symbol - Farbcodiert für schnelle Einordnung (links) '
- + 'Behauptung - Die geprüfte Aussage '
- + 'Quellenanzahl - Wie viele Quellen diese Behauptung stützen
'
- + 'Die Filterfunktion oben rechts ermöglicht es, nach Status zu filtern, '
- + 'z.B. nur unbestätigte Meldungen anzeigen.',
- position: 'left',
- onEnter: function() {
- var item = document.querySelector('.factcheck-item[data-fc-status="confirmed"]');
- if (item) item.classList.add('tutorial-sub-highlight');
- Tutorial._cleanupFns.push(function() {
- if (item) item.classList.remove('tutorial-sub-highlight');
- });
- },
- onExit: function() {
- Tutorial._clearSubHighlights();
- },
- },
- // 15 - Quellen
- {
- id: 'quellen',
- target: '[gs-id="quellen"]',
- title: 'Quellenübersicht',
- text: 'Die Quellenübersicht zeigt alle für diese Lage verwendeten Quellen, gruppiert nach Kategorie:
'
- + 'Marker - Klicken Sie auf einen Marker für Details zum Ort und verknüpfte Artikel '
- + 'Cluster - Bei vielen Markern werden nahe Orte gruppiert '
- + 'Orte einlesen - Startet das Geoparsing manuell neu '
- + 'Vollbild - Vergrößert die Karte auf den gesamten Bildschirm
'
- + 'Besonders bei internationalen Lagen bietet die Karte einen schnellen Überblick über die räumliche Verteilung.',
- position: 'top',
- onEnter: function() {
- Tutorial._highlightSub('#geoparse-btn');
- setTimeout(function() {
- Tutorial._clearSubHighlights();
- Tutorial._highlightSub('#map-expand-btn');
- }, 3000);
- },
- onExit: function() {
- Tutorial._clearSubHighlights();
- },
- },
- // 18 - Drag Demo
- {
- id: 'drag-demo',
- target: '[gs-id="lagebild"] .card-header',
- title: 'Kacheln verschieben',
- text: 'Alle Kacheln im Dashboard lassen sich frei per Drag-and-Drop verschieben. '
- + 'Greifen Sie dazu die Kopfzeile einer Kachel und ziehen Sie sie an die gewünschte Position.
'
- + 'Beobachten Sie die virtuelle Maus-Demo:',
- position: 'right',
- disableNav: true,
- onEnter: function() {
- Tutorial._simulateDrag();
- },
- },
- // 19 - Resize Demo
- {
- id: 'resize-demo',
- target: '[gs-id="faktencheck"]',
- title: 'Kacheln in der Größe anpassen',
- text: 'Ziehen Sie am rechten unteren Rand einer Kachel, um ihre Größe zu verändern. '
- + 'So können Sie wichtigen Inhalten wie dem Faktencheck mehr Platz einräumen.
'
- + 'Beobachten Sie die virtuelle Maus-Demo:',
- position: 'left',
- disableNav: true,
- onEnter: function() {
- Tutorial._simulateResize();
- },
- },
- // 20 - Theme
- {
- id: 'theme',
- target: '#theme-toggle',
- title: 'Design umschalten',
- text: 'Wechseln Sie zwischen dem dunklen und hellen Design. '
- + 'Ihre Auswahl wird automatisch gespeichert und beim nächsten Besuch beibehalten.',
- position: 'bottom',
- },
- // 21 - Quellen verwalten
- {
- id: 'sources-btn',
- target: '.sidebar-sources-link button:first-child',
- title: 'Quellenverwaltung öffnen',
- text: 'In der Seitenleiste ganz unten finden Sie den Zugang zur Quellenverwaltung. '
- + 'Hier können Sie:
'
- + 'Name und URL - Die Quellbezeichnung und Adresse '
- + 'Kategorie - Nachrichtenagentur, Qualitätszeitung, etc. '
- + 'Sprache - Deutsch, Englisch oder Mehrsprachig '
- + 'Status - Aktiv oder deaktiviert
'
- + 'Sie können Quellen auch für einzelne Lagen ausschließen, ohne sie global zu deaktivieren.',
- position: 'left',
- onEnter: function() {
- var overlay = document.getElementById('modal-sources');
- if (overlay && !overlay.classList.contains('active')) {
- if (typeof App !== 'undefined' && App.openSourceManagement) {
- App.openSourceManagement();
- }
- }
- if (overlay) overlay.style.zIndex = '9002';
- },
- onExit: function() {
- var overlay = document.getElementById('modal-sources');
- if (overlay) {
- overlay.classList.remove('active');
- overlay.style.zIndex = '';
- }
- },
- },
- // 23 - Chat
- {
- id: 'chat',
- target: '#chat-toggle-btn',
- title: 'Chat-Assistent',
- text: 'Der Chat-Assistent steht Ihnen jederzeit zur Verfügung. '
- + 'Stellen Sie Fragen zur Bedienung des Monitors und erhalten Sie sofort eine Antwort.
'
- + 'Beispiele: '
- + '"Wie erstelle ich eine neue Lage?" '
- + '"Was bedeuten die Faktencheck-Status?" '
- + '"Wie exportiere ich einen Lagebericht?"',
- position: 'left',
- },
- // 24 - Ende
- {
- id: 'end',
- target: null,
- title: 'Rundgang abgeschlossen',
- text: 'Sie kennen jetzt alle wichtigen Funktionen des AegisSight Monitors.
'
- + 'Die Demo-Daten werden nach dem Schließen entfernt. '
- + 'Erstellen Sie Ihre erste eigene Lage über den Button "+ Neue Lage" in der Seitenleiste.
Analyse: Cyberangriffe auf Kritische Infrastruktur 2026
'
+ + '
8 Artikel · demo-user
'
+ + '
'
+ + '
',
+
+ _DEMO_SUMMARY: '
Am Morgen des 16. März 2026 kam es im Hamburger Hafen zu einer schweren Explosion '
+ + 'in einem Containerterminal am Burchardkai. Nach übereinstimmenden Berichten von '
+ + 'dpa [1], '
+ + 'Reuters [2] und '
+ + 'NDR [3] '
+ + 'ereignete sich die Detonation gegen 06:45 Uhr Ortszeit in einem Lagerbereich für Gefahrgut.
'
+ + '
Die Hamburger Feuerwehr ist mit einem Großaufgebot vor Ort. Laut '
+ + 'Hamburger Abendblatt [4] '
+ + 'wurden mindestens 12 Personen verletzt, davon 3 schwer. Die Ursache der Explosion ist noch unklar. '
+ + 'Die Polizei Hamburg hat den Bereich weiträumig abgesperrt.
'
+ + '
Der Hamburger Hafen, Europas drittgrößter Seehafen, hat den Betrieb im betroffenen Terminal vorübergehend '
+ + 'eingestellt. Auswirkungen auf den Schiffsverkehr werden derzeit geprüft '
+ + 'HPA [5].
',
+
+ _DEMO_FACTCHECKS: [
+ { status: 'confirmed', icon: '✓', claim: 'Eine Explosion ereignete sich am 16.03.2026 gegen 06:45 Uhr im Hamburger Hafen.', sources: 5 },
+ { status: 'confirmed', icon: '✓', claim: 'Mindestens 12 Personen wurden bei dem Vorfall verletzt.', sources: 3 },
+ { status: 'established', icon: '✓', claim: 'Die Explosion fand im Bereich des Burchardkai-Terminals statt.', sources: 4 },
+ { status: 'unconfirmed', icon: '?', claim: 'Es soll sich um eine Fehlfunktion in einem Gefahrgutcontainer handeln.', sources: 1 },
+ { status: 'disputed', icon: '⚠', claim: 'Die Rauchwolke soll gesundheitsgefährdende Stoffe enthalten.', sources: 2 },
+ { status: 'contradicted', icon: '✗', claim: 'Der gesamte Hamburger Hafen wurde geschlossen.', sources: 2 },
+ ],
+
+ _DEMO_SOURCES_STATS: '5 Kategorien · 14 Quellen · 14 Artikel',
+
+ _DEMO_TIMELINE: [
+ { time: '06:45', title: 'Explosion im Containerterminal Burchardkai', source: 'dpa', type: 'article' },
+ { time: '07:02', title: 'Hamburger Feuerwehr rückt mit Großaufgebot aus', source: 'NDR', type: 'article' },
+ { time: '07:15', title: 'Polizei sperrt Hafengebiet weiträumig ab', source: 'Hamburger Abendblatt', type: 'article' },
+ { time: '07:30', title: 'Erste Meldungen über Verletzte', source: 'Reuters', type: 'article' },
+ { time: '08:00', title: 'Hamburg Port Authority stoppt Betrieb im Terminal', source: 'HPA', type: 'article' },
+ { time: '08:22', title: 'Lagebericht: Erster Überblick zum Vorfall', source: 'AegisSight', type: 'snapshot' },
+ { time: '09:10', title: 'Gefahrgut-Spezialisten am Einsatzort eingetroffen', source: 'tagesschau.de', type: 'article' },
+ ],
+
+ // -----------------------------------------------------------------------
+ // Demo-View injizieren / entfernen
+ // -----------------------------------------------------------------------
+ _injectDemoView() {
+ // Zustand sichern
+ var incidentView = document.getElementById('incident-view');
+ var emptyState = document.getElementById('empty-state');
+ this._savedState = {
+ incidentViewDisplay: incidentView ? incidentView.style.display : 'none',
+ emptyStateDisplay: emptyState ? emptyState.style.display : '',
+ incidentTitle: document.getElementById('incident-title') ? document.getElementById('incident-title').textContent : '',
+ summaryText: document.getElementById('summary-text') ? document.getElementById('summary-text').innerHTML : '',
+ factcheckList: document.getElementById('factcheck-list') ? document.getElementById('factcheck-list').innerHTML : '',
+ sourceStats: document.getElementById('source-overview-header-stats') ? document.getElementById('source-overview-header-stats').innerHTML : '',
+ timeline: document.getElementById('timeline') ? document.getElementById('timeline').innerHTML : '',
+ mapEmpty: document.getElementById('map-empty') ? document.getElementById('map-empty').style.display : '',
+ layoutToolbar: document.getElementById('layout-toolbar') ? document.getElementById('layout-toolbar').style.display : 'none',
+ typeBadge: document.getElementById('incident-type-badge') ? document.getElementById('incident-type-badge').innerHTML : '',
+ refreshMode: document.getElementById('meta-refresh-mode') ? document.getElementById('meta-refresh-mode').innerHTML : '',
+ headerStrip: document.getElementById('incident-header-strip') ? document.getElementById('incident-header-strip').style.display : '',
+ fcFilters: document.getElementById('fc-filters') ? document.getElementById('fc-filters').innerHTML : '',
+ mapStats: document.getElementById('map-stats') ? document.getElementById('map-stats').innerHTML : '',
+ sidebarItems: null,
+ };
+
+ // Sidebar: Demo-Einträge hinzufügen
+ var activeList = document.getElementById('active-incidents');
+ if (activeList) {
+ this._savedState.sidebarItems = activeList.innerHTML;
+ activeList.insertAdjacentHTML('afterbegin', this._DEMO_SIDEBAR_ITEM);
+ }
+
+ // Empty-State verstecken, Incident-View anzeigen
+ if (emptyState) emptyState.style.display = 'none';
+ if (incidentView) incidentView.style.display = '';
+
+ // Header
+ var title = document.getElementById('incident-title');
+ if (title) title.textContent = 'Explosion in Hamburger Hafen';
+ var badge = document.getElementById('incident-type-badge');
+ if (badge) { badge.textContent = 'Live-Monitoring'; badge.className = 'incident-type-badge type-adhoc'; }
+ var refreshMode = document.getElementById('meta-refresh-mode');
+ if (refreshMode) refreshMode.innerHTML = 'Auto-Refresh: 15 Min';
+ var creator = document.getElementById('incident-creator');
+ if (creator) creator.textContent = 'demo-user';
+ var desc = document.getElementById('incident-description');
+ if (desc) desc.textContent = 'Schwere Explosion im Hamburger Hafengebiet, Burchardkai-Terminal';
+
+ // Layout-Toolbar
+ var toolbar = document.getElementById('layout-toolbar');
+ if (toolbar) toolbar.style.display = '';
+
+ // Lagebild
+ var summaryText = document.getElementById('summary-text');
+ if (summaryText) summaryText.innerHTML = this._DEMO_SUMMARY;
+
+ // Timestamp
+ var ts = document.getElementById('lagebild-timestamp');
+ if (ts) ts.textContent = '16.03.2026, 08:22';
+
+ // Faktencheck
+ var fcList = document.getElementById('factcheck-list');
+ if (fcList) {
+ var fcHtml = '';
+ this._DEMO_FACTCHECKS.forEach(function(fc) {
+ fcHtml += '
';
+ mapContainer.appendChild(mapPlaceholder);
+ }
+ var mapStats = document.getElementById('map-stats');
+ if (mapStats) mapStats.textContent = '3 Orte';
+
+ // Meta
+ var metaUpdated = document.getElementById('meta-updated');
+ if (metaUpdated) metaUpdated.textContent = 'Aktualisiert: 16.03.2026, 09:10';
+ },
+
+ _removeDemoView() {
+ if (!this._savedState) return;
+ var s = this._savedState;
+
+ // Sidebar Demo-Einträge entfernen
+ document.querySelectorAll('.tutorial-demo').forEach(function(el) { el.remove(); });
+
+ // Sidebar wiederherstellen
+ var activeList = document.getElementById('active-incidents');
+ if (activeList && s.sidebarItems !== null) activeList.innerHTML = s.sidebarItems;
+
+ // Views wiederherstellen
+ var incidentView = document.getElementById('incident-view');
+ if (incidentView) incidentView.style.display = s.incidentViewDisplay;
+ var emptyState = document.getElementById('empty-state');
+ if (emptyState) emptyState.style.display = s.emptyStateDisplay;
+
+ // Inhalte wiederherstellen
+ var title = document.getElementById('incident-title');
+ if (title) title.textContent = s.incidentTitle;
+ var summaryText = document.getElementById('summary-text');
+ if (summaryText) summaryText.innerHTML = s.summaryText;
+ var fcList = document.getElementById('factcheck-list');
+ if (fcList) fcList.innerHTML = s.factcheckList;
+ var sourceStats = document.getElementById('source-overview-header-stats');
+ if (sourceStats) sourceStats.innerHTML = s.sourceStats;
+ var timeline = document.getElementById('timeline');
+ if (timeline) timeline.innerHTML = s.timeline;
+ var mapEmpty = document.getElementById('map-empty');
+ if (mapEmpty) mapEmpty.style.display = s.mapEmpty;
+ var toolbar = document.getElementById('layout-toolbar');
+ if (toolbar) toolbar.style.display = s.layoutToolbar;
+ var badge = document.getElementById('incident-type-badge');
+ if (badge) badge.innerHTML = s.typeBadge;
+ var refreshMode = document.getElementById('meta-refresh-mode');
+ if (refreshMode) refreshMode.innerHTML = s.refreshMode;
+ var fcFilters = document.getElementById('fc-filters');
+ if (fcFilters) fcFilters.innerHTML = s.fcFilters;
+ var mapStats = document.getElementById('map-stats');
+ if (mapStats) mapStats.innerHTML = s.mapStats;
+
+ // Map-Platzhalter entfernen
+ var mapPlaceholder = document.querySelector('.tutorial-map-placeholder');
+ if (mapPlaceholder) mapPlaceholder.remove();
+
+ // Meta
+ var metaUpdated = document.getElementById('meta-updated');
+ if (metaUpdated) metaUpdated.textContent = '';
+ var creator = document.getElementById('incident-creator');
+ if (creator) creator.textContent = '';
+ var desc = document.getElementById('incident-description');
+ if (desc) desc.textContent = '';
+ var ts = document.getElementById('lagebild-timestamp');
+ if (ts) ts.textContent = '';
+
+ this._savedState = null;
+ },
+
+ // -----------------------------------------------------------------------
+ // Highlight-Helfer: Einzelnes Sub-Element innerhalb einer Kachel markieren
+ // -----------------------------------------------------------------------
+ _highlightSub(selector) {
+ var el = document.querySelector(selector);
+ if (!el) return;
+ el.classList.add('tutorial-sub-highlight');
+ this._cleanupFns.push(function() {
+ el.classList.remove('tutorial-sub-highlight');
+ });
+ },
+
+ _clearSubHighlights() {
+ document.querySelectorAll('.tutorial-sub-highlight').forEach(function(el) {
+ el.classList.remove('tutorial-sub-highlight');
+ });
+ },
+
+ _cleanupFns: [],
+
+ // -----------------------------------------------------------------------
+ // Scroll-Helfer: Element in den sichtbaren Bereich scrollen
+ // -----------------------------------------------------------------------
+ _scrollToTarget(selector) {
+ return new Promise(function(resolve) {
+ var el = document.querySelector(selector);
+ if (!el) { resolve(); return; }
+ var rect = el.getBoundingClientRect();
+ var vh = window.innerHeight;
+ if (rect.top >= 0 && rect.bottom <= vh) {
+ resolve();
+ return;
+ }
+ el.scrollIntoView({ behavior: 'smooth', block: 'center' });
+ setTimeout(resolve, 500);
+ });
+ },
+
+ // -----------------------------------------------------------------------
+ // Step-Definitionen
+ // -----------------------------------------------------------------------
+ _defineSteps() {
+ this._steps = [
+ // 0 - Welcome
+ {
+ id: 'welcome',
+ target: '#main-content',
+ title: 'Willkommen im AegisSight Monitor',
+ text: 'Dieser interaktive Rundgang führt Sie durch alle Funktionen des OSINT-Monitors. '
+ + 'Wir werden gemeinsam eine Demo-Lage anlegen und alle Bereiche des Dashboards erkunden.
'
+ + 'Navigieren Sie mit den Pfeiltasten oder den Buttons. Mit Escape können Sie jederzeit abbrechen.',
+ position: 'center',
+ },
+ // 1 - Sidebar
+ {
+ id: 'sidebar',
+ target: '.sidebar',
+ title: 'Seitenleiste: Ihre Lagen',
+ text: 'Die Seitenleiste zeigt all Ihre Lagen in drei Bereichen:
'
+ + 'Live-Monitoring - Laufende Ereignisbeobachtung mit automatischer Aktualisierung '
+ + 'Recherchen - Themenanalysen ohne Echtzeit-Updates '
+ + 'Archiv - Abgeschlossene Lagen zur späteren Einsicht
'
+ + 'Klicken Sie auf eine Lage, um sie im Hauptbereich zu öffnen.',
+ position: 'right',
+ },
+ // 2 - Neue Lage Button
+ {
+ id: 'new-incident-btn',
+ target: '#new-incident-btn',
+ title: 'Neue Lage anlegen',
+ text: 'Hier starten Sie die Erstellung einer neuen Lage. Im nächsten Schritt zeigen wir Ihnen das Formular dazu.',
+ position: 'right',
+ onEnter: function() {
+ setTimeout(function() {
+ var overlay = document.getElementById('modal-new');
+ if (overlay && !overlay.classList.contains('active')) {
+ overlay.classList.add('active');
+ }
+ }, 1500);
+ },
+ onExit: function() {
+ var overlay = document.getElementById('modal-new');
+ if (overlay) overlay.classList.remove('active');
+ },
+ },
+ // 3 - Neue Lage Modal: Überblick
+ {
+ id: 'new-incident-modal',
+ target: '#modal-new .modal',
+ title: 'Lage konfigurieren',
+ text: 'Das Formular zur Lage-Erstellung. Hier legen Sie fest:
'
+ + 'Titel - Kurze Bezeichnung des Vorfalls '
+ + 'Beschreibung - Kontext und Hintergrundinformationen '
+ + 'Art der Lage - Live-Monitoring oder Analyse/Recherche '
+ + 'Quellen - Internationale und Telegram-Quellen ein/aus '
+ + 'Sichtbarkeit - Öffentlich oder privat für Ihr Team '
+ + 'Aktualisierung - Manuell oder automatisch mit Intervall',
+ position: 'left',
+ onEnter: function() {
+ var overlay = document.getElementById('modal-new');
+ if (overlay && !overlay.classList.contains('active')) {
+ overlay.classList.add('active');
+ }
+ if (overlay) overlay.style.zIndex = '9002';
+ // Demo: Titel vorausfüllen
+ var titleInput = document.getElementById('inc-title');
+ if (titleInput) titleInput.value = 'Explosion in Hamburger Hafen';
+ var descInput = document.getElementById('inc-description');
+ if (descInput) descInput.value = 'Schwere Explosion im Hamburger Hafengebiet, Burchardkai-Terminal';
+ },
+ onExit: function() {
+ var overlay = document.getElementById('modal-new');
+ if (overlay) {
+ overlay.classList.remove('active');
+ overlay.style.zIndex = '';
+ }
+ var titleInput = document.getElementById('inc-title');
+ if (titleInput) titleInput.value = '';
+ var descInput = document.getElementById('inc-description');
+ if (descInput) descInput.value = '';
+ },
+ },
+ // 4 - Lage-Typ: Live vs Recherche (mit Cursor-Demo)
+ {
+ id: 'incident-type',
+ target: '#modal-new .modal',
+ title: 'Live-Monitoring vs. Recherche',
+ text: 'Live-Monitoring beobachtet ein Ereignis in Echtzeit. '
+ + 'Hunderte Nachrichtenquellen werden automatisch durchsucht. '
+ + 'Ideal f\u00fcr aktuelle Vorf\u00e4lle, Krisen oder sich entwickelnde Lagen.
'
+ + 'Analyse/Recherche untersucht ein Thema tiefergehend. '
+ + 'Keine automatischen Updates, stattdessen gezielte Recherche mit eigenen Suchbegriffen. '
+ + 'Ideal f\u00fcr Hintergrundanalysen und Lageberichte.',
+ position: 'left',
+ disableNav: true,
+ onEnter: function() {
+ var overlay = document.getElementById('modal-new');
+ if (overlay && !overlay.classList.contains('active')) {
+ overlay.classList.add('active');
+ }
+ if (overlay) overlay.style.zIndex = '9002';
+ Tutorial._highlightSub('#inc-type');
+ Tutorial._simulateTypeSwitch();
+ },
+ onExit: function() {
+ var overlay = document.getElementById('modal-new');
+ if (overlay) {
+ overlay.classList.remove('active');
+ overlay.style.zIndex = '';
+ }
+ // Select zur\u00fccksetzen
+ var sel = document.getElementById('inc-type');
+ if (sel) { sel.value = 'adhoc'; sel.dispatchEvent(new Event('change')); }
+ Tutorial._clearSubHighlights();
+ },
+ },
+ // 5 - Sidebar Filter
+ {
+ id: 'sidebar-filters',
+ target: '.sidebar-filter',
+ title: 'Lagen filtern',
+ text: 'Mit diesen Filtern steuern Sie, welche Lagen angezeigt werden:
'
+ + 'Alle - Zeigt sämtliche Lagen Ihrer Organisation '
+ + 'Eigene - Nur Lagen, die Sie selbst erstellt haben
'
+ + 'Bei vielen Lagen hilft dies, den Überblick zu behalten.',
+ position: 'right',
+ },
+ // 6 - Demo-Lage einführen
+ {
+ id: 'demo-intro',
+ target: '.incident-item.active.tutorial-demo',
+ title: 'Unsere Demo-Lage',
+ text: 'Für diesen Rundgang haben wir eine Demo-Lage erstellt: '
+ + '"Explosion in Hamburger Hafen". Sie sehen sie hier in der Seitenleiste '
+ + 'als aktive Lage mit Auto-Refresh.
'
+ + 'In den folgenden Schritten erkunden wir alle Bereiche, '
+ + 'die nach dem Öffnen einer Lage im Hauptbereich erscheinen.',
+ position: 'right',
+ onEnter: function() {
+ Tutorial._injectDemoView();
+ },
+ },
+ // 7 - Header-Bereich
+ {
+ id: 'incident-header',
+ target: '#incident-header-strip',
+ title: 'Lage-Kopfbereich',
+ text: 'Der Kopfbereich zeigt alle wichtigen Informationen auf einen Blick:
'
+ + 'Typ-Badge - Live-Monitoring oder Recherche '
+ + 'Auto-Refresh - Zeigt das Aktualisierungsintervall '
+ + 'Aktionsleiste - Aktualisieren, Bearbeiten, Exportieren, Archivieren und Löschen
'
+ + 'Der Zeitstempel zeigt, wann die letzte Aktualisierung stattfand.',
+ position: 'bottom',
+ },
+ // 8 - Refresh-Button
+ {
+ id: 'refresh',
+ target: '#refresh-btn',
+ title: 'Manuelle Aktualisierung',
+ text: 'Mit diesem Button starten Sie eine sofortige Aktualisierung der Lage. '
+ + 'Der Monitor durchsucht dann alle konfigurierten Quellen nach neuen Meldungen, '
+ + 'erstellt ein aktualisiertes Lagebild und führt einen neuen Faktencheck durch.
'
+ + 'Bei Live-Monitoring-Lagen mit Auto-Refresh geschieht dies zusätzlich automatisch im eingestellten Intervall.',
+ position: 'bottom',
+ onEnter: function() {
+ Tutorial._highlightSub('#refresh-btn');
+ },
+ onExit: function() {
+ Tutorial._clearSubHighlights();
+ },
+ },
+ // 9 - Export
+ {
+ id: 'export',
+ target: '#export-dropdown',
+ title: 'Lagebericht exportieren',
+ text: 'Exportieren Sie Ihre Lage in verschiedenen Formaten:
'
+ + 'Lagebericht (Markdown/JSON) - Kompakte Zusammenfassung mit Faktencheck '
+ + 'Vollexport - Alle Daten inklusive Artikel und Quellen '
+ + 'Drucken / PDF - Druckoptimierte Ansicht für Berichte
'
+ + 'Ideal, um Ergebnisse mit Kollegen zu teilen, die keinen Monitor-Zugang haben.',
+ position: 'bottom',
+ onEnter: function() {
+ Tutorial._highlightSub('#export-dropdown');
+ },
+ onExit: function() {
+ Tutorial._clearSubHighlights();
+ },
+ },
+ // 10 - Layout Toolbar
+ {
+ id: 'layout-toolbar',
+ target: '#layout-toolbar',
+ title: 'Layout-Steuerung',
+ text: 'Mit der Layout-Steuerung passen Sie Ihr Dashboard individuell an:
'
+ + 'Jeder Button steht für eine Kachel: Lagebild, Faktencheck, '
+ + 'Quellen, Timeline und Karte.
'
+ + 'Klicken Sie auf einen Button, um die entsprechende Kachel ein- oder auszublenden. '
+ + 'Mit "Layout zurücksetzen" stellen Sie die Standardansicht wieder her.',
+ position: 'bottom',
+ },
+ // 11 - Lagebild (detailliert)
+ {
+ id: 'lagebild',
+ target: '[gs-id="lagebild"]',
+ title: 'Lagebild',
+ text: 'Das Lagebild ist das Herzstück jeder Lage. Es wird automatisch aus allen gesammelten '
+ + 'Quellen erstellt und bei jeder Aktualisierung neu generiert.
'
+ + 'Quellenverweise - Die nummerierten Verweise [1], [2] etc. verlinken '
+ + 'direkt zu den Originalartikeln. So können Sie jede Aussage nachprüfen. '
+ + 'Vollansicht - Klicken Sie auf "Lagebild" in der Kopfzeile für eine '
+ + 'große Darstellung mit mehr Platz zum Lesen. '
+ + 'Zeitstempel - Zeigt, wann dieses Lagebild zuletzt generiert wurde.',
+ position: 'right',
+ onEnter: function() {
+ Tutorial._highlightSub('[gs-id="lagebild"] .card-title');
+ },
+ onExit: function() {
+ Tutorial._clearSubHighlights();
+ },
+ },
+ // 12 - Quellenverweise im Lagebild
+ {
+ id: 'lagebild-sources',
+ target: '#summary-text',
+ title: 'Quellenverweise im Detail',
+ text: 'Die farbigen Nummern im Text sind Quellenverweise. Wenn Sie mit der Maus darüberfahren, '
+ + 'sehen Sie den Namen der Quelle. Ein Klick öffnet den Originalartikel.
'
+ + 'So können Sie jede Behauptung im Lagebild direkt an der Originalquelle überprüfen. '
+ + 'Je mehr unabhängige Quellen eine Information stützen, desto verlässlicher ist sie.',
+ position: 'right',
+ onEnter: function() {
+ Tutorial._highlightSub('.source-ref[data-index="1"]');
+ },
+ onExit: function() {
+ Tutorial._clearSubHighlights();
+ },
+ },
+ // 13 - Faktencheck (detailliert)
+ {
+ id: 'faktencheck',
+ target: '[gs-id="faktencheck"]',
+ title: 'Faktencheck',
+ text: 'Der Faktencheck prüft automatisch die wichtigsten Behauptungen anhand aller verfügbaren Quellen. '
+ + 'Jeder Eintrag erhält einen Status:
'
+ + '✓ Bestätigt/Gesichert - Durch mehrere unabhängige Quellen belegt '
+ + '? Unbestätigt - Nur aus einer Quelle bekannt '
+ + '⚠ Umstritten - Quellen widersprechen sich '
+ + '✗ Widerlegt - Zuverlässige Quellen widersprechen',
+ position: 'left',
+ onEnter: function() {
+ Tutorial._highlightSub('#factcheck-card');
+ },
+ onExit: function() {
+ Tutorial._clearSubHighlights();
+ },
+ },
+ // 14 - Faktencheck: Einzelner Eintrag
+ {
+ id: 'faktencheck-detail',
+ target: '.factcheck-item[data-fc-status="confirmed"]',
+ title: 'Faktencheck-Eintrag',
+ text: 'Jeder Faktencheck-Eintrag besteht aus:
'
+ + 'Status-Symbol - Farbcodiert für schnelle Einordnung (links) '
+ + 'Behauptung - Die geprüfte Aussage '
+ + 'Quellenanzahl - Wie viele Quellen diese Behauptung stützen
'
+ + 'Die Filterfunktion oben rechts ermöglicht es, nach Status zu filtern, '
+ + 'z.B. nur unbestätigte Meldungen anzeigen.',
+ position: 'left',
+ onEnter: function() {
+ var item = document.querySelector('.factcheck-item[data-fc-status="confirmed"]');
+ if (item) item.classList.add('tutorial-sub-highlight');
+ Tutorial._cleanupFns.push(function() {
+ if (item) item.classList.remove('tutorial-sub-highlight');
+ });
+ },
+ onExit: function() {
+ Tutorial._clearSubHighlights();
+ },
+ },
+ // 15 - Quellen
+ {
+ id: 'quellen',
+ target: '[gs-id="quellen"]',
+ title: 'Quellenübersicht',
+ text: 'Die Quellenübersicht zeigt alle für diese Lage verwendeten Quellen, gruppiert nach Kategorie:
'
+ + 'Marker - Klicken Sie auf einen Marker für Details zum Ort und verknüpfte Artikel '
+ + 'Cluster - Bei vielen Markern werden nahe Orte gruppiert '
+ + 'Orte einlesen - Startet das Geoparsing manuell neu '
+ + 'Vollbild - Vergrößert die Karte auf den gesamten Bildschirm
'
+ + 'Besonders bei internationalen Lagen bietet die Karte einen schnellen Überblick über die räumliche Verteilung.',
+ position: 'top',
+ onEnter: function() {
+ Tutorial._highlightSub('#geoparse-btn');
+ setTimeout(function() {
+ Tutorial._clearSubHighlights();
+ Tutorial._highlightSub('#map-expand-btn');
+ }, 3000);
+ },
+ onExit: function() {
+ Tutorial._clearSubHighlights();
+ },
+ },
+ // 18 - Drag Demo
+ {
+ id: 'drag-demo',
+ target: '[gs-id="lagebild"] .card-header',
+ title: 'Kacheln verschieben',
+ text: 'Alle Kacheln im Dashboard lassen sich frei per Drag-and-Drop verschieben. '
+ + 'Greifen Sie dazu die Kopfzeile einer Kachel und ziehen Sie sie an die gewünschte Position.
'
+ + 'Beobachten Sie die virtuelle Maus-Demo:',
+ position: 'right',
+ disableNav: true,
+ onEnter: function() {
+ Tutorial._simulateDrag();
+ },
+ },
+ // 19 - Resize Demo
+ {
+ id: 'resize-demo',
+ target: '[gs-id="faktencheck"]',
+ title: 'Kacheln in der Größe anpassen',
+ text: 'Ziehen Sie am rechten unteren Rand einer Kachel, um ihre Größe zu verändern. '
+ + 'So können Sie wichtigen Inhalten wie dem Faktencheck mehr Platz einräumen.
'
+ + 'Beobachten Sie die virtuelle Maus-Demo:',
+ position: 'left',
+ disableNav: true,
+ onEnter: function() {
+ Tutorial._simulateResize();
+ },
+ },
+ // 20 - Theme
+ {
+ id: 'theme',
+ target: '#theme-toggle',
+ title: 'Design umschalten',
+ text: 'Wechseln Sie zwischen dem dunklen und hellen Design. '
+ + 'Ihre Auswahl wird automatisch gespeichert und beim nächsten Besuch beibehalten.',
+ position: 'bottom',
+ },
+ // 21 - Quellen verwalten
+ {
+ id: 'sources-btn',
+ target: '.sidebar-sources-link button:first-child',
+ title: 'Quellenverwaltung öffnen',
+ text: 'In der Seitenleiste ganz unten finden Sie den Zugang zur Quellenverwaltung. '
+ + 'Hier können Sie:
'
+ + 'Name und URL - Die Quellbezeichnung und Adresse '
+ + 'Kategorie - Nachrichtenagentur, Qualitätszeitung, etc. '
+ + 'Sprache - Deutsch, Englisch oder Mehrsprachig '
+ + 'Status - Aktiv oder deaktiviert
'
+ + 'Sie können Quellen auch für einzelne Lagen ausschließen, ohne sie global zu deaktivieren.',
+ position: 'left',
+ onEnter: function() {
+ var overlay = document.getElementById('modal-sources');
+ if (overlay && !overlay.classList.contains('active')) {
+ if (typeof App !== 'undefined' && App.openSourceManagement) {
+ App.openSourceManagement();
+ }
+ }
+ if (overlay) overlay.style.zIndex = '9002';
+ },
+ onExit: function() {
+ var overlay = document.getElementById('modal-sources');
+ if (overlay) {
+ overlay.classList.remove('active');
+ overlay.style.zIndex = '';
+ }
+ },
+ },
+ // 23 - Chat
+ {
+ id: 'chat',
+ target: '#chat-toggle-btn',
+ title: 'Chat-Assistent',
+ text: 'Der Chat-Assistent steht Ihnen jederzeit zur Verfügung. '
+ + 'Stellen Sie Fragen zur Bedienung des Monitors und erhalten Sie sofort eine Antwort.
'
+ + 'Beispiele: '
+ + '"Wie erstelle ich eine neue Lage?" '
+ + '"Was bedeuten die Faktencheck-Status?" '
+ + '"Wie exportiere ich einen Lagebericht?"',
+ position: 'left',
+ },
+ // 24 - Ende
+ {
+ id: 'end',
+ target: null,
+ title: 'Rundgang abgeschlossen',
+ text: 'Sie kennen jetzt alle wichtigen Funktionen des AegisSight Monitors.
'
+ + 'Die Demo-Daten werden nach dem Schließen entfernt. '
+ + 'Erstellen Sie Ihre erste eigene Lage über den Button "+ Neue Lage" in der Seitenleiste.