"use strict"; import { apiGet } from "../core/api.js"; let refreshTimer = null; function ensurePanel() { let panel = document.getElementById("mhrn-structural-inspector"); if (panel) return panel; const workspace = document.getElementById("tab-network"); if (!workspace) return null; panel = document.createElement("section"); panel.id = "mhrn-structural-inspector"; panel.className = "mhrn-structural-inspector card"; panel.hidden = true; panel.innerHTML = `
STRUCTURAL HEATMAP · HISTORY · CONFIG

Strukturelle Analyse

Heatmap der strukturellen Aktivität, Verlaufshistorie und Konfiguration.

lade …

Heatmap

lade …

Verlaufshistorie

lade …

Konfiguration

lade …
`; const anchor = workspace.querySelector(":scope > header"); if (anchor) anchor.insertAdjacentElement("afterend", panel); else workspace.prepend(panel); return panel; } function renderHeatmap(data) { const el = document.getElementById("structural-heatmap"); if (!el) return; if (!data || data.available === false) { el.textContent = "Heatmap nicht verfügbar."; return; } const cells = data.cells || data.matrix || []; const maxVal = data.max_value || 1; if (!cells.length) { el.textContent = "Keine Heatmap-Daten."; return; } el.innerHTML = `
${cells.map(c => { const val = typeof c === "object" ? (c.value ?? c.intensity ?? 0) : c; const pct = Math.min(100, (val / maxVal) * 100); return `
`; }).join("")}
0
${escapeHtml(String(maxVal))}
`; } function renderHistory(data) { const el = document.getElementById("structural-history"); if (!el) return; if (!data || data.available === false) { el.textContent = "Historie nicht verfügbar."; return; } const entries = data.history || data.entries || []; if (!entries.length) { el.textContent = "Keine Historie."; return; } el.innerHTML = ` ${entries.slice(0, 20).map(e => ``).join("")}
TickEreignisÄnderung
${e.tick ?? "—"}${escapeHtml(e.event || e.type || "—")}${escapeHtml(e.change || e.delta || "—")}
`; } function renderConfig(data) { const el = document.getElementById("structural-config"); if (!el) return; if (!data || data.available === false) { el.textContent = "Konfiguration nicht verfügbar."; return; } const entries = Object.entries(data).filter(([, v]) => v !== null && v !== undefined); el.innerHTML = `
${entries.map(([k, v]) => `
${escapeHtml(k)}
${escapeHtml(typeof v === "object" ? JSON.stringify(v) : String(v))}
`).join("")}
`; const badge = document.getElementById("structural-badge"); if (badge) badge.textContent = data.status || "aktiv"; } async function refresh() { const panel = ensurePanel(); if (!panel || panel.hidden || panel.closest('.tab-content')?.hidden) return; const [heatmap, history, config] = await Promise.allSettled([ apiGet("/api/structural/heatmap"), apiGet("/api/structural/history"), apiGet("/api/structural/config"), ]); if (heatmap.status === "fulfilled") renderHeatmap(heatmap.value); else document.getElementById("structural-heatmap").textContent = `Fehler: ${heatmap.reason.message}`; if (history.status === "fulfilled") renderHistory(history.value); else document.getElementById("structural-history").textContent = `Fehler: ${history.reason.message}`; if (config.status === "fulfilled") renderConfig(config.value); else document.getElementById("structural-config").textContent = `Fehler: ${config.reason.message}`; } function escapeHtml(s) { const div = document.createElement("div"); div.textContent = s; return div.innerHTML; } function escapeAttr(s) { return String(s).replace(/"/g, """).replace(/'/g, "'"); } export function initStructuralInspector() { ensurePanel(); refresh(); if (refreshTimer) clearInterval(refreshTimer); refreshTimer = setInterval(refresh, 5000); }