From 177c9a311ca1bc12f0f1b08585518932d0a876b7 Mon Sep 17 00:00:00 2001 From: Hitonabi Date: Wed, 23 Sep 2026 22:29:38 +0200 Subject: [PATCH] boxwart: Modell-Radar sucht, testet nachts selbst und empfiehlt (Hirn und Coder) Suche aus Merkliste (deploy/radar-watchlist.json) und Hugging-Face-Entdeckung; nur Kandidaten mit Bild-Projektor, die neben das Warm-Set passen (<= 115 GB inkl. KV-Cache). Nachtlauf mc2-radar.timer 00:30, Tests nur bis 02:30 (um 03:00 kommt NerdQuiz), hoechstens ein neuer Kandidat pro Woche, Notbremse 02:35, RuntimeMaxSec als letzte Sicherung. Pruefstand als Modul (deploy/bench/pruefstand.py): Tempo, Werkzeuge, Deutsch/JSON bzw. Programmieraufgaben und Bild-Probe gegen das heutige Modell der Rolle. Durchgefallene werden geloescht, Bestandene gemeldet und erst nach "Uebernehmen" getauscht. Beim Uebernehmen wandern die Zweitrollen mit (fast beim Hirn, heavy beim Coder), und das Warm-Set des Stewards wird selbst umgestellt statt als Handgriff zu bleiben. Modell-Code im Pruefstand darf keine Prozesse starten (RLIMIT_NPROC=0). Radar steht im Flugplan und unter Waechter-Aufsicht; deploy.sh spielt seine Units ein. Oberflaeche: Vergleichswerte je Kandidat, Rueckfrage vor Uebernehmen und Verwerfen, Status auf Deutsch. Co-Authored-By: Claude Opus 5.5 --- backend/app.py | 2 + backend/radar_lauf.py | 112 ++ backend/routers/radar.py | 44 + backend/services/llamaswap.py | 15 + backend/services/maintenance.py | 2 +- backend/services/radar.py | 1374 +++++++++++++++++ backend/services/waechter.py | 1 + backend/services/zeitplan.py | 2 +- backend/tests/test_radar.py | 617 ++++++++ deploy/bench/pruefstand-hirn.py | 230 +-- deploy/bench/pruefstand.py | 1106 +++++++++++++ deploy/deploy.sh | 4 + deploy/mc2-radar.service | 28 + deploy/mc2-radar.timer | 10 + deploy/radar-watchlist.json | 27 + frontend/dist/assets/Bestaetigen-VrcNpcBb.js | 1 + ...ienste-QEbMZv2T.js => Dienste-DEn0Zjkq.js} | 2 +- ...-DMWgWLUo.js => Einstellungen-BwCmWl9x.js} | 2 +- ...enue-gZV9ubEU.js => MehrMenue-CXteqmy8.js} | 2 +- frontend/dist/assets/Modelle-CHK2sw1N.js | 1 + frontend/dist/assets/Modelle-PWfbWtFC.js | 1 - frontend/dist/assets/Updates-3PYj6oWY.js | 2 - frontend/dist/assets/Updates-DPFIId2v.js | 2 + frontend/dist/assets/index-C3amg33Y.css | 2 + frontend/dist/assets/index-D4C10235.css | 2 - .../{index-B6MevgIX.js => index-ZVRs0IGR.js} | 4 +- frontend/dist/index.html | 4 +- frontend/src/lib/anzeige.ts | 17 + frontend/src/views/Modelle.tsx | 85 +- frontend/src/views/Start.tsx | 4 +- 30 files changed, 3511 insertions(+), 194 deletions(-) create mode 100644 backend/radar_lauf.py create mode 100644 backend/routers/radar.py create mode 100644 backend/services/radar.py create mode 100644 backend/tests/test_radar.py create mode 100644 deploy/bench/pruefstand.py create mode 100644 deploy/mc2-radar.service create mode 100644 deploy/mc2-radar.timer create mode 100644 deploy/radar-watchlist.json create mode 100644 frontend/dist/assets/Bestaetigen-VrcNpcBb.js rename frontend/dist/assets/{Dienste-QEbMZv2T.js => Dienste-DEn0Zjkq.js} (85%) rename frontend/dist/assets/{Einstellungen-DMWgWLUo.js => Einstellungen-BwCmWl9x.js} (86%) rename frontend/dist/assets/{MehrMenue-gZV9ubEU.js => MehrMenue-CXteqmy8.js} (83%) create mode 100644 frontend/dist/assets/Modelle-CHK2sw1N.js delete mode 100644 frontend/dist/assets/Modelle-PWfbWtFC.js delete mode 100644 frontend/dist/assets/Updates-3PYj6oWY.js create mode 100644 frontend/dist/assets/Updates-DPFIId2v.js create mode 100644 frontend/dist/assets/index-C3amg33Y.css delete mode 100644 frontend/dist/assets/index-D4C10235.css rename frontend/dist/assets/{index-B6MevgIX.js => index-ZVRs0IGR.js} (95%) diff --git a/backend/app.py b/backend/app.py index 63a877d..b149407 100644 --- a/backend/app.py +++ b/backend/app.py @@ -32,6 +32,7 @@ from routers import ( hermes_ui, maintenance, models, + radar, routing, system, voice, @@ -107,6 +108,7 @@ async def no_cache( app.include_router(health.router) app.include_router(boxwart.router) # Cockpit: Start, Hinweise, Modell-Nutzung, Zeitplan +app.include_router(radar.router) # Modell-Radar: Kandidaten, Nachttests, Übernehmen/Verwerfen app.include_router(models.router) app.include_router(routing.router) app.include_router(system.router) diff --git a/backend/radar_lauf.py b/backend/radar_lauf.py new file mode 100644 index 0000000..40f36b2 --- /dev/null +++ b/backend/radar_lauf.py @@ -0,0 +1,112 @@ +""" +Nächtlicher Lauf des Modell-Radars (Box-Wart, 09/2026) — gestartet von mc2-radar.timer um 00:30. + +Warum ein eigener Einstieg: Der Test lädt ein bis zu ~85 GB großes Modell neben Lucys Hirn. Das +darf nur nachts passieren und muss um 02:30 sicher vorbei sein, weil um 03:00 der NerdQuiz- +Nachtlauf das Hirn braucht. Ablauf: + + 1. Suchen — höchstens einmal am Tag (Merkliste + Entdeckung). + 2. Offene Urteile nachholen („getestet“: damals fehlte die Vergleichsmessung). + 3. Testen — nur im Fenster 00:30–02:30 und höchstens ein neuer Kandidat pro Woche. + +Die Messungen prüfen die Frist selbst. Hängt trotzdem etwas, zieht fünf Minuten nach der Frist die +Notbremse: Kandidaten-Server und Download werden gestoppt, der Prozess endet hart. systemd +(RuntimeMaxSec) ist die letzte Sicherung. Ist nichts fällig, endet der Lauf sofort mit Code 0. +""" + +import logging +import os +import signal +import subprocess +import sys +import threading +import time +from pathlib import Path + +from services import radar + +logging.basicConfig( + level=os.environ.get("MC_LOG_LEVEL", "INFO").upper(), + format="%(asctime)s %(levelname)-7s %(name)s: %(message)s", +) +log = logging.getLogger("radar_lauf") + +NOTBREMSE_S = int(os.environ.get("MC_RADAR_NOTBREMSE_S", "300")) + + +def _beim_beenden(signum, _frame) -> None: + """SIGTERM (systemd stop, RuntimeMaxSec) → normal auslaufen, damit der Kandidaten-Server gestoppt wird.""" + raise SystemExit(f"Signal {signum}") + + +def _notbremse(frist: float) -> threading.Timer: + def ziehen() -> None: + log.error("Radar: Notbremse – %s s nach der Frist läuft noch etwas, der Lauf wird hart beendet.", NOTBREMSE_S) + try: + radar.notstopp() + finally: + os._exit(3) + + bremse = threading.Timer(max(frist - time.time(), 0) + NOTBREMSE_S, ziehen) + bremse.daemon = True + bremse.start() + return bremse + + +NOTIFY = Path(__file__).resolve().parents[1] / "deploy" / "notify.sh" + + +def melde_bestanden(test: dict) -> None: + """Ein bestandener Kandidat wartet auf eine Entscheidung — einmal Bescheid geben, sonst liegt er + unbemerkt herum (Lehre der Pins vom September). notify.sh sammelt Nachtmeldungen für den Morgen.""" + k = radar.lade_stand()["kandidaten"].get(test.get("kandidat")) or {} + rolle = "das Hirn" if test.get("rolle") == "hirn" else "den Coder" + text = (f"{k.get('name') or test.get('kandidat')} hat den Nachttest für {rolle} bestanden. " + f"{str(test.get('zusammenfassung') or '')[:300]} " + "In MC2 unter Modelle kannst du ihn übernehmen oder verwerfen.") + try: + subprocess.run(["bash", str(NOTIFY), "-s", "[Modell-Radar]", text], timeout=120, check=False, + stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + except (OSError, subprocess.SubprocessError): + log.warning("Radar: Meldung über den bestandenen Kandidaten ging nicht raus.", exc_info=True) + + +def main() -> int: + beginn = radar.jetzt() + if radar.suche_faellig(beginn): + try: + ergebnis = radar.suche() + log.info("Radar: Suche – %s neu, %s warten", len(ergebnis.get("neu") or []), ergebnis.get("wartend")) + except Exception: + log.warning("Radar: Suche fehlgeschlagen", exc_info=True) + else: + log.info("Radar: heute schon gesucht.") + + if not radar.im_fenster(radar.jetzt()): + log.info("Radar: außerhalb des Test-Fensters %s–%s, nichts zu testen.", radar.FENSTER_START, + radar.FENSTER_ENDE) + return 0 + + frist = radar.fenster_ende(radar.jetzt()).timestamp() + signal.signal(signal.SIGTERM, _beim_beenden) + bremse = _notbremse(frist) + try: + if (nachgeholt := radar.nachurteilen(frist)): + log.info("Radar: %s offene Urteile nachgeholt.", nachgeholt) + plan = radar.plane_test(radar.lade_stand(), radar.jetzt()) + if not plan.get("kandidat"): + log.info("Radar: nichts fällig (%s).", plan.get("grund")) + return 0 + log.info("Radar: teste %s bis spätestens %s.", plan.get("grund"), radar.FENSTER_ENDE) + test = radar.teste(plan["kandidat"], frist) + if test: + log.info("Radar: %s – %s", test.get("ergebnis"), test.get("zusammenfassung")) + if test.get("ergebnis") == "bestanden": + melde_bestanden(test) + return 0 + finally: + bremse.cancel() + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/backend/routers/radar.py b/backend/routers/radar.py new file mode 100644 index 0000000..867d9b8 --- /dev/null +++ b/backend/routers/radar.py @@ -0,0 +1,44 @@ +""" +Modell-Radar-Schnittstellen (Box-Wart, Umbau 09/2026). + + GET /api/radar Nächster und letzter Test, Kandidaten, Test-Verlauf + POST /api/radar/suche Jetzt suchen (Merkliste + Hugging-Face-Entdeckung) + POST /api/radar/{id}/uebernehmen Bestandenen Kandidaten in Betrieb nehmen (Modell-Tausch) + POST /api/radar/{id}/verwerfen Kandidaten verwerfen (Dateien weg, nie wieder testen) + +Dünn: die Logik liegt in services/radar.py. Getestet wird nur nachts (backend/radar_lauf.py). +""" + +from fastapi import APIRouter, HTTPException +from services import radar + +router = APIRouter(prefix="/api", tags=["radar"]) + + +def _antwort(ergebnis: dict) -> dict: + if not ergebnis.get("ok"): + raise HTTPException(status_code=int(ergebnis.get("status") or 409), + detail=ergebnis.get("detail") or "Das ging nicht.") + return ergebnis + + +@router.get("/radar") +def radar_stand() -> dict: + return radar.uebersicht() + + +@router.post("/radar/suche") +def radar_suche() -> dict: + """Sucht sofort (Netz: Hugging Face) und liefert danach den neuen Stand.""" + ergebnis = radar.suche() + return {**radar.uebersicht(), "suche": ergebnis} + + +@router.post("/radar/{kandidat_id}/uebernehmen") +def radar_uebernehmen(kandidat_id: str) -> dict: + return _antwort(radar.uebernehmen(kandidat_id)) + + +@router.post("/radar/{kandidat_id}/verwerfen") +def radar_verwerfen(kandidat_id: str) -> dict: + return _antwort(radar.verwerfen(kandidat_id)) diff --git a/backend/services/llamaswap.py b/backend/services/llamaswap.py index 20079fe..7a28bf1 100644 --- a/backend/services/llamaswap.py +++ b/backend/services/llamaswap.py @@ -474,6 +474,21 @@ def set_role(model_id: str, role: str | None) -> bool: return True +def add_role(model_id: str, role: str) -> bool: + """Wie set_role, aber die übrigen Aliase des Ziel-Modells bleiben — für Modelle mit zwei Rollen + (Coder: coder UND heavy). set_role behielte nur die geschützten Aliase und würfe coder wieder weg.""" + cfg = read_config() + models = cfg.get("models") or {} + rolle = (role or "").strip().lower() + if model_id not in models or not rolle or not isinstance(models[model_id], dict): + return False + bisher = [a for a in (models[model_id].get("aliases") or []) if str(a).lower() != rolle] + set_role_alias(cfg, model_id, rolle) # nimmt die Rolle allen anderen Modellen weg + models[model_id]["aliases"] = bisher + [rolle] + write_config(cfg) + return True + + def set_ctx(model_id: str, ctx: int) -> bool: """Kontextlänge (-c) eines bestehenden Modells ändern.""" cfg = read_config() diff --git a/backend/services/maintenance.py b/backend/services/maintenance.py index 2f4dd23..ce9fd51 100644 --- a/backend/services/maintenance.py +++ b/backend/services/maintenance.py @@ -24,7 +24,7 @@ SYSTEM_SERVICES = {"llama-swap"} # erneut laufen lassen“ — der Wächter bietet das als Knopf an (services/waechter.py). USER_SERVICES = {"mission-control-2", "mc2-gateway", "mc2-steward", "box-console", "hermes-gateway", "hermes-builtin-ui", "voice-service", "lucy-stimme", - "projekte-sync", "mc2-backup"} + "projekte-sync", "mc2-backup", "mc2-radar"} # Engine-Update: lädt den neuesten Vulkan-Build (deploy/update-engine.sh, läuft als root). _REPO_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")) diff --git a/backend/services/radar.py b/backend/services/radar.py new file mode 100644 index 0000000..60bacf9 --- /dev/null +++ b/backend/services/radar.py @@ -0,0 +1,1374 @@ +""" +Modell-Radar (Box-Wart, Umbau 09/2026): sucht, prüft und empfiehlt neue Modelle für genau zwei +Rollen — das Hirn (Lucy: Hermes-Agent, ~100 Werkzeuge, Deutsch, ~13k Systemprompt) und den Coder +(agentisches Coding in OpenCode). Beide sollen auch Bilder verstehen. + +Warum: Neue Modelle tauchten bisher nur als Radar-Meldung auf; ob eines wirklich besser ist, zeigte +erst ein Prüfstand von Hand (17.09.). Das Radar macht beides selbst, mit engen Leitplanken +(User-Entscheid 23.09.): + + • Suche Merkliste deploy/radar-watchlist.json + discover.safe_discover. Ein Kandidat braucht + ein GGUF, ein mmproj und muss neben das Warm-Set passen + (27 GB inkl. Cache + Kandidat inkl. KV-Cache ≤ ~115 GB). + • Test nur nachts 00:30–02:30 (um 03:00 braucht der NerdQuiz-Nachtlauf das Hirn), höchstens + ein neuer Kandidat pro Woche: Download → llama-server auf :5899 → Prüfstand + (deploy/bench/pruefstand.py) gegen das heutige Modell der Rolle → Server stoppen. + • Ergebnis Durchgefallene werden gelöscht. Bestandene bleiben liegen, bis der Nutzer entscheidet; + getauscht wird erst mit „Übernehmen“. Nur ein Bestandener wird gemeldet (radar_lauf.py → + notify.sh; nachts landet das im Morgen-Überblick), alles andere steht nur in MC2. + +Status eines Kandidaten: + neu → wartet (als Nächster dran oder angefangen) → getestet (gemessen, Vergleich steht aus) + → bestanden / durchgefallen → uebernommen / verworfen (vom Nutzer oder vom Radar mit Grund). + +Zustand: MODELS_DIR/mc2-radar.json. Zwei Schreiber (der Nachtlauf radar_lauf.py und MC2 für die +Knöpfe) → jede Änderung läuft unter einer Datei-Sperre und wird atomar geschrieben. +Auf Windows (Entwicklung) scheitert alles Box-Nahe harmlos: kein Download, kein Server. +""" + +import hashlib +import importlib.util +import json +import logging +import math +import os +import re +import shutil +import signal +import struct +import subprocess +import sys +import threading +import time +from contextlib import contextmanager +from datetime import date, datetime, timedelta +from datetime import time as uhrzeit +from pathlib import Path +from urllib.parse import quote +from zoneinfo import ZoneInfo + +import httpx +import psutil +from config import HF_DOWNLOAD_ENV, LLAMA_SWAP_URL, MODELS_DIR +from ruamel.yaml.scalarstring import LiteralScalarString + +from services import discover, geheimnisse, hf, llamaswap +from services.fit import extract_active_params_b, extract_params_b + +try: + import fcntl # Linux: Datei-Sperre zwischen MC2 und dem Nachtlauf +except ImportError: # Windows (Entwicklung) + fcntl = None + +log = logging.getLogger(__name__) + +# --- Grenzen (jede mit Env-Override) ---------------------------------------------------- + +LOCAL_TZ = ZoneInfo(os.environ.get("MC_LOCAL_TZ", "Europe/Berlin")) +FENSTER_START = os.environ.get("MC_RADAR_FENSTER_START", "00:30") # Tests nur nachts … +FENSTER_ENDE = os.environ.get("MC_RADAR_FENSTER_ENDE", "02:30") # … um 03:00 kommt NerdQuiz +KANDIDATEN_PRO_WOCHE = int(os.environ.get("MC_RADAR_PRO_WOCHE", "1")) +SPEICHER_GRENZE_GB = float(os.environ.get("MC_RADAR_GRENZE_GB", "115")) # Warm-Set + Kandidat +WARMSET_GB = float(os.environ.get("MC_RADAR_WARMSET_GB", "27")) # Hirn + embed + reranker inkl. Cache +CODER_HEUTE_GB = float(os.environ.get("MC_RADAR_CODER_GB", "29")) # Coder heute inkl. Cache +HIRN_HEUTE_GB = float(os.environ.get("MC_RADAR_HIRN_GB", "25")) # Hirn-Anteil am Warm-Set +ENG_ANTEIL = float(os.environ.get("MC_RADAR_ENG_ANTEIL", "0.9")) # ab 90 % des Budgets „eng“ +CTX_ROLLE = {"hirn": int(os.environ.get("MC_RADAR_CTX_HIRN", "131072")), # Kontext wie im Betrieb + "coder": int(os.environ.get("MC_RADAR_CTX_CODER", "131072"))} +CTX_MIN = 32768 # darunter trägt der 13k-Test nicht mehr sinnvoll +PLATTE_MAX_PCT = float(os.environ.get("MC_RADAR_PLATTE_MAX_PCT", "80")) # = gelbe Grenze des Wächters +TESTZEIT_MIN = int(os.environ.get("MC_RADAR_TESTZEIT_MIN", "40")) # so viel Fenster muss nach dem Download bleiben +MIN_RESTZEIT_MIN = int(os.environ.get("MC_RADAR_MIN_RESTZEIT_MIN", "20")) # kurz vor Fensterende fängt nichts mehr an +VERSUCHE_MAX = int(os.environ.get("MC_RADAR_VERSUCHE", "3")) +BASELINE_TAGE = int(os.environ.get("MC_RADAR_BASELINE_TAGE", "30")) # Baseline höchstens monatlich neu messen +BILD_PFLICHT = os.environ.get("MC_RADAR_BILD_PFLICHT", "1") != "0" # ohne mmproj kein Kandidat +DISCOVER_MAX_JE_ROLLE = int(os.environ.get("MC_RADAR_DISCOVER_MAX", "3")) +MIN_PARAMS_B = float(os.environ.get("MC_RADAR_MIN_PARAMS_B", "20")) +HIRN_MAX_AKTIV_B = float(os.environ.get("MC_RADAR_HIRN_MAX_AKTIV_B", "12")) # Verdikt: dichte Modelle nie als Hirn +ABGELEHNT_TAGE = 30 +TESTS_MAX = 100 + +STORE_PATH = Path(os.environ.get("MC_RADAR_STORE", str(MODELS_DIR / "mc2-radar.json"))) +BASELINE_PATH = Path(os.environ.get("MC_RADAR_BASELINE", str(MODELS_DIR / "mc2-radar-baseline.json"))) +RADAR_DIR = Path(os.environ.get("MC_RADAR_DIR", str(MODELS_DIR / "radar"))) +_REPO = Path(__file__).resolve().parents[2] +WATCHLIST_PATH = Path(os.environ.get("MC_RADAR_WATCHLIST", str(_REPO / "deploy" / "radar-watchlist.json"))) +PRUEFSTAND_PATH = _REPO / "deploy" / "bench" / "pruefstand.py" +ENGINE_LIB = Path(os.environ.get("MC_RADAR_ENGINE_LIB", "/opt/llamacpp-vulkan/libllama.so")) +STEWARD_WARMSET = Path(os.environ.get("MC_RADAR_STEWARD_WARMSET", str( + Path.home() / ".config" / "systemd" / "user" / "mc2-steward.service.d" / "warmset.conf"))) +HF_BASIS = "https://huggingface.co" + +ROLLEN = ("hirn", "coder") +ALIAS = {"hirn": "hermes", "coder": "coder"} # llama-swap-Alias der Rolle heute +DISCOVER_ROLLEN = {"coder": "coder", "fast": "hirn", "hermes": "hirn"} +PARALLEL = {"hirn": 2, "coder": 1} # Slots im Betrieb, wie heute +KANDIDAT_FELDER = ("id", "name", "rolle", "repo", "datei", "groesse_gb", "passt", "eng", "quelle", "status", + "begruendung") +TEST_FELDER = ("id", "kandidat", "rolle", "datum", "ergebnis", "werte", "vergleich", "zusammenfassung") +_REIHENFOLGE = {"wartet": 0, "neu": 1, "getestet": 2, "bestanden": 3, "uebernommen": 4, "durchgefallen": 5, + "verworfen": 6} +_SCHRITTE = {"download": "lädt herunter", "baseline": "misst das heutige Modell", "test": "testet den Kandidaten"} + + +class Abbruch(Exception): + """Ein Lauf endet ohne Urteil. zaehlt=False: nicht die Schuld des Kandidaten (zählt nicht als Versuch).""" + + def __init__(self, grund: str, zaehlt: bool = True): + super().__init__(grund) + self.grund, self.zaehlt = grund, zaehlt + + +# --- Zeit -------------------------------------------------------------------------------- + +def jetzt() -> datetime: + return datetime.now(LOCAL_TZ) + + +def _hhmm(text: str) -> uhrzeit: + stunde, minute = text.strip().split(":") + return uhrzeit(int(stunde), int(minute)) + + +def _lokal(tag: date, uhr: uhrzeit) -> datetime: + """Ortszeit als eindeutiger Zeitpunkt. Am Umstellungstag (fehlende/doppelte Stunde) gilt der + FRÜHERE Zeitpunkt — ein Fenster endet lieber zu früh als in den NerdQuiz-Lauf hinein.""" + varianten = [datetime.combine(tag, uhr, tzinfo=LOCAL_TZ).replace(fold=f) for f in (0, 1)] + return min(varianten, key=lambda d: d.timestamp()) + + +def im_fenster(dt: datetime) -> bool: + start, ende, t = _hhmm(FENSTER_START), _hhmm(FENSTER_ENDE), dt.astimezone(LOCAL_TZ).time() + return start <= t < ende if start < ende else (t >= start or t < ende) + + +def fenster_ende(dt: datetime) -> datetime: + """Ende des Test-Fensters, in dem dt liegt (bzw. des nächsten).""" + dt = dt.astimezone(LOCAL_TZ) + start, ende = _hhmm(FENSTER_START), _hhmm(FENSTER_ENDE) + tag = dt.date() + timedelta(days=1) if (start > ende and dt.time() >= start) else dt.date() + return _lokal(tag, ende) + + +def naechster_start(dt: datetime) -> datetime: + """Nächster Fensterbeginn nach dt — dann startet der Timer den nächsten Lauf. Mitten im Fenster ist + der Lauf dieser Nacht schon gestartet (oder bewusst nicht), also zählt erst die nächste Nacht.""" + dt = dt.astimezone(LOCAL_TZ) + start = _lokal(dt.date(), _hhmm(FENSTER_START)) + if start.timestamp() <= dt.timestamp(): + start = _lokal(dt.date() + timedelta(days=1), _hhmm(FENSTER_START)) + return start + + +def _tag_von(ts: float | None) -> date | None: + return datetime.fromtimestamp(ts, LOCAL_TZ).date() if ts else None + + +def _iso(ts: float | None) -> str | None: + return datetime.fromtimestamp(ts, LOCAL_TZ).isoformat(timespec="seconds") if ts else None + + +def _datum(ts: float) -> str: + return datetime.fromtimestamp(ts, LOCAL_TZ).strftime("%d.%m.") + + +def _gb(wert: float) -> str: + return f"{wert:.1f}".replace(".", ",").removesuffix(",0") + + +# --- Namen --------------------------------------------------------------------------------- + +def kandidat_id(rolle: str, repo: str, quant: str) -> str: + return re.sub(r"[^a-z0-9]+", "-", f"{rolle}-{repo}-{quant}".lower()).strip("-") + + +def anzeigename(repo: str) -> str: + """Basisname aus dem Repo: ohne Org und ohne -GGUF; bartowskis „Qwen_Qwen3.6-…“ → „Qwen3.6-…“.""" + name = re.sub(r"[-_]GGUF$", "", repo.split("/")[-1], flags=re.IGNORECASE) + if "_" in name and (name.find("-") < 0 or name.index("_") < name.find("-")): + name = name.split("_", 1)[1] + return name + + +def stamm(name: str) -> str: + """Vergleichs-Stamm eines Modells (Repo, Ordner, Datei oder llama-swap-Name).""" + s = anzeigename(name).lower() + s = re.sub(r"\.gguf$", "", s) + s = re.sub(r"-\d{5}-of-\d{5}$", "", s) + s = re.sub(r"[-_](ud-)?(i?q\d\w*|f16|bf16|fp16|f32|mxfp4)$", "", s) + return s.strip("-_ ") + + +_FAMILIEN = (("qwen", r"qwen[-_ ]?(\d+(?:\.\d+)?)"), ("gemma", r"gemma[-_ ]?(\d+(?:\.\d+)?)"), + ("llama", r"llama[-_ ]?(\d+(?:\.\d+)?)"), ("glm", r"glm[-_ ]?(\d+(?:\.\d+)?)"), + ("nemotron", r"nemotron[-_ ]?(\d+(?:\.\d+)?)"), ("mistral", r"mistral[-_ ]?(\d+(?:\.\d+)?)"), + ("phi", r"phi[-_ ]?(\d+(?:\.\d+)?)"), ("deepseek", r"deepseek[-_ ]?v?(\d+(?:\.\d+)?)")) + + +def generation(name: str) -> tuple[str, float] | None: + """(Familie, Version) aus dem Namen, z. B. „Qwen3.6-35B-A3B“ → ("qwen", 3.6).""" + klein = anzeigename(name).lower() + for familie, muster in _FAMILIEN: + if (m := re.search(muster, klein)): + return familie, float(m.group(1)) + return None + + +# --- Filter (rein, ohne Netz) ------------------------------------------------------------------- + +def entdeckung_ungeeignet(m: dict, rolle: str, bekannt: set[str], heute: dict[str, str]) -> str | None: + """Warum ein discover-Fund fürs Radar nicht taugt; None = taugt. Discover rankt nach Beliebtheit — + ohne diese Vorauswahl verbrächte das Radar Wochen mit alten oder zu kleinen Modellen.""" + repo = str(m.get("repo") or "") + if m.get("curated"): + return "steht schon im kuratierten Katalog" + if stamm(repo) in bekannt: + return "liegt schon auf der Box" + params = float(m.get("params_b") or 0) + if params < MIN_PARAMS_B: + return f"zu klein ({params:.0f}B)" + if rolle == "hirn": + aktiv = (m.get("caps") or {}).get("active_b") or extract_active_params_b(repo) + if not aktiv or float(aktiv) > HIRN_MAX_AKTIV_B: + return "kein MoE mit wenigen aktiven Parametern (dichte Modelle nie als Hirn)" + neu, alt = generation(repo), generation(heute.get(rolle, "")) + if neu and alt and neu[0] == alt[0] and neu[1] < alt[1]: + return f"ältere Generation als das heutige Modell ({heute[rolle]})" + return None + + +def _groesse(eintrag: dict) -> int: + return int(eintrag.get("size") or (eintrag.get("lfs") or {}).get("size") or 0) + + +def _ist_hilfsdatei(pfad: str) -> bool: + name = pfad.lower().rsplit("/", 1)[-1] + return name.startswith("mtp-") or "draft" in name or "dflash" in name or "/mtp/" in f"/{pfad.lower()}" + + +def waehle_dateien(baum: list[dict], quant: str) -> dict | None: + """GGUF-Auswahl eines Repos: alle Teile des gewünschten Quants (Split-Dateien als Gruppe) und das + mmproj (F16 vor BF16 vor dem Rest). None, wenn es den Quant nicht gibt.""" + ggufs = [(str(e.get("path", "")), _groesse(e)) for e in baum if str(e.get("path", "")).lower().endswith(".gguf")] + muster = re.compile(rf"(^|[-_.]){re.escape(quant.lower())}([-_.]|$)") + modell = [(p, s) for p, s in ggufs + if "mmproj" not in p.lower() and not _ist_hilfsdatei(p) and muster.search(p.lower().rsplit("/", 1)[-1])] + if not modell: + return None + teile = sorted((p, s) for p, s in modell if re.search(r"-\d{5}-of-\d{5}\.gguf$", p, re.IGNORECASE)) + if teile: + praefix = re.sub(r"-\d{5}-of-\d{5}\.gguf$", "", teile[0][0], flags=re.IGNORECASE) + dateien = [[p, s] for p, s in teile if p.startswith(praefix)] + else: + dateien = [list(min(modell, key=lambda x: x[1]))] + + def rang(pfad: str) -> int: + klein = pfad.lower() + return 1 if "bf16" in klein else (0 if "f16" in klein else 2) + + projektoren = sorted(((p, s) for p, s in ggufs if "mmproj" in p.lower()), key=lambda x: (rang(x[0]), x[0])) + return {"dateien": dateien, "mmproj": list(projektoren[0]) if projektoren else None} + + +def speicher_passung(rolle: str, dateien_gb: float, kv_je_token_gb: float, eng_markiert: bool = False) -> dict: + """Passt der Kandidat neben das Warm-Set? Kontext wie im Betrieb, sonst stufenweise kleiner. + Regel (User 23.09.): Warm-Set + Kandidat inkl. KV-Cache ≤ Grenze. Ein Coder-Kandidat ersetzt den + heutigen Coder, ein Hirn-Kandidat läuft im Test neben dem heutigen Hirn — beides zählt so.""" + budget = SPEICHER_GRENZE_GB - WARMSET_GB + ziel = CTX_ROLLE[rolle] + for ctx in dict.fromkeys(c for c in (ziel, 65536, CTX_MIN) if c <= ziel): + bedarf = dateien_gb + kv_je_token_gb * ctx + if bedarf > budget: + continue + eng = eng_markiert or ctx < ziel or bedarf > ENG_ANTEIL * budget + text = (f"Passt{' knapp' if eng else ''}: braucht ~{_gb(bedarf)} GB inkl. KV-Cache (Kontext {ctx // 1024}k), " + f"neben dem Warm-Set sind {_gb(budget)} GB frei.") + if rolle == "hirn": + # Nach dem Tausch sitzt der Kandidat im Warm-Set — dann muss auch der Coder noch daneben passen. + betrieb = WARMSET_GB - HIRN_HEUTE_GB + bedarf + CODER_HEUTE_GB + if betrieb > SPEICHER_GRENZE_GB: + eng = True + text += f" Im Betrieb mit dem Coder wären es ~{_gb(betrieb)} GB – das wird eng." + return {"passt": True, "eng": eng, "ctx": ctx, "bedarf_gb": round(bedarf, 1), "text": text} + bedarf = dateien_gb + kv_je_token_gb * CTX_MIN + return {"passt": False, "eng": True, "ctx": CTX_MIN, "bedarf_gb": round(bedarf, 1), + "text": f"Passt nicht: braucht selbst mit {CTX_MIN // 1024}k Kontext ~{_gb(bedarf)} GB, neben dem " + f"Warm-Set sind nur {_gb(budget)} GB frei."} + + +def platte_nach_download(benutzt: int, gesamt: int, zusaetzlich: int) -> float: + """Füllstand der Platte in Prozent, wenn zusaetzlich Bytes dazukommen.""" + return (benutzt + zusaetzlich) / gesamt * 100 if gesamt else 100.0 + + +# --- GGUF-Kopf ------------------------------------------------------------------------------ + +_GGUF_SKALAR = {0: " dict | None: + """Skalare Metadaten vom Anfang einer GGUF-Datei (bis zum Tokenizer). Reicht für die Speicher- + Schätzung; die ersten paar MB kommen per Range-Anfrage, ohne das Modell zu laden.""" + pos = 0 + + def lies(n: int) -> bytes: + nonlocal pos + if pos + n > len(daten): + raise EOFError + stueck = daten[pos:pos + n] + pos += n + return stueck + + def zahl(fmt: str): + return struct.unpack(fmt, lies(struct.calcsize(fmt)))[0] + + def text() -> str: + return lies(zahl(" None: + if typ == 8: + lies(zahl(" float | None: + """KV-Cache in GB pro Kontext-Token bei q8_0. Hybrid-Modelle (full_attention_interval = n, z. B. + Qwen3.5/3.8) halten nur in jeder n-ten Schicht einen KV-Cache — services.gguf_meta rechnet hier mit + allen Schichten und käme auf das Vierfache.""" + arch = kopf.get("general.architecture") + if not arch: + return None + + def wert(schluessel: str): + return kopf.get(f"{arch}.{schluessel}") + + schichten, koepfe = wert("block_count"), wert("attention.head_count") + kv_koepfe = wert("attention.head_count_kv") or koepfe + einbettung = wert("embedding_length") + k_laenge = wert("attention.key_length") or (einbettung // koepfe if einbettung and koepfe else None) + v_laenge = wert("attention.value_length") or k_laenge + if not (schichten and kv_koepfe and k_laenge and v_laenge): + return None + intervall = int(wert("full_attention_interval") or 1) + voll = math.ceil(schichten / intervall) if intervall > 1 else schichten + return voll * kv_koepfe * (k_laenge + v_laenge) * bytes_je_wert / 1e9 + + +def _kv_schaetzung(repo: str, dateien_gb: float) -> float: + """Ohne lesbaren Kopf: grobe, eher zu große Schätzung wie services.fit (f16 kalibriert, × 0,53 für q8_0).""" + params = extract_params_b(repo) + if params <= 7.0: + params = max(dateien_gb / 0.55, 7.0) + return (max(params, 7) / 7) ** 0.5 * 0.84 / 8192 * 0.53 + + +def engine_kennt(arch: str) -> bool | None: + """Kennt die installierte llama.cpp-Engine diese Architektur? Die Namen stehen als C-Strings in + libllama.so. None = nicht prüfbar (keine Engine, z. B. auf Windows).""" + try: + daten = ENGINE_LIB.read_bytes() + except OSError: + return None + return (b"\x00" + arch.encode() + b"\x00") in daten + + +# --- Hugging Face (Netz) ------------------------------------------------------------------------ + +def _hf_kopfzeilen() -> dict: + token = geheimnisse.hf_token() + return {"Authorization": f"Bearer {token}"} if token else {} + + +def _hf_baum(repo: str) -> list[dict]: + with httpx.Client(timeout=20.0, headers=_hf_kopfzeilen()) as c: + r = c.get(f"{HF_BASIS}/api/models/{repo}/tree/main", params={"recursive": "true"}) + r.raise_for_status() + daten = r.json() + return daten if isinstance(daten, list) else [] + + +def _gguf_kopf(repo: str, datei: str, max_bytes: int = 8 << 20) -> dict | None: + """Die ersten MB einer GGUF-Datei per Range-Anfrage lesen und den Kopf auswerten.""" + puffer = bytearray() + try: + with httpx.Client(timeout=30.0, follow_redirects=True, headers=_hf_kopfzeilen()) as c: + with c.stream("GET", f"{HF_BASIS}/{repo}/resolve/main/{quote(datei)}", + headers={"Range": f"bytes=0-{max_bytes - 1}"}) as r: + if r.status_code not in (200, 206): + return None + for stueck in r.iter_bytes(): + puffer += stueck + if len(puffer) >= max_bytes: + break + except Exception: + log.debug("radar: GGUF-Kopf von %s/%s nicht lesbar", repo, datei, exc_info=True) + return None + return gguf_kopf_aus_bytes(bytes(puffer)) + + +# --- Zustand ------------------------------------------------------------------------------ + +def _leer() -> dict: + return {"version": 1, "letzte_suche": 0.0, "kandidaten": {}, "tests": [], "abgelehnt": {}, "lauf": None} + + +def _lade() -> dict: + try: + daten = json.loads(STORE_PATH.read_text(encoding="utf-8")) + except (OSError, ValueError): + daten = {} + stand = _leer() + if isinstance(daten, dict): + stand.update({k: v for k, v in daten.items() if k in stand and v is not None}) + return stand + + +def lade_stand() -> dict: + return _lade() + + +def _speichere(stand: dict) -> None: + try: + tmp = STORE_PATH.with_suffix(".tmp") + tmp.write_text(json.dumps(stand, ensure_ascii=False), encoding="utf-8") + tmp.replace(STORE_PATH) + except OSError: + log.warning("radar: Zustand %s nicht schreibbar", STORE_PATH, exc_info=True) + + +_thread_sperre = threading.Lock() +_sperr_tiefe = threading.local() + + +@contextmanager +def _gesperrt(): + """Sperre für Lesen-Ändern-Schreiben: Thread-Lock plus flock (MC2 und Nachtlauf sind zwei Prozesse). + Verschachtelt im selben Thread nur einmal sperren — flock über eine zweite Datei-Öffnung hinge sonst.""" + if getattr(_sperr_tiefe, "n", 0): + _sperr_tiefe.n += 1 + try: + yield + finally: + _sperr_tiefe.n -= 1 + return + with _thread_sperre: + datei = None + if fcntl is not None: + try: + datei = open(STORE_PATH.with_suffix(".lock"), "a+") + fcntl.flock(datei, fcntl.LOCK_EX) + except OSError: + datei = None + _sperr_tiefe.n = 1 + try: + yield + finally: + _sperr_tiefe.n = 0 + if datei is not None: + try: + fcntl.flock(datei, fcntl.LOCK_UN) + finally: + datei.close() + + +def _aendere(aenderung): + with _gesperrt(): + stand = _lade() + ergebnis = aenderung(stand) + _speichere(stand) + return ergebnis + + +def _aktiver_lauf(stand: dict) -> dict | None: + """Der laufende Nachtlauf — nur, wenn sein Prozess noch lebt und die Frist nicht lange vorbei ist.""" + lauf = stand.get("lauf") + if not isinstance(lauf, dict): + return None + try: + lebt = psutil.pid_exists(int(lauf.get("pid") or 0)) + except Exception: + lebt = False + if not lebt or time.time() > float(lauf.get("frist") or 0) + 900: + return None + return lauf + + +def _hat_geschichte(k: dict) -> bool: + """Einträge mit Geschichte fasst die Suche nicht mehr an (getestet, entschieden, angefangen).""" + return (k.get("status") in ("getestet", "bestanden", "durchgefallen", "uebernommen") + or (k.get("status") == "verworfen" and k.get("verworfen_von") == "nutzer") + or bool(k.get("erster_start"))) + + +def warteschlange(stand: dict) -> list[dict]: + """Testbare Kandidaten in Reihenfolge: Angefangene zuerst, dann Merkliste, dann Entdeckung.""" + offen = [k for k in stand["kandidaten"].values() if k.get("status") in ("neu", "wartet") and k.get("passt")] + return sorted(offen, key=lambda k: (0 if k.get("erster_start") else 1, 0 if k.get("quelle") == "watchlist" else 1, + k.get("rang", 999), k.get("gefunden", 0))) + + +def _ordne(stand: dict) -> None: + """Der Kopf der Warteschlange (und jeder Angefangene) steht auf „wartet“, alle anderen offenen auf „neu“.""" + for i, k in enumerate(warteschlange(stand)): + k["status"] = "wartet" if i == 0 or k.get("erster_start") else "neu" + + +def wochen_frei_ab(stand: dict, heute: date) -> date | None: + """Frühester Tag für einen NEUEN Kandidaten; None = heute schon frei. Ein Kandidat belegt die Woche + ab seinem ersten Start; Fortsetzungen (Download, Abbruch) belegen nichts Neues.""" + if KANDIDATEN_PRO_WOCHE <= 0: # 0 = Radar testet gar nicht + return heute + timedelta(days=3650) + starts = sorted((d for k in stand["kandidaten"].values() if (d := _tag_von(k.get("erster_start")))), + reverse=True) + in_woche = [d for d in starts if 0 <= (heute - d).days < 7] + if len(in_woche) < KANDIDATEN_PRO_WOCHE: + return None + return in_woche[KANDIDATEN_PRO_WOCHE - 1] + timedelta(days=7) + + +def plane_test(stand: dict, zeit: datetime) -> dict: + """Was jetzt zu tun ist: {"kandidat": id} oder {"kandidat": None, "grund": …}.""" + if not im_fenster(zeit): + return {"kandidat": None, "grund": f"außerhalb des Test-Fensters {FENSTER_START}–{FENSTER_ENDE}"} + rest = (fenster_ende(zeit).timestamp() - zeit.timestamp()) / 60 + if rest < MIN_RESTZEIT_MIN: + return {"kandidat": None, "grund": f"nur noch {rest:.0f} Minuten bis {FENSTER_ENDE}"} + if _aktiver_lauf(stand): + return {"kandidat": None, "grund": "es läuft schon ein Test"} + schlange = warteschlange(stand) + if not schlange: + return {"kandidat": None, "grund": "kein Kandidat wartet"} + k = schlange[0] + if not k.get("erster_start") and (frei := wochen_frei_ab(stand, zeit.astimezone(LOCAL_TZ).date())): + return {"kandidat": None, "grund": f"diese Woche lief schon ein Kandidat, der nächste frühestens am " + f"{frei:%d.%m.}"} + return {"kandidat": k["id"], "grund": f"{k['name']} ({k['rolle']})"} + + +def suche_faellig(zeit: datetime) -> bool: + """Der Nachtlauf sucht höchstens einmal am Tag.""" + return _tag_von(_lade().get("letzte_suche")) != zeit.astimezone(LOCAL_TZ).date() + + +# --- Suche -------------------------------------------------------------------------------- + +def _heutige_modelle() -> dict[str, dict]: + """Rolle → llama-swap-Modell, das heute den Alias der Rolle trägt.""" + heute: dict[str, dict] = {} + try: + modelle = llamaswap.list_models() + except Exception: + log.debug("radar: llama-swap-Config nicht lesbar", exc_info=True) + return heute + for m in modelle: + aliase = {str(a).lower() for a in m.get("aliases") or []} + for rolle, alias in ALIAS.items(): + if alias in aliase: + heute[rolle] = m + return heute + + +def _bekannte_staemme() -> set[str]: + """Was schon auf der Box liegt: llama-swap-Modelle und Ordner unter MODELS_DIR.""" + staemme: set[str] = set() + try: + for m in llamaswap.list_models(): + staemme.add(stamm(m["name"])) + if m.get("gguf_path"): + staemme.update({stamm(Path(m["gguf_path"]).parent.name), stamm(Path(m["gguf_path"]).name)}) + except Exception: + pass + try: + staemme.update(stamm(d.name) for d in MODELS_DIR.iterdir() if d.is_dir() and not d.name.startswith(".")) + except OSError: + pass + return staemme + + +def _merkliste() -> tuple[list[dict], bool]: + try: + daten = json.loads(WATCHLIST_PATH.read_text(encoding="utf-8")) + except (OSError, ValueError): + log.warning("radar: Merkliste %s nicht lesbar", WATCHLIST_PATH) + return [], False + eintraege = daten.get("kandidaten") if isinstance(daten, dict) else daten + funde = [{**e, "quelle": "watchlist", "rang": i} for i, e in enumerate(eintraege or []) + if isinstance(e, dict) and e.get("rolle") in ROLLEN and e.get("repo")] + return funde, True + + +def _entdeckung(bekannt: set[str], heute: dict[str, str], ausschluss: set[str]) -> tuple[list[dict], bool]: + try: + daten = discover.safe_discover(psutil.virtual_memory().total / 1024 ** 3) + except Exception: + log.warning("radar: Entdeckung fehlgeschlagen", exc_info=True) + daten = None + if not daten: + return [], False + funde: list[dict] = [] + je_rolle = dict.fromkeys(ROLLEN, 0) + for kategorie in daten.get("categories") or []: + rolle = DISCOVER_ROLLEN.get(kategorie.get("role")) + if not rolle: + continue + for rang, m in enumerate(kategorie.get("models") or []): + if je_rolle[rolle] >= DISCOVER_MAX_JE_ROLLE: + break + if not m.get("repo") or stamm(m["repo"]) in ausschluss: + continue + if (grund := entdeckung_ungeeignet(m, rolle, bekannt, heute)): + log.debug("radar: %s übergangen (%s)", m.get("repo"), grund) + continue + funde.append({"rolle": rolle, "repo": m["repo"], "quant": "Q4_K_M", "quelle": "discover", + "rang": 100 + rang, "autor": m.get("author")}) + je_rolle[rolle] += 1 + return funde, True + + +def _bewerte(fund: dict) -> dict: + """Aus einem Fund einen Kandidaten machen: Dateien auflösen, Größe, Engine-Unterstützung, Speicher. + Braucht Netz (Hugging Face) — wird deshalb außerhalb der Sperre aufgerufen.""" + rolle = fund["rolle"] + repo = hf.normalize_repo(fund["repo"]) + quant = str(fund.get("quant") or "Q4_K_M") + k: dict = {"id": kandidat_id(rolle, repo, quant), "name": fund.get("name") or anzeigename(repo), "rolle": rolle, + "repo": repo, "quant": quant, "quelle": fund["quelle"], "rang": fund.get("rang", 999), + "datei": "", "dateien": [], "mmproj": None, "draft": None, + "flags": [str(f) for f in fund.get("flags") or []], "groesse_gb": None, "passt": False, + "eng": bool(fund.get("eng")), "ctx": None, "bedarf_gb": None, "tauglich": False, "begruendung": ""} + herkunft = "Aus der Merkliste." if fund["quelle"] == "watchlist" else \ + f"Aus der Hugging-Face-Entdeckung ({fund.get('autor') or repo.split('/')[0]})." + notiz = f" {fund['notiz']}" if fund.get("notiz") else "" + if fund.get("ueberspringen"): + k["begruendung"] = f"Übersprungen: {fund['ueberspringen']}" + return k + try: + baum = _hf_baum(repo) + except Exception as e: + k["netzfehler"] = True + k["begruendung"] = f"Hugging Face gerade nicht erreichbar ({str(e)[:80]})." + return k + wahl = waehle_dateien(baum, quant) + if not wahl: + k["begruendung"] = f"Kein GGUF mit {quant} im Repo." + return k + k.update(dateien=wahl["dateien"], mmproj=wahl["mmproj"], datei=Path(wahl["dateien"][0][0]).name) + if BILD_PFLICHT and not wahl["mmproj"]: + k["begruendung"] = "Versteht keine Bilder: kein mmproj im Repo." + return k + groesse = sum(s for _, s in wahl["dateien"]) + (wahl["mmproj"][1] if wahl["mmproj"] else 0) + if isinstance(fund.get("draft"), dict): + d = fund["draft"] + d_repo, d_datei = hf.normalize_repo(d.get("repo") or repo), d.get("datei") + d_bytes = 0 + if d_datei: + try: + treffer = [e for e in (baum if d_repo == repo else _hf_baum(d_repo)) if e.get("path") == d_datei] + except Exception: + treffer = [] + if not treffer: + k["begruendung"] = f"Draft-Datei {d_datei} fehlt im Repo {d_repo}." + return k + d_bytes = _groesse(treffer[0]) + k["draft"] = {"repo": d_repo, "datei": d_datei, "bytes": d_bytes, "typ": d.get("typ") or "draft-simple", + "n_max": d.get("n_max")} + groesse += d_bytes + kopf = _gguf_kopf(repo, wahl["dateien"][0][0]) + arch = (kopf or {}).get("general.architecture") + if arch and engine_kennt(arch) is False: + k["begruendung"] = f"Läuft noch nicht im offiziellen llama.cpp (Architektur {arch} unbekannt).{notiz}" + return k + kv = (kv_je_token_gb(kopf) if kopf else None) or _kv_schaetzung(repo, groesse / 1e9) + passung = speicher_passung(rolle, groesse / 1e9, kv, eng_markiert=bool(fund.get("eng"))) + k.update(groesse_gb=round(groesse / 1e9, 1), passt=passung["passt"], eng=passung["eng"], ctx=passung["ctx"], + bedarf_gb=passung["bedarf_gb"], tauglich=passung["passt"], arch=arch) + k["begruendung"] = f"{herkunft} {passung['text']}{notiz}" + if not kopf and not passung["passt"]: + # Ohne Kopf rechnet die Schätzung den KV-Cache grob zu groß — darauf hin nichts verwerfen, + # die nächste Suche liest den Kopf erneut. + k.update(netzfehler=True, tauglich=False, + begruendung="Speicherbedarf unklar: der GGUF-Kopf ließ sich nicht lesen. Die nächste Suche " + "versucht es wieder.") + return k + + +_UEBERNEHMEN = ("name", "rolle", "repo", "quant", "quelle", "rang", "datei", "dateien", "mmproj", "draft", "flags", + "groesse_gb", "passt", "eng", "ctx", "bedarf_gb", "arch", "begruendung") + + +def _suche_anwenden(stand: dict, bewertet: list[dict], quellen_ok: dict[str, bool], zeit: float) -> dict: + """Bewertete Funde in den Zustand übernehmen (rein, ohne Netz).""" + kandidaten = stand["kandidaten"] + geschichte = {(k["rolle"], stamm(k["repo"])): kid for kid, k in kandidaten.items() if _hat_geschichte(k)} + gesehen, neu = set(), [] + for b in bewertet: + kid = b["id"] + gesehen.add(kid) + alt = kandidaten.get(kid) + if alt and _hat_geschichte(alt): + continue + frueher = geschichte.get((b["rolle"], stamm(b["repo"]))) + if frueher and frueher != kid: + continue # dasselbe Modell lief schon (z. B. aus einem anderen Repo) + if b.get("netzfehler"): + continue # alte Bewertung behalten, nicht wegen eines Netz-Aussetzers verwerfen + if b["quelle"] == "discover" and not b.get("tauglich"): + stand["abgelehnt"][stamm(b["repo"])] = {"grund": b["begruendung"], "zeit": zeit} + kandidaten.pop(kid, None) + continue + eintrag = {**(alt or {}), **{f: b.get(f) for f in _UEBERNEHMEN}, "id": kid, + "gefunden": (alt or {}).get("gefunden", zeit), "geaendert": zeit} + if b.get("tauglich"): + eintrag.update(status=(alt or {}).get("status", "neu"), verworfen_von=None) + if eintrag["status"] not in ("neu", "wartet"): + eintrag["status"] = "neu" + if not alt or alt.get("status") == "verworfen": + neu.append(eintrag["name"]) + else: + eintrag.update(status="verworfen", verworfen_von="radar") + kandidaten[kid] = eintrag + # Offene Einträge, die ihre (erreichbare) Quelle nicht mehr nennt, fliegen raus. + for kid in [kid for kid, k in kandidaten.items() + if kid not in gesehen and not _hat_geschichte(k) and quellen_ok.get(k.get("quelle"), False)]: + del kandidaten[kid] + stand["abgelehnt"] = {s: e for s, e in stand["abgelehnt"].items() + if zeit - float(e.get("zeit") or 0) < ABGELEHNT_TAGE * 86400} + _ordne(stand) + stand["letzte_suche"] = zeit + return {"ok": True, "neu": neu, "wartend": len(warteschlange(stand)), "gesamt": len(kandidaten), + "quellen": quellen_ok} + + +def suche() -> dict: + """Merkliste und Entdeckung auswerten und in den Zustand übernehmen. Das Netz (Hugging Face) läuft + außerhalb der Sperre, damit Knöpfe und Nachtlauf nicht warten müssen.""" + stand = _lade() + heute = {rolle: m["name"] for rolle, m in _heutige_modelle().items()} + ausschluss = {s for s, e in stand["abgelehnt"].items() + if time.time() - float(e.get("zeit") or 0) < ABGELEHNT_TAGE * 86400} + ausschluss |= {stamm(k["repo"]) for k in stand["kandidaten"].values() if _hat_geschichte(k)} + merkliste, merkliste_ok = _merkliste() + entdeckung, entdeckung_ok = _entdeckung(_bekannte_staemme(), heute, ausschluss) + bewertet = [] + for fund in merkliste + entdeckung: + try: + bewertet.append(_bewerte(fund)) + except Exception: + log.warning("radar: Bewertung von %s fehlgeschlagen", fund.get("repo"), exc_info=True) + ergebnis = _aendere(lambda s: _suche_anwenden(s, bewertet, {"watchlist": merkliste_ok, + "discover": entdeckung_ok}, time.time())) + log.info("radar: Suche fertig – %s neu, %s warten, %s insgesamt", len(ergebnis["neu"]), ergebnis["wartend"], + ergebnis["gesamt"]) + return ergebnis + + +# --- Test --------------------------------------------------------------------------------- + +_PS = None +_DOWNLOAD: dict = {"prozess": None} + + +def _pruefstand(): + """deploy/bench/pruefstand.py laden — ein Skript-Ordner, kein Paket; darum per Pfad.""" + global _PS + if _PS is None: + spec = importlib.util.spec_from_file_location("pruefstand", PRUEFSTAND_PATH) + modul = importlib.util.module_from_spec(spec) + sys.modules["pruefstand"] = modul + spec.loader.exec_module(modul) + _PS = modul + return _PS + + +def _protokoll(*teile) -> None: + log.info("radar: %s", " ".join(str(t) for t in teile)) + + +def _markiere_lauf(kid: str, schritt: str, frist: float) -> None: + def aenderung(stand: dict) -> None: + k = stand["kandidaten"].get(kid) + if k: + k["erster_start"] = k.get("erster_start") or time.time() + k["status"] = "wartet" + alt = stand.get("lauf") if isinstance(stand.get("lauf"), dict) else {} + eigener = alt.get("pid") == os.getpid() and alt.get("kandidat") == kid # nicht der Rest einer Vornacht + stand["lauf"] = {"pid": os.getpid(), "kandidat": kid, "schritt": schritt, + "seit": alt.get("seit") if eigener else time.time(), "frist": frist} + _aendere(aenderung) + + +def _loesche_dateien(k: dict) -> None: + """Kandidaten-Ordner löschen — nur, wenn er wirklich direkt unter RADAR_DIR liegt.""" + ordner = k.get("ordner") + if not ordner: + return + pfad = Path(ordner) + try: + if pfad.resolve().parent != RADAR_DIR.resolve(): + log.warning("radar: %s liegt nicht im Radar-Ordner – nicht gelöscht", pfad) + return + shutil.rmtree(pfad, ignore_errors=True) + except OSError: + log.warning("radar: %s nicht löschbar", pfad, exc_info=True) + return + k["ordner"] = None + + +def _abschluss(stand: dict, kid: str, ergebnis: str | None, satz: str, *, werte: dict | None = None, + vergleich: dict | None = None, zaehlt: bool = True, zeit: float | None = None) -> dict | None: + """Ergebnis eines Laufs in den Zustand schreiben: Status, Begründung, Test-Eintrag, ggf. Dateien löschen. + ergebnis None = gemessen, aber kein Vergleich möglich → „getestet“ (Urteil folgt später).""" + k = stand["kandidaten"].get(kid) + if not k: + return None + zeit = zeit or time.time() + tag = _datum(zeit) + k["geaendert"] = zeit + if ergebnis is None: + k.update(status="getestet", messung=werte, + begruendung=f"Gemessen am {tag}; der Vergleich mit dem heutigen Modell steht noch aus.") + _ordne(stand) + return None + zusammenfassung = satz + if ergebnis == "abgebrochen": + zusammenfassung = f"Abgebrochen: {satz}" + if zaehlt: + k["versuche"] = int(k.get("versuche") or 0) + 1 + if int(k.get("versuche") or 0) >= VERSUCHE_MAX: + _loesche_dateien(k) + k.update(status="durchgefallen", + begruendung=f"{VERSUCHE_MAX}-mal abgebrochen, zuletzt am {tag}: {satz} Dateien gelöscht.") + else: + k.update(status="wartet", begruendung=f"Abgebrochen am {tag}: {satz} Nächster Versuch in der nächsten Nacht.") + elif ergebnis == "bestanden": + k.update(status="bestanden", begruendung=f"{satz} Getestet am {tag}; wartet auf deine Entscheidung.") + else: + _loesche_dateien(k) + k.update(status="durchgefallen", begruendung=f"{satz} Getestet am {tag}; Dateien gelöscht.") + k.pop("messung", None) + test = {"id": f"{kid}-{datetime.fromtimestamp(zeit, LOCAL_TZ):%Y%m%d-%H%M}", "kandidat": kid, "rolle": k["rolle"], + "datum": _iso(zeit), "ergebnis": ergebnis, "werte": werte or {}, "vergleich": vergleich or {}, + "zusammenfassung": zusammenfassung} + stand["tests"].append(test) + del stand["tests"][:-TESTS_MAX] + _ordne(stand) + return test + + +def _erwartete_dateien(k: dict) -> dict[str, int]: + """Dateiname im Kandidaten-Ordner → erwartete Größe (Modellteile, mmproj, Draft).""" + namen = {Path(p).name: int(s) for p, s in k.get("dateien") or []} + if k.get("mmproj"): + namen[Path(k["mmproj"][0]).name] = int(k["mmproj"][1]) + if (k.get("draft") or {}).get("datei"): + namen[Path(k["draft"]["datei"]).name] = int(k["draft"].get("bytes") or 0) + return namen + + +def _vollstaendig(pfad: Path, groesse: int) -> bool: + try: + return pfad.is_file() and (not groesse or pfad.stat().st_size == groesse) + except OSError: + return False + + +def _lokale_pfade(k: dict, ordner: Path) -> dict: + return {"gguf": str(ordner / Path(k["dateien"][0][0]).name), + "mmproj": str(ordner / Path(k["mmproj"][0]).name) if k.get("mmproj") else None, + "draft": str(ordner / Path(k["draft"]["datei"]).name) if (k.get("draft") or {}).get("datei") else None} + + +def _ordner_bytes(ordner: Path) -> int: + summe = 0 + for wurzel, _, dateien in os.walk(ordner): + for name in dateien: + try: + summe += os.path.getsize(os.path.join(wurzel, name)) + except OSError: + pass + return summe + + +def _flach_legen(ordner: Path) -> None: + """hf legt Dateien mit ihrem Repo-Pfad ab (UD-IQ3_XXS/…). llama-swap leitet die Modell-ID aus dem + Elternordner ab — darum alle GGUF-Dateien in den Kandidaten-Ordner selbst holen.""" + for pfad in list(ordner.rglob("*.gguf")): + teile = pfad.relative_to(ordner).parts + if len(teile) == 1 or ".cache" in teile: + continue + pfad.replace(ordner / pfad.name) + for wurzel, _, _ in sorted(os.walk(ordner), key=lambda x: -len(x[0])): + if Path(wurzel) != ordner and ".cache" not in Path(wurzel).relative_to(ordner).parts: + try: + os.rmdir(wurzel) + except OSError: + pass + + +def _beende(prozess: subprocess.Popen) -> None: + try: + if os.name == "posix": # ganze Gruppe: hf startet eigene Kindprozesse + os.killpg(prozess.pid, signal.SIGTERM) + else: + prozess.terminate() + prozess.wait(timeout=30) + except Exception: + try: + prozess.kill() + except Exception: + pass + + +def _hf_download(repo: str, dateien: list[str], ordner: Path, bis: float) -> None: + befehl = [hf.hf_bin(), "download", repo, *dateien, "--local-dir", str(ordner)] + umgebung = {**os.environ, **HF_DOWNLOAD_ENV} + if (token := geheimnisse.hf_token()): + umgebung["HF_TOKEN"] = token + vorher = _ordner_bytes(ordner) + logpfad = RADAR_DIR / "download.log" + with open(logpfad, "w", encoding="utf-8") as logdatei: + prozess = subprocess.Popen(befehl, stdout=logdatei, stderr=subprocess.STDOUT, stdin=subprocess.DEVNULL, + env=umgebung, start_new_session=True) + _DOWNLOAD["prozess"] = prozess + try: + while prozess.poll() is None: + if time.time() > bis: + _beende(prozess) + geladen = (_ordner_bytes(ordner) - vorher) / 1e9 + raise Abbruch(f"Download bis {datetime.fromtimestamp(bis, LOCAL_TZ):%H:%M} nicht fertig " + f"({_gb(geladen)} GB in dieser Nacht) – geht in der nächsten Nacht weiter.", + zaehlt=geladen < 1.0) + time.sleep(5) + finally: + _DOWNLOAD["prozess"] = None + if prozess.returncode != 0: + try: + ende = logpfad.read_text(encoding="utf-8", errors="replace").strip().splitlines()[-1:] + except OSError: + ende = [] + raise Abbruch(f"Download von {repo} scheiterte: {(ende or ['ohne Meldung'])[0][:200]}") + + +def _download(k: dict, bis: float) -> Path: + """Fehlende Dateien des Kandidaten nach RADAR_DIR/ holen; Platz vorher prüfen.""" + ordner = RADAR_DIR / k["id"] + erwartet = _erwartete_dateien(k) + fehlend = {n: b for n, b in erwartet.items() if not _vollstaendig(ordner / n, b)} + if not fehlend: + return ordner + if os.name != "posix": + raise Abbruch("Herunterladen und Testen gehen nur auf der Box.", zaehlt=False) + try: + platte = shutil.disk_usage(MODELS_DIR) + except OSError as e: + raise Abbruch(f"Plattenplatz nicht prüfbar ({e}).", zaehlt=False) from e + nachher = platte_nach_download(platte.used, platte.total, sum(fehlend.values())) + if nachher > PLATTE_MAX_PCT: + raise Abbruch(f"Zu wenig Platz: nach dem Download wäre die Platte zu {nachher:.0f} % voll " + f"(Grenze {PLATTE_MAX_PCT:.0f} %).", zaehlt=False) + ordner.mkdir(parents=True, exist_ok=True) + _aendere(lambda s: s["kandidaten"].get(k["id"], {}).update(ordner=str(ordner))) + k["ordner"] = str(ordner) + haupt = [p for p, _ in k["dateien"]] + ([k["mmproj"][0]] if k.get("mmproj") else []) + draft = k.get("draft") or {} + if draft.get("datei") and draft.get("repo") == k["repo"]: + haupt.append(draft["datei"]) + _hf_download(k["repo"], haupt, ordner, bis) + if draft.get("datei") and draft.get("repo") != k["repo"]: + _hf_download(draft["repo"], [draft["datei"]], ordner, bis) + _flach_legen(ordner) + if (noch := [n for n, b in erwartet.items() if not _vollstaendig(ordner / n, b)]): + raise Abbruch(f"Download unvollständig: {', '.join(noch)}") + return ordner + + +def _warmset() -> set[str]: + warm: set[str] = set() + for gruppe in (llamaswap.list_groups() or {}).values(): + if isinstance(gruppe, dict) and (gruppe.get("persistent") or gruppe.get("persist")): + warm.update(gruppe.get("members") or []) + return warm + + +def _fremde_modelle(warm: set[str]) -> list[str]: + return [m for m in llamaswap.get_running_models() if m and m not in warm] + + +def _nur_warmset(warte_s: float = 90) -> set[str]: + """Vor dem Kandidaten darf in llama-swap nur das Warm-Set laufen (der Coder z. B. nicht) — + sonst reicht die 115-GB-Rechnung nicht.""" + warm = _warmset() + if not warm: + raise Abbruch("Das Warm-Set ist unbekannt (llama-swap-Config ohne persistente Gruppe) – ohne sichere " + "Speicherrechnung kein Test.", zaehlt=False) + fremd = _fremde_modelle(warm) + for name in fremd: + try: + with httpx.Client(timeout=30.0) as c: + c.post(f"{LLAMA_SWAP_URL}/api/models/unload/{quote(name)}") + except Exception: + log.warning("radar: %s ließ sich nicht entladen", name, exc_info=True) + t0 = time.time() + while fremd and time.time() - t0 < warte_s: + time.sleep(3) + fremd = _fremde_modelle(warm) + if fremd: + raise Abbruch(f"{', '.join(fremd)} ließ sich nicht entladen – ohne freien Speicher kein Test.", zaehlt=False) + return warm + + +class _Nachtwaechter(threading.Thread): + """Passt während des Kandidaten-Tests auf: Lädt llama-swap nachts ein weiteres Modell (etwa den Coder + für OpenCode), reicht der Speicher nicht mehr — dann den Kandidaten sofort stoppen.""" + + def __init__(self, warm: set[str], intervall: float = 10.0): + super().__init__(daemon=True, name="radar-nachtwaechter") + self.warm, self.intervall, self.grund = warm, intervall, "" + self._halt = threading.Event() + + def run(self) -> None: + while not self._halt.wait(self.intervall): + if (fremd := _fremde_modelle(self.warm)): + self.grund = (f"Während des Tests wurde {', '.join(fremd)} geladen – abgebrochen, damit der " + f"Speicher reicht.") + _pruefstand().stoppe_alle(warte_s=10) + return + + def halt(self) -> None: + self._halt.set() + + +def _baseline(rolle: str, frist: float) -> dict | None: + """Werte des heutigen Modells der Rolle (Cache, höchstens monatlich neu gemessen).""" + heute = _heutige_modelle().get(rolle) + if not heute: + return None + befehl = str(heute.get("cmd") or "") + kennung = f"{heute['name']}|{hashlib.sha1(befehl.encode()).hexdigest()[:10]}" + return _pruefstand().baseline(rolle, str(BASELINE_PATH), kennung=kennung, bild="--mmproj" in befehl, + frist=frist, max_alter_tage=BASELINE_TAGE, modell=ALIAS[rolle], + protokoll=_protokoll) + + +def teste(kid: str, frist: float) -> dict | None: + """Einen Kandidaten prüfen: Download → Baseline → nur Warm-Set in llama-swap → Kandidat auf :5899 → + Urteil. Gibt den Test-Eintrag zurück (None, wenn nur gemessen wurde oder es den Kandidaten nicht gibt).""" + ps = _pruefstand() + k = _lade()["kandidaten"].get(kid) + if not k or k.get("status") not in ("neu", "wartet"): # inzwischen verworfen o. Ä. + return None + _markiere_lauf(kid, "download", frist) + ergebnis, satz, werte, vergleich, zaehlt = "abgebrochen", "", None, None, True + waechter, von_aussen = None, None + try: + ordner = _download(k, frist - TESTZEIT_MIN * 60) + pfade = _lokale_pfade(k, ordner) + _markiere_lauf(kid, "baseline", frist) + basis = _baseline(k["rolle"], frist) + _markiere_lauf(kid, "test", frist) + waechter = _Nachtwaechter(_nur_warmset()) + waechter.start() + draft = k.get("draft") or {} + flags = ps.draft_flags(pfade["draft"], draft.get("typ"), draft.get("n_max")) + list(k.get("flags") or []) + lauf = ps.pruefe_kandidat(k["rolle"], pfade["gguf"], mmproj=pfade["mmproj"], flags=flags, + ctx=int(k.get("ctx") or ps.CTX_STANDARD), basis=(basis or {}).get("werte"), + frist=frist, protokoll=_protokoll) + werte, vergleich = lauf["werte"], lauf["vergleich"] + if basis: + werte["baseline"] = {"modell": (basis.get("werte") or {}).get("modell"), "gemessen": _iso(basis.get("zeit"))} + ergebnis, satz = lauf["ergebnis"], lauf["zusammenfassung"] + except ps.Zeitende: + satz = f"Das Nachtfenster endete um {FENSTER_ENDE}, bevor der Test fertig war." + except ps.ServerFehler as e: + if "unknown model architecture" in str(e).lower(): + ergebnis, satz = "durchgefallen", f"Durchgefallen: läuft nicht im offiziellen llama.cpp ({str(e)[:160]})." + else: + satz = f"Der Kandidat lief nicht: {str(e)[:240]}" + except Abbruch as e: + satz, zaehlt = e.grund, e.zaehlt + except Exception as e: + if not (waechter and waechter.grund): # Wächter-Abbruch ist erwartet, kein Fehler fürs Journal + log.exception("radar: Test von %s scheiterte", kid) + satz = f"Unerwarteter Fehler: {str(e)[:200]}" + except BaseException as e: # SIGTERM von systemd (SystemExit) oder Strg+C: festhalten, dann weiter + von_aussen = e + satz, zaehlt = "Der Lauf wurde von außen beendet.", False + finally: + if waechter: + waechter.halt() + ps.stoppe_alle() + if waechter and waechter.grund: # der Wächter hat abgebrochen — dann zählt kein Messwert als Urteil + ergebnis, satz, zaehlt, vergleich = "abgebrochen", waechter.grund, False, None + + def abschluss(stand: dict): + stand["lauf"] = None + return _abschluss(stand, kid, ergebnis, satz, werte=werte, vergleich=vergleich, zaehlt=zaehlt) + test = _aendere(abschluss) + log.info("radar: %s → %s (%s)", kid, ergebnis, satz) + if von_aussen is not None: + raise von_aussen + return test + + +def nachurteilen(frist: float) -> int: + """„getestet“-Kandidaten (damals fehlte die Vergleichsmessung) jetzt beurteilen, falls es sie gibt.""" + offen = [k for k in _lade()["kandidaten"].values() if k.get("status") == "getestet" and k.get("messung")] + if not offen: + return 0 + ps, n = _pruefstand(), 0 + for k in offen: + try: + basis = _baseline(k["rolle"], frist) + except Exception: + log.warning("radar: Baseline für %s nicht messbar", k["rolle"], exc_info=True) + break + if not basis: + continue + u = ps.urteil(k["rolle"], k["messung"], basis["werte"]) + + def abschluss(stand: dict, kid=k["id"], u=u, werte=k["messung"]): + return _abschluss(stand, kid, u["ergebnis"], u["zusammenfassung"], werte=werte, vergleich=u["vergleich"]) + _aendere(abschluss) + n += 1 + return n + + +def notstopp() -> None: + """Notbremse des Nachtlaufs: Kandidaten-Server und Download sofort beenden (ohne Zustand anzufassen).""" + try: + if _PS is not None: + _PS.stoppe_alle(warte_s=10) + finally: + if (prozess := _DOWNLOAD.get("prozess")) is not None: + _beende(prozess) + + +# --- Übernehmen und Verwerfen ---------------------------------------------------------------- + +def betriebs_befehl(rolle: str, pfade: dict, k: dict) -> str: + """llama-swap-Befehl für den übernommenen Kandidaten: die getesteten Flags plus die Betriebs-Flags + der Rolle wie heute (Hirn 2 Slots, Coder 1 Slot, KV q8_0, Prompt-Cache 16 GB).""" + teile = ["llama-server", "-m", pfade["gguf"], "--host", "127.0.0.1", "--port", "${PORT}", + "-c", str(int(k.get("ctx") or CTX_ROLLE[rolle])), "-ngl", "999", "-fa", "on", "--load-mode", "none"] + if pfade.get("mmproj"): + teile += ["--mmproj", pfade["mmproj"]] + teile += ["--jinja", "--parallel", str(PARALLEL[rolle]), "-cram", "16384", "-ctk", "q8_0", "-ctv", "q8_0"] + draft = k.get("draft") or {} + if draft.get("typ"): + teile += ["--spec-type", draft["typ"]] + if pfade.get("draft"): + teile += ["--spec-draft-model", pfade["draft"]] + if draft.get("n_max"): + teile += ["--spec-draft-n-max", str(draft["n_max"])] + return " ".join(teile + [str(f) for f in k.get("flags") or []]) + + +def _steward_neu_starten() -> str | None: + """Drop-in neu einlesen und den Steward neu starten (User-Dienst, ohne sudo). Fehlertext oder None.""" + if os.name != "posix": + return None + for befehl in (["systemctl", "--user", "daemon-reload"], ["systemctl", "--user", "restart", "mc2-steward"]): + try: + subprocess.run(befehl, capture_output=True, timeout=60, check=True) + except (OSError, subprocess.SubprocessError) as e: + return str(e) + return None + + +def _warmset_umstellen(alt: str | None, neu: str) -> str | None: + """Der Re-Warm-Wächter (mc2-steward) nennt sein Warm-Set per MC_WARMSET beim Namen (systemd-Drop-in). + Bliebe dort das alte Hirn stehen, lüde er es nach dem Tausch immer wieder neben das neue. Darum den + Namen hier tauschen und den Steward neu starten. Gibt nur dann einen Hinweis zurück, wenn das nicht ging.""" + try: + text = STEWARD_WARMSET.read_text(encoding="utf-8") + except OSError: + return None # kein Drop-in: der Steward leitet das Warm-Set aus der brains-Gruppe ab + treffer = re.search(r"MC_WARMSET=([^\"\n]*)", text) + namen = treffer.group(1).split() if treffer else [] + if not treffer or not alt or alt not in namen or neu in namen: + return None + neu_text = text[:treffer.start(1)] + " ".join(neu if n == alt else n for n in namen) + text[treffer.end(1):] + try: + tmp = STEWARD_WARMSET.with_name(STEWARD_WARMSET.name + ".tmp") # systemd liest nur *.conf + tmp.write_text(neu_text, encoding="utf-8") + os.replace(tmp, STEWARD_WARMSET) + except OSError as e: + return f"Das Warm-Set des Stewards ließ sich nicht umstellen ({e}); er hält noch {alt} warm." + if (fehler := _steward_neu_starten()): + return f"Warm-Set umgestellt, aber der Steward-Neustart scheiterte ({fehler}); es greift beim nächsten Neustart." + return None + + +def _zielordner(k: dict) -> Path: + name = k["repo"].split("/")[-1] + ziel = MODELS_DIR / name + if ziel.exists(): + ziel = MODELS_DIR / f"{re.sub(r'[-_]GGUF$', '', name, flags=re.IGNORECASE)}-Radar-GGUF" + return ziel + + +def _tausche_ein(k: dict) -> dict: + """Bestandenen Kandidaten in Betrieb nehmen: Ordner nach MODELS_DIR, in llama-swap registrieren, Rolle setzen.""" + rolle = k["rolle"] + quelle = Path(k.get("ordner") or "") + if not k.get("ordner") or not Path(_lokale_pfade(k, quelle)["gguf"]).is_file(): + raise RuntimeError("Die Modelldateien fehlen – der Kandidat müsste neu getestet werden.") + alt = _heutige_modelle().get(rolle) + if quelle.resolve().parent == RADAR_DIR.resolve(): + ziel = _zielordner(k) + if ziel.exists(): + raise RuntimeError(f"{ziel} gibt es schon.") + quelle.replace(ziel) # gleiche Platte → nur umbenennen + k["ordner"] = str(ziel) # scheitert es danach, findet ein zweiter Klick die Dateien hier + else: + ziel = quelle # schon verschoben (früherer, abgebrochener Versuch) + pfade = _lokale_pfade(k, ziel) + modell_id = llamaswap.register_model(pfade["gguf"], role=ALIAS[rolle], ctx=int(k.get("ctx") or CTX_ROLLE[rolle]), + mmproj_path=pfade["mmproj"], jinja=True, set_alias=False) + cfg = llamaswap.read_config() + try: # die getesteten Flags statt der Vorlage aus register_model (sonst liefe ein ungetesteter Draft mit) + cfg["models"][modell_id]["cmd"] = LiteralScalarString(betriebs_befehl(rolle, pfade, k) + "\n") + except (KeyError, TypeError) as e: + raise RuntimeError(f"{modell_id} fehlt nach dem Eintragen in der llama-swap-Config.") from e + llamaswap.write_config(cfg) + hinweis = None + if rolle == "hirn": + from services.agent import set_agent_brain + antwort = set_agent_brain(modell_id) # hermes-Alias, brains-Gruppe, ttl 0, Hermes-Config + if not antwort.get("ok"): + raise RuntimeError(antwort.get("reason") or "Hirn-Wechsel fehlgeschlagen") + # Das Hirn ist heute hermes UND fast (Chat-Spur, warmup.sh, Oberfläche). Bliebe fast am alten + # Modell, lüde warmup.sh es nachts neben das neue Hirn. + if alt and "fast" in {str(a).lower() for a in alt.get("aliases") or []}: + llamaswap.add_role(modell_id, "fast") + hinweis = " ".join(h for h in (antwort.get("warning"), _warmset_umstellen((alt or {}).get("name"), modell_id)) + if h) or None + else: + if not llamaswap.set_role(modell_id, "coder"): + raise RuntimeError(f"Die Rolle coder ließ sich nicht auf {modell_id} setzen.") + # heavy ist heute derselbe Coder (OpenCode plant damit). Bliebe es am alten Modell, lägen zwei Coder + # bereit und der alte ließe sich nie löschen. + if alt and "heavy" in {str(a).lower() for a in alt.get("aliases") or []}: + llamaswap.add_role(modell_id, "heavy") + if alt and alt.get("ttl") is not None: + llamaswap.set_ttl(modell_id, int(alt["ttl"])) + return {"modell_id": modell_id, "pfad": str(ziel), "alt": (alt or {}).get("name"), "hinweis": hinweis} + + +def _oeffentlich(k: dict) -> dict: + return {f: k.get(f) for f in KANDIDAT_FELDER} + + +def uebernehmen(kid: str) -> dict: + """Knopf „Übernehmen“: nur bei Status „bestanden“ und nicht während eines Nachtlaufs.""" + with _gesperrt(): + stand = _lade() + k = stand["kandidaten"].get(kid) + if not k: + return {"ok": False, "status": 404, "detail": "Diesen Kandidaten gibt es nicht."} + if k.get("status") != "bestanden": + return {"ok": False, "status": 409, + "detail": f"Übernehmen geht nur bei bestandenen Kandidaten (Status: {k.get('status')})."} + if _aktiver_lauf(stand): + return {"ok": False, "status": 409, "detail": "Das Radar testet gerade – bitte nach dem Nachtlauf übernehmen."} + try: + tausch = _tausche_ein(k) + except Exception as e: + _speichere(stand) # k["ordner"] kann sich schon geändert haben + log.warning("radar: Übernehmen von %s scheiterte", kid, exc_info=True) + return {"ok": False, "status": 409, "detail": f"Übernehmen ging nicht: {e}"} + rolle_text = "das Hirn" if k["rolle"] == "hirn" else "der Coder" + k.update(status="uebernommen", modell_id=tausch["modell_id"], pfad=tausch["pfad"], ordner=None, + geaendert=time.time(), + begruendung=f"Übernommen am {_datum(time.time())}: ist jetzt {rolle_text}" + + (f" (vorher {tausch['alt']})." if tausch.get("alt") else ".") + + (f" Noch zu tun: {tausch['hinweis']}" if tausch.get("hinweis") else "")) + _ordne(stand) + _speichere(stand) + return {"ok": True, "kandidat": _oeffentlich(k), "modell_id": tausch["modell_id"], "text": tausch["hinweis"]} + + +def verwerfen(kid: str) -> dict: + """Knopf „Verwerfen“: Dateien weg, nie wieder testen.""" + def aenderung(stand: dict) -> dict: + k = stand["kandidaten"].get(kid) + if not k: + return {"ok": False, "status": 404, "detail": "Diesen Kandidaten gibt es nicht."} + if k.get("status") == "uebernommen": + return {"ok": False, "status": 409, "detail": "Schon übernommen – zurück geht es über die Modell-Rollen."} + if k.get("status") == "durchgefallen": + return {"ok": False, "status": 409, "detail": "Ist schon durchgefallen, die Dateien sind gelöscht."} + if (lauf := _aktiver_lauf(stand)) and lauf.get("kandidat") == kid: + return {"ok": False, "status": 409, "detail": "Wird gerade getestet – nach dem Nachtlauf noch einmal."} + _loesche_dateien(k) + k.pop("messung", None) + k.update(status="verworfen", verworfen_von="nutzer", geaendert=time.time(), + begruendung=f"Von dir verworfen am {_datum(time.time())}.") + _ordne(stand) + return {"ok": True, "kandidat": _oeffentlich(k)} + return _aendere(aenderung) + + +# --- Übersicht (GET /api/radar) -------------------------------------------------------------- + +def naechster_test(stand: dict, zeit: datetime | None = None) -> str | None: + """Wann der nächste Test frühestens beginnt (ISO-Zeit), None ohne wartenden Kandidaten. + Läuft gerade einer, ist es dessen Beginn.""" + zeit = (zeit or jetzt()).astimezone(LOCAL_TZ) + if (lauf := _aktiver_lauf(stand)) and lauf.get("kandidat") in stand["kandidaten"]: + return _iso(lauf.get("seit")) + schlange = warteschlange(stand) + if not schlange: + return None + start = naechster_start(zeit) + if not schlange[0].get("erster_start") and (frei := wochen_frei_ab(stand, start.date())) and frei > start.date(): + start = _lokal(frei, _hhmm(FENSTER_START)) + return start.isoformat(timespec="seconds") + + +def uebersicht(zeit: datetime | None = None) -> dict: + """GET /api/radar: nächster und letzter Test (ISO-Zeit), Kandidaten, Tests (neueste zuerst).""" + stand = _lade() + kandidaten = sorted(stand["kandidaten"].values(), + key=lambda k: (_REIHENFOLGE.get(k.get("status"), 9), 0 if k.get("quelle") == "watchlist" else 1, + k.get("rang", 999))) + oeffentlich = [_oeffentlich(k) for k in kandidaten] + if (lauf := _aktiver_lauf(stand)): # den laufenden Test in seiner Begründung zeigen (nicht gespeichert) + for k in oeffentlich: + if k["id"] == lauf.get("kandidat"): + seit = datetime.fromtimestamp(float(lauf.get("seit") or time.time()), LOCAL_TZ) + k["begruendung"] = (f"Läuft gerade seit {seit:%H:%M}: " + f"{_SCHRITTE.get(lauf.get('schritt'), lauf.get('schritt'))}.") + tests = [{f: t.get(f) for f in TEST_FELDER} for t in reversed(stand["tests"])] + return {"naechster_test": naechster_test(stand, zeit), "letzter_test": tests[0]["datum"] if tests else None, + "kandidaten": oeffentlich, "tests": tests} diff --git a/backend/services/waechter.py b/backend/services/waechter.py index 284d411..8262f5c 100644 --- a/backend/services/waechter.py +++ b/backend/services/waechter.py @@ -83,6 +83,7 @@ DIENSTE: dict[str, tuple[bool, bool, str]] = { TIMER_DIENSTE: dict[str, tuple[str, bool]] = { "projekte-sync": ("Projekte-Abgleich", False), "mc2-backup": ("Sicherung", True), + "mc2-radar": ("Modell-Radar", False), } HERMES_JOBS_PATH = HERMES_HOME / "cron" / "jobs.json" diff --git a/backend/services/zeitplan.py b/backend/services/zeitplan.py index 2e60785..85af680 100644 --- a/backend/services/zeitplan.py +++ b/backend/services/zeitplan.py @@ -14,7 +14,7 @@ from zoneinfo import ZoneInfo from services import modell_nutzung, waechter -TIMER = {"mc2-backup.timer": "Sicherung"} +TIMER = {"mc2-backup.timer": "Sicherung", "mc2-radar.timer": "Modell-Radar"} LOCAL_TZ = ZoneInfo(os.environ.get("MC_LOCAL_TZ", "Europe/Berlin")) diff --git a/backend/tests/test_radar.py b/backend/tests/test_radar.py new file mode 100644 index 0000000..b11568d --- /dev/null +++ b/backend/tests/test_radar.py @@ -0,0 +1,617 @@ +"""Tests für das Modell-Radar: reine Logik (Zeitfenster, Wochengrenze, Filter, Speicher-Rechnung, +Zustandsübergänge) und die Urteile und Programmieraufgaben des Prüfstands — ohne Netz und ohne Box. +Zahlen wie auf der Box am 23.09.2026 (Ornith 21,7 GB + mmproj, Flash-Next UD-IQ3_XXS 82 GB).""" + +import json +import os +import struct +import time +import zlib +from datetime import date, datetime + +import pytest +from services import radar + +BERLIN = radar.LOCAL_TZ + + +def _zeit(text: str) -> datetime: + return datetime.fromisoformat(text).replace(tzinfo=BERLIN) + + +def _kandidat(kid: str, rolle: str = "hirn", status: str = "neu", quelle: str = "watchlist", rang: int = 0, + **extra) -> dict: + return {"id": kid, "name": kid, "rolle": rolle, "repo": f"org/{kid}-GGUF", "quant": "Q4_K_M", "quelle": quelle, + "rang": rang, "datei": f"{kid}-Q4_K_M.gguf", "dateien": [[f"{kid}-Q4_K_M.gguf", 100]], + "mmproj": ["mmproj-F16.gguf", 10], "draft": None, "flags": [], "groesse_gb": 21.7, "passt": True, + "eng": False, "ctx": 131072, "status": status, "begruendung": "", **extra} + + +@pytest.fixture +def zustand(monkeypatch, tmp_path): + """Radar-Zustand und Radar-Ordner in einem Temp-Ordner statt unter /srv/models.""" + monkeypatch.setattr(radar, "STORE_PATH", tmp_path / "mc2-radar.json") + monkeypatch.setattr(radar, "RADAR_DIR", tmp_path / "radar") + (tmp_path / "radar").mkdir() + return tmp_path + + +# --- Zeitfenster und Wochengrenze ------------------------------------------------------------ + +def test_zeitfenster_nur_von_0030_bis_0230(): + assert not radar.im_fenster(_zeit("2026-09-29T00:29:59")) + assert radar.im_fenster(_zeit("2026-09-29T00:30:00")) + assert radar.im_fenster(_zeit("2026-09-29T02:29:59")) + assert not radar.im_fenster(_zeit("2026-09-29T02:30:00")) + assert not radar.im_fenster(_zeit("2026-09-29T14:00:00")) + assert radar.fenster_ende(_zeit("2026-09-29T00:45:00")) == _zeit("2026-09-29T02:30:00") + + +def test_fensterende_am_umstellungstag_nie_nach_0300(): + # 28.03.2027: 02:00 springt auf 03:00, 02:30 gibt es nicht. Lieber früher enden als in den NerdQuiz-Lauf. + ende = radar.fenster_ende(_zeit("2027-03-28T00:45:00")) + assert ende.timestamp() <= datetime(2027, 3, 28, 3, 0, tzinfo=BERLIN).timestamp() + + +def test_naechster_start_ist_die_naechste_nacht(): + assert radar.naechster_start(_zeit("2026-09-29T00:10:00")) == _zeit("2026-09-29T00:30:00") + assert radar.naechster_start(_zeit("2026-09-29T01:00:00")) == _zeit("2026-09-30T00:30:00") + assert radar.naechster_start(_zeit("2026-09-29T14:00:00")) == _zeit("2026-09-30T00:30:00") + + +def test_wochengrenze_ein_neuer_kandidat_pro_woche(): + stand = radar._leer() + stand["kandidaten"] = {"a": _kandidat("a", status="bestanden", + erster_start=_zeit("2026-09-29T00:31:00").timestamp()), + "b": _kandidat("b")} + assert radar.wochen_frei_ab(stand, date(2026, 10, 3)) == date(2026, 10, 6) + assert radar.wochen_frei_ab(stand, date(2026, 10, 6)) is None + + +def test_plan_testet_nur_im_fenster_mit_freier_woche_und_setzt_angefangene_fort(): + stand = radar._leer() + stand["kandidaten"] = {"a": _kandidat("a", status="bestanden", + erster_start=_zeit("2026-09-29T00:31:00").timestamp()), + "b": _kandidat("b", rang=1)} + radar._ordne(stand) + assert stand["kandidaten"]["b"]["status"] == "wartet" + + plan = radar.plane_test(stand, _zeit("2026-10-03T00:31:00")) + assert plan["kandidat"] is None and "06.10." in plan["grund"] + assert radar.plane_test(stand, _zeit("2026-10-06T00:31:00"))["kandidat"] == "b" + assert "außerhalb" in radar.plane_test(stand, _zeit("2026-10-06T14:00:00"))["grund"] + assert "Minuten" in radar.plane_test(stand, _zeit("2026-10-06T02:15:00"))["grund"] + + # angefangen (z. B. Download unterbrochen): darf in der nächsten Nacht weiter, die Woche gilt ab dem 1. Start + stand["kandidaten"]["b"]["erster_start"] = _zeit("2026-10-06T00:31:00").timestamp() + assert radar.plane_test(stand, _zeit("2026-10-07T00:31:00"))["kandidat"] == "b" + + +def test_laufender_test_blockiert_zweiten_lauf_und_zeigt_sich(zustand): + stand = radar._leer() + stand["kandidaten"]["b"] = _kandidat("b", status="wartet", erster_start=time.time()) + stand["lauf"] = {"pid": os.getpid(), "kandidat": "b", "schritt": "test", "seit": time.time(), + "frist": time.time() + 3600} + assert radar.plane_test(stand, _zeit("2026-10-06T00:40:00"))["grund"] == "es läuft schon ein Test" + radar._speichere(stand) + assert radar.uebersicht()["kandidaten"][0]["begruendung"].startswith("Läuft gerade seit") + stand["lauf"]["pid"] = 999_999_999 # Prozess tot → Lauf gilt als beendet + assert radar._aktiver_lauf(stand) is None + + +# --- Namen, Filter, Dateien, Speicher ----------------------------------------------------------- + +def test_namen_und_staemme(): + assert radar.anzeigename("bartowski/Qwen_Qwen3.6-35B-A3B-GGUF") == "Qwen3.6-35B-A3B" + assert radar.anzeigename("unsloth/Qwen3.8-Flash-Next-GGUF") == "Qwen3.8-Flash-Next" + assert radar.stamm("Qwen3.8-Flash-Next-UD-IQ3_XXS-00001-of-00003.gguf") == "qwen3.8-flash-next" + assert radar.stamm("Qwen3.6-35B-A3B") == radar.stamm("unsloth/Qwen3.6-35B-A3B-GGUF") + assert radar.generation("Qwen3.8-27B") == ("qwen", 3.8) + assert radar.kandidat_id("hirn", "ornith-ai/Ornith-1.5-35B-A3B-GGUF", "Q4_K_M") == \ + "hirn-ornith-ai-ornith-1-5-35b-a3b-gguf-q4-k-m" + + +def test_entdeckung_filtert_alte_kleine_bekannte_und_dichte_hirne(): + heute = {"hirn": "Qwen3.6-35B-A3B", "coder": "Qwen3.8-27B"} + bekannt = {"qwen3.6-35b-a3b", "qwen3.8-27b"} + + def fund(repo, params, aktiv=None, kuratiert=False): + return {"repo": repo, "params_b": params, "caps": {"active_b": aktiv}, "curated": kuratiert} + + def grund(m, rolle): + return radar.entdeckung_ungeeignet(m, rolle, bekannt, heute) + + assert "Katalog" in grund(fund("unsloth/Qwen3-Coder-30B-A3B-Instruct-GGUF", 30, 3, kuratiert=True), "coder") + assert "auf der Box" in grund(fund("bartowski/Qwen_Qwen3.6-35B-A3B-GGUF", 35, 3), "hirn") + assert "zu klein" in grund(fund("lmstudio-community/Qwen2.5-Coder-14B-Instruct-GGUF", 14), "coder") + assert "dichte" in grund(fund("bartowski/Hermes-3-Llama-3.1-70B-GGUF", 70), "hirn") + assert "ältere Generation" in grund(fund("bartowski/Qwen_Qwen3.5-35B-A3B-GGUF", 35, 3), "hirn") + assert grund(fund("unsloth/Qwen-AgentWorld-35B-A3B-GGUF", 35, 3), "hirn") is None + + +BAUM_FLASH = [ + {"type": "directory", "path": "UD-IQ3_XXS"}, + {"path": "UD-IQ3_XXS/Qwen3.8-Flash-Next-UD-IQ3_XXS-00001-of-00003.gguf", "size": 10_000_000}, + {"path": "UD-IQ3_XXS/Qwen3.8-Flash-Next-UD-IQ3_XXS-00002-of-00003.gguf", "size": 49_570_000_000}, + {"path": "UD-IQ3_XXS/Qwen3.8-Flash-Next-UD-IQ3_XXS-00003-of-00003.gguf", "lfs": {"size": 32_380_000_000}}, + {"path": "UD-IQ4_XS/Qwen3.8-Flash-Next-UD-IQ4_XS-00001-of-00003.gguf", "size": 10_000_000}, + {"path": "MTP/mtp-Qwen3.8-Flash-Next-Q8_0.gguf", "size": 4_140_000_000}, + {"path": "mmproj-BF16.gguf", "size": 910_000_000}, + {"path": "mmproj-F16.gguf", "size": 900_000_000}, +] +KOPF_FLASH = {"general.architecture": "qwen4exp", "qwen4exp.block_count": 48, "qwen4exp.attention.head_count": 24, + "qwen4exp.attention.head_count_kv": 2, "qwen4exp.attention.key_length": 256, + "qwen4exp.attention.value_length": 256, "qwen4exp.full_attention_interval": 4} + + +def test_dateiauswahl_nimmt_alle_teile_des_quants_und_das_f16_mmproj(): + wahl = radar.waehle_dateien(BAUM_FLASH, "UD-IQ3_XXS") + assert [p.rsplit("-", 3)[-3] for p, _ in wahl["dateien"]] == ["00001", "00002", "00003"] + assert all(p.startswith("UD-IQ3_XXS/") for p, _ in wahl["dateien"]) + assert wahl["mmproj"] == ["mmproj-F16.gguf", 900_000_000] + assert radar.waehle_dateien(BAUM_FLASH, "Q4_K_M") is None + assert radar.waehle_dateien(BAUM_FLASH, "Q8_0") is None # der MTP-Kopf ist kein Modell + ornith = [{"path": "Ornith-1.5-35B-Q4_K_M.gguf", "size": 21_710_000_000}, + {"path": "Ornith-1.5-35B-Q8_0.gguf", "size": 37_800_000_000}, + {"path": "mmproj-Ornith-1.5-35B-BF16.gguf", "size": 900_000_000}] + wahl = radar.waehle_dateien(ornith, "Q4_K_M") + assert wahl["dateien"] == [["Ornith-1.5-35B-Q4_K_M.gguf", 21_710_000_000]] + assert wahl["mmproj"][0] == "mmproj-Ornith-1.5-35B-BF16.gguf" + + +def _gguf_kopf_bytes(werte: dict) -> bytes: + """Minimaler GGUF-Kopf wie von llama.cpp: Architektur-Schlüssel, danach der Tokenizer (abgeschnitten).""" + def s(text: str) -> bytes: + return struct.pack(" tuple[list, dict]: + """Bestandenen Kandidaten „o“ anlegen und llama-swap/Hirn-Wechsel durch Protokoll-Attrappen ersetzen.""" + modelle = zustand / "models" + modelle.mkdir() + monkeypatch.setattr(radar, "MODELS_DIR", modelle) + ordner = radar.RADAR_DIR / "o" + ordner.mkdir() + (ordner / "o-Q4_K_M.gguf").write_bytes(b"x") + (ordner / "mmproj-F16.gguf").write_bytes(b"x") + stand = radar._leer() + stand["kandidaten"]["o"] = _kandidat("o", rolle=rolle, status="bestanden", ordner=str(ordner)) + radar._speichere(stand) + aufrufe, cfg = [], {"models": {}} + + def eintragen(pfad, **kw): + aufrufe.append(("eintragen", pfad, kw["role"], kw["set_alias"])) + cfg["models"]["o"] = {"cmd": "vorlage"} + return "o" + + from services import agent + monkeypatch.setattr(radar, "_heutige_modelle", lambda: {rolle: alt}) + monkeypatch.setattr(radar.llamaswap, "register_model", eintragen) + monkeypatch.setattr(radar.llamaswap, "read_config", lambda: cfg) + monkeypatch.setattr(radar.llamaswap, "write_config", lambda c: aufrufe.append(("schreiben",))) + monkeypatch.setattr(radar.llamaswap, "set_role", lambda mid, r: aufrufe.append(("rolle", mid, r)) or True) + monkeypatch.setattr(radar.llamaswap, "add_role", lambda mid, r: aufrufe.append(("dazu", mid, r)) or True) + monkeypatch.setattr(radar, "_steward_neu_starten", lambda: aufrufe.append(("steward",)) or None) + monkeypatch.setattr(radar.llamaswap, "set_ttl", lambda mid, ttl: aufrufe.append(("ttl", mid, ttl)) or True) + monkeypatch.setattr(agent, "set_agent_brain", lambda mid: aufrufe.append(("hirn", mid)) or {"ok": True}) + monkeypatch.setattr(radar, "STEWARD_WARMSET", zustand / "warmset.conf") + return aufrufe, cfg + + +def test_uebernehmen_hirn_nutzt_den_hirn_wechsel_und_nimmt_fast_mit(zustand, monkeypatch): + aufrufe, cfg = _uebernahme_vorbereiten(zustand, monkeypatch, "hirn", + {"name": "Qwen3.6-35B-A3B", "aliases": ["hermes", "fast"], "ttl": 0}) + (zustand / "warmset.conf").write_text('[Service]\nEnvironment="MC_WARMSET=Qwen3-Embedding-0.6B Qwen3.6-35B-A3B"\n', + encoding="utf-8") + antwort = radar.uebernehmen("o") + assert antwort["ok"] and antwort["modell_id"] == "o" + assert [a[0] for a in aufrufe] == ["eintragen", "schreiben", "hirn", "dazu", "steward"] + assert aufrufe[0][2:] == ("hermes", False) and aufrufe[3] == ("dazu", "o", "fast") + befehl = str(cfg["models"]["o"]["cmd"]) + assert "--parallel 2" in befehl and "-ctk q8_0" in befehl and "--mmproj" in befehl + assert (zustand / "models" / "o-GGUF" / "o-Q4_K_M.gguf").exists() and not (radar.RADAR_DIR / "o").exists() + k = radar._lade()["kandidaten"]["o"] + assert k["status"] == "uebernommen" and "vorher Qwen3.6-35B-A3B" in k["begruendung"] + # Der Steward hält danach das neue Hirn warm, nicht mehr das alte — ohne Handgriff. + assert 'MC_WARMSET=Qwen3-Embedding-0.6B o"' in (zustand / "warmset.conf").read_text(encoding="utf-8") + assert antwort["text"] is None and "Noch zu tun" not in k["begruendung"] + + +def test_uebernehmen_coder_nimmt_heavy_mit(zustand, monkeypatch): + aufrufe, cfg = _uebernahme_vorbereiten(zustand, monkeypatch, "coder", + {"name": "Qwen3.8-27B", "aliases": ["coder", "heavy"], "ttl": 5400}) + antwort = radar.uebernehmen("o") + assert antwort["ok"] and antwort["text"] is None + assert aufrufe[2:] == [("rolle", "o", "coder"), ("dazu", "o", "heavy"), ("ttl", "o", 5400)] + assert "--parallel 1" in str(cfg["models"]["o"]["cmd"]) + + +def test_betriebsbefehl_uebernimmt_die_getesteten_flags(): + k = _kandidat("f", rolle="coder", ctx=65536, draft={"typ": "draft-mtp", "n_max": 2, "datei": None}, flags=["-ub", "512"]) + befehl = radar.betriebs_befehl("coder", {"gguf": "/srv/models/F-GGUF/f.gguf", "mmproj": "/srv/models/F-GGUF/mm.gguf", + "draft": None}, k) + assert "-c 65536" in befehl and "--parallel 1" in befehl and "-ctk q8_0 -ctv q8_0" in befehl + assert "--mmproj /srv/models/F-GGUF/mm.gguf" in befehl and "--load-mode none" in befehl + assert befehl.endswith("--spec-type draft-mtp --spec-draft-n-max 2 -ub 512") + assert "--parallel 2" in radar.betriebs_befehl("hirn", {"gguf": "x.gguf", "mmproj": None, "draft": None}, + _kandidat("h")) + + +# --- Prüfstand: Urteil, Programmieraufgaben, Bild ---------------------------------------------------- + +@pytest.fixture(scope="module") +def ps(): + return radar._pruefstand() + + +BILD_GUT = {"direkt": 1.0, "gefunden": ["Wort ZEBRA", "Zahl 4711"], "agentisch": True} + + +def _werte(rolle: str, decode: float = 100.0, prefill: float = 13.0, werkzeuge: int = 6, code: int = 8, + bild: dict | None = None, deutsch: bool = True) -> dict: + werte = {"rolle": rolle, "tiefe": {"tg_tps": decode, "pp_s": prefill}, "werkzeuge": {"ok": werkzeuge, "von": 6}, + "bild": bild} + if rolle == "hirn": + werte.update(deutsch={"ok": deutsch}, json={"ok": True}) + else: + werte["code"] = {"ok": code, "von": 10} + return werte + + +def test_urteil_hirn_mit_bildern_besteht_ohne_verschlechterung(ps): + u = ps.urteil("hirn", _werte("hirn", decode=95.0, bild=BILD_GUT), _werte("hirn", decode=100.8)) + assert u["ergebnis"] == "bestanden" + assert u["zusammenfassung"] == "Bestanden: versteht Bilder (heute nicht)." + assert u["vergleich"]["Decode bei 13k"]["urteil"] == "gleich" # −6 % liegt in der Toleranz + assert list(u["vergleich"]) == ["Decode bei 13k", "Prefill bei 13k", "Werkzeug-Aufrufe", "Deutsch", "JSON", + "Bilder"] + + +def test_urteil_hirn_faellt_bei_schwaeche_oder_ohne_vorteil_durch(ps): + basis = _werte("hirn", decode=100.8) + u = ps.urteil("hirn", _werte("hirn", werkzeuge=5, bild=BILD_GUT), basis) + assert u["ergebnis"] == "durchgefallen" and "Werkzeuge 5/6 (heute 6/6)" in u["zusammenfassung"] + u = ps.urteil("hirn", _werte("hirn", decode=70.0, bild=BILD_GUT), basis) + assert u["ergebnis"] == "durchgefallen" and "Decode bei 13k 70 statt 100,8 t/s" in u["zusammenfassung"] + u = ps.urteil("hirn", _werte("hirn", bild=BILD_GUT), _werte("hirn", bild=BILD_GUT)) + assert u["zusammenfassung"] == "Durchgefallen: kein Vorteil gegenüber dem heutigen Modell." + u = ps.urteil("hirn", _werte("hirn", decode=130.0), basis) # schneller, aber blind + assert u["ergebnis"] == "durchgefallen" and "versteht keine Bilder" in u["zusammenfassung"] + + +def test_urteil_coder_zaehlt_programmieraufgaben_und_bilder(ps): + basis = _werte("coder", decode=30.4, prefill=41.2, code=8, bild=BILD_GUT) + u = ps.urteil("coder", _werte("coder", decode=45.0, prefill=12.0, code=9, bild=BILD_GUT), basis) + assert u["ergebnis"] == "bestanden" and "Programmieraufgaben 9/10 statt 8/10" in u["zusammenfassung"] + u = ps.urteil("coder", _werte("coder", decode=45.0, prefill=12.0, code=7, bild=BILD_GUT), basis) + assert u["ergebnis"] == "durchgefallen" and "Programmieraufgaben 7/10 (heute 8/10)" in u["zusammenfassung"] + u = ps.urteil("coder", _werte("coder", code=9), basis) # der heutige Coder kann Bilder + assert u["ergebnis"] == "durchgefallen" and "versteht keine Bilder" in u["zusammenfassung"] + + +REFERENZ = { + "palindrom": "def ist_palindrom(text):\n z = [c.lower() for c in text if c.isalnum()]\n return z == z[::-1]\n", + "roemisch": ( + "def roemisch(zahl):\n" + " if not isinstance(zahl, int) or not 1 <= zahl <= 3999:\n" + " raise ValueError(zahl)\n" + " out = ''\n" + " for wert, zeichen in ((1000, 'M'), (900, 'CM'), (500, 'D'), (400, 'CD'), (100, 'C'), (90, 'XC'),\n" + " (50, 'L'), (40, 'XL'), (10, 'X'), (9, 'IX'), (5, 'V'), (4, 'IV'), (1, 'I')):\n" + " while zahl >= wert:\n" + " out += zeichen\n" + " zahl -= wert\n" + " return out\n"), + "intervalle": ( + "def zusammenfassen(intervalle):\n" + " out = []\n" + " for a, b in sorted(intervalle):\n" + " if out and a <= out[-1][1]:\n" + " out[-1][1] = max(out[-1][1], b)\n" + " else:\n" + " out.append([a, b])\n" + " return out\n"), + "flach": ( + "def flach(liste):\n" + " out = []\n" + " for x in liste:\n" + " out.extend(flach(x) if isinstance(x, list) else [x])\n" + " return out\n"), + "iban": ( + "def iban_gueltig(iban):\n" + " s = iban.replace(' ', '').upper()\n" + " if not 15 <= len(s) <= 34 or not s.isalnum() or not s.isascii():\n" + " return False\n" + " return int(''.join(str(int(c, 36)) for c in s[4:] + s[:4])) % 97 == 1\n"), + "lru": ( + "from collections import OrderedDict\n" + "class LRUCache:\n" + " def __init__(self, kapazitaet):\n" + " self.k, self.d = kapazitaet, OrderedDict()\n" + " def get(self, schluessel):\n" + " if schluessel not in self.d:\n" + " return None\n" + " self.d.move_to_end(schluessel)\n" + " return self.d[schluessel]\n" + " def put(self, schluessel, wert):\n" + " self.d[schluessel] = wert\n" + " self.d.move_to_end(schluessel)\n" + " if len(self.d) > self.k:\n" + " self.d.popitem(last=False)\n"), + "klammern": ( + "def klammern_ok(text):\n" + " paare, stapel = {')': '(', ']': '[', '}': '{'}, []\n" + " for c in text:\n" + " if c in '([{':\n" + " stapel.append(c)\n" + " elif c in paare and (not stapel or stapel.pop() != paare[c]):\n" + " return False\n" + " return not stapel\n"), + "wege": ( + "import heapq\n" + "def kuerzeste_wege(graph, start):\n" + " dist, heap = {start: 0}, [(0, start)]\n" + " while heap:\n" + " d, u = heapq.heappop(heap)\n" + " if d > dist[u]:\n" + " continue\n" + " for v, w in graph.get(u, {}).items():\n" + " if v not in dist or d + w < dist[v]:\n" + " dist[v] = d + w\n" + " heapq.heappush(heap, (d + w, v))\n" + " return dist\n"), + "median": ( + "def median(zahlen):\n" + " if not zahlen:\n" + " raise ValueError('leer')\n" + " s, n = sorted(zahlen), len(zahlen)\n" + " return s[n // 2] if n % 2 else (s[n // 2 - 1] + s[n // 2]) / 2\n"), + "csv": ( + "def spaltensumme(csv_text, spalte):\n" + " zeilen = [z for z in csv_text.splitlines() if z.strip()]\n" + " kopf = zeilen[0].split(';')\n" + " if spalte not in kopf:\n" + " raise KeyError(spalte)\n" + " i, summe = kopf.index(spalte), 0.0\n" + " for z in zeilen[1:]:\n" + " zellen = z.split(';')\n" + " wert = zellen[i].strip() if i < len(zellen) else ''\n" + " if wert:\n" + " summe += float(wert.replace('.', '').replace(',', '.'))\n" + " return summe\n"), +} + + +def test_referenzloesungen_bestehen_alle_programmieraufgaben(ps): + assert {a["id"] for a in ps.AUFGABEN_CODE} == set(REFERENZ) + for aufgabe in ps.AUFGABEN_CODE: + ok, grund = ps.fuehre_aufgabe_aus(REFERENZ[aufgabe["id"]], aufgabe["tests"]) + assert ok, f"{aufgabe['id']}: {grund}" + + +def test_falsche_verbotene_und_endlose_loesungen_fallen_durch(ps): + tests = next(a["tests"] for a in ps.AUFGABEN_CODE if a["id"] == "median") + ok, _ = ps.fuehre_aufgabe_aus("def median(z):\n z.sort()\n return z[len(z) // 2]\n", tests) + assert not ok + ok, grund = ps.fuehre_aufgabe_aus("import os\ndef median(z):\n return os.getpid()\n", tests) + assert not ok and grund.startswith("unerlaubter Aufruf") + ok, grund = ps.fuehre_aufgabe_aus("def median(z):\n while True:\n pass\n", tests, zeitlimit=2) + assert not ok and "Zeitlimit" in grund + + +def test_code_aus_antwort_nimmt_den_loesungsblock(ps): + antwort = "kurz nachdenkenHier:\n```python\ndef f():\n return 1\n```\nAufruf:\n```python\nf()\n```" + assert ps.code_aus_antwort(antwort) == "def f():\n return 1\n" + assert ps.code_aus_antwort("def g(): return 2") == "def g(): return 2" + + +def test_bild_ist_ein_gueltiges_png_mit_rotem_kreis(ps): + png = ps.bild_png() + assert png.startswith(b"\x89PNG\r\n\x1a\n") + breite, hoehe = struct.unpack(">II", png[16:24]) + assert (breite, hoehe) == (448, 300) + laenge = struct.unpack(">I", png[33:37])[0] + roh = zlib.decompress(png[41:41 + laenge]) + zeile = 1 + breite * 3 + assert roh[95 * zeile + 1 + 80 * 3:95 * zeile + 1 + 81 * 3] == b"\xdc\x14\x14" # Mitte des Kreises + beschreibung = "Ein roter Kreis, ein blaues Quadrat, ein grünes Dreieck und darunter der Text ZEBRA 4711." + assert ps.bild_merkmale(beschreibung) == list(ps.BILD_MERKMALE) + assert ps.bild_data_url().startswith("data:image/png;base64,") + + +def test_werkzeug_treffer_liest_json_argumente(ps): + aufruf = [{"function": {"name": "send_telegram", "arguments": json.dumps({"text": "Prüfstand läuft."})}}] + assert ps.trifft(aufruf, [("send_telegram", r"pr(ü|ue)fstand")]) + assert not ps.trifft(aufruf, [("terminal", r".*")]) + assert len(ps.WERKZEUGE_HIRN) >= 90 # Lucy hat ~100 Werkzeuge + assert ps.tiefen_prompt("ab12").startswith("Messlauf ab12.") + + +def test_add_role_behaelt_die_uebrigen_aliase(monkeypatch): + """add_role ohne Attrappe: coder bleibt, heavy wandert vom alten Coder herüber.""" + from services import llamaswap + cfg = {"models": {"alt": {"cmd": "x", "aliases": ["coder", "heavy"]}, "neu": {"cmd": "y", "aliases": ["coder"]}}} + monkeypatch.setattr(llamaswap, "read_config", lambda: cfg) + monkeypatch.setattr(llamaswap, "write_config", lambda c: None) + assert llamaswap.add_role("neu", "heavy") is True + assert cfg["models"]["neu"]["aliases"] == ["coder", "heavy"] + assert cfg["models"]["alt"]["aliases"] == ["coder"] + assert llamaswap.add_role("gibt-es-nicht", "heavy") is False diff --git a/deploy/bench/pruefstand-hirn.py b/deploy/bench/pruefstand-hirn.py index 71f8812..78e335d 100644 --- a/deploy/bench/pruefstand-hirn.py +++ b/deploy/bench/pruefstand-hirn.py @@ -1,22 +1,23 @@ #!/usr/bin/env python3 -"""Prüfstand für Hirn-Kandidaten (17.09.2026). Kandidat läuft standalone auf :5899 — der Live-Stack bleibt unberührt —, -Baselines laufen über llama-swap :8080. Je Betriebsart: Kurz- und 13k-Tiefenmessung (Prefill/Decode/Draft-Akzeptanz), -Tool-Calling direkt (3 Aufgaben, Denken an), Deutsch- und JSON-Probe (Denken aus) und der Tool-Smoke durch den ECHTEN -Hermes-Agenten (`hermes chat --provider pruefstand -m kandidat`; Provider `pruefstand` -> http://127.0.0.1:5899/v1 muss in -`providers:` der Hermes-Config stehen). Aufruf auf der Box: python3 pruefstand-hirn.py [baseline] [nemo] [u38] [u36] -(Kandidaten-Pfade unten anpassen). Ergebnis: ~/pruefstand-.json + Log auf stdout. Lehren: Denk-Modelle brauchen -für Tool-Aufrufe >=1500 Tokens Budget, /no_think wirkt bei Qwen 3.6 nicht (chat_template_kwargs.enable_thinking=false); -der erste Lauf nach dem Laden ist ~40 % langsamer (Warmlauf verwerfen).""" +"""Prüfstand für Hirn-Kandidaten (17.09.2026), seit 09/2026 eine dünne Hülle um pruefstand.py. + +Die Messungen selbst (Tempo, 13k-Tiefe, Werkzeuge, Deutsch/JSON, Bild-Probe, Server auf :5899) liegen +im Modul — dasselbe nutzt das Modell-Radar nachts. Dieses Skript bleibt der Handbetrieb: Kandidaten +mit festen Pfaden gegen die Live-Modelle (llama-swap :8080) messen, optional mit dem Tool-Smoke durch +den ECHTEN Hermes-Agenten (`hermes chat --provider pruefstand -m kandidat`; der Provider `pruefstand` +-> http://127.0.0.1:5899/v1 muss in `providers:` der Hermes-Config stehen). + +Aufruf auf der Box: python3 pruefstand-hirn.py [baseline] [nemo] [u38] [u36] (Pfade unten anpassen). +Ergebnis: ~/pruefstand-.json + Log auf stdout. +""" + import json import os -import re -import subprocess import sys import time -import urllib.request -BIN = "/opt/llamacpp-vulkan/llama-server"; PORT = 5899 -BASE = ["-c", "65536", "-ngl", "999", "-fa", "on", "--load-mode", "none", "--jinja", "--parallel", "1", "-ctk", "q8_0", "-ctv", "q8_0"] +import pruefstand as ps # liegt daneben; beim Skriptaufruf steht dieser Ordner auf sys.path + M = "/srv/models" DFLASH_36 = f"{M}/Qwen3.6-35B-A3B-DFlash-GGUF/giocom-Qwen3.6-35B-A3B-DFlash-Q8_0.gguf" DFLASH2_38 = f"{M}/Qwen3.8-27B-DFlash2-GGUF/Qwen3.8-27B-DFlash2-Q4_K_M.gguf" @@ -24,170 +25,65 @@ NEMO = f"{M}/Nemotron-3.5-Lightning-30B-A3B-GGUF/NVIDIA-Nemotron-3.5-Lightning-3 NEMO_MTP = f"{M}/Nemotron-3.5-Lightning-30B-A3B-GGUF/mtp-NVIDIA-Nemotron-3.5-Lightning-30B-A3B-Q8_0.gguf" U38 = f"{M}/Qwen3.8-27B-Uncensored-GGUF/Qwen3.8-27B-Uncensored-Q4_K_M.gguf" U36 = f"{M}/Qwen3.6-35B-A3B-Uncensored-GGUF/Qwen3.6-35B-A3B-Uncensored-HauhauCS-Aggressive-Q4_K_M.gguf" -HERMES = os.path.expanduser("~/.local/bin/hermes") -OUT = os.path.expanduser("~/pruefstand-2026-09-17.json") -RESULTS = [] +OUT = os.path.expanduser(f"~/pruefstand-{time.strftime('%Y-%m-%d')}.json") +RESULTS: list[dict] = [] -def log(*a): - print(*a, flush=True) +def save() -> None: + with open(OUT, "w", encoding="utf-8") as f: + json.dump(RESULTS, f, indent=1, ensure_ascii=False) -def post(url, payload, timeout=900): - r = urllib.request.Request(url, data=json.dumps(payload).encode(), headers={"Content-Type": "application/json"}) - return json.loads(urllib.request.urlopen(r, timeout=timeout).read()) - - -def chat(base, model, messages, max_tokens=200, tools=None, think=True): - p = {"model": model, "temperature": 0, "max_tokens": max_tokens, "messages": messages} - if not think: - p["chat_template_kwargs"] = {"enable_thinking": False} - if tools: - p["tools"] = tools - p["tool_choice"] = "auto" - t0 = time.time() - j = post(f"{base}/v1/chat/completions", p) - j["_wall"] = time.time() - t0 - return j - - -PARA = ("Notiz {i}: Die Box läuft mit llama-swap auf Port 8080, das Hirn ist ein Mixture-of-Experts-Modell mit drei Milliarden " - "aktiven Parametern, der Coder ein dichtes 27B-Modell mit Draft-Beschleunigung. Lucy hört über Parakeet, spricht über " - "pocket-tts und meldet sich per Telegram. Der Sonntags-Job aktualisiert Router, Engine und Agent und rollt bei Rot zurück. ") -DEPTH_PROMPT = "".join(PARA.format(i=i) for i in range(130)) + \ - "\n\nFrage: Fasse in drei Sätzen zusammen, was in den Notizen steht, und nenne die Nummer der letzten Notiz." - -TOOLS = [ - {"type": "function", "function": {"name": "terminal", "description": "Führt einen Shell-Befehl auf der Box aus und gibt stdout zurück.", - "parameters": {"type": "object", "properties": {"command": {"type": "string"}}, "required": ["command"]}}}, - {"type": "function", "function": {"name": "read_file", "description": "Liest eine Datei und gibt den Inhalt zurück.", - "parameters": {"type": "object", "properties": {"path": {"type": "string"}}, "required": ["path"]}}}, - {"type": "function", "function": {"name": "send_telegram", "description": "Schickt dem Nutzer eine Telegram-Nachricht.", - "parameters": {"type": "object", "properties": {"text": {"type": "string"}}, "required": ["text"]}}}, -] -TOOL_TASKS = [ - ("Wie viel freier Speicher ist auf /srv/models? Nutze das passende Werkzeug.", "terminal", r"df"), - ("Lies die Datei /etc/hostname und sag mir, wie die Box heißt.", "read_file", r"/etc/hostname"), - ("Schick mir per Telegram die Nachricht: Prüfstand läuft.", "send_telegram", r"Pr.fstand"), -] - - -def timings(j): - t = j.get("timings") or {} - acc = (t.get("draft_n_accepted", 0) / t["draft_n"]) if t.get("draft_n") else None - return {"pp_n": t.get("prompt_n"), "pp_s": round((t.get("prompt_ms") or 0) / 1000, 1), "pp_tps": round(t.get("prompt_per_second") or 0), - "tg_n": t.get("predicted_n"), "tg_tps": round(t.get("predicted_per_second") or 0, 1), "acc": None if acc is None else round(acc, 2)} - - -def save(): - json.dump(RESULTS, open(OUT, "w"), indent=1, ensure_ascii=False) - - -def probes(base, model, label, with_hermes, hermes_args): - res = {"label": label} - chat(base, model, [{"role": "user", "content": "Sag kurz hallo."}], 32) # Warmlauf - j = chat(base, model, [{"role": "user", "content": "Erkläre in fünf Sätzen, was ein Mixture-of-Experts-Modell ist."}], 200) - res["kurz"] = timings(j); log(f" kurz : {res['kurz']}") - j = chat(base, model, [{"role": "user", "content": DEPTH_PROMPT}], 160) - res["tiefe"] = timings(j); log(f" 13k : {res['tiefe']}") - tc = [] - for q, want_fn, want_arg in TOOL_TASKS: - try: - j = chat(base, model, [{"role": "user", "content": q}], 1500, TOOLS) - msg = j["choices"][0]["message"] - calls = msg.get("tool_calls") or [] - ok = any(c["function"]["name"] == want_fn and re.search(want_arg, c["function"].get("arguments", "")) for c in calls) - raw = "" if calls else (msg.get("content") or "")[:120].replace("\n", " ") - tc.append({"task": want_fn, "ok": ok, "calls": [(c["function"]["name"], c["function"].get("arguments", "")[:80]) for c in calls], "raw": raw}) - except Exception as e: - tc.append({"task": want_fn, "ok": False, "error": str(e)[:120]}) - res["tools_direkt"] = tc - log(f" tools: {sum(1 for t in tc if t['ok'])}/3 " + "; ".join(f"{t['task']}={'✓' if t['ok'] else '✗'}" for t in tc)) - for t in tc: - if not t["ok"]: - log(f" {t['task']}: calls={t.get('calls')} raw={t.get('raw', '')!r} {t.get('error', '')}") - j = chat(base, model, [{"role": "user", "content": "Antworte auf Deutsch in genau drei Sätzen: Warum braucht ein Heimserver ein Backup?"}], 300, think=False) - m = j["choices"][0]["message"] - txt = (m.get("content") or "").strip() or ("[nur reasoning] " + (m.get("reasoning_content") or "")[:200]) - res["deutsch"] = txt[:400]; log(f" de : {txt[:160]!r}") - j = chat(base, model, [{"role": "user", "content": 'Antworte NUR mit JSON, ohne Erklärung: {"modell": "", "ok": true}'}], 120, think=False) - m = j["choices"][0]["message"] - txt = (m.get("content") or "").strip() - try: - json.loads(txt[txt.find("{"): txt.rfind("}") + 1]); js = True - except Exception: - js = False - res["json_ok"] = js; log(f" json : {'✓' if js else '✗'} {txt[:80]!r}") +def probes(basis: str, modell: str, label: str, with_hermes: bool, hermes_args: list[str], bild: bool = False) -> None: + werte = {"label": label, **ps.pruefe("hirn", basis, modell, bild=bild)} if with_hermes: - hz = [] - for q, want in [("Führe im Terminal exakt den Befehl echo pruefstand-ok aus und gib mir nur dessen Ausgabe zurück.", "pruefstand-ok"), - ("Welche Verzeichnisse liegen direkt unter /srv/models? Nenne mir drei davon.", "GGUF")]: - t0 = time.time() - try: - p = subprocess.run([HERMES, "chat", *hermes_args, "-Q", "--oneshot", "--max-turns", "6", "-q", q], - capture_output=True, text=True, timeout=900) - out = (p.stdout + p.stderr)[-600:] - except subprocess.TimeoutExpired: - out = "TIMEOUT" - ok = want.lower() in out.lower() - hz.append({"ok": ok, "s": round(time.time() - t0), "tail": out[-160:].replace("\n", " ")}) - log(f" hermes: {'✓' if ok else '✗'} {round(time.time() - t0)} s {out[-120:].replace(chr(10), ' ')!r}") - res["hermes"] = hz - RESULTS.append(res); save() + werte["hermes"] = ps.hermes_smoke(hermes_args) + RESULTS.append(werte) + save() -def start_server(model, extra): - cmd = [BIN, "-m", model, "--host", "127.0.0.1", "--port", str(PORT), *BASE, *extra] - logf = open("/tmp/pruefstand-server.log", "w") - p = subprocess.Popen(cmd, stdout=logf, stderr=subprocess.STDOUT) - t0 = time.time() - for _ in range(150): - time.sleep(2) - if p.poll() is not None: - tail = open("/tmp/pruefstand-server.log", errors="replace").read()[-500:] - return None, f"LOAD-CRASH rc={p.returncode}: {tail.strip()[-300:]}" - try: - if b"ok" in urllib.request.urlopen(f"http://127.0.0.1:{PORT}/health", timeout=2).read(): - return p, round(time.time() - t0) - except Exception: - pass - p.kill() - return None, "TIMEOUT beim Laden" - - -def candidate(label, model, extra, with_hermes): - log(f"\n=== {label}"); log(f" {os.path.basename(model)} {' '.join(extra)}") - if not os.path.exists(model): - log(" FEHLT: Datei nicht da"); RESULTS.append({"label": label, "fehler": "Datei fehlt"}); save(); return - p, info = start_server(model, extra) - if p is None: - log(f" {info}"); RESULTS.append({"label": label, "fehler": info}); save(); return - log(f" geladen in {info} s") +def candidate(label: str, model: str, extra: list[str], with_hermes: bool, mmproj: str | None = None) -> None: + ps.log(f"\n=== {label}") + ps.log(f" {os.path.basename(model)} {' '.join(extra)}") try: - probes(f"http://127.0.0.1:{PORT}", "kandidat", label, with_hermes, ["--provider", "pruefstand", "-m", "kandidat"]) + server = ps.starte_server(model, mmproj=mmproj, flags=extra, ctx=ps.CTX_STANDARD) + except ps.ServerFehler as e: + ps.log(f" {e}") + RESULTS.append({"label": label, "fehler": str(e)[:300]}) + save() + return + try: + probes(ps.KANDIDAT_URL, "kandidat", label, with_hermes, ["--provider", "pruefstand", "-m", "kandidat"], + bild=bool(mmproj)) except Exception as e: - log(f" FEHLER in Proben: {e}"); RESULTS.append({"label": label, "fehler": str(e)[:200]}); save() + ps.log(f" FEHLER in Proben: {e}") + RESULTS.append({"label": label, "fehler": str(e)[:200]}) + save() finally: - p.terminate() - try: - p.wait(timeout=60) - except Exception: - p.kill() + ps.stoppe_server(server) time.sleep(3) -which = set(sys.argv[1:]) or {"baseline", "nemo", "u38", "u36"} -if "baseline" in which: - log("\n=== BASELINE fast (live, llama-swap)"); probes("http://127.0.0.1:8080", "fast", "fast-live", True, ["-m", "fast"]) - log("\n=== BASELINE coder = Qwen3.8-27B+DFlash2 (live)"); probes("http://127.0.0.1:8080", "coder", "coder-live", True, ["-m", "coder"]) -if "nemo" in which: - candidate("Nemotron 3.5 Lightning · MTP n3", NEMO, ["--spec-type", "draft-mtp", "--spec-draft-model", NEMO_MTP, "--spec-draft-n-max", "3"], True) - candidate("Nemotron 3.5 Lightning · ohne Spec", NEMO, [], False) -if "u38" in which: - candidate("Qwen3.8-27B-Uncensored · MTP fused n2", U38, ["--spec-type", "draft-mtp", "--spec-draft-n-max", "2"], True) - candidate("Qwen3.8-27B-Uncensored · DFlash2 (z-lab) n3", U38, ["--spec-type", "draft-dflash", "--spec-draft-model", DFLASH2_38, "--spec-draft-n-max", "3"], False) - candidate("Qwen3.8-27B-Uncensored · ohne Spec", U38, [], False) -if "u36" in which: - candidate("Qwen3.6-35B-A3B-Uncensored-Aggressive · DFlash (giocom)", U36, ["--spec-type", "draft-dflash", "--spec-draft-model", DFLASH_36], True) - candidate("Qwen3.6-35B-A3B-Uncensored-Aggressive · ohne Spec", U36, [], False) -log("\nPRUEFSTAND_DONE") +def main() -> None: + which = set(sys.argv[1:]) or {"baseline", "nemo", "u38", "u36"} + if "baseline" in which: + ps.log("\n=== BASELINE fast (live, llama-swap)") + probes(ps.SWAP_URL, "fast", "fast-live", True, ["-m", "fast"]) + ps.log("\n=== BASELINE coder (live, llama-swap)") + probes(ps.SWAP_URL, "coder", "coder-live", True, ["-m", "coder"], bild=True) + if "nemo" in which: + candidate("Nemotron 3.5 Lightning · MTP n3", NEMO, + ps.draft_flags(NEMO_MTP, "draft-mtp", 3), True) + candidate("Nemotron 3.5 Lightning · ohne Spec", NEMO, [], False) + if "u38" in which: + candidate("Qwen3.8-27B · MTP fused n2", U38, ps.draft_flags(None, "draft-mtp", 2), True) + candidate("Qwen3.8-27B · DFlash2 (z-lab) n3", U38, ps.draft_flags(DFLASH2_38, "draft-dflash", 3), False) + candidate("Qwen3.8-27B · ohne Spec", U38, [], False) + if "u36" in which: + candidate("Qwen3.6-35B-A3B · DFlash (giocom)", U36, ps.draft_flags(DFLASH_36, "draft-dflash"), True) + candidate("Qwen3.6-35B-A3B · ohne Spec", U36, [], False) + ps.log("\nPRUEFSTAND_DONE") + + +if __name__ == "__main__": + main() diff --git a/deploy/bench/pruefstand.py b/deploy/bench/pruefstand.py new file mode 100644 index 0000000..9c2db0f --- /dev/null +++ b/deploy/bench/pruefstand.py @@ -0,0 +1,1106 @@ +#!/usr/bin/env python3 +""" +Prüfstand als Modul (Modell-Radar, 09/2026) — herausgelöst aus pruefstand-hirn.py (17.09.). + +Warum: Der Prüfstand vom 17.09. lief von Hand, mit festen Pfaden und nur für das Hirn. Das +Modell-Radar (backend/services/radar.py) misst Kandidaten nachts selbst — für beide Rollen, +gegen das heutige Modell der Rolle und mit einem Urteil, das ohne Menschen trägt. Deshalb +nimmt hier jede Messung einen Kandidaten-Pfad (GGUF, optional mmproj und Draft), und jede +Anfrage kennt eine Frist (das Nachtfenster endet hart um 02:30). + + • Server Kandidat standalone auf 127.0.0.1:5899 (llama-server, Flags wie am 17.09.); + der Live-Stack bleibt unberührt. + • hirn Tempo kurz + 13k-Tiefe (Prefill, Decode, Draft-Akzeptanz), Werkzeug-Aufrufe + zwischen ~100 Werkzeugen mit ~12k Kontext, Deutsch- und JSON-Probe. + • coder Tempo, Werkzeug-Aufrufe eines Coding-Agenten, 10 kleine Programmieraufgaben, + deren Lösung mit Unit-Tests in einem Temp-Ordner mit Zeitlimit läuft. + • Bild Nur mit mmproj: ein im Code gezeichnetes PNG (Formen, Farben, Text) als + image_url — einmal direkt, einmal mitten in einer Werkzeug-Aufgabe. + • Baseline Das heutige Modell der Rolle über llama-swap (:8080). Das Ergebnis wird + gecacht und höchstens monatlich neu gemessen. + • Urteil bestanden = keine Verschlechterung bei den Pflichtwerten UND mindestens ein + echter Vorteil (siehe urteil()). + +Lehren vom 17.09. (gelten weiter): Denk-Modelle brauchen für Werkzeug-Aufrufe >= 1500 Tokens +Budget; /no_think wirkt bei Qwen 3.6 nicht (chat_template_kwargs.enable_thinking=false); der +erste Lauf nach dem Laden ist ~40 % langsamer (Warmlauf verwerfen). Neu: Das warme Live-Hirn +hatte den 13k-Text im Prompt-Cache (Prefill 0,1 s statt ~13 s) — jede Tiefenmessung beginnt +deshalb mit einer Zufallsmarke. + +Nur Standardbibliothek: läuft mit dem System-Python der Box genauso wie im MC2-venv. +""" + +import atexit +import base64 +import json +import os +import re +import secrets +import signal +import socket +import struct +import subprocess +import sys +import tempfile +import textwrap +import time +import urllib.error +import urllib.request +import zlib +from pathlib import Path + +# --- Grundeinstellungen --------------------------------------------------------------- + +BIN = os.environ.get("MC_PRUEFSTAND_BIN", "/opt/llamacpp-vulkan/llama-server") +LIB_DIR = os.environ.get("MC_PRUEFSTAND_LIB", os.path.dirname(BIN)) +PORT = int(os.environ.get("MC_PRUEFSTAND_PORT", "5899")) +KANDIDAT_URL = f"http://127.0.0.1:{PORT}" +SWAP_URL = os.environ.get("MC_LLAMA_SWAP_URL", "http://127.0.0.1:8080").rstrip("/") +SERVER_LOG = os.path.join(tempfile.gettempdir(), "pruefstand-server.log") +HERMES = os.path.expanduser("~/.local/bin/hermes") + +CTX_STANDARD = 65536 +# Flags wie am 17.09. (der Kontext kommt je Kandidat dazu): voller GPU-Offload, Flash-Attention, +# kein mmap (--load-mode none, das alte --no-mmap gibt es seit b10936 nicht mehr), ein Slot, +# KV-Cache q8_0 wie im Betrieb. +BASIS_FLAGS = ["-ngl", "999", "-fa", "on", "--load-mode", "none", "--jinja", "--parallel", "1", + "-ctk", "q8_0", "-ctv", "q8_0"] +LADEZEIT_MAX_S = int(os.environ.get("MC_PRUEFSTAND_LADEZEIT", "600")) +ANFRAGE_MAX_S = 900 +WERKZEUG_TOKENS = 1500 # Denk-Modelle brauchen so viel Luft vor dem Werkzeug-Aufruf +CODE_TOKENS = 2500 +CODE_ZEITLIMIT_S = 10 + +# Baseline = das heutige Modell der Rolle, angesprochen über seinen llama-swap-Alias. +ALIAS = {"hirn": "hermes", "coder": "coder"} + +# Urteil: Faktor Kandidat/Baseline. *_min = Pflicht (darunter durchgefallen), *_plus = Vorteil. +# Beim Hirn zählt Tempo mehr (Lucy antwortet live), beim Coder die Code-Qualität. +REGELN = { + "hirn": {"decode_min": 0.85, "decode_plus": 1.10, "prefill_min": 0.80, "prefill_plus": 1.10}, + "coder": {"decode_min": 0.80, "decode_plus": 1.15, "prefill_min": 0.67, "prefill_plus": 1.25}, +} +WERKZEUG_BODEN = 0.5 # so viele Werkzeug-Aufgaben muss jeder schaffen, auch wenn heute alle scheitern +BILD_MIN = 0.75 # Anteil erkannter Bild-Merkmale +# Beide Rollen sollen Bilder verstehen (User-Entscheid 23.09.) — wer es nicht kann, fällt durch. +BILD_PFLICHT = os.environ.get("MC_RADAR_BILD_PFLICHT", "1") != "0" + + +class Zeitende(Exception): + """Die Frist (Ende des Nachtfensters) ist erreicht — Messung abbrechen.""" + + +class ServerFehler(Exception): + """Der Kandidat startet nicht oder stürzt ab (Laden, Port belegt, Absturz im Test).""" + + +def log(*teile) -> None: + """Protokollzeile. Eine Konsole ohne UTF-8 darf nie eine Messung abbrechen.""" + try: + print(*teile, flush=True) + except UnicodeEncodeError: + print(*(str(t).encode("ascii", "replace").decode() for t in teile), flush=True) + + +# --- HTTP --------------------------------------------------------------------------- + +def _restzeit(frist: float | None) -> float | None: + if frist is None: + return None + rest = frist - time.time() + if rest <= 5: + raise Zeitende("Frist erreicht.") + return rest + + +def post(url: str, nutzlast: dict, timeout: float = ANFRAGE_MAX_S, frist: float | None = None) -> dict: + """JSON-POST; der Timeout endet spätestens mit der Frist.""" + rest = _restzeit(frist) + if rest is not None: + timeout = min(timeout, rest) + anfrage = urllib.request.Request(url, data=json.dumps(nutzlast).encode(), + headers={"Content-Type": "application/json"}) + try: + with urllib.request.urlopen(anfrage, timeout=timeout) as antwort: + return json.loads(antwort.read()) + except (TimeoutError, urllib.error.URLError) as e: + if frist is not None and time.time() >= frist - 5: + raise Zeitende("Frist während einer Anfrage erreicht.") from e + raise + + +def chat(basis: str, modell: str, messages: list, max_tokens: int = 200, tools: list | None = None, + think: bool = True, frist: float | None = None) -> dict: + p: dict = {"model": modell, "temperature": 0, "max_tokens": max_tokens, "messages": messages} + if not think: + p["chat_template_kwargs"] = {"enable_thinking": False} + if tools: + p["tools"] = tools + p["tool_choice"] = "auto" + t0 = time.time() + j = post(f"{basis}/v1/chat/completions", p, frist=frist) + j["_wall"] = time.time() - t0 + return j + + +def _nachricht(j: dict) -> dict: + return ((j.get("choices") or [{}])[0].get("message")) or {} + + +def _text(j: dict) -> str: + """Antworttext ohne Denkblock (manche Templates lassen im content stehen).""" + text = _nachricht(j).get("content") or "" + return re.sub(r".*?", "", text, flags=re.DOTALL).strip() + + +def timings(j: dict) -> dict: + t = j.get("timings") or {} + acc = (t.get("draft_n_accepted", 0) / t["draft_n"]) if t.get("draft_n") else None + return {"pp_n": t.get("prompt_n"), "pp_s": round((t.get("prompt_ms") or 0) / 1000, 1), + "pp_tps": round(t.get("prompt_per_second") or 0), "tg_n": t.get("predicted_n"), + "tg_tps": round(t.get("predicted_per_second") or 0, 1), "acc": None if acc is None else round(acc, 2)} + + +# --- Tempo --------------------------------------------------------------------------- + +PARA = ("Notiz {i}: Die Box läuft mit llama-swap auf Port 8080, das Hirn ist ein Mixture-of-Experts-Modell mit drei " + "Milliarden aktiven Parametern, der Coder ein dichtes 27B-Modell mit Draft-Beschleunigung. Lucy hört über " + "Parakeet, spricht über pocket-tts und meldet sich per Telegram. Der Sonntags-Job aktualisiert Router, Engine " + "und Agent und rollt bei Rot zurück. ") + + +def tiefen_prompt(marke: str) -> str: + """~13k Tokens. Die Zufallsmarke vorn verhindert, dass ein warmes Modell den Text aus dem + Prompt-Cache holt (am 17.09. kam das Live-Hirn so auf 0,1 s Prefill).""" + return (f"Messlauf {marke}.\n" + "".join(PARA.format(i=i) for i in range(130)) + + "\n\nFrage: Fasse in drei Sätzen zusammen, was in den Notizen steht, und nenne die Nummer der letzten Notiz.") + + +def messe_tempo(basis: str, modell: str, frist: float | None = None) -> dict: + chat(basis, modell, [{"role": "user", "content": "Sag kurz hallo."}], 32, frist=frist) # Warmlauf + kurz = chat(basis, modell, [{"role": "user", "content": + "Erkläre in fünf Sätzen, was ein Mixture-of-Experts-Modell ist."}], 200, frist=frist) + tiefe = chat(basis, modell, [{"role": "user", "content": tiefen_prompt(secrets.token_hex(4))}], 160, frist=frist) + return {"kurz": timings(kurz), "tiefe": timings(tiefe)} + + +# --- Werkzeuge ----------------------------------------------------------------------- + +def _werkzeug(name: str, beschreibung: str, **parameter: str) -> dict: + return {"type": "function", "function": { + "name": name, "description": beschreibung, + "parameters": {"type": "object", "properties": {k: {"type": "string", "description": v} + for k, v in parameter.items()}, + "required": list(parameter)}}} + + +SCREENSHOT = _werkzeug("screenshot", "Nimmt ein Bildschirmfoto vom PC des Nutzers auf und zeigt es dir.") +WERKZEUGE_HIRN_ECHT = [ + _werkzeug("terminal", "Führt einen Shell-Befehl auf der Box aus und gibt stdout zurück.", command="Der Befehl"), + _werkzeug("read_file", "Liest eine Datei und gibt den Inhalt zurück.", path="Absoluter Pfad"), + _werkzeug("send_telegram", "Schickt dem Nutzer eine Telegram-Nachricht.", text="Nachrichtentext"), + _werkzeug("web_fetch", "Ruft eine Webseite ab und liefert ihren Text.", url="Adresse der Seite"), + _werkzeug("erinnerung_anlegen", "Legt eine Erinnerung für den Nutzer an.", text="Worum es geht", + zeit="Wann (ISO-Zeit oder natürlich)"), + SCREENSHOT, +] +# Lucy hat ~100 Werkzeuge. Die Ablenker machen die Auswahl so schwer wie im Alltag. +_ABLENKER = { + "kalender": ("Kalender", ("lesen", "eintragen", "verschieben", "loeschen")), + "notiz": ("Notizen", ("lesen", "anlegen", "suchen", "loeschen")), + "mail": ("E-Mails", ("lesen", "suchen", "entwerfen", "archivieren")), + "kontakt": ("Kontakte", ("suchen", "anlegen", "aendern")), + "einkauf": ("Einkaufsliste", ("lesen", "ergaenzen", "leeren")), + "licht": ("Licht", ("einschalten", "ausschalten", "dimmen")), + "heizung": ("Heizung", ("lesen", "stellen")), + "rollladen": ("Rollläden", ("oeffnen", "schliessen")), + "musik": ("Musik", ("abspielen", "pausieren", "suchen")), + "jellyfin": ("Jellyfin-Mediathek", ("suchen", "abspielen")), + "docker": ("Docker-Container", ("auflisten", "neustarten", "logs")), + "gitea": ("Gitea-Repos", ("auflisten", "issue_anlegen", "pr_lesen")), + "backup": ("Sicherungen", ("auflisten", "starten", "pruefen")), + "wetter": ("Wetter", ("heute", "vorhersage")), + "bahn": ("Bahnverbindungen", ("suchen", "verspaetung")), + "paket": ("Paketsendungen", ("verfolgen",)), + "rezept": ("Rezepte", ("suchen", "speichern")), + "wissen": ("Wissensartikel", ("suchen", "zusammenfassen")), + "uebersetzung": ("Übersetzungen", ("deutsch_englisch", "englisch_deutsch")), + "rechner": ("Taschenrechner", ("rechnen",)), + "timer": ("Küchentimer", ("stellen", "stoppen")), + "wecker": ("Wecker", ("stellen", "loeschen")), + "drucker": ("Drucker", ("drucken", "status")), + "sauger": ("Saugroboter", ("starten", "stoppen", "status")), + "tuer": ("Haustür", ("status",)), + "kamera": ("Kamera an der Haustür", ("bild_holen",)), + "strom": ("Stromverbrauch", ("heute", "monat")), + "nerdquiz": ("NerdQuiz", ("frage_holen", "punkte")), + "projekt": ("Projekte", ("status", "anlegen")), + "modell": ("KI-Modelle", ("auflisten", "laden")), + "system": ("Box-System", ("temperatur", "speicher", "prozesse")), + "datei": ("Dateien", ("suchen", "kopieren", "verschieben")), + "aufgabe": ("Aufgaben", ("anlegen", "erledigen", "auflisten")), + "browser": ("Browser-Tabs", ("auflisten", "schliessen")), + "ablage": ("Zwischenablage", ("lesen", "setzen")), + "sprache": ("Sprachausgabe", ("sprechen",)), + "tagebuch": ("Tagebuch", ("eintragen", "lesen")), + "nachrichten": ("Nachrichten", ("schlagzeilen", "suchen")), +} +WERKZEUGE_HIRN = WERKZEUGE_HIRN_ECHT + [ + _werkzeug(f"{objekt}_{verb}", f"{anzeige}: {verb.replace('_', ' ')}.", eingabe="Freitext") + for objekt, (anzeige, verben) in _ABLENKER.items() for verb in verben] +SYSTEM_HIRN = ("Du bist Lucy, die persönliche Assistentin auf der Box. Du antwortest auf Deutsch, knapp und freundlich. " + "Wenn eine Aufgabe ein Werkzeug braucht, rufst du genau das passende auf, statt zu raten.\n\n" + "Hintergrundwissen aus deinem Gedächtnis:\n" + "".join(PARA.format(i=i) for i in range(80))) +# (Frage, [(Werkzeug, Muster in den Argumenten), …]) — eine Alternative reicht. +AUFGABEN_HIRN = [ + ("Wie viel Platz ist auf /srv/models noch frei? Nutze das passende Werkzeug.", [("terminal", r"\bd[fu]\b")]), + ("Lies die Datei /etc/hostname und sag mir, wie die Box heißt.", [("read_file", r"/etc/hostname")]), + ("Schick mir per Telegram die Nachricht: Prüfstand läuft.", [("send_telegram", r"pr(ü|ue)fstand")]), + ("Was steht gerade auf https://example.org? Ruf die Seite ab.", [("web_fetch", r"example\.org")]), + ("Erinnere mich morgen um 8 Uhr an den Zahnarzttermin.", [("erinnerung_anlegen", r"zahnarzt")]), + ("Schau auf meinen Bildschirm: Was ist da gerade offen?", [("screenshot", r"")]), +] + +WERKZEUGE_CODER = [ + _werkzeug("bash", "Führt einen Shell-Befehl im Projektordner aus.", command="Befehl", description="Wozu, kurz"), + _werkzeug("read", "Liest eine Datei.", filePath="Pfad"), + _werkzeug("write", "Schreibt eine Datei (legt sie an oder überschreibt sie).", filePath="Pfad", content="Inhalt"), + _werkzeug("edit", "Ersetzt in einer Datei einen Textabschnitt.", filePath="Pfad", oldString="Alter Text", + newString="Neuer Text"), + _werkzeug("glob", "Findet Dateien per Muster.", pattern="z. B. src/**/*.py"), + _werkzeug("grep", "Durchsucht Dateien nach einem regulären Ausdruck.", pattern="Suchmuster", include="Dateimuster"), + _werkzeug("list", "Listet einen Ordner auf.", path="Ordner"), + _werkzeug("webfetch", "Lädt eine Webseite.", url="Adresse"), + _werkzeug("todowrite", "Schreibt die Aufgabenliste des Agenten.", todos="Aufgaben als Text"), + _werkzeug("task", "Startet einen Unter-Agenten für eine Teilaufgabe.", description="Kurzbeschreibung", + prompt="Auftrag"), +] +SYSTEM_CODER = ("Du bist ein Coding-Agent in OpenCode. Das Projekt liegt in /home/nutzer/projekt (Python, Tests mit " + "pytest, Quellcode unter src/). Erledige Aufträge mit den Werkzeugen, ohne nachzufragen. " + "In src/config.py steht die Zeile `PORT = 8080`.") +AUFGABEN_CODER = [ + ("Führe die Tests des Projekts mit pytest aus.", [("bash", r"pytest")]), + ("Zeig mir den Inhalt von src/app.py.", [("read", r"src/app\.py")]), + ("Ersetze in src/config.py den Port 8080 durch 9090.", + [("edit", r"8080[\s\S]*9090"), ("write", r"9090"), ("bash", r"sed[\s\S]*9090")]), + ("Finde alle Stellen im Code, an denen TODO steht.", [("grep", r"TODO"), ("bash", r"grep[\s\S]*TODO")]), + ("Lege die Datei hallo.py an, mit einer Funktion hallo(), die 'Hallo' zurückgibt.", + [("write", r"hallo\.py[\s\S]*def hallo")]), +] + + +def _werkzeug_satz(rolle: str) -> tuple[str, list, list]: + if rolle == "hirn": + return SYSTEM_HIRN, WERKZEUGE_HIRN, AUFGABEN_HIRN + return SYSTEM_CODER, WERKZEUGE_CODER, AUFGABEN_CODER + + +def argumente_text(roh) -> str: + """Argumente eines Werkzeug-Aufrufs als durchsuchbarer Text (JSON-Escapes wie \\u00fc aufgelöst).""" + werte = roh + if not isinstance(roh, dict): + try: + werte = json.loads(roh or "{}") + except (TypeError, ValueError): + return str(roh or "") + if isinstance(werte, dict): + return " ".join(str(v) for v in werte.values()) + return str(werte) + + +def trifft(aufrufe: list, erwartet: list) -> bool: + for aufruf in aufrufe or []: + fn = (aufruf or {}).get("function") or {} + text = argumente_text(fn.get("arguments")) + if any(fn.get("name") == name and re.search(muster, text, re.IGNORECASE) for name, muster in erwartet): + return True + return False + + +def _aufrufe_kurz(aufrufe: list) -> list: + return [[(a.get("function") or {}).get("name"), argumente_text((a.get("function") or {}).get("arguments"))[:80]] + for a in aufrufe or []] + + +def messe_werkzeuge(basis: str, modell: str, rolle: str, frist: float | None = None) -> dict: + system, werkzeuge, aufgaben = _werkzeug_satz(rolle) + details, ok, kontext = [], 0, None + for frage, erwartet in aufgaben: + eintrag: dict = {"aufgabe": frage[:60], "ok": False} + try: + j = chat(basis, modell, [{"role": "system", "content": system}, {"role": "user", "content": frage}], + WERKZEUG_TOKENS, werkzeuge, frist=frist) + t = j.get("timings") or {} + kontext = kontext or ((t.get("prompt_n") or 0) + (t.get("cache_n") or 0)) or None + aufrufe = _nachricht(j).get("tool_calls") or [] + eintrag["ok"] = trifft(aufrufe, erwartet) + eintrag["aufrufe"] = _aufrufe_kurz(aufrufe) + if not aufrufe: + eintrag["antwort"] = _text(j)[:120] + except Zeitende: + raise + except Exception as e: + eintrag["fehler"] = str(e)[:120] + ok += eintrag["ok"] + details.append(eintrag) + return {"ok": ok, "von": len(aufgaben), "kontext_tokens": kontext, "details": details} + + +# --- Deutsch und JSON (Hirn) -------------------------------------------------------------- + +_DEUTSCHE_WOERTER = re.compile(r"\b(und|die|der|das|ist|nicht|ein|eine|für|mit|wird|sind|auch|oder)\b", re.IGNORECASE) + + +def ist_deutsch(text: str) -> bool: + return len(text) >= 60 and len({w.lower() for w in _DEUTSCHE_WOERTER.findall(text)}) >= 3 + + +def ist_json(text: str) -> bool: + try: + json.loads(text[text.find("{"): text.rfind("}") + 1]) + return True + except ValueError: + return False + + +def messe_sprache(basis: str, modell: str, frist: float | None = None) -> dict: + j = chat(basis, modell, [{"role": "user", "content": + "Antworte auf Deutsch in genau drei Sätzen: Warum braucht ein Heimserver ein Backup?"}], + 300, think=False, frist=frist) + deutsch = _text(j) + j = chat(basis, modell, [{"role": "user", "content": + 'Antworte NUR mit JSON, ohne Erklärung: {"modell": "", "ok": true}'}], + 120, think=False, frist=frist) + roh = _text(j) + return {"deutsch": {"ok": ist_deutsch(deutsch), "text": deutsch[:300]}, + "json": {"ok": ist_json(roh), "text": roh[:120]}} + + +# --- Programmieraufgaben (Coder) ------------------------------------------------------------- + +def _aufgabe(kennung: str, auftrag: str, tests: str) -> dict: + return {"id": kennung, "auftrag": auftrag, "tests": textwrap.dedent(tests).strip() + "\n"} + + +AUFGABEN_CODE = [ + _aufgabe("palindrom", + "Schreibe eine Python-Funktion `ist_palindrom(text: str) -> bool`. Sie gibt True zurück, wenn der Text " + "vorwärts wie rückwärts gleich lautet. Groß- und Kleinschreibung, Leerzeichen und Satzzeichen zählen " + "nicht; verglichen werden nur Buchstaben (auch Umlaute) und Ziffern. Ein leerer Text ist ein Palindrom.", + """ + assert ist_palindrom("Ein Esel lese nie") is True + assert ist_palindrom("Reliefpfeiler") is True + assert ist_palindrom("Otto!") is True + assert ist_palindrom("Ölö") is True + assert ist_palindrom("12a21") is True + assert ist_palindrom("") is True + assert ist_palindrom("Hallo Welt") is False + """), + _aufgabe("roemisch", + "Schreibe `roemisch(zahl: int) -> str`, die eine ganze Zahl von 1 bis 3999 als römische Zahl schreibt " + "(mit Subtraktion: 4 = IV, 9 = IX, 40 = XL, 90 = XC, 400 = CD, 900 = CM). Zahlen außerhalb des Bereichs " + "lösen ValueError aus.", + """ + assert roemisch(1) == "I" + assert roemisch(4) == "IV" + assert roemisch(9) == "IX" + assert roemisch(58) == "LVIII" + assert roemisch(1994) == "MCMXCIV" + assert roemisch(3999) == "MMMCMXCIX" + for falsch in (0, 4000, -3): + try: + roemisch(falsch) + except ValueError: + pass + else: + raise AssertionError(f"kein ValueError für {falsch}") + """), + _aufgabe("intervalle", + "Schreibe `zusammenfassen(intervalle: list[list[int]]) -> list[list[int]]`. Sie fasst sich überlappende " + "oder berührende Intervalle [start, ende] zusammen und gibt sie nach Start sortiert zurück. Die Eingabe " + "ist unsortiert und darf nicht verändert werden.", + """ + assert zusammenfassen([[1, 3], [2, 6], [8, 10], [15, 18]]) == [[1, 6], [8, 10], [15, 18]] + assert zusammenfassen([[1, 4], [4, 5]]) == [[1, 5]] + assert zusammenfassen([]) == [] + assert zusammenfassen([[5, 7], [1, 2]]) == [[1, 2], [5, 7]] + assert zusammenfassen([[1, 10], [2, 3], [4, 8]]) == [[1, 10]] + eingabe = [[3, 4], [1, 2]] + zusammenfassen(eingabe) + assert eingabe == [[3, 4], [1, 2]] + """), + _aufgabe("flach", + "Schreibe `flach(liste: list) -> list`, die beliebig tief verschachtelte Listen zu einer flachen Liste " + "macht. Die Reihenfolge bleibt erhalten. Nur Listen werden aufgelöst; Tupel und Strings bleiben einzelne " + "Elemente.", + """ + assert flach([1, [2, [3, [4]], 5]]) == [1, 2, 3, 4, 5] + assert flach([]) == [] + assert flach([[[]]]) == [] + assert flach(["ab", ("c", "d"), ["e"]]) == ["ab", ("c", "d"), "e"] + tief = [1] + for _ in range(50): + tief = [tief] + assert flach(tief) == [1] + """), + _aufgabe("iban", + "Schreibe `iban_gueltig(iban: str) -> bool`. Leerzeichen werden ignoriert, Groß-/Kleinschreibung ist " + "egal. Prüfe die Länge (15 bis 34 Zeichen), dass nur Buchstaben und Ziffern vorkommen, und die Prüfsumme " + "nach ISO 13616: die ersten vier Zeichen ans Ende stellen, Buchstaben durch Zahlen ersetzen (A=10 … Z=35), " + "die entstehende Zahl modulo 97 muss 1 ergeben.", + """ + assert iban_gueltig("DE89 3704 0044 0532 0130 00") is True + assert iban_gueltig("de89370400440532013000") is True + assert iban_gueltig("GB82 WEST 1234 5698 7654 32") is True + assert iban_gueltig("DE89 3704 0044 0532 0130 01") is False + assert iban_gueltig("DE89-3704-0044") is False + assert iban_gueltig("") is False + """), + _aufgabe("lru", + "Schreibe eine Klasse `LRUCache` mit `__init__(self, kapazitaet: int)`, `get(self, schluessel)` (liefert " + "den Wert oder None und markiert den Eintrag als zuletzt benutzt) und `put(self, schluessel, wert)` (legt " + "an oder überschreibt, ebenfalls als zuletzt benutzt; ist die Kapazität überschritten, fliegt der am " + "längsten nicht benutzte Eintrag raus).", + """ + c = LRUCache(2) + c.put("a", 1) + c.put("b", 2) + assert c.get("a") == 1 + c.put("c", 3) + assert c.get("b") is None + assert c.get("a") == 1 + assert c.get("c") == 3 + c.put("a", 10) + c.put("d", 4) + assert c.get("c") is None + assert c.get("a") == 10 + assert c.get("d") == 4 + """), + _aufgabe("klammern", + "Schreibe `klammern_ok(text: str) -> bool`. Sie prüft, ob die Klammern (), [] und {} im Text korrekt " + "geschachtelt und geschlossen sind. Alle anderen Zeichen werden ignoriert.", + """ + assert klammern_ok("") is True + assert klammern_ok("f(a[1], {b: 2})") is True + assert klammern_ok("x = {'a': [1, (2, 3)]}") is True + assert klammern_ok("([)]") is False + assert klammern_ok("((") is False + assert klammern_ok("())") is False + """), + _aufgabe("wege", + "Schreibe `kuerzeste_wege(graph: dict[str, dict[str, int]], start: str) -> dict[str, int]`. graph ordnet " + "jedem Knoten seine Nachbarn mit nicht negativen Kantengewichten zu. Liefere die kürzeste Entfernung vom " + "Start zu jedem erreichbaren Knoten (der Start selbst mit 0). Nicht erreichbare Knoten fehlen im " + "Ergebnis. Nachbarn, die nicht als Schlüssel in graph stehen, sind trotzdem gültige Knoten.", + """ + g = {"A": {"B": 1, "C": 4}, "B": {"C": 2, "D": 5}, "C": {"D": 1}, "D": {}, "X": {"A": 1}} + assert kuerzeste_wege(g, "A") == {"A": 0, "B": 1, "C": 3, "D": 4} + assert kuerzeste_wege(g, "D") == {"D": 0} + assert kuerzeste_wege(g, "X") == {"X": 0, "A": 1, "B": 2, "C": 4, "D": 5} + assert kuerzeste_wege({"A": {"Z": 7}}, "A") == {"A": 0, "Z": 7} + """), + _aufgabe("median", + "Diese Funktion soll den Median einer Liste von Zahlen liefern, ist aber fehlerhaft. Korrigiere sie. Die " + "Eingabeliste darf nicht verändert werden; bei einer leeren Liste soll ValueError kommen.\n\n" + "```python\ndef median(zahlen):\n zahlen.sort()\n mitte = len(zahlen) // 2\n" + " return zahlen[mitte]\n```", + """ + assert median([3, 1, 2]) == 2 + assert median([4, 1, 3, 2]) == 2.5 + assert median([5]) == 5 + daten = [9, 7, 8] + median(daten) + assert daten == [9, 7, 8] + try: + median([]) + except ValueError: + pass + else: + raise AssertionError("kein ValueError bei leerer Liste") + """), + _aufgabe("csv", + "Schreibe `spaltensumme(csv_text: str, spalte: str) -> float`. Der Text ist eine CSV-Datei mit Semikolon " + "als Trenner und einer Kopfzeile. Zahlen haben ein Komma als Dezimaltrenner und können einen Punkt als " + "Tausendertrenner haben (z. B. 1.234,5). Leere Zellen zählen als 0. Gibt es die Spalte nicht, löse " + "KeyError aus.", + """ + text = "name;betrag;menge\\nA;1,5;2\\nB;1.234,5;\\nC;;3\\n" + assert abs(spaltensumme(text, "betrag") - 1236.0) < 1e-9 + assert abs(spaltensumme(text, "menge") - 5.0) < 1e-9 + try: + spaltensumme(text, "preis") + except KeyError: + pass + else: + raise AssertionError("kein KeyError") + """), +] +SYSTEM_CODE = "Du bist ein erfahrener Python-Entwickler. Antworte nur mit einem Python-Codeblock, ohne Erklärung." + +# Modell-Code läuft auf der Box — nur reine Funktionen sind erlaubt, kein Zugriff auf Dateien, +# Prozesse oder Netz. Die Sperrliste ist grob, aber für diese Aufgaben braucht es nichts davon. +_VERBOTEN = re.compile( + r"^\s*(?:import|from)\s+(?:os|subprocess|shutil|socket|pathlib|ctypes|multiprocessing|threading|urllib|http|" + r"requests|signal|importlib|builtins|pty|resource|glob|tempfile|io|codecs)\b" + r"|__import__|(? str: + """Längster Python-Codeblock der Antwort (Lösung statt Beispielaufruf); ohne Block die ganze Antwort.""" + text = re.sub(r".*?", "", text or "", flags=re.DOTALL) + bloecke = re.findall(r"```[ \t]*(?:python|py|python3)?[^\n]*\n(.*?)```", text, re.DOTALL | re.IGNORECASE) + return max(bloecke, key=len) if bloecke else text.strip() + + +def fuehre_aufgabe_aus(code: str, tests: str, zeitlimit: float = CODE_ZEITLIMIT_S) -> tuple[bool, str]: + """Lösung + Tests in einem frischen Temp-Ordner mit Zeit- und Speichergrenze ausführen.""" + if not code.strip(): + return False, "keine Lösung in der Antwort" + if (treffer := _VERBOTEN.search(code)): + return False, f"unerlaubter Aufruf: {treffer.group(0).strip()[:40]}" + with tempfile.TemporaryDirectory(prefix="pruefstand-code-") as ordner: + Path(ordner, "loesung.py").write_text(code, encoding="utf-8") + Path(ordner, "pruefung.py").write_text(_RUNNER_KOPF + tests + "print('OK')\n", encoding="utf-8") + umgebung = {"PATH": os.environ.get("PATH", ""), "HOME": ordner, "TMPDIR": ordner, "LANG": "C.UTF-8"} + umgebung.update({k: os.environ[k] for k in ("SYSTEMROOT", "WINDIR") if k in os.environ}) + try: + p = subprocess.run([sys.executable, "-I", "pruefung.py"], cwd=ordner, capture_output=True, + encoding="utf-8", errors="replace", timeout=zeitlimit, env=umgebung, + stdin=subprocess.DEVNULL) + except subprocess.TimeoutExpired: + return False, f"Zeitlimit {zeitlimit:.0f} s überschritten" + if p.returncode == 0 and "OK" in p.stdout: + return True, "" + zeilen = (p.stderr or p.stdout or "").strip().splitlines() + return False, (zeilen[-1] if zeilen else f"Exit-Code {p.returncode}")[:200] + + +def messe_code(basis: str, modell: str, frist: float | None = None) -> dict: + """Denken aus: bei so kleinen Aufgaben misst das die Code-Qualität und hält die Nacht kurz.""" + details, ok, t0 = [], 0, time.time() + for aufgabe in AUFGABEN_CODE: + try: + j = chat(basis, modell, [{"role": "system", "content": SYSTEM_CODE}, + {"role": "user", "content": aufgabe["auftrag"]}], + CODE_TOKENS, think=False, frist=frist) + geschafft, grund = fuehre_aufgabe_aus(code_aus_antwort(_text(j)), aufgabe["tests"]) + except Zeitende: + raise + except Exception as e: + geschafft, grund = False, f"Anfrage scheiterte: {e}"[:160] + ok += geschafft + details.append({"aufgabe": aufgabe["id"], "ok": geschafft, "grund": grund}) + return {"ok": ok, "von": len(AUFGABEN_CODE), "sekunden": round(time.time() - t0), "details": details} + + +# --- Bild-Probe ------------------------------------------------------------------------ + +BILD_TEXT = "ZEBRA 4711" +BILD_MERKMALE = { + "Wort ZEBRA": r"zebra", + "Zahl 4711": r"4[\s.]?711", + "rot": r"\brot(e|er|es|en)?\b|\bred\b", + "blau": r"\bblau|\bblue\b", + "grün": r"\bgr(ü|ue)n|\bgreen\b", + "Kreis": r"kreis|circle", + "Quadrat": r"quadrat|rechteck|viereck|square|rectangle", + "Dreieck": r"dreieck|triangle", +} +_GLYPHEN = { + "Z": ("#####", "....#", "...#.", "..#..", ".#...", "#....", "#####"), + "E": ("#####", "#....", "#....", "####.", "#....", "#....", "#####"), + "B": ("####.", "#...#", "#...#", "####.", "#...#", "#...#", "####."), + "R": ("####.", "#...#", "#...#", "####.", "#.#..", "#..#.", "#...#"), + "A": (".###.", "#...#", "#...#", "#####", "#...#", "#...#", "#...#"), + "4": ("...#.", "..##.", ".#.#.", "#..#.", "#####", "...#.", "...#."), + "7": ("#####", "....#", "...#.", "..#..", ".#...", ".#...", ".#..."), + "1": ("..#..", ".##..", "..#..", "..#..", "..#..", "..#..", ".###."), + " ": (".....",) * 7, +} + + +def bild_png(breite: int = 448, hoehe: int = 300) -> bytes: + """Testbild ohne Pillow: roter Kreis, blaues Quadrat, grünes Dreieck, darunter „ZEBRA 4711“.""" + px = bytearray(b"\xff" * (breite * hoehe * 3)) + + def setze(x: int, y: int, farbe: bytes) -> None: + if 0 <= x < breite and 0 <= y < hoehe: + i = (y * breite + x) * 3 + px[i:i + 3] = farbe + + rot, blau, gruen, schwarz = b"\xdc\x14\x14", b"\x14\x3c\xdc", b"\x14\xa0\x28", b"\x10\x10\x10" + cx, cy, r = 80, 95, 55 + for y in range(cy - r, cy + r + 1): + for x in range(cx - r, cx + r + 1): + if (x - cx) ** 2 + (y - cy) ** 2 <= r * r: + setze(x, y, rot) + for y in range(40, 150): + for x in range(170, 280): + setze(x, y, blau) + spitze_x, oben, unten, links, rechts = 370, 40, 150, 315, 425 + for y in range(oben, unten + 1): + anteil = (y - oben) / (unten - oben) + for x in range(round(spitze_x + (links - spitze_x) * anteil), round(spitze_x + (rechts - spitze_x) * anteil) + 1): + setze(x, y, gruen) + skala, zelle = 6, 6 + x0, y0 = (breite - len(BILD_TEXT) * zelle * skala) // 2, 205 + for n, zeichen in enumerate(BILD_TEXT): + for zy, reihe in enumerate(_GLYPHEN[zeichen]): + for zx, punkt in enumerate(reihe): + if punkt == "#": + for dy in range(skala): + for dx in range(skala): + setze(x0 + (n * zelle + zx) * skala + dx, y0 + zy * skala + dy, schwarz) + roh = b"".join(b"\x00" + bytes(px[y * breite * 3:(y + 1) * breite * 3]) for y in range(hoehe)) + + def block(typ: bytes, daten: bytes) -> bytes: + return struct.pack(">I", len(daten)) + typ + daten + struct.pack(">I", zlib.crc32(typ + daten) & 0xFFFFFFFF) + + return (b"\x89PNG\r\n\x1a\n" + block(b"IHDR", struct.pack(">IIBBBBB", breite, hoehe, 8, 2, 0, 0, 0)) + + block(b"IDAT", zlib.compress(roh, 9)) + block(b"IEND", b"")) + + +def bild_data_url() -> str: + return "data:image/png;base64," + base64.b64encode(bild_png()).decode() + + +def bild_merkmale(text: str) -> list[str]: + return [name for name, muster in BILD_MERKMALE.items() if re.search(muster, text or "", re.IGNORECASE)] + + +def _bild_im_ablauf(basis: str, modell: str, rolle: str, url: str, frist: float | None) -> dict: + """Das Bild kommt mitten in einer Werkzeug-Aufgabe (als Ergebnis von „screenshot“), wie bei Lucy + am Bildschirm oder beim Coder mit einem Screenshot der App. Erwartet wird der nächste richtige Schritt.""" + if rolle == "hirn": + system, werkzeuge = SYSTEM_HIRN, WERKZEUGE_HIRN + auftrag = "Schau auf meinen Bildschirm und schick mir per Telegram, welches Wort und welche Zahl dort stehen." + erwartet = [("send_telegram", r"zebra[\s\S]*4[\s.]?711|4[\s.]?711[\s\S]*zebra")] + else: + system, werkzeuge = SYSTEM_CODER, WERKZEUGE_CODER + [SCREENSHOT] + auftrag = ("Mach einen Screenshot der laufenden App. Die Zahl, die dort angezeigt wird, soll in src/config.py " + "als PORT stehen. Pass die Datei an.") + erwartet = [("edit", r"4711"), ("write", r"4711"), ("bash", r"4711")] + verlauf = [ + {"role": "system", "content": system}, + {"role": "user", "content": auftrag}, + {"role": "assistant", "content": "", "tool_calls": [ + {"id": "call_bild_1", "type": "function", "function": {"name": "screenshot", "arguments": "{}"}}]}, + {"role": "tool", "tool_call_id": "call_bild_1", "content": "Bildschirmfoto aufgenommen, es folgt als Bild."}, + {"role": "user", "content": [{"type": "image_url", "image_url": {"url": url}}, + {"type": "text", "text": "Bildschirmfoto aus dem Werkzeug screenshot."}]}, + ] + j = chat(basis, modell, verlauf, WERKZEUG_TOKENS, werkzeuge, frist=frist) + aufrufe = _nachricht(j).get("tool_calls") or [] + return {"ok": trifft(aufrufe, erwartet), "aufrufe": _aufrufe_kurz(aufrufe), + "antwort": "" if aufrufe else _text(j)[:160]} + + +def messe_bild(basis: str, modell: str, rolle: str, frist: float | None = None) -> dict: + url = bild_data_url() + j = chat(basis, modell, [{"role": "user", "content": [ + {"type": "image_url", "image_url": {"url": url}}, + {"type": "text", "text": "Beschreibe das Bild: Welche Formen in welchen Farben siehst du, und welcher Text " + "steht darin?"}]}], 600, think=False, frist=frist) + antwort = _text(j) + gefunden = bild_merkmale(antwort) + try: + ablauf = _bild_im_ablauf(basis, modell, rolle, url, frist) + except Zeitende: + raise + except Exception as e: + ablauf = {"ok": False, "fehler": str(e)[:160]} + return {"direkt": round(len(gefunden) / len(BILD_MERKMALE), 2), "gefunden": gefunden, + "agentisch": bool(ablauf.get("ok")), "ablauf": ablauf, "antwort": antwort[:300]} + + +# --- Gesamtprüfung --------------------------------------------------------------------- + +def pruefe(rolle: str, basis: str, modell: str, *, bild: bool = False, frist: float | None = None, + protokoll=log) -> dict: + """Alle Proben der Rolle gegen ein laufendes Modell (Kandidat auf :5899 oder Baseline über llama-swap).""" + if rolle not in ALIAS: + raise ValueError(f"Unbekannte Rolle {rolle!r}") + t0 = time.time() + werte: dict = {"rolle": rolle, "modell": modell, + "zeitpunkt": time.strftime("%Y-%m-%dT%H:%M:%S%z")} + werte.update(messe_tempo(basis, modell, frist)) + protokoll(f" kurz : {werte['kurz']}") + protokoll(f" 13k : {werte['tiefe']}") + werte["werkzeuge"] = messe_werkzeuge(basis, modell, rolle, frist) + protokoll(f" werkzeuge: {werte['werkzeuge']['ok']}/{werte['werkzeuge']['von']}") + if rolle == "hirn": + werte.update(messe_sprache(basis, modell, frist)) + protokoll(f" deutsch: {'ja' if werte['deutsch']['ok'] else 'nein'} json: {'ja' if werte['json']['ok'] else 'nein'}") + else: + werte["code"] = messe_code(basis, modell, frist) + protokoll(f" code : {werte['code']['ok']}/{werte['code']['von']} in {werte['code']['sekunden']} s") + werte["bild"] = None + if bild: + try: + werte["bild"] = messe_bild(basis, modell, rolle, frist) + except Zeitende: + raise + except Exception as e: + werte["bild"] = {"direkt": 0.0, "gefunden": [], "agentisch": False, "fehler": str(e)[:160]} + protokoll(f" bild : {werte['bild'].get('direkt')} direkt, im Ablauf " + f"{'ja' if werte['bild'].get('agentisch') else 'nein'}") + werte["dauer_s"] = round(time.time() - t0) + return werte + + +# --- Kandidaten-Server ------------------------------------------------------------------- + +class Server: + """Ein laufender Kandidaten-Server (llama-server auf PORT).""" + + def __init__(self, prozess: subprocess.Popen, befehl: list[str], log_pfad: str): + self.prozess, self.befehl, self.log_pfad = prozess, befehl, log_pfad + self.ladezeit = 0 + + +_LAUFENDE: list[Server] = [] + + +def draft_flags(pfad: str | None = None, typ: str | None = None, n_max: int | None = None) -> list[str]: + """Spekulatives Dekodieren: Typ (draft-dflash, draft-mtp, draft-simple …) plus Entwurfsmodell. + Ein MTP-Kopf im Modell selbst braucht nur den Typ.""" + if not typ: + return [] + flags = ["--spec-type", typ] + if pfad: + flags += ["--spec-draft-model", pfad] + if n_max: + flags += ["--spec-draft-n-max", str(n_max)] + return flags + + +def server_befehl(gguf: str, *, mmproj: str | None = None, ctx: int = CTX_STANDARD, flags=(), + binary: str | None = None) -> list[str]: + befehl = [binary or BIN, "-m", gguf, "--host", "127.0.0.1", "--port", str(PORT), "-c", str(ctx), *BASIS_FLAGS] + if mmproj: + befehl += ["--mmproj", mmproj] + return befehl + [str(f) for f in flags] + + +def port_belegt(port: int = PORT) -> bool: + try: + with socket.create_connection(("127.0.0.1", port), timeout=1): + return True + except OSError: + return False + + +def _gesund() -> bool: + try: + with urllib.request.urlopen(f"{KANDIDAT_URL}/health", timeout=3) as antwort: + return antwort.status == 200 and b"ok" in antwort.read() + except Exception: + return False + + +def log_ende(pfad: str, zeichen: int = 400) -> str: + try: + return Path(pfad).read_text(encoding="utf-8", errors="replace")[-zeichen:].strip() + except OSError: + return "" + + +def _signal(prozess: subprocess.Popen, hart: bool) -> None: + try: + if os.name == "posix": # ganze Prozessgruppe (start_new_session), falls llama-server Kinder hat + os.killpg(prozess.pid, signal.SIGKILL if hart else signal.SIGTERM) + elif hart: + prozess.kill() + else: + prozess.terminate() + except OSError: + pass + + +def stoppe_server(server: Server, warte_s: float = 60) -> None: + p = server.prozess + if p.poll() is None: + _signal(p, hart=False) + try: + p.wait(timeout=warte_s) + except subprocess.TimeoutExpired: + _signal(p, hart=True) + try: + p.wait(timeout=15) + except subprocess.TimeoutExpired: + pass + if server in _LAUFENDE: + _LAUFENDE.remove(server) + + +def stoppe_alle(warte_s: float = 20) -> None: + """Alle Kandidaten-Server dieses Prozesses stoppen (Notbremse, Programmende).""" + for server in _LAUFENDE.copy(): # Kopie: stoppe_server nimmt den Server aus der Liste + stoppe_server(server, warte_s) + + +atexit.register(stoppe_alle) + + +def starte_server(gguf: str, *, mmproj: str | None = None, ctx: int = CTX_STANDARD, flags=(), + frist: float | None = None, ladezeit_max: float = LADEZEIT_MAX_S, protokoll=log) -> Server: + """Kandidat standalone starten und warten, bis /health „ok“ meldet.""" + if not os.path.exists(gguf): + raise ServerFehler(f"Modelldatei fehlt: {gguf}") + if mmproj and not os.path.exists(mmproj): + raise ServerFehler(f"mmproj fehlt: {mmproj}") + if port_belegt(): + raise ServerFehler(f"Port {PORT} ist belegt – läuft noch ein anderer Prüfstand?") + befehl = server_befehl(gguf, mmproj=mmproj, ctx=ctx, flags=flags) + umgebung = dict(os.environ) + umgebung["LD_LIBRARY_PATH"] = os.pathsep.join(p for p in (LIB_DIR, umgebung.get("LD_LIBRARY_PATH")) if p) + protokoll(" starte: " + " ".join(befehl)) + with open(SERVER_LOG, "w", encoding="utf-8") as logdatei: + prozess = subprocess.Popen(befehl, stdout=logdatei, stderr=subprocess.STDOUT, stdin=subprocess.DEVNULL, + env=umgebung, start_new_session=(os.name == "posix")) + server = Server(prozess, befehl, SERVER_LOG) + _LAUFENDE.append(server) + t0 = time.time() + try: + while True: + if prozess.poll() is not None: + raise ServerFehler(f"Absturz beim Laden (Code {prozess.returncode}): {log_ende(SERVER_LOG, 300)}") + if _gesund(): + server.ladezeit = round(time.time() - t0) + protokoll(f" geladen in {server.ladezeit} s") + return server + if time.time() - t0 > ladezeit_max: + raise ServerFehler(f"Nach {ladezeit_max:.0f} s noch nicht geladen: {log_ende(SERVER_LOG, 200)}") + if frist is not None and time.time() > frist - 5: + raise Zeitende("Frist erreicht, während der Kandidat noch lud.") + time.sleep(2) + except BaseException: + stoppe_server(server) + raise + + +def pruefe_kandidat(rolle: str, gguf: str, *, mmproj: str | None = None, flags=(), ctx: int = CTX_STANDARD, + basis: dict | None = None, frist: float | None = None, protokoll=log) -> dict: + """Ganzer Durchlauf eines Kandidaten: Server starten → messen → stoppen → urteilen. + basis = Werte der Baseline (ohne sie gibt es kein Urteil, ergebnis None). + Rückgabe: {"werte", "ergebnis", "vergleich", "zusammenfassung"}.""" + server = starte_server(gguf, mmproj=mmproj, ctx=ctx, flags=flags, frist=frist, protokoll=protokoll) + + def absturz() -> str: + return f"Während des Tests abgestürzt (Code {server.prozess.returncode}): {log_ende(SERVER_LOG, 300)}" + + try: + werte = pruefe(rolle, KANDIDAT_URL, "kandidat", bild=bool(mmproj), frist=frist, protokoll=protokoll) + except Exception as e: + if not isinstance(e, Zeitende) and server.prozess.poll() is not None: + raise ServerFehler(absturz()) from e + raise + else: + # Einzelproben fangen Fehler ab — ein toter Server darf nicht wie ein schlechtes Modell aussehen. + if server.prozess.poll() is not None: + raise ServerFehler(absturz()) + finally: + stoppe_server(server) + time.sleep(3) # Speicher freigeben lassen, bevor jemand anderes lädt + werte.update(ladezeit_s=server.ladezeit, ctx=ctx, befehl=" ".join(server.befehl)) + if not basis: + return {"werte": werte, "ergebnis": None, "vergleich": {}, + "zusammenfassung": "Gemessen, aber ohne Vergleichswerte des heutigen Modells."} + return {"werte": werte, **urteil(rolle, werte, basis)} + + +# --- Baseline ------------------------------------------------------------------------ + +def _lies_json(pfad: str) -> dict: + try: + daten = json.loads(Path(pfad).read_text(encoding="utf-8")) + return daten if isinstance(daten, dict) else {} + except (OSError, ValueError): + return {} + + +def _schreibe_json(pfad: str, daten: dict) -> None: + try: + tmp = Path(pfad).with_suffix(".tmp") + tmp.write_text(json.dumps(daten, ensure_ascii=False, indent=1), encoding="utf-8") + tmp.replace(pfad) + except OSError as e: + log(f" Baseline-Cache nicht schreibbar ({pfad}): {e}") + + +def baseline(rolle: str, cache_pfad: str, *, kennung: str, bild: bool = False, frist: float | None = None, + max_alter_tage: int = 30, basis_url: str = SWAP_URL, modell: str | None = None, + protokoll=log) -> dict | None: + """Werte des heutigen Modells der Rolle, höchstens alle max_alter_tage neu gemessen. + kennung = welches Modell mit welchen Flags (ändert sie sich, wird neu gemessen). + Rückgabe {"kennung", "zeit", "werte"} oder None, wenn es weder Cache noch Messung gibt.""" + cache = _lies_json(cache_pfad) + eintrag = cache.get(rolle) if isinstance(cache.get(rolle), dict) else None + passend = eintrag if eintrag and eintrag.get("kennung") == kennung else None + if passend and time.time() - float(passend.get("zeit") or 0) < max_alter_tage * 86400: + return passend + protokoll(f" Baseline {rolle} wird neu gemessen ({modell or ALIAS[rolle]} über llama-swap)") + try: + werte = pruefe(rolle, basis_url, modell or ALIAS[rolle], bild=bild, frist=frist, protokoll=protokoll) + except Zeitende: + raise + except Exception as e: + protokoll(f" Baseline {rolle} nicht messbar: {e}") + return passend # lieber einen Monat alt als gar nicht vergleichen + neu = {"kennung": kennung, "zeit": time.time(), "werte": werte} + cache[rolle] = neu + _schreibe_json(cache_pfad, cache) + return neu + + +# --- Urteil -------------------------------------------------------------------------- + +def _zahl(wert) -> str: + if wert is None: + return "–" + if isinstance(wert, float) and wert % 1: + return f"{wert:.1f}".replace(".", ",") + return f"{wert:.0f}" + + +def _prozent(faktor: float) -> str: + return f"{(faktor - 1) * 100:+.0f} %".replace("-", "−") + + +def _anteil(wert: dict | None) -> float: + return (wert.get("ok", 0) / wert["von"]) if wert and wert.get("von") else 0.0 + + +def bild_kann(bild: dict | None) -> bool: + return bool(bild) and float(bild.get("direkt") or 0) >= BILD_MIN and bool(bild.get("agentisch")) + + +def _bild_text(bild: dict | None) -> str: + if not bild: + return "kein mmproj" + return (f"{len(bild.get('gefunden') or [])}/{len(BILD_MERKMALE)} Merkmale, im Ablauf " + f"{'ja' if bild.get('agentisch') else 'nein'}") + + +def urteil(rolle: str, k: dict, b: dict) -> dict: + """Kandidat k gegen Baseline b (jeweils die Werte aus pruefe()). + bestanden = keine Pflicht verfehlt UND mindestens ein Vorteil. Pflicht: Tempo nicht deutlich + schlechter, Werkzeuge (und beim Coder der Code) nicht schlechter, Deutsch/JSON (Hirn), Bilder.""" + b = b.get("werte", b) # auch ein ganzer Baseline-Eintrag ist recht + r = REGELN[rolle] + zeilen: dict[str, dict] = {} # Messwert → Kandidat/Baseline/Einheit/Urteil, in Anzeige-Reihenfolge + maengel, vorteile = [], [] + + def zeile(name: str, kw, bw, einheit: str, bewertung: str) -> None: + zeilen[name] = {"kandidat": kw, "baseline": bw, "einheit": einheit, "urteil": bewertung} + + kt, bt = k.get("tiefe") or {}, b.get("tiefe") or {} + # Decode in t/s (mehr ist besser), Prefill als Zeit in s (weniger ist besser, Faktor = Tempo). + kd, bd = kt.get("tg_tps"), bt.get("tg_tps") + kp, bp = kt.get("pp_s"), bt.get("pp_s") + for name, kw, bw, einheit, faktor, pmin, pplus in ( + ("Decode bei 13k", kd, bd, "t/s", (kd / bd) if kd and bd else None, r["decode_min"], r["decode_plus"]), + ("Prefill bei 13k", kp, bp, "s", (bp / kp) if kp and bp else None, r["prefill_min"], r["prefill_plus"])): + if not kw: + maengel.append(f"{name} nicht messbar") + zeile(name, kw, bw, einheit, "schlechter") + elif faktor is None: + zeile(name, kw, bw, einheit, "unbekannt") + elif faktor < pmin: + maengel.append(f"{name} {_zahl(kw)} statt {_zahl(bw)} {einheit} (Tempo {_prozent(faktor)})") + zeile(name, kw, bw, einheit, "schlechter") + elif faktor >= pplus: + vorteile.append(f"{name} {_prozent(faktor)} schneller".replace("+", "")) + zeile(name, kw, bw, einheit, "besser") + else: + zeile(name, kw, bw, einheit, "gleich") + + kw_, bw_ = k.get("werkzeuge") or {}, b.get("werkzeuge") or {} + ka, ba = _anteil(kw_), _anteil(bw_) + ktext, btext = f"{kw_.get('ok', 0)}/{kw_.get('von', 0)}", f"{bw_.get('ok', 0)}/{bw_.get('von', 0)}" + if ka + 1e-9 < ba or ka < WERKZEUG_BODEN: + maengel.append(f"Werkzeuge {ktext} (heute {btext})") + zeile("Werkzeug-Aufrufe", ktext, btext, "", "schlechter") + elif ka > ba + 1e-9: + vorteile.append(f"Werkzeuge {ktext} statt {btext}") + zeile("Werkzeug-Aufrufe", ktext, btext, "", "besser") + else: + zeile("Werkzeug-Aufrufe", ktext, btext, "", "gleich") + + if rolle == "hirn": + for schluessel, name in (("deutsch", "Deutsch"), ("json", "JSON")): + ko, bo = bool((k.get(schluessel) or {}).get("ok")), bool((b.get(schluessel) or {}).get("ok")) + if not ko: + maengel.append(f"{name}-Probe nicht bestanden") + zeile(name, "ja" if ko else "nein", "ja" if bo else "nein", "", + "gleich" if ko == bo else ("besser" if ko else "schlechter")) + else: + kc, bc = k.get("code") or {}, b.get("code") or {} + ktext, btext = f"{kc.get('ok', 0)}/{kc.get('von', 0)}", f"{bc.get('ok', 0)}/{bc.get('von', 0)}" + if kc.get("ok", 0) < bc.get("ok", 0): + maengel.append(f"Programmieraufgaben {ktext} (heute {btext})") + zeile("Programmieraufgaben", ktext, btext, "", "schlechter") + elif kc.get("ok", 0) > bc.get("ok", 0): + vorteile.append(f"Programmieraufgaben {ktext} statt {btext}") + zeile("Programmieraufgaben", ktext, btext, "", "besser") + else: + zeile("Programmieraufgaben", ktext, btext, "", "gleich") + + kb, bb = k.get("bild"), b.get("bild") + kann_k, kann_b = bild_kann(kb), bild_kann(bb) + if not kann_k and (BILD_PFLICHT or kann_b): + maengel.append("versteht keine Bilder" if not kb else f"Bild-Probe nicht bestanden ({_bild_text(kb)})") + zeile("Bilder", _bild_text(kb), _bild_text(bb), "", "schlechter") + elif kann_k and not kann_b: + vorteile.append("versteht Bilder (heute nicht)") + zeile("Bilder", _bild_text(kb), _bild_text(bb), "", "besser") + else: + zeile("Bilder", _bild_text(kb), _bild_text(bb), "", "gleich") + + if maengel: + ergebnis, satz = "durchgefallen", "Durchgefallen: " + "; ".join(maengel) + "." + elif not vorteile: + ergebnis, satz = "durchgefallen", "Durchgefallen: kein Vorteil gegenüber dem heutigen Modell." + else: + ergebnis, satz = "bestanden", "Bestanden: " + "; ".join(vorteile) + "." + return {"ergebnis": ergebnis, "vergleich": zeilen, "zusammenfassung": satz, + "maengel": maengel, "vorteile": vorteile} + + +# --- Hermes-Smoke (nur für den Handbetrieb, pruefstand-hirn.py) --------------------------------- + +def hermes_smoke(hermes_args: list[str], protokoll=log) -> list[dict]: + """Zwei Aufgaben durch den ECHTEN Hermes-Agenten (Provider `pruefstand` -> :5899 muss in + `providers:` der Hermes-Config stehen).""" + ergebnisse = [] + for frage, erwartet in ((("Führe im Terminal exakt den Befehl echo pruefstand-ok aus und gib mir nur dessen " + "Ausgabe zurück."), "pruefstand-ok"), + ("Welche Verzeichnisse liegen direkt unter /srv/models? Nenne mir drei davon.", "GGUF")): + t0 = time.time() + try: + p = subprocess.run([HERMES, "chat", *hermes_args, "-Q", "--oneshot", "--max-turns", "6", "-q", frage], + capture_output=True, text=True, timeout=900) + ausgabe = (p.stdout + p.stderr)[-600:] + except subprocess.TimeoutExpired: + ausgabe = "TIMEOUT" + except OSError as e: + ausgabe = f"FEHLER {e}" + ok = erwartet.lower() in ausgabe.lower() + ergebnisse.append({"ok": ok, "s": round(time.time() - t0), "tail": ausgabe[-160:].replace("\n", " ")}) + protokoll(f" hermes: {'ok' if ok else 'FEHLT'} {round(time.time() - t0)} s {ausgabe[-120:].replace(chr(10), ' ')!r}") + return ergebnisse diff --git a/deploy/deploy.sh b/deploy/deploy.sh index ab2073b..f6fe0be 100644 --- a/deploy/deploy.sh +++ b/deploy/deploy.sh @@ -48,7 +48,11 @@ main() { fi # 4. Systemd Units neu laden (falls sich .service Dateien geändert haben) + # Das Modell-Radar (09/2026) ist die erste Unit, die deploy.sh selbst einspielt: Sie gehört ganz dem + # Repo, auf der Box wird an ihr nichts von Hand gedreht. Die übrigen Units bleiben wie bisher Handarbeit. + install -m 644 deploy/mc2-radar.service deploy/mc2-radar.timer "$HOME/.config/systemd/user/" systemctl --user daemon-reload + systemctl --user enable --now mc2-radar.timer # 4.5 Hermes Skills synchronisieren echo "Synchronisiere Hermes Skills..." diff --git a/deploy/mc2-radar.service b/deploy/mc2-radar.service new file mode 100644 index 0000000..c5d8318 --- /dev/null +++ b/deploy/mc2-radar.service @@ -0,0 +1,28 @@ +# systemd-USER-Unit für das Modell-Radar (Box-Wart, 09/2026) — gestartet von mc2-radar.timer um 00:30. +# Sucht höchstens einmal am Tag nach neuen Modellen für Hirn und Coder und testet nachts im Fenster +# 00:30–02:30 höchstens einen neuen Kandidaten pro Woche (backend/radar_lauf.py, services/radar.py). +# Um 03:00 braucht der NerdQuiz-Nachtlauf das Hirn: Der Lauf hört um 02:30 selbst auf, um 02:35 zieht +# seine Notbremse, und RuntimeMaxSec beendet ihn spätestens 02:40 samt llama-server (control-group). +# Type=simple statt oneshot: Bei oneshot greift RuntimeMaxSec nicht. +# Sudo-frei wie alle MC2-Units: ~/.config/systemd/user/ + systemctl --user. +# Ablage: ~/.config/systemd/user/mc2-radar.service (+ mc2-radar.timer) ; dann: +# systemctl --user daemon-reload && systemctl --user enable --now mc2-radar.timer + +[Unit] +Description=MC2 Modell-Radar (Suche + nächtlicher Prüfstand 00:30–02:30) +After=network-online.target +Wants=network-online.target + +[Service] +Type=simple +WorkingDirectory=%h/mission-control-v2/backend +ExecStart=%h/mission-control-v2/backend/.venv/bin/python radar_lauf.py +Environment=PYTHONPATH=%h/mission-control-v2 +Environment=MC_LLAMA_SWAP_URL=http://127.0.0.1:8080 +Environment=MC_CONFIG_PATH=/etc/llama-swap/config.yaml +Environment=MC_MODELS_DIR=/srv/models +Environment=MC_LOCAL_TZ=Europe/Berlin +# Kein Nice=: der Kandidaten-Server erbt die Priorität — gemessen wird gegen das Live-Modell. +RuntimeMaxSec=2h10min +KillMode=control-group +TimeoutStopSec=60 diff --git a/deploy/mc2-radar.timer b/deploy/mc2-radar.timer new file mode 100644 index 0000000..4b2eaa5 --- /dev/null +++ b/deploy/mc2-radar.timer @@ -0,0 +1,10 @@ +[Unit] +Description=Nächtliches Modell-Radar (00:30, Test-Fenster bis 02:30) + +[Timer] +OnCalendar=*-*-* 00:30:00 +Persistent=true +AccuracySec=1min + +[Install] +WantedBy=timers.target diff --git a/deploy/radar-watchlist.json b/deploy/radar-watchlist.json new file mode 100644 index 0000000..110ca0d --- /dev/null +++ b/deploy/radar-watchlist.json @@ -0,0 +1,27 @@ +{ + "_hinweis": "Merkliste des Modell-Radars (backend/services/radar.py). Einträge hier werden vor den Funden der Hugging-Face-Entdeckung getestet, in dieser Reihenfolge. Felder: name, rolle (hirn|coder), repo, quant (Standard Q4_K_M), eng (true = passt nur knapp neben das Warm-Set), notiz (erscheint in der Begründung), ueberspringen (Grund; Eintrag wird nicht getestet), optional draft {repo, datei, typ, n_max} und flags (zusätzliche llama-server-Flags). Getestet wird nur, was ein mmproj hat und neben das Warm-Set passt (27 GB + Kandidat inkl. KV-Cache <= 115 GB).", + "kandidaten": [ + { + "name": "Ornith-1.5-35B-A3B", + "rolle": "hirn", + "repo": "ornith-ai/Ornith-1.5-35B-A3B-GGUF", + "quant": "Q4_K_M", + "notiz": "MoE mit 3B aktiven Parametern (Architektur qwen35moe), mmproj im Repo." + }, + { + "name": "Qwen3.8-Flash-Next", + "rolle": "coder", + "repo": "unsloth/Qwen3.8-Flash-Next-GGUF", + "quant": "UD-IQ3_XXS", + "eng": true, + "notiz": "UD-IQ3_XXS ist ca. 82 GB groß und passt nur knapp neben das Warm-Set (UD-IQ4_XS mit 94 GB passt nicht)." + }, + { + "name": "K2-Horizon-MoVA-36B-A4B", + "rolle": "hirn", + "repo": "IFM/K2-Horizon-MoVA-36B-A4B-GGUF", + "quant": "Q4_K_M", + "ueberspringen": "läuft noch nicht im offiziellen llama.cpp." + } + ] +} diff --git a/frontend/dist/assets/Bestaetigen-VrcNpcBb.js b/frontend/dist/assets/Bestaetigen-VrcNpcBb.js new file mode 100644 index 0000000..a07f376 --- /dev/null +++ b/frontend/dist/assets/Bestaetigen-VrcNpcBb.js @@ -0,0 +1 @@ +import{a as e,c as t,i as n,s as r,t as i,u as a}from"./button-Dd8hfusv.js";import{a as o,i as s,n as c,o as l,r as u,s as d,t as f}from"./dist-CgRgLCFz.js";var p=r();a();var m=t();function h(e){let t=(0,p.c)(4),n;t[0]===e?n=t[1]:({...n}=e,t[0]=e,t[1]=n);let r;return t[2]===n?r=t[3]:(r=(0,m.jsx)(f,{"data-slot":`dialog`,...n}),t[2]=n,t[3]=r),r}function g(e){let t=(0,p.c)(4),n;t[0]===e?n=t[1]:({...n}=e,t[0]=e,t[1]=n);let r;return t[2]===n?r=t[3]:(r=(0,m.jsx)(l,{"data-slot":`dialog-portal`,...n}),t[2]=n,t[3]=r),r}function _(e){let t=(0,p.c)(8),r,i;t[0]===e?(r=t[1],i=t[2]):({className:r,...i}=e,t[0]=e,t[1]=r,t[2]=i);let a;t[3]===r?a=t[4]:(a=n(`fixed inset-0 isolate z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0`,r),t[3]=r,t[4]=a);let s;return t[5]!==i||t[6]!==a?(s=(0,m.jsx)(o,{"data-slot":`dialog-overlay`,className:a,...i}),t[5]=i,t[6]=a,t[7]=s):s=t[7],s}function v(t){let r=(0,p.c)(15),a,o,s,l;r[0]===t?(a=r[1],o=r[2],s=r[3],l=r[4]):({className:o,children:a,showCloseButton:l,...s}=t,r[0]=t,r[1]=a,r[2]=o,r[3]=s,r[4]=l);let d=l===void 0||l,f;r[5]===Symbol.for(`react.memo_cache_sentinel`)?(f=(0,m.jsx)(_,{}),r[5]=f):f=r[5];let h;r[6]===o?h=r[7]:(h=n(`fixed top-1/2 left-1/2 z-50 grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl bg-popover p-4 text-sm text-popover-foreground ring-1 ring-foreground/10 duration-100 outline-none sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95`,o),r[6]=o,r[7]=h);let v;r[8]===d?v=r[9]:(v=d&&(0,m.jsx)(c,{"data-slot":`dialog-close`,asChild:!0,children:(0,m.jsxs)(i,{variant:`ghost`,className:`absolute top-2 right-2`,size:`icon-sm`,children:[(0,m.jsx)(e,{}),(0,m.jsx)(`span`,{className:`sr-only`,children:`Schließen`})]})}),r[8]=d,r[9]=v);let y;return r[10]!==a||r[11]!==s||r[12]!==h||r[13]!==v?(y=(0,m.jsxs)(g,{children:[f,(0,m.jsxs)(u,{"data-slot":`dialog-content`,className:h,...s,children:[a,v]})]}),r[10]=a,r[11]=s,r[12]=h,r[13]=v,r[14]=y):y=r[14],y}function y(e){let t=(0,p.c)(8),r,i;t[0]===e?(r=t[1],i=t[2]):({className:r,...i}=e,t[0]=e,t[1]=r,t[2]=i);let a;t[3]===r?a=t[4]:(a=n(`flex flex-col gap-2`,r),t[3]=r,t[4]=a);let o;return t[5]!==i||t[6]!==a?(o=(0,m.jsx)(`div`,{"data-slot":`dialog-header`,className:a,...i}),t[5]=i,t[6]=a,t[7]=o):o=t[7],o}function b(e){let t=(0,p.c)(14),r,a,o,s;t[0]===e?(r=t[1],a=t[2],o=t[3],s=t[4]):({className:a,showCloseButton:s,children:r,...o}=e,t[0]=e,t[1]=r,t[2]=a,t[3]=o,t[4]=s);let l=s!==void 0&&s,u;t[5]===a?u=t[6]:(u=n(`-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t bg-muted/50 p-4 sm:flex-row sm:justify-end`,a),t[5]=a,t[6]=u);let d;t[7]===l?d=t[8]:(d=l&&(0,m.jsx)(c,{asChild:!0,children:(0,m.jsx)(i,{variant:`outline`,children:`Schließen`})}),t[7]=l,t[8]=d);let f;return t[9]!==r||t[10]!==o||t[11]!==u||t[12]!==d?(f=(0,m.jsxs)(`div`,{"data-slot":`dialog-footer`,className:u,...o,children:[r,d]}),t[9]=r,t[10]=o,t[11]=u,t[12]=d,t[13]=f):f=t[13],f}function x(e){let t=(0,p.c)(8),r,i;t[0]===e?(r=t[1],i=t[2]):({className:r,...i}=e,t[0]=e,t[1]=r,t[2]=i);let a;t[3]===r?a=t[4]:(a=n(`font-heading text-base leading-none font-medium`,r),t[3]=r,t[4]=a);let o;return t[5]!==i||t[6]!==a?(o=(0,m.jsx)(d,{"data-slot":`dialog-title`,className:a,...i}),t[5]=i,t[6]=a,t[7]=o):o=t[7],o}function S(e){let t=(0,p.c)(8),r,i;t[0]===e?(r=t[1],i=t[2]):({className:r,...i}=e,t[0]=e,t[1]=r,t[2]=i);let a;t[3]===r?a=t[4]:(a=n(`text-sm text-muted-foreground *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground`,r),t[3]=r,t[4]=a);let o;return t[5]!==i||t[6]!==a?(o=(0,m.jsx)(s,{"data-slot":`dialog-description`,className:a,...i}),t[5]=i,t[6]=a,t[7]=o):o=t[7],o}function C(e){let t=(0,p.c)(26),{offen:n,titel:r,text:a,knopf:o,gefahr:s,onJa:c,onNein:l,children:u}=e,d;t[0]===l?d=t[1]:(d=e=>!e&&l(),t[0]=l,t[1]=d);let f;t[2]===r?f=t[3]:(f=(0,m.jsx)(x,{className:`schild text-xl`,children:r}),t[2]=r,t[3]=f);let g;t[4]===a?g=t[5]:(g=(0,m.jsx)(S,{className:`text-[15px] leading-relaxed text-text-2`,children:a}),t[4]=a,t[5]=g);let _;t[6]!==f||t[7]!==g?(_=(0,m.jsxs)(y,{children:[f,g]}),t[6]=f,t[7]=g,t[8]=_):_=t[8];let C;t[9]===l?C=t[10]:(C=(0,m.jsx)(i,{variant:`outline`,onClick:l,children:`Abbrechen`}),t[9]=l,t[10]=C);let w=s?`gefahr`:`default`,T;t[11]!==o||t[12]!==c||t[13]!==w?(T=(0,m.jsx)(i,{variant:w,onClick:c,children:o}),t[11]=o,t[12]=c,t[13]=w,t[14]=T):T=t[14];let E;t[15]!==C||t[16]!==T?(E=(0,m.jsxs)(b,{className:`gap-2 sm:gap-2`,children:[C,T]}),t[15]=C,t[16]=T,t[17]=E):E=t[17];let D;t[18]!==u||t[19]!==_||t[20]!==E?(D=(0,m.jsxs)(v,{className:`border-linie bg-panel sm:max-w-lg`,children:[_,u,E]}),t[18]=u,t[19]=_,t[20]=E,t[21]=D):D=t[21];let O;return t[22]!==n||t[23]!==d||t[24]!==D?(O=(0,m.jsx)(h,{open:n,onOpenChange:d,children:D}),t[22]=n,t[23]=d,t[24]=D,t[25]=O):O=t[25],O}export{C as t}; \ No newline at end of file diff --git a/frontend/dist/assets/Dienste-QEbMZv2T.js b/frontend/dist/assets/Dienste-DEn0Zjkq.js similarity index 85% rename from frontend/dist/assets/Dienste-QEbMZv2T.js rename to frontend/dist/assets/Dienste-DEn0Zjkq.js index 8a6b175..0704260 100644 --- a/frontend/dist/assets/Dienste-QEbMZv2T.js +++ b/frontend/dist/assets/Dienste-DEn0Zjkq.js @@ -1 +1 @@ -import{c as e,f as t,i as n,t as r,u as i}from"./button-Dd8hfusv.js";import{F as a,O as o,_ as s,k as c,u as l}from"./index-B6MevgIX.js";import{a as u,i as d,n as f,r as p,t as m}from"./sheet-DWG2Q04V.js";var h=t(i(),1),g=e();function _({offen:e,onSchliessen:t}){let i=a(),_=l(),[v,y]=(0,h.useState)(null),[b,x]=(0,h.useState)(null),S=s(v);async function C(e){x(null);try{let t=await o(`/api/maintenance/restart`,{service:e});t.ok?c(`erfolg`,`${e} startet neu.`):c(`fehler`,t.err||`${e} ließ sich nicht neu starten.`),i.invalidateQueries({queryKey:[`dienste`]})}catch(e){c(`fehler`,e.message)}}return(0,g.jsx)(m,{open:e,onOpenChange:e=>!e&&t(),children:(0,g.jsxs)(f,{side:`right`,className:`w-full gap-3 overflow-y-auto border-linie bg-panel sm:max-w-2xl`,children:[(0,g.jsxs)(d,{children:[(0,g.jsx)(u,{className:`schild text-lg`,children:`Dienste und Protokolle`}),(0,g.jsx)(p,{className:`text-text-2`,children:`Welcher Dienst läuft, was er zuletzt geschrieben hat.`})]}),(0,g.jsx)(`ul`,{className:`m-0 flex list-none flex-col px-4 pb-2`,children:(_.data?.services??[]).map(e=>(0,g.jsxs)(`li`,{className:`flex flex-wrap items-center justify-between gap-2 border-t border-linie py-2.5`,children:[(0,g.jsxs)(`span`,{className:`flex min-w-0 items-center gap-2.5`,children:[(0,g.jsx)(`span`,{className:n(`size-2.5 shrink-0 rounded-full`,e.ok?`bg-gruen`:`bg-rot`),"aria-hidden":!0}),(0,g.jsxs)(`span`,{className:`min-w-0`,children:[(0,g.jsx)(`span`,{className:`block text-[15px]`,children:e.name}),(0,g.jsxs)(`span`,{className:`ziffern text-xs text-text-3`,children:[e.unit,` · `,e.ok?`läuft`:`antwortet nicht`]})]})]}),(0,g.jsxs)(`span`,{className:`flex gap-2`,children:[(0,g.jsx)(r,{variant:v===e.unit?`info`:`ghost`,size:`sm`,onClick:()=>y(e.unit),children:`Protokoll`}),b===e.unit?(0,g.jsx)(r,{variant:`gefahr`,size:`sm`,onClick:()=>C(e.unit),children:`Wirklich neu starten?`}):(0,g.jsx)(r,{variant:`outline`,size:`sm`,onClick:()=>x(e.unit),children:`Neu starten`})]})]},e.unit))}),v&&(0,g.jsx)(`pre`,{className:`ziffern mx-4 mb-4 max-h-[50vh] overflow-auto rounded-lg border border-linie bg-[#0b0d0f] p-3 text-xs leading-relaxed whitespace-pre-wrap text-text-2`,children:S.isFetching?`Wird gelesen …`:S.data?.text||S.data?.err||`Kein Protokoll.`})]})})}export{_ as Dienste}; \ No newline at end of file +import{c as e,f as t,i as n,t as r,u as i}from"./button-Dd8hfusv.js";import{A as a,L as o,f as s,j as c,y as l}from"./index-ZVRs0IGR.js";import{a as u,i as d,n as f,r as p,t as m}from"./sheet-DWG2Q04V.js";var h=t(i(),1),g=e();function _({offen:e,onSchliessen:t}){let i=o(),_=s(),[v,y]=(0,h.useState)(null),[b,x]=(0,h.useState)(null),S=l(v);async function C(e){x(null);try{let t=await a(`/api/maintenance/restart`,{service:e});t.ok?c(`erfolg`,`${e} startet neu.`):c(`fehler`,t.err||`${e} ließ sich nicht neu starten.`),i.invalidateQueries({queryKey:[`dienste`]})}catch(e){c(`fehler`,e.message)}}return(0,g.jsx)(m,{open:e,onOpenChange:e=>!e&&t(),children:(0,g.jsxs)(f,{side:`right`,className:`w-full gap-3 overflow-y-auto border-linie bg-panel sm:max-w-2xl`,children:[(0,g.jsxs)(d,{children:[(0,g.jsx)(u,{className:`schild text-lg`,children:`Dienste und Protokolle`}),(0,g.jsx)(p,{className:`text-text-2`,children:`Welcher Dienst läuft, was er zuletzt geschrieben hat.`})]}),(0,g.jsx)(`ul`,{className:`m-0 flex list-none flex-col px-4 pb-2`,children:(_.data?.services??[]).map(e=>(0,g.jsxs)(`li`,{className:`flex flex-wrap items-center justify-between gap-2 border-t border-linie py-2.5`,children:[(0,g.jsxs)(`span`,{className:`flex min-w-0 items-center gap-2.5`,children:[(0,g.jsx)(`span`,{className:n(`size-2.5 shrink-0 rounded-full`,e.ok?`bg-gruen`:`bg-rot`),"aria-hidden":!0}),(0,g.jsxs)(`span`,{className:`min-w-0`,children:[(0,g.jsx)(`span`,{className:`block text-[15px]`,children:e.name}),(0,g.jsxs)(`span`,{className:`ziffern text-xs text-text-3`,children:[e.unit,` · `,e.ok?`läuft`:`antwortet nicht`]})]})]}),(0,g.jsxs)(`span`,{className:`flex gap-2`,children:[(0,g.jsx)(r,{variant:v===e.unit?`info`:`ghost`,size:`sm`,onClick:()=>y(e.unit),children:`Protokoll`}),b===e.unit?(0,g.jsx)(r,{variant:`gefahr`,size:`sm`,onClick:()=>C(e.unit),children:`Wirklich neu starten?`}):(0,g.jsx)(r,{variant:`outline`,size:`sm`,onClick:()=>x(e.unit),children:`Neu starten`})]})]},e.unit))}),v&&(0,g.jsx)(`pre`,{className:`ziffern mx-4 mb-4 max-h-[50vh] overflow-auto rounded-lg border border-linie bg-[#0b0d0f] p-3 text-xs leading-relaxed whitespace-pre-wrap text-text-2`,children:S.isFetching?`Wird gelesen …`:S.data?.text||S.data?.err||`Kein Protokoll.`})]})})}export{_ as Dienste}; \ No newline at end of file diff --git a/frontend/dist/assets/Einstellungen-DMWgWLUo.js b/frontend/dist/assets/Einstellungen-BwCmWl9x.js similarity index 86% rename from frontend/dist/assets/Einstellungen-DMWgWLUo.js rename to frontend/dist/assets/Einstellungen-BwCmWl9x.js index d0b2664..9089d16 100644 --- a/frontend/dist/assets/Einstellungen-DMWgWLUo.js +++ b/frontend/dist/assets/Einstellungen-BwCmWl9x.js @@ -1 +1 @@ -import{c as e,f as t,t as n,u as r}from"./button-Dd8hfusv.js";import{D as i,F as a,N as o,O as s,P as c,k as l}from"./index-B6MevgIX.js";import{a as u,i as d,n as f,r as p,t as m}from"./sheet-DWG2Q04V.js";var h=t(r(),1),g=e();function _({offen:e,onSchliessen:t}){let r=a(),_=c({queryKey:[`geheimnisse`],queryFn:()=>i(`/api/maintenance/geheimnisse`),enabled:e}),[v,y]=(0,h.useState)(``);async function b(e){try{await s(`/api/maintenance/geheimnisse`,{schluessel:`hf_token`,wert:e}),l(`erfolg`,e?`Hugging-Face-Zugang gespeichert.`:`Hugging-Face-Zugang gelöscht.`),y(``),r.invalidateQueries({queryKey:[`geheimnisse`]})}catch(e){l(`fehler`,e.message)}}let x=_.data;return(0,g.jsx)(m,{open:e,onOpenChange:e=>!e&&t(),children:(0,g.jsxs)(f,{side:`right`,className:`w-full gap-3 overflow-y-auto border-linie bg-panel sm:max-w-lg`,children:[(0,g.jsxs)(d,{children:[(0,g.jsx)(u,{className:`schild text-lg`,children:`Einstellungen`}),(0,g.jsx)(p,{className:`text-text-2`,children:`Was die Box sich merkt.`})]}),(0,g.jsxs)(`section`,{className:`flex flex-col gap-3 border-t border-linie px-4 pt-4`,children:[(0,g.jsx)(`h3`,{className:`schild text-sm text-text-3`,children:`Hugging-Face-Zugang`}),(0,g.jsxs)(`p`,{className:`text-sm text-text-2`,children:[x?.hf_token_gesetzt?`Ist hinterlegt.`:`Fehlt.`,` Nötig für gesperrte Modelle und schnellere Downloads.`,x?.hf_token_aus_env?` Er kommt aus der Dienst-Einstellung und lässt sich hier nicht löschen.`:``]}),(0,g.jsxs)(`form`,{className:`flex gap-2`,onSubmit:e=>{e.preventDefault(),v.trim()&&b(v.trim())},children:[(0,g.jsx)(`label`,{htmlFor:`hf-token`,className:`sr-only`,children:`Hugging-Face-Zugang`}),(0,g.jsx)(`input`,{id:`hf-token`,type:`password`,autoComplete:`off`,value:v,onChange:e=>y(e.target.value),placeholder:`hf_…`,className:`h-11 min-w-0 flex-1 rounded-lg border border-linie-stark bg-erhaben px-3 text-[15px] outline-none focus:border-cyan`}),(0,g.jsx)(n,{type:`submit`,disabled:!v.trim()||x?.schreibbar===!1,children:`Speichern`})]}),x?.hf_token_gesetzt&&!x.hf_token_aus_env&&(0,g.jsx)(n,{variant:`ghost`,size:`sm`,className:`self-start`,onClick:()=>b(null),children:`Zugang löschen`})]}),(0,g.jsxs)(`section`,{className:`flex flex-col gap-2 border-t border-linie px-4 pt-4`,children:[(0,g.jsx)(`h3`,{className:`schild text-sm text-text-3`,children:`Hinweise`}),(0,g.jsx)(`p`,{className:`text-sm text-text-2`,children:`Dringende Hinweise gehen zusätzlich per Telegram raus, alles andere bleibt hier. Einfache Probleme wie einen abgestürzten Dienst behebt der Wächter selbst und schreibt es in den Verlauf.`})]}),(0,g.jsxs)(`section`,{className:`flex flex-col gap-2 border-t border-linie px-4 pt-4 pb-4`,children:[(0,g.jsx)(`h3`,{className:`schild text-sm text-text-3`,children:`Hermes`}),(0,g.jsxs)(`a`,{href:`/hermes-ui/`,target:`_blank`,rel:`noopener`,className:`flex h-11 items-center gap-2 self-start rounded-lg border border-linie-stark bg-erhaben px-4 text-[15px] hover:border-text-3`,children:[(0,g.jsx)(o,{className:`size-4`,"aria-hidden":!0}),` Hermes-Dashboard öffnen`]}),(0,g.jsx)(`p`,{className:`text-xs text-text-3`,children:`Chat, Sitzungen und Cron-Jobs verwaltet Hermes selbst. Es fragt nach seiner eigenen Anmeldung.`})]})]})})}export{_ as Einstellungen}; \ No newline at end of file +import{c as e,f as t,t as n,u as r}from"./button-Dd8hfusv.js";import{A as i,F as a,I as o,L as s,j as c,k as l}from"./index-ZVRs0IGR.js";import{a as u,i as d,n as f,r as p,t as m}from"./sheet-DWG2Q04V.js";var h=t(r(),1),g=e();function _({offen:e,onSchliessen:t}){let r=s(),_=o({queryKey:[`geheimnisse`],queryFn:()=>l(`/api/maintenance/geheimnisse`),enabled:e}),[v,y]=(0,h.useState)(``);async function b(e){try{await i(`/api/maintenance/geheimnisse`,{schluessel:`hf_token`,wert:e}),c(`erfolg`,e?`Hugging-Face-Zugang gespeichert.`:`Hugging-Face-Zugang gelöscht.`),y(``),r.invalidateQueries({queryKey:[`geheimnisse`]})}catch(e){c(`fehler`,e.message)}}let x=_.data;return(0,g.jsx)(m,{open:e,onOpenChange:e=>!e&&t(),children:(0,g.jsxs)(f,{side:`right`,className:`w-full gap-3 overflow-y-auto border-linie bg-panel sm:max-w-lg`,children:[(0,g.jsxs)(d,{children:[(0,g.jsx)(u,{className:`schild text-lg`,children:`Einstellungen`}),(0,g.jsx)(p,{className:`text-text-2`,children:`Was die Box sich merkt.`})]}),(0,g.jsxs)(`section`,{className:`flex flex-col gap-3 border-t border-linie px-4 pt-4`,children:[(0,g.jsx)(`h3`,{className:`schild text-sm text-text-3`,children:`Hugging-Face-Zugang`}),(0,g.jsxs)(`p`,{className:`text-sm text-text-2`,children:[x?.hf_token_gesetzt?`Ist hinterlegt.`:`Fehlt.`,` Nötig für gesperrte Modelle und schnellere Downloads.`,x?.hf_token_aus_env?` Er kommt aus der Dienst-Einstellung und lässt sich hier nicht löschen.`:``]}),(0,g.jsxs)(`form`,{className:`flex gap-2`,onSubmit:e=>{e.preventDefault(),v.trim()&&b(v.trim())},children:[(0,g.jsx)(`label`,{htmlFor:`hf-token`,className:`sr-only`,children:`Hugging-Face-Zugang`}),(0,g.jsx)(`input`,{id:`hf-token`,type:`password`,autoComplete:`off`,value:v,onChange:e=>y(e.target.value),placeholder:`hf_…`,className:`h-11 min-w-0 flex-1 rounded-lg border border-linie-stark bg-erhaben px-3 text-[15px] outline-none focus:border-cyan`}),(0,g.jsx)(n,{type:`submit`,disabled:!v.trim()||x?.schreibbar===!1,children:`Speichern`})]}),x?.hf_token_gesetzt&&!x.hf_token_aus_env&&(0,g.jsx)(n,{variant:`ghost`,size:`sm`,className:`self-start`,onClick:()=>b(null),children:`Zugang löschen`})]}),(0,g.jsxs)(`section`,{className:`flex flex-col gap-2 border-t border-linie px-4 pt-4`,children:[(0,g.jsx)(`h3`,{className:`schild text-sm text-text-3`,children:`Hinweise`}),(0,g.jsx)(`p`,{className:`text-sm text-text-2`,children:`Dringende Hinweise gehen zusätzlich per Telegram raus, alles andere bleibt hier. Einfache Probleme wie einen abgestürzten Dienst behebt der Wächter selbst und schreibt es in den Verlauf.`})]}),(0,g.jsxs)(`section`,{className:`flex flex-col gap-2 border-t border-linie px-4 pt-4 pb-4`,children:[(0,g.jsx)(`h3`,{className:`schild text-sm text-text-3`,children:`Hermes`}),(0,g.jsxs)(`a`,{href:`/hermes-ui/`,target:`_blank`,rel:`noopener`,className:`flex h-11 items-center gap-2 self-start rounded-lg border border-linie-stark bg-erhaben px-4 text-[15px] hover:border-text-3`,children:[(0,g.jsx)(a,{className:`size-4`,"aria-hidden":!0}),` Hermes-Dashboard öffnen`]}),(0,g.jsx)(`p`,{className:`text-xs text-text-3`,children:`Chat, Sitzungen und Cron-Jobs verwaltet Hermes selbst. Es fragt nach seiner eigenen Anmeldung.`})]})]})})}export{_ as Einstellungen}; \ No newline at end of file diff --git a/frontend/dist/assets/MehrMenue-gZV9ubEU.js b/frontend/dist/assets/MehrMenue-CXteqmy8.js similarity index 83% rename from frontend/dist/assets/MehrMenue-gZV9ubEU.js rename to frontend/dist/assets/MehrMenue-CXteqmy8.js index 7956cf3..5af0cb3 100644 --- a/frontend/dist/assets/MehrMenue-gZV9ubEU.js +++ b/frontend/dist/assets/MehrMenue-CXteqmy8.js @@ -1 +1 @@ -import{c as e,s as t}from"./button-Dd8hfusv.js";import{M as n,N as r,j as i}from"./index-B6MevgIX.js";import{a,i as o,n as s,r as c,t as l}from"./sheet-DWG2Q04V.js";var u=t(),d=e();function f(e){let t=(0,u.c)(17),{verbindung:f,onDienste:p,onEinstellungen:m,onSchliessen:h}=e,g;t[0]===h?g=t[1]:(g=e=>!e&&h(),t[0]=h,t[1]=g);let _;t[2]===Symbol.for(`react.memo_cache_sentinel`)?(_=(0,d.jsxs)(o,{children:[(0,d.jsx)(a,{className:`schild text-lg`,children:`Mehr`}),(0,d.jsx)(c,{className:`sr-only`,children:`Weitere Bereiche`})]}),t[2]=_):_=t[2];let v;t[3]===Symbol.for(`react.memo_cache_sentinel`)?(v=(0,d.jsxs)(`a`,{href:`/hermes-ui/`,target:`_blank`,rel:`noopener`,className:`flex h-12 items-center gap-3 rounded-lg border border-linie px-4 text-base`,children:[(0,d.jsx)(r,{className:`size-5`,"aria-hidden":!0}),` Hermes-Dashboard öffnen`]}),t[3]=v):v=t[3];let y;t[4]===Symbol.for(`react.memo_cache_sentinel`)?(y=(0,d.jsx)(n,{className:`size-5`,"aria-hidden":!0}),t[4]=y):y=t[4];let b;t[5]===p?b=t[6]:(b=(0,d.jsxs)(`button`,{type:`button`,onClick:p,className:`flex h-12 items-center gap-3 rounded-lg border border-linie px-4 text-left text-base`,children:[y,` Dienste und Protokolle`]}),t[5]=p,t[6]=b);let x;t[7]===Symbol.for(`react.memo_cache_sentinel`)?(x=(0,d.jsx)(i,{className:`size-5`,"aria-hidden":!0}),t[7]=x):x=t[7];let S;t[8]===m?S=t[9]:(S=(0,d.jsxs)(`button`,{type:`button`,onClick:m,className:`flex h-12 items-center gap-3 rounded-lg border border-linie px-4 text-left text-base`,children:[x,` Einstellungen`]}),t[8]=m,t[9]=S);let C;t[10]!==b||t[11]!==S||t[12]!==f?(C=(0,d.jsxs)(s,{side:`bottom`,className:`border-linie bg-panel pb-[calc(1rem+env(safe-area-inset-bottom))]`,children:[_,(0,d.jsxs)(`div`,{className:`flex flex-col gap-2 px-4`,children:[f,v,b,S]})]}),t[10]=b,t[11]=S,t[12]=f,t[13]=C):C=t[13];let w;return t[14]!==g||t[15]!==C?(w=(0,d.jsx)(l,{open:!0,onOpenChange:g,children:C}),t[14]=g,t[15]=C,t[16]=w):w=t[16],w}export{f as MehrMenue}; \ No newline at end of file +import{c as e,s as t}from"./button-Dd8hfusv.js";import{F as n,N as r,P as i}from"./index-ZVRs0IGR.js";import{a,i as o,n as s,r as c,t as l}from"./sheet-DWG2Q04V.js";var u=t(),d=e();function f(e){let t=(0,u.c)(17),{verbindung:f,onDienste:p,onEinstellungen:m,onSchliessen:h}=e,g;t[0]===h?g=t[1]:(g=e=>!e&&h(),t[0]=h,t[1]=g);let _;t[2]===Symbol.for(`react.memo_cache_sentinel`)?(_=(0,d.jsxs)(o,{children:[(0,d.jsx)(a,{className:`schild text-lg`,children:`Mehr`}),(0,d.jsx)(c,{className:`sr-only`,children:`Weitere Bereiche`})]}),t[2]=_):_=t[2];let v;t[3]===Symbol.for(`react.memo_cache_sentinel`)?(v=(0,d.jsxs)(`a`,{href:`/hermes-ui/`,target:`_blank`,rel:`noopener`,className:`flex h-12 items-center gap-3 rounded-lg border border-linie px-4 text-base`,children:[(0,d.jsx)(n,{className:`size-5`,"aria-hidden":!0}),` Hermes-Dashboard öffnen`]}),t[3]=v):v=t[3];let y;t[4]===Symbol.for(`react.memo_cache_sentinel`)?(y=(0,d.jsx)(i,{className:`size-5`,"aria-hidden":!0}),t[4]=y):y=t[4];let b;t[5]===p?b=t[6]:(b=(0,d.jsxs)(`button`,{type:`button`,onClick:p,className:`flex h-12 items-center gap-3 rounded-lg border border-linie px-4 text-left text-base`,children:[y,` Dienste und Protokolle`]}),t[5]=p,t[6]=b);let x;t[7]===Symbol.for(`react.memo_cache_sentinel`)?(x=(0,d.jsx)(r,{className:`size-5`,"aria-hidden":!0}),t[7]=x):x=t[7];let S;t[8]===m?S=t[9]:(S=(0,d.jsxs)(`button`,{type:`button`,onClick:m,className:`flex h-12 items-center gap-3 rounded-lg border border-linie px-4 text-left text-base`,children:[x,` Einstellungen`]}),t[8]=m,t[9]=S);let C;t[10]!==b||t[11]!==S||t[12]!==f?(C=(0,d.jsxs)(s,{side:`bottom`,className:`border-linie bg-panel pb-[calc(1rem+env(safe-area-inset-bottom))]`,children:[_,(0,d.jsxs)(`div`,{className:`flex flex-col gap-2 px-4`,children:[f,v,b,S]})]}),t[10]=b,t[11]=S,t[12]=f,t[13]=C):C=t[13];let w;return t[14]!==g||t[15]!==C?(w=(0,d.jsx)(l,{open:!0,onOpenChange:g,children:C}),t[14]=g,t[15]=C,t[16]=w):w=t[16],w}export{f as MehrMenue}; \ No newline at end of file diff --git a/frontend/dist/assets/Modelle-CHK2sw1N.js b/frontend/dist/assets/Modelle-CHK2sw1N.js new file mode 100644 index 0000000..d925a95 --- /dev/null +++ b/frontend/dist/assets/Modelle-CHK2sw1N.js @@ -0,0 +1 @@ +import{c as e,f as t,o as n,s as r,t as i,u as a}from"./button-Dd8hfusv.js";import{A as o,I as s,L as c,M as l,S as u,_ as d,b as f,c as p,d as m,g as h,i as g,j as _,k as v,l as y,n as b,o as x,r as S,s as C,t as w,u as T,v as E,w as D,x as O}from"./index-ZVRs0IGR.js";import{a as k,i as A,n as j,r as M,t as N}from"./sheet-DWG2Q04V.js";import{t as P}from"./Bestaetigen-VrcNpcBb.js";var F={name:`search`,size:24,node:[[`path`,{d:`m21 21-4.34-4.34`,key:`14j7rj`}],[`circle`,{cx:`11`,cy:`11`,r:`8`,key:`4ej97u`}]]};F.node;var I=n(F),L=r(),R=t(a(),1),z=e();function B({offen:e,onSchliessen:t}){let n=c(),[r,a]=(0,R.useState)(``),[l,u]=(0,R.useState)(``),[d,f]=(0,R.useState)(null),[p,h]=(0,R.useState)(``),g=s({queryKey:[`hf-suche`,l],queryFn:()=>v(`/api/hf/search?q=${encodeURIComponent(l)}`),enabled:l.length>1}),y=s({queryKey:[`hf-quants`,d],queryFn:()=>v(`/api/hf/quants?repo=${encodeURIComponent(d??``)}`),enabled:!!d});async function b(e){if(d)try{await o(`/api/models/install`,{repo:d,quant:e,role:p||null}),_(`erfolg`,`${d} (${e}) wird heruntergeladen. Den Fortschritt siehst du unter Updates.`),n.invalidateQueries({queryKey:[`jobs`]}),n.invalidateQueries({queryKey:[`models`]}),t()}catch(e){_(`fehler`,e.message)}}let x=(y.data?.quants??[]).map(e=>typeof e==`string`?{quant:e}:e);return(0,z.jsx)(N,{open:e,onOpenChange:e=>!e&&t(),children:(0,z.jsxs)(j,{side:`right`,className:`w-full gap-3 overflow-y-auto border-linie bg-panel sm:max-w-xl`,children:[(0,z.jsxs)(A,{children:[(0,z.jsx)(k,{className:`schild text-lg`,children:`Modelle selbst suchen`}),(0,z.jsx)(M,{className:`text-text-2`,children:`Auf Hugging Face suchen, Quantisierung wählen, installieren.`})]}),(0,z.jsxs)(`form`,{className:`flex gap-2 px-4`,onSubmit:e=>{e.preventDefault(),f(null),u(r.trim())},children:[(0,z.jsx)(`label`,{htmlFor:`hf-suche`,className:`sr-only`,children:`Suchbegriff`}),(0,z.jsx)(`input`,{id:`hf-suche`,value:r,onChange:e=>a(e.target.value),placeholder:`z. B. Qwen3.8 GGUF`,className:`h-11 min-w-0 flex-1 rounded-lg border border-linie-stark bg-erhaben px-3 text-[15px] outline-none focus:border-cyan`}),(0,z.jsx)(i,{type:`submit`,children:`Suchen`})]}),(0,z.jsxs)(`div`,{className:`flex flex-col px-4 pb-4`,children:[g.isFetching&&(0,z.jsx)(`p`,{className:`py-3 text-sm text-text-2`,children:`Suche läuft …`}),!d&&g.data?.results.map(e=>(0,z.jsxs)(`button`,{type:`button`,onClick:()=>f(e.repo),className:`flex min-h-11 items-center justify-between gap-3 border-t border-linie py-2 text-left hover:text-cyan`,children:[(0,z.jsx)(`span`,{className:`ziffern min-w-0 text-sm break-all`,children:e.repo}),(0,z.jsxs)(`span`,{className:`ziffern shrink-0 text-xs text-text-3`,children:[m(e.downloads),` ↓`]})]},e.repo)),d&&(0,z.jsxs)(`div`,{className:`flex flex-col gap-3 pt-2`,children:[(0,z.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,z.jsx)(`span`,{className:`ziffern text-sm break-all`,children:d}),(0,z.jsx)(i,{variant:`ghost`,size:`sm`,onClick:()=>f(null),children:`Zurück`})]}),(0,z.jsxs)(`label`,{className:`flex items-center gap-3 text-sm text-text-2`,children:[`Rolle`,(0,z.jsxs)(`select`,{value:p,onChange:e=>h(e.target.value),className:`h-11 rounded-lg border border-linie-stark bg-erhaben px-3 text-foreground`,children:[(0,z.jsx)(`option`,{value:``,children:`ohne Rolle (nur installieren)`}),(0,z.jsx)(`option`,{value:`coder`,children:`Coder`})]})]}),y.isFetching&&(0,z.jsx)(`p`,{className:`text-sm text-text-2`,children:`Quantisierungen werden gelesen …`}),x.map(e=>{let t=e.quant??e.name??`?`,n=e.total_bytes??e.size_bytes;return(0,z.jsxs)(`div`,{className:`flex items-center justify-between gap-3 border-t border-linie py-2`,children:[(0,z.jsx)(`span`,{className:`ziffern text-sm`,children:t}),(0,z.jsxs)(`span`,{className:`flex items-center gap-3`,children:[n?(0,z.jsxs)(`span`,{className:`ziffern text-xs text-text-3`,children:[(n/1024**3).toFixed(1).replace(`.`,`,`),` GB`]}):null,(0,z.jsx)(i,{variant:`outline`,size:`sm`,onClick:()=>b(t),children:`Installieren`})]})]},t)})]})]})]})})}var V=115;function H(e){let t=(0,L.c)(55),{modelle:n,laufend:r}=e,i=l(),a=D(),o,s,c,u,d,f,p,m,h,g;if(t[0]!==r||t[1]!==i?.ram_total||t[2]!==i?.ram_used||t[3]!==n||t[4]!==a){let e=y(i?.ram_total??a.data?.box.ram_total)??122.7,l=y(i?.ram_used??a.data?.box.ram_used)??0,_;t[15]===r?_=t[16]:(_=e=>r.includes(e.name),t[15]=r,t[16]=_);let v=n.filter(_).reduce(U,0);s=Math.max(0,l-v);let b=t=>`${Math.min(100,t/e*100)}%`;o=w,m=`Speicher`,h=(0,z.jsxs)(`span`,{className:`ziffern text-sm text-text-2`,children:[Math.round(l),` von `,Math.round(e),` GB belegt · Grenze ~`,V,` GB`]});let x=`Speicher: ${Math.round(l)} von ${Math.round(e)} GB belegt`,S=b(l),C;t[17]===S?C=t[18]:(C={width:S},t[17]=S,t[18]=C);let T=`${l?v/l*100:0}%`,E;t[19]===T?E=t[20]:(E=(0,z.jsx)(`div`,{className:`h-full bg-cyan`,style:{width:T}}),t[19]=T,t[20]=E);let D=`${l?s/l*100:0}%`,O;t[21]===D?O=t[22]:(O=(0,z.jsx)(`div`,{className:`h-full bg-cyan/35`,style:{width:D}}),t[21]=D,t[22]=O);let k;t[23]!==C||t[24]!==E||t[25]!==O?(k=(0,z.jsxs)(`div`,{className:`absolute inset-y-0 left-0 flex overflow-hidden rounded-lg`,style:C,children:[E,O]}),t[23]=C,t[24]=E,t[25]=O,t[26]=k):k=t[26];let A=b(V),j;t[27]===A?j=t[28]:(j=(0,z.jsx)(`div`,{className:`absolute -top-1.5 -bottom-1.5 w-0.5 bg-bernstein`,style:{left:A}}),t[27]=A,t[28]=j),t[29]!==x||t[30]!==k||t[31]!==j?(g=(0,z.jsxs)(`div`,{className:`relative h-8 rounded-lg bg-erhaben`,role:`img`,"aria-label":x,children:[k,j]}),t[29]=x,t[30]=k,t[31]=j,t[32]=g):g=t[32],p=`flex flex-wrap gap-x-6 gap-y-2 text-sm text-text-2`,c=`flex items-center gap-2`,t[33]===Symbol.for(`react.memo_cache_sentinel`)?(u=(0,z.jsx)(`span`,{className:`size-2.5 rounded-sm bg-cyan`}),t[33]=u):u=t[33],d=` Geladene Modelle: `,f=Math.round(v),t[0]=r,t[1]=i?.ram_total,t[2]=i?.ram_used,t[3]=n,t[4]=a,t[5]=o,t[6]=s,t[7]=c,t[8]=u,t[9]=d,t[10]=f,t[11]=p,t[12]=m,t[13]=h,t[14]=g}else o=t[5],s=t[6],c=t[7],u=t[8],d=t[9],f=t[10],p=t[11],m=t[12],h=t[13],g=t[14];let _;t[34]!==c||t[35]!==u||t[36]!==d||t[37]!==f?(_=(0,z.jsxs)(`span`,{className:c,children:[u,d,f,` GB Dateien`]}),t[34]=c,t[35]=u,t[36]=d,t[37]=f,t[38]=_):_=t[38];let v;t[39]===Symbol.for(`react.memo_cache_sentinel`)?(v=(0,z.jsx)(`span`,{className:`size-2.5 rounded-sm bg-cyan/35`}),t[39]=v):v=t[39];let b;t[40]===s?b=t[41]:(b=Math.round(s),t[40]=s,t[41]=b);let x;t[42]===b?x=t[43]:(x=(0,z.jsxs)(`span`,{className:`flex items-center gap-2`,children:[v,` Cache, Dienste, System: `,b,` GB`]}),t[42]=b,t[43]=x);let S;t[44]===Symbol.for(`react.memo_cache_sentinel`)?(S=(0,z.jsxs)(`span`,{className:`flex items-center gap-2`,children:[(0,z.jsx)(`span`,{className:`h-3 w-0.5 bg-bernstein`}),` Ab hier wird es eng`]}),t[44]=S):S=t[44];let C;t[45]!==x||t[46]!==p||t[47]!==_?(C=(0,z.jsxs)(`div`,{className:p,children:[_,x,S]}),t[45]=x,t[46]=p,t[47]=_,t[48]=C):C=t[48];let T;return t[49]!==o||t[50]!==C||t[51]!==m||t[52]!==h||t[53]!==g?(T=(0,z.jsxs)(o,{titel:m,rechts:h,children:[g,C]}),t[49]=o,t[50]=C,t[51]=m,t[52]=h,t[53]=g,t[54]=T):T=t[54],T}function U(e,t){return e+(y(t.size_bytes)??0)}function W(e){let t=(0,L.c)(7),{name:n,wert:r}=e,i;t[0]===n?i=t[1]:(i=(0,z.jsx)(`dt`,{className:`text-xs text-text-3`,children:n}),t[0]=n,t[1]=i);let a;t[2]===r?a=t[3]:(a=(0,z.jsx)(`dd`,{className:`ziffern m-0 text-lg`,children:r}),t[2]=r,t[3]=a);let o;return t[4]!==i||t[5]!==a?(o=(0,z.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[i,a]}),t[4]=i,t[5]=a,t[6]=o):o=t[6],o}function G(e){let t=(0,L.c)(47),{titel:n,modell:r,laeuft:a,nutzer:o}=e,s=h();if(!r){let e;t[0]===n?e=t[1]:(e=(0,z.jsx)(`span`,{className:`schild text-sm text-text-3`,children:n}),t[0]=n,t[1]=e);let r;t[2]===Symbol.for(`react.memo_cache_sentinel`)?(r=(0,z.jsx)(x,{children:`Frei`}),t[2]=r):r=t[2];let i;t[3]===e?i=t[4]:(i=(0,z.jsxs)(`div`,{className:`flex items-center justify-between`,children:[e,r]}),t[3]=e,t[4]=i);let a,o;t[5]===Symbol.for(`react.memo_cache_sentinel`)?(a=(0,z.jsx)(`h3`,{className:`font-anzeige text-xl font-semibold text-text-2`,children:`Nicht belegt`}),o=(0,z.jsx)(`p`,{className:`text-sm text-text-2`,children:`Nur belegen, wenn ein Modell hier echten Mehrwert bringt. Das Radar meldet Kandidaten.`}),t[5]=a,t[6]=o):(a=t[5],o=t[6]);let s;return t[7]===i?s=t[8]:(s=(0,z.jsxs)(`article`,{className:`flex flex-col gap-3.5 rounded-2xl border border-dashed border-linie-stark p-5`,children:[i,a,o]}),t[7]=i,t[8]=s),s}let c;t[9]!==r.ctx||t[10]!==r.parallel_slots?(c=r.ctx?Math.round(r.ctx/Math.max(1,r.parallel_slots)/1024):null,t[9]=r.ctx,t[10]=r.parallel_slots,t[11]=c):c=t[11];let l=c,u=!!r.capabilities?.vision,d;t[12]===n?d=t[13]:(d=(0,z.jsx)(`span`,{className:`schild text-sm text-text-3`,children:n}),t[12]=n,t[13]=d);let f=a?`gruen`:`grau`,p=a?`Geladen`:`Auf Abruf`,m;t[14]!==f||t[15]!==p?(m=(0,z.jsx)(x,{art:f,children:p}),t[14]=f,t[15]=p,t[16]=m):m=t[16];let g;t[17]!==d||t[18]!==m?(g=(0,z.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[d,m]}),t[17]=d,t[18]=m,t[19]=g):g=t[19];let _;t[20]===r.name?_=t[21]:(_=(0,z.jsx)(`h3`,{className:`ziffern m-0 text-lg font-medium break-all`,children:r.name}),t[20]=r.name,t[21]=_);let v;t[22]===r.size_bytes?v=t[23]:(v=T(r.size_bytes),t[22]=r.size_bytes,t[23]=v);let y;t[24]===v?y=t[25]:(y=(0,z.jsx)(W,{name:`Größe`,wert:v}),t[24]=v,t[25]=y);let b=l?`${l}k`:`–`,S;t[26]===b?S=t[27]:(S=(0,z.jsx)(W,{name:`Kontext`,wert:b}),t[26]=b,t[27]=S);let C=u?`ja`:`nein`,w;t[28]===C?w=t[29]:(w=(0,z.jsx)(W,{name:`Bilder`,wert:C}),t[28]=C,t[29]=w);let E;t[30]!==S||t[31]!==w||t[32]!==y?(E=(0,z.jsxs)(`dl`,{className:`m-0 grid grid-cols-3 gap-3`,children:[y,S,w]}),t[30]=S,t[31]=w,t[32]=y,t[33]=E):E=t[33];let D=r.spec_active?` Mit Draft-Beschleunigung.`:``,O;t[34]!==o||t[35]!==D?(O=(0,z.jsxs)(`p`,{className:`text-sm text-text-2`,children:[`Genutzt von `,o,`.`,D]}),t[34]=o,t[35]=D,t[36]=O):O=t[36];let k;t[37]!==s||t[38]!==a||t[39]!==r.name?(k=!a&&(0,z.jsx)(i,{variant:`outline`,size:`sm`,className:`mt-auto self-start`,onClick:()=>s.mutate(r.name),disabled:s.isPending,children:`Jetzt laden`}),t[37]=s,t[38]=a,t[39]=r.name,t[40]=k):k=t[40];let A;return t[41]!==E||t[42]!==O||t[43]!==k||t[44]!==g||t[45]!==_?(A=(0,z.jsxs)(`article`,{className:`flex flex-col gap-3.5 rounded-2xl border border-linie bg-panel p-5`,children:[g,_,E,O,k]}),t[41]=E,t[42]=O,t[43]=k,t[44]=g,t[45]=_,t[46]=A):A=t[46],A}function K(e){let t=(0,L.c)(51),{nutzung:n}=e;if(!n)return null;let r;t[0]===n.absender?r=t[1]:(r=Math.max(1,...n.absender.map(X)),t[0]=n.absender,t[1]=r);let i=r,a,o,s,c,l,u,d,f,p,h,g,_;if(t[2]!==i||t[3]!==n.absender||t[4]!==n.letzte_24h||t[5]!==n.tage){let e=n.letzte_24h.map(J),r=Math.max(1,...e);a=w,_=`Wer nutzt die Modelle`,t[18]===n.tage?o=t[19]:(o=(0,z.jsxs)(`span`,{className:`ziffern text-xs text-text-3`,children:[`letzte `,n.tage,` Tage`]}),t[18]=n.tage,t[19]=o),t[20]===n.absender.length?s=t[21]:(s=n.absender.length===0&&(0,z.jsx)(`p`,{className:`text-[15px] text-text-2`,children:`Keine Anfragen aufgezeichnet.`}),t[20]=n.absender.length,t[21]=s);let v;if(t[22]!==i||t[23]!==n.absender){let e;t[25]===i?e=t[26]:(e=e=>(0,z.jsxs)(`li`,{className:`flex flex-col gap-1.5`,children:[(0,z.jsxs)(`div`,{className:`flex justify-between gap-3 text-sm`,children:[(0,z.jsx)(`span`,{children:e.name}),(0,z.jsx)(`span`,{className:`ziffern`,children:m(e.anfragen)})]}),(0,z.jsx)(`div`,{className:`h-2 rounded-full bg-erhaben`,children:(0,z.jsx)(`div`,{className:`h-2 rounded-full bg-cyan`,style:{width:`${e.anfragen/i*100}%`}})})]},e.name),t[25]=i,t[26]=e),v=n.absender.map(e),t[22]=i,t[23]=n.absender,t[24]=v}else v=t[24];t[27]===v?c=t[28]:(c=(0,z.jsx)(`ul`,{className:`m-0 flex list-none flex-col gap-3.5 p-0`,children:v}),t[27]=v,t[28]=c),h=`flex flex-col gap-1.5`,t[29]===Symbol.for(`react.memo_cache_sentinel`)?(g=(0,z.jsx)(`span`,{className:`schild text-xs text-text-3`,children:`Anfragen je Stunde, letzte 24 h`}),t[29]=g):g=t[29],l=`0 0 240 64`,u=`h-16 w-full`,d=`img`,f=`Anfragen je Stunde in den letzten 24 Stunden`;let y;t[30]===r?y=t[31]:(y=(e,t)=>{let n=e?Math.max(3,e/r*50):2;return(0,z.jsx)(`rect`,{x:t*10+1.5,y:52-n,width:7,height:n,rx:1.5,fill:e?`var(--cyan)`:`var(--linie)`},t)},t[30]=r,t[31]=y),p=e.map(y),t[2]=i,t[3]=n.absender,t[4]=n.letzte_24h,t[5]=n.tage,t[6]=a,t[7]=o,t[8]=s,t[9]=c,t[10]=l,t[11]=u,t[12]=d,t[13]=f,t[14]=p,t[15]=h,t[16]=g,t[17]=_}else a=t[6],o=t[7],s=t[8],c=t[9],l=t[10],u=t[11],d=t[12],f=t[13],p=t[14],h=t[15],g=t[16],_=t[17];let v;t[32]===Symbol.for(`react.memo_cache_sentinel`)?(v=[0,6,12,18].map(q),t[32]=v):v=t[32];let y;t[33]!==l||t[34]!==u||t[35]!==d||t[36]!==f||t[37]!==p?(y=(0,z.jsxs)(`svg`,{viewBox:l,className:u,role:d,"aria-label":f,children:[p,v]}),t[33]=l,t[34]=u,t[35]=d,t[36]=f,t[37]=p,t[38]=y):y=t[38];let b;t[39]!==y||t[40]!==h||t[41]!==g?(b=(0,z.jsxs)(`div`,{className:h,children:[g,y]}),t[39]=y,t[40]=h,t[41]=g,t[42]=b):b=t[42];let x;t[43]===Symbol.for(`react.memo_cache_sentinel`)?(x=(0,z.jsx)(`p`,{className:`text-xs text-text-3`,children:`Anfragen an llama-swap. NerdQuiz geht direkt dorthin, alles andere über MC2.`}),t[43]=x):x=t[43];let S;return t[44]!==a||t[45]!==o||t[46]!==s||t[47]!==c||t[48]!==b||t[49]!==_?(S=(0,z.jsxs)(a,{titel:_,rechts:o,children:[s,c,b,x]}),t[44]=a,t[45]=o,t[46]=s,t[47]=c,t[48]=b,t[49]=_,t[50]=S):S=t[50],S}function q(e){return(0,z.jsx)(`text`,{x:e*10+5,y:63,textAnchor:`middle`,style:{fontSize:9,fill:`var(--text-3)`,fontFamily:`var(--font-mono)`},children:e},e)}function J(e){return Object.values(e.je_absender).reduce(Y,0)}function Y(e,t){return e+t}function X(e){return e.anfragen}var Z={bestanden:`gruen`,durchgefallen:`rot`,wartet:`cyan`,neu:`cyan`,getestet:`grau`,uebernommen:`gruen`,verworfen:`grau`},Q={besser:`text-gruen`,schlechter:`text-rot-text`,gleich:`text-text-2`};function $(e){let t=(0,L.c)(4),{test:n}=e,r,i;if(t[0]!==n.vergleich){i=Symbol.for(`react.early_return_sentinel`);bb0:{let e=Object.entries(n.vergleich??{});if(e.length===0){i=null;break bb0}let a;t[3]===Symbol.for(`react.memo_cache_sentinel`)?(a=(0,z.jsxs)(`div`,{role:`row`,className:`schild grid grid-cols-[minmax(0,1fr)_auto_auto] gap-x-4 pb-1 text-xs text-text-3`,children:[(0,z.jsx)(`span`,{role:`columnheader`,children:`Messwert`}),(0,z.jsx)(`span`,{role:`columnheader`,className:`text-right`,children:`Kandidat`}),(0,z.jsx)(`span`,{role:`columnheader`,className:`text-right`,children:`Heute`})]}),t[3]=a):a=t[3],r=(0,z.jsxs)(`div`,{role:`table`,"aria-label":`Messwerte gegen das heutige Modell`,className:`rounded-lg border border-linie bg-erhaben/50 px-3 py-2 text-sm`,children:[a,e.map(ee)]})}t[0]=n.vergleich,t[1]=r,t[2]=i}else r=t[1],i=t[2];return i===Symbol.for(`react.early_return_sentinel`)?r:i}function ee(e){let[t,n]=e;return(0,z.jsxs)(`div`,{role:`row`,className:`grid grid-cols-[minmax(0,1fr)_auto_auto] gap-x-4 border-t border-linie py-1`,children:[(0,z.jsx)(`span`,{role:`rowheader`,className:`text-text-2`,children:t}),(0,z.jsx)(`span`,{role:`cell`,className:`ziffern text-right ${Q[n.urteil??``]??`text-text-2`}`,children:S(n.kandidat,n.einheit)}),(0,z.jsx)(`span`,{role:`cell`,className:`ziffern text-right text-text-3`,children:S(n.baseline,n.einheit)})]},t)}function te(e){let t=(0,L.c)(54),{k:n,test:r,heute:a}=e,o=O(),[s,c]=(0,R.useState)(null),l;t[0]===Symbol.for(`react.memo_cache_sentinel`)?(l=[`bestanden`,`wartet`,`neu`,`getestet`],t[0]=l):l=t[0];let u=l.includes(n.status),d=n.rolle===`hirn`,f;t[1]===n.name?f=t[2]:(f=(0,z.jsx)(`span`,{className:`ziffern text-[15px] font-medium`,children:n.name}),t[1]=n.name,t[2]=f);let p=d?`fürs Hirn`:`fürs Coden`,m;t[3]===p?m=t[4]:(m=(0,z.jsx)(x,{art:`cyan`,children:p}),t[3]=p,t[4]=m);let h=n.eng?`bernstein`:n.passt?`gruen`:`rot`,g=n.eng?`passt knapp`:n.passt?`passt`:`passt nicht`,_;t[5]!==h||t[6]!==g?(_=(0,z.jsx)(x,{art:h,children:g}),t[5]=h,t[6]=g,t[7]=_):_=t[7];let v=Z[n.status]??`grau`,y=b[n.status]??n.status,S;t[8]!==v||t[9]!==y?(S=(0,z.jsx)(x,{art:v,children:y}),t[8]=v,t[9]=y,t[10]=S):S=t[10];let C;t[11]!==S||t[12]!==f||t[13]!==m||t[14]!==_?(C=(0,z.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[f,m,_,S]}),t[11]=S,t[12]=f,t[13]=m,t[14]=_,t[15]=C):C=t[15];let w;t[16]===n.groesse_gb?w=t[17]:(w=n.groesse_gb==null?``:`${n.groesse_gb.toLocaleString(`de-DE`)} GB. `,t[16]=n.groesse_gb,t[17]=w);let T;t[18]!==n.begruendung||t[19]!==w?(T=(0,z.jsxs)(`p`,{className:`text-sm text-text-2`,children:[w,n.begruendung]}),t[18]=n.begruendung,t[19]=w,t[20]=T):T=t[20];let E;t[21]!==n.status||t[22]!==r?(E=r&&[`bestanden`,`durchgefallen`].includes(n.status)&&(0,z.jsx)($,{test:r}),t[21]=n.status,t[22]=r,t[23]=E):E=t[23];let D;t[24]!==o.isPending||t[25]!==n.status||t[26]!==u?(D=u&&(0,z.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[n.status===`bestanden`&&(0,z.jsx)(i,{size:`sm`,disabled:o.isPending,onClick:()=>c(`uebernehmen`),children:`Übernehmen`}),(0,z.jsx)(i,{variant:`outline`,size:`sm`,disabled:o.isPending,onClick:()=>c(`verwerfen`),children:`Verwerfen`})]}),t[24]=o.isPending,t[25]=n.status,t[26]=u,t[27]=D):D=t[27];let k=s===`uebernehmen`,A=`${n.name} übernehmen?`,j=d?`${n.name} wird Lucys Hirn${a?` und löst ${a} ab`:``}. NerdQuiz und OpenChamber nutzen ab dann ebenfalls das neue Modell. Hermes startet dafür kurz neu, Lucy ist etwa eine Minute nicht erreichbar. Das alte Modell bleibt auf der Platte.`:`${n.name} wird der Coder${a?` und löst ${a} ab`:``}. OpenChamber plant und baut ab dann damit. Das alte Modell bleibt auf der Platte.`,M;t[28]===Symbol.for(`react.memo_cache_sentinel`)?(M=()=>c(null),t[28]=M):M=t[28];let N;t[29]!==o||t[30]!==n.id||t[31]!==n.name?(N=()=>{o.mutate({id:n.id,aktion:`uebernehmen`,name:n.name}),c(null)},t[29]=o,t[30]=n.id,t[31]=n.name,t[32]=N):N=t[32];let F;t[33]!==k||t[34]!==A||t[35]!==j||t[36]!==N?(F=(0,z.jsx)(P,{offen:k,titel:A,text:j,knopf:`Übernehmen`,onNein:M,onJa:N}),t[33]=k,t[34]=A,t[35]=j,t[36]=N,t[37]=F):F=t[37];let I=s===`verwerfen`,B=`${n.name} verwerfen?`,V;t[38]===Symbol.for(`react.memo_cache_sentinel`)?(V=()=>c(null),t[38]=V):V=t[38];let H;t[39]!==o||t[40]!==n.id||t[41]!==n.name?(H=()=>{o.mutate({id:n.id,aktion:`verwerfen`,name:n.name}),c(null)},t[39]=o,t[40]=n.id,t[41]=n.name,t[42]=H):H=t[42];let U;t[43]!==I||t[44]!==B||t[45]!==H?(U=(0,z.jsx)(P,{offen:I,gefahr:!0,titel:B,text:`Die heruntergeladenen Dateien werden gelöscht, und das Radar testet dieses Modell nicht noch einmal.`,knopf:`Verwerfen`,onNein:V,onJa:H}),t[43]=I,t[44]=B,t[45]=H,t[46]=U):U=t[46];let W;return t[47]!==C||t[48]!==T||t[49]!==E||t[50]!==D||t[51]!==F||t[52]!==U?(W=(0,z.jsxs)(`li`,{className:`flex flex-col gap-2 border-t border-linie py-3.5`,children:[C,T,E,D,F,U]}),t[47]=C,t[48]=T,t[49]=E,t[50]=D,t[51]=F,t[52]=U,t[53]=W):W=t[53],W}function ne(e){let t=(0,L.c)(21),{hirn:n,coder:r}=e,a=f(),o=u();if(a.isError){let e;return t[0]===Symbol.for(`react.memo_cache_sentinel`)?(e=(0,z.jsx)(w,{titel:`Modell-Radar`,id:`radar`,children:(0,z.jsx)(`p`,{className:`text-[15px] text-text-2`,children:`Das Radar ist auf dieser Box noch nicht eingerichtet.`})}),t[0]=e):e=t[0],e}let s=a.data,c;t[1]===o?c=t[2]:(c=()=>o.mutate(void 0),t[1]=o,t[2]=c);let l;t[3]!==o.isPending||t[4]!==c?(l=(0,z.jsx)(i,{variant:`info`,size:`sm`,onClick:c,disabled:o.isPending,children:`Jetzt suchen`}),t[3]=o.isPending,t[4]=c,t[5]=l):l=t[5];let d;t[6]===s?d=t[7]:(d=s?.naechster_test?` Nächster Test: ${p(s.naechster_test)}.`:``,t[6]=s,t[7]=d);let m;t[8]===d?m=t[9]:(m=(0,z.jsxs)(`p`,{className:`-mt-2 text-sm text-text-2`,children:[`Testet nachts zwischen 00:30 und 02:30 selbst, höchstens einen Kandidaten pro Woche.`,d]}),t[8]=d,t[9]=m);let h;t[10]!==r||t[11]!==s||t[12]!==n?(h=s?s.kandidaten.length===0?(0,z.jsx)(`p`,{className:`text-[15px] text-text-2`,children:`Nichts Besseres in Sicht.`}):(0,z.jsx)(`ul`,{className:`m-0 flex list-none flex-col p-0`,children:s.kandidaten.map(e=>(0,z.jsx)(te,{k:e,test:s.tests.find(t=>t.kandidat===e.id),heute:e.rolle===`hirn`?n:r},e.id))}):(0,z.jsx)(`p`,{className:`text-[15px] text-text-2`,children:`Wird gelesen …`}),t[10]=r,t[11]=s,t[12]=n,t[13]=h):h=t[13];let g;t[14]===s?g=t[15]:(g=s&&s.tests.length>0&&(0,z.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,z.jsx)(`h3`,{className:`schild text-xs text-text-3`,children:`Letzte Tests`}),s.tests.slice(0,3).map(re)]}),t[14]=s,t[15]=g);let _;return t[16]!==l||t[17]!==m||t[18]!==h||t[19]!==g?(_=(0,z.jsxs)(w,{titel:`Modell-Radar`,id:`radar`,rechts:l,children:[m,h,g]}),t[16]=l,t[17]=m,t[18]=h,t[19]=g,t[20]=_):_=t[20],_}function re(e){return(0,z.jsxs)(`p`,{className:`text-sm text-text-2`,children:[(0,z.jsx)(`span`,{className:`ziffern text-text-3`,children:p(e.datum)}),` · `,e.zusammenfassung]},e.id)}function ie(){let e=(0,L.c)(55),t=d(),n=E(),[r,a]=(0,R.useState)(!1);if(t.isPending){let t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t=(0,z.jsx)(C,{text:`Modelle werden gelesen …`}),e[0]=t):t=e[0],t}if(t.error||!t.data){let n=`Die Modell-Liste fehlt: ${t.error?.message??`keine Daten`}`,r;return e[1]===n?r=e[2]:(r=(0,z.jsx)(C,{fehler:!0,text:n}),e[1]=n,e[2]=r),r}let o=t.data.models,s=t.data.running,c,l,u,f,m,h,g,_;if(e[3]!==s||e[4]!==o||e[5]!==n.data){let t=o.find(oe),r=o.find(ae),d=o.filter(e=>e!==t&&e!==r),v;e[14]===n.data?.zuletzt_geladen?v=e[15]:(v=n.data?.zuletzt_geladen??{},e[14]=n.data?.zuletzt_geladen,e[15]=v);let y=v;e[16]!==s||e[17]!==o?(h=(0,z.jsx)(H,{modelle:o,laufend:s}),e[16]=s,e[17]=o,e[18]=h):h=e[18];let b=(0,z.jsx)(G,{titel:`Hirn`,modell:t,laeuft:!!t&&s.includes(t.name),nutzer:`Lucy, NerdQuiz und OpenChamber für Kleinkram`}),x=!!r&&s.includes(r.name),S;e[19]!==r||e[20]!==x?(S=(0,z.jsx)(G,{titel:`Coder`,modell:r,laeuft:x,nutzer:`OpenChamber zum Planen und Bauen und Lucys Delegation`}),e[19]=r,e[20]=x,e[21]=S):S=e[21];let C;e[22]===Symbol.for(`react.memo_cache_sentinel`)?(C=(0,z.jsx)(G,{titel:`Dritte Rolle`,laeuft:!1,nutzer:``}),e[22]=C):C=e[22],e[23]!==S||e[24]!==b?(g=(0,z.jsxs)(`section`,{"aria-label":`Rollen`,className:`grid gap-5 md:grid-cols-3 md:gap-6`,children:[b,S,C]}),e[23]=S,e[24]=b,e[25]=g):g=e[25];let E;e[26]===n.data?E=e[27]:(E=(0,z.jsx)(K,{nutzung:n.data}),e[26]=n.data,e[27]=E);let D=t?.name,O=r?.name,k;e[28]!==D||e[29]!==O?(k=(0,z.jsx)(ne,{hirn:D,coder:O}),e[28]=D,e[29]=O,e[30]=k):k=e[30],e[31]!==E||e[32]!==k?(_=(0,z.jsxs)(`div`,{className:`grid gap-5 md:gap-6 lg:grid-cols-[minmax(0,1fr)_minmax(0,1.3fr)]`,children:[E,k]}),e[31]=E,e[32]=k,e[33]=_):_=e[33],c=w,f=`Weitere Einträge`,e[34]===Symbol.for(`react.memo_cache_sentinel`)?(m=(0,z.jsxs)(i,{variant:`outline`,size:`sm`,onClick:()=>a(!0),children:[(0,z.jsx)(I,{"aria-hidden":!0}),` Modelle selbst suchen`]}),e[34]=m):m=e[34],l=`m-0 flex list-none flex-col p-0`;let A;e[35]!==s||e[36]!==y?(A=e=>(0,z.jsxs)(`li`,{className:`grid grid-cols-[minmax(0,1fr)_auto] items-center gap-3 border-t border-linie py-2.5 sm:grid-cols-[minmax(0,1fr)_120px_160px]`,children:[(0,z.jsxs)(`span`,{className:`min-w-0`,children:[(0,z.jsx)(`span`,{className:`ziffern block text-sm break-all`,children:e.name}),(0,z.jsx)(`span`,{className:`text-xs text-text-3`,children:e.aliases.length?e.aliases.join(`, `):`ohne Rolle`})]}),(0,z.jsx)(`span`,{className:`ziffern text-sm text-text-2`,children:T(e.size_bytes)}),(0,z.jsx)(`span`,{className:`ziffern hidden text-xs text-text-3 sm:block`,children:s.includes(e.name)?`geladen`:y[e.name]?`zuletzt ${p(y[e.name])}`:`länger nicht geladen`})]},e.name),e[35]=s,e[36]=y,e[37]=A):A=e[37],u=d.map(A),e[3]=s,e[4]=o,e[5]=n.data,e[6]=c,e[7]=l,e[8]=u,e[9]=f,e[10]=m,e[11]=h,e[12]=g,e[13]=_}else c=e[6],l=e[7],u=e[8],f=e[9],m=e[10],h=e[11],g=e[12],_=e[13];let v;e[38]!==l||e[39]!==u?(v=(0,z.jsx)(`ul`,{className:l,children:u}),e[38]=l,e[39]=u,e[40]=v):v=e[40];let y;e[41]!==c||e[42]!==f||e[43]!==m||e[44]!==v?(y=(0,z.jsx)(c,{titel:f,rechts:m,children:v}),e[41]=c,e[42]=f,e[43]=m,e[44]=v,e[45]=y):y=e[45];let b;e[46]===Symbol.for(`react.memo_cache_sentinel`)?(b=()=>a(!1),e[46]=b):b=e[46];let x;e[47]===r?x=e[48]:(x=(0,z.jsx)(B,{offen:r,onSchliessen:b}),e[47]=r,e[48]=x);let S;return e[49]!==x||e[50]!==h||e[51]!==g||e[52]!==_||e[53]!==y?(S=(0,z.jsxs)(z.Fragment,{children:[h,g,_,y,x]}),e[49]=x,e[50]=h,e[51]=g,e[52]=_,e[53]=y,e[54]=S):S=e[54],S}function ae(e){return g(e)===`coder`}function oe(e){return g(e)===`hirn`}export{ie as ModelleSeite}; \ No newline at end of file diff --git a/frontend/dist/assets/Modelle-PWfbWtFC.js b/frontend/dist/assets/Modelle-PWfbWtFC.js deleted file mode 100644 index b09ef75..0000000 --- a/frontend/dist/assets/Modelle-PWfbWtFC.js +++ /dev/null @@ -1 +0,0 @@ -import{c as e,f as t,o as n,s as r,t as i,u as a}from"./button-Dd8hfusv.js";import{A as o,D as s,F as c,O as l,P as u,S as d,a as f,b as p,c as m,g as h,h as g,i as _,k as v,l as y,m as b,n as x,o as S,s as C,t as w,v as T,y as E}from"./index-B6MevgIX.js";import{a as D,i as O,n as k,r as A,t as j}from"./sheet-DWG2Q04V.js";var M={name:`search`,size:24,node:[[`path`,{d:`m21 21-4.34-4.34`,key:`14j7rj`}],[`circle`,{cx:`11`,cy:`11`,r:`8`,key:`4ej97u`}]]};M.node;var N=n(M),P=r(),F=t(a(),1),I=e();function L({offen:e,onSchliessen:t}){let n=c(),[r,a]=(0,F.useState)(``),[o,d]=(0,F.useState)(``),[f,p]=(0,F.useState)(null),[m,h]=(0,F.useState)(``),g=u({queryKey:[`hf-suche`,o],queryFn:()=>s(`/api/hf/search?q=${encodeURIComponent(o)}`),enabled:o.length>1}),_=u({queryKey:[`hf-quants`,f],queryFn:()=>s(`/api/hf/quants?repo=${encodeURIComponent(f??``)}`),enabled:!!f});async function b(e){if(f)try{await l(`/api/models/install`,{repo:f,quant:e,role:m||null}),v(`erfolg`,`${f} (${e}) wird heruntergeladen. Den Fortschritt siehst du unter Updates.`),n.invalidateQueries({queryKey:[`jobs`]}),n.invalidateQueries({queryKey:[`models`]}),t()}catch(e){v(`fehler`,e.message)}}let x=(_.data?.quants??[]).map(e=>typeof e==`string`?{quant:e}:e);return(0,I.jsx)(j,{open:e,onOpenChange:e=>!e&&t(),children:(0,I.jsxs)(k,{side:`right`,className:`w-full gap-3 overflow-y-auto border-linie bg-panel sm:max-w-xl`,children:[(0,I.jsxs)(O,{children:[(0,I.jsx)(D,{className:`schild text-lg`,children:`Modelle selbst suchen`}),(0,I.jsx)(A,{className:`text-text-2`,children:`Auf Hugging Face suchen, Quantisierung wählen, installieren.`})]}),(0,I.jsxs)(`form`,{className:`flex gap-2 px-4`,onSubmit:e=>{e.preventDefault(),p(null),d(r.trim())},children:[(0,I.jsx)(`label`,{htmlFor:`hf-suche`,className:`sr-only`,children:`Suchbegriff`}),(0,I.jsx)(`input`,{id:`hf-suche`,value:r,onChange:e=>a(e.target.value),placeholder:`z. B. Qwen3.8 GGUF`,className:`h-11 min-w-0 flex-1 rounded-lg border border-linie-stark bg-erhaben px-3 text-[15px] outline-none focus:border-cyan`}),(0,I.jsx)(i,{type:`submit`,children:`Suchen`})]}),(0,I.jsxs)(`div`,{className:`flex flex-col px-4 pb-4`,children:[g.isFetching&&(0,I.jsx)(`p`,{className:`py-3 text-sm text-text-2`,children:`Suche läuft …`}),!f&&g.data?.results.map(e=>(0,I.jsxs)(`button`,{type:`button`,onClick:()=>p(e.repo),className:`flex min-h-11 items-center justify-between gap-3 border-t border-linie py-2 text-left hover:text-cyan`,children:[(0,I.jsx)(`span`,{className:`ziffern min-w-0 text-sm break-all`,children:e.repo}),(0,I.jsxs)(`span`,{className:`ziffern shrink-0 text-xs text-text-3`,children:[y(e.downloads),` ↓`]})]},e.repo)),f&&(0,I.jsxs)(`div`,{className:`flex flex-col gap-3 pt-2`,children:[(0,I.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,I.jsx)(`span`,{className:`ziffern text-sm break-all`,children:f}),(0,I.jsx)(i,{variant:`ghost`,size:`sm`,onClick:()=>p(null),children:`Zurück`})]}),(0,I.jsxs)(`label`,{className:`flex items-center gap-3 text-sm text-text-2`,children:[`Rolle`,(0,I.jsxs)(`select`,{value:m,onChange:e=>h(e.target.value),className:`h-11 rounded-lg border border-linie-stark bg-erhaben px-3 text-foreground`,children:[(0,I.jsx)(`option`,{value:``,children:`ohne Rolle (nur installieren)`}),(0,I.jsx)(`option`,{value:`coder`,children:`Coder`})]})]}),_.isFetching&&(0,I.jsx)(`p`,{className:`text-sm text-text-2`,children:`Quantisierungen werden gelesen …`}),x.map(e=>{let t=e.quant??e.name??`?`,n=e.total_bytes??e.size_bytes;return(0,I.jsxs)(`div`,{className:`flex items-center justify-between gap-3 border-t border-linie py-2`,children:[(0,I.jsx)(`span`,{className:`ziffern text-sm`,children:t}),(0,I.jsxs)(`span`,{className:`flex items-center gap-3`,children:[n?(0,I.jsxs)(`span`,{className:`ziffern text-xs text-text-3`,children:[(n/1024**3).toFixed(1).replace(`.`,`,`),` GB`]}):null,(0,I.jsx)(i,{variant:`outline`,size:`sm`,onClick:()=>b(t),children:`Installieren`})]})]},t)})]})]})]})})}var R=115;function z(e){let t=(0,P.c)(55),{modelle:n,laufend:r}=e,i=o(),a=d(),s,c,l,u,f,p,m,h,g,_;if(t[0]!==r||t[1]!==i?.ram_total||t[2]!==i?.ram_used||t[3]!==n||t[4]!==a){let e=C(i?.ram_total??a.data?.box.ram_total)??122.7,o=C(i?.ram_used??a.data?.box.ram_used)??0,d;t[15]===r?d=t[16]:(d=e=>r.includes(e.name),t[15]=r,t[16]=d);let v=n.filter(d).reduce(B,0);c=Math.max(0,o-v);let y=t=>`${Math.min(100,t/e*100)}%`;s=w,h=`Speicher`,g=(0,I.jsxs)(`span`,{className:`ziffern text-sm text-text-2`,children:[Math.round(o),` von `,Math.round(e),` GB belegt · Grenze ~`,R,` GB`]});let b=`Speicher: ${Math.round(o)} von ${Math.round(e)} GB belegt`,x=y(o),S;t[17]===x?S=t[18]:(S={width:x},t[17]=x,t[18]=S);let T=`${o?v/o*100:0}%`,E;t[19]===T?E=t[20]:(E=(0,I.jsx)(`div`,{className:`h-full bg-cyan`,style:{width:T}}),t[19]=T,t[20]=E);let D=`${o?c/o*100:0}%`,O;t[21]===D?O=t[22]:(O=(0,I.jsx)(`div`,{className:`h-full bg-cyan/35`,style:{width:D}}),t[21]=D,t[22]=O);let k;t[23]!==S||t[24]!==E||t[25]!==O?(k=(0,I.jsxs)(`div`,{className:`absolute inset-y-0 left-0 flex overflow-hidden rounded-lg`,style:S,children:[E,O]}),t[23]=S,t[24]=E,t[25]=O,t[26]=k):k=t[26];let A=y(R),j;t[27]===A?j=t[28]:(j=(0,I.jsx)(`div`,{className:`absolute -top-1.5 -bottom-1.5 w-0.5 bg-bernstein`,style:{left:A}}),t[27]=A,t[28]=j),t[29]!==b||t[30]!==k||t[31]!==j?(_=(0,I.jsxs)(`div`,{className:`relative h-8 rounded-lg bg-erhaben`,role:`img`,"aria-label":b,children:[k,j]}),t[29]=b,t[30]=k,t[31]=j,t[32]=_):_=t[32],m=`flex flex-wrap gap-x-6 gap-y-2 text-sm text-text-2`,l=`flex items-center gap-2`,t[33]===Symbol.for(`react.memo_cache_sentinel`)?(u=(0,I.jsx)(`span`,{className:`size-2.5 rounded-sm bg-cyan`}),t[33]=u):u=t[33],f=` Geladene Modelle: `,p=Math.round(v),t[0]=r,t[1]=i?.ram_total,t[2]=i?.ram_used,t[3]=n,t[4]=a,t[5]=s,t[6]=c,t[7]=l,t[8]=u,t[9]=f,t[10]=p,t[11]=m,t[12]=h,t[13]=g,t[14]=_}else s=t[5],c=t[6],l=t[7],u=t[8],f=t[9],p=t[10],m=t[11],h=t[12],g=t[13],_=t[14];let v;t[34]!==l||t[35]!==u||t[36]!==f||t[37]!==p?(v=(0,I.jsxs)(`span`,{className:l,children:[u,f,p,` GB Dateien`]}),t[34]=l,t[35]=u,t[36]=f,t[37]=p,t[38]=v):v=t[38];let y;t[39]===Symbol.for(`react.memo_cache_sentinel`)?(y=(0,I.jsx)(`span`,{className:`size-2.5 rounded-sm bg-cyan/35`}),t[39]=y):y=t[39];let b;t[40]===c?b=t[41]:(b=Math.round(c),t[40]=c,t[41]=b);let x;t[42]===b?x=t[43]:(x=(0,I.jsxs)(`span`,{className:`flex items-center gap-2`,children:[y,` Cache, Dienste, System: `,b,` GB`]}),t[42]=b,t[43]=x);let S;t[44]===Symbol.for(`react.memo_cache_sentinel`)?(S=(0,I.jsxs)(`span`,{className:`flex items-center gap-2`,children:[(0,I.jsx)(`span`,{className:`h-3 w-0.5 bg-bernstein`}),` Ab hier wird es eng`]}),t[44]=S):S=t[44];let T;t[45]!==x||t[46]!==m||t[47]!==v?(T=(0,I.jsxs)(`div`,{className:m,children:[v,x,S]}),t[45]=x,t[46]=m,t[47]=v,t[48]=T):T=t[48];let E;return t[49]!==s||t[50]!==T||t[51]!==h||t[52]!==g||t[53]!==_?(E=(0,I.jsxs)(s,{titel:h,rechts:g,children:[_,T]}),t[49]=s,t[50]=T,t[51]=h,t[52]=g,t[53]=_,t[54]=E):E=t[54],E}function B(e,t){return e+(C(t.size_bytes)??0)}function V(e){let t=(0,P.c)(7),{name:n,wert:r}=e,i;t[0]===n?i=t[1]:(i=(0,I.jsx)(`dt`,{className:`text-xs text-text-3`,children:n}),t[0]=n,t[1]=i);let a;t[2]===r?a=t[3]:(a=(0,I.jsx)(`dd`,{className:`ziffern m-0 text-lg`,children:r}),t[2]=r,t[3]=a);let o;return t[4]!==i||t[5]!==a?(o=(0,I.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[i,a]}),t[4]=i,t[5]=a,t[6]=o):o=t[6],o}function H(e){let t=(0,P.c)(47),{titel:n,modell:r,laeuft:a,nutzer:o}=e,s=b();if(!r){let e;t[0]===n?e=t[1]:(e=(0,I.jsx)(`span`,{className:`schild text-sm text-text-3`,children:n}),t[0]=n,t[1]=e);let r;t[2]===Symbol.for(`react.memo_cache_sentinel`)?(r=(0,I.jsx)(_,{children:`Frei`}),t[2]=r):r=t[2];let i;t[3]===e?i=t[4]:(i=(0,I.jsxs)(`div`,{className:`flex items-center justify-between`,children:[e,r]}),t[3]=e,t[4]=i);let a,o;t[5]===Symbol.for(`react.memo_cache_sentinel`)?(a=(0,I.jsx)(`h3`,{className:`font-anzeige text-xl font-semibold text-text-2`,children:`Nicht belegt`}),o=(0,I.jsx)(`p`,{className:`text-sm text-text-2`,children:`Nur belegen, wenn ein Modell hier echten Mehrwert bringt. Das Radar meldet Kandidaten.`}),t[5]=a,t[6]=o):(a=t[5],o=t[6]);let s;return t[7]===i?s=t[8]:(s=(0,I.jsxs)(`article`,{className:`flex flex-col gap-3.5 rounded-2xl border border-dashed border-linie-stark p-5`,children:[i,a,o]}),t[7]=i,t[8]=s),s}let c;t[9]!==r.ctx||t[10]!==r.parallel_slots?(c=r.ctx?Math.round(r.ctx/Math.max(1,r.parallel_slots)/1024):null,t[9]=r.ctx,t[10]=r.parallel_slots,t[11]=c):c=t[11];let l=c,u=!!r.capabilities?.vision,d;t[12]===n?d=t[13]:(d=(0,I.jsx)(`span`,{className:`schild text-sm text-text-3`,children:n}),t[12]=n,t[13]=d);let f=a?`gruen`:`grau`,p=a?`Geladen`:`Auf Abruf`,h;t[14]!==f||t[15]!==p?(h=(0,I.jsx)(_,{art:f,children:p}),t[14]=f,t[15]=p,t[16]=h):h=t[16];let g;t[17]!==d||t[18]!==h?(g=(0,I.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[d,h]}),t[17]=d,t[18]=h,t[19]=g):g=t[19];let v;t[20]===r.name?v=t[21]:(v=(0,I.jsx)(`h3`,{className:`ziffern m-0 text-lg font-medium break-all`,children:r.name}),t[20]=r.name,t[21]=v);let y;t[22]===r.size_bytes?y=t[23]:(y=m(r.size_bytes),t[22]=r.size_bytes,t[23]=y);let x;t[24]===y?x=t[25]:(x=(0,I.jsx)(V,{name:`Größe`,wert:y}),t[24]=y,t[25]=x);let S=l?`${l}k`:`–`,C;t[26]===S?C=t[27]:(C=(0,I.jsx)(V,{name:`Kontext`,wert:S}),t[26]=S,t[27]=C);let w=u?`ja`:`nein`,T;t[28]===w?T=t[29]:(T=(0,I.jsx)(V,{name:`Bilder`,wert:w}),t[28]=w,t[29]=T);let E;t[30]!==C||t[31]!==T||t[32]!==x?(E=(0,I.jsxs)(`dl`,{className:`m-0 grid grid-cols-3 gap-3`,children:[x,C,T]}),t[30]=C,t[31]=T,t[32]=x,t[33]=E):E=t[33];let D=r.spec_active?` Mit Draft-Beschleunigung.`:``,O;t[34]!==o||t[35]!==D?(O=(0,I.jsxs)(`p`,{className:`text-sm text-text-2`,children:[`Genutzt von `,o,`.`,D]}),t[34]=o,t[35]=D,t[36]=O):O=t[36];let k;t[37]!==s||t[38]!==a||t[39]!==r.name?(k=!a&&(0,I.jsx)(i,{variant:`outline`,size:`sm`,className:`mt-auto self-start`,onClick:()=>s.mutate(r.name),disabled:s.isPending,children:`Jetzt laden`}),t[37]=s,t[38]=a,t[39]=r.name,t[40]=k):k=t[40];let A;return t[41]!==E||t[42]!==O||t[43]!==k||t[44]!==g||t[45]!==v?(A=(0,I.jsxs)(`article`,{className:`flex flex-col gap-3.5 rounded-2xl border border-linie bg-panel p-5`,children:[g,v,E,O,k]}),t[41]=E,t[42]=O,t[43]=k,t[44]=g,t[45]=v,t[46]=A):A=t[46],A}function U(e){let t=(0,P.c)(51),{nutzung:n}=e;if(!n)return null;let r;t[0]===n.absender?r=t[1]:(r=Math.max(1,...n.absender.map(q)),t[0]=n.absender,t[1]=r);let i=r,a,o,s,c,l,u,d,f,p,m,h,g;if(t[2]!==i||t[3]!==n.absender||t[4]!==n.letzte_24h||t[5]!==n.tage){let e=n.letzte_24h.map(G),r=Math.max(1,...e);a=w,g=`Wer nutzt die Modelle`,t[18]===n.tage?o=t[19]:(o=(0,I.jsxs)(`span`,{className:`ziffern text-xs text-text-3`,children:[`letzte `,n.tage,` Tage`]}),t[18]=n.tage,t[19]=o),t[20]===n.absender.length?s=t[21]:(s=n.absender.length===0&&(0,I.jsx)(`p`,{className:`text-[15px] text-text-2`,children:`Keine Anfragen aufgezeichnet.`}),t[20]=n.absender.length,t[21]=s);let _;if(t[22]!==i||t[23]!==n.absender){let e;t[25]===i?e=t[26]:(e=e=>(0,I.jsxs)(`li`,{className:`flex flex-col gap-1.5`,children:[(0,I.jsxs)(`div`,{className:`flex justify-between gap-3 text-sm`,children:[(0,I.jsx)(`span`,{children:e.name}),(0,I.jsx)(`span`,{className:`ziffern`,children:y(e.anfragen)})]}),(0,I.jsx)(`div`,{className:`h-2 rounded-full bg-erhaben`,children:(0,I.jsx)(`div`,{className:`h-2 rounded-full bg-cyan`,style:{width:`${e.anfragen/i*100}%`}})})]},e.name),t[25]=i,t[26]=e),_=n.absender.map(e),t[22]=i,t[23]=n.absender,t[24]=_}else _=t[24];t[27]===_?c=t[28]:(c=(0,I.jsx)(`ul`,{className:`m-0 flex list-none flex-col gap-3.5 p-0`,children:_}),t[27]=_,t[28]=c),m=`flex flex-col gap-1.5`,t[29]===Symbol.for(`react.memo_cache_sentinel`)?(h=(0,I.jsx)(`span`,{className:`schild text-xs text-text-3`,children:`Anfragen je Stunde, letzte 24 h`}),t[29]=h):h=t[29],l=`0 0 240 64`,u=`h-16 w-full`,d=`img`,f=`Anfragen je Stunde in den letzten 24 Stunden`;let v;t[30]===r?v=t[31]:(v=(e,t)=>{let n=e?Math.max(3,e/r*50):2;return(0,I.jsx)(`rect`,{x:t*10+1.5,y:52-n,width:7,height:n,rx:1.5,fill:e?`var(--cyan)`:`var(--linie)`},t)},t[30]=r,t[31]=v),p=e.map(v),t[2]=i,t[3]=n.absender,t[4]=n.letzte_24h,t[5]=n.tage,t[6]=a,t[7]=o,t[8]=s,t[9]=c,t[10]=l,t[11]=u,t[12]=d,t[13]=f,t[14]=p,t[15]=m,t[16]=h,t[17]=g}else a=t[6],o=t[7],s=t[8],c=t[9],l=t[10],u=t[11],d=t[12],f=t[13],p=t[14],m=t[15],h=t[16],g=t[17];let _;t[32]===Symbol.for(`react.memo_cache_sentinel`)?(_=[0,6,12,18].map(W),t[32]=_):_=t[32];let v;t[33]!==l||t[34]!==u||t[35]!==d||t[36]!==f||t[37]!==p?(v=(0,I.jsxs)(`svg`,{viewBox:l,className:u,role:d,"aria-label":f,children:[p,_]}),t[33]=l,t[34]=u,t[35]=d,t[36]=f,t[37]=p,t[38]=v):v=t[38];let b;t[39]!==v||t[40]!==m||t[41]!==h?(b=(0,I.jsxs)(`div`,{className:m,children:[h,v]}),t[39]=v,t[40]=m,t[41]=h,t[42]=b):b=t[42];let x;t[43]===Symbol.for(`react.memo_cache_sentinel`)?(x=(0,I.jsx)(`p`,{className:`text-xs text-text-3`,children:`Anfragen an llama-swap. NerdQuiz geht direkt dorthin, alles andere über MC2.`}),t[43]=x):x=t[43];let S;return t[44]!==a||t[45]!==o||t[46]!==s||t[47]!==c||t[48]!==b||t[49]!==g?(S=(0,I.jsxs)(a,{titel:g,rechts:o,children:[s,c,b,x]}),t[44]=a,t[45]=o,t[46]=s,t[47]=c,t[48]=b,t[49]=g,t[50]=S):S=t[50],S}function W(e){return(0,I.jsx)(`text`,{x:e*10+5,y:63,textAnchor:`middle`,style:{fontSize:9,fill:`var(--text-3)`,fontFamily:`var(--font-mono)`},children:e},e)}function G(e){return Object.values(e.je_absender).reduce(K,0)}function K(e,t){return e+t}function q(e){return e.anfragen}var J={bestanden:`gruen`,durchgefallen:`rot`,wartet:`cyan`,neu:`cyan`,getestet:`grau`,uebernommen:`gruen`,verworfen:`grau`};function Y(e){let t=(0,P.c)(31),{k:n}=e,r=E(),a;t[0]===Symbol.for(`react.memo_cache_sentinel`)?(a=[`bestanden`,`wartet`,`neu`],t[0]=a):a=t[0];let o=a.includes(n.status),s;t[1]===n.name?s=t[2]:(s=(0,I.jsx)(`span`,{className:`ziffern text-[15px] font-medium`,children:n.name}),t[1]=n.name,t[2]=s);let c=n.rolle===`hirn`?`fürs Hirn`:`fürs Coden`,l;t[3]===c?l=t[4]:(l=(0,I.jsx)(_,{art:`cyan`,children:c}),t[3]=c,t[4]=l);let u=n.eng?`bernstein`:n.passt?`gruen`:`rot`,d=n.eng?`passt knapp`:n.passt?`passt`:`passt nicht`,f;t[5]!==u||t[6]!==d?(f=(0,I.jsx)(_,{art:u,children:d}),t[5]=u,t[6]=d,t[7]=f):f=t[7];let p=J[n.status]??`grau`,m;t[8]!==n.status||t[9]!==p?(m=(0,I.jsx)(_,{art:p,children:n.status}),t[8]=n.status,t[9]=p,t[10]=m):m=t[10];let h;t[11]!==s||t[12]!==l||t[13]!==f||t[14]!==m?(h=(0,I.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[s,l,f,m]}),t[11]=s,t[12]=l,t[13]=f,t[14]=m,t[15]=h):h=t[15];let g;t[16]===n.groesse_gb?g=t[17]:(g=n.groesse_gb==null?``:`${n.groesse_gb.toLocaleString(`de-DE`)} GB. `,t[16]=n.groesse_gb,t[17]=g);let v;t[18]!==n.begruendung||t[19]!==g?(v=(0,I.jsxs)(`p`,{className:`text-sm text-text-2`,children:[g,n.begruendung]}),t[18]=n.begruendung,t[19]=g,t[20]=v):v=t[20];let y;t[21]!==r||t[22]!==n.id||t[23]!==n.name||t[24]!==n.status||t[25]!==o?(y=o&&(0,I.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[n.status===`bestanden`&&(0,I.jsx)(i,{size:`sm`,disabled:r.isPending,onClick:()=>r.mutate({id:n.id,aktion:`uebernehmen`,name:n.name}),children:`Übernehmen`}),(0,I.jsx)(i,{variant:`outline`,size:`sm`,disabled:r.isPending,onClick:()=>r.mutate({id:n.id,aktion:`verwerfen`,name:n.name}),children:`Verwerfen`})]}),t[21]=r,t[22]=n.id,t[23]=n.name,t[24]=n.status,t[25]=o,t[26]=y):y=t[26];let b;return t[27]!==h||t[28]!==v||t[29]!==y?(b=(0,I.jsxs)(`li`,{className:`flex flex-col gap-2 border-t border-linie py-3.5`,children:[h,v,y]}),t[27]=h,t[28]=v,t[29]=y,t[30]=b):b=t[30],b}function X(){let e=(0,P.c)(18),t=T(),n=p();if(t.isError){let t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t=(0,I.jsx)(w,{titel:`Modell-Radar`,id:`radar`,children:(0,I.jsx)(`p`,{className:`text-[15px] text-text-2`,children:`Das Radar ist auf dieser Box noch nicht eingerichtet.`})}),e[0]=t):t=e[0],t}let r=t.data,a;e[1]===n?a=e[2]:(a=()=>n.mutate(void 0),e[1]=n,e[2]=a);let o;e[3]!==n.isPending||e[4]!==a?(o=(0,I.jsx)(i,{variant:`info`,size:`sm`,onClick:a,disabled:n.isPending,children:`Jetzt suchen`}),e[3]=n.isPending,e[4]=a,e[5]=o):o=e[5];let s;e[6]===r?s=e[7]:(s=r?.naechster_test?` Nächster Test: ${S(r.naechster_test)}.`:``,e[6]=r,e[7]=s);let c;e[8]===s?c=e[9]:(c=(0,I.jsxs)(`p`,{className:`-mt-2 text-sm text-text-2`,children:[`Testet nachts zwischen 00:30 und 02:30 selbst, höchstens einen Kandidaten pro Woche.`,s]}),e[8]=s,e[9]=c);let l,u;e[10]===r?(l=e[11],u=e[12]):(l=r?r.kandidaten.length===0?(0,I.jsx)(`p`,{className:`text-[15px] text-text-2`,children:`Nichts Besseres in Sicht.`}):(0,I.jsx)(`ul`,{className:`m-0 flex list-none flex-col p-0`,children:r.kandidaten.map(Q)}):(0,I.jsx)(`p`,{className:`text-[15px] text-text-2`,children:`Wird gelesen …`}),u=r&&r.tests.length>0&&(0,I.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,I.jsx)(`h3`,{className:`schild text-xs text-text-3`,children:`Letzte Tests`}),r.tests.slice(0,3).map(Z)]}),e[10]=r,e[11]=l,e[12]=u);let d;return e[13]!==o||e[14]!==c||e[15]!==l||e[16]!==u?(d=(0,I.jsxs)(w,{titel:`Modell-Radar`,id:`radar`,rechts:o,children:[c,l,u]}),e[13]=o,e[14]=c,e[15]=l,e[16]=u,e[17]=d):d=e[17],d}function Z(e){return(0,I.jsxs)(`p`,{className:`text-sm text-text-2`,children:[(0,I.jsx)(`span`,{className:`ziffern text-text-3`,children:S(e.datum)}),` · `,e.zusammenfassung]},e.id)}function Q(e){return(0,I.jsx)(Y,{k:e},e.id)}function $(){let e=(0,P.c)(52),t=g(),n=h(),[r,a]=(0,F.useState)(!1);if(t.isPending){let t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t=(0,I.jsx)(f,{text:`Modelle werden gelesen …`}),e[0]=t):t=e[0],t}if(t.error||!t.data){let n=`Die Modell-Liste fehlt: ${t.error?.message??`keine Daten`}`,r;return e[1]===n?r=e[2]:(r=(0,I.jsx)(f,{fehler:!0,text:n}),e[1]=n,e[2]=r),r}let o=t.data.models,s=t.data.running,c,l,u,d,p,_,v,y;if(e[3]!==s||e[4]!==o||e[5]!==n.data){let t=o.find(te),r=o.find(ee),f=o.filter(e=>e!==t&&e!==r),h;e[14]===n.data?.zuletzt_geladen?h=e[15]:(h=n.data?.zuletzt_geladen??{},e[14]=n.data?.zuletzt_geladen,e[15]=h);let g=h;e[16]!==s||e[17]!==o?(_=(0,I.jsx)(z,{modelle:o,laufend:s}),e[16]=s,e[17]=o,e[18]=_):_=e[18];let b=(0,I.jsx)(H,{titel:`Hirn`,modell:t,laeuft:!!t&&s.includes(t.name),nutzer:`Lucy, NerdQuiz und OpenChamber für Kleinkram`}),x=!!r&&s.includes(r.name),C;e[19]!==r||e[20]!==x?(C=(0,I.jsx)(H,{titel:`Coder`,modell:r,laeuft:x,nutzer:`OpenChamber zum Planen und Bauen und Lucys Delegation`}),e[19]=r,e[20]=x,e[21]=C):C=e[21];let T;e[22]===Symbol.for(`react.memo_cache_sentinel`)?(T=(0,I.jsx)(H,{titel:`Dritte Rolle`,laeuft:!1,nutzer:``}),e[22]=T):T=e[22],e[23]!==C||e[24]!==b?(v=(0,I.jsxs)(`section`,{"aria-label":`Rollen`,className:`grid gap-5 md:grid-cols-3 md:gap-6`,children:[b,C,T]}),e[23]=C,e[24]=b,e[25]=v):v=e[25];let E;e[26]===n.data?E=e[27]:(E=(0,I.jsx)(U,{nutzung:n.data}),e[26]=n.data,e[27]=E);let D;e[28]===Symbol.for(`react.memo_cache_sentinel`)?(D=(0,I.jsx)(X,{}),e[28]=D):D=e[28],e[29]===E?y=e[30]:(y=(0,I.jsxs)(`div`,{className:`grid gap-5 md:gap-6 lg:grid-cols-[minmax(0,1fr)_minmax(0,1.3fr)]`,children:[E,D]}),e[29]=E,e[30]=y),c=w,d=`Weitere Einträge`,e[31]===Symbol.for(`react.memo_cache_sentinel`)?(p=(0,I.jsxs)(i,{variant:`outline`,size:`sm`,onClick:()=>a(!0),children:[(0,I.jsx)(N,{"aria-hidden":!0}),` Modelle selbst suchen`]}),e[31]=p):p=e[31],l=`m-0 flex list-none flex-col p-0`;let O;e[32]!==s||e[33]!==g?(O=e=>(0,I.jsxs)(`li`,{className:`grid grid-cols-[minmax(0,1fr)_auto] items-center gap-3 border-t border-linie py-2.5 sm:grid-cols-[minmax(0,1fr)_120px_160px]`,children:[(0,I.jsxs)(`span`,{className:`min-w-0`,children:[(0,I.jsx)(`span`,{className:`ziffern block text-sm break-all`,children:e.name}),(0,I.jsx)(`span`,{className:`text-xs text-text-3`,children:e.aliases.length?e.aliases.join(`, `):`ohne Rolle`})]}),(0,I.jsx)(`span`,{className:`ziffern text-sm text-text-2`,children:m(e.size_bytes)}),(0,I.jsx)(`span`,{className:`ziffern hidden text-xs text-text-3 sm:block`,children:s.includes(e.name)?`geladen`:g[e.name]?`zuletzt ${S(g[e.name])}`:`länger nicht geladen`})]},e.name),e[32]=s,e[33]=g,e[34]=O):O=e[34],u=f.map(O),e[3]=s,e[4]=o,e[5]=n.data,e[6]=c,e[7]=l,e[8]=u,e[9]=d,e[10]=p,e[11]=_,e[12]=v,e[13]=y}else c=e[6],l=e[7],u=e[8],d=e[9],p=e[10],_=e[11],v=e[12],y=e[13];let b;e[35]!==l||e[36]!==u?(b=(0,I.jsx)(`ul`,{className:l,children:u}),e[35]=l,e[36]=u,e[37]=b):b=e[37];let x;e[38]!==c||e[39]!==d||e[40]!==p||e[41]!==b?(x=(0,I.jsx)(c,{titel:d,rechts:p,children:b}),e[38]=c,e[39]=d,e[40]=p,e[41]=b,e[42]=x):x=e[42];let C;e[43]===Symbol.for(`react.memo_cache_sentinel`)?(C=()=>a(!1),e[43]=C):C=e[43];let T;e[44]===r?T=e[45]:(T=(0,I.jsx)(L,{offen:r,onSchliessen:C}),e[44]=r,e[45]=T);let E;return e[46]!==T||e[47]!==_||e[48]!==v||e[49]!==y||e[50]!==x?(E=(0,I.jsxs)(I.Fragment,{children:[_,v,y,x,T]}),e[46]=T,e[47]=_,e[48]=v,e[49]=y,e[50]=x,e[51]=E):E=e[51],E}function ee(e){return x(e)===`coder`}function te(e){return x(e)===`hirn`}export{$ as ModelleSeite}; \ No newline at end of file diff --git a/frontend/dist/assets/Updates-3PYj6oWY.js b/frontend/dist/assets/Updates-3PYj6oWY.js deleted file mode 100644 index 22f2d4a..0000000 --- a/frontend/dist/assets/Updates-3PYj6oWY.js +++ /dev/null @@ -1,2 +0,0 @@ -import{a as e,c as t,f as n,i as r,s as i,t as a,u as o}from"./button-Dd8hfusv.js";import{a as s,i as c,n as l,o as u,r as d,s as f,t as p}from"./dist-CgRgLCFz.js";import{C as m,E as h,S as g,T as _,a as v,d as y,f as b,i as x,o as S,p as C,r as w,t as T,w as E,x as D}from"./index-B6MevgIX.js";var O=i(),k=n(o(),1),A=t();function j(e){let t=(0,O.c)(4),n;t[0]===e?n=t[1]:({...n}=e,t[0]=e,t[1]=n);let r;return t[2]===n?r=t[3]:(r=(0,A.jsx)(p,{"data-slot":`dialog`,...n}),t[2]=n,t[3]=r),r}function M(e){let t=(0,O.c)(4),n;t[0]===e?n=t[1]:({...n}=e,t[0]=e,t[1]=n);let r;return t[2]===n?r=t[3]:(r=(0,A.jsx)(u,{"data-slot":`dialog-portal`,...n}),t[2]=n,t[3]=r),r}function N(e){let t=(0,O.c)(8),n,i;t[0]===e?(n=t[1],i=t[2]):({className:n,...i}=e,t[0]=e,t[1]=n,t[2]=i);let a;t[3]===n?a=t[4]:(a=r(`fixed inset-0 isolate z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0`,n),t[3]=n,t[4]=a);let o;return t[5]!==i||t[6]!==a?(o=(0,A.jsx)(s,{"data-slot":`dialog-overlay`,className:a,...i}),t[5]=i,t[6]=a,t[7]=o):o=t[7],o}function P(t){let n=(0,O.c)(15),i,o,s,c;n[0]===t?(i=n[1],o=n[2],s=n[3],c=n[4]):({className:o,children:i,showCloseButton:c,...s}=t,n[0]=t,n[1]=i,n[2]=o,n[3]=s,n[4]=c);let u=c===void 0||c,f;n[5]===Symbol.for(`react.memo_cache_sentinel`)?(f=(0,A.jsx)(N,{}),n[5]=f):f=n[5];let p;n[6]===o?p=n[7]:(p=r(`fixed top-1/2 left-1/2 z-50 grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl bg-popover p-4 text-sm text-popover-foreground ring-1 ring-foreground/10 duration-100 outline-none sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95`,o),n[6]=o,n[7]=p);let m;n[8]===u?m=n[9]:(m=u&&(0,A.jsx)(l,{"data-slot":`dialog-close`,asChild:!0,children:(0,A.jsxs)(a,{variant:`ghost`,className:`absolute top-2 right-2`,size:`icon-sm`,children:[(0,A.jsx)(e,{}),(0,A.jsx)(`span`,{className:`sr-only`,children:`Schließen`})]})}),n[8]=u,n[9]=m);let h;return n[10]!==i||n[11]!==s||n[12]!==p||n[13]!==m?(h=(0,A.jsxs)(M,{children:[f,(0,A.jsxs)(d,{"data-slot":`dialog-content`,className:p,...s,children:[i,m]})]}),n[10]=i,n[11]=s,n[12]=p,n[13]=m,n[14]=h):h=n[14],h}function F(e){let t=(0,O.c)(8),n,i;t[0]===e?(n=t[1],i=t[2]):({className:n,...i}=e,t[0]=e,t[1]=n,t[2]=i);let a;t[3]===n?a=t[4]:(a=r(`flex flex-col gap-2`,n),t[3]=n,t[4]=a);let o;return t[5]!==i||t[6]!==a?(o=(0,A.jsx)(`div`,{"data-slot":`dialog-header`,className:a,...i}),t[5]=i,t[6]=a,t[7]=o):o=t[7],o}function I(e){let t=(0,O.c)(14),n,i,o,s;t[0]===e?(n=t[1],i=t[2],o=t[3],s=t[4]):({className:i,showCloseButton:s,children:n,...o}=e,t[0]=e,t[1]=n,t[2]=i,t[3]=o,t[4]=s);let c=s!==void 0&&s,u;t[5]===i?u=t[6]:(u=r(`-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t bg-muted/50 p-4 sm:flex-row sm:justify-end`,i),t[5]=i,t[6]=u);let d;t[7]===c?d=t[8]:(d=c&&(0,A.jsx)(l,{asChild:!0,children:(0,A.jsx)(a,{variant:`outline`,children:`Schließen`})}),t[7]=c,t[8]=d);let f;return t[9]!==n||t[10]!==o||t[11]!==u||t[12]!==d?(f=(0,A.jsxs)(`div`,{"data-slot":`dialog-footer`,className:u,...o,children:[n,d]}),t[9]=n,t[10]=o,t[11]=u,t[12]=d,t[13]=f):f=t[13],f}function L(e){let t=(0,O.c)(8),n,i;t[0]===e?(n=t[1],i=t[2]):({className:n,...i}=e,t[0]=e,t[1]=n,t[2]=i);let a;t[3]===n?a=t[4]:(a=r(`font-heading text-base leading-none font-medium`,n),t[3]=n,t[4]=a);let o;return t[5]!==i||t[6]!==a?(o=(0,A.jsx)(f,{"data-slot":`dialog-title`,className:a,...i}),t[5]=i,t[6]=a,t[7]=o):o=t[7],o}function R(e){let t=(0,O.c)(8),n,i;t[0]===e?(n=t[1],i=t[2]):({className:n,...i}=e,t[0]=e,t[1]=n,t[2]=i);let a;t[3]===n?a=t[4]:(a=r(`text-sm text-muted-foreground *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground`,n),t[3]=n,t[4]=a);let o;return t[5]!==i||t[6]!==a?(o=(0,A.jsx)(c,{"data-slot":`dialog-description`,className:a,...i}),t[5]=i,t[6]=a,t[7]=o):o=t[7],o}function z(e){let t=(0,O.c)(26),{offen:n,titel:r,text:i,knopf:o,gefahr:s,onJa:c,onNein:l,children:u}=e,d;t[0]===l?d=t[1]:(d=e=>!e&&l(),t[0]=l,t[1]=d);let f;t[2]===r?f=t[3]:(f=(0,A.jsx)(L,{className:`schild text-xl`,children:r}),t[2]=r,t[3]=f);let p;t[4]===i?p=t[5]:(p=(0,A.jsx)(R,{className:`text-[15px] leading-relaxed text-text-2`,children:i}),t[4]=i,t[5]=p);let m;t[6]!==f||t[7]!==p?(m=(0,A.jsxs)(F,{children:[f,p]}),t[6]=f,t[7]=p,t[8]=m):m=t[8];let h;t[9]===l?h=t[10]:(h=(0,A.jsx)(a,{variant:`outline`,onClick:l,children:`Abbrechen`}),t[9]=l,t[10]=h);let g=s?`gefahr`:`default`,_;t[11]!==o||t[12]!==c||t[13]!==g?(_=(0,A.jsx)(a,{variant:g,onClick:c,children:o}),t[11]=o,t[12]=c,t[13]=g,t[14]=_):_=t[14];let v;t[15]!==h||t[16]!==_?(v=(0,A.jsxs)(I,{className:`gap-2 sm:gap-2`,children:[h,_]}),t[15]=h,t[16]=_,t[17]=v):v=t[17];let y;t[18]!==u||t[19]!==m||t[20]!==v?(y=(0,A.jsxs)(P,{className:`border-linie bg-panel sm:max-w-lg`,children:[m,u,v]}),t[18]=u,t[19]=m,t[20]=v,t[21]=y):y=t[21];let b;return t[22]!==n||t[23]!==d||t[24]!==y?(b=(0,A.jsx)(j,{open:n,onOpenChange:d,children:y}),t[22]=n,t[23]=d,t[24]=y,t[25]=b):b=t[25],b}var B=[{id:`os`,name:`Betriebssystem`},{id:`engine`,name:`Motor (llama.cpp)`},{id:`swap`,name:`llama-swap`},{id:`hermes`,name:`Hermes`}];function V(e){let t=(0,O.c)(45),{id:n,name:r,gelesen:i,hatUpdate:o,fest:s,onStart:c,onFreigeben:l,laeuftGerade:u}=e,{data:d,isPending:f}=m(n),p;t[0]!==d||t[1]!==n?(p=w(n,d),t[0]=d,t[1]=n,t[2]=p):p=t[2];let h=p,g=o?h.neu??`neu`:null,_;t[3]!==d?.count||t[4]!==d?.summary||t[5]!==i||t[6]!==o||t[7]!==n||t[8]!==f?(_=i?o?d?.summary?.trim()||(n===`os`&&d?.count?`Paketliste unten in den Details.`:f?`Wird gelesen …`:``):`Aktuell.`:`Wird gerade geprüft …`,t[3]=d?.count,t[4]=d?.summary,t[5]=i,t[6]=o,t[7]=n,t[8]=f,t[9]=_):_=t[9];let v=_,y;t[10]===g?y=t[11]:(y=g?(0,A.jsx)(`span`,{className:`text-cyan`,children:g}):(0,A.jsx)(`span`,{className:`text-text-3`,children:`–`}),t[10]=g,t[11]=y);let b=y,x;t[12]===r?x=t[13]:(x=(0,A.jsx)(`span`,{role:`rowheader`,className:`text-[15px] font-semibold`,children:r}),t[12]=r,t[13]=x);let S;t[14]!==g||t[15]!==b?(S=g&&(0,A.jsxs)(A.Fragment,{children:[` → `,b]}),t[14]=g,t[15]=b,t[16]=S):S=t[16];let C;t[17]!==S||t[18]!==h.laeuft?(C=(0,A.jsxs)(`span`,{role:`cell`,className:`ziffern text-right text-sm text-text-2 md:hidden`,children:[h.laeuft,S]}),t[17]=S,t[18]=h.laeuft,t[19]=C):C=t[19];let T;t[20]===h.laeuft?T=t[21]:(T=(0,A.jsx)(`span`,{role:`cell`,className:`ziffern hidden text-sm text-text-2 md:block`,children:h.laeuft}),t[20]=h.laeuft,t[21]=T);let E;t[22]===b?E=t[23]:(E=(0,A.jsx)(`span`,{role:`cell`,className:`ziffern hidden text-sm md:block`,children:b}),t[22]=b,t[23]=E);let D;t[24]!==s||t[25]!==r?(D=s&&(0,A.jsxs)(`span`,{className:`mb-1.5 block text-bernstein`,children:[`Festgehalten seit `,s.seit,` auf `,s.version,`: `,s.grund,`. Der Sonntags-Lauf überspringt `,r,`.`]}),t[24]=s,t[25]=r,t[26]=D):D=t[26];let k;t[27]===v?k=t[28]:(k=(0,A.jsx)(`span`,{className:`line-clamp-3 whitespace-pre-line`,children:v}),t[27]=v,t[28]=k);let j;t[29]!==k||t[30]!==D?(j=(0,A.jsxs)(`span`,{role:`cell`,className:`col-span-2 text-sm leading-relaxed text-text-2 md:col-span-1`,children:[D,k]}),t[29]=k,t[30]=D,t[31]=j):j=t[31];let M;t[32]!==s||t[33]!==o||t[34]!==u||t[35]!==l||t[36]!==c?(M=(s||o)&&(0,A.jsxs)(`span`,{role:`cell`,className:`col-span-2 flex flex-wrap gap-2 md:col-span-1 md:flex-col md:items-end`,children:[s&&(0,A.jsx)(a,{variant:`outline`,size:`sm`,onClick:l,children:`Freigeben`}),o&&(0,A.jsx)(a,{variant:`outline`,size:`sm`,onClick:c,disabled:u,children:`Aktualisieren`})]}),t[32]=s,t[33]=o,t[34]=u,t[35]=l,t[36]=c,t[37]=M):M=t[37];let N;return t[38]!==j||t[39]!==M||t[40]!==x||t[41]!==C||t[42]!==T||t[43]!==E?(N=(0,A.jsxs)(`div`,{role:`row`,className:`grid grid-cols-[minmax(0,1fr)_auto] items-baseline gap-x-4 gap-y-2 border-t border-linie py-3.5 md:grid-cols-[170px_100px_170px_minmax(0,1fr)_auto] md:items-start`,children:[x,C,T,E,j,M]}),t[38]=j,t[39]=M,t[40]=x,t[41]=C,t[42]=T,t[43]=E,t[44]=N):N=t[44],N}var H={rot:`rot`,gelb:`bernstein`,gruen:`gruen`,info:`cyan`,grau:`grau`},U={rot:`bg-rot`,gelb:`bg-bernstein`,gruen:`bg-gruen`,info:`bg-cyan`,grau:`bg-text-3`};function W(e){let t=(0,O.c)(19),{lauf:n}=e,r;t[0]===n.start?r=t[1]:(r=S(n.start),t[0]=n.start,t[1]=r);let i;t[2]===r?i=t[3]:(i=(0,A.jsx)(`span`,{className:`ziffern text-sm text-text-3`,children:r}),t[2]=r,t[3]=i);let a;t[4]===n.anlass?a=t[5]:(a=(0,A.jsx)(`span`,{className:`min-w-0 text-[15px]`,children:n.anlass}),t[4]=n.anlass,t[5]=a);let o=H[n.stufe],s;t[6]!==n.titel||t[7]!==o?(s=(0,A.jsx)(x,{art:o,children:n.titel}),t[6]=n.titel,t[7]=o,t[8]=s):s=t[8];let c;t[9]!==i||t[10]!==a||t[11]!==s?(c=(0,A.jsxs)(`div`,{className:`grid grid-cols-[auto_minmax(0,1fr)_auto] items-center gap-3 md:grid-cols-[112px_minmax(0,1fr)_auto]`,children:[i,a,s]}),t[9]=i,t[10]=a,t[11]=s,t[12]=c):c=t[12];let l;t[13]!==n.stufe||t[14]!==n.zeilen?(l=n.stufe!==`grau`&&n.zeilen.length>0&&(0,A.jsx)(`ul`,{className:`m-0 flex list-none flex-col gap-1 p-0 md:pl-[124px]`,children:n.zeilen.map(G)}),t[13]=n.stufe,t[14]=n.zeilen,t[15]=l):l=t[15];let u;return t[16]!==c||t[17]!==l?(u=(0,A.jsxs)(`li`,{className:`flex flex-col gap-2 border-t border-linie py-3`,children:[c,l]}),t[16]=c,t[17]=l,t[18]=u):u=t[18],u}function G(e){return(0,A.jsxs)(`li`,{className:`flex items-baseline gap-2 text-sm leading-snug text-text-2`,children:[(0,A.jsx)(`span`,{"aria-hidden":!0,className:r(`size-1.5 shrink-0 -translate-y-px rounded-full`,U[e.stufe])}),(0,A.jsxs)(`span`,{className:`min-w-0`,children:[(0,A.jsx)(`span`,{className:`text-foreground`,children:e.baustein}),` · `,e.text]})]},`${e.baustein}-${e.text}`)}function K(e){let t=(0,O.c)(13),{job:n}=e,r=n.state===`done`?`gruen`:n.state===`failed`?`rot`:`cyan`,i=n.state===`done`?`Fertig`:n.state===`failed`?`Fehler`:n.state===`queued`?`Wartet`:`Läuft`,a;t[0]===n.label?a=t[1]:(a=(0,A.jsx)(`span`,{className:`text-[15px] font-semibold`,children:n.label}),t[0]=n.label,t[1]=a);let o;t[2]!==r||t[3]!==i?(o=(0,A.jsx)(x,{art:r,children:i}),t[2]=r,t[3]=i,t[4]=o):o=t[4];let s;t[5]!==a||t[6]!==o?(s=(0,A.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[a,o]}),t[5]=a,t[6]=o,t[7]=s):s=t[7];let c;t[8]===n.log?c=t[9]:(c=n.log&&n.log.length>0&&(0,A.jsx)(`pre`,{className:`ziffern max-h-40 overflow-auto rounded-md bg-[#0b0d0f] p-2 text-xs whitespace-pre-wrap text-text-2`,children:n.log.slice(-8).join(` -`)}),t[8]=n.log,t[9]=c);let l;return t[10]!==s||t[11]!==c?(l=(0,A.jsxs)(`div`,{className:`flex flex-col gap-2 rounded-xl border border-linie bg-erhaben/50 p-3`,children:[s,c]}),t[10]=s,t[11]=c,t[12]=l):l=t[12],l}function q(e){return e.mtime?S(new Date(e.mtime*1e3).toISOString()):e.snapshot}function J(){let e=(0,O.c)(60),t=g(),n=C(),r=_(),i=D(),o=E(),s=y(),c=b(),l=h(),[u,d]=(0,k.useState)(null),f;e[0]===t.data?.updates.bausteine?f=e[1]:(f=new Set(t.data?.updates.bausteine.map(re)??[]),e[0]=t.data?.updates.bausteine,e[1]=f);let p=f,m;e[2]===t.data?.updates.festgehalten?m=e[3]:(m=new Map((t.data?.updates.festgehalten??[]).map(ne)),e[2]=t.data?.updates.festgehalten,e[3]=m);let x=m,S;if(e[4]!==x||e[5]!==s||e[6]!==n.data?.jobs||e[7]!==p||e[8]!==t.data?.updates||e[9]!==t.isPending||e[10]!==o){let r=(n.data?.jobs??[]).filter(te),i=r.some(ee),c;e[12]===o?c=e[13]:(c=()=>o.mutate(`pruefen`),e[12]=o,e[13]=c);let l;e[14]!==c||e[15]!==o.isPending?(l=(0,A.jsx)(a,{variant:`outline`,onClick:c,disabled:o.isPending,children:`Nach Neuem suchen`}),e[14]=c,e[15]=o.isPending,e[16]=l):l=e[16];let u;e[17]===Symbol.for(`react.memo_cache_sentinel`)?(u=()=>d({art:`alle`}),e[17]=u):u=e[17];let f;e[18]===Symbol.for(`react.memo_cache_sentinel`)?(f=(0,A.jsx)(`p`,{className:`-mt-2 text-[15px] text-text-2`,children:`Jeden Sonntag um 04:30 automatisch. Vorher wird gesichert, danach geprüft.`}),e[18]=f):f=e[18],S=(0,A.jsxs)(T,{titel:`Updates`,rechts:(0,A.jsxs)(`div`,{className:`flex flex-wrap gap-2.5`,children:[l,(0,A.jsx)(a,{onClick:u,disabled:i||p.size===0,children:`Alles jetzt aktualisieren`})]}),children:[f,t.isPending?(0,A.jsx)(v,{text:`Updates werden gelesen …`}):(0,A.jsxs)(`div`,{role:`table`,"aria-label":`Bausteine und ihre Updates`,className:`flex flex-col`,children:[(0,A.jsxs)(`div`,{role:`row`,className:`schild hidden grid-cols-[170px_100px_170px_minmax(0,1fr)_auto] gap-x-4 pb-2 text-xs font-semibold text-text-3 md:grid`,children:[(0,A.jsx)(`span`,{role:`columnheader`,children:`Baustein`}),(0,A.jsx)(`span`,{role:`columnheader`,children:`Läuft`}),(0,A.jsx)(`span`,{role:`columnheader`,children:`Neu`}),(0,A.jsx)(`span`,{role:`columnheader`,children:`Was sich ändert`}),(0,A.jsx)(`span`,{role:`columnheader`,className:`sr-only`,children:`Aktion`})]}),B.map(e=>(0,A.jsx)(V,{id:e.id,name:e.name,gelesen:t.data?.updates.gelesen??!1,hatUpdate:p.has(e.id),fest:x.get(e.id),laeuftGerade:i,onStart:()=>o.mutate(e.id),onFreigeben:()=>s.mutate(e.id)},e.id))]}),r.length>0&&(0,A.jsxs)(`div`,{className:`flex flex-col gap-2.5`,children:[(0,A.jsx)(`h3`,{className:`schild text-sm text-text-3`,children:`Laufende und letzte Aufträge`}),r.slice(-3).reverse().map(X)]})]}),e[4]=x,e[5]=s,e[6]=n.data?.jobs,e[7]=p,e[8]=t.data?.updates,e[9]=t.isPending,e[10]=o,e[11]=S}else S=e[11];let w;e[19]!==r.data||e[20]!==r.isPending?(w=(0,A.jsx)(T,{titel:`Verlauf`,children:r.data?.laeufe.length?(0,A.jsx)(`ol`,{className:`m-0 flex list-none flex-col p-0`,children:r.data.laeufe.map(Y)}):(0,A.jsx)(`p`,{className:`text-[15px] text-text-2`,children:r.isPending?`Wird gelesen …`:`Noch keine Update-Läufe aufgezeichnet.`})}),e[19]=r.data,e[20]=r.isPending,e[21]=w):w=e[21];let j;e[22]===c?j=e[23]:(j=()=>c.mutate(void 0),e[22]=c,e[23]=j);let M;e[24]!==c.isPending||e[25]!==j?(M=(0,A.jsx)(a,{variant:`outline`,size:`sm`,onClick:j,disabled:c.isPending,children:`Jetzt sichern`}),e[24]=c.isPending,e[25]=j,e[26]=M):M=e[26];let N;e[27]===Symbol.for(`react.memo_cache_sentinel`)?(N=(0,A.jsx)(`p`,{className:`-mt-2 text-[15px] text-text-2`,children:`Täglich um 03:35, mit Kopie auf einem zweiten Gerät.`}),e[27]=N):N=e[27];let P;if(e[28]!==i.data?.available||e[29]!==i.data?.backups){let t;e[31]===i.data?.available?t=e[32]:(t=e=>(0,A.jsxs)(`li`,{className:`flex items-center justify-between gap-3 border-t border-linie py-2.5`,children:[(0,A.jsx)(`span`,{className:`ziffern text-sm`,children:q(e)}),(0,A.jsxs)(`span`,{className:`flex items-center gap-3`,children:[(0,A.jsxs)(`span`,{className:`ziffern text-xs text-text-3`,children:[e.size_mb.toLocaleString(`de-DE`),` MB`]}),(0,A.jsx)(a,{variant:`ghost`,size:`sm`,disabled:!i.data?.available,onClick:()=>d({art:`zurueck`,datei:e.file,zeit:q(e)}),children:`Zurückspielen`})]})]},e.file),e[31]=i.data?.available,e[32]=t),P=(i.data?.backups??[]).slice(0,5).map(t),e[28]=i.data?.available,e[29]=i.data?.backups,e[30]=P}else P=e[30];let F;e[33]===P?F=e[34]:(F=(0,A.jsx)(`ul`,{className:`m-0 flex list-none flex-col p-0`,children:P}),e[33]=P,e[34]=F);let I;e[35]!==M||e[36]!==F?(I=(0,A.jsxs)(T,{titel:`Sicherungen`,rechts:M,children:[N,F]}),e[35]=M,e[36]=F,e[37]=I):I=e[37];let L;e[38]!==w||e[39]!==I?(L=(0,A.jsxs)(`div`,{className:`grid gap-5 md:gap-6 lg:grid-cols-[minmax(0,1.4fr)_minmax(0,1fr)]`,children:[w,I]}),e[38]=w,e[39]=I,e[40]=L):L=e[40];let R=u?.art===`alle`,H;e[41]===Symbol.for(`react.memo_cache_sentinel`)?(H=()=>d(null),e[41]=H):H=e[41];let U;e[42]===o?U=e[43]:(U=()=>{o.mutate(`alle`),d(null)},e[42]=o,e[43]=U);let W;e[44]!==R||e[45]!==U?(W=(0,A.jsx)(z,{offen:R,titel:`Alles jetzt aktualisieren?`,text:`Betriebssystem, Motor, llama-swap und Hermes werden nacheinander aktualisiert. Vorher wird gesichert, danach geprüft. Lucy ist dabei ein paar Minuten nicht erreichbar.`,knopf:`Aktualisieren`,onNein:H,onJa:U}),e[44]=R,e[45]=U,e[46]=W):W=e[46];let G=u?.art===`zurueck`,K=`Die Einstellungen von Hermes und llama-swap werden auf den Stand von ${u?.art===`zurueck`?u.zeit:``} gesetzt. Vorher wird der jetzige Stand gesichert. Die Dienste starten danach neu.`,J;e[47]===Symbol.for(`react.memo_cache_sentinel`)?(J=()=>d(null),e[47]=J):J=e[47];let Z;e[48]!==u||e[49]!==l?(Z=()=>{u?.art===`zurueck`&&l.mutate(u.datei),d(null)},e[48]=u,e[49]=l,e[50]=Z):Z=e[50];let Q;e[51]!==G||e[52]!==K||e[53]!==Z?(Q=(0,A.jsx)(z,{offen:G,gefahr:!0,titel:`Sicherung zurückspielen?`,text:K,knopf:`Zurückspielen`,onNein:J,onJa:Z}),e[51]=G,e[52]=K,e[53]=Z,e[54]=Q):Q=e[54];let $;return e[55]!==L||e[56]!==W||e[57]!==Q||e[58]!==S?($=(0,A.jsxs)(A.Fragment,{children:[S,L,W,Q]}),e[55]=L,e[56]=W,e[57]=Q,e[58]=S,e[59]=$):$=e[59],$}function Y(e){return(0,A.jsx)(W,{lauf:e},e.start)}function X(e){return(0,A.jsx)(K,{job:e},e.id)}function ee(e){return e.state===`running`||e.state===`queued`}function te(e){return e.group===`maintenance`}function ne(e){return[e.baustein,e]}function re(e){return e.id}export{J as UpdatesSeite}; \ No newline at end of file diff --git a/frontend/dist/assets/Updates-DPFIId2v.js b/frontend/dist/assets/Updates-DPFIId2v.js new file mode 100644 index 0000000..035d4c6 --- /dev/null +++ b/frontend/dist/assets/Updates-DPFIId2v.js @@ -0,0 +1,2 @@ +import{c as e,f as t,i as n,s as r,t as i,u as a}from"./button-Dd8hfusv.js";import{C as o,D as s,E as c,O as l,T as u,a as d,c as f,h as p,m,o as h,p as g,s as _,t as v,w as y}from"./index-ZVRs0IGR.js";import{t as b}from"./Bestaetigen-VrcNpcBb.js";var x=r(),S=t(a(),1),C=e(),w=[{id:`os`,name:`Betriebssystem`},{id:`engine`,name:`Motor (llama.cpp)`},{id:`swap`,name:`llama-swap`},{id:`hermes`,name:`Hermes`}];function T(e){let t=(0,x.c)(45),{id:n,name:r,gelesen:a,hatUpdate:o,fest:s,onStart:c,onFreigeben:l,laeuftGerade:f}=e,{data:p,isPending:m}=u(n),h;t[0]!==p||t[1]!==n?(h=d(n,p),t[0]=p,t[1]=n,t[2]=h):h=t[2];let g=h,_=o?g.neu??`neu`:null,v;t[3]!==p?.count||t[4]!==p?.summary||t[5]!==a||t[6]!==o||t[7]!==n||t[8]!==m?(v=a?o?p?.summary?.trim()||(n===`os`&&p?.count?`Paketliste unten in den Details.`:m?`Wird gelesen …`:``):`Aktuell.`:`Wird gerade geprüft …`,t[3]=p?.count,t[4]=p?.summary,t[5]=a,t[6]=o,t[7]=n,t[8]=m,t[9]=v):v=t[9];let y=v,b;t[10]===_?b=t[11]:(b=_?(0,C.jsx)(`span`,{className:`text-cyan`,children:_}):(0,C.jsx)(`span`,{className:`text-text-3`,children:`–`}),t[10]=_,t[11]=b);let S=b,w;t[12]===r?w=t[13]:(w=(0,C.jsx)(`span`,{role:`rowheader`,className:`text-[15px] font-semibold`,children:r}),t[12]=r,t[13]=w);let T;t[14]!==_||t[15]!==S?(T=_&&(0,C.jsxs)(C.Fragment,{children:[` → `,S]}),t[14]=_,t[15]=S,t[16]=T):T=t[16];let E;t[17]!==T||t[18]!==g.laeuft?(E=(0,C.jsxs)(`span`,{role:`cell`,className:`ziffern text-right text-sm text-text-2 md:hidden`,children:[g.laeuft,T]}),t[17]=T,t[18]=g.laeuft,t[19]=E):E=t[19];let D;t[20]===g.laeuft?D=t[21]:(D=(0,C.jsx)(`span`,{role:`cell`,className:`ziffern hidden text-sm text-text-2 md:block`,children:g.laeuft}),t[20]=g.laeuft,t[21]=D);let O;t[22]===S?O=t[23]:(O=(0,C.jsx)(`span`,{role:`cell`,className:`ziffern hidden text-sm md:block`,children:S}),t[22]=S,t[23]=O);let k;t[24]!==s||t[25]!==r?(k=s&&(0,C.jsxs)(`span`,{className:`mb-1.5 block text-bernstein`,children:[`Festgehalten seit `,s.seit,` auf `,s.version,`: `,s.grund,`. Der Sonntags-Lauf überspringt `,r,`.`]}),t[24]=s,t[25]=r,t[26]=k):k=t[26];let A;t[27]===y?A=t[28]:(A=(0,C.jsx)(`span`,{className:`line-clamp-3 whitespace-pre-line`,children:y}),t[27]=y,t[28]=A);let j;t[29]!==A||t[30]!==k?(j=(0,C.jsxs)(`span`,{role:`cell`,className:`col-span-2 text-sm leading-relaxed text-text-2 md:col-span-1`,children:[k,A]}),t[29]=A,t[30]=k,t[31]=j):j=t[31];let M;t[32]!==s||t[33]!==o||t[34]!==f||t[35]!==l||t[36]!==c?(M=(s||o)&&(0,C.jsxs)(`span`,{role:`cell`,className:`col-span-2 flex flex-wrap gap-2 md:col-span-1 md:flex-col md:items-end`,children:[s&&(0,C.jsx)(i,{variant:`outline`,size:`sm`,onClick:l,children:`Freigeben`}),o&&(0,C.jsx)(i,{variant:`outline`,size:`sm`,onClick:c,disabled:f,children:`Aktualisieren`})]}),t[32]=s,t[33]=o,t[34]=f,t[35]=l,t[36]=c,t[37]=M):M=t[37];let N;return t[38]!==j||t[39]!==M||t[40]!==w||t[41]!==E||t[42]!==D||t[43]!==O?(N=(0,C.jsxs)(`div`,{role:`row`,className:`grid grid-cols-[minmax(0,1fr)_auto] items-baseline gap-x-4 gap-y-2 border-t border-linie py-3.5 md:grid-cols-[170px_100px_170px_minmax(0,1fr)_auto] md:items-start`,children:[w,E,D,O,j,M]}),t[38]=j,t[39]=M,t[40]=w,t[41]=E,t[42]=D,t[43]=O,t[44]=N):N=t[44],N}var E={rot:`rot`,gelb:`bernstein`,gruen:`gruen`,info:`cyan`,grau:`grau`},D={rot:`bg-rot`,gelb:`bg-bernstein`,gruen:`bg-gruen`,info:`bg-cyan`,grau:`bg-text-3`};function O(e){let t=(0,x.c)(19),{lauf:n}=e,r;t[0]===n.start?r=t[1]:(r=f(n.start),t[0]=n.start,t[1]=r);let i;t[2]===r?i=t[3]:(i=(0,C.jsx)(`span`,{className:`ziffern text-sm text-text-3`,children:r}),t[2]=r,t[3]=i);let a;t[4]===n.anlass?a=t[5]:(a=(0,C.jsx)(`span`,{className:`min-w-0 text-[15px]`,children:n.anlass}),t[4]=n.anlass,t[5]=a);let o=E[n.stufe],s;t[6]!==n.titel||t[7]!==o?(s=(0,C.jsx)(h,{art:o,children:n.titel}),t[6]=n.titel,t[7]=o,t[8]=s):s=t[8];let c;t[9]!==i||t[10]!==a||t[11]!==s?(c=(0,C.jsxs)(`div`,{className:`grid grid-cols-[auto_minmax(0,1fr)_auto] items-center gap-3 md:grid-cols-[112px_minmax(0,1fr)_auto]`,children:[i,a,s]}),t[9]=i,t[10]=a,t[11]=s,t[12]=c):c=t[12];let l;t[13]!==n.stufe||t[14]!==n.zeilen?(l=n.stufe!==`grau`&&n.zeilen.length>0&&(0,C.jsx)(`ul`,{className:`m-0 flex list-none flex-col gap-1 p-0 md:pl-[124px]`,children:n.zeilen.map(k)}),t[13]=n.stufe,t[14]=n.zeilen,t[15]=l):l=t[15];let u;return t[16]!==c||t[17]!==l?(u=(0,C.jsxs)(`li`,{className:`flex flex-col gap-2 border-t border-linie py-3`,children:[c,l]}),t[16]=c,t[17]=l,t[18]=u):u=t[18],u}function k(e){return(0,C.jsxs)(`li`,{className:`flex items-baseline gap-2 text-sm leading-snug text-text-2`,children:[(0,C.jsx)(`span`,{"aria-hidden":!0,className:n(`size-1.5 shrink-0 -translate-y-px rounded-full`,D[e.stufe])}),(0,C.jsxs)(`span`,{className:`min-w-0`,children:[(0,C.jsx)(`span`,{className:`text-foreground`,children:e.baustein}),` · `,e.text]})]},`${e.baustein}-${e.text}`)}function A(e){let t=(0,x.c)(13),{job:n}=e,r=n.state===`done`?`gruen`:n.state===`failed`?`rot`:`cyan`,i=n.state===`done`?`Fertig`:n.state===`failed`?`Fehler`:n.state===`queued`?`Wartet`:`Läuft`,a;t[0]===n.label?a=t[1]:(a=(0,C.jsx)(`span`,{className:`text-[15px] font-semibold`,children:n.label}),t[0]=n.label,t[1]=a);let o;t[2]!==r||t[3]!==i?(o=(0,C.jsx)(h,{art:r,children:i}),t[2]=r,t[3]=i,t[4]=o):o=t[4];let s;t[5]!==a||t[6]!==o?(s=(0,C.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[a,o]}),t[5]=a,t[6]=o,t[7]=s):s=t[7];let c;t[8]===n.log?c=t[9]:(c=n.log&&n.log.length>0&&(0,C.jsx)(`pre`,{className:`ziffern max-h-40 overflow-auto rounded-md bg-[#0b0d0f] p-2 text-xs whitespace-pre-wrap text-text-2`,children:n.log.slice(-8).join(` +`)}),t[8]=n.log,t[9]=c);let l;return t[10]!==s||t[11]!==c?(l=(0,C.jsxs)(`div`,{className:`flex flex-col gap-2 rounded-xl border border-linie bg-erhaben/50 p-3`,children:[s,c]}),t[10]=s,t[11]=c,t[12]=l):l=t[12],l}function j(e){return e.mtime?f(new Date(e.mtime*1e3).toISOString()):e.snapshot}function M(){let e=(0,x.c)(60),t=y(),n=p(),r=s(),a=o(),u=c(),d=g(),f=m(),h=l(),[E,D]=(0,S.useState)(null),O;e[0]===t.data?.updates.bausteine?O=e[1]:(O=new Set(t.data?.updates.bausteine.map(re)??[]),e[0]=t.data?.updates.bausteine,e[1]=O);let k=O,A;e[2]===t.data?.updates.festgehalten?A=e[3]:(A=new Map((t.data?.updates.festgehalten??[]).map(ne)),e[2]=t.data?.updates.festgehalten,e[3]=A);let M=A,F;if(e[4]!==M||e[5]!==d||e[6]!==n.data?.jobs||e[7]!==k||e[8]!==t.data?.updates||e[9]!==t.isPending||e[10]!==u){let r=(n.data?.jobs??[]).filter(te),a=r.some(ee),o;e[12]===u?o=e[13]:(o=()=>u.mutate(`pruefen`),e[12]=u,e[13]=o);let s;e[14]!==o||e[15]!==u.isPending?(s=(0,C.jsx)(i,{variant:`outline`,onClick:o,disabled:u.isPending,children:`Nach Neuem suchen`}),e[14]=o,e[15]=u.isPending,e[16]=s):s=e[16];let c;e[17]===Symbol.for(`react.memo_cache_sentinel`)?(c=()=>D({art:`alle`}),e[17]=c):c=e[17];let l;e[18]===Symbol.for(`react.memo_cache_sentinel`)?(l=(0,C.jsx)(`p`,{className:`-mt-2 text-[15px] text-text-2`,children:`Jeden Sonntag um 04:30 automatisch. Vorher wird gesichert, danach geprüft.`}),e[18]=l):l=e[18],F=(0,C.jsxs)(v,{titel:`Updates`,rechts:(0,C.jsxs)(`div`,{className:`flex flex-wrap gap-2.5`,children:[s,(0,C.jsx)(i,{onClick:c,disabled:a||k.size===0,children:`Alles jetzt aktualisieren`})]}),children:[l,t.isPending?(0,C.jsx)(_,{text:`Updates werden gelesen …`}):(0,C.jsxs)(`div`,{role:`table`,"aria-label":`Bausteine und ihre Updates`,className:`flex flex-col`,children:[(0,C.jsxs)(`div`,{role:`row`,className:`schild hidden grid-cols-[170px_100px_170px_minmax(0,1fr)_auto] gap-x-4 pb-2 text-xs font-semibold text-text-3 md:grid`,children:[(0,C.jsx)(`span`,{role:`columnheader`,children:`Baustein`}),(0,C.jsx)(`span`,{role:`columnheader`,children:`Läuft`}),(0,C.jsx)(`span`,{role:`columnheader`,children:`Neu`}),(0,C.jsx)(`span`,{role:`columnheader`,children:`Was sich ändert`}),(0,C.jsx)(`span`,{role:`columnheader`,className:`sr-only`,children:`Aktion`})]}),w.map(e=>(0,C.jsx)(T,{id:e.id,name:e.name,gelesen:t.data?.updates.gelesen??!1,hatUpdate:k.has(e.id),fest:M.get(e.id),laeuftGerade:a,onStart:()=>u.mutate(e.id),onFreigeben:()=>d.mutate(e.id)},e.id))]}),r.length>0&&(0,C.jsxs)(`div`,{className:`flex flex-col gap-2.5`,children:[(0,C.jsx)(`h3`,{className:`schild text-sm text-text-3`,children:`Laufende und letzte Aufträge`}),r.slice(-3).reverse().map(P)]})]}),e[4]=M,e[5]=d,e[6]=n.data?.jobs,e[7]=k,e[8]=t.data?.updates,e[9]=t.isPending,e[10]=u,e[11]=F}else F=e[11];let I;e[19]!==r.data||e[20]!==r.isPending?(I=(0,C.jsx)(v,{titel:`Verlauf`,children:r.data?.laeufe.length?(0,C.jsx)(`ol`,{className:`m-0 flex list-none flex-col p-0`,children:r.data.laeufe.map(N)}):(0,C.jsx)(`p`,{className:`text-[15px] text-text-2`,children:r.isPending?`Wird gelesen …`:`Noch keine Update-Läufe aufgezeichnet.`})}),e[19]=r.data,e[20]=r.isPending,e[21]=I):I=e[21];let L;e[22]===f?L=e[23]:(L=()=>f.mutate(void 0),e[22]=f,e[23]=L);let R;e[24]!==f.isPending||e[25]!==L?(R=(0,C.jsx)(i,{variant:`outline`,size:`sm`,onClick:L,disabled:f.isPending,children:`Jetzt sichern`}),e[24]=f.isPending,e[25]=L,e[26]=R):R=e[26];let z;e[27]===Symbol.for(`react.memo_cache_sentinel`)?(z=(0,C.jsx)(`p`,{className:`-mt-2 text-[15px] text-text-2`,children:`Täglich um 03:35, mit Kopie auf einem zweiten Gerät.`}),e[27]=z):z=e[27];let B;if(e[28]!==a.data?.available||e[29]!==a.data?.backups){let t;e[31]===a.data?.available?t=e[32]:(t=e=>(0,C.jsxs)(`li`,{className:`flex items-center justify-between gap-3 border-t border-linie py-2.5`,children:[(0,C.jsx)(`span`,{className:`ziffern text-sm`,children:j(e)}),(0,C.jsxs)(`span`,{className:`flex items-center gap-3`,children:[(0,C.jsxs)(`span`,{className:`ziffern text-xs text-text-3`,children:[e.size_mb.toLocaleString(`de-DE`),` MB`]}),(0,C.jsx)(i,{variant:`ghost`,size:`sm`,disabled:!a.data?.available,onClick:()=>D({art:`zurueck`,datei:e.file,zeit:j(e)}),children:`Zurückspielen`})]})]},e.file),e[31]=a.data?.available,e[32]=t),B=(a.data?.backups??[]).slice(0,5).map(t),e[28]=a.data?.available,e[29]=a.data?.backups,e[30]=B}else B=e[30];let V;e[33]===B?V=e[34]:(V=(0,C.jsx)(`ul`,{className:`m-0 flex list-none flex-col p-0`,children:B}),e[33]=B,e[34]=V);let H;e[35]!==R||e[36]!==V?(H=(0,C.jsxs)(v,{titel:`Sicherungen`,rechts:R,children:[z,V]}),e[35]=R,e[36]=V,e[37]=H):H=e[37];let U;e[38]!==I||e[39]!==H?(U=(0,C.jsxs)(`div`,{className:`grid gap-5 md:gap-6 lg:grid-cols-[minmax(0,1.4fr)_minmax(0,1fr)]`,children:[I,H]}),e[38]=I,e[39]=H,e[40]=U):U=e[40];let W=E?.art===`alle`,G;e[41]===Symbol.for(`react.memo_cache_sentinel`)?(G=()=>D(null),e[41]=G):G=e[41];let K;e[42]===u?K=e[43]:(K=()=>{u.mutate(`alle`),D(null)},e[42]=u,e[43]=K);let q;e[44]!==W||e[45]!==K?(q=(0,C.jsx)(b,{offen:W,titel:`Alles jetzt aktualisieren?`,text:`Betriebssystem, Motor, llama-swap und Hermes werden nacheinander aktualisiert. Vorher wird gesichert, danach geprüft. Lucy ist dabei ein paar Minuten nicht erreichbar.`,knopf:`Aktualisieren`,onNein:G,onJa:K}),e[44]=W,e[45]=K,e[46]=q):q=e[46];let J=E?.art===`zurueck`,Y=`Die Einstellungen von Hermes und llama-swap werden auf den Stand von ${E?.art===`zurueck`?E.zeit:``} gesetzt. Vorher wird der jetzige Stand gesichert. Die Dienste starten danach neu.`,X;e[47]===Symbol.for(`react.memo_cache_sentinel`)?(X=()=>D(null),e[47]=X):X=e[47];let Z;e[48]!==E||e[49]!==h?(Z=()=>{E?.art===`zurueck`&&h.mutate(E.datei),D(null)},e[48]=E,e[49]=h,e[50]=Z):Z=e[50];let Q;e[51]!==J||e[52]!==Y||e[53]!==Z?(Q=(0,C.jsx)(b,{offen:J,gefahr:!0,titel:`Sicherung zurückspielen?`,text:Y,knopf:`Zurückspielen`,onNein:X,onJa:Z}),e[51]=J,e[52]=Y,e[53]=Z,e[54]=Q):Q=e[54];let $;return e[55]!==U||e[56]!==q||e[57]!==Q||e[58]!==F?($=(0,C.jsxs)(C.Fragment,{children:[F,U,q,Q]}),e[55]=U,e[56]=q,e[57]=Q,e[58]=F,e[59]=$):$=e[59],$}function N(e){return(0,C.jsx)(O,{lauf:e},e.start)}function P(e){return(0,C.jsx)(A,{job:e},e.id)}function ee(e){return e.state===`running`||e.state===`queued`}function te(e){return e.group===`maintenance`}function ne(e){return[e.baustein,e]}function re(e){return e.id}export{M as UpdatesSeite}; \ No newline at end of file diff --git a/frontend/dist/assets/index-C3amg33Y.css b/frontend/dist/assets/index-C3amg33Y.css new file mode 100644 index 0000000..67eddcc --- /dev/null +++ b/frontend/dist/assets/index-C3amg33Y.css @@ -0,0 +1,2 @@ +/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */ +@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){:root,:host{--shimmer-angle:20deg}*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-animation-delay:0s;--tw-animation-direction:normal;--tw-animation-duration:initial;--tw-animation-fill-mode:none;--tw-animation-iteration-count:1;--tw-enter-blur:0;--tw-enter-opacity:1;--tw-enter-rotate:0;--tw-enter-scale:1;--tw-enter-translate-x:0;--tw-enter-translate-y:0;--tw-exit-blur:0;--tw-exit-opacity:1;--tw-exit-rotate:0;--tw-exit-scale:1;--tw-exit-translate-x:0;--tw-exit-translate-y:0;--scroll-fade-t:0px;--scroll-fade-b:0px;--scroll-fade-s:0px;--scroll-fade-e:0px;--scroll-fade-mask:initial;--shimmer-image:initial;--shimmer-text-fill:initial}}}@layer theme{:root,:host{--font-mono:"JetBrains Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;--color-black:#000;--spacing:.25rem;--container-sm:24rem;--container-lg:32rem;--container-xl:36rem;--container-2xl:42rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-normal:0em;--leading-tight:1.25;--leading-snug:1.375;--leading-relaxed:1.625;--ease-in-out:cubic-bezier(.4, 0, .2, 1);--blur-xs:4px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:"Barlow", "Segoe UI", system-ui, sans-serif;--default-mono-font-family:"JetBrains Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;--font-anzeige:"Barlow Condensed", "Barlow", "Segoe UI", sans-serif}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*{border-color:var(--border);outline-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){*{outline-color:color-mix(in oklab, var(--ring) 50%, transparent)}}html{-webkit-font-smoothing:antialiased;font-family:Barlow,Segoe UI,system-ui,sans-serif}body{background-color:var(--background);color:var(--foreground);margin:0}:focus-visible{outline:2px solid var(--cyan);outline-offset:2px}}@layer components;@layer utilities{.\@container{container-type:inline-size}.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.not-sr-only{clip-path:none;white-space:normal;width:auto;height:auto;margin:0;padding:0;position:static;overflow:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.inset-0{inset:0}.inset-x-0{inset-inline:0}.inset-y-0{inset-block:0}.-top-1\.5{top:calc(var(--spacing) * -1.5)}.top-1\/2{top:50%}.top-2{top:calc(var(--spacing) * 2)}.top-3{top:calc(var(--spacing) * 3)}.right-2{right:calc(var(--spacing) * 2)}.right-3{right:calc(var(--spacing) * 3)}.right-4{right:calc(var(--spacing) * 4)}.-bottom-1\.5{bottom:calc(var(--spacing) * -1.5)}.bottom-0{bottom:0}.bottom-24{bottom:calc(var(--spacing) * 24)}.left-0{left:0}.left-1\/2{left:50%}.left-4{left:calc(var(--spacing) * 4)}.isolate{isolation:isolate}.z-40{z-index:40}.z-50{z-index:50}.col-span-2{grid-column:span 2/span 2}.container{width:100%}@media (width>=40rem){.container{max-width:40rem}}@media (width>=48rem){.container{max-width:48rem}}@media (width>=64rem){.container{max-width:64rem}}@media (width>=80rem){.container{max-width:80rem}}@media (width>=96rem){.container{max-width:96rem}}.-m-2{margin:calc(var(--spacing) * -2)}.m-0{margin:0}.-mx-4{margin-inline:calc(var(--spacing) * -4)}.mx-4{margin-inline:calc(var(--spacing) * 4)}.mx-auto{margin-inline:auto}.-mt-2{margin-top:calc(var(--spacing) * -2)}.mt-auto{margin-top:auto}.mr-2{margin-right:calc(var(--spacing) * 2)}.-mb-4{margin-bottom:calc(var(--spacing) * -4)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.ml-0\.5{margin-left:calc(var(--spacing) * .5)}.line-clamp-3{-webkit-line-clamp:3;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.contents{display:contents}.flex{display:flex}.flow-root{display:flow-root}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.table-caption{display:table-caption}.table-cell{display:table-cell}.table-column{display:table-column}.table-column-group{display:table-column-group}.table-footer-group{display:table-footer-group}.table-header-group{display:table-header-group}.table-row{display:table-row}.size-1\.5{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5)}.size-2{width:calc(var(--spacing) * 2);height:calc(var(--spacing) * 2)}.size-2\.5{width:calc(var(--spacing) * 2.5);height:calc(var(--spacing) * 2.5)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-5{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.size-11{width:calc(var(--spacing) * 11);height:calc(var(--spacing) * 11)}.h-0{height:0}.h-2{height:calc(var(--spacing) * 2)}.h-3{height:calc(var(--spacing) * 3)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-10{height:calc(var(--spacing) * 10)}.h-11{height:calc(var(--spacing) * 11)}.h-12{height:calc(var(--spacing) * 12)}.h-14{height:calc(var(--spacing) * 14)}.h-16{height:calc(var(--spacing) * 16)}.h-\[150px\]{height:150px}.h-auto{height:auto}.h-full{height:100%}.max-h-40{max-height:calc(var(--spacing) * 40)}.max-h-\[50vh\]{max-height:50vh}.min-h-11{min-height:calc(var(--spacing) * 11)}.min-h-\[58px\]{min-height:58px}.min-h-\[130px\]{min-height:130px}.min-h-dvh{min-height:100dvh}.w-0\.5{width:calc(var(--spacing) * .5)}.w-\[38px\]{width:38px}.w-full{width:100%}.w-px{width:1px}.max-w-\[200px\]{max-width:200px}.max-w-\[1440px\]{max-width:1440px}.max-w-\[calc\(100\%-2rem\)\]{max-width:calc(100% - 2rem)}.max-w-full{max-width:100%}.min-w-0{min-width:0}.flex-1{flex:1}.shrink-0{flex-shrink:0}.flex-grow{flex-grow:1}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-px{--tw-translate-y:-1px;translate:var(--tw-translate-x) var(--tw-translate-y)}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.resize{resize:both}.list-none{list-style-type:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-\[112px_minmax\(0\,1fr\)_auto\]{grid-template-columns:112px minmax(0,1fr) auto}.grid-cols-\[170px_100px_170px_minmax\(0\,1fr\)_auto\]{grid-template-columns:170px 100px 170px minmax(0,1fr) auto}.grid-cols-\[auto_minmax\(0\,1fr\)_auto\]{grid-template-columns:auto minmax(0,1fr) auto}.grid-cols-\[minmax\(0\,1fr\)_auto\]{grid-template-columns:minmax(0,1fr) auto}.grid-cols-\[minmax\(0\,1fr\)_auto_auto\]{grid-template-columns:minmax(0,1fr) auto auto}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-3\.5{gap:calc(var(--spacing) * 3.5)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-x-4{column-gap:calc(var(--spacing) * 4)}.gap-x-6{column-gap:calc(var(--spacing) * 6)}.gap-y-2{row-gap:calc(var(--spacing) * 2)}.gap-y-6{row-gap:calc(var(--spacing) * 6)}.self-start{align-self:flex-start}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded-2xl{border-radius:calc(var(--radius) * 1.8)}.rounded-\[9px\]{border-radius:9px}.rounded-full{border-radius:2147483647px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) * .8)}.rounded-sm{border-radius:calc(var(--radius) * .6)}.rounded-xl{border-radius:calc(var(--radius) * 1.4)}.rounded-b-xl{border-bottom-right-radius:calc(var(--radius) * 1.4);border-bottom-left-radius:calc(var(--radius) * 1.4)}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-dotted{--tw-border-style:dotted;border-style:dotted}.\!border-linie-stark{border-color:var(--linie-stark)!important}.border-\[\#2a3036\]{border-color:#2a3036}.border-aus-rand{border-color:var(--aus-rand)}.border-bernstein,.border-bernstein\/60{border-color:var(--bernstein)}@supports (color:color-mix(in lab, red, red)){.border-bernstein\/60{border-color:color-mix(in oklab, var(--bernstein) 60%, transparent)}}.border-cyan-rand{border-color:var(--cyan-rand)}.border-gruen-rand{border-color:var(--gruen-rand)}.border-linie{border-color:var(--linie)}.border-linie-stark{border-color:var(--linie-stark)}.border-rot{border-color:var(--rot)}.border-rot-rand{border-color:var(--rot-rand)}.border-transparent{border-color:#0000}.bg-\[\#0b0d0f\]{background-color:#0b0d0f}.bg-\[\#0e1119\]\/95{background-color:oklab(17.8423% -.00041081 -.0172642/.95)}.bg-\[\#121518\]{background-color:#121518}.bg-aus-grund{background-color:var(--aus-grund)}.bg-bernstein{background-color:var(--bernstein)}.bg-bernstein-grund{background-color:var(--bernstein-grund)}.bg-bernstein-lampe{background-color:var(--bernstein-lampe)}.bg-black\/10{background-color:#0000001a}@supports (color:color-mix(in lab, red, red)){.bg-black\/10{background-color:color-mix(in oklab, var(--color-black) 10%, transparent)}}.bg-cyan{background-color:var(--cyan)}.bg-cyan-grund{background-color:var(--cyan-grund)}.bg-cyan\/35{background-color:var(--cyan)}@supports (color:color-mix(in lab, red, red)){.bg-cyan\/35{background-color:color-mix(in oklab, var(--cyan) 35%, transparent)}}.bg-erhaben,.bg-erhaben\/50{background-color:var(--erhaben)}@supports (color:color-mix(in lab, red, red)){.bg-erhaben\/50{background-color:color-mix(in oklab, var(--erhaben) 50%, transparent)}}.bg-gruen{background-color:var(--gruen)}.bg-gruen-grund{background-color:var(--gruen-grund)}.bg-linie{background-color:var(--linie)}.bg-muted\/50{background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.bg-muted\/50{background-color:color-mix(in oklab, var(--muted) 50%, transparent)}}.bg-panel{background-color:var(--panel)}.bg-popover{background-color:var(--popover)}.bg-rot{background-color:var(--rot)}.bg-rot-grund{background-color:var(--rot-grund)}.bg-text-3{background-color:var(--text-3)}.bg-transparent{background-color:#0000}.bg-clip-padding{background-clip:padding-box}.p-0{padding:0}.p-1{padding:var(--spacing)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.px-0{padding-inline:0}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-1{padding-block:var(--spacing)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-3\.5{padding-block:calc(var(--spacing) * 3.5)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-5{padding-block:calc(var(--spacing) * 5)}.py-8{padding-block:calc(var(--spacing) * 8)}.pt-1{padding-top:var(--spacing)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pb-1{padding-bottom:var(--spacing)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-4{padding-bottom:calc(var(--spacing) * 4)}.pb-5{padding-bottom:calc(var(--spacing) * 5)}.pb-28{padding-bottom:calc(var(--spacing) * 28)}.pb-\[calc\(0\.75rem\+env\(safe-area-inset-bottom\)\)\]{padding-bottom:calc(.75rem + env(safe-area-inset-bottom))}.pb-\[calc\(1rem\+env\(safe-area-inset-bottom\)\)\]{padding-bottom:calc(1rem + env(safe-area-inset-bottom))}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-anzeige,.font-heading{font-family:Barlow Condensed,Barlow,Segoe UI,sans-serif}.font-sans{font-family:Barlow,Segoe UI,system-ui,sans-serif}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[13px\]{font-size:13px}.text-\[15px\]{font-size:15px}.text-\[17px\]{font-size:17px}.text-\[28px\]{font-size:28px}.text-\[32px\]{font-size:32px}.text-\[40px\]{font-size:40px}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-\[0\.04em\]{--tw-tracking:.04em;letter-spacing:.04em}.tracking-\[0\.06em\]{--tw-tracking:.06em;letter-spacing:.06em}.tracking-\[0\.12em\]{--tw-tracking:.12em;letter-spacing:.12em}.tracking-\[0\.18em\]{--tw-tracking:.18em;letter-spacing:.18em}.tracking-\[0\.22em\]{--tw-tracking:.22em;letter-spacing:.22em}.tracking-\[0\.26em\]{--tw-tracking:.26em;letter-spacing:.26em}.tracking-normal{--tw-tracking:var(--tracking-normal);letter-spacing:var(--tracking-normal)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-line{white-space:pre-line}.whitespace-pre-wrap{white-space:pre-wrap}.\!text-foreground{color:var(--foreground)!important}.text-\[\#f2c46b\]{color:#f2c46b}.text-aus-text{color:var(--aus-text)}.text-bernstein{color:var(--bernstein)}.text-bernstein-hell{color:var(--bernstein-hell)}.text-cyan{color:var(--cyan)}.text-cyan-text{color:var(--cyan-text)}.text-foreground{color:var(--foreground)}.text-gruen{color:var(--gruen)}.text-gruen-text{color:var(--gruen-text)}.text-muted-foreground{color:var(--muted-foreground)}.text-popover-foreground{color:var(--popover-foreground)}.text-primary-foreground{color:var(--primary-foreground)}.text-rot{color:var(--rot)}.text-rot-text{color:var(--rot-text)}.text-text-2{color:var(--text-2)}.text-text-3{color:var(--text-3)}.capitalize{text-transform:capitalize}.lowercase{text-transform:lowercase}.normal-case{text-transform:none}.uppercase{text-transform:uppercase}.italic{font-style:italic}.diagonal-fractions{--tw-numeric-fraction:diagonal-fractions;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.lining-nums{--tw-numeric-figure:lining-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.proportional-nums{--tw-numeric-spacing:proportional-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.no-underline{text-decoration-line:none}.underline-offset-4{text-underline-offset:4px}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.opacity-70{opacity:.7}.opacity-80{opacity:.8}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_0_8px_rgba\(61\,220\,138\,0\.7\)\]{--tw-shadow:0 0 8px var(--tw-shadow-color,#3ddc8ab3);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_0_18px_rgba\(255\,90\,79\,0\.35\)\]{--tw-shadow:0 0 18px var(--tw-shadow-color,#ff5a4f59);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_0_32px_rgba\(255\,90\,79\,0\.3\)\]{--tw-shadow:0 0 32px var(--tw-shadow-color,#ff5a4f4d);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-1{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-foreground\/10{--tw-ring-color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.ring-foreground\/10{--tw-ring-color:color-mix(in oklab, var(--foreground) 10%, transparent)}}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.filter\!{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)!important}.backdrop-blur{--tw-backdrop-blur:blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-100{--tw-duration:.1s;transition-duration:.1s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.paused{animation-play-state:paused}.running{animation-play-state:running}.zoom-in{--tw-enter-scale:0}@media (hover:hover){.hover\:border-text-3:hover{border-color:var(--text-3)}.hover\:bg-\[\#3a1512\]:hover{background-color:#3a1512}.hover\:bg-\[\#232931\]:hover{background-color:#232931}.hover\:bg-bernstein-hell:hover{background-color:var(--bernstein-hell)}.hover\:bg-cyan-grund:hover{background-color:var(--cyan-grund)}.hover\:bg-erhaben:hover{background-color:var(--erhaben)}.hover\:text-cyan:hover{color:var(--cyan)}.hover\:text-foreground:hover{color:var(--foreground)}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}}.focus\:border-cyan:focus{border-color:var(--cyan)}.focus-visible\:ring-3:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-ring\/50:focus-visible{--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.focus-visible\:ring-ring\/50:focus-visible{--tw-ring-color:color-mix(in oklab, var(--ring) 50%, transparent)}}.active\:not-aria-\[haspopup\]\:translate-y-px:active:not([aria-haspopup]){--tw-translate-y:1px;translate:var(--tw-translate-x) var(--tw-translate-y)}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:opacity-45:disabled{opacity:.45}.data-\[side\=bottom\]\:inset-x-0[data-side=bottom]{inset-inline:0}.data-\[side\=bottom\]\:bottom-0[data-side=bottom]{bottom:0}.data-\[side\=bottom\]\:h-auto[data-side=bottom]{height:auto}.data-\[side\=bottom\]\:border-t[data-side=bottom]{border-top-style:var(--tw-border-style);border-top-width:1px}.data-\[side\=left\]\:inset-y-0[data-side=left]{inset-block:0}.data-\[side\=left\]\:left-0[data-side=left]{left:0}.data-\[side\=left\]\:h-full[data-side=left]{height:100%}.data-\[side\=left\]\:w-3\/4[data-side=left]{width:75%}.data-\[side\=left\]\:border-r[data-side=left]{border-right-style:var(--tw-border-style);border-right-width:1px}.data-\[side\=right\]\:inset-y-0[data-side=right]{inset-block:0}.data-\[side\=right\]\:right-0[data-side=right]{right:0}.data-\[side\=right\]\:h-full[data-side=right]{height:100%}.data-\[side\=right\]\:w-3\/4[data-side=right]{width:75%}.data-\[side\=right\]\:border-l[data-side=right]{border-left-style:var(--tw-border-style);border-left-width:1px}.data-\[side\=top\]\:inset-x-0[data-side=top]{inset-inline:0}.data-\[side\=top\]\:top-0[data-side=top]{top:0}.data-\[side\=top\]\:h-auto[data-side=top]{height:auto}.data-\[side\=top\]\:border-b[data-side=top]{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}@supports ((-webkit-backdrop-filter:var(--tw)) or (backdrop-filter:var(--tw))){.supports-backdrop-filter\:backdrop-blur-xs{--tw-backdrop-blur:blur(var(--blur-xs));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}}@media (width>=40rem){.sm\:block{display:block}.sm\:max-w-2xl{max-width:var(--container-2xl)}.sm\:max-w-lg{max-width:var(--container-lg)}.sm\:max-w-sm{max-width:var(--container-sm)}.sm\:max-w-xl{max-width:var(--container-xl)}.sm\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.sm\:grid-cols-\[minmax\(0\,1fr\)_120px_160px\]{grid-template-columns:minmax(0,1fr) 120px 160px}.sm\:flex-row{flex-direction:row}.sm\:justify-end{justify-content:flex-end}.sm\:gap-2{gap:calc(var(--spacing) * 2)}.sm\:p-6{padding:calc(var(--spacing) * 6)}.sm\:px-6{padding-inline:calc(var(--spacing) * 6)}.sm\:text-\[44px\]{font-size:44px}.data-\[side\=left\]\:sm\:max-w-sm[data-side=left],.data-\[side\=right\]\:sm\:max-w-sm[data-side=right]{max-width:var(--container-sm)}}@media (width>=48rem){.md\:bottom-6{bottom:calc(var(--spacing) * 6)}.md\:left-auto{left:auto}.md\:col-span-1{grid-column:span 1/span 1}.md\:block{display:block}.md\:flex{display:flex}.md\:grid{display:grid}.md\:hidden{display:none}.md\:w-\[420px\]{width:420px}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-\[112px_minmax\(0\,1fr\)_auto\]{grid-template-columns:112px minmax(0,1fr) auto}.md\:grid-cols-\[170px_100px_170px_minmax\(0\,1fr\)_auto\]{grid-template-columns:170px 100px 170px minmax(0,1fr) auto}.md\:grid-cols-\[260px_minmax\(0\,1fr\)\]{grid-template-columns:260px minmax(0,1fr)}.md\:flex-col{flex-direction:column}.md\:items-end{align-items:flex-end}.md\:items-start{align-items:flex-start}.md\:gap-5{gap:calc(var(--spacing) * 5)}.md\:gap-6{gap:calc(var(--spacing) * 6)}.md\:px-10{padding-inline:calc(var(--spacing) * 10)}.md\:pt-8{padding-top:calc(var(--spacing) * 8)}.md\:pb-10{padding-bottom:calc(var(--spacing) * 10)}.md\:pl-\[124px\]{padding-left:124px}}@media (width>=64rem){.lg\:block{display:block}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:grid-cols-\[minmax\(0\,1\.4fr\)_minmax\(0\,1fr\)\]{grid-template-columns:minmax(0,1.4fr) minmax(0,1fr)}.lg\:grid-cols-\[minmax\(0\,1\.35fr\)_minmax\(0\,1fr\)\]{grid-template-columns:minmax(0,1.35fr) minmax(0,1fr)}.lg\:grid-cols-\[minmax\(0\,1fr\)_minmax\(0\,1\.3fr\)\]{grid-template-columns:minmax(0,1fr) minmax(0,1.3fr)}.lg\:px-6{padding-inline:calc(var(--spacing) * 6)}}.data-open\:animate-in:where([data-state=open]),.data-open\:animate-in:where([data-open]:not([data-open=false])){animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.data-open\:fade-in-0:where([data-state=open]),.data-open\:fade-in-0:where([data-open]:not([data-open=false])){--tw-enter-opacity:0}.data-open\:zoom-in-95:where([data-state=open]),.data-open\:zoom-in-95:where([data-open]:not([data-open=false])){--tw-enter-scale:.95}.data-\[side\=bottom\]\:data-open\:slide-in-from-bottom-10[data-side=bottom]:where([data-state=open]),.data-\[side\=bottom\]\:data-open\:slide-in-from-bottom-10[data-side=bottom]:where([data-open]:not([data-open=false])){--tw-enter-translate-y:calc(.1*100%)}.data-\[side\=left\]\:data-open\:slide-in-from-left-10[data-side=left]:where([data-state=open]),.data-\[side\=left\]\:data-open\:slide-in-from-left-10[data-side=left]:where([data-open]:not([data-open=false])){--tw-enter-translate-x:calc(.1*-100%)}.data-\[side\=right\]\:data-open\:slide-in-from-right-10[data-side=right]:where([data-state=open]),.data-\[side\=right\]\:data-open\:slide-in-from-right-10[data-side=right]:where([data-open]:not([data-open=false])){--tw-enter-translate-x:calc(.1*100%)}.data-\[side\=top\]\:data-open\:slide-in-from-top-10[data-side=top]:where([data-state=open]),.data-\[side\=top\]\:data-open\:slide-in-from-top-10[data-side=top]:where([data-open]:not([data-open=false])){--tw-enter-translate-y:calc(.1*-100%)}.data-closed\:animate-out:where([data-state=closed]),.data-closed\:animate-out:where([data-closed]:not([data-closed=false])){animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.data-closed\:fade-out-0:where([data-state=closed]),.data-closed\:fade-out-0:where([data-closed]:not([data-closed=false])){--tw-exit-opacity:0}.data-closed\:zoom-out-95:where([data-state=closed]),.data-closed\:zoom-out-95:where([data-closed]:not([data-closed=false])){--tw-exit-scale:.95}.data-\[side\=bottom\]\:data-closed\:slide-out-to-bottom-10[data-side=bottom]:where([data-state=closed]),.data-\[side\=bottom\]\:data-closed\:slide-out-to-bottom-10[data-side=bottom]:where([data-closed]:not([data-closed=false])){--tw-exit-translate-y:calc(.1*100%)}.data-\[side\=left\]\:data-closed\:slide-out-to-left-10[data-side=left]:where([data-state=closed]),.data-\[side\=left\]\:data-closed\:slide-out-to-left-10[data-side=left]:where([data-closed]:not([data-closed=false])){--tw-exit-translate-x:calc(.1*-100%)}.data-\[side\=right\]\:data-closed\:slide-out-to-right-10[data-side=right]:where([data-state=closed]),.data-\[side\=right\]\:data-closed\:slide-out-to-right-10[data-side=right]:where([data-closed]:not([data-closed=false])){--tw-exit-translate-x:calc(.1*100%)}.data-\[side\=top\]\:data-closed\:slide-out-to-top-10[data-side=top]:where([data-state=closed]),.data-\[side\=top\]\:data-closed\:slide-out-to-top-10[data-side=top]:where([data-closed]:not([data-closed=false])){--tw-exit-translate-y:calc(.1*-100%)}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_svg\:not\(\[class\*\=\'size-\'\]\)\]\:size-4 svg:not([class*=size-]){width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}:is(.\*\:\[a\]\:underline>*):is(a){text-decoration-line:underline}:is(.\*\:\[a\]\:underline-offset-3>*):is(a){text-underline-offset:3px}@media (hover:hover){:is(.\*\:\[a\]\:hover\:text-foreground>*):is(a):hover{color:var(--foreground)}}.schild{font-family:var(--font-anzeige);text-transform:uppercase;letter-spacing:.16em;font-weight:600}.ziffern{font-family:var(--font-mono);font-variant-numeric:tabular-nums}}@property --tw-animation-delay{syntax:"*";inherits:false;initial-value:0s}@property --tw-animation-direction{syntax:"*";inherits:false;initial-value:normal}@property --tw-animation-duration{syntax:"*";inherits:false}@property --tw-animation-fill-mode{syntax:"*";inherits:false;initial-value:none}@property --tw-animation-iteration-count{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-blur{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-opacity{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-rotate{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-scale{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-blur{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-opacity{syntax:"*";inherits:false;initial-value:1}@property --tw-exit-rotate{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-scale{syntax:"*";inherits:false;initial-value:1}@property --tw-exit-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-translate-y{syntax:"*";inherits:false;initial-value:0}@property --scroll-fade-t{syntax:"";inherits:false;initial-value:0}@property --scroll-fade-b{syntax:"";inherits:false;initial-value:0}@property --scroll-fade-s{syntax:"";inherits:false;initial-value:0}@property --scroll-fade-e{syntax:"";inherits:false;initial-value:0}@property --scroll-fade-mask{syntax:"*";inherits:false}@property --shimmer-angle{syntax:"";inherits:true;initial-value:20deg}@property --shimmer-image{syntax:"*";inherits:false}@property --shimmer-text-fill{syntax:"*";inherits:false}@media (prefers-reduced-motion:reduce){.shimmer{-webkit-text-fill-color:currentColor;background-image:none;animation:none}}@font-face{font-family:Barlow;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/barlow-vietnamese-400-normal-Dpl4UHAZ.woff2)format("woff2"),url(/assets/barlow-vietnamese-400-normal-BFeobeCK.woff)format("woff");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Barlow;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/barlow-latin-ext-400-normal-HxX4XjxC.woff2)format("woff2"),url(/assets/barlow-latin-ext-400-normal-CvBsJvxq.woff)format("woff");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Barlow;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/barlow-latin-400-normal-qiz4-Cze.woff2)format("woff2"),url(/assets/barlow-latin-400-normal-fsAxiSwU.woff)format("woff");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Barlow;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/barlow-vietnamese-500-normal-zTViEIzf.woff2)format("woff2"),url(/assets/barlow-vietnamese-500-normal-GNfB7rCE.woff)format("woff");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Barlow;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/barlow-latin-ext-500-normal-DOaysfXq.woff2)format("woff2"),url(/assets/barlow-latin-ext-500-normal-CJPcKP2Q.woff)format("woff");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Barlow;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/barlow-latin-500-normal-BPAOfeC8.woff2)format("woff2"),url(/assets/barlow-latin-500-normal-C1h8hMer.woff)format("woff");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Barlow;font-style:normal;font-display:swap;font-weight:600;src:url(/assets/barlow-vietnamese-600-normal-DcjprdFV.woff2)format("woff2"),url(/assets/barlow-vietnamese-600-normal-CA_GiK2e.woff)format("woff");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Barlow;font-style:normal;font-display:swap;font-weight:600;src:url(/assets/barlow-latin-ext-600-normal-B8NK_A3D.woff2)format("woff2"),url(/assets/barlow-latin-ext-600-normal-DMVRjfRT.woff)format("woff");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Barlow;font-style:normal;font-display:swap;font-weight:600;src:url(/assets/barlow-latin-600-normal-DILqtrty.woff2)format("woff2"),url(/assets/barlow-latin-600-normal-CNwfPWQD.woff)format("woff");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Barlow Condensed;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/barlow-condensed-vietnamese-500-normal-DjeaNLFD.woff2)format("woff2"),url(/assets/barlow-condensed-vietnamese-500-normal-CsrJDWc5.woff)format("woff");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Barlow Condensed;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/barlow-condensed-latin-ext-500-normal-yA5ONLQ9.woff2)format("woff2"),url(/assets/barlow-condensed-latin-ext-500-normal-B1RE8WP7.woff)format("woff");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Barlow Condensed;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/barlow-condensed-latin-500-normal-BgYH2mbd.woff2)format("woff2"),url(/assets/barlow-condensed-latin-500-normal-HIEiP5Ov.woff)format("woff");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Barlow Condensed;font-style:normal;font-display:swap;font-weight:600;src:url(/assets/barlow-condensed-vietnamese-600-normal-A5AYRdjN.woff2)format("woff2"),url(/assets/barlow-condensed-vietnamese-600-normal-CNlPk46_.woff)format("woff");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Barlow Condensed;font-style:normal;font-display:swap;font-weight:600;src:url(/assets/barlow-condensed-latin-ext-600-normal-18ESti3H.woff2)format("woff2"),url(/assets/barlow-condensed-latin-ext-600-normal-Clv9cIcR.woff)format("woff");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Barlow Condensed;font-style:normal;font-display:swap;font-weight:600;src:url(/assets/barlow-condensed-latin-600-normal-DepVgxBB.woff2)format("woff2"),url(/assets/barlow-condensed-latin-600-normal-BFJEwTuo.woff)format("woff");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Barlow Condensed;font-style:normal;font-display:swap;font-weight:700;src:url(/assets/barlow-condensed-vietnamese-700-normal-DYeBwlKR.woff2)format("woff2"),url(/assets/barlow-condensed-vietnamese-700-normal-DhIzd8Tb.woff)format("woff");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Barlow Condensed;font-style:normal;font-display:swap;font-weight:700;src:url(/assets/barlow-condensed-latin-ext-700-normal-CwuXbfVR.woff2)format("woff2"),url(/assets/barlow-condensed-latin-ext-700-normal-BIHFfxf0.woff)format("woff");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Barlow Condensed;font-style:normal;font-display:swap;font-weight:700;src:url(/assets/barlow-condensed-latin-700-normal-v1xN8_Wq.woff2)format("woff2"),url(/assets/barlow-condensed-latin-700-normal-Dmwat-ge.woff)format("woff");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:400;src:url(data:font/woff2;base64,d09GMgABAAAAAASIABAAAAAACQQAAAQuAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhwbHhwoBmA/U1RBVF4AdBEICoRkhAALIAABNgIkAzoEIAWFAAeBFAwHG2oHKJ6DceNW4lJEFHn9tEOE37LNsvkjHr7f739rn3u+OSrSxLQytE91Dw2PYtNVq3Qaw/vJ7fUBMdOj/u2ImB98cT5WUx9F13ZKt06mU7tG1sAYcM26yCRX4f/0904bmwq8hwkUUMTRX61pa9C3xlpAGYw1vOu8C2SBZZFlld7DAW82RJWmwYMI1AJCKBNCIASqdZGFmtPSNQRhMpR0EKjWTwm6z6sJ+4jqhxjovTinVdRpZaQjaQzAYjI8NgAKDJCokgunCn9oUQE8VZd/F//+v6P4F1U9gLr58yNI/dJX9BAshEoJbTDogz7ocKoUsPvES8UK/aQIUQgpGgECBVLkOEV6iASTYgNAPKdNXayhDPL7IJuAZnEYSZ0eOLc9i5Rv5/+lEi3sW/kfnCf/+fTe0sxS7CKLx5erRJkKOixEqQaoqrvx5HN4iz4VhX0gS6DjFIWUzn/fIXJRVFY1NFRVNVeFt+SYmrK6vCU6eJsnKnJj5HTESMTQZOTI3Y/tzr3rUcOsiRy/ciP50s3Mycgxmhz9GMXhjzVH30ut796NHP0UUa31/Zoa6vCH6iPvdIM0IRANaT60FablmZlZd+UKNFy9NrvnFGxb5NC2CRxR0/rIyF/WNn+35sv9r+tHVhkseuWGKkCPPh96+GXt8Lc/Sh24ujfjf+tNw1lZWreiPuHb/PSpyjdv2rf/++ZE5TSKjFdZxYsBvr1sEHl5STuHZqYR7jGYGvGBBdjcaB5bODY1GAxMjsd0wDMIzXAXODRd74DxNMtO4YuYHclgLQRzp9KlUmxptCwv9bYgvWGD2xBW7r9413fdJu+mxzvzAUYeeONQvZP4kgfqZle4jhH/MWh+UbxgtJdrLdXLymNL53PRU0D3Q6FcXTfGqGcul6vrqhgLGAVSv+IVIfZOHpu+mlLqSlnj903j8mazXDsba/wbxhS/4Oubh1c5/uXDgt4j5KtnGEy5BIJHo0ur+jD+r2qCkuP1aRVM8EpUoRYSJyqNRA38uwDvHBNo0AejO2Z+ZYLLal1QiFyFh1EDQOgSCSCpjwwKU8yDbIjroEwne0G5Qca49cYp4AlqtQNZfWTQoFb1tRpFYAmRD+HXTkV4uQhG2bg4OKmyoypAsUGtWgQXyFxYrkpODeUxvGqIZA61erXo0sFG1UBGuPgpuon8RNUG2DhovAjZCBuZwtXrU3mQGki9+pm0eVZAXoWxLWTQoYHBPrJR4WunNxIFbCHfkTyPK+sqxjxDmGArZvf79JGJ3GwEqjwc7a7NIrl/7bJ7Nzu4+n1Ow6shEPnUrtVo7cnd5Wi5qCUbBIQbNKCP95FMCSZylEV5VCiiMqqiOmrKZ/I/C0gI1fyuulVcM2E1r4MhtcV/fbCD+HwEvVzH1dGNAzFE0FTbKzyQz3gootrNbN2a4PuG0j0JOgE=)format("woff2"),url(data:font/woff;base64,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)format("woff");unicode-range:U+460-52F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/jetbrains-mono-cyrillic-400-normal-BEIGL1Tu.woff2)format("woff2"),url(/assets/jetbrains-mono-cyrillic-400-normal-ugxPyKxw.woff)format("woff");unicode-range:U+301,U+400-45F,U+490-491,U+4B0-4B1,U+2116}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/jetbrains-mono-greek-400-normal-C190GLew.woff2)format("woff2"),url(/assets/jetbrains-mono-greek-400-normal-B9oWc5Lo.woff)format("woff");unicode-range:U+370-377,U+37A-37F,U+384-38A,U+38C,U+38E-3A1,U+3A3-3FF}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:400;src:url(data:font/woff2;base64,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)format("woff2"),url(/assets/jetbrains-mono-vietnamese-400-normal-CqNFfHCs.woff)format("woff");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/jetbrains-mono-latin-ext-400-normal-Bc8Ftmh3.woff2)format("woff2"),url(/assets/jetbrains-mono-latin-ext-400-normal-fXTG6kC5.woff)format("woff");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2)format("woff2"),url(/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff)format("woff");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:500;src:url(data:font/woff2;base64,d09GMgABAAAAAASUABAAAAAACRAAAAQ3AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhwbHhwoBmA/U1RBVEwAdBEICoRkg3oLIAABNgIkAzoEIAWFHgeBFAwHG3AHKB4HzukrRjyF5Gb4kQ/B873d17mv8TWkoqUUGaHodJCtoqntw7m8tiPWyGkfWDU/IMpzVk4zAs9Czv3c7Os5NvKFG1Ht9vBVXySRZpJc4tTrbM3sTRFcLa3zVboKWRIoAksKSKgqUQWEwlSoqjp44V5J9/kjd0+Fi5xaFjwJArgBAIJgIAgCCAI4CdNMqGuYXYUKdADLAkAAJwl6iX0+bZqEm1AH0Hu9rvrJHwxQG1Q/gFYwWYbgTRWgwEESVzbmtjQAt3DXO7Tu/+9Q/KNKWhTCgZ8fQSWoL0CUUgTBjgL8iEAcce7YHBeA8ZvogieCnxI0BCVeACCAAhBD/oDcAdUPABSgAX4kBPBTwjCAjwYSCneiqF65LUo/qXdYFrRwTujtMrKm07plTbSqLQFAiHBN7E4DG5wkiGXhCYBNETh3K/AciHN69iFfQjFOr9EXQQAAQXRNszs8PR0OH4fDV/dwGe76CHdj1MQa11DXYGcfZ6+B1X0OfwjY+i7KpQ1w9d+1z3/HydCB1f3U8A0fRFv+0bXxPWrZu3d9Nn4UcbLs/QCXLH/j3PCKblKOiZxLOR78W9brPo7eGTLz/F27ZPmePQdCB1YP4nJU91o4gU9cy64L3c3SPu8GfDn6ZXD2cGmllVqSxtD5vCXHm5xaeHlnpffx7DcPvXog5NnjA//cPz2btsz3yf+0MI8ri33tuv7upNbYmW5STbosW8bYItV/SPzxvXC0KnpWnFdC91oojit5Lyo6WcJQ1YzwBYbi52ohJVpcxfcHBqsv0nFz8U74rzS6M7r0RVlXZ3jJC4G92O//7Lm78VOtnUx+aQxAzsqPnrRr1t9zDrezKePvZ027x+fGte4s4NXu7/jEp3G9cM1bICYgACbuETUUD5wmenGXA/IBpAKVrl0AEJ5cqr6Q89tGq+SpqkDfX2DtG+pZ9teuae0AX98c301CX179InyErnSG8WCiABB4HFbVrw/lpTdBIOk82nXbpHKoQGyBpUovAAD4XQA8ZTUCeBJHIpI0v0FRrgcnckV3ANckrwYJKXEihQfdSKPER6XeExmEeEMmSe6QBwWmkZdmSOSthhibgIkBlUYreBKd/0NeVAE9WAyEaQpH6KikDWlUVg43Jy2FOmaYlsZhDEGZXO3mWEyWHI6zuaJkMlcSQ9k4F+KidIiFyZItGDc7r1pUj6wP6zrWB0/fbeeFeHl4YOvETMNiM8Ny+7OO6Qh2wur20YVxFts5dlORdl5Kwd5utR7SRcxqX8RA5Ehacha76hg7c6yzNm/Xf6vOLNrv544lIEkWg7xWo/ItBAeIJEmt0XgBwgM8gTifoiiLJroYYooNTeziEKe4zOoR/wvIKp89hSr+6jFAqw/LaonjmZHSscMNg4iPlWpFrO1RN3zkMU+/xUP+JQ99TbvTl1Vg0gtirT6lbwYAAAA=)format("woff2"),url(data:font/woff;base64,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)format("woff");unicode-range:U+460-52F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/jetbrains-mono-cyrillic-500-normal-DmUKJPL_.woff2)format("woff2"),url(/assets/jetbrains-mono-cyrillic-500-normal-DJqRU3vO.woff)format("woff");unicode-range:U+301,U+400-45F,U+490-491,U+4B0-4B1,U+2116}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/jetbrains-mono-greek-500-normal-JpySY46c.woff2)format("woff2"),url(/assets/jetbrains-mono-greek-500-normal-D7SFKleX.woff)format("woff");unicode-range:U+370-377,U+37A-37F,U+384-38A,U+38C,U+38E-3A1,U+3A3-3FF}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:500;src:url(data:font/woff2;base64,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)format("woff2"),url(/assets/jetbrains-mono-vietnamese-500-normal-DNRqzVM1.woff)format("woff");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/jetbrains-mono-latin-ext-500-normal-Cut-4mMH.woff2)format("woff2"),url(/assets/jetbrains-mono-latin-ext-500-normal-ckzbgY84.woff)format("woff");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/jetbrains-mono-latin-500-normal-BWZEU5yA.woff2)format("woff2"),url(/assets/jetbrains-mono-latin-500-normal-CJOVTJB7.woff)format("woff");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}:root{--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark;--radius:.625rem;--background:#0e1012;--foreground:#e6eaee;--card:#15181b;--card-foreground:#e6eaee;--popover:#15181b;--popover-foreground:#e6eaee;--primary:#ffb020;--primary-foreground:#1a1300;--secondary:#1c2126;--secondary-foreground:#e6eaee;--muted:#1c2126;--muted-foreground:#8b949e;--accent:#1c2126;--accent-foreground:#e6eaee;--destructive:#ff5a4f;--border:#262b30;--input:#3a4148;--ring:#5cc8ff;--panel:#15181b;--erhaben:#1c2126;--linie:#262b30;--linie-stark:#3a4148;--text-2:#aeb6bf;--text-3:#8b949e;--bernstein:#ffb020;--bernstein-hell:#ffc24d;--bernstein-grund:#2a1e05;--bernstein-lampe:#3a2a08;--gruen:#3ddc8a;--gruen-text:#7cc9a0;--gruen-grund:#0f2319;--gruen-rand:#1f5a3b;--cyan:#5cc8ff;--cyan-text:#93d5f8;--cyan-grund:#0c2230;--cyan-rand:#2f7fb0;--rot:#ff5a4f;--rot-text:#ff9a92;--rot-grund:#2e0f0d;--rot-rand:#a33a33;--aus-grund:#171b1f;--aus-rand:#2e343a;--aus-text:#9aa3ad}@keyframes lampe-atmen{0%,to{box-shadow:0 0 10px color-mix(in srgb, var(--bernstein) 25%, transparent)}50%{box-shadow:0 0 22px color-mix(in srgb, var(--bernstein) 45%, transparent)}}@media (prefers-reduced-motion:no-preference){.lampe-atmet{animation:3.2s ease-in-out infinite lampe-atmen}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0)scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1))rotate(var(--tw-enter-rotate,0));filter:blur(var(--tw-enter-blur,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0)scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1))rotate(var(--tw-exit-rotate,0));filter:blur(var(--tw-exit-blur,0))}} diff --git a/frontend/dist/assets/index-D4C10235.css b/frontend/dist/assets/index-D4C10235.css deleted file mode 100644 index bfa949c..0000000 --- a/frontend/dist/assets/index-D4C10235.css +++ /dev/null @@ -1,2 +0,0 @@ -/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */ -@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){:root,:host{--shimmer-angle:20deg}*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-animation-delay:0s;--tw-animation-direction:normal;--tw-animation-duration:initial;--tw-animation-fill-mode:none;--tw-animation-iteration-count:1;--tw-enter-blur:0;--tw-enter-opacity:1;--tw-enter-rotate:0;--tw-enter-scale:1;--tw-enter-translate-x:0;--tw-enter-translate-y:0;--tw-exit-blur:0;--tw-exit-opacity:1;--tw-exit-rotate:0;--tw-exit-scale:1;--tw-exit-translate-x:0;--tw-exit-translate-y:0;--scroll-fade-t:0px;--scroll-fade-b:0px;--scroll-fade-s:0px;--scroll-fade-e:0px;--scroll-fade-mask:initial;--shimmer-image:initial;--shimmer-text-fill:initial}}}@layer theme{:root,:host{--font-mono:"JetBrains Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;--color-black:#000;--spacing:.25rem;--container-sm:24rem;--container-lg:32rem;--container-xl:36rem;--container-2xl:42rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-normal:0em;--leading-tight:1.25;--leading-snug:1.375;--leading-relaxed:1.625;--ease-in-out:cubic-bezier(.4, 0, .2, 1);--blur-xs:4px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:"Barlow", "Segoe UI", system-ui, sans-serif;--default-mono-font-family:"JetBrains Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;--font-anzeige:"Barlow Condensed", "Barlow", "Segoe UI", sans-serif}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*{border-color:var(--border);outline-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){*{outline-color:color-mix(in oklab, var(--ring) 50%, transparent)}}html{-webkit-font-smoothing:antialiased;font-family:Barlow,Segoe UI,system-ui,sans-serif}body{background-color:var(--background);color:var(--foreground);margin:0}:focus-visible{outline:2px solid var(--cyan);outline-offset:2px}}@layer components;@layer utilities{.\@container{container-type:inline-size}.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.not-sr-only{clip-path:none;white-space:normal;width:auto;height:auto;margin:0;padding:0;position:static;overflow:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.inset-0{inset:0}.inset-x-0{inset-inline:0}.inset-y-0{inset-block:0}.-top-1\.5{top:calc(var(--spacing) * -1.5)}.top-1\/2{top:50%}.top-2{top:calc(var(--spacing) * 2)}.top-3{top:calc(var(--spacing) * 3)}.right-2{right:calc(var(--spacing) * 2)}.right-3{right:calc(var(--spacing) * 3)}.right-4{right:calc(var(--spacing) * 4)}.-bottom-1\.5{bottom:calc(var(--spacing) * -1.5)}.bottom-0{bottom:0}.bottom-24{bottom:calc(var(--spacing) * 24)}.left-0{left:0}.left-1\/2{left:50%}.left-4{left:calc(var(--spacing) * 4)}.isolate{isolation:isolate}.z-40{z-index:40}.z-50{z-index:50}.col-span-2{grid-column:span 2/span 2}.container{width:100%}@media (width>=40rem){.container{max-width:40rem}}@media (width>=48rem){.container{max-width:48rem}}@media (width>=64rem){.container{max-width:64rem}}@media (width>=80rem){.container{max-width:80rem}}@media (width>=96rem){.container{max-width:96rem}}.-m-2{margin:calc(var(--spacing) * -2)}.m-0{margin:0}.-mx-4{margin-inline:calc(var(--spacing) * -4)}.mx-4{margin-inline:calc(var(--spacing) * 4)}.mx-auto{margin-inline:auto}.-mt-2{margin-top:calc(var(--spacing) * -2)}.mt-auto{margin-top:auto}.mr-2{margin-right:calc(var(--spacing) * 2)}.-mb-4{margin-bottom:calc(var(--spacing) * -4)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.ml-0\.5{margin-left:calc(var(--spacing) * .5)}.line-clamp-3{-webkit-line-clamp:3;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.contents{display:contents}.flex{display:flex}.flow-root{display:flow-root}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.table-caption{display:table-caption}.table-cell{display:table-cell}.table-column{display:table-column}.table-column-group{display:table-column-group}.table-footer-group{display:table-footer-group}.table-header-group{display:table-header-group}.table-row{display:table-row}.size-1\.5{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5)}.size-2{width:calc(var(--spacing) * 2);height:calc(var(--spacing) * 2)}.size-2\.5{width:calc(var(--spacing) * 2.5);height:calc(var(--spacing) * 2.5)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-5{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.size-11{width:calc(var(--spacing) * 11);height:calc(var(--spacing) * 11)}.h-0{height:0}.h-2{height:calc(var(--spacing) * 2)}.h-3{height:calc(var(--spacing) * 3)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-10{height:calc(var(--spacing) * 10)}.h-11{height:calc(var(--spacing) * 11)}.h-12{height:calc(var(--spacing) * 12)}.h-14{height:calc(var(--spacing) * 14)}.h-16{height:calc(var(--spacing) * 16)}.h-\[150px\]{height:150px}.h-auto{height:auto}.h-full{height:100%}.max-h-40{max-height:calc(var(--spacing) * 40)}.max-h-\[50vh\]{max-height:50vh}.min-h-11{min-height:calc(var(--spacing) * 11)}.min-h-\[58px\]{min-height:58px}.min-h-\[130px\]{min-height:130px}.min-h-dvh{min-height:100dvh}.w-0\.5{width:calc(var(--spacing) * .5)}.w-\[38px\]{width:38px}.w-full{width:100%}.w-px{width:1px}.max-w-\[200px\]{max-width:200px}.max-w-\[1440px\]{max-width:1440px}.max-w-\[calc\(100\%-2rem\)\]{max-width:calc(100% - 2rem)}.max-w-full{max-width:100%}.min-w-0{min-width:0}.flex-1{flex:1}.shrink-0{flex-shrink:0}.flex-grow{flex-grow:1}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-px{--tw-translate-y:-1px;translate:var(--tw-translate-x) var(--tw-translate-y)}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.resize{resize:both}.list-none{list-style-type:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-\[112px_minmax\(0\,1fr\)_auto\]{grid-template-columns:112px minmax(0,1fr) auto}.grid-cols-\[170px_100px_170px_minmax\(0\,1fr\)_auto\]{grid-template-columns:170px 100px 170px minmax(0,1fr) auto}.grid-cols-\[auto_minmax\(0\,1fr\)_auto\]{grid-template-columns:auto minmax(0,1fr) auto}.grid-cols-\[minmax\(0\,1fr\)_auto\]{grid-template-columns:minmax(0,1fr) auto}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-3\.5{gap:calc(var(--spacing) * 3.5)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-x-4{column-gap:calc(var(--spacing) * 4)}.gap-x-6{column-gap:calc(var(--spacing) * 6)}.gap-y-2{row-gap:calc(var(--spacing) * 2)}.gap-y-6{row-gap:calc(var(--spacing) * 6)}.self-start{align-self:flex-start}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded-2xl{border-radius:calc(var(--radius) * 1.8)}.rounded-\[9px\]{border-radius:9px}.rounded-full{border-radius:2147483647px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) * .8)}.rounded-sm{border-radius:calc(var(--radius) * .6)}.rounded-xl{border-radius:calc(var(--radius) * 1.4)}.rounded-b-xl{border-bottom-right-radius:calc(var(--radius) * 1.4);border-bottom-left-radius:calc(var(--radius) * 1.4)}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-dotted{--tw-border-style:dotted;border-style:dotted}.\!border-linie-stark{border-color:var(--linie-stark)!important}.border-\[\#2a3036\]{border-color:#2a3036}.border-aus-rand{border-color:var(--aus-rand)}.border-bernstein,.border-bernstein\/60{border-color:var(--bernstein)}@supports (color:color-mix(in lab, red, red)){.border-bernstein\/60{border-color:color-mix(in oklab, var(--bernstein) 60%, transparent)}}.border-cyan-rand{border-color:var(--cyan-rand)}.border-gruen-rand{border-color:var(--gruen-rand)}.border-linie{border-color:var(--linie)}.border-linie-stark{border-color:var(--linie-stark)}.border-rot{border-color:var(--rot)}.border-rot-rand{border-color:var(--rot-rand)}.border-transparent{border-color:#0000}.bg-\[\#0b0d0f\]{background-color:#0b0d0f}.bg-\[\#0e1119\]\/95{background-color:oklab(17.8423% -.00041081 -.0172642/.95)}.bg-\[\#121518\]{background-color:#121518}.bg-aus-grund{background-color:var(--aus-grund)}.bg-bernstein{background-color:var(--bernstein)}.bg-bernstein-grund{background-color:var(--bernstein-grund)}.bg-bernstein-lampe{background-color:var(--bernstein-lampe)}.bg-black\/10{background-color:#0000001a}@supports (color:color-mix(in lab, red, red)){.bg-black\/10{background-color:color-mix(in oklab, var(--color-black) 10%, transparent)}}.bg-cyan{background-color:var(--cyan)}.bg-cyan-grund{background-color:var(--cyan-grund)}.bg-cyan\/35{background-color:var(--cyan)}@supports (color:color-mix(in lab, red, red)){.bg-cyan\/35{background-color:color-mix(in oklab, var(--cyan) 35%, transparent)}}.bg-erhaben,.bg-erhaben\/50{background-color:var(--erhaben)}@supports (color:color-mix(in lab, red, red)){.bg-erhaben\/50{background-color:color-mix(in oklab, var(--erhaben) 50%, transparent)}}.bg-gruen{background-color:var(--gruen)}.bg-gruen-grund{background-color:var(--gruen-grund)}.bg-linie{background-color:var(--linie)}.bg-muted\/50{background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.bg-muted\/50{background-color:color-mix(in oklab, var(--muted) 50%, transparent)}}.bg-panel{background-color:var(--panel)}.bg-popover{background-color:var(--popover)}.bg-rot{background-color:var(--rot)}.bg-rot-grund{background-color:var(--rot-grund)}.bg-text-3{background-color:var(--text-3)}.bg-transparent{background-color:#0000}.bg-clip-padding{background-clip:padding-box}.p-0{padding:0}.p-1{padding:var(--spacing)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.px-0{padding-inline:0}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-3\.5{padding-block:calc(var(--spacing) * 3.5)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-5{padding-block:calc(var(--spacing) * 5)}.py-8{padding-block:calc(var(--spacing) * 8)}.pt-1{padding-top:var(--spacing)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-4{padding-bottom:calc(var(--spacing) * 4)}.pb-5{padding-bottom:calc(var(--spacing) * 5)}.pb-28{padding-bottom:calc(var(--spacing) * 28)}.pb-\[calc\(0\.75rem\+env\(safe-area-inset-bottom\)\)\]{padding-bottom:calc(.75rem + env(safe-area-inset-bottom))}.pb-\[calc\(1rem\+env\(safe-area-inset-bottom\)\)\]{padding-bottom:calc(1rem + env(safe-area-inset-bottom))}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-anzeige,.font-heading{font-family:Barlow Condensed,Barlow,Segoe UI,sans-serif}.font-sans{font-family:Barlow,Segoe UI,system-ui,sans-serif}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[13px\]{font-size:13px}.text-\[15px\]{font-size:15px}.text-\[17px\]{font-size:17px}.text-\[28px\]{font-size:28px}.text-\[32px\]{font-size:32px}.text-\[40px\]{font-size:40px}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-\[0\.04em\]{--tw-tracking:.04em;letter-spacing:.04em}.tracking-\[0\.06em\]{--tw-tracking:.06em;letter-spacing:.06em}.tracking-\[0\.12em\]{--tw-tracking:.12em;letter-spacing:.12em}.tracking-\[0\.18em\]{--tw-tracking:.18em;letter-spacing:.18em}.tracking-\[0\.22em\]{--tw-tracking:.22em;letter-spacing:.22em}.tracking-\[0\.26em\]{--tw-tracking:.26em;letter-spacing:.26em}.tracking-normal{--tw-tracking:var(--tracking-normal);letter-spacing:var(--tracking-normal)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-line{white-space:pre-line}.whitespace-pre-wrap{white-space:pre-wrap}.\!text-foreground{color:var(--foreground)!important}.text-\[\#f2c46b\]{color:#f2c46b}.text-aus-text{color:var(--aus-text)}.text-bernstein{color:var(--bernstein)}.text-bernstein-hell{color:var(--bernstein-hell)}.text-cyan{color:var(--cyan)}.text-cyan-text{color:var(--cyan-text)}.text-foreground{color:var(--foreground)}.text-gruen{color:var(--gruen)}.text-gruen-text{color:var(--gruen-text)}.text-muted-foreground{color:var(--muted-foreground)}.text-popover-foreground{color:var(--popover-foreground)}.text-primary-foreground{color:var(--primary-foreground)}.text-rot{color:var(--rot)}.text-rot-text{color:var(--rot-text)}.text-text-2{color:var(--text-2)}.text-text-3{color:var(--text-3)}.capitalize{text-transform:capitalize}.lowercase{text-transform:lowercase}.normal-case{text-transform:none}.uppercase{text-transform:uppercase}.italic{font-style:italic}.diagonal-fractions{--tw-numeric-fraction:diagonal-fractions;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.lining-nums{--tw-numeric-figure:lining-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.proportional-nums{--tw-numeric-spacing:proportional-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.no-underline{text-decoration-line:none}.underline-offset-4{text-underline-offset:4px}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.opacity-70{opacity:.7}.opacity-80{opacity:.8}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_0_8px_rgba\(61\,220\,138\,0\.7\)\]{--tw-shadow:0 0 8px var(--tw-shadow-color,#3ddc8ab3);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_0_18px_rgba\(255\,90\,79\,0\.35\)\]{--tw-shadow:0 0 18px var(--tw-shadow-color,#ff5a4f59);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_0_32px_rgba\(255\,90\,79\,0\.3\)\]{--tw-shadow:0 0 32px var(--tw-shadow-color,#ff5a4f4d);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-1{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-foreground\/10{--tw-ring-color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.ring-foreground\/10{--tw-ring-color:color-mix(in oklab, var(--foreground) 10%, transparent)}}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.filter\!{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)!important}.backdrop-blur{--tw-backdrop-blur:blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-100{--tw-duration:.1s;transition-duration:.1s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.paused{animation-play-state:paused}.running{animation-play-state:running}.zoom-in{--tw-enter-scale:0}@media (hover:hover){.hover\:border-text-3:hover{border-color:var(--text-3)}.hover\:bg-\[\#3a1512\]:hover{background-color:#3a1512}.hover\:bg-\[\#232931\]:hover{background-color:#232931}.hover\:bg-bernstein-hell:hover{background-color:var(--bernstein-hell)}.hover\:bg-cyan-grund:hover{background-color:var(--cyan-grund)}.hover\:bg-erhaben:hover{background-color:var(--erhaben)}.hover\:text-cyan:hover{color:var(--cyan)}.hover\:text-foreground:hover{color:var(--foreground)}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}}.focus\:border-cyan:focus{border-color:var(--cyan)}.focus-visible\:ring-3:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-ring\/50:focus-visible{--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.focus-visible\:ring-ring\/50:focus-visible{--tw-ring-color:color-mix(in oklab, var(--ring) 50%, transparent)}}.active\:not-aria-\[haspopup\]\:translate-y-px:active:not([aria-haspopup]){--tw-translate-y:1px;translate:var(--tw-translate-x) var(--tw-translate-y)}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:opacity-45:disabled{opacity:.45}.data-\[side\=bottom\]\:inset-x-0[data-side=bottom]{inset-inline:0}.data-\[side\=bottom\]\:bottom-0[data-side=bottom]{bottom:0}.data-\[side\=bottom\]\:h-auto[data-side=bottom]{height:auto}.data-\[side\=bottom\]\:border-t[data-side=bottom]{border-top-style:var(--tw-border-style);border-top-width:1px}.data-\[side\=left\]\:inset-y-0[data-side=left]{inset-block:0}.data-\[side\=left\]\:left-0[data-side=left]{left:0}.data-\[side\=left\]\:h-full[data-side=left]{height:100%}.data-\[side\=left\]\:w-3\/4[data-side=left]{width:75%}.data-\[side\=left\]\:border-r[data-side=left]{border-right-style:var(--tw-border-style);border-right-width:1px}.data-\[side\=right\]\:inset-y-0[data-side=right]{inset-block:0}.data-\[side\=right\]\:right-0[data-side=right]{right:0}.data-\[side\=right\]\:h-full[data-side=right]{height:100%}.data-\[side\=right\]\:w-3\/4[data-side=right]{width:75%}.data-\[side\=right\]\:border-l[data-side=right]{border-left-style:var(--tw-border-style);border-left-width:1px}.data-\[side\=top\]\:inset-x-0[data-side=top]{inset-inline:0}.data-\[side\=top\]\:top-0[data-side=top]{top:0}.data-\[side\=top\]\:h-auto[data-side=top]{height:auto}.data-\[side\=top\]\:border-b[data-side=top]{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}@supports ((-webkit-backdrop-filter:var(--tw)) or (backdrop-filter:var(--tw))){.supports-backdrop-filter\:backdrop-blur-xs{--tw-backdrop-blur:blur(var(--blur-xs));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}}@media (width>=40rem){.sm\:block{display:block}.sm\:max-w-2xl{max-width:var(--container-2xl)}.sm\:max-w-lg{max-width:var(--container-lg)}.sm\:max-w-sm{max-width:var(--container-sm)}.sm\:max-w-xl{max-width:var(--container-xl)}.sm\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.sm\:grid-cols-\[minmax\(0\,1fr\)_120px_160px\]{grid-template-columns:minmax(0,1fr) 120px 160px}.sm\:flex-row{flex-direction:row}.sm\:justify-end{justify-content:flex-end}.sm\:gap-2{gap:calc(var(--spacing) * 2)}.sm\:p-6{padding:calc(var(--spacing) * 6)}.sm\:px-6{padding-inline:calc(var(--spacing) * 6)}.sm\:pl-\[124px\]{padding-left:124px}.sm\:text-\[44px\]{font-size:44px}.data-\[side\=left\]\:sm\:max-w-sm[data-side=left],.data-\[side\=right\]\:sm\:max-w-sm[data-side=right]{max-width:var(--container-sm)}}@media (width>=48rem){.md\:bottom-6{bottom:calc(var(--spacing) * 6)}.md\:left-auto{left:auto}.md\:col-span-1{grid-column:span 1/span 1}.md\:block{display:block}.md\:flex{display:flex}.md\:grid{display:grid}.md\:hidden{display:none}.md\:w-\[420px\]{width:420px}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-\[112px_minmax\(0\,1fr\)_auto\]{grid-template-columns:112px minmax(0,1fr) auto}.md\:grid-cols-\[170px_100px_170px_minmax\(0\,1fr\)_auto\]{grid-template-columns:170px 100px 170px minmax(0,1fr) auto}.md\:grid-cols-\[260px_minmax\(0\,1fr\)\]{grid-template-columns:260px minmax(0,1fr)}.md\:flex-col{flex-direction:column}.md\:items-end{align-items:flex-end}.md\:items-start{align-items:flex-start}.md\:gap-5{gap:calc(var(--spacing) * 5)}.md\:gap-6{gap:calc(var(--spacing) * 6)}.md\:px-10{padding-inline:calc(var(--spacing) * 10)}.md\:pt-8{padding-top:calc(var(--spacing) * 8)}.md\:pb-10{padding-bottom:calc(var(--spacing) * 10)}.md\:pl-\[124px\]{padding-left:124px}}@media (width>=64rem){.lg\:block{display:block}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:grid-cols-\[minmax\(0\,1\.4fr\)_minmax\(0\,1fr\)\]{grid-template-columns:minmax(0,1.4fr) minmax(0,1fr)}.lg\:grid-cols-\[minmax\(0\,1\.35fr\)_minmax\(0\,1fr\)\]{grid-template-columns:minmax(0,1.35fr) minmax(0,1fr)}.lg\:grid-cols-\[minmax\(0\,1fr\)_minmax\(0\,1\.3fr\)\]{grid-template-columns:minmax(0,1fr) minmax(0,1.3fr)}.lg\:px-6{padding-inline:calc(var(--spacing) * 6)}}.data-open\:animate-in:where([data-state=open]),.data-open\:animate-in:where([data-open]:not([data-open=false])){animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.data-open\:fade-in-0:where([data-state=open]),.data-open\:fade-in-0:where([data-open]:not([data-open=false])){--tw-enter-opacity:0}.data-open\:zoom-in-95:where([data-state=open]),.data-open\:zoom-in-95:where([data-open]:not([data-open=false])){--tw-enter-scale:.95}.data-\[side\=bottom\]\:data-open\:slide-in-from-bottom-10[data-side=bottom]:where([data-state=open]),.data-\[side\=bottom\]\:data-open\:slide-in-from-bottom-10[data-side=bottom]:where([data-open]:not([data-open=false])){--tw-enter-translate-y:calc(.1*100%)}.data-\[side\=left\]\:data-open\:slide-in-from-left-10[data-side=left]:where([data-state=open]),.data-\[side\=left\]\:data-open\:slide-in-from-left-10[data-side=left]:where([data-open]:not([data-open=false])){--tw-enter-translate-x:calc(.1*-100%)}.data-\[side\=right\]\:data-open\:slide-in-from-right-10[data-side=right]:where([data-state=open]),.data-\[side\=right\]\:data-open\:slide-in-from-right-10[data-side=right]:where([data-open]:not([data-open=false])){--tw-enter-translate-x:calc(.1*100%)}.data-\[side\=top\]\:data-open\:slide-in-from-top-10[data-side=top]:where([data-state=open]),.data-\[side\=top\]\:data-open\:slide-in-from-top-10[data-side=top]:where([data-open]:not([data-open=false])){--tw-enter-translate-y:calc(.1*-100%)}.data-closed\:animate-out:where([data-state=closed]),.data-closed\:animate-out:where([data-closed]:not([data-closed=false])){animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.data-closed\:fade-out-0:where([data-state=closed]),.data-closed\:fade-out-0:where([data-closed]:not([data-closed=false])){--tw-exit-opacity:0}.data-closed\:zoom-out-95:where([data-state=closed]),.data-closed\:zoom-out-95:where([data-closed]:not([data-closed=false])){--tw-exit-scale:.95}.data-\[side\=bottom\]\:data-closed\:slide-out-to-bottom-10[data-side=bottom]:where([data-state=closed]),.data-\[side\=bottom\]\:data-closed\:slide-out-to-bottom-10[data-side=bottom]:where([data-closed]:not([data-closed=false])){--tw-exit-translate-y:calc(.1*100%)}.data-\[side\=left\]\:data-closed\:slide-out-to-left-10[data-side=left]:where([data-state=closed]),.data-\[side\=left\]\:data-closed\:slide-out-to-left-10[data-side=left]:where([data-closed]:not([data-closed=false])){--tw-exit-translate-x:calc(.1*-100%)}.data-\[side\=right\]\:data-closed\:slide-out-to-right-10[data-side=right]:where([data-state=closed]),.data-\[side\=right\]\:data-closed\:slide-out-to-right-10[data-side=right]:where([data-closed]:not([data-closed=false])){--tw-exit-translate-x:calc(.1*100%)}.data-\[side\=top\]\:data-closed\:slide-out-to-top-10[data-side=top]:where([data-state=closed]),.data-\[side\=top\]\:data-closed\:slide-out-to-top-10[data-side=top]:where([data-closed]:not([data-closed=false])){--tw-exit-translate-y:calc(.1*-100%)}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_svg\:not\(\[class\*\=\'size-\'\]\)\]\:size-4 svg:not([class*=size-]){width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}:is(.\*\:\[a\]\:underline>*):is(a){text-decoration-line:underline}:is(.\*\:\[a\]\:underline-offset-3>*):is(a){text-underline-offset:3px}@media (hover:hover){:is(.\*\:\[a\]\:hover\:text-foreground>*):is(a):hover{color:var(--foreground)}}.schild{font-family:var(--font-anzeige);text-transform:uppercase;letter-spacing:.16em;font-weight:600}.ziffern{font-family:var(--font-mono);font-variant-numeric:tabular-nums}}@property --tw-animation-delay{syntax:"*";inherits:false;initial-value:0s}@property --tw-animation-direction{syntax:"*";inherits:false;initial-value:normal}@property --tw-animation-duration{syntax:"*";inherits:false}@property --tw-animation-fill-mode{syntax:"*";inherits:false;initial-value:none}@property --tw-animation-iteration-count{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-blur{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-opacity{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-rotate{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-scale{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-blur{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-opacity{syntax:"*";inherits:false;initial-value:1}@property --tw-exit-rotate{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-scale{syntax:"*";inherits:false;initial-value:1}@property --tw-exit-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-translate-y{syntax:"*";inherits:false;initial-value:0}@property --scroll-fade-t{syntax:"";inherits:false;initial-value:0}@property --scroll-fade-b{syntax:"";inherits:false;initial-value:0}@property --scroll-fade-s{syntax:"";inherits:false;initial-value:0}@property --scroll-fade-e{syntax:"";inherits:false;initial-value:0}@property --scroll-fade-mask{syntax:"*";inherits:false}@property --shimmer-angle{syntax:"";inherits:true;initial-value:20deg}@property --shimmer-image{syntax:"*";inherits:false}@property --shimmer-text-fill{syntax:"*";inherits:false}@media (prefers-reduced-motion:reduce){.shimmer{-webkit-text-fill-color:currentColor;background-image:none;animation:none}}@font-face{font-family:Barlow;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/barlow-vietnamese-400-normal-Dpl4UHAZ.woff2)format("woff2"),url(/assets/barlow-vietnamese-400-normal-BFeobeCK.woff)format("woff");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Barlow;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/barlow-latin-ext-400-normal-HxX4XjxC.woff2)format("woff2"),url(/assets/barlow-latin-ext-400-normal-CvBsJvxq.woff)format("woff");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Barlow;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/barlow-latin-400-normal-qiz4-Cze.woff2)format("woff2"),url(/assets/barlow-latin-400-normal-fsAxiSwU.woff)format("woff");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Barlow;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/barlow-vietnamese-500-normal-zTViEIzf.woff2)format("woff2"),url(/assets/barlow-vietnamese-500-normal-GNfB7rCE.woff)format("woff");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Barlow;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/barlow-latin-ext-500-normal-DOaysfXq.woff2)format("woff2"),url(/assets/barlow-latin-ext-500-normal-CJPcKP2Q.woff)format("woff");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Barlow;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/barlow-latin-500-normal-BPAOfeC8.woff2)format("woff2"),url(/assets/barlow-latin-500-normal-C1h8hMer.woff)format("woff");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Barlow;font-style:normal;font-display:swap;font-weight:600;src:url(/assets/barlow-vietnamese-600-normal-DcjprdFV.woff2)format("woff2"),url(/assets/barlow-vietnamese-600-normal-CA_GiK2e.woff)format("woff");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Barlow;font-style:normal;font-display:swap;font-weight:600;src:url(/assets/barlow-latin-ext-600-normal-B8NK_A3D.woff2)format("woff2"),url(/assets/barlow-latin-ext-600-normal-DMVRjfRT.woff)format("woff");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Barlow;font-style:normal;font-display:swap;font-weight:600;src:url(/assets/barlow-latin-600-normal-DILqtrty.woff2)format("woff2"),url(/assets/barlow-latin-600-normal-CNwfPWQD.woff)format("woff");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Barlow Condensed;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/barlow-condensed-vietnamese-500-normal-DjeaNLFD.woff2)format("woff2"),url(/assets/barlow-condensed-vietnamese-500-normal-CsrJDWc5.woff)format("woff");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Barlow Condensed;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/barlow-condensed-latin-ext-500-normal-yA5ONLQ9.woff2)format("woff2"),url(/assets/barlow-condensed-latin-ext-500-normal-B1RE8WP7.woff)format("woff");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Barlow Condensed;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/barlow-condensed-latin-500-normal-BgYH2mbd.woff2)format("woff2"),url(/assets/barlow-condensed-latin-500-normal-HIEiP5Ov.woff)format("woff");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Barlow Condensed;font-style:normal;font-display:swap;font-weight:600;src:url(/assets/barlow-condensed-vietnamese-600-normal-A5AYRdjN.woff2)format("woff2"),url(/assets/barlow-condensed-vietnamese-600-normal-CNlPk46_.woff)format("woff");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Barlow Condensed;font-style:normal;font-display:swap;font-weight:600;src:url(/assets/barlow-condensed-latin-ext-600-normal-18ESti3H.woff2)format("woff2"),url(/assets/barlow-condensed-latin-ext-600-normal-Clv9cIcR.woff)format("woff");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Barlow Condensed;font-style:normal;font-display:swap;font-weight:600;src:url(/assets/barlow-condensed-latin-600-normal-DepVgxBB.woff2)format("woff2"),url(/assets/barlow-condensed-latin-600-normal-BFJEwTuo.woff)format("woff");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Barlow Condensed;font-style:normal;font-display:swap;font-weight:700;src:url(/assets/barlow-condensed-vietnamese-700-normal-DYeBwlKR.woff2)format("woff2"),url(/assets/barlow-condensed-vietnamese-700-normal-DhIzd8Tb.woff)format("woff");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Barlow Condensed;font-style:normal;font-display:swap;font-weight:700;src:url(/assets/barlow-condensed-latin-ext-700-normal-CwuXbfVR.woff2)format("woff2"),url(/assets/barlow-condensed-latin-ext-700-normal-BIHFfxf0.woff)format("woff");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Barlow Condensed;font-style:normal;font-display:swap;font-weight:700;src:url(/assets/barlow-condensed-latin-700-normal-v1xN8_Wq.woff2)format("woff2"),url(/assets/barlow-condensed-latin-700-normal-Dmwat-ge.woff)format("woff");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:400;src:url(data:font/woff2;base64,d09GMgABAAAAAASIABAAAAAACQQAAAQuAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhwbHhwoBmA/U1RBVF4AdBEICoRkhAALIAABNgIkAzoEIAWFAAeBFAwHG2oHKJ6DceNW4lJEFHn9tEOE37LNsvkjHr7f739rn3u+OSrSxLQytE91Dw2PYtNVq3Qaw/vJ7fUBMdOj/u2ImB98cT5WUx9F13ZKt06mU7tG1sAYcM26yCRX4f/0904bmwq8hwkUUMTRX61pa9C3xlpAGYw1vOu8C2SBZZFlld7DAW82RJWmwYMI1AJCKBNCIASqdZGFmtPSNQRhMpR0EKjWTwm6z6sJ+4jqhxjovTinVdRpZaQjaQzAYjI8NgAKDJCokgunCn9oUQE8VZd/F//+v6P4F1U9gLr58yNI/dJX9BAshEoJbTDogz7ocKoUsPvES8UK/aQIUQgpGgECBVLkOEV6iASTYgNAPKdNXayhDPL7IJuAZnEYSZ0eOLc9i5Rv5/+lEi3sW/kfnCf/+fTe0sxS7CKLx5erRJkKOixEqQaoqrvx5HN4iz4VhX0gS6DjFIWUzn/fIXJRVFY1NFRVNVeFt+SYmrK6vCU6eJsnKnJj5HTESMTQZOTI3Y/tzr3rUcOsiRy/ciP50s3Mycgxmhz9GMXhjzVH30ut796NHP0UUa31/Zoa6vCH6iPvdIM0IRANaT60FablmZlZd+UKNFy9NrvnFGxb5NC2CRxR0/rIyF/WNn+35sv9r+tHVhkseuWGKkCPPh96+GXt8Lc/Sh24ujfjf+tNw1lZWreiPuHb/PSpyjdv2rf/++ZE5TSKjFdZxYsBvr1sEHl5STuHZqYR7jGYGvGBBdjcaB5bODY1GAxMjsd0wDMIzXAXODRd74DxNMtO4YuYHclgLQRzp9KlUmxptCwv9bYgvWGD2xBW7r9413fdJu+mxzvzAUYeeONQvZP4kgfqZle4jhH/MWh+UbxgtJdrLdXLymNL53PRU0D3Q6FcXTfGqGcul6vrqhgLGAVSv+IVIfZOHpu+mlLqSlnj903j8mazXDsba/wbxhS/4Oubh1c5/uXDgt4j5KtnGEy5BIJHo0ur+jD+r2qCkuP1aRVM8EpUoRYSJyqNRA38uwDvHBNo0AejO2Z+ZYLLal1QiFyFh1EDQOgSCSCpjwwKU8yDbIjroEwne0G5Qca49cYp4AlqtQNZfWTQoFb1tRpFYAmRD+HXTkV4uQhG2bg4OKmyoypAsUGtWgQXyFxYrkpODeUxvGqIZA61erXo0sFG1UBGuPgpuon8RNUG2DhovAjZCBuZwtXrU3mQGki9+pm0eVZAXoWxLWTQoYHBPrJR4WunNxIFbCHfkTyPK+sqxjxDmGArZvf79JGJ3GwEqjwc7a7NIrl/7bJ7Nzu4+n1Ow6shEPnUrtVo7cnd5Wi5qCUbBIQbNKCP95FMCSZylEV5VCiiMqqiOmrKZ/I/C0gI1fyuulVcM2E1r4MhtcV/fbCD+HwEvVzH1dGNAzFE0FTbKzyQz3gootrNbN2a4PuG0j0JOgE=)format("woff2"),url(data:font/woff;base64,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)format("woff");unicode-range:U+460-52F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/jetbrains-mono-cyrillic-400-normal-BEIGL1Tu.woff2)format("woff2"),url(/assets/jetbrains-mono-cyrillic-400-normal-ugxPyKxw.woff)format("woff");unicode-range:U+301,U+400-45F,U+490-491,U+4B0-4B1,U+2116}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/jetbrains-mono-greek-400-normal-C190GLew.woff2)format("woff2"),url(/assets/jetbrains-mono-greek-400-normal-B9oWc5Lo.woff)format("woff");unicode-range:U+370-377,U+37A-37F,U+384-38A,U+38C,U+38E-3A1,U+3A3-3FF}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:400;src:url(data:font/woff2;base64,d09GMgABAAAAAA9UABAAAAAALMAAAA7zAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGnAbhWocghYGYD9TVEFUXgCDBBEICrBAp3ILgjgAATYCJAOEKAQgBYUAB4xODAcbIiYzo8LGAQCKfn4o/usELQ4rdj22ABHwitFYjZPqB3XSqAbV3C5dFkHYtTehxpeGbU+3+QexdERCkxARw9oNxAyetvXzdhdjl/7aiBiHgcqBjZywaGPSh4mNFccpF3DHlfyO8Jc/OiSe/kb7/iQYRAE23iScpHngiRRBFETNiZzQwc2HOllJ0fqXIjTY8RTYbDsklKc81hGPQcOJojhD/w80ll1aG/qiQErbzqOXjmvOVKd14tuv+Hxrlbarq/5xH7CiMPjaZXlrfNSp7uqaroZXvYAzc8A0kH2zs3MvHQBUORcJ2GG2cdFRgArh+Sgb7yOsjImpmgM0kq1FwhQCQzQ1Mt+j7at5GSAAIQAAKFLk6uMul4pIl4HIpEEUK0dUMiCMmhFWNoSDC+Exghgzi5i3hNhtN9qaINo+EbQj1tEIgJVLj5oebQ6I1/fyLMQYALYgALKS0yEOQCJG89uIiEPKyeRDVCmC0HgZ203jIg7kk6cHxfEKeBSDXtxd6n5yJzqpfSgXs9xMri1fPezlKMAVcCGEIhmwHiDRtJOyKfXkGsAVqI7ohIZs0rsDM/IU4fuQgkppCk2n+VRHy6mFttJ26t16mBjQPyIeYhvZnyXaiDSeaAYYXLiKPIm4uKh1zIq6gSRVU7WNPIV5v1PwBOy07RrrT6skwoEAtYyZeYgpBUABaDEmtPWRGP/UGABFgUUjchFXAghAgAYQpyPkCIBBoRwQgU/g3kQcyqTY9KSDItmjjmmkP+qJHG3C66hjXhtlhzwglI+1+4Be+T77hYQxxeNkCIDaKU+ANXhkMqePOVAQr7uwCjoBlCdtHQE8TNRd17//A/evkhSpkOMDA9VTmwAVAbLNlwMkoAG5qG2bWCYA/h3uEYgEhFqSmJJPpCIFbJHg1Aw5GaAujjqMzIHc8NrIHBEJJjGZP3cuFQZD9PvzLvZIaCIjBcTvEnIzTWiGjqdzlD+VAO2TUERK8smEi8lNNOguiAM9P6Gfo6bX8bD0v7V/cPwA/fDBi0BaGgUllWy5AATy6X9gAZqRVIsMLuVmqQ3QmrBbiFgTiWbxLDj1hBqINGLVYewQwySWWRyeQK1kXVJ0S2UjZ5WgXaIOSTodp42CUzqHXH226ZfJI4tXth45eqnslGdQgSGFhmmMyOdTbEyJcdv56U0pNa3MDJ1JVRZUmldtkcESglQkAOA8AMgAoBeYLQi+wDxAtwAAGlXJUdVLPLmo/TLRystE3SsqO29LUY0hsrtvBoXUw1Fy+XjIhqbj4rEZISsUysW1L68PlGRwyWImjWXjS9LFyUzjC7v7Z5hYsYKRhIH49EyxTJxutwOy2PRxp1R63SVViB+eNFYRywlEzJBIMDIl5Aa4PtbFOno416WTTkfVQwSPgIve66BCbLAuLmpCh59ln5uFECODSuUIJ2CJCCzDwbf+DV2/3yTtan5J1gEVuilcVASHULO9Bt+nWkIEHMMit5gOxaO4JpWjvdzOcySeFek9q4dy3jxi2BxHwsuuo2CzbQ+KJWxyqPUJljVCU3WT8JwlhZyLkKODRhZkQByHu8ERJIcGBexSmdwGPfMPbjnC0SwRUTyCAIwY4Mdr9zxJTKE5yp0mcEe9s3Umm/TZp2s4X/27cQUmhrd4Ow4ibPOTOxxT6w+S8ENc9AGE7meFOlNbuzjngJtzjFKcrMsxtf4G4UIPcNGXbvwNaeDea6+1L7kaYG+M13a455pruOh5Ww0HlhllPy/PsqS9Zr7ZV9cSLODAoItzBt2cI5i1brCxQRIcH6yr9wV5+XjhtlxuziH7LiqGTXVnkfCZntd1doJ5liyIno6X3GqH56fcnGNwE2IXvYhw5a/MJGsMns/TOawd+2HX5kOXxQZFsYkwmMetzGtqKDKSe+h9h7jX77z2Snb98vyL7rjmil1N3B/cCBfsC5rymA/ExpPlni/DL9i7eflmn66oxrSlMRRB/8Dbq/e/3aN95L3BG+dFd1d+uCVzKhQy5/+I77CmWJ/o2Hygaay8yleXU1c1NH2IpqHOYUtriyWHf3iZwxjZvNxm/Ti/O5+22uC3nVFxhu1wvQc08ZZ+nb5/9oBF38ehJXaKPt7K6/v34Ltqai21rbXDXI3BRDa+9XDSGp8gzZZarV2ag9v3RBzSNfFjU/M+uVduNDTsMNY0GCOHDU3O4dazeb3zFXjg0rlPuiV75+m+kzV3v5qc/PHdJ2j6pI+wDP+U7mFPW/uw23ltZemTVTo+3+KNa1yyuwdmfI41j1/yvbG3oaLR3G3Sd1xdrNOUfAou3jYw0z860D9jr+9sqU1IIHve9W56/fIEU2fztvaqHQ213trhKauqjXVmr/kFxP1m7bdCE88Plpb1m840l/VNQz72QvvMPlc5z9fvKPt1xBtXv9yVZ9nGmxscXiDfwGcI4LQ9duBaG7Nxjw2aWMuArp7In2qxObTwKfr40/iy/j34zhqeN59qHuZqDBaysQWiL/PZsk4cyV13mvbwWw7phfEDC/O+fm9/ram+sspcXxs5hm9pHjufSujGRbKXaTPmBAPPfMm45bau15+jR/bbBx80mR7sCth94rfB6Q6sngJcuO1v4a7Lu157ad9GKIlypuEea9GDnXs0IytDmZ2Rka2cVv4jrIHmaFZ3O9OWlWX7gLuRH1mMjsxE8VrEH/XNRrErsh61R6PD3e2d7dDsb3Z38k15W/kFkrwmHk+PhWNKx3nLMhHkSl5ZLMvHWPGPfwRB9AKr2QoSUb4qSlB18X715zkqwRI0G3lvUOptugtcID+tsKQForrC+pqxS4X1dcof21bf4OQcbZ2Le6y53kKao3rxNWE9f1a+S3t2tiIu5yej2d/W12RozBwrLh7LbDT0NkUDi+HBQPj0xIlAoKHFFxAMPB8Vce+KKo28Rq0SHV3LUk6MNLv35DMrCzVNmbxBeCGCKzMtu20y8f+SVD4h31Sosky03Upl9YJxzh+L0ZFANLR4LOpYj452tne145E/wok2e6JX/xBX/vH8WaFQojdWlrhzuOXjs1Zn3cCkT4qWSmZeqX/B4tciE4HBmUBZwGxtMDaqnCpdllPVaIzdNw9ZqfDU30ppYDgw2B+A5JP5L8bj4tgWoy/t6WRRcO2P8uFDakiP2fMWaviyaOYFr94gE0nEsXysWligOuHRC2TiH0XSJ/4WqQcjE4GxmUAocKlG+jECgZHFwGX8vabVzf8f4KQSi8Gp6laIdgV0q8OzbmjyaWdnW1MQXZoJDb7ZaEdzVzMoNQiAGESUwszDAIzTDIqSxGFoxoRZ/vTKM8CfyZ9V/ZAPfzZ/Ds4tMHm0dSxCkOPaNpKlK8/KwGQVCdzqbPDn1HKuiT8WHUnStEQYZB2TC6WJ6spymNIjBV7JK5lSs1C5qDoRSYBUSlgH31LlM7X5O4o8eBxrX3MDwtOG1iZdZ/NjXsu0gBJohRVmlQNfwVfQmsReAdZEAahljqkMaxLHg/gT+BONkwxcgT0CH/5k/pQrcCpMUYiGtPqbDGvVgALfitYyTHyI7iP25WqsSqAlstCbcmZ3k0PcRZlgbs0KCrwb7lImBTqQCCawVEpMWHur0DRm3+9sVAOK6UQiqESr8NaEtY8Vu86AIjK3KRZhXNwqD34Oc38umLZM7/33+38/uOj7///Z9yMAAHqAUtN3Bsa/l9rSiKVxlONqqbKozYWfYMRMRkicEE2FhIs4TuWQJL0RDNwCPy0hP1CbGAVY9Mb6W+DZ2p14CIQoIBjqGKpe6lOONhDJTUFBXMgZYOPct8C7Ffmf2jR2ksQ72U7f6SBu5gywoW8x2Qhy1APl1CZGAQ4ksGGD8loGsjY0UQKXmhdvpBboCNglmiU2XUCieL2dF1bDaTacoykaTjgFAhquyoFkiSk0LZyooeM7gQDVIlmNOwCPlICNKQpatkhBhUQJpdLCVwFqWj3FQ8sWeajTWbJiLeRJQlRmsyh1YLRZtAzVNr0dAoCqYN6wXLhzQGL8LY6mvwSAd1698ly88s2Xfwa7FbVA/wsgBhQAgABfG3dQHs2o/066DhB0wWo68NIlpR8Rtqkj9flbwtMc3oZyWoIn3n+L86o5vA1V8ng6L4C9+Ax3YgMBHN8Er4rV97ZRXgdo2vF244hH35wAzlOM0Y1BABGNnNCZ4UFNPID7U9KeSCgiP5EiDnMizejpExlFzj9RIM2BE2MU8pwgViH7TAQQSqpgnDuJJAk2kHIaYDNnhs+sFsvBuaf5DXMbXT9uwvLIbk49b4mBNm3JsEV+85YtKUHWb5rT5ywap9WpUZtWo6q5Fot8W89a0m4OaXOK2Ywat2KaD3NdRi1S/+eloldCT0fn1K5q61Mpa6eaNrKMB6WMQqn83IfXmTNv1eIRiaKj7aOsikMmoxej+EfqsmjOpFHDLnneylGLQxT66vnHnh/n12VXDN1Hw6/bcNpctWo3vrwApZvfrdEDiP8IzgPkeiYUoQlzDvYWB0cnZ6uLq5t7+aRk5I6TIFGS5IqkSJWWXjqFDEqZVLJky5FrG7W8quQrUEijSLESWtsz0tErVVa9chUqValmUMNoh1omZjxSM4s69Ro0atKspTe1smrLpl2HTl262dg5OLm4eezMw6tHrz79BgzyGarXsBGjxqJtJvhNmjJtxqw58xYsWrJsxS4Bu61aE7THXvvsFxJ2wEERhxx2xFHHrIs6fuE/r+1vm6/8jhhtDCwnASDGR1h4SGhYwEGU1Y/Xffk5G4u9XgIAYtxyGpZ5y9sDdNbyP142W5DgAhoE7i3q0c5x2vm9v24aZuNohdcxqSEAz8up00My03HSwmqPa8bMecG3Tjzb+f9EelEtg2vpzPeiIEEBwSA8IEDBwAE9F5Z6vQIQjAnLGTgWLO+uZTL/qwGEAYOAQpg3TefgwBCQgBDzqukKDBAOoU3KVtqIbBXK9XpEAAujuudkZN724kIGmrtVaS38ZZLrS9/4fsKMQhN3yXK5gvSBvJ2Y9/Nydbcvb0bm58+e3FhmGfGLJ9u7axl1F1LQTbaCeyrbu7wFCsorFgV4qnh+GUrWtaczqkSBB96AEeKRB94k2SyLuyw3qwrxeg3P5FNR1Av1Gsq2/ds6dPPkBAAA)format("woff2"),url(/assets/jetbrains-mono-vietnamese-400-normal-CqNFfHCs.woff)format("woff");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/jetbrains-mono-latin-ext-400-normal-Bc8Ftmh3.woff2)format("woff2"),url(/assets/jetbrains-mono-latin-ext-400-normal-fXTG6kC5.woff)format("woff");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2)format("woff2"),url(/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff)format("woff");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:500;src:url(data:font/woff2;base64,d09GMgABAAAAAASUABAAAAAACRAAAAQ3AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhwbHhwoBmA/U1RBVEwAdBEICoRkg3oLIAABNgIkAzoEIAWFHgeBFAwHG3AHKB4HzukrRjyF5Gb4kQ/B873d17mv8TWkoqUUGaHodJCtoqntw7m8tiPWyGkfWDU/IMpzVk4zAs9Czv3c7Os5NvKFG1Ht9vBVXySRZpJc4tTrbM3sTRFcLa3zVboKWRIoAksKSKgqUQWEwlSoqjp44V5J9/kjd0+Fi5xaFjwJArgBAIJgIAgCCAI4CdNMqGuYXYUKdADLAkAAJwl6iX0+bZqEm1AH0Hu9rvrJHwxQG1Q/gFYwWYbgTRWgwEESVzbmtjQAt3DXO7Tu/+9Q/KNKWhTCgZ8fQSWoL0CUUgTBjgL8iEAcce7YHBeA8ZvogieCnxI0BCVeACCAAhBD/oDcAdUPABSgAX4kBPBTwjCAjwYSCneiqF65LUo/qXdYFrRwTujtMrKm07plTbSqLQFAiHBN7E4DG5wkiGXhCYBNETh3K/AciHN69iFfQjFOr9EXQQAAQXRNszs8PR0OH4fDV/dwGe76CHdj1MQa11DXYGcfZ6+B1X0OfwjY+i7KpQ1w9d+1z3/HydCB1f3U8A0fRFv+0bXxPWrZu3d9Nn4UcbLs/QCXLH/j3PCKblKOiZxLOR78W9brPo7eGTLz/F27ZPmePQdCB1YP4nJU91o4gU9cy64L3c3SPu8GfDn6ZXD2cGmllVqSxtD5vCXHm5xaeHlnpffx7DcPvXog5NnjA//cPz2btsz3yf+0MI8ri33tuv7upNbYmW5STbosW8bYItV/SPzxvXC0KnpWnFdC91oojit5Lyo6WcJQ1YzwBYbi52ohJVpcxfcHBqsv0nFz8U74rzS6M7r0RVlXZ3jJC4G92O//7Lm78VOtnUx+aQxAzsqPnrRr1t9zDrezKePvZ027x+fGte4s4NXu7/jEp3G9cM1bICYgACbuETUUD5wmenGXA/IBpAKVrl0AEJ5cqr6Q89tGq+SpqkDfX2DtG+pZ9teuae0AX98c301CX179InyErnSG8WCiABB4HFbVrw/lpTdBIOk82nXbpHKoQGyBpUovAAD4XQA8ZTUCeBJHIpI0v0FRrgcnckV3ANckrwYJKXEihQfdSKPER6XeExmEeEMmSe6QBwWmkZdmSOSthhibgIkBlUYreBKd/0NeVAE9WAyEaQpH6KikDWlUVg43Jy2FOmaYlsZhDEGZXO3mWEyWHI6zuaJkMlcSQ9k4F+KidIiFyZItGDc7r1pUj6wP6zrWB0/fbeeFeHl4YOvETMNiM8Ny+7OO6Qh2wur20YVxFts5dlORdl5Kwd5utR7SRcxqX8RA5Ehacha76hg7c6yzNm/Xf6vOLNrv544lIEkWg7xWo/ItBAeIJEmt0XgBwgM8gTifoiiLJroYYooNTeziEKe4zOoR/wvIKp89hSr+6jFAqw/LaonjmZHSscMNg4iPlWpFrO1RN3zkMU+/xUP+JQ99TbvTl1Vg0gtirT6lbwYAAAA=)format("woff2"),url(data:font/woff;base64,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)format("woff");unicode-range:U+460-52F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/jetbrains-mono-cyrillic-500-normal-DmUKJPL_.woff2)format("woff2"),url(/assets/jetbrains-mono-cyrillic-500-normal-DJqRU3vO.woff)format("woff");unicode-range:U+301,U+400-45F,U+490-491,U+4B0-4B1,U+2116}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/jetbrains-mono-greek-500-normal-JpySY46c.woff2)format("woff2"),url(/assets/jetbrains-mono-greek-500-normal-D7SFKleX.woff)format("woff");unicode-range:U+370-377,U+37A-37F,U+384-38A,U+38C,U+38E-3A1,U+3A3-3FF}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:500;src:url(data:font/woff2;base64,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)format("woff2"),url(/assets/jetbrains-mono-vietnamese-500-normal-DNRqzVM1.woff)format("woff");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/jetbrains-mono-latin-ext-500-normal-Cut-4mMH.woff2)format("woff2"),url(/assets/jetbrains-mono-latin-ext-500-normal-ckzbgY84.woff)format("woff");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/jetbrains-mono-latin-500-normal-BWZEU5yA.woff2)format("woff2"),url(/assets/jetbrains-mono-latin-500-normal-CJOVTJB7.woff)format("woff");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}:root{--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark;--radius:.625rem;--background:#0e1012;--foreground:#e6eaee;--card:#15181b;--card-foreground:#e6eaee;--popover:#15181b;--popover-foreground:#e6eaee;--primary:#ffb020;--primary-foreground:#1a1300;--secondary:#1c2126;--secondary-foreground:#e6eaee;--muted:#1c2126;--muted-foreground:#8b949e;--accent:#1c2126;--accent-foreground:#e6eaee;--destructive:#ff5a4f;--border:#262b30;--input:#3a4148;--ring:#5cc8ff;--panel:#15181b;--erhaben:#1c2126;--linie:#262b30;--linie-stark:#3a4148;--text-2:#aeb6bf;--text-3:#8b949e;--bernstein:#ffb020;--bernstein-hell:#ffc24d;--bernstein-grund:#2a1e05;--bernstein-lampe:#3a2a08;--gruen:#3ddc8a;--gruen-text:#7cc9a0;--gruen-grund:#0f2319;--gruen-rand:#1f5a3b;--cyan:#5cc8ff;--cyan-text:#93d5f8;--cyan-grund:#0c2230;--cyan-rand:#2f7fb0;--rot:#ff5a4f;--rot-text:#ff9a92;--rot-grund:#2e0f0d;--rot-rand:#a33a33;--aus-grund:#171b1f;--aus-rand:#2e343a;--aus-text:#9aa3ad}@keyframes lampe-atmen{0%,to{box-shadow:0 0 10px color-mix(in srgb, var(--bernstein) 25%, transparent)}50%{box-shadow:0 0 22px color-mix(in srgb, var(--bernstein) 45%, transparent)}}@media (prefers-reduced-motion:no-preference){.lampe-atmet{animation:3.2s ease-in-out infinite lampe-atmen}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0)scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1))rotate(var(--tw-enter-rotate,0));filter:blur(var(--tw-enter-blur,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0)scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1))rotate(var(--tw-exit-rotate,0));filter:blur(var(--tw-exit-blur,0))}} diff --git a/frontend/dist/assets/index-B6MevgIX.js b/frontend/dist/assets/index-ZVRs0IGR.js similarity index 95% rename from frontend/dist/assets/index-B6MevgIX.js rename to frontend/dist/assets/index-ZVRs0IGR.js index 9c51f76..582985c 100644 --- a/frontend/dist/assets/index-B6MevgIX.js +++ b/frontend/dist/assets/index-ZVRs0IGR.js @@ -1,4 +1,4 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/Dienste-QEbMZv2T.js","assets/button-Dd8hfusv.js","assets/sheet-DWG2Q04V.js","assets/dist-CgRgLCFz.js","assets/Einstellungen-DMWgWLUo.js","assets/MehrMenue-gZV9ubEU.js","assets/Protokollfenster-CDb28asU.js","assets/Updates-3PYj6oWY.js","assets/Modelle-PWfbWtFC.js"])))=>i.map(i=>d[i]); +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/Dienste-DEn0Zjkq.js","assets/button-Dd8hfusv.js","assets/sheet-DWG2Q04V.js","assets/dist-CgRgLCFz.js","assets/Einstellungen-BwCmWl9x.js","assets/MehrMenue-CXteqmy8.js","assets/Protokollfenster-CDb28asU.js","assets/Updates-DPFIId2v.js","assets/Bestaetigen-VrcNpcBb.js","assets/Modelle-CHK2sw1N.js"])))=>i.map(i=>d[i]); import{a as e,c as t,d as n,f as r,i,l as a,o,s,t as c,u as l}from"./button-Dd8hfusv.js";(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),t.credentials=e.crossOrigin===`use-credentials`?`include`:e.crossOrigin===`anonymous`?`omit`:`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var u=n((e=>{function t(e,t){var n=e.length;e.push(t);a:for(;0>>1,a=e[r];if(0>>1;ri(c,n))li(u,c)?(e[r]=u,e[l]=n,r=l):(e[r]=c,e[s]=n,r=s);else if(li(u,n))e[r]=u,e[l]=n,r=l;else break a}}return t}function i(e,t){var n=e.sortIndex-t.sortIndex;return n===0?e.id-t.id:n}if(e.unstable_now=void 0,typeof performance==`object`&&typeof performance.now==`function`){var a=performance;e.unstable_now=function(){return a.now()}}else{var o=Date,s=o.now();e.unstable_now=function(){return o.now()-s}}var c=[],l=[],u=1,d=null,f=3,p=!1,m=!1,h=!1,g=!1,_=typeof setTimeout==`function`?setTimeout:null,v=typeof clearTimeout==`function`?clearTimeout:null,y=typeof setImmediate<`u`?setImmediate:null;function b(e){for(var i=n(l);i!==null;){if(i.callback===null)r(l);else if(i.startTime<=e)r(l),i.sortIndex=i.expirationTime,t(c,i);else break;i=n(l)}}function x(e){if(h=!1,b(e),!m){if(n(c)!==null)m=!0,S||(S=!0,te());else{var t=n(l);t!==null&&re(x,t.startTime-e)}}}var S=!1,C=-1,w=5,T=-1;function ee(){return g?!0:!(e.unstable_now()-Tt&&ee());){var o=d.callback;if(typeof o==`function`){d.callback=null,f=d.priorityLevel;var s=o(d.expirationTime<=t);if(t=e.unstable_now(),typeof s==`function`){d.callback=s,b(t),i=!0;break b}d===n(c)&&r(c),b(t)}else r(c);d=n(c)}if(d!==null)i=!0;else{var u=n(l);u!==null&&re(x,u.startTime-t),i=!1}}break a}finally{d=null,f=a,p=!1}i=void 0}}finally{i?te():S=!1}}}var te;if(typeof y==`function`)te=function(){y(E)};else if(typeof MessageChannel<`u`){var D=new MessageChannel,ne=D.port2;D.port1.onmessage=E,te=function(){ne.postMessage(null)}}else te=function(){_(E,0)};function re(t,n){C=_(function(){t(e.unstable_now())},n)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(e){e.callback=null},e.unstable_forceFrameRate=function(e){0>e||125o?(r.sortIndex=a,t(l,r),n(c)===null&&r===n(l)&&(h?(v(C),C=-1):h=!0,re(x,a-o))):(r.sortIndex=s,t(c,r),m||p||(m=!0,S||(S=!0,te()))),r},e.unstable_shouldYield=ee,e.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}})),d=n(((e,t)=>{t.exports=u()})),f=n((e=>{var t=d(),n=l(),r=a();function i(e){var t=`https://react.dev/errors/`+e;if(1we||(e.current=Ce[we],Ce[we]=null,we--)}function j(e,t){we++,Ce[we]=e.current,e.current=t}var De=Te(null),Oe=Te(null),ke=Te(null),Ae=Te(null);function je(e,t){switch(j(ke,t),j(Oe,e),j(De,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?up(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=up(t),e=dp(t,e);else switch(e){case`svg`:e=1;break;case`math`:e=2;break;default:e=0}}Ee(De),j(De,e)}function Me(){Ee(De),Ee(Oe),Ee(ke)}function Ne(e){var t=e.memoizedState;t!==null&&(sh._currentValue=t.memoizedState,j(Ae,e)),t=De.current;var n=dp(t,e.type);t!==n&&(j(Oe,e),j(De,n))}function Pe(e){Oe.current===e&&(Ee(De),Ee(Oe)),Ae.current===e&&(Ee(Ae),sh._currentValue=A)}var Fe,Ie;function Le(e){if(Fe===void 0)try{throw Error()}catch(e){var t=e.stack.trim().match(/\n( *(at )?)/);Fe=t&&t[1]||``,Ie=-1)`:-1>>=0,e===0?32:31-(ot(e)/st|0)|0}var lt=256,ut=262144,dt=4194304;function ft(e){var t=e&42;if(t!==0)return t;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return e&-e;case 262144:case 524288:case 1048576:case 2097152:return e&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function pt(e,t,n){var r=e.pendingLanes;if(r===0)return 0;var i=0,a=e.suspendedLanes,o=e.pingedLanes;e=e.warmLanes;var s=r&134217727;return s===0?(s=r&~a,s===0?o===0?n||(n=r&~e,n!==0&&(i=ft(n))):i=ft(o):i=ft(s)):(r=s&~a,r===0?(o&=s,o===0?n||(n=s&~e,n!==0&&(i=ft(n))):i=ft(o)):i=ft(r)),i===0?0:t!==0&&t!==i&&(t&a)===0&&(a=i&-i,n=t&-t,a>=n||a===32&&n&4194048)?t:i}function mt(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function ht(e,t){t&8&&(t|=t&32);var n=e.entangledLanes;if(n!==0)for(e=e.entanglements,n&=t;0n;n++)t.push(e);return t}function yt(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function bt(e,t,n,r,i,a){var o=e.pendingLanes;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=n,e.entangledLanes&=n,e.errorRecoveryDisabledLanes&=n,e.shellSuspendCounter=0;var s=e.entanglements,c=e.expirationTimes,l=e.hiddenUpdates;for(n=o&~n;0=yr),Sr=` `,Cr=!1;function wr(e,t){switch(e){case`keyup`:return _r.indexOf(t.keyCode)!==-1;case`keydown`:return t.keyCode!==229;case`keypress`:case`mousedown`:case`focusout`:return!0;default:return!1}}function Tr(e){return e=e.detail,typeof e==`object`&&`data`in e?e.data:null}var Er=!1;function Dr(e,t){switch(e){case`compositionend`:return Tr(t);case`keypress`:return t.which===32?(Cr=!0,Sr):null;case`textInput`:return e=t.data,e===Sr&&Cr?null:e;default:return null}}function Or(e,t){if(Er)return e===`compositionend`||!vr&&wr(e,t)?(e=Bn(),zn=Rn=Ln=null,Er=!1,e):null;switch(e){case`paste`:return null;case`keypress`:if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:n,offset:t-e};e=r}a:{for(;n;){if(n.nextSibling){n=n.nextSibling;break a}n=n.parentNode}n=void 0}n=Zr(n)}}function $r(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?$r(e,t.parentNode):`contains`in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function ei(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var t=Xr(e.document);t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href==`string`}catch{n=!1}if(n)e=t.contentWindow;else break;t=Xr(e.document)}return t}function ti(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t===`input`&&(e.type===`text`||e.type===`search`||e.type===`tel`||e.type===`url`||e.type===`password`)||t===`textarea`||e.contentEditable===`true`)}var ni=Pn&&`documentMode`in document&&11>=document.documentMode,ri=null,ii=null,ai=null,oi=!1;function si(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;oi||ri==null||ri!==Xr(r)||(r=ri,`selectionStart`in r&&ti(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),ai&&Yr(ai,r)||(ai=r,r=Jf(ii,`onSelect`),0>=o,i-=o,ra=1<<32-at(t)+i|n<h?(g=d,d=null):g=d.sibling;var _=p(i,d,s[h],c);if(_===null){d===null&&(d=g);break}e&&d&&_.alternate===null&&t(i,d),a=o(_,a,h),u===null?l=_:u.sibling=_,u=_,d=g}if(h===s.length)return n(i,d),P&&aa(i,h),l;if(d===null){for(;hg?(_=h,h=null):_=h.sibling;var y=p(a,h,v.value,l);if(y===null){h===null&&(h=_);break}e&&h&&y.alternate===null&&t(a,h),s=o(y,s,g),d===null?u=y:d.sibling=y,d=y,h=_}if(v.done)return n(a,h),P&&aa(a,g),u;if(h===null){for(;!v.done;g++,v=c.next())v=f(a,v.value,l),v!==null&&(s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return P&&aa(a,g),u}for(h=r(h);!v.done;g++,v=c.next())v=m(h,a,g,v.value,l),v!==null&&(e&&(_=v.alternate,_!==null&&h.delete(_.key===null?g:_.key)),s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return e&&h.forEach(function(e){return t(a,e)}),P&&aa(a,g),u}function _(e,r,o,c){if(typeof o==`object`&&o&&o.type===re&&o.key===null&&o.props.ref===void 0&&(o=o.props.children),typeof o==`object`&&o){switch(o.$$typeof){case D:a:{for(var l=o.key;r!==null;){if(r.key===l){if(l=o.type,l===re){if(r.tag===7){n(e,r.sibling),c=a(r,o.props.children),mo(c,o),c.return=e,e=c;break a}}else if(r.elementType===l||typeof l==`object`&&l&&l.$$typeof===fe&&oo(l)===r.type){n(e,r.sibling),c=a(r,o.props),mo(c,o),c.return=e,e=c;break a}n(e,r);break}t(e,r),r=r.sibling}o.type===re?(c=Wi(o.props.children,e.mode,c,o.key),mo(c,o),c.return=e,e=c):(c=Ui(o.type,o.key,o.props,null,e.mode,c),mo(c,o),c.return=e,e=c)}return s(e);case ne:a:{for(l=o.key;r!==null;){if(r.key===l){if(r.tag===4&&r.stateNode.containerInfo===o.containerInfo&&r.stateNode.implementation===o.implementation){n(e,r.sibling),c=a(r,o.children||[]),c.return=e,e=c;break a}n(e,r);break}t(e,r),r=r.sibling}c=qi(o,e.mode,c),c.return=e,e=c}return s(e);case fe:return o=oo(o),_(e,r,o,c)}if(Se(o))return h(e,r,o,c);if(ye(o)){if(l=ye(o),typeof l!=`function`)throw Error(i(150));return o=l.call(o),g(e,r,o,c)}if(typeof o.then==`function`)return _(e,r,po(o),c);if(o.$$typeof===se)return _(e,r,Ma(e,o),c);ho(e,o)}return typeof o==`string`&&o!==``||typeof o==`number`||typeof o==`bigint`?(o=``+o,r!==null&&r.tag===6?(n(e,r.sibling),c=a(r,o),c.return=e,e=c):(n(e,r),c=Gi(o,e.mode,c),c.return=e,e=c),s(e)):n(e,r)}return function(e,t,n,r){try{fo=0;var i=_(e,t,n,r);return uo=null,i}catch(t){if(t===eo||t===no)throw t;var a=zi(29,t,null,e.mode);return a.lanes=r,a.return=e,a}}}var _o=go(!0),vo=go(!1),yo=!1;function bo(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function xo(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,callbacks:null})}function So(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function Co(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,W&2){var i=r.pending;return i===null?t.next=t:(t.next=i.next,i.next=t),r.pending=t,t=Ii(e),Fi(e,null,n),t}return Mi(e,r,t,n),Ii(e)}function wo(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,n&4194048)){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,St(e,n)}}function To(e,t){var n=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,n===r)){var i=null,a=null;if(n=n.firstBaseUpdate,n!==null){do{var o={lane:n.lane,tag:n.tag,payload:n.payload,callback:null,next:null};a===null?i=a=o:a=a.next=o,n=n.next}while(n!==null);a===null?i=a=t:a=a.next=t}else i=a=t;n={baseState:r.baseState,firstBaseUpdate:i,lastBaseUpdate:a,shared:r.shared,callbacks:r.callbacks},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}var Eo=!1;function Do(){if(Eo){var e=Ga;if(e!==null)throw e}}function Oo(e,t,n,r){Eo=!1;var i=e.updateQueue;yo=!1;var a=i.firstBaseUpdate,o=i.lastBaseUpdate,s=i.shared.pending;if(s!==null){i.shared.pending=null;var c=s,l=c.next;c.next=null,o===null?a=l:o.next=l,o=c;var u=e.alternate;u!==null&&(u=u.updateQueue,s=u.lastBaseUpdate,s!==o&&(s===null?u.firstBaseUpdate=l:s.next=l,u.lastBaseUpdate=c))}if(a!==null){var d=i.baseState;o=0,u=l=c=null,s=a;do{var f=s.lane&-536870913,p=f!==s.lane;if(p?(q&f)===f:(r&f)===f){f!==0&&f===Wa&&(Eo=!0),u!==null&&(u=u.next={lane:0,tag:s.tag,payload:s.payload,callback:null,next:null});a:{var m=e,h=s;f=t;var g=n;switch(h.tag){case 1:if(m=h.payload,typeof m==`function`){d=m.call(g,d,f);break a}d=m;break a;case 3:m.flags=m.flags&-65537|128;case 0:if(m=h.payload,f=typeof m==`function`?m.call(g,d,f):m,f==null)break a;d=E({},d,f);break a;case 2:yo=!0}}f=s.callback,f!==null&&(e.flags|=64,p&&(e.flags|=8192),p=i.callbacks,p===null?i.callbacks=[f]:p.push(f))}else p={lane:f,tag:s.tag,payload:s.payload,callback:s.callback,next:null},u===null?(l=u=p,c=d):u=u.next=p,o|=f;if(s=s.next,s===null){if(s=i.shared.pending,s===null)break;p=s,s=p.next,p.next=null,i.lastBaseUpdate=p,i.shared.pending=null}}while(1);u===null&&(c=d),i.baseState=c,i.firstBaseUpdate=l,i.lastBaseUpdate=u,a===null&&(i.shared.lanes=0),sd|=o,e.lanes=o,e.memoizedState=d}}function ko(e,t){if(typeof e!=`function`)throw Error(i(191,e));e.call(t)}function Ao(e,t){var n=e.callbacks;if(n!==null)for(e.callbacks=null,e=0;ea?a:8;var o=O.T,s={};s.types=o===null?null:o.types,O.T=s,pc(e,!1,t,n);try{var c=i(),l=O.S;l!==null&&l(s,c),typeof c==`object`&&c&&typeof c.then==`function`?fc(e,t,Ja(c,r),jd(e)):fc(e,t,r,jd(e))}catch(n){fc(e,t,{then:function(){},status:`rejected`,reason:n},jd())}finally{k.p=a,o!==null&&s.types!==null&&(o.types=s.types),O.T=o}}function nc(){}function rc(e,t,n,r){if(e.tag!==5)throw Error(i(476));var a=ic(e).queue;tc(e,a,t,A,n===null?nc:function(){return ac(e),n(r)})}function ic(e){var t=e.memoizedState;if(t!==null)return t;t={memoizedState:A,baseState:A,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:ms,lastRenderedState:A},next:null};var n={};return t.next={memoizedState:n,baseState:n,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:ms,lastRenderedState:n},next:null},e.memoizedState=t,e=e.alternate,e!==null&&(e.memoizedState=t),t}function ac(e){var t=ic(e);t.next===null&&(t=e.alternate.memoizedState),fc(e,t.next.queue,{},jd())}function oc(){return ja(sh)}function sc(){return B().memoizedState}function cc(){return B().memoizedState}function lc(e){for(var t=e.return;t!==null;){switch(t.tag){case 24:case 3:var n=jd();e=So(n);var r=Co(t,e,n);r!==null&&(Pd(r,t,n),wo(r,t,n)),t={cache:Ra()},e.payload=t;return}t=t.return}}function uc(e,t,n){var r=jd();n={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null},mc(e)?hc(t,n):(n=Ni(e,t,n,r),n!==null&&(Pd(n,e,r),gc(n,t,r)))}function dc(e,t,n){fc(e,t,n,jd())}function fc(e,t,n,r){var i={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null};if(mc(e))hc(t,i);else{var a=e.alternate;if(e.lanes===0&&(a===null||a.lanes===0)&&(a=t.lastRenderedReducer,a!==null))try{var o=t.lastRenderedState,s=a(o,n);if(i.hasEagerState=!0,i.eagerState=s,Jr(s,o))return Mi(e,t,i,0),G===null&&ji(),!1}catch{}if(n=Ni(e,t,i,r),n!==null)return Pd(n,e,r),gc(n,t,r),!0}return!1}function pc(e,t,n,r){if(r={lane:2,revertLane:Pf(),gesture:null,action:r,hasEagerState:!1,eagerState:null,next:null},mc(e)){if(t)throw Error(i(479))}else t=Ni(e,n,r,2),t!==null&&Pd(t,e,2)}function mc(e){var t=e.alternate;return e===I||t!==null&&t===I}function hc(e,t){Yo=Jo=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function gc(e,t,n){if(n&4194048){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,St(e,n)}}var _c={readContext:ja,use:fs,useCallback:z,useContext:z,useEffect:z,useImperativeHandle:z,useLayoutEffect:z,useInsertionEffect:z,useMemo:z,useReducer:z,useRef:z,useState:z,useDebugValue:z,useDeferredValue:z,useTransition:z,useSyncExternalStore:z,useId:z,useHostTransitionStatus:z,useFormState:z,useActionState:z,useOptimistic:z,useMemoCache:z,useCacheRefresh:z,useEffectEvent:z},vc={readContext:ja,use:fs,useCallback:function(e,t){return ls().memoizedState=[e,t===void 0?null:t],e},useContext:ja,useEffect:Hs,useImperativeHandle:function(e,t,n){n=n==null?null:n.concat([e]),Bs(4194308,4,Js.bind(null,t,e),n)},useLayoutEffect:function(e,t){return Bs(4194308,4,e,t)},useInsertionEffect:function(e,t){Bs(4,2,e,t)},useMemo:function(e,t){var n=ls();t=t===void 0?null:t;var r=e();if(Xo){it(!0);try{e()}finally{it(!1)}}return n.memoizedState=[r,t],r},useReducer:function(e,t,n){var r=ls();if(n!==void 0){var i=n(t);if(Xo){it(!0);try{n(t)}finally{it(!1)}}}else i=t;return r.memoizedState=r.baseState=i,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:i},r.queue=e,e=e.dispatch=uc.bind(null,I,e),[r.memoizedState,e]},useRef:function(e){var t=ls();return e={current:e},t.memoizedState=e},useState:function(e){e=ws(e);var t=e.queue,n=dc.bind(null,I,t);return t.dispatch=n,[e.memoizedState,n]},useDebugValue:Xs,useDeferredValue:function(e,t){return $s(ls(),e,t)},useTransition:function(){var e=ws(!1);return e=tc.bind(null,I,e.queue,!0,!1),ls().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,n){var r=I,a=ls();if(P){if(n===void 0)throw Error(i(407));n=n()}else{if(n=t(),G===null)throw Error(i(349));q&127||ys(r,t,n)}a.memoizedState=n;var o={value:n,getSnapshot:t};return a.queue=o,Hs(xs.bind(null,r,o,e),[e]),r.flags|=2048,Rs(9,{destroy:void 0},bs.bind(null,r,o,n,t),null),n},useId:function(){var e=ls(),t=G.identifierPrefix;if(P){var n=ia,r=ra;n=(r&~(1<<32-at(r)-1)).toString(32)+n,t=`_`+t+`R_`+n,n=Zo++,0<\/script>`,o=o.removeChild(o.firstChild);break;case`select`:o=typeof r.is==`string`?s.createElement(`select`,{is:r.is}):s.createElement(`select`),r.multiple?o.multiple=!0:r.size&&(o.size=r.size);break;default:o=typeof r.is==`string`?s.createElement(a,{is:r.is}):s.createElement(a)}}o[kt]=t,o[At]=r;a:for(s=t.child;s!==null;){if(s.tag===5||s.tag===6)o.appendChild(s.stateNode);else if(s.tag!==4&&s.tag!==27&&s.child!==null){s.child.return=s,s=s.child;continue}if(s===t)break a;for(;s.sibling===null;){if(s.return===null||s.return===t)break a;s=s.return}s.sibling.return=s.return,s=s.sibling}t.stateNode=o;a:switch(np(o,a,r),a){case`button`:case`input`:case`select`:case`textarea`:r=!!r.autoFocus;break a;case`img`:r=!0;break a;default:r=!1}r&&gl(t)}}return V(t),t.subtreeFlags&=-33554433,_l(t,t.type,e===null?null:e.memoizedProps,t.pendingProps,n),null;case 6:if(e&&t.stateNode!=null)e.memoizedProps!==r&&gl(t);else{if(typeof r!=`string`&&t.stateNode===null)throw Error(i(166));if(e=ke.current,_a(t)){if(e=t.stateNode,n=t.memoizedProps,r=null,a=ua,a!==null)switch(a.tag){case 27:case 5:r=a.memoizedProps}e[kt]=t,e=!!(e.nodeValue===n||r!==null&&!0===r.suppressHydrationWarning||ep(e.nodeValue,n)),e||ma(t,!0)}else e=lp(e).createTextNode(r),e[kt]=t,t.stateNode=e}return V(t),null;case 31:if(n=t.memoizedState,e===null||e.memoizedState!==null){if(r=_a(t),n!==null){if(e===null){if(!r)throw Error(i(318));if(e=t.memoizedState,e=e===null?null:e.dehydrated,!e)throw Error(i(557));e[kt]=t}else va(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;V(t),e=!1}else n=ya(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=n),e=!0;if(!e)return t.flags&256?(Ho(t),t):(Ho(t),null);if(t.flags&128)throw Error(i(558))}return V(t),null;case 13:if(r=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(a=_a(t),r!==null&&r.dehydrated!==null){if(e===null){if(!a)throw Error(i(318));if(a=t.memoizedState,a=a===null?null:a.dehydrated,!a)throw Error(i(317));a[kt]=t}else va(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;V(t),a=!1}else a=ya(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=a),a=!0;if(!a)return t.flags&256?(Ho(t),t):(Ho(t),null)}return Ho(t),t.flags&128?(t.lanes=n,t):(n=r!==null,e=e!==null&&e.memoizedState!==null,n&&(r=t.child,a=null,r.alternate!==null&&r.alternate.memoizedState!==null&&r.alternate.memoizedState.cachePool!==null&&(a=r.alternate.memoizedState.cachePool.pool),o=null,r.memoizedState!==null&&r.memoizedState.cachePool!==null&&(o=r.memoizedState.cachePool.pool),o!==a&&(r.flags|=2048)),n!==e&&n&&(t.child.flags|=8192),yl(t,t.updateQueue),V(t),null);case 4:return Me(),e===null&&Wf(t.stateNode.containerInfo),t.flags|=67108864,V(t),null;case 10:return Ta(t.type),V(t),null;case 19:if(Go(t),r=t.memoizedState,r===null)return V(t),null;if(a=!!(t.flags&128),o=r.rendering,o===null){if(a)bl(r,!1);else{if(Y!==0||e!==null&&e.flags&128)for(e=t.child;e!==null;){if(o=Ko(e),o!==null){for(t.flags|=128,bl(r,!1),e=o.updateQueue,t.updateQueue=e,yl(t,e),t.subtreeFlags=0,e=n,n=t.child;n!==null;)Hi(n,e),n=n.sibling;return Wo(t,Uo.current&1|2),P&&aa(t,r.treeForkCount),t.child}e=e.sibling}r.tail!==null&&qe()>_d&&(t.flags|=128,a=!0,bl(r,!1),t.lanes=4194304)}}else{if(!a){if(e=Ko(o),e!==null){if(t.flags|=128,a=!0,e=e.updateQueue,t.updateQueue=e,yl(t,e),bl(r,!0),r.tail===null&&r.tailMode!==`collapsed`&&r.tailMode!==`visible`&&!o.alternate&&!P)return V(t),null}else 2*qe()-r.renderingStartTime>_d&&n!==536870912&&(t.flags|=128,a=!0,bl(r,!1),t.lanes=4194304)}r.isBackwards?(o.sibling=t.child,t.child=o):(e=r.last,e===null?t.child=o:e.sibling=o,r.last=o)}if(r.tail!==null){e=r.tail;a:{for(n=e;n!==null;){if(n.alternate!==null){n=!1;break a}n=n.sibling}n=!0}return r.rendering=e,r.tail=e.sibling,r.renderingStartTime=qe(),e.sibling=null,o=Uo.current,o=a?o&1|2:o&1,r.tailMode===`visible`||r.tailMode===`collapsed`||!n||P?Wo(t,o):(n=o,j(Io,t),j(Uo,n),Lo===null&&(Lo=t)),P&&aa(t,r.treeForkCount),e}return V(t),null;case 22:case 23:return Ho(t),Fo(),r=t.memoizedState!==null,e===null?r&&(t.flags|=8192):e.memoizedState!==null!==r&&(t.flags|=8192),r?n&536870912&&!(t.flags&128)&&(V(t),t.subtreeFlags&6&&(t.flags|=8192)):V(t),n=t.updateQueue,n!==null&&yl(t,n.retryQueue),n=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(n=e.memoizedState.cachePool.pool),r=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(r=t.memoizedState.cachePool.pool),r!==n&&(t.flags|=2048),e!==null&&Ee(Xa),null;case 24:return n=null,e!==null&&(n=e.memoizedState.cache),t.memoizedState.cache!==n&&(t.flags|=2048),Ta(La),V(t),null;case 25:return null;case 30:return t.flags|=33554432,V(t),null}throw Error(i(156,t.tag))}function Sl(e,t){switch(ca(t),t.tag){case 1:return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return Ta(La),Me(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 26:case 27:case 5:return Pe(t),null;case 31:if(t.memoizedState!==null){if(Ho(t),t.alternate===null)throw Error(i(340));va()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 13:if(Ho(t),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(i(340));va()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return Go(t),e=t.flags,e&65536?(t.flags=e&-65537|128,e=t.memoizedState,e!==null&&(e.rendering=null,e.tail=null),t.flags|=4,t):null;case 4:return Me(),null;case 10:return Ta(t.type),null;case 22:case 23:return Ho(t),Fo(),e!==null&&Ee(Xa),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 24:return Ta(La),null;case 25:return null;default:return null}}function Cl(e,t){switch(ca(t),t.tag){case 3:Ta(La),Me();break;case 26:case 27:case 5:Pe(t);break;case 4:Me();break;case 31:t.memoizedState!==null&&Ho(t);break;case 13:Ho(t);break;case 19:Go(t);break;case 10:Ta(t.type);break;case 22:case 23:Ho(t),Fo(),e!==null&&Ee(Xa);break;case 24:Ta(La)}}function wl(e,t){try{var n=t.updateQueue,r=n===null?null:n.lastEffect;if(r!==null){var i=r.next;n=i;do{if((n.tag&e)===e){r=void 0;var a=n.create,o=n.inst;r=a(),o.destroy=r}n=n.next}while(n!==i)}}catch(e){Z(t,t.return,e)}}function Tl(e,t,n){try{var r=t.updateQueue,i=r===null?null:r.lastEffect;if(i!==null){var a=i.next;r=a;do{if((r.tag&e)===e){var o=r.inst,s=o.destroy;if(s!==void 0){o.destroy=void 0,i=t;var c=n,l=s;try{l()}catch(e){Z(i,c,e)}}}r=r.next}while(r!==a)}}catch(e){Z(t,t.return,e)}}function El(e){var t=e.updateQueue;if(t!==null){var n=e.stateNode;try{Ao(t,n)}catch(t){Z(e,e.return,t)}}}function Dl(e,t,n){n.props=Tc(e.type,e.memoizedProps),n.state=e.memoizedState;try{n.componentWillUnmount()}catch(n){Z(e,t,n)}}function Ol(e,t){try{var n=e.ref;if(n!==null){switch(e.tag){case 26:case 27:case 5:var r=e.stateNode;break;case 30:var i=e.stateNode,a=wi(e.memoizedProps,i);(i.ref===null||i.ref.name!==a)&&(i.ref=Pp(a)),r=i.ref;break;case 7:if(e.stateNode===null){var o=new Fp(e);h(e.child,!1,Qp,o,void 0,void 0),e.stateNode=o}r=e.stateNode;break;default:r=e.stateNode}typeof n==`function`?e.refCleanup=n(r):n.current=r}}catch(n){Z(e,t,n)}}function kl(e,t){var n=e.ref,r=e.refCleanup;if(n!==null){if(typeof r==`function`)try{r()}catch(n){Z(e,t,n)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof n==`function`)try{n(null)}catch(n){Z(e,t,n)}else n.current=null}}function Al(e,t){if((e.tag===5||e.tag===27||e.tag===6)&&e.alternate===null&&t!==null)for(var n=0;n title`))),np(r,t,n),r[kt]=e,Ut(r),t=r;break a;case`link`:if(o=Gm(`link`,`href`,a).get(t+(n.href||``))){for(s=0;sg&&(o=g,g=h,h=o);var _=Qr(s,h),v=Qr(s,g);if(_&&v&&(p.rangeCount!==1||p.anchorNode!==_.node||p.anchorOffset!==_.offset||p.focusNode!==v.node||p.focusOffset!==v.offset)){var y=d.createRange();y.setStart(_.node,_.offset),p.removeAllRanges(),h>g?(p.addRange(y),p.extend(v.node,v.offset)):(y.setEnd(v.node,v.offset),p.addRange(y))}}}}for(d=[],p=s;p=p.parentNode;)p.nodeType===1&&d.push({element:p,left:p.scrollLeft,top:p.scrollTop});for(typeof s.focus==`function`&&s.focus(),s=0;sn?32:n,O.T=null,n=wd,wd=null;var o=bd,s=Sd;if(X=0,xd=bd=null,Sd=0,W&6)throw Error(i(331));var c=W;if(W|=4,Zu(o.current),Uu(o,o.current,s,n),W=c,Df(0,!1),rt&&typeof rt.onPostCommitFiberRoot==`function`)try{rt.onPostCommitFiberRoot(nt,o)}catch{}return!0}finally{k.p=a,O.T=r,uf(e,t)}}function pf(e,t,n){t=Yi(n,t),t=jc(e.stateNode,t,2),e=Co(e,t,2),e!==null&&(yt(e,2),Ef(e))}function Z(e,t,n){if(e.tag===3)pf(e,e,n);else for(;t!==null;){if(t.tag===3){pf(t,e,n);break}if(t.tag===1){var r=t.stateNode;if(typeof t.type.getDerivedStateFromError==`function`||typeof r.componentDidCatch==`function`&&(yd===null||!yd.has(r))){e=Yi(n,e),n=Mc(2),r=Co(t,n,2),r!==null&&(Nc(n,r,t,e),yt(r,2),Ef(r));break}}t=t.return}}function mf(e,t,n){var r=e.pingCache;if(r===null){r=e.pingCache=new td;var i=new Set;r.set(t,i)}else i=r.get(t),i===void 0&&(i=new Set,r.set(t,i));i.has(n)||(ad=!0,i.add(n),e=hf.bind(null,e,t,n),t.then(e,e))}function hf(e,t,n){var r=e.pingCache;r!==null&&r.delete(t),e.pingedLanes|=e.suspendedLanes&n,e.warmLanes&=~n,G===e&&(q&n)===n&&(Y===4||Y===3&&(q&62914560)===q&&300>qe()-hd?W&2?ld|=n:Vd(e,0):ld|=n,dd===q&&(dd=0)),Ef(e)}function gf(e,t){t===0&&(t=_t()),e=Pi(e,t),e!==null&&(yt(e,t),Ef(e))}function _f(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),gf(e,n)}function vf(e,t){var n=0;switch(e.tag){case 31:case 13:var r=e.stateNode,a=e.memoizedState;a!==null&&(n=a.retryLane);break;case 19:r=e.stateNode;break;case 22:r=e.stateNode._retryCache;break;default:throw Error(i(314))}r!==null&&r.delete(t),gf(e,n)}function yf(e,t){return Ue(e,t)}var bf=null,xf=null,Sf=!1,Cf=!1,wf=!1,Tf=0;function Ef(e){e!==xf&&e.next===null&&(xf===null?bf=xf=e:xf=xf.next=e),Cf=!0,Sf||(Sf=!0,Nf())}function Df(e,t){if(!wf&&Cf){wf=!0;do for(var n=!1,r=bf;r!==null;){if(!t){if(e!==0){var i=r.pendingLanes;if(i===0)var a=0;else{var o=r.suspendedLanes,s=r.pingedLanes;a=(1<<31-at(42|e)+1)-1,a&=i&~(o&~s),a=a&201326741?a&201326741|1:a?a|2:0}a!==0&&(n=!0,Mf(r,a))}else a=q,a=pt(r,r===G?a:0,r.cancelPendingCommit!==null||r.timeoutHandle!==-1),!(a&3)||mt(r,a)||(n=!0,Mf(r,a))}r=r.next}while(n);wf=!1}}function Of(){kf()}function kf(){Cf=Sf=!1;var e=0;Tf!==0&&hp()&&(e=Tf);for(var t=qe(),n=null,r=bf;r!==null;){var i=r.next,a=Af(r,t);a===0?(r.next=null,n===null?bf=i:n.next=i,i===null&&(xf=n)):(n=r,(e!==0||a&3)&&(Cf=!0)),r=i}X!==0&&X!==5||Df(e,!1),Tf!==0&&(Tf=0)}function Af(e,t){for(var n=e.suspendedLanes,r=e.pingedLanes,i=e.expirationTimes,a=e.pendingLanes&-62914561;0s)break;var u=c.transferSize,d=c.initiatorType;u&&ap(d)&&(c=c.responseEnd,o+=u*(c$m){s.length=o;break}f=new Promise(jp.bind(f)),s.push(f)}}}if(0`u`?null:document;function Tm(e,t,n){var r=wm;if(r&&typeof t==`string`&&t){var i=un(t);i=`link[rel="`+e+`"][href="`+i+`"]`,typeof n==`string`&&(i+=`[crossorigin="`+n+`"]`),ym.has(i)||(ym.add(i),e={rel:e,crossOrigin:n,href:t},r.querySelector(i)===null&&(t=r.createElement(`link`),np(t,`link`,e),Ut(t),r.head.appendChild(t)))}}function Em(e){xm.D(e),Tm(`dns-prefetch`,e,null)}function Dm(e,t){xm.C(e,t),Tm(`preconnect`,e,t)}function Om(e,t,n){xm.L(e,t,n);var r=wm;if(r&&e&&t){var i=`link[rel="preload"][as="`+un(t)+`"]`;t===`image`&&n&&n.imageSrcSet?(i+=`[imagesrcset="`+un(n.imageSrcSet)+`"]`,typeof n.imageSizes==`string`&&(i+=`[imagesizes="`+un(n.imageSizes)+`"]`)):i+=`[href="`+un(e)+`"]`;var a=i;switch(t){case`style`:a=Pm(e);break;case`script`:a=Rm(e)}if(!(vm.has(a)||(e=E({rel:`preload`,href:t===`image`&&n&&n.imageSrcSet?void 0:e,as:t},n),vm.set(a,e),r.querySelector(i)!==null||t===`style`&&r.querySelector(Fm(a))||t===`script`&&r.querySelector(zm(a))))){var o=r.createElement(`link`);np(o,`link`,e),t===`style`&&(o[Lt]=!0,o.onload=o.onerror=function(){Wt(o)}),Ut(o),r.head.appendChild(o)}}}function km(e,t){xm.m(e,t);var n=wm;if(n&&e){var r=t&&typeof t.as==`string`?t.as:`script`,i=`link[rel="modulepreload"][as="`+un(r)+`"][href="`+un(e)+`"]`,a=i;switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:a=Rm(e)}if(!vm.has(a)&&(e=E({rel:`modulepreload`,href:e},t),vm.set(a,e),n.querySelector(i)===null)){switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:if(n.querySelector(zm(a)))return}r=n.createElement(`link`),np(r,`link`,e),Ut(r),n.head.appendChild(r)}}}function Am(e,t,n){xm.S(e,t,n);var r=wm;if(r&&e){var i=Ht(r).hoistableStyles,a=Pm(e);t||=`default`;var o=i.get(a);if(!o){var s={loading:0,preload:null};if(o=r.querySelector(Fm(a)))s.loading=5;else{e=E({rel:`stylesheet`,href:e,"data-precedence":t},n),(n=vm.get(a))&&Hm(e,n);var c=o=r.createElement(`link`);Ut(c),np(c,`link`,e),c._p=new Promise(function(e,t){c.onload=e,c.onerror=t}),c.addEventListener(`load`,function(){s.loading|=1}),c.addEventListener(`error`,function(){s.loading|=2}),s.loading|=4,Vm(o,t,r)}o={type:`stylesheet`,instance:o,count:1,state:s},i.set(a,o)}}}function jm(e,t){xm.X(e,t);var n=wm;if(n&&e){var r=Ht(n).hoistableScripts,i=Rm(e),a=r.get(i);a||(a=n.querySelector(zm(i)),a||(e=E({src:e,async:!0},t),(t=vm.get(i))&&Um(e,t),a=n.createElement(`script`),Ut(a),np(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function Mm(e,t){xm.M(e,t);var n=wm;if(n&&e){var r=Ht(n).hoistableScripts,i=Rm(e),a=r.get(i);a||(a=n.querySelector(zm(i)),a||(e=E({src:e,async:!0,type:`module`},t),(t=vm.get(i))&&Um(e,t),a=n.createElement(`script`),Ut(a),np(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function Nm(e,t,n,r){var a=(a=ke.current)?bm(a):null;if(!a)throw Error(i(446));switch(e){case`meta`:case`title`:return null;case`style`:return typeof n.precedence==`string`&&typeof n.href==`string`?(n=Pm(n.href),t=Ht(a).hoistableStyles,r=t.get(n),r||(r={type:`style`,instance:null,count:0,state:null},t.set(n,r)),r):{type:`void`,instance:null,count:0,state:null};case`link`:if(n.rel===`stylesheet`&&typeof n.href==`string`&&typeof n.precedence==`string`){e=Pm(n.href);var o=Ht(a).hoistableStyles,s=o.get(e);if(s||(a=a.ownerDocument||a,s={type:`stylesheet`,instance:null,count:0,state:{loading:0,preload:null}},o.set(e,s),(o=a.querySelector(Fm(e)))?o._p||(s.instance=o,s.state.loading=5):(o=vm.get(e),o||(o={rel:`preload`,as:`style`,href:n.href,crossOrigin:n.crossOrigin,integrity:n.integrity,media:n.media,hrefLang:n.hrefLang,referrerPolicy:n.referrerPolicy},vm.set(e,o)),Lm(a,e,o,s.state))),t&&r===null)throw Error(i(528,``));return s}if(t&&r!==null)throw Error(i(529,``));return null;case`script`:return t=n.async,n=n.src,typeof n==`string`&&t&&typeof t!=`function`&&typeof t!=`symbol`?(n=Rm(n),t=Ht(a).hoistableScripts,r=t.get(n),r||(r={type:`script`,instance:null,count:0,state:null},t.set(n,r)),r):{type:`void`,instance:null,count:0,state:null};default:throw Error(i(444,e))}}function Pm(e){return`href="`+un(e)+`"`}function Fm(e){return`link[rel="stylesheet"][`+e+`]`}function Im(e){return E({},e,{"data-precedence":e.precedence,precedence:null})}function Lm(e,t,n,r){if(t=e.querySelector(`link[rel="preload"][as="style"][`+t+`]`)){if(!0!==t[Lt]){r.loading=1;return}}else t=e.createElement(`link`),t[Lt]=!0,t.onload=t.onerror=Wt.bind(null,t),np(t,`link`,n),Ut(t),e.head.appendChild(t);r.preload=t,t.addEventListener(`load`,function(){return r.loading|=1}),t.addEventListener(`error`,function(){return r.loading|=2})}function Rm(e){return`[src="`+un(e)+`"]`}function zm(e){return`script[async]`+e}function Bm(e,t,n){if(t.count++,t.instance===null)switch(t.type){case`style`:var r=e.querySelector(`style[data-href~="`+un(n.href)+`"]`);if(r)return t.instance=r,Ut(r),r;var a=E({},n,{"data-href":n.href,"data-precedence":n.precedence,href:null,precedence:null});return r=(e.ownerDocument||e).createElement(`style`),Ut(r),np(r,`style`,a),Vm(r,n.precedence,e),t.instance=r;case`stylesheet`:a=Pm(n.href);var o=e.querySelector(Fm(a));if(o)return t.state.loading|=4,t.instance=o,Ut(o),o;r=Im(n),(a=vm.get(a))&&Hm(r,a),o=(e.ownerDocument||e).createElement(`link`),Ut(o);var s=o;return s._p=new Promise(function(e,t){s.onload=e,s.onerror=t}),np(o,`link`,r),t.state.loading|=4,Vm(o,n.precedence,e),t.instance=o;case`script`:return o=Rm(n.src),(a=e.querySelector(zm(o)))?(t.instance=a,Ut(a),a):(r=n,(a=vm.get(o))&&(r=E({},n),Um(r,a)),e=e.ownerDocument||e,a=e.createElement(`script`),Ut(a),np(a,`link`,r),e.head.appendChild(a),t.instance=a);case`void`:return null;default:throw Error(i(443,t.type))}else t.type===`stylesheet`&&!(t.state.loading&4)&&(r=t.instance,t.state.loading|=4,Vm(r,n.precedence,e));return t.instance}function Vm(e,t,n){for(var r=n.querySelectorAll(`link[rel="stylesheet"][data-precedence],style[data-precedence]`),i=r.length?r[r.length-1]:null,a=i,o=0;o title`):null)}function qm(e,t,n){if(n===1||t.itemProp!=null)return!1;switch(e){case`meta`:case`title`:return!0;case`style`:if(typeof t.precedence!=`string`||typeof t.href!=`string`||t.href===``)break;return!0;case`link`:if(typeof t.rel!=`string`||typeof t.href!=`string`||t.href===``||t.onLoad||t.onError)break;switch(t.rel){case`stylesheet`:return e=t.disabled,typeof t.precedence==`string`&&e==null;default:return!0}case`script`:if(t.async&&typeof t.async!=`function`&&typeof t.async!=`symbol`&&!t.onLoad&&!t.onError&&t.src&&typeof t.src==`string`)return!0}return!1}function Jm(e,t){return e===`img`&&t.src!=null&&t.src!==``&&t.onLoad==null&&t.loading!==`lazy`}function Ym(e){return!(e.type===`stylesheet`&&!(e.state.loading&3))}function Xm(e){return(e.width||100)*(e.height||100)*(typeof devicePixelRatio==`number`?devicePixelRatio:1)*.25}function Zm(e,t){typeof t.decode==`function`&&(e.imgCount++,t.complete||(e.imgBytes+=Xm(t),e.suspenseyImages.push(t)),e=rh.bind(e),t.decode().then(e,e))}function Qm(e,t,n,r){if(n.type===`stylesheet`&&(typeof r.media!=`string`||!1!==matchMedia(r.media).matches)&&!(n.state.loading&4)){if(n.instance===null){var i=Pm(r.href),a=t.querySelector(Fm(i));if(a){t=a._p,typeof t==`object`&&t&&typeof t.then==`function`&&(e.count++,e=nh.bind(e),t.then(e,e)),n.state.loading|=4,n.instance=a,Ut(a);return}a=t.ownerDocument||t,r=Im(r),(i=vm.get(i))&&Hm(r,i),a=a.createElement(`link`),Ut(a);var o=a;o._p=new Promise(function(e,t){o.onload=e,o.onerror=t}),np(a,`link`,r),n.instance=a}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(n,t),(t=n.state.preload)&&!(n.state.loading&3)&&(e.count++,n=nh.bind(e),t.addEventListener(`load`,n),t.addEventListener(`error`,n))}}var $m=0;function eh(e,t){return e.stylesheets&&e.count===0&&ah(e,e.stylesheets),0$m?50:800)+t);return e.unsuspend=n,function(){e.unsuspend=null,clearTimeout(r),clearTimeout(i)}}:null}function th(e){if(e.count===0&&(e.imgCount===0||!e.waitingForImages)){if(e.stylesheets)ah(e,e.stylesheets);else if(e.unsuspend){var t=e.unsuspend;e.unsuspend=null,t()}}}function nh(){this.count--,th(this)}function rh(){this.imgCount--,th(this)}var ih=null;function ah(e,t){e.stylesheets=null,e.unsuspend!==null&&(e.count++,ih=new Map,t.forEach(oh,e),ih=null,nh.call(e))}function oh(e,t){if(!(t.state.loading&4)){var n=ih.get(e);if(n)var r=n.get(null);else{n=new Map,ih.set(e,n);for(var i=e.querySelectorAll(`link[data-precedence],style[data-precedence]`),a=0;a{function n(){if(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<`u`&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE==`function`)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=f()})),m=r(l(),1),h=t(),g=m.createContext(void 0),_=e=>{let t=m.useContext(g);if(e)return e;if(!t)throw Error(`No QueryClient set, use QueryClientProvider to set one`);return t},v=({client:e,children:t})=>(m.useEffect(()=>(e.mount(),()=>{e.unmount()}),[e]),(0,h.jsx)(g.Provider,{value:e,children:t})),y={setTimeout:(e,t)=>setTimeout(e,t),clearTimeout:e=>clearTimeout(e),setInterval:(e,t)=>setInterval(e,t),clearInterval:e=>clearInterval(e)},b=new class{#e=y;setTimeoutProvider(e){this.#e=e}setTimeout(e,t){return this.#e.setTimeout(e,t)}clearTimeout(e){this.#e.clearTimeout(e)}setInterval(e,t){return this.#e.setInterval(e,t)}clearInterval(e){this.#e.clearInterval(e)}};function x(e){setTimeout(e,0)}var S=typeof window>`u`||`Deno`in globalThis;function C(){}function w(e,t){return typeof e==`function`?e(t):e}function T(e){return typeof e==`number`&&e>=0&&e!==1/0}function ee(e,t){return Math.max(e+(t||0)-Date.now(),0)}function E(e,t){return typeof e==`function`?e(t):e}function te(e,t){let{type:n=`all`,exact:r,fetchStatus:i,predicate:a,queryKey:o,stale:s}=e;if(o){if(r){if(t.queryHash!==ne(o,t.options))return!1}else if(!ie(t.queryKey,o))return!1}if(n!==`all`){let e=t.isActive();if(n===`active`&&!e||n===`inactive`&&e)return!1}return!(typeof s==`boolean`&&t.isStale()!==s||i&&i!==t.state.fetchStatus||a&&!a(t))}function D(e,t){let{exact:n,status:r,predicate:i,mutationKey:a}=e;if(a){if(!t.options.mutationKey)return!1;if(n){if(re(t.options.mutationKey)!==re(a))return!1}else if(!ie(t.options.mutationKey,a))return!1}return!(r&&t.state.status!==r||i&&!i(t))}function ne(e,t){return(t?.queryKeyHashFn||re)(e)}function re(e){return JSON.stringify(e,(e,t)=>le(t)?Object.keys(t).sort().reduce((e,n)=>(e[n]=t[n],e),{}):t)}function ie(e,t){if(e===t)return!0;if(typeof e!=typeof t)return!1;if(e&&t&&typeof e==`object`&&typeof t==`object`){if(Array.isArray(e)&&Array.isArray(t)){if(t.length>e.length)return!1;for(let n=0;n500)return t;let r=ce(e)&&ce(t);if(!r&&!(le(e)&&le(t)))return t;let i=(r?e:Object.keys(e)).length,a=r?t:Object.keys(t),o=a.length,s=r?Array(o):{},c=0;for(let l=0;l{b.setTimeout(t,e)})}function fe(e,t,n){return typeof n.structuralSharing==`function`?n.structuralSharing(e,t):n.structuralSharing===!1?t:oe(e,t)}function pe(e,t,n=0){let r=[...e,t];return n&&r.length>n?r.slice(1):r}function me(e,t,n=0){let r=[t,...e];return n&&r.length>n?r.slice(0,-1):r}var he=Symbol();function ge(e,t){return!e.queryFn&&t?.initialPromise?()=>t.initialPromise:!e.queryFn||e.queryFn===he?()=>Promise.reject(Error(`Missing queryFn: '${e.queryHash}'`)):e.queryFn}function _e(e,t){return typeof e==`function`?e(...t):!!e}function ve(e,t,n){let r=!1,i;return Object.defineProperty(e,"signal",{enumerable:!0,get:()=>(i??=t(),r?i:(r=!0,i.aborted?n():i.addEventListener(`abort`,n,{once:!0}),i))}),e}var ye=()=>S,be=()=>ye(),xe=class{constructor(){this.listeners=new Set,this.subscribe=this.subscribe.bind(this)}subscribe(e){return this.listeners.add(e),this.onSubscribe(),()=>{this.listeners.delete(e),this.onUnsubscribe()}}hasListeners(){return this.listeners.size>0}onSubscribe(){}onUnsubscribe(){}},Se=new class extends xe{#e;#t;#n;constructor(){super(),this.#n=e=>{if(typeof window<`u`&&window.addEventListener){let t=()=>e();return window.addEventListener(`visibilitychange`,t,!1),()=>{window.removeEventListener(`visibilitychange`,t)}}}}onSubscribe(){this.#t||this.setEventListener(this.#n)}onUnsubscribe(){this.hasListeners()||(this.#t?.(),this.#t=void 0)}setEventListener(e){this.#n=e,this.#t?.(),this.#t=e(e=>{typeof e==`boolean`?this.setFocused(e):this.onFocus()})}setFocused(e){this.#e!==e&&(this.#e=e,this.onFocus())}onFocus(){let e=this.isFocused();this.listeners.forEach(t=>{t(e)})}isFocused(){return typeof this.#e==`boolean`?this.#e:globalThis.document?.visibilityState!==`hidden`}},O=x;function k(){let e=[],t=0,n=e=>{e()},r=e=>{e()},i=O,a=r=>{t?e.push(r):i(()=>{n(r)})},o=()=>{let t=e;e=[],t.length&&i(()=>{r(()=>{t.forEach(e=>{n(e)})})})};return{batch:e=>{let n;t++;try{n=e()}finally{t--,t||o()}return n},batchCalls:e=>(...t)=>{a(()=>{e(...t)})},schedule:a,setNotifyFunction:e=>{n=e},setBatchNotifyFunction:e=>{r=e},setScheduler:e=>{i=e}}}var A=k(),Ce=new class extends xe{#e=!0;#t;#n;constructor(){super(),this.#n=e=>{if(typeof window<`u`&&window.addEventListener){let t=()=>e(!0),n=()=>e(!1);return window.addEventListener(`online`,t,!1),window.addEventListener(`offline`,n,!1),()=>{window.removeEventListener(`online`,t),window.removeEventListener(`offline`,n)}}}}onSubscribe(){this.#t||this.setEventListener(this.#n)}onUnsubscribe(){this.hasListeners()||(this.#t?.(),this.#t=void 0)}setEventListener(e){this.#n=e,this.#t?.(),this.#t=e(this.setOnline.bind(this))}setOnline(e){this.#e!==e&&(this.#e=e,this.listeners.forEach(t=>{t(e)}))}isOnline(){return this.#e}};function we(e){return Math.min(1e3*2**e,3e4)}function Te(e){return(e??`online`)!==`online`||Ce.isOnline()}var Ee=class extends Error{constructor(e){super(`CancelledError`),this.revert=e?.revert,this.silent=e?.silent}};function j(e){let t=!1,n=0,r,i=`pending`,a,o,s=new Promise((e,t)=>{a=e,o=t});s.catch(C);let c=()=>i!==`pending`,l=t=>{if(!c()){let n=new Ee(t);h(n),e.onCancel?.(n)}},u=()=>{t=!0},d=()=>{t=!1},f=()=>Se.isFocused()&&(e.networkMode===`always`||Ce.isOnline())&&e.canRun(),p=()=>Te(e.networkMode)&&e.canRun(),m=e=>{c()||(r?.(),i=`resolved`,a(e))},h=e=>{c()||(r?.(),i=`rejected`,o(e))},g=()=>new Promise(t=>{r=e=>{(c()||f())&&t(e)},e.onPause?.()}).then(()=>{r=void 0,c()||e.onContinue?.()}),_=()=>{if(c())return;let r,i=n===0?e.initialPromise:void 0;try{r=i??e.fn()}catch(e){r=Promise.reject(e)}Promise.resolve(r).then(m).catch(r=>{if(c())return;let i=e.retry??(be()?0:3),a=e.retryDelay??we,o=typeof a==`function`?a(n,r):a,s=i===!0||typeof i==`number`&&nf()?void 0:g()).then(()=>{t?h(r):_()})})};return{promise:s,status:()=>i,cancel:l,continue:()=>(r?.(),s),cancelRetry:u,continueRetry:d,canStart:p,start:()=>(p()?_():g().then(_),s)}}var De=class{#e;destroy(){this.clearGcTimeout()}scheduleGc(){this.clearGcTimeout(),T(this.gcTime)&&(this.#e=b.setTimeout(()=>{this.optionalRemove()},this.gcTime))}updateGcTime(e){this.gcTime=Math.max(this.gcTime||0,e??(be()?1/0:3e5))}clearGcTimeout(){this.#e!==void 0&&(b.clearTimeout(this.#e),this.#e=void 0)}};function Oe(e){return{onFetch:(t,n)=>{let r=t.options,i=t.fetchOptions?.meta?.fetchMore?.direction,a=t.state.data?.pages||[],o=t.state.data?.pageParams||[],s={pages:[],pageParams:[]},c=0,l=async()=>{let n=!1,l=e=>{ve(e,()=>t.signal,()=>n=!0)},u=ge(t.options,t.fetchOptions),d=async(e,r,i)=>{if(n)return Promise.reject(t.signal.reason);if(r==null&&e.pages.length)return Promise.resolve(e);let a=(()=>{let e={client:t.client,queryKey:t.queryKey,pageParam:r,direction:i?`backward`:`forward`,meta:t.options.meta};return l(e),e})(),o=await u(a),{maxPages:s}=t.options,c=i?me:pe;return{pages:c(e.pages,o,s),pageParams:c(e.pageParams,r,s)}};if(i&&a.length){let e=i===`backward`,t=e?Ae:ke,n={pages:a,pageParams:o};s=await d(n,t(r,n),e)}else{let t=e??a.length;do{let e=c===0?o[0]??r.initialPageParam:ke(r,s);if(c>0&&e==null)break;s=await d(s,e),c++}while(ct.options.persister?.(l,{client:t.client,queryKey:t.queryKey,meta:t.options.meta,signal:t.signal},n):l}}}function ke(e,{pages:t,pageParams:n}){let r=t.length-1;return t.length>0?e.getNextPageParam(t[r],t,n[r],n):void 0}function Ae(e,{pages:t,pageParams:n}){return t.length>0?e.getPreviousPageParam?.(t[0],t,n[0],n):void 0}var je=class extends De{#e;#t;#n;#r;#i;#a;#o;#s;constructor(e){super(),this.#s=!1,this.#o=e.defaultOptions,this.setOptions(e.options),this.observers=[],this.#i=e.client,this.#r=this.#i.getQueryCache(),this.queryKey=e.queryKey,this.queryHash=e.queryHash,this.#t=Pe(this.options),this.state=e.state??this.#t,this.scheduleGc()}get meta(){return this.options.meta}get queryType(){return this.#e}get promise(){return this.#a?.promise}setOptions(e){if(this.options={...this.#o,...e},e?._type&&(this.#e=e._type),this.updateGcTime(this.options.gcTime),this.state&&this.state.data===void 0){let e=Pe(this.options);e.data!==void 0&&(this.setState(Ne(e.data,e.dataUpdatedAt)),this.#t=e)}}optionalRemove(){!this.observers.length&&this.state.fetchStatus===`idle`&&this.#r.remove(this)}setData(e,t){let n=fe(this.state.data,e,this.options);return this.#c({data:n,type:`success`,dataUpdatedAt:t?.updatedAt,manual:t?.manual}),n}setState(e){this.#c({type:`setState`,state:e})}cancel(e){let t=this.#a?.promise;return this.#a?.cancel(e),t?t.then(C).catch(C):Promise.resolve()}destroy(){super.destroy(),this.cancel({silent:!0})}get resetState(){return this.#t}reset(){this.destroy(),this.setState(this.resetState)}isActive(){return this.observers.some(e=>E(e.options.enabled,this)!==!1)}isDisabled(){return this.getObserversCount()>0?!this.isActive():this.options.queryFn===he||!this.isFetched()}isFetched(){return this.state.dataUpdateCount+this.state.errorUpdateCount>0}isStatic(){return this.getObserversCount()>0&&this.observers.some(e=>E(e.options.staleTime,this)===`static`)}isStale(){return this.getObserversCount()>0?this.observers.some(e=>e.getCurrentResult().isStale):this.state.data===void 0||this.state.isInvalidated}isStaleByTime(e=0){return this.state.data===void 0?!0:e===`static`?!1:this.state.isInvalidated?!0:!ee(this.state.dataUpdatedAt,e)}onFocus(){this.observers.find(e=>e.shouldFetchOnWindowFocus())?.refetch({cancelRefetch:!1}),this.#a?.continue()}onOnline(){this.observers.find(e=>e.shouldFetchOnReconnect())?.refetch({cancelRefetch:!1}),this.#a?.continue()}addObserver(e){this.observers.includes(e)||(this.observers.push(e),this.clearGcTimeout(),this.#r.notify({type:`observerAdded`,query:this,observer:e}))}removeObserver(e){let t=this.observers.indexOf(e);t!==-1&&(this.observers.splice(t,1),this.observers.length||(this.#a&&(this.#s||this.state.fetchStatus===`paused`&&this.state.status===`pending`?this.#a.cancel({revert:!0}):this.#a.cancelRetry()),this.scheduleGc()),this.#r.notify({type:`observerRemoved`,query:this,observer:e}))}getObserversCount(){return this.observers.length}invalidate(){this.state.isInvalidated||this.#c({type:`invalidate`})}async fetch(e,t){if(this.state.fetchStatus!==`idle`&&this.#a?.status()!==`rejected`){if(this.state.data!==void 0&&t?.cancelRefetch)this.cancel({silent:!0});else if(this.#a)return this.#a.continueRetry(),this.#a.promise}if(e&&this.setOptions(e),!this.options.queryFn){let e=this.observers.find(e=>e.options.queryFn);e&&this.setOptions(e.options)}let n=new AbortController,r=e=>{Object.defineProperty(e,"signal",{enumerable:!0,get:()=>(this.#s=!0,n.signal)})},i=()=>{let e=ge(this.options,t),n=(()=>{let e={client:this.#i,queryKey:this.queryKey,meta:this.meta};return r(e),e})();return this.#s=!1,this.options.persister?this.options.persister(e,n,this):e(n)},a=(()=>{let e={fetchOptions:t,options:this.options,queryKey:this.queryKey,client:this.#i,state:this.state,fetchFn:i};return r(e),e})();(this.#e===`infinite`?Oe(this.options.pages):this.options.behavior)?.onFetch(a,this),this.#n=this.state,(this.state.fetchStatus===`idle`||this.state.fetchMeta!==a.fetchOptions?.meta)&&this.#c({type:`fetch`,meta:a.fetchOptions?.meta});let o=this.#a=j({initialPromise:t?.initialPromise,fn:a.fetchFn,onCancel:e=>{e instanceof Ee&&e.revert&&this.setState({...this.#n,fetchStatus:`idle`}),n.abort()},onFail:(e,t)=>{this.#c({type:`failed`,failureCount:e,error:t})},onPause:()=>{this.#c({type:`pause`})},onContinue:()=>{this.#c({type:`continue`})},retry:a.options.retry,retryDelay:a.options.retryDelay,networkMode:a.options.networkMode,canRun:()=>!0});try{let e=await o.start();if(e===void 0)throw Error(`${this.queryHash} data is undefined`);return this.setData(e),this.#r.config.onSuccess?.(e,this),this.#r.config.onSettled?.(e,this.state.error,this),e}catch(e){if(e instanceof Ee){if(e.silent)return this.#a.promise;if(e.revert){if(this.state.data===void 0)throw e;return this.state.data}}throw this.#c({type:`error`,error:e}),this.#r.config.onError?.(e,this),this.#r.config.onSettled?.(this.state.data,e,this),e}finally{this.#a===o&&(this.#a=void 0),this.scheduleGc()}}#c(e){let t=t=>{switch(e.type){case`failed`:return{...t,fetchFailureCount:e.failureCount,fetchFailureReason:e.error};case`pause`:return{...t,fetchStatus:`paused`};case`continue`:return{...t,fetchStatus:`fetching`};case`fetch`:return{...t,...Me(t.data,this.options),fetchMeta:e.meta??null};case`success`:let n={...t,...Ne(e.data,e.dataUpdatedAt),dataUpdateCount:t.dataUpdateCount+1,...!e.manual&&{fetchStatus:`idle`,fetchFailureCount:0,fetchFailureReason:null}};return this.#n=e.manual?n:void 0,n;case`error`:let r=e.error;return{...t,error:r,errorUpdateCount:t.errorUpdateCount+1,errorUpdatedAt:Date.now(),fetchFailureCount:t.fetchFailureCount+1,fetchFailureReason:r,fetchStatus:`idle`,status:`error`,isInvalidated:!0};case`invalidate`:return{...t,isInvalidated:!0};case`setState`:return{...t,...e.state}}};this.state=t(this.state),A.batch(()=>{this.observers.slice().forEach(e=>{e.onQueryUpdate()}),this.#r.notify({query:this,type:`updated`,action:e})})}};function Me(e,t){return{fetchFailureCount:0,fetchFailureReason:null,fetchStatus:Te(t.networkMode)?`fetching`:`paused`,...e===void 0&&{error:null,status:`pending`}}}function Ne(e,t){return{data:e,dataUpdatedAt:t??Date.now(),error:null,isInvalidated:!1,status:`success`}}function Pe(e){let t=typeof e.initialData==`function`?e.initialData():e.initialData,n=t!==void 0,r=n?typeof e.initialDataUpdatedAt==`function`?e.initialDataUpdatedAt():e.initialDataUpdatedAt:0;return{data:t,dataUpdateCount:0,dataUpdatedAt:n?r??Date.now():0,error:null,errorUpdateCount:0,errorUpdatedAt:0,fetchFailureCount:0,fetchFailureReason:null,fetchMeta:null,isInvalidated:!1,status:n?`success`:`pending`,fetchStatus:`idle`}}var Fe=class extends xe{#e;#t=void 0;#n=void 0;#r=void 0;#i;#a;#o;#s;#c;#l;#u;#d;#f;#p=new Set;constructor(e,t){super(),this.options=t,this.#e=e,this.#o=null,this.bindMethods(),this.setOptions(t)}bindMethods(){this.refetch=this.refetch.bind(this)}onSubscribe(){this.listeners.size===1&&(this.#t.addObserver(this),Le(this.#t,this.options)?this.#m():this.updateResult(),this.#y())}onUnsubscribe(){this.hasListeners()||this.destroy()}shouldFetchOnReconnect(){return Re(this.#t,this.options,this.options.refetchOnReconnect)}shouldFetchOnWindowFocus(){return Re(this.#t,this.options,this.options.refetchOnWindowFocus)}destroy(){this.listeners=new Set,this.#b(),this.#x(),this.#t.removeObserver(this)}setOptions(e){let t=this.options,n=this.#t;if(this.options=this.#e.defaultQueryOptions(e),this.options.enabled!==void 0&&typeof this.options.enabled!=`boolean`&&typeof this.options.enabled!=`function`&&typeof E(this.options.enabled,this.#t)!=`boolean`)throw Error(`Expected enabled to be a boolean or a callback that returns a boolean`);this.#S(),this.#t.setOptions(this.options),t._defaulted&&!se(this.options,t)&&this.#e.getQueryCache().notify({type:`observerOptionsUpdated`,query:this.#t,observer:this});let r=this.hasListeners();r&&ze(this.#t,n,this.options,t)&&this.#m(),this.updateResult(),r&&(this.#t!==n||E(this.options.enabled,this.#t)!==E(t.enabled,this.#t)||E(this.options.staleTime,this.#t)!==E(t.staleTime,this.#t))&&this.#g();let i=this.#_();r&&(this.#t!==n||E(this.options.enabled,this.#t)!==E(t.enabled,this.#t)||i!==this.#f)&&this.#v(i)}getOptimisticResult(e){let t=this.#e.getQueryCache().build(this.#e,e),n=this.createResult(t,e);return se(this.getCurrentResult(),n)||(this.#r=n,this.#a=this.options,this.#i=this.#t.state),n}getCurrentResult(){return this.#r}trackResult(e,t){return new Proxy(e,{get:(e,n)=>(this.trackProp(n),t?.(n),Reflect.get(e,n))})}trackProp(e){this.#p.add(e)}getCurrentQuery(){return this.#t}refetch({...e}={}){return this.fetch({...e})}fetchOptimistic(e){let t=this.#e.defaultQueryOptions(e),n=this.#e.getQueryCache().build(this.#e,t),r=()=>{},i,a=new Promise(e=>{i=e,r=this.#e.getQueryCache().subscribe(i=>{i.type===`updated`&&i.query.queryHash===n.queryHash&&n.state.data!==void 0&&(r(),e(this.createResult(n,t)))})});return Promise.race([n.fetch().then(()=>{let e=this.createResult(n,t);return i?.(e),e}).finally(()=>{r()}),a])}fetch(e){return this.#m({...e,cancelRefetch:e.cancelRefetch??!0}).then(()=>(this.updateResult(),this.#r))}#m(e){this.#S();let t=this.#t.fetch(this.options,e);return e?.throwOnError||(t=t.catch(C)),t}#h(e){return!be()&&E(this.options.enabled,this.#t)!==!1&&T(e)}#g(){this.#b();let e=E(this.options.staleTime,this.#t);if(this.#r.isStale||!this.#h(e))return;let t=ee(this.#r.dataUpdatedAt,e)+1;this.#u=b.setTimeout(()=>{this.#r.isStale||this.updateResult()},t)}#_(){return E(this.options.refetchInterval,this.#t)??!1}#v(e){this.#x(),this.#f=e,this.#f!==0&&this.#h(this.#f)&&(this.#d=b.setInterval(()=>{(this.options.refetchIntervalInBackground||Se.isFocused())&&this.#m()},this.#f))}#y(){this.#g(),this.#v(this.#_())}#b(){this.#u!==void 0&&(b.clearTimeout(this.#u),this.#u=void 0)}#x(){this.#d!==void 0&&(b.clearInterval(this.#d),this.#d=void 0)}createResult(e,t){let n=this.#t,r=this.options,i=this.#r,a=this.#i,o=this.#a,s=e===n?this.#n:e.state,{state:c}=e,l={...c},u=!1,d;if(t._optimisticResults){let i=this.hasListeners(),a=!i&&Le(e,t),o=i&&ze(e,n,t,r);(a||o)&&(l={...l,...Me(c.data,e.options)}),t._optimisticResults===`isRestoring`&&(l.fetchStatus=`idle`)}let{error:f,errorUpdatedAt:p,status:m}=l;d=l.data;let h=!1;if(t.placeholderData!==void 0&&d===void 0&&m===`pending`){let e;i?.isPlaceholderData&&t.placeholderData===o?.placeholderData?(e=i.data,h=!0):e=typeof t.placeholderData==`function`?t.placeholderData(this.#l?.state.data,this.#l):t.placeholderData,e!==void 0&&(m=`success`,d=fe(i?.data,e,t),u=!0)}if(t.select&&d!==void 0&&!h){if(i&&d===a?.data&&t.select===this.#s)d=this.#c;else try{this.#s=t.select,d=t.select(d),d=fe(i?.data,d,t),this.#c=d,this.#o=null}catch(e){this.#o=e}}else d===void 0&&(this.#o=null);this.#o&&(f=this.#o,d=this.#c,p=Date.now(),m=`error`,u=!1);let g=l.fetchStatus===`fetching`,_=m===`pending`,v=m===`error`,y=_&&g,b=d!==void 0;return{status:m,fetchStatus:l.fetchStatus,isPending:_,isSuccess:m===`success`,isError:v,isInitialLoading:y,isLoading:y,data:d,dataUpdatedAt:l.dataUpdatedAt,error:f,errorUpdatedAt:p,failureCount:l.fetchFailureCount,failureReason:l.fetchFailureReason,errorUpdateCount:l.errorUpdateCount,isFetched:e.isFetched(),isFetchedAfterMount:l.dataUpdateCount>s.dataUpdateCount||l.errorUpdateCount>s.errorUpdateCount,isFetching:g,isRefetching:g&&!_,isLoadingError:v&&!b,isPaused:l.fetchStatus===`paused`,isPlaceholderData:u,isRefetchError:v&&b,isStale:Be(e,t),refetch:this.refetch,isEnabled:E(t.enabled,e)!==!1}}updateResult(){let e=this.#r,t=this.createResult(this.#t,this.options);if(this.#i=this.#t.state,this.#a=this.options,this.#i.data!==void 0&&(this.#l=this.#t),se(t,e))return;this.#r=t;let n=(()=>{if(!e)return!0;let{notifyOnChangeProps:t}=this.options,n=typeof t==`function`?t():t;if(n===`all`||!n&&!this.#p.size)return!0;let r=new Set(n??this.#p);return this.options.throwOnError&&r.add(`error`),Object.keys(this.#r).some(t=>{let n=t;return this.#r[n]!==e[n]&&r.has(n)})})();A.batch(()=>{n&&this.listeners.forEach(e=>{e(this.#r)}),this.#e.getQueryCache().notify({query:this.#t,type:`observerResultsUpdated`})})}#S(){let e=this.#e.getQueryCache().build(this.#e,this.options);if(e===this.#t)return;let t=this.#t;this.#t=e,this.#n=e.state,this.hasListeners()&&(t?.removeObserver(this),e.addObserver(this))}onQueryUpdate(){this.updateResult(),this.hasListeners()&&this.#y()}};function Ie(e,t){return E(t.enabled,e)!==!1&&e.state.data===void 0&&(e.state.status!==`error`||E(t.retryOnMount,e)!==!1)}function Le(e,t){return Ie(e,t)||e.state.data!==void 0&&Re(e,t,t.refetchOnMount)}function Re(e,t,n){if(E(t.enabled,e)!==!1&&E(t.staleTime,e)!==`static`){let r=E(n,e);return r===`always`||r!==!1&&Be(e,t)}return!1}function ze(e,t,n,r){return(e!==t||E(r.enabled,e)===!1)&&(!n.suspense||e.state.status!==`error`)&&Be(e,n)}function Be(e,t){return E(t.enabled,e)!==!1&&e.isStaleByTime(E(t.staleTime,e))}var Ve=class extends De{#e;#t;#n;#r;constructor(e){super(),this.#e=e.client,this.mutationId=e.mutationId,this.#n=e.mutationCache,this.#t=[],this.state=e.state||He(),this.setOptions(e.options),this.scheduleGc()}setOptions(e){this.options=e,this.updateGcTime(this.options.gcTime)}get meta(){return this.options.meta}addObserver(e){this.#t.includes(e)||(this.#t.push(e),this.clearGcTimeout(),this.#n.notify({type:`observerAdded`,mutation:this,observer:e}))}removeObserver(e){this.#t=this.#t.filter(t=>t!==e),this.scheduleGc(),this.#n.notify({type:`observerRemoved`,mutation:this,observer:e})}optionalRemove(){this.#t.length||(this.state.status===`pending`?this.scheduleGc():this.#n.remove(this))}continue(){return this.#r?.continue()??(this.state.status===`pending`?this.execute(this.state.variables):Promise.resolve())}async execute(e){let t=()=>{this.#i({type:`continue`})},n={client:this.#e,meta:this.options.meta,mutationKey:this.options.mutationKey},r=this.#r=j({fn:()=>this.options.mutationFn?this.options.mutationFn(e,n):Promise.reject(Error(`No mutationFn found`)),onFail:(e,t)=>{this.#i({type:`failed`,failureCount:e,error:t})},onPause:()=>{this.#i({type:`pause`})},onContinue:t,retry:this.options.retry??0,retryDelay:this.options.retryDelay,networkMode:this.options.networkMode,canRun:()=>this.#n.canRun(this)}),i=this.state.status===`pending`,a=!r.canStart();try{if(i)t();else{this.#i({type:`pending`,variables:e,isPaused:a}),this.#n.config.onMutate&&await this.#n.config.onMutate(e,this,n);let t=await this.options.onMutate?.(e,n);t!==this.state.context&&this.#i({type:`pending`,context:t,variables:e,isPaused:a})}let o=await r.start();return await this.#n.config.onSuccess?.(o,e,this.state.context,this,n),await this.options.onSuccess?.(o,e,this.state.context,n),await this.#n.config.onSettled?.(o,null,this.state.variables,this.state.context,this,n),await this.options.onSettled?.(o,null,e,this.state.context,n),this.#i({type:`success`,data:o}),o}catch(t){try{await this.#n.config.onError?.(t,e,this.state.context,this,n)}catch(e){Promise.reject(e)}try{await this.options.onError?.(t,e,this.state.context,n)}catch(e){Promise.reject(e)}try{await this.#n.config.onSettled?.(void 0,t,this.state.variables,this.state.context,this,n)}catch(e){Promise.reject(e)}try{await this.options.onSettled?.(void 0,t,e,this.state.context,n)}catch(e){Promise.reject(e)}throw this.#i({type:`error`,error:t}),t}finally{this.#r===r&&(this.#r=void 0),this.#n.runNext(this)}}#i(e){let t=t=>{switch(e.type){case`failed`:return{...t,failureCount:e.failureCount,failureReason:e.error};case`pause`:return{...t,isPaused:!0};case`continue`:return{...t,isPaused:!1};case`pending`:return{...t,context:e.context,data:void 0,failureCount:0,failureReason:null,error:null,isPaused:e.isPaused,status:`pending`,variables:e.variables,submittedAt:Date.now()};case`success`:return{...t,data:e.data,failureCount:0,failureReason:null,error:null,status:`success`,isPaused:!1};case`error`:return{...t,data:void 0,error:e.error,failureCount:t.failureCount+1,failureReason:e.error,isPaused:!1,status:`error`}}};this.state=t(this.state),A.batch(()=>{this.#t.forEach(t=>{t.onMutationUpdate(e)}),this.#n.notify({mutation:this,type:`updated`,action:e})})}};function He(){return{context:void 0,data:void 0,error:null,failureCount:0,failureReason:null,isPaused:!1,status:`idle`,variables:void 0,submittedAt:0}}var Ue=class extends xe{#e;#t;#n;constructor(e={}){super(),this.config=e,this.#e=new Set,this.#t=new Map,this.#n=0}build(e,t,n){let r=new Ve({client:e,mutationCache:this,mutationId:++this.#n,options:e.defaultMutationOptions(t),state:n});return this.add(r),r}add(e){this.#e.add(e);let t=We(e);if(typeof t==`string`){let n=this.#t.get(t);n?n.push(e):this.#t.set(t,[e])}this.notify({type:`added`,mutation:e})}remove(e){if(this.#e.delete(e)){let t=We(e);if(typeof t==`string`){let n=this.#t.get(t);if(n){if(n.length>1){let t=n.indexOf(e);t!==-1&&n.splice(t,1)}else n[0]===e&&this.#t.delete(t)}}}this.notify({type:`removed`,mutation:e})}canRun(e){let t=We(e);if(typeof t==`string`){let n=this.#t.get(t)?.find(e=>e.state.status===`pending`);return!n||n===e}return!0}runNext(e){let t=We(e);return typeof t==`string`?(this.#t.get(t)?.find(t=>t!==e&&t.state.isPaused))?.continue()??Promise.resolve():Promise.resolve()}clear(){A.batch(()=>{this.#e.forEach(e=>{this.notify({type:`removed`,mutation:e})}),this.#e.clear(),this.#t.clear()})}getAll(){return Array.from(this.#e)}find(e){let t={exact:!0,...e};return this.getAll().find(e=>D(t,e))}findAll(e={}){return this.getAll().filter(t=>D(e,t))}notify(e){A.batch(()=>{this.listeners.forEach(t=>{t(e)})})}resumePausedMutations(){let e=this.getAll().filter(e=>e.state.isPaused);return A.batch(()=>Promise.all(e.map(e=>e.continue().catch(C))))}};function We(e){return e.options.scope?.id}var Ge=class extends xe{#e;#t=void 0;#n;#r;constructor(e,t){super(),this.#e=e,this.setOptions(t),this.bindMethods(),this.#i()}bindMethods(){this.mutate=this.mutate.bind(this),this.reset=this.reset.bind(this)}setOptions(e){let t=this.options;this.options=this.#e.defaultMutationOptions(e),se(this.options,t)||this.#e.getMutationCache().notify({type:`observerOptionsUpdated`,mutation:this.#n,observer:this}),t?.mutationKey&&this.options.mutationKey&&re(t.mutationKey)!==re(this.options.mutationKey)?this.reset():this.#n?.state.status===`pending`&&this.#n.setOptions(this.options)}onSubscribe(){this.listeners.size===1&&this.#n&&(this.#n.addObserver(this),this.#i())}onUnsubscribe(){this.hasListeners()||this.#n?.removeObserver(this)}onMutationUpdate(e){this.#i(),this.#a(e)}getCurrentResult(){return this.#t}reset(){this.#n?.removeObserver(this),this.#n=void 0,this.#i(),this.#a()}mutate(e,t){return this.#r=t,this.#n?.removeObserver(this),this.#n=this.#e.getMutationCache().build(this.#e,this.options),this.#n.addObserver(this),this.#n.execute(e)}#i(){let e=this.#n?.state??He();this.#t={...e,isPending:e.status===`pending`,isSuccess:e.status===`success`,isError:e.status===`error`,isIdle:e.status===`idle`,mutate:this.mutate,reset:this.reset}}#a(e){A.batch(()=>{if(this.#r&&this.hasListeners()){let t=this.#t.variables,n=this.#t.context,r={client:this.#e,meta:this.options.meta,mutationKey:this.options.mutationKey};if(e?.type===`success`){try{this.#r.onSuccess?.(e.data,t,n,r)}catch(e){Promise.reject(e)}try{this.#r.onSettled?.(e.data,null,t,n,r)}catch(e){Promise.reject(e)}}else if(e?.type===`error`){try{this.#r.onError?.(e.error,t,n,r)}catch(e){Promise.reject(e)}try{this.#r.onSettled?.(void 0,e.error,t,n,r)}catch(e){Promise.reject(e)}}}this.listeners.forEach(e=>{e(this.#t)})})}},Ke=class extends xe{#e;constructor(e={}){super(),this.config=e,this.#e=new Map}build(e,t,n){let r=t.queryKey,i=t.queryHash??ne(r,t),a=this.get(i);return a||(a=new je({client:e,queryKey:r,queryHash:i,options:e.defaultQueryOptions(t),state:n,defaultOptions:e.getQueryDefaults(r)}),this.add(a)),a}add(e){this.#e.has(e.queryHash)||(this.#e.set(e.queryHash,e),this.notify({type:`added`,query:e}))}remove(e){this.#e.get(e.queryHash)===e&&(e.destroy(),this.#e.delete(e.queryHash),this.notify({type:`removed`,query:e}))}clear(){A.batch(()=>{this.getAll().forEach(e=>{this.remove(e)})})}get(e){return this.#e.get(e)}getAll(){return[...this.#e.values()]}find(e){let t={exact:!0,...e};return this.getAll().find(e=>te(t,e))}findAll(e={}){let t=this.getAll();return Object.keys(e).length>0?t.filter(t=>te(e,t)):t}notify(e){A.batch(()=>{this.listeners.forEach(t=>{t(e)})})}onFocus(){A.batch(()=>{this.getAll().forEach(e=>{e.onFocus()})})}onOnline(){A.batch(()=>{this.getAll().forEach(e=>{e.onOnline()})})}},qe=class{#e;#t;#n;#r;#i;#a;#o;#s;constructor(e={}){this.#e=e.queryCache||new Ke,this.#t=e.mutationCache||new Ue,this.#n=e.defaultOptions||{},this.#r=new Map,this.#i=new Map,this.#a=0}mount(){this.#a++,this.#a===1&&(this.#o=Se.subscribe(async e=>{e&&(await this.resumePausedMutations(),this.#e.onFocus())}),this.#s=Ce.subscribe(async e=>{e&&(await this.resumePausedMutations(),this.#e.onOnline())}))}unmount(){this.#a--,this.#a===0&&(this.#o?.(),this.#o=void 0,this.#s?.(),this.#s=void 0)}isFetching(e){return this.#e.findAll({...e,fetchStatus:`fetching`}).length}isMutating(e){return this.#t.findAll({...e,status:`pending`}).length}getQueryData(e){let t=this.defaultQueryOptions({queryKey:e});return this.#e.get(t.queryHash)?.state.data}ensureQueryData(e){let t=this.defaultQueryOptions(e),n=this.#e.build(this,t),r=n.state.data;return r===void 0?this.fetchQuery(e):(e.revalidateIfStale&&n.isStaleByTime(E(t.staleTime,n))&&this.prefetchQuery(t),Promise.resolve(r))}getQueriesData(e){return this.#e.findAll(e).map(({queryKey:e,state:t})=>[e,t.data])}setQueryData(e,t,n){let r=this.defaultQueryOptions({queryKey:e}),i=this.#e.get(r.queryHash)?.state.data,a=w(t,i);if(a!==void 0)return this.#e.build(this,r).setData(a,{...n,manual:!0})}setQueriesData(e,t,n){return A.batch(()=>this.#e.findAll(e).map(({queryKey:e})=>[e,this.setQueryData(e,t,n)]))}getQueryState(e){let t=this.defaultQueryOptions({queryKey:e});return this.#e.get(t.queryHash)?.state}removeQueries(e){let t=this.#e;A.batch(()=>{t.findAll(e).forEach(e=>{t.remove(e)})})}resetQueries(e,t){let n=this.#e;return A.batch(()=>{let r=n.findAll(e),i=new Set(r);return r.forEach(e=>{e.reset()}),this.refetchQueries({type:`active`,predicate:e=>i.has(e)},t)})}cancelQueries(e,t={}){let n={revert:!0,...t},r=A.batch(()=>this.#e.findAll(e).map(e=>e.cancel(n)));return Promise.all(r).then(C).catch(C)}invalidateQueries(e,t={}){return A.batch(()=>(this.#e.findAll(e).forEach(e=>{e.invalidate()}),e?.refetchType===`none`?Promise.resolve():this.refetchQueries({...e,type:e?.refetchType??e?.type??`active`},t)))}refetchQueries(e,t={}){let n={...t,cancelRefetch:t.cancelRefetch??!0},r=A.batch(()=>this.#e.findAll(e).filter(e=>!e.isDisabled()&&!e.isStatic()).map(e=>{let t=e.fetch(void 0,n);return n.throwOnError||(t=t.catch(C)),e.state.fetchStatus===`paused`?Promise.resolve():t}));return Promise.all(r).then(C)}async query(e){let t=this.defaultQueryOptions(e);t.retry===void 0&&(t.retry=!1);let n=this.#e.build(this,t),r=n.isStaleByTime(E(t.staleTime,n))?await n.fetch(t):n.state.data,i=t.select;return i?i(r):r}fetchQuery(e){let t=this.defaultQueryOptions(e);t.retry===void 0&&(t.retry=!1);let n=this.#e.build(this,t);return n.isStaleByTime(E(t.staleTime,n))?n.fetch(t):Promise.resolve(n.state.data)}prefetchQuery(e){return this.fetchQuery(e).then(C).catch(C)}infiniteQuery(e){return e._type=`infinite`,this.query(e)}fetchInfiniteQuery(e){return e._type=`infinite`,this.fetchQuery(e)}prefetchInfiniteQuery(e){return this.fetchInfiniteQuery(e).then(C).catch(C)}ensureInfiniteQueryData(e){return e._type=`infinite`,this.ensureQueryData(e)}resumePausedMutations(){return Ce.isOnline()?this.#t.resumePausedMutations():Promise.resolve()}getQueryCache(){return this.#e}getMutationCache(){return this.#t}getDefaultOptions(){return this.#n}setDefaultOptions(e){this.#n=e}setQueryDefaults(e,t){this.#r.set(re(e),{queryKey:e,defaultOptions:t})}getQueryDefaults(e){let t=[...this.#r.values()],n={};return t.forEach(t=>{ie(e,t.queryKey)&&Object.assign(n,t.defaultOptions)}),n}setMutationDefaults(e,t){this.#i.set(re(e),{mutationKey:e,defaultOptions:t})}getMutationDefaults(e){let t=[...this.#i.values()],n={};return t.forEach(t=>{ie(e,t.mutationKey)&&Object.assign(n,t.defaultOptions)}),n}defaultQueryOptions(e){if(e._defaulted)return e;let t={...this.#n.queries,...this.getQueryDefaults(e.queryKey),...e,_defaulted:!0};return t.queryHash||=ne(t.queryKey,t),t.refetchOnReconnect===void 0&&(t.refetchOnReconnect=t.networkMode!==`always`),t.throwOnError===void 0&&(t.throwOnError=!!t.suspense),!t.networkMode&&t.persister&&(t.networkMode=`offlineFirst`),t.queryFn===he&&(t.enabled=!1),t}defaultMutationOptions(e){return e?._defaulted?e:{...this.#n.mutations,...e?.mutationKey&&this.getMutationDefaults(e.mutationKey),...e,_defaulted:!0}}clear(){this.#e.clear(),this.#t.clear()}},Je=m.createContext(!1),Ye=()=>m.useContext(Je);Je.Provider;function Xe(){let e=!1;return{clearReset:()=>{e=!1},reset:()=>{e=!0},isReset:()=>e}}var Ze=m.createContext(Xe()),Qe=()=>m.useContext(Ze),$e=(e,t,n)=>{let r=n?.state.error&&typeof e.throwOnError==`function`?_e(e.throwOnError,[n.state.error,n]):e.throwOnError;(e.suspense||r)&&(t.isReset()||(e.retryOnMount=!1))},et=e=>{m.useEffect(()=>{e.clearReset()},[e])},tt=({result:e,errorResetBoundary:t,throwOnError:n,query:r,suspense:i})=>e.isError&&!t.isReset()&&!e.isFetching&&r&&(i&&e.data===void 0||_e(n,[e.error,r])),nt=e=>{if(e.suspense){let t=1e3,n=e=>e===`static`?e:Math.max(e??t,t),r=e.staleTime;e.staleTime=typeof r==`function`?(...e)=>n(r(...e)):n(r),typeof e.gcTime==`number`&&(e.gcTime=Math.max(e.gcTime,t))}},rt=(e,t)=>e?.suspense&&t.isPending,it=(e,t,n)=>t.fetchOptimistic(e).catch(()=>{n.clearReset()});function at(e,t,n){let r=Ye(),i=Qe(),a=_(n),o=a.defaultQueryOptions(e),s=a.getQueryCache().get(o.queryHash),c=e.subscribed!==!1;o._optimisticResults=r?`isRestoring`:c?`optimistic`:void 0,nt(o),$e(o,i,s),et(i);let[l]=m.useState(()=>new t(a,o)),u=l.getOptimisticResult(o),d=!r&&c;if(m.useSyncExternalStore(m.useCallback(e=>{let t=d?l.subscribe(A.batchCalls(e)):C;return l.updateResult(),t},[l,d]),()=>l.getCurrentResult(),()=>l.getCurrentResult()),m.useEffect(()=>{l.setOptions(o)},[o,l]),rt(o,u))throw it(o,l,i);if(tt({result:u,errorResetBoundary:i,throwOnError:o.throwOnError,query:s,suspense:o.suspense}))throw u.error;return o.notifyOnChangeProps?u:l.trackResult(u)}function ot(e,t){return at(e,Fe,t)}function st(e,t){let n=_(t),[r]=m.useState(()=>new Ge(n,e));m.useEffect(()=>{r.setOptions(e)},[r,e]);let i=m.useSyncExternalStore(m.useCallback(e=>r.subscribe(A.batchCalls(e)),[r]),()=>r.getCurrentResult(),()=>r.getCurrentResult()),a=m.useCallback((...e)=>{r.mutate(e[0],e[1]).catch(C)},[r]);if(i.error&&_e(r.options.throwOnError,[i.error]))throw i.error;return{...i,mutate:a,mutateAsync:i.mutate}}var ct=m.use,lt=m.useLayoutEffect;function ut(e){return e[e.length-1]}function dt(e,t){return typeof e==`function`?e(t):e}var ft=Object.prototype.hasOwnProperty;function pt(e){for(let t in e)if(ft.call(e,t))return!0;return!1}var mt=()=>Object.create(null),ht=(e,t)=>gt(e,t,!0);function gt(e,t,n,r=0){if(e===t)return e;if(r++>500)return t;let i=Array.isArray(e)&&Array.isArray(t);if(!i&&!(_t(e)&&_t(t)))return t;let a=Object.keys(e),o=a.length,s=Object.keys(t),c=s.length;if(i?o!==e.length||c!==t.length||o&&ut(a)!==`${o-1}`||c&&ut(s)!==`${c-1}`:o!==Object.getOwnPropertyNames(e).length||c!==Object.getOwnPropertyNames(t).length||Object.getOwnPropertySymbols(t).length)return t;let l=0,u,d,f;if(i){for(;ll&&(u=t[f],u=d===u?d:typeof d==`object`?gt(d,u,n,r):u),p[f]=o`{}]/g;function xt(e){return e.replace(bt,e=>`%`+e.charCodeAt(0).toString(16).toUpperCase().padStart(2,`0`))}function St(e){let t;try{t=decodeURI(e)}catch{t=e.replaceAll(/%[0-9A-F]{2}/gi,e=>{try{return decodeURI(e)}catch{return e}})}return xt(t)}var Ct=[`http:`,`https:`,`mailto:`,`tel:`];function wt(e){if(e[0]!==`/`&&e.includes(`:`))return/^[\x00-\x20]*([a-z][a-z\d+.\t\n\r-]*:)/i.exec(e)?.[1]?.replace(/[\t\n\r]/g,``).toLowerCase()}var Tt=/^[\x00-\x20]*[\\/][\t\n\r]*[\\/]/;function Et(e,t){if(!e)return!1;if(Tt.test(e))return!0;let n=wt(e);return n?!t.has(n):!1}function Dt(e){if(!e)return e;let t=e;if(/[%\\\x00-\x1f\x7f]/.test(e)){let n=/%25|%5C/gi,r=0,i;for(t=``;(i=n.exec(e))!==null;)t+=St(e.slice(r,i.index))+i[0],r=n.lastIndex;t+=St(r?e.slice(r):e)}return t}function Ot(e){return/[\s\u0080-\uFFFF]/.test(e)?e.replace(/\s|[^\u0000-\u007F]/gu,encodeURIComponent):e}function kt(e,t){if(e===t)return!0;if(e.length!==t.length)return!1;for(let n=0;n1&&e[t-1]===`/`?e.replace(/\/+$/,``):e}function Pt(e){return Nt(Mt(e))}function Ft(e,t){return e?.endsWith(`/`)&&e!==`/`&&e!==`${t}/`?e.slice(0,-1):e}function It(e,t,n=`never`,r){if(t.includes(`//`)&&(t=jt(t)),t.startsWith(`/`))return t.length===1||n===`preserve`?t:n===`always`?t.endsWith(`/`)?t:`${t}/`:t.endsWith(`/`)?t.slice(0,-1):t;let i=t===`.`,a;if(r){a=i?e:e+`\0`+t;let n=r.get(a);if(n)return n}let o;if(i)o=e.split(`/`);else{for(e.includes(`//`)&&(e=jt(e)),o=e.split(`/`);o.length>1&&ut(o)===``;)o.pop();let n=t.split(`/`);for(let e=0,t=n.length;e1?o.pop():o=[``]:r===`.`||o.push(r)}}o.length>1&&(ut(o)===``?n===`never`&&o.pop():n===`always`&&o.push(``));let s=o.join(`/`),c=(i?jt(s):s)||`/`;return a&&r&&r.set(a,c),c}function Lt(e){let t=new Map(e.map(e=>[encodeURIComponent(e),e])),n=new RegExp([...t.keys()].join(`|`).replace(/[.*()]/g,`\\$&`),`g`);return e=>e.replace(n,e=>t.get(e)??e)}function Rt(e){return e==null||e===``}function zt(e,t,n){if(typeof t!=`string`)return``+(t??void 0);let r=e===`_splat`;if(r&&(!t||/^[a-zA-Z0-9\-._~!/]*$/.test(t)))return t;let i=encodeURIComponent(t);return r&&(i=i.replaceAll(`%2F`,`/`)),n?n(i):i}function Bt(e,t,n,r,i){let a=e.endsWith(`/`)?`/`:``,o=``;for(let e of t){if(typeof e==`string`){o+=e;continue}let[t,s,c,l]=e,u=t===2,d=u&&l!==void 0?l+a:l,f=n[s];if(t!==3||f!=null){if(i&&(i[s]=f,u&&(i[`*`]=f)),u&&Rt(f)){if(c===`/`&&!d)continue;f=``}o+=c+zt(s,f,r)+(d||``)}}return o+a||`/`}function Vt(e){return e?.isNotFound===!0}function Ht(){try{return sessionStorage}catch{return}}var Ut=`tsr-scroll-restoration-v1_3`,Wt=Ht();function Gt(){try{return JSON.parse(Wt?.getItem(`tsr-scroll-restoration-v1_3`)||`{}`)}catch{return{}}}function Kt(){try{Wt?.setItem(Ut,JSON.stringify(qt))}catch{}}var qt=Gt(),Jt=`data-scroll-restoration-id`,Yt=e=>e.state.__TSR_key||e.href;function Xt(e){let t=e.getAttribute(Jt);if(t)return`[${Jt}="${t}"]`;let n=``,r=e,i;for(;i=r.parentNode;){let e=1,t=r;for(;t=t.previousElementSibling;)e++;let a=`${r.localName}:nth-child(${e})`;n=n?`${a} > ${n}`:a,r=i}return n}var Zt=!1,Qt=`window`;function M(e){try{return typeof e==`function`?e():document.querySelector(e)}catch{}}function $t(e){let t=new Set;for(let n of e){if(n===Qt)continue;let e=M(n);e&&t.add(e)}return t}function en(e,t){let n=t??e.options.scrollRestoration,r=e._scroll;n&&(r.restoring=!0);let i=e.options.getScrollRestorationKey||Yt,a=new Set,o=e=>{let t=qt[e]||={};for(let e of a)e===document?t[Qt]={scrollX,scrollY}:e.isConnected&&(t[Xt(e)]={scrollX:e.scrollLeft,scrollY:e.scrollTop})};n&&!r.restoration&&(r.restoration=!0,Zt=!1,history.scrollRestoration=`manual`,document.addEventListener(`scroll`,e=>{Zt||a.add(e.target)},!0),e.subscribe(`onBeforeLoad`,e=>{e.fromLocation&&o(i(e.fromLocation)),a.clear()}),addEventListener(`pagehide`,()=>{o(i(e.stores.resolvedLocation.get()??e.stores.location.get())),Kt()})),!r.reset&&(r.reset=!0,e.subscribe(`onRendered`,t=>{let n=e.options.scrollRestorationBehavior,o=e.options.scrollToTopSelectors,s=r.next,c=r.hash,l;if(a.clear(),r.next=!0,r.hash=!1,typeof e.options.scrollRestoration==`function`&&!e.options.scrollRestoration({location:e.latestLocation}))return;let u=i(t.toLocation),d=t.fromLocation&&i(t.fromLocation);if(r.restoring&&d&&d!==u){let e=qt[d];if(e){let t=qt[u];for(let n in e){if(n===Qt){if(s)continue}else{let e=M(n);if(!e||s&&o&&(l??=$t(o),l.has(e)))continue}t||=qt[u]={},t[n]??=e[n]}}}Zt=!0;try{let e=t.toLocation.hash,i=t.toLocation.state.__hashScrollIntoViewOptions??!0,a=!1;if(s){!e&&o&&(l??=$t(o));let t=e&&i&&c,s=r.restoring?qt[u]:void 0;if(s)for(let e in s){let{scrollX:r,scrollY:i}=s[e];if(e===Qt){if(t)continue;scrollTo({top:i,left:r,behavior:n}),a=!0}else{let t=M(e);t&&(t.scrollLeft=r,t.scrollTop=i,l?.delete(t))}}if(!e){let e={top:0,left:0,behavior:n};if(a||scrollTo(e),l)for(let t of l)t.scrollTo(e)}}!a&&e&&i&&document.getElementById(e)?.scrollIntoView(i)}finally{Zt=!1}}))}function tn(e,t=String){let n;for(let r in e){let i=e[r];i!==void 0&&(n||=new URLSearchParams).set(r,t(i))}return n?n.toString():``}function nn(e){return e?e===`false`?!1:e===`true`?!0:e*0==0&&+e+``===e?+e:e:``}function rn(e){let t=new URLSearchParams(e),n=Object.create(null);for(let[e,r]of t.entries()){let t=n[e];t==null?n[e]=nn(r):Array.isArray(t)?t.push(nn(r)):n[e]=[t,nn(r)]}return n}var an=/^(?:\s|["[{\d-]|fa|nu|tr)/,on=cn(JSON.parse),sn=ln(JSON.stringify,JSON.parse);function cn(e){let t=e===JSON.parse;return n=>{n[0]===`?`&&(n=n.substring(1));let r=rn(n);for(let n in r){let i=r[n];if(typeof i==`string`){if(t&&!an.test(i))continue;try{r[n]=e(i)}catch{}}}return r}}function ln(e,t){let n=t===JSON.parse;function r(r){if(r&&typeof r==`object`)try{return e(r)}catch{}else if(t&&typeof r==`string`){if(n&&!an.test(r))return r;try{return t(r),e(r)}catch{}}return r}return e=>{let t=tn(e,r);return t?`?${t}`:``}}var un=`__root__`;function dn(e){e.statusCode=e.statusCode||e.code||307;let t=new Headers(e.headers);e.href&&t.get(`Location`)===null&&t.set(`Location`,e.href);let n=new Response(null,{status:e.statusCode,headers:t});if(n.options=e,e.throw)throw n;return n}function fn(e){return e instanceof Response&&!!e.options}function pn(e){let t=new Map,n,r;return{get(e){let n=t.get(e);if(n)return n.visited=!0,n.value},set(i,a){let o=t.get(i);if(o){o.value=a;return}if(t.size>=e){let e=n?.next().value;for(;!e||e.visited;)e?e.visited=!1:n=t.values(),e=n.next().value;e===r&&(n=void 0),t.delete(e.key)}let s={key:i,value:a,visited:!1};r=s,t.set(i,s)},clear(){t.clear(),n=void 0,r=void 0}}}var mn=4,hn=5;function gn(e){let t=e.names;if(t)return t;let n=[];for(let t of e)typeof t!=`string`&&n.push(t[1]);return e.names=n}function _n(e,t,n){let r=e.substring(t,n);if(r.charCodeAt(0)===36)return r.length===1?[2,`_splat`,``,void 0]:[1,r.substring(1),``,``];let i=r.indexOf(`{`);if(i>=0){let a=r.indexOf(`}`,i),o=r.charCodeAt(i+1)===45,s=i+(o?3:2);if(a>=0&&r.charCodeAt(s-1)===36&&(!o||s!e.parse&&e.caseSensitive===_&&e.prefix===h&&e.suffix===g);if(y)c=y;else{let e=bn(r,t,_,h,g);c=e,v.push(e),v.length===2&&i?.push(v)}}r=c}p&&m=0;e--){let n=i.wildcard[e],{prefix:r,suffix:a}=n;if(!r||!_&&(n.caseSensitive?v:y??=v.toLowerCase()).startsWith(r)){if(a){if(_)continue;let e=t.slice(u).join(`/`),i=e.slice(-a.length);if((n.caseSensitive?i:i.toLowerCase())!==a||e.length-a.length=0;t--){let n=i.optional[t];s.push({node:n,index:u,skipped:e,statics:f,dynamics:p,optionals:m,extract:h,rawParams:g})}if(!_)for(let e=i.optional.length-1;e>=0;e--){let t=i.optional[e],{prefix:n,suffix:r}=t;if(n||r){let e=t.caseSensitive?v:y??=v.toLowerCase();if(n&&!e.startsWith(n)||r&&e.indexOf(r,e.length-r.length)=0;e--){let t=i.dynamic[e],{prefix:n,suffix:r}=t;if(n||r){let e=t.caseSensitive?v:y??=v.toLowerCase();if(n&&!e.startsWith(n)||r&&e.indexOf(r,e.length-r.length)=0;e--){let t=i.pathless[e];s.push({node:t,index:u,skipped:d,statics:f,dynamics:p,optionals:m,extract:h,rawParams:g})}}if(l)return l;if(r&&c){let n=c.index;for(let e=0;ee.statics||t.statics===e.statics&&(t.dynamics>e.dynamics||t.dynamics===e.dynamics&&(t.optionals>e.optionals||t.optionals===e.optionals&&((t.node.kind===mn)>(e.node.kind===mn)||t.node.kind===mn==(e.node.kind===mn)&&t.node.depth>e.node.depth)))}function Fn(e,t,n){let r=Pt(e),i=`/${r}`,a=t?i:i.toLowerCase(),o=`${a}/`,s={input:({url:e})=>{let n=t?e.pathname:e.pathname.toLowerCase();return n===a?e.pathname=`/`:n.startsWith(o)&&(e.pathname=e.pathname.slice(i.length)),e},output:({url:e})=>(e.pathname=jt(`/${r}${e.pathname}`),e)};return n?{input:({url:e})=>In(n,s.input({url:e})),output:({url:e})=>s.output({url:Ln(n,e)})}:s}function In(e,t){let n=e?.input?.({url:t});if(n){if(typeof n==`string`)return new URL(n);if(n instanceof URL)return n}return t}function Ln(e,t){let n=e?.output?.({url:t});if(n){if(typeof n==`string`)return new URL(n);if(n instanceof URL)return n}return t}function Rn(e,t){let{createMutableStore:n,createReadonlyStore:r,batch:i}=t,a=new Map,o=n(`idle`),s=n(e),c=n(void 0),l=n([]),u=r(()=>l.get().map(e=>a.get(e).get())),d=r(()=>({status:o.get(),isLoading:o.get()===`pending`,matches:u.get(),location:s.get(),resolvedLocation:c.get()}));function f(e){let t=a.get(e);return t||(t=n(void 0),a.set(e,t)),t}let p={status:o,location:s,resolvedLocation:c,ids:l,matches:u,byRoute:a,__store:d,getMatchStore:f,setMatches:m};function m(e){let t=l.get(),n=e.map(e=>e.routeId);i(()=>{kt(t,n)||l.set(n);for(let e of t)n.includes(e)||a.get(e).set(()=>void 0);for(let t of e){let e=f(t.routeId);e.get()!==t&&e.set(t)}})}return p}var zn=`__TSR_index`,Bn=`popstate`,Vn=`beforeunload`,Hn=/^[\x00-\x20]*(?:[\\/][\t\n\r]*){2,}/;function Un(e){let t=Hn.exec(e);return t?`/`+e.slice(t[0].length):e}function Wn(e){return/[\x00-\x1f\x7f]/.test(e)&&(e=e.replace(/[\x00-\x1f\x7f]/g,e=>` -\r`.includes(e)?``:encodeURIComponent(e))),Un(e)}function Gn(e){let t=e.getLocation(),n=new Set,r=r=>{t=e.getLocation(),n.forEach(e=>e({location:t,action:r}))},i=n=>{e.notifyOnIndexChange??!0?r(n):t=e.getLocation()},a=async({task:n,navigateOpts:r,...i})=>{if(r?.ignoreBlocker??!1){n();return}let a=e.getBlockers?.()??[],o=i.type===`PUSH`||i.type===`REPLACE`;if(typeof document<`u`&&a.length&&o)for(let n of a){let r=Jn(i.path,i.state);if(await n.blockerFn({currentLocation:t,nextLocation:r,action:i.type})){e.onBlocked?.();return}}n()};return{get location(){return t},get length(){return e.getLength()},subscribers:n,subscribe:e=>(n.add(e),()=>{n.delete(e)}),push:(n,i,o)=>{let s=t.state[zn];i=Kn(s+1,i),a({task:()=>{e.pushState(n,i),r({type:`PUSH`})},navigateOpts:o,type:`PUSH`,path:n,state:i})},replace:(n,i,o)=>{let s=t.state[zn];i=Kn(s,i),a({task:()=>{e.replaceState(n,i),r({type:`REPLACE`})},navigateOpts:o,type:`REPLACE`,path:n,state:i})},go:(t,n)=>{a({task:()=>{e.go(t,n?.ignoreBlocker??!1),i({type:`GO`,index:t})},navigateOpts:n,type:`GO`})},back:t=>{a({task:()=>{e.back(t?.ignoreBlocker??!1),i({type:`BACK`})},navigateOpts:t,type:`BACK`})},forward:t=>{a({task:()=>{e.forward(t?.ignoreBlocker??!1),i({type:`FORWARD`})},navigateOpts:t,type:`FORWARD`})},canGoBack:()=>t.state[zn]!==0,createHref:t=>e.createHref(t),block:t=>{if(!e.setBlockers)return()=>{};let n=e.getBlockers?.()??[];return e.setBlockers([...n,t]),()=>{let n=e.getBlockers?.()??[];e.setBlockers?.(n.filter(e=>e!==t))}},flush:()=>e.flush?.(),destroy:()=>e.destroy?.(),notify:r,_getBlockers:()=>e.getBlockers?.()??[]}}function Kn(e,t){let n=Yn();return{...t,key:n,__TSR_key:n,[zn]:e}}function qn(e){let t=e?.window??(typeof document<`u`?window:void 0),n=t.history.pushState,r=t.history.replaceState,i=[],a=()=>i,o=e=>i=e,s=t=>Wn(e?.createHref?e.createHref(t):t),c=e?.parseLocation??(()=>Jn(`${t.location.pathname}${t.location.search}${t.location.hash}`,t.history.state));if(!t.history.state?.__TSR_key&&!t.history.state?.key){let e=Yn();t.history.replaceState({[zn]:0,key:e,__TSR_key:e},``)}let l=c(),u,d=!1,f=!1,p=!1,m=!1,h=()=>l,g,_=()=>{g&&(S._ignoreSubscribers=!0,(g[2]?t.history.pushState:t.history.replaceState)(g[1],``,g[0]),S._ignoreSubscribers=!1,g=void 0,u=void 0)},v=(t,n,r)=>{let i=e?.createHref?s(n):void 0,a=!!g;a||(u=l),l=Jn(n,r),g=[i??l.href,r,g?.[2]||t],a||queueMicrotask(()=>_())},y=e=>{l=c(),S.notify({type:e})},b=async()=>{if(m=!1,f){f=!1;return}let e=c(),n=e.state[zn]-l.state[zn],r=n===1,i=n===-1,o=!r&&!i||d;d=!1;let s=o?`GO`:i?`BACK`:`FORWARD`,u=o?{type:`GO`,index:n}:{type:i?`BACK`:`FORWARD`};if(p)p=!1;else{let r=a();if(typeof document<`u`&&r.length){for(let i of r)if(await i.blockerFn({currentLocation:l,nextLocation:e,action:s})){f=!0,t.history.go(-n),S.notify(u);return}}}l=c(),S.notify(u)},x=e=>{if(m){m=!1;return}let t=!1,n=a();if(typeof document<`u`&&n.length)for(let e of n){let n=e.enableBeforeUnload??!0;if(n===!0){t=!0;break}if(typeof n==`function`&&n()===!0){t=!0;break}}if(t)return e.preventDefault(),e.returnValue=``},S=Gn({getLocation:h,getLength:()=>t.history.length,pushState:(e,t)=>v(!0,e,t),replaceState:(e,t)=>v(!1,e,t),back:e=>(e&&(p=!0,m=!0),t.history.back()),forward:e=>{e&&(p=!0,m=!0),t.history.forward()},go:(e,n)=>{d=!0,n&&(p=!0,m=!0),t.history.go(e)},createHref:e=>s(e),flush:_,destroy:()=>{t.history.pushState=n,t.history.replaceState=r,t.removeEventListener(Vn,x,{capture:!0}),t.removeEventListener(Bn,b)},onBlocked:()=>{u&&l!==u&&(l=u)},getBlockers:a,setBlockers:o,notifyOnIndexChange:!1});return S._ignoreNextBeforeUnload=e=>{m=!1;try{e=new URL(e,t.document.baseURI).href,m=/^https?:/.test(e)&&(!e.includes(`#`)||e.split(`#`)[0]!==t.location.href.split(`#`)[0])}catch{}},t.addEventListener(Vn,x,{capture:!0}),t.addEventListener(Bn,b),t.history.pushState=function(...e){let r=n.apply(t.history,e);return S._ignoreSubscribers||y(`PUSH`),r},t.history.replaceState=function(...e){let n=r.apply(t.history,e);return S._ignoreSubscribers||y(`REPLACE`),n},S}function Jn(e,t){let n=Wn(e),r=n.indexOf(`#`),i=n.indexOf(`?`);if(!t){let e=Yn();t={[zn]:0,key:e,__TSR_key:e}}return{href:n,pathname:n.substring(0,r>0?i>0?Math.min(r,i):r:i>0?i:n.length),hash:r>-1?n.substring(r):``,search:i>-1?n.slice(i,r===-1?void 0:r):``,state:t}}function Yn(){return(Math.random()+1).toString(36).substring(7)}function Xn(e,t){return e.protocol!==`http:`&&e.protocol!==`https:`||e.origin!==t||!!e.username||!!e.password}function Zn(e){return e.pathname+e.search+e.hash}function Qn(e){return e.options.loader||e.options.beforeLoad||e.lazyFn||e.options.component?.preload||e.options.pendingComponent?.preload}function $n(e,t){return{fromLocation:t,toLocation:e,pathChanged:t?.pathname!==e.pathname,hrefChanged:t?.href!==e.href,hashChanged:t?.hash!==e.hash}}function er({key:e,__TSR_key:t,__TSR_index:n,__hashScrollIntoViewOptions:r,...i}){return i}function tr(e){return e.findIndex(e=>e.status===`error`||e.status===`notFound`||e._notFound)+1}function nr(e,t,n,r,i,a){r&&(t=t.slice(0,r)),i&&(n=n.slice(0,i));for(let r of t){if(a&&e._tx!==a)return;n.some(e=>e.routeId===r.routeId)||e.routesById[r.routeId].options.onLeave?.(r)}for(let r of n){if(a&&e._tx!==a)return;e.routesById[r.routeId].options[t.some(e=>e.routeId===r.routeId)?`onStay`:`onEnter`]?.(r)}}var rr=class{constructor(e,t){this.tempLocationKey=`${Math.round(Math.random()*1e7)}`,this._scroll={next:!0},this.subscribers=new Set,this._cache=new Map,this._committed=[],this.startTransition=async e=>(e(),!1),this.update=e=>{let t=this.options;this.options={...t,...e},this.isServer=this.options.isServer??!1??typeof document>`u`,this.staticLocations=new WeakMap,this.protocolAllowlist=new Set(this.options.protocolAllowlist),(!this.history||this.options.history&&this.options.history!==this.history)&&(this.history=this.options.history?this.options.history:qn()),this.origin=this.options.origin,this.origin||=window?.origin&&window.origin!==`null`?window.origin:`http://localhost`;let n=this.options.basepath??`/`,r=this.options.rewrite,i=this.basepath!==n||t?.rewrite!==r||t?.caseSensitive!==this.options.caseSensitive;if(i&&(this.basepath=n,this.rewrite=n!==`/`&&Pt(n)?Fn(n,this.options.caseSensitive,r):r),this.history&&this.updateLatestLocation(),this.options.routeTree!==this.routeTree){this.routeTree=this.options.routeTree;let e;e=this.buildRouteTree(),this.setRoutes(e)}if(this.stores)i&&this.stores.location.set(this.latestLocation);else if(this.latestLocation){let e=this.getStoreConfig(this);this.batch=e.batch,this.stores=Rn(this.latestLocation,e),en(this)}},this.updateLatestLocation=()=>{this.latestLocation=this.parseLocation(this.history.location,this.latestLocation)},this.buildRouteTree=()=>{let e=Tn(this.routeTree,this.options.caseSensitive);return this.options.routeMasks&&xn(this.options.routeMasks,e.processedTree),{...e,resolvePathCache:pn(1e3)}},this.subscribe=(e,t)=>{let n={eventType:e,fn:t};return this.subscribers.add(n),()=>{this.subscribers.delete(n)}},this.emit=e=>{for(let t of this.subscribers)if(t.eventType===e.type)try{t.fn(e)}catch(e){console.error(e)}},this.parseLocation=(e,t)=>{let n=({pathname:e,search:n,hash:r,href:i},a)=>{if(!this.rewrite&&!/[ \x00-\x1f\x7f\u0080-\uffff]/.test(e)){let i=this.options.parseSearch(n),o=this.options.stringifySearch(i);return{href:e+o+r,publicHref:e+o+r,pathname:Dt(e),external:!1,searchStr:o,search:ht(t?.search,i),hash:Dt(r.slice(1)),state:gt(t?.state,a)}}let o=In(this.rewrite,new URL(i,this.origin)),s=this.options.parseSearch(o.search),c=this.options.stringifySearch(s);return o.search=c,{href:o.href.replace(o.origin,``),publicHref:i,pathname:Dt(Un(o.pathname)),external:!!this.rewrite&&Xn(o,this.origin),searchStr:c,search:ht(t?.search,s),hash:Dt(o.hash.slice(1)),state:gt(t?.state,a)}},r=n(e,e.state),{__tempLocation:i,__tempKey:a}=r.state;if(i&&(!a||a===this.tempLocationKey)){let e=n(i,{...i.state,__tempLocation:void 0,key:r.state.key,__TSR_key:r.state.__TSR_key});return e.maskedLocation=r,e}return r},this.matchRoutes=(e,t,n)=>typeof e==`string`?this.matchRoutesInternal({pathname:e,search:t},n):this.matchRoutesInternal(e,t),this.getMatchedRoutes=e=>{let t=Object.create(null),n=wn(Nt(e),this.processedTree,!0);return n&&Object.assign(t,n.rawParams),[n?.branch||[this.routesById.__root__],t,n?.route]},this.buildLocation=e=>{{let t=this.staticLocations.get(e);if(t)return t}let t=!1,n=(n={})=>{if(n.href){let e=Jn(n.href,{});n={...n,to:In(this.rewrite,new URL(e.pathname,this.origin)).pathname,search:this.options.parseSearch(e.search),hash:e.hash.slice(1)}}let r=n._fromLocation||this._pendingLocation||this.latestLocation,i,a=()=>(t=!0,r),o=()=>(t=!0,i??=this.matchRoutesLightweight(r)),s=n.to?`${n.to}`:`.`,c=It(s[0]===`/`?``:n.unsafeRelative===`path`?a().pathname:n.from??o()[1],s,this.options.trailingSlash,this.resolvePathCache),l=this.routesByPath[Nt(c)],u=c.includes(`$`),d;if(l)d=l._branch??=On(l);else if(u)d=[];else{let[e,t,n]=this.getMatchedRoutes(c);d=e,this.options.notFoundRoute&&(!n||n.path!==`/`&&t[`**`])&&(d=[...d,this.options.notFoundRoute])}let f=u?l?._interpolation??vn(!1,{fullPath:c},0):void 0,p;for(let e of d){let t=e.options.params?.stringify??e.options.stringifyParams;if(t){let e=o()[3];if(p??=cr(n.params,e),!pt(p))break;p===e&&(p=Object.assign(mt(),p));try{Object.assign(p,t(p))}catch{}}}p??=cr(n.params,lr(n.params,f)?o()[3]:ur);let m=e.leaveParams?c:Un(Dt(f?Bt(c,f,p,this.pathParamsDecoder):c)),h=dr(d,e._includeValidateSearch),g=()=>{let t=o()[2];if(e._includeValidateSearch&&this.options.search?.strict){let e={};d.forEach(n=>{if(n.options.validateSearch)try{Object.assign(e,sr(n.options.validateSearch,{...e,...t}))}catch{}}),t=e}return t},_=h.length?fr(h,g(),n):n.search===!0?g():typeof n.search==`function`?n.search(g()):n.search||ur,v=this.options.stringifySearch(_),y=n.hash===!0?a().hash:typeof n.hash==`function`?n.hash(a().hash):n.hash||void 0,b=y?`#${y}`:``,x=n.state?n.state===!0?a().state:typeof n.state==`function`?n.state(a().state):n.state:ur,S=`${m}${v}${b}`,C,w,T=!1;if(this.rewrite){let e=new URL(S,this.origin),t=e.origin,n=Ln(this.rewrite,e);C=Zn(e),Xn(n,t)?(w=n.href,T=!0):w=Un(Zn(n))}else C=Ot(S),w=C;return{publicHref:w,href:C,pathname:m,search:_,searchStr:v,state:x,hash:y??``,external:T,unmaskOnReload:n.unmaskOnReload}},r=n(e);if(e.mask)r.maskedLocation=n({from:e.from,...e.mask});else if(this.options.routeMasks){let t=Sn(r.pathname,this.processedTree);if(t){let i=Object.assign(mt(),t.rawParams),{from:a,params:o,...s}=t.route,c=cr(o,i);r.maskedLocation=n({from:e.from,...s,params:c})}}return!t&&e._fromLocation&&!r.maskedLocation&&this.staticLocations.set(e,r),r},this.commitLocation=async({viewTransition:e,ignoreBlocker:t,...n})=>{let r=n.maskedLocation??n;if(r.external)return ir(this,r.publicHref,{replace:n.replace,ignoreBlocker:t});let i,a=Nt(this.latestLocation.href)===Nt(n.href)&&vt(er(n.state),er(this.latestLocation.state)),o=this._commitPromise,s,c=new Promise(e=>{s=e});if(c.resolve=()=>{s(),o?.resolve()},this._commitPromise=c,a)this.load();else{let{maskedLocation:r,hashScrollIntoView:a,...o}=n;r&&(o={...r,state:{...r.state,__tempKey:void 0,__tempLocation:{...o,search:o.searchStr,state:{...o.state,__tempKey:void 0,__tempLocation:void 0,__TSR_key:void 0,key:void 0}}}},(o.unmaskOnReload??this.options.unmaskOnReload??!1)&&(o.state.__tempKey=this.tempLocationKey)),o.state={...o.state,__hashScrollIntoViewOptions:a??this.options.defaultHashScrollIntoView??!0},this.shouldViewTransition=e,i=n.replace?`REPLACE`:`PUSH`,this.history[i===`REPLACE`?`replace`:`push`](o.publicHref,o.state,{ignoreBlocker:t}),this.history.subscribers.size||this.load({action:{type:i}})}return this._scroll.next=n.resetScroll??!0,this._commitPromise},this.buildAndCommitLocation=({replace:e,resetScroll:t,hashScrollIntoView:n,viewTransition:r,ignoreBlocker:i,...a}={})=>{let o=this.buildLocation({...a,_includeValidateSearch:!0});this._pendingLocation=o;let s=this.commitLocation({...o,viewTransition:r,replace:e,resetScroll:t,hashScrollIntoView:n,ignoreBlocker:i});return queueMicrotask(()=>{this._pendingLocation===o&&(this._pendingLocation=void 0)}),s},this.navigate=async({to:e,reloadDocument:t,href:n,publicHref:r,...i})=>{let a=n?wt(n):void 0;if(a||t){if(e!==void 0||!n){let t=this.buildLocation({to:e,...i}),a=t.maskedLocation??t;n??=a.publicHref,r??=a.publicHref}let t=!a&&r?r:n;return ir(this,t,i)}return this.buildAndCommitLocation({...i,href:n,to:e,_isNavigate:!0})},this.load=async e=>{this.updateLatestLocation(),e?.action&&(this._scroll.hash=e.action.type===`PUSH`||e.action.type===`REPLACE`),await ii(this,e)},this.startViewTransition=e=>{let t=this.shouldViewTransition??this.options.defaultViewTransition;if(this.shouldViewTransition=void 0,t&&typeof document.startViewTransition==`function`){let n;if(typeof t==`object`&&window.CSS?.supports?.(`selector(:active-view-transition-type(a))`)){let r=this.latestLocation,i=this.stores.resolvedLocation.get(),a=typeof t.types==`function`?t.types($n(r,i)):t.types;if(a===!1)return e();n={update:e,types:a}}else n=e;return document.startViewTransition(n).updateCallbackDone}return e()},this.invalidate=e=>{let t=this._committed,n=e?.filter,r=this._preloads,i=new Set,a=e=>{(!n||n(e))&&i.add(e.id)};t.forEach(a),this._cache.forEach(a),r?.forEach(e=>e.forEach(a)),this._tx?.[3].forEach(a);let o=[];for(let[e,t]of r??[])t.some(e=>i.has(e.id))&&(r.delete(e),o.push(e));let s=t=>{if(i.has(t.id)){let n=this.routesById[t.routeId],r={...t,invalid:!0,...(e?.forcePending||t.status===`error`||t.status===`notFound`)&&Qn(n)?{status:`pending`,error:void 0}:void 0};return t._flight=void 0,r}return t};this._committed=t.map(s);for(let[t,n]of this._cache)i.has(t)&&(n.invalid=!0,e?.forcePending&&(n.status=`pending`));for(let e of i)this._flights?.delete(e);for(let e of o)e.abort();return this.shouldViewTransition=!1,this.load({sync:e?.sync})},this.resolveRedirect=e=>{let t=e.options,n=e.headers.get(`Location`)||t.href;if(!n){let e=this.buildLocation(t);n=(e.maskedLocation??e).publicHref||`/`}let r;if(Tt.test(n)||(r=wt(n))&&!this.protocolAllowlist.has(r))throw Error(`Redirect blocked: unsafe protocol`);if(r===`http:`||r===`https:`){let e=new URL(n);e.pathname.startsWith(`//`)?n=e.href:Xn(e,this.origin)||(n=Zn(e),r=void 0)}return r&&(t.reloadDocument=!0),t.href=n,e.headers.set(`Location`,n),e},this.clearCache=e=>{let t=this._cache,n=this._preloads,r=e?.filter,i=[],a=[];for(let[e,n]of t)(!r||r(n))&&(a.push(e),i.push(n));let o=[];for(let[e,t]of n??[])(!r||t.some(r))&&(o.push(e),i.push(...t));for(let e of a)t.delete(e);for(let e of o)n.delete(e);for(let e of i){let t=e._flight;e._flight=void 0,t&&!--t[2]&&(this._flights?.get(e.id)===t&&this._flights.delete(e.id),o.push(t[1]))}for(let e of o)e.abort()},this.loadRouteChunk=_r,this.preloadRoute=e=>ai(this,e),this.matchRoute=(e,t)=>{let n={...e,to:e.to?It(e.from||``,e.to,this.options.trailingSlash,this.resolvePathCache):void 0,params:e.params||{},leaveParams:!0},r=this.buildLocation(n),i=this.stores.status.get()===`pending`;if(t?.pending&&!i)return!1;let a=t?.pending??!i?this.latestLocation:this.stores.resolvedLocation.get()||this.stores.location.get(),o=Cn(r.pathname,t?.caseSensitive??!1,t?.fuzzy??!1,a.pathname,this.processedTree);return!o||e.params&&!vt(o.rawParams,e.params,!0)?!1:t?.includeSearch??!0?vt(a.search,r.search,!0)?o.rawParams:!1:o.rawParams},this.getStoreConfig=t,e.pathParamsAllowedCharacters?.length&&(this.pathParamsDecoder=Lt(e.pathParamsAllowedCharacters)),this.update({defaultPreloadDelay:50,defaultPendingMs:1e3,defaultPendingMinMs:500,context:void 0,...e,caseSensitive:e.caseSensitive??!1,notFoundMode:e.notFoundMode??`fuzzy`,stringifySearch:e.stringifySearch??sn,parseSearch:e.parseSearch??on,protocolAllowlist:e.protocolAllowlist??Ct}),self.__TSR_ROUTER__=this}isShell(){return!!this.options.isShell}get state(){return this.stores.__store.get()}setRoutes(e){Object.assign(this,e),this.lightweightCache=new WeakMap,this.staticLocations=new WeakMap;let t=this.options.notFoundRoute;t&&(t.init(99999999999),this.routesById[t.id]!==t&&(t._interpolation=vn(!1,t,0)),this.routesById[t.id]=t)}matchRoutesInternal(e,t){let[n,r,i]=this.getMatchedRoutes(e.pathname),a=n,o=!1;(i?i.path!==`/`&&r[`**`]:Nt(e.pathname))&&(this.options.notFoundRoute?a=[...a,this.options.notFoundRoute]:o=!0);let s=o?pr(this.options.notFoundMode,a):void 0,c=Array(a.length),l=this._committed,u=(e,t)=>{let n=l[t];return n?.routeId===e.id?n:e===this.options.notFoundRoute?l.find(t=>t.routeId===e.id):void 0},d;for(let n=0;ntypeof t!=`string`&&!ft.call(e,t[1]))}var ur=Object.freeze({});function dr(e,t){let n=[];for(let r=0;r{let n=t(i.preSearchFilters?i.preSearchFilters.reduce((e,t)=>t(e),e):e);return i.postSearchFilters?i.postSearchFilters.reduce((e,t)=>t(e),n):n});let a=i.validateSearch;t&&a&&n.push(({search:e,next:t,meta:n})=>{let r=t(e);try{let e=sr(a,r);if(n&&e)for(let t in e)t in r||(n.defaulted||=new Map).set(t,e[t]);return{...r,...e}}catch{}return r})}return n}function fr(e,t,n){let r=(t,i,a)=>{if(t>=e.length){if(!n.search)return{};if(n.search===!0)return i;let e=dt(n.search,i);return a&&(a.explicit=e),e}return e[t]({search:i,next:(e,n)=>{if(n){let n=a||{};return{search:r(t+1,e,n),meta:n}}return r(t+1,e,a)},meta:a})};return r(0,t)}function pr(e,t){if(e!==`root`){let e;for(let n=t.length-1;n>=0;n--){let r=t[n];if(r.options.notFoundComponent)return r.id;e||=r.children&&r.id}if(e)return e}return un}function mr(e,t){let n=e.options.params?.parse??e.options.parseParams;n&&Object.assign(t,n(t))}function hr(e,t){return e.options[t]?.preload?.()}function gr(e,t){let n=hr(e,`component`),r=hr(e,`pendingComponent`);return t&&(r?r=r.then(t):t()),n&&r?Promise.all([n,r]).then(()=>{}):n??r}function _r(e,t,n){let r=()=>t===!1?void 0:t?hr(e,t):gr(e,n),i=e._lazy;if(i)return i===!0?r():i.then(r);if(!e.lazyFn)return r();let a=e.lazyFn().then(t=>{{let{id:n,...r}=t.options;Object.assign(e.options,r),e._lazy=!0}},t=>{throw e._lazy=void 0,t});return e._lazy=a,a.then(r)}function vr(e){let t=e.findIndex(e=>e.status!==`success`||e._notFound)+1;return t&&t{let i=()=>r(t);t.addEventListener(`abort`,i,{once:!0}),Promise.resolve(e).then(n,r).then(()=>t.removeEventListener(`abort`,i))})}function Er(e,t){return e.routesById[t.routeId]}function Dr(e,t,n){return fn(e)?[Sr,e]:Vt(e)?(e.routeId||=n,[xr,e]):t?(typeof e?.then==`function`&&(e=Error(`A Promise was thrown`,{cause:e})),[br,e]):[yr,e]}function Or(e,t){let n=Dr(t,!0,e.id);if(n[0]!==br)return n;try{e.options.onError?.(n[1])}catch(t){n=Dr(t,!0,e.id)}return n}function kr(e,t,n,r,i){return i[0].signal.aborted?Cr:Gr(e,t,n,Or(n,r),i)}async function Ar(e,t,n,r,i,a){let[o,s]=t,c=n[0].signal,l=!!n[3];for(let i=n[6]??0;ie.navigate({...t,_fromLocation:o}),buildLocation:e.buildLocation,cause:l?`preload`:r.cause,abortController:n[0],preload:l,matches:s,routeId:u.id};try{let e=r._ctx||=u.options.context?u.options.context({...f,deps:r.loaderDeps,context:d})||{}:void 0;r.context={...d,...e}}catch(a){return Mr(e,r),[i,kr(e,t,u,a,n)]}if(c.aborted)return[i,Cr];let p=r.paramsError??r.searchError;if(p!==void 0)return Mr(e,r),[i,kr(e,t,u,p,n)];let m=u.options.beforeLoad;if(!m)continue;let h=r.status;i>=a&&(r.status=`pending`,n[7]?.());try{Fr(e,r,`beforeLoad`,n[0]);let a=m({...f,search:r.search,context:r.context,...e.options.additionalContext}),o=await(typeof a?.then==`function`?Tr(a,c):a);if(c.aborted)return[i,Cr];let s=Gr(e,t,u,Dr(o,!1,u.id),n);if(s[0]!==yr)return Mr(e,r),[i,s];r.context={...r.context,...o}}catch(a){return Mr(e,r),[i,kr(e,t,u,a,n)]}finally{r.status=h,Fr(e,r,!1,n[0])}}i()}function jr(e,t,n){if(!(!n||--n[2])){if(e._flights?.get(t.id)===n){let n=e._tx;if(n&&!n[0].signal.aborted&&!n[3].includes(t)&&n[3].some(e=>e.id===t.id)&&n[3].some(e=>e.isFetching===`beforeLoad`))return;e._flights.delete(t.id)}return n[1]}}function Mr(e,t){let n=t._flight;t._flight=void 0,jr(e,t,n)?.abort()}function Nr(e,t,n,r){let i=[];for(let a of t)if(!n?.includes(a)){let t=a._flight;if(a._flight=void 0,r&&t?.[2]===1&&e._flights?.get(a.id)===t&&n?.some(e=>e.id===a.id))t[2]=0;else{let n=jr(e,a,t);n&&i.push(n)}}for(let e of i)e.abort()}function Pr(e){for(let t of e){let e=t._flight;e&&e[2]++}}function Fr(e,t,n,r){if(t.isFetching=n,r&&e._tx?.[0]!==r)return;let i=e.stores.byRoute.get(t.routeId),a=i?.get();a?.id===t.id&&i.set({...a,isFetching:n})}function Ir(e,t,n,r,i,a,o){let s=t[0];return{params:n.params,location:s,navigate:t=>e.navigate({...t,_fromLocation:s}),cause:o?`preload`:n.cause,abortController:i,preload:o,deps:n.loaderDeps,parentMatchPromise:a,context:n.context,route:r,...e.options.additionalContext}}async function Lr(e,t,n,r,i,a,o){let s=o[0],c=s.signal;if(c.aborted)return Cr;if(!i)return[yr,void 0];let l=n._flight;Fr(e,n,`loader`,s);try{if(!l){let s=new AbortController;l=[Promise.resolve().then(()=>i(Ir(e,t,n,r,s,a,!!o[3]))).then(e=>Dr(e,!1,r.id),e=>Dr(e,!0,r.id)).then(t=>(t[0]!==yr&&e._flights?.get(n.id)===l&&(e._flights.delete(n.id),l[2]||s.abort()),t[0]===br&&l[2]?Or(r,t[1]):t)),s,1],(e._flights??=new Map).set(n.id,l)}return n._flight=l,n.abortController=l[1],Gr(e,t,r,await Tr(l[0],c),o)}catch(t){if(t!==c||!c.aborted)throw t;return Mr(e,n),Cr}finally{Fr(e,n,!1,s)}}function Rr(e,t,n){t[0]!==Sr&&(e.status=`success`,e.error=void 0,t[0]===yr?(e.loaderData=t[1],e.invalid=!1,e.updatedAt=Date.now(),e.preload=n):e.invalid=!0)}function zr(e,t,n){let r=e._cache.get(t.id);if(r!==n||e._committed.some(e=>e.id===t.id&&e._flight===t._flight))return;let i={...t,_notFound:void 0,context:{}};i._flight&&i._flight[2]++,e._cache.set(t.id,i),r&&Mr(e,r)}function Br(e,t){return t[0]===br||t[0]===xr?{...e,status:t[0]===br?`error`:`notFound`,error:t[1],_flight:void 0}:e}function Vr(e,t,n,r,i,a,o){let s=t[1][n],c=Er(e,s),l=!!a[3],u=e._cache.get(s.id),d,f=!1,p;try{if(s.status===`success`&&(d=c.options.shouldReload,typeof d==`function`&&(d=d(Ir(e,t,s,c,a[0],i,l))),a[0].signal.aborted&&(p=Cr)),!p){if(s.status!==`success`)f=!0;else{let t=l||s.preload?c.options.preloadStaleTime??e.options.defaultPreloadStaleTime??3e4:c.options.staleTime??e.options.defaultStaleTime??0;f=!!(s.invalid||d||d===void 0&&Date.now()-s.updatedAt>=t&&(a[5]||s.cause===`enter`||a[2].some(e=>e.routeId===s.routeId&&e.id!==s.id)))}}}catch(n){s.invalid=!0,Mr(e,s),p=kr(e,t,c,n,a)}let m=c.options.loader,h=typeof m==`function`,g=h?m:m?.handler,_=!l||c.options.preload!==!1,v=_&&m?e._flights?.get(s.id):void 0;v===s._flight||p?v=void 0:v&&!f&&!l&&d===void 0?f=!0:f||(v=void 0);let y=!(!m||!f||s.status!==`success`||l||a[4]||((h?void 0:m.staleReloadMode)??e.options.defaultStaleReloadMode)===`blocking`),b=f&&_,x=b&&!y&&(s.status!==`success`||!!m),S=n>=o?a[7]:void 0,C=c.lazyFn&&c._lazy!==!0?S:void 0;if(b&&!m&&(s.invalid=!1,s.updatedAt=Date.now()),v&&v[2]++,x){let t=s._flight;s._flight=v,jr(e,s,t)?.abort(),n>=o&&(s.status=`pending`),S?.()}b||(s.isFetching=!1);let w=!p&&x?Lr(e,t,s,c,g,i,a).then(t=>(Rr(s,t,l),t[0]===yr&&(m&&!a[0].signal.aborted&&zr(e,s,u),n>=o&&(s.status=`pending`)),t)):Promise.resolve(p??[yr,s.loaderData]),T=(async()=>{try{let e=_r(c,void 0,C);e&&await Tr(e,a[0].signal)}catch(r){if(!t[1].some((e,t)=>t<=n&&(e.status===`error`||e.status===`notFound`||e._notFound)))return[n,kr(e,t,c,r,a)]}let r=await w;x&&r[0]===yr&&s.status===`pending`&&!a[0].signal.aborted&&(s.status=`success`,S?.())})();if(r.push([n,w,T]),!y)return w.then(e=>Br(s,e));let ee={...s,status:`pending`,preload:!1,_flight:v};s.invalid=!1,s.isFetching=`loader`;let E=Lr(e,t,ee,c,g,i,a).then(e=>(s.isFetching=!1,Rr(ee,e,!1),e));return(t[2]??=[]).push([n,E,T,ee]),E.then(e=>Br(ee,e))}async function Hr(e,t,n,r,i=0){let a=n?.[1][1],o=a?.routeId?t.findIndex(e=>e.routeId===a.routeId):n?.[0]??t.length-1;o<0&&(o=0);for(let n=o;n>=0;n--){let i=Er(e,t[n]);try{let e=_r(i,!1);e&&await Tr(e,r)}catch(e){if(e===r&&r.aborted)throw e}if(i.options.notFoundComponent)return n}return a?.routeId?o:i}function Ur(e,t){t[2]&&=(Nr(e,t[2].map(e=>e[3])),void 0)}async function Wr(e,t,n,r){let i;try{await Promise.all(e.map(e=>e[1].then(async t=>{let a=e[0];if(!(r&&a>=await r)){if(t[0]>=Sr)throw[a,t];!i&&t[0]!==yr&&(i=[a,t],await Promise.all((n??[]).map(e=>{if(!(e[0]<=a))return e[1].then(t=>{if(t[0]===Sr)throw[e[0],t]})})))}})))}catch(e){return e}return t??i}function Gr(e,t,n,r,i,a){for(;r[0]===Sr;){let o=r[1],s=o.options;try{if((s.href||o.headers.has(`Location`))&&(e.resolveRedirect(o),s.reloadDocument)||(s.reloadDocument?i[3]:i[1]>=20))return r;let n=e.buildLocation({...s,_fromLocation:t[0],_includeValidateSearch:!0}),a=n.maskedLocation??n;if(a.external){let t=o.clone();return t.options={...s},t.headers.set(`Location`,a.publicHref),e.resolveRedirect(t),i[3]?[Sr,t]:[Sr,t,a]}return[Sr,o,n]}catch(e){r=a?[br,e]:Or(n,e),a=!0}}return r}async function Kr(e,t,n,r,i,a){let o=t[1],s=await i,c=!1,l=o.findIndex(e=>e._notFound),u=t=>t[1][0]===xr?Hr(e,o,t,r.signal):t[0],d=l<0?o.length:l;if((s?.[1][0]??0)>=Sr)d=0;else if(s){d=s[2]??=await u(s);for(let e of n){if(e[0]>=d)break;let t=await e[1];if(t[0]!==yr&&t[0]=d)break;let t=await e[2];if(t){s=t;break}}if((s?.[1][0]??0)>=Sr){let n=s[1];if(n[0]!==Sr||n[1].options.reloadDocument||n[2])return Ur(e,t),n;c=!0,s=[0,[br,Error(`Too many redirects`)]]}let f=s?s[2]??await u(s):l;if(f>=0){let i=s?.[1],l=i?.[0],u=o[f],d=i?.[1],p=()=>{i&&(u._notFound=void 0,l===br?u.status=`error`:(d.routeId=u.routeId,u.routeId===e.routeTree.id?(u.status=`success`,u._notFound=!0):u.status=`notFound`),u.error=d,u.isFetching=!1)};p(),i||a?.();let m=Er(e,u);try{await Tr(i?Promise.resolve().then(()=>_r(m,l===br?`errorComponent`:`notFoundComponent`)):Promise.all([_r(m),_r(m,`notFoundComponent`)]),r.signal)}catch(n){if(n===r.signal&&r.signal.aborted)return Ur(e,t),Cr}i?c&&(r.abort(),await Promise.all([...n.map(e=>e[1]),...n.map(e=>e[2]),...(t[2]??[]).map(e=>e[1])]),Ur(e,t),Nr(e,o),p()):u.status=`success`}return t}async function qr(e,t,n,r=0,i=t[1].length){let a=t[1];for(let t=r;te._notFound);if(e.options.notFoundMode!==`root`&&s>=0){let t=await Hr(e,n,void 0,a,s);n[s]._notFound=void 0,n[t]._notFound=!0,s=t}let c=s<0?n.length:s+1,l=0;for(;l{for(let t=d;t=Sr&&(c=0);p()}if(!a.aborted&&!r[3]){let t=[];for(let[n,r]of e._flights??[])r[2]||(e._flights.delete(n),t.push(r[1]));for(let e of t)e.abort()}let h=Kr(e,i,u,r[0],Wr(u,m,i[2]),r[7]);i[2]?.length&&(i[3]=Wr(i[2],void 0,void 0,h.then(e=>wr(e)?0:vr(n).length,()=>0))),o=await h}catch(t){if(Ur(e,i),t===a&&a.aborted)return Cr;throw t}return wr(o)?o:qr(e,o,a,r[6]===n.length?r[6]:0)}function Yr(e,t){if(e._tx!==t)return;let n=t[3],r=e.stores.matches.get(),i=e._pending;for(let a=0;a0){i[3]=setTimeout(()=>Yr(e,t),n);return}i[2]=0}let m=n.map(e=>({...e,_flight:void 0}));m[a].status=`pending`;let h=i[4]=e.startTransition(()=>e.stores.setMatches(m),m).then(t=>(t&&e._pending===i&&i[4]===h&&!i[2]&&(i[2]=Date.now()+f),t));return}}function Xr(e,t){let n=e._pending;(e._tx===t||!e._tx?.[3].some(e=>e.id===n?.[1]))&&(clearTimeout(n?.[3]),e._pending=void 0)}async function Zr(e,t){let n=e._pending;if(!n)return;clearTimeout(n[3]);let r=n[2]-Date.now();if(!n[4]||r<=0||!vr(t[3]).some(e=>e.id===n[1]))return;let i;try{await Tr(new Promise(e=>{i=setTimeout(e,r)}),t[0].signal)}catch{}clearTimeout(i)}function Qr(e,t){e._committed=t,e.stores.setMatches(t)}function $r(e,t,n,r){let i=e._committed,a=e._lifecycleEnd,o=e._cache;for(let e of n)e.preload=!1,r&&(e._assetEnd=void 0);let s=vr(n).length,c=new Map;{let t=Date.now(),r=new Set;for(let e=0;e=(n.preload?i.options.preloadGcTime??e.options.defaultPreloadGcTime??3e5:i.options.gcTime??e.options.defaultGcTime??3e5)||c.set(n.id,o.get(n.id)===n?n:{...n,_flight:void 0,isFetching:!1,context:{}})}}t[3]=[],e._cache=c;let l=e._lifecycleEnd=tr(n);Qr(e,n),Nr(e,[...o.values(),...i].filter(e=>e._flight&&c.get(e.id)!==e),n),nr(e,i,n,a,l,t)}async function ei(e,t){let n=e._tx;for(;n&&n!==t;)t=n,await n[5],n=e._tx}function ti(e,t,n){let r=n[1].options,i=n[2];if(!i)return e.navigate({...r,replace:!0,ignoreBlocker:!0});if(r.reloadDocument)return e.navigate({href:(i.maskedLocation??i).publicHref,reloadDocument:!0,replace:!0,ignoreBlocker:!0});i._redirects=t[1]+1,e._pendingLocation=i;let a=e.commitLocation({...i,viewTransition:r.viewTransition,replace:!0,resetScroll:r.resetScroll,hashScrollIntoView:r.hashScrollIntoView,ignoreBlocker:!0});return queueMicrotask(()=>{e._pendingLocation===i&&(e._pendingLocation=void 0)}),a}async function ni(e,t,n,r,i){let a=n.map(e=>({...e}));Pr(a);for(let t of r)Mr(e,a[t[0]]),a[t[0]]=t[3];let o=[t[2],a],s;try{s=await Kr(e,o,r,t[0],i)}catch(t){throw Nr(e,a),t}if(wr(s)){Nr(e,a),s[0]===Sr&&e._tx===t&&e._committed===n&&await ti(e,t,s);return}if(await qr(e,s,t[0].signal),e._tx!==t||e._committed!==n){Nr(e,a);return}for(let t of a){let n=e._cache.get(t.id);n?._flight&&n._flight===t._flight&&(e._cache.delete(t.id),Mr(e,n))}Qr(e,a),Nr(e,n,a)}async function ri(e,t,n,r,i,a){let o=await Jr(e,t[2],t[3],[t[0],t[1],e._committed,void 0,i,n,a,r]);if(wr(o)){let n=o[0]===Sr&&e._tx===t;if((!n||o[1].options.reloadDocument)&&Xr(e,t),Nr(e,t[3]),t[3]=[],!n)return;if(e._tx!==t){Xr(e,t);return}await ti(e,t,o);return}let s=o[1];if(e._tx===t&&await Zr(e,t),e._tx!==t){Xr(e,t),Nr(e,s),Ur(e,o);return}let c=t[2],l=$n(c,e.stores.resolvedLocation.get()),u=o[2];await e.startViewTransition(async()=>{if(e._tx===t&&await Zr(e,t),e._tx!==t){Xr(e,t),Nr(e,s),Ur(e,o);return}let n=await e.startTransition(()=>{Xr(e,t),$r(e,t,s,a),e._tx===t&&(e.emit({type:`onLoad`,...l}),e._tx===t&&e.emit({type:`onBeforeRouteMount`,...l}))},s);if(e._tx!==t){Ur(e,o);return}u?.length&&ni(e,t,s,u,o[3]).catch(console.error),e.batch(()=>{e.stores.resolvedLocation.set(c),e.stores.status.set(`idle`),e._tx===t&&e.emit({type:`onResolved`,...l}),n&&e._tx===t&&e.emit({type:`onRendered`,...l})}),e._tx===t&&(e._commitPromise?.resolve(),e._commitPromise=void 0)})}async function ii(e,t){let n=e._tx,r=e.stores.resolvedLocation.get(),i=r??e.stores.location.get(),a=e.latestLocation,o=e._pendingLocation,s=o?.href===a.href?o._redirects??0:0,c=e._handoff,l=c?.[0](),u=new AbortController,d=e._preflight;if(e._preflight=u,l||c?.[1](),d?.abort(),!u.signal.aborted){let t=$n(a,r);e.emit({type:`onBeforeNavigate`,...t}),u.signal.aborted||e.emit({type:`onBeforeLoad`,...t})}if(u.signal.aborted){await ei(e,n);return}let f=i.href===a.href,p=u,m=e.matchRoutes(a,{_controller:u});Pr(m);let h=l?c[1](m):void 0;if(h?p=l:l?.abort(),u.signal.aborted){Nr(e,m),await ei(e,n);return}e._preflight=void 0;let g,_=()=>ri(e,y,f,()=>Yr(e,y),t?.sync,h),v=t?.sync?new Promise(e=>g=e):Promise.resolve().then(_),y=[p,s,a,m,Date.now(),v.then(()=>ei(e,y))];if(e._tx=y,n){for(let t of e.stores.matches.get()){if(e._tx!==y)break;t.isFetching&&Fr(e,t,!1)}n[0].abort(),Nr(e,n[3],y[3],!0)}if(e._tx!==y){Nr(e,y[3]),y[3]=[],g?.(),await ei(e,y);return}e.batch(()=>{e.stores.status.set(`pending`),e.stores.location.set(a)}),(h||!e._committed.length&&m[0]?.status!==`success`&&!m.some(e=>e._notFound))&&Yr(e,y),g?.(_()),await y[5]}async function ai(e,t){let n=e.buildLocation(t);for(let t=0;;t++){let r=e._committed,i=new AbortController,a,o,s;try{try{a=e.matchRoutes(n,{_controller:i}),Pr(a),o=(e._preloads??=new Map).set(i,a),s=await Jr(e,n,a,[i,t,r,!0])}finally{o&&(o=o.delete(i),Nr(e,a)),i.abort()}if(!wr(s))return s[1];if(!o||s.length<3)return;n=s[2]}catch(e){Vt(e)||console.error(e);return}}}var oi=`Error preloading route! ☝️`,si=class{get to(){return this._to}get id(){return this._id}get path(){return this._path}get fullPath(){return this._fullPath}constructor(e){if(this.init=e=>{this.originalIndex=e,this._branch=void 0;let t=this.options,n=!t?.path&&!t?.id;this.parentRoute=this.options.getParentRoute?.(),n?this._path=un:this.parentRoute||At();let r=n?un:t?.path;r&&r!==`/`&&(r=Mt(r));let i=t?.id||r,a=n?un:jt((this.parentRoute.id===`__root__`?``:this.parentRoute.id)+`/`+(i??``));r===`__root__`&&(r=`/`);let o=a===`__root__`?`/`:r===void 0?this.parentRoute.fullPath:jt(this.parentRoute.fullPath+`/`+r);this._path=r,this._id=a,this._fullPath=o,this._to=Nt(o)},this.addChildren=e=>this._addFileChildren(e),this._addFileChildren=e=>(Array.isArray(e)&&(this.children=e),typeof e==`object`&&e&&(this.children=Object.values(e)),this),this._addFileTypes=()=>this,this.updateLoader=e=>(Object.assign(this.options,e),this),this.update=e=>(Object.assign(this.options,e),this),this.lazy=e=>(this.lazyFn=e,this),this.redirect=e=>dn({from:this.fullPath,...e}),this.options=e||{},this.isRoot=!e?.getParentRoute,e?.id&&e?.path)throw Error(`Route cannot have both an 'id' and a 'path' option.`)}},ci=class extends si{constructor(e){super(e)}},li=class extends m.Component{constructor(...e){super(...e),this.state={error:0},this.reset=()=>{this.setState({error:0})}}static getDerivedStateFromProps(e,t){let n=e.getResetKey();return t.error&&t.resetKey!==n?{resetKey:n,error:0}:{resetKey:n}}static getDerivedStateFromError(e){return{error:[e]}}componentDidCatch(e,t){this.props.onCatch?.(e,t)}render(){let e=this.state.error;return e?m.createElement(this.props.errorComponent??ui,{error:e[0],reset:this.reset}):this.props.children}};function ui({error:e}){let[t,n]=m.useState(!1);return(0,h.jsxs)(`div`,{style:{padding:`.5rem`,maxWidth:`100%`},children:[(0,h.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:`.5rem`},children:[(0,h.jsx)(`strong`,{style:{fontSize:`1rem`},children:`Something went wrong!`}),(0,h.jsx)(`button`,{style:{appearance:`none`,fontSize:`.6em`,border:`1px solid currentColor`,padding:`.1rem .2rem`,fontWeight:`bold`,borderRadius:`.25rem`},onClick:()=>n(e=>!e),children:t?`Hide Error`:`Show Error`})]}),(0,h.jsx)(`div`,{style:{height:`.25rem`}}),t?(0,h.jsx)(`div`,{children:(0,h.jsx)(`pre`,{style:{fontSize:`.7em`,border:`1px solid red`,borderRadius:`.25rem`,padding:`.3rem`,color:`red`,overflow:`auto`},children:e?.message?(0,h.jsx)(`code`,{children:e.message}):null})}):null]})}var di=()=>!0,fi=()=>!1;function pi({children:e,fallback:t=null}){return(0,h.jsx)(m.Fragment,{children:mi()?e:t})}function mi(e=!0){return m.useSyncExternalStore(hi,di,e?fi:di)}function hi(){return()=>{}}var gi=m.createContext(null);function _i(e){return m.useContext(gi)}var vi=m.createContext(void 0),yi=m.createContext(void 0);function bi({update:e,notify:t,unwatched:n}){return{link:r,unlink:i,propagate:a,checkDirty:o,shallowPropagate:s};function r(e,t,n){let r=t.depsTail;if(r!==void 0&&r.dep===e)return;let i=r===void 0?t.deps:r.nextDep;if(i!==void 0&&i.dep===e){i.version=n,t.depsTail=i;return}let a=e.subsTail;if(a!==void 0&&a.version===n&&a.sub===t)return;let o=t.depsTail=e.subsTail={version:n,dep:e,sub:t,prevDep:r,nextDep:i,prevSub:a,nextSub:void 0};i!==void 0&&(i.prevDep=o),r===void 0?t.deps=o:r.nextDep=o,a===void 0?e.subs=o:a.nextSub=o}function i(e,t=e.sub){let r=e.dep,i=e.prevDep,a=e.nextDep,o=e.nextSub,s=e.prevSub;return a===void 0?t.depsTail=i:a.prevDep=i,i===void 0?t.deps=a:i.nextDep=a,o===void 0?r.subsTail=s:o.prevSub=s,s===void 0?(r.subs=o)===void 0&&n(r):s.nextSub=o,a}function a(e){let n=e.nextSub,r;top:do{let i=e.sub,a=i.flags;if(a&60?a&12?a&4?!(a&48)&&c(e,i)?(i.flags=a|40,a&=1):a=0:i.flags=a&-9|32:a=0:i.flags=a|32,a&2&&t(i),a&1){let t=i.subs;if(t!==void 0){let i=(e=t).nextSub;i!==void 0&&(r={value:n,prev:r},n=i);continue}}if((e=n)!==void 0){n=e.nextSub;continue}for(;r!==void 0;)if(e=r.value,r=r.prev,e!==void 0){n=e.nextSub;continue top}break}while(1)}function o(t,n){let r,i=0,a=!1;top:do{let o=t.dep,c=o.flags;if(n.flags&16)a=!0;else if((c&17)==17){if(e(o)){let e=o.subs;e.nextSub!==void 0&&s(e),a=!0}}else if((c&33)==33){(t.nextSub!==void 0||t.prevSub!==void 0)&&(r={value:t,prev:r}),t=o.deps,n=o,++i;continue}if(!a){let e=t.nextDep;if(e!==void 0){t=e;continue}}for(;i--;){let i=n.subs,o=i.nextSub!==void 0;if(o?(t=r.value,r=r.prev):t=i,a){if(e(n)){o&&s(i),n=t.sub;continue}a=!1}else n.flags&=-33;n=t.sub;let c=t.nextDep;if(c!==void 0){t=c;continue top}}return a}while(1)}function s(e){do{let n=e.sub,r=n.flags;(r&48)==32&&(n.flags=r|16,(r&6)==2&&t(n))}while((e=e.nextSub)!==void 0)}function c(e,t){let n=t.depsTail;for(;n!==void 0;){if(n===e)return!0;n=n.prevDep}return!1}}function xi(e,t,n){let r=typeof e==`object`,i=r?e:void 0;return{next:(r?e.next:e)?.bind(i),error:(r?e.error:t)?.bind(i),complete:(r?e.complete:n)?.bind(i)}}var Si=[],Ci=0,{link:wi,unlink:Ti,propagate:Ei,checkDirty:Di,shallowPropagate:Oi}=bi({update(e){return e._update()},notify(e){Si[Ai++]=e,e.flags&=-3},unwatched(e){e.depsTail!==void 0&&(e.depsTail=void 0,e.flags=17,Pi(e))}}),ki=0,Ai=0,ji,Mi=0;function Ni(e){try{++Mi,e()}finally{--Mi||Fi()}}function Pi(e){let t=e.depsTail,n=t===void 0?e.deps:t.nextDep;for(;n!==void 0;)n=Ti(n,e)}function Fi(){if(!(Mi>0)){for(;ki{i.get(),n.current?t.next?.(i._snapshot):n.current=!0});return{unsubscribe:()=>{r.stop()}}},_update(e){let a=ji,o=t?.compare??Object.is;if(n)ji=i,++Ci,i.depsTail=void 0;else if(e===void 0)return!1;n&&(i.flags=5);try{let t=i._snapshot,a=typeof e==`function`?e(t):e===void 0&&n?r(t):e;return t===void 0||!o(t,a)?(i._snapshot=a,!0):!1}finally{ji=a,n&&(i.flags&=-5),Pi(i)}}};return n?(i.flags=17,i.get=function(){let e=i.flags;if(e&16||e&32&&Di(i.deps,i)){if(i._update()){let e=i.subs;e!==void 0&&Oi(e)}}else e&32&&(i.flags=e&-33);return ji!==void 0&&wi(i,ji,Ci),i._snapshot}):i.set=function(e){if(i._update(e)){let e=i.subs;e!==void 0&&(Ei(e),Oi(e),Fi())}},i}function Li(e){let t=()=>{let t=ji;ji=n,++Ci,n.depsTail=void 0,n.flags=6;try{return e()}finally{ji=t,n.flags&=-5,Pi(n)}},n={deps:void 0,depsTail:void 0,subs:void 0,subsTail:void 0,flags:6,notify(){let e=this.flags;e&16||e&32&&Di(this.deps,this)?t():this.flags=2},stop(){this.flags=0,this.depsTail=void 0,Pi(this)}};return t(),n}var Ri=n((e=>{var t=l();function n(e,t){return e===t&&(e!==0||1/e==1/t)||e!==e&&t!==t}var r=typeof Object.is==`function`?Object.is:n,i=t.useState,a=t.useEffect,o=t.useLayoutEffect,s=t.useDebugValue;function c(e,t){var n=t(),r=i({inst:{value:n,getSnapshot:t}}),c=r[0].inst,l=r[1];return o(function(){c.value=n,c.getSnapshot=t,u(c)&&l({inst:c})},[e,n,t]),a(function(){return u(c)&&l({inst:c}),e(function(){u(c)&&l({inst:c})})},[e]),s(n),n}function u(e){var t=e.getSnapshot;e=e.value;try{var n=t();return!r(e,n)}catch{return!0}}function d(e,t){return t()}var f=typeof window>`u`||window.document===void 0||window.document.createElement===void 0?d:c;e.useSyncExternalStore=t.useSyncExternalStore===void 0?f:t.useSyncExternalStore})),zi=n(((e,t)=>{t.exports=Ri()})),Bi=n((e=>{var t=l(),n=zi();function r(e,t){return e===t&&(e!==0||1/e==1/t)||e!==e&&t!==t}var i=typeof Object.is==`function`?Object.is:r,a=n.useSyncExternalStore,o=t.useRef,s=t.useEffect,c=t.useMemo,u=t.useDebugValue;e.useSyncExternalStoreWithSelector=function(e,t,n,r,l){var d=o(null);if(d.current===null){var f={hasValue:!1,value:null};d.current=f}else f=d.current;d=c(function(){function e(e){if(!a){if(a=!0,o=e,e=r(e),l!==void 0&&f.hasValue){var t=f.value;if(l(t,e))return s=t}return s=e}if(t=s,i(o,e))return t;var n=r(e);return l!==void 0&&l(t,n)?(o=e,t):(o=e,s=n)}var a=!1,o,s,c=n===void 0?null:n;return[function(){return e(t())},c===null?void 0:function(){return e(c())}]},[t,n,r,l]);var p=a(e,d[0],d[1]);return s(function(){f.hasValue=!0,f.value=p},[p]),u(p),p}})),Vi=n(((e,t)=>{t.exports=Bi()}))();function Hi(e,t){return e===t}function Ui(e,t=e=>e,n){let r=n?.compare??Hi,i=(0,m.useCallback)(t=>{let{unsubscribe:n}=e.subscribe(t);return n},[e]),a=(0,m.useCallback)(()=>e.get(),[e]);return(0,Vi.useSyncExternalStoreWithSelector)(i,a,a,t,r)}var Wi={};function Gi(e,t){let n=m.useRef();return r=>{let i=e?.select?e.select(r):r;return e?.structuralSharing??t.options.defaultStructuralSharing?n.current=gt(n.current,i):i}}function Ki(e){let t=_i(),n=m.useContext(e.from?yi:vi),r=e.from??n,i=t.stores.getMatchStore(r),a=Gi(e,t),o=Ui(i,e=>e?a(e):Wi);if(o!==Wi)return o;(e.shouldThrow??!0)&&At()}function qi(e){return Ki({from:e.from,strict:e.strict,structuralSharing:e.structuralSharing,select:t=>e.select?e.select(t.loaderData):t.loaderData})}function Ji(e){let{select:t,...n}=e;return Ki({...n,select:e=>t?t(e.loaderDeps):e.loaderDeps})}function Yi(e){return Ki({from:e.from,shouldThrow:e.shouldThrow,structuralSharing:e.structuralSharing,strict:e.strict,select:t=>{let n=e.strict===!1?t.params:t._strictParams;return e.select?e.select(n):n}})}function Xi(e){return Ki({from:e.from,strict:e.strict,shouldThrow:e.shouldThrow,structuralSharing:e.structuralSharing,select:t=>e.select?e.select(t.search):t.search})}function Zi(e){let t=_i();return m.useCallback(n=>t.navigate({...n,from:n.from??e?.from}),[e?.from,t])}function Qi(e){let t=_i(),n=Zi(),r=m.useRef(null);return lt(()=>{r.current!==e&&(n(e),r.current=e)},[t,e,n]),null}function $i(e){return Ki({...e,select:t=>e.select?e.select(t.context):t.context})}function ea(...e){let t=m.useRef(e),n=t.current;return e.forEach((e,t)=>{vt(n[t],e,!1,!0)||(n[t]=e)}),t.current}function ta(e,t){e.preloadRoute(t).catch(e=>{console.warn(e),console.warn(oi)})}var na={compare:(e,t)=>e[0]===t[0]&&e[1]===t[1]};function ra(e,t){let n=typeof e==`string`&&wt(e);if(n)return t.has(n)?e:null}function ia(e,t,n,r,i){let a=Ft(e.pathname,r),o=Ft(t.pathname,r);return(n?.exact?a!==o:!a.startsWith(o)||a.length!==o.length&&a[o.length]!==`/`)||(n?.includeSearch??!0)&&!vt(e.search,t.search,!n?.exact,n?.explicitUndefined)?!1:!n?.includeHash||i&&e.hash===t.hash}function aa(e,t,n){let r=_i(),i=m.useRef(null),a=m.useCallback(e=>{if(i.current=e,typeof t==`function`)return t(e);t&&(t.current=e)},[t]),{activeOptions:o,to:s,preload:c,preloadDelay:l,hashScrollIntoView:u,replace:d,startTransition:f,resetScroll:p,viewTransition:h,ignoreBlocker:g,disabled:_,target:v,onClick:y,onBlur:b,onFocus:x,onMouseEnter:S,onMouseLeave:C,onTouchStart:w}=e,T=mi(!!o?.includeHash),[ee,E,te]=ea(e.search,e.params,o),[D,ne]=m.useMemo(()=>[e,{...e}],[r,e.from,e._fromLocation,e.hash,e.to,ee,E,e.state,e.mask,e.unsafeRelative]),re=m.useCallback(e=>{let t=ra(s,r.protocolAllowlist);if(t!==void 0)return[t??void 0];D._fromLocation||(ne._fromLocation=e);let n=r.buildLocation(ne),i=fa(n,r,_);return[i,!_&&(!i||wt(i))?void 0:ia(e,n,te,r.basepath,T)]},[te,_,T,D,ne,r,s]),[ie,ae]=Ui(r.stores.location,re,na),oe=ae===void 0?ie:void 0,se=_||ie===void 0,ce=m.useRef(!1),le=e.reloadDocument||oe||se?!1:c??r.options.defaultPreload,ue=l??r.options.defaultPreloadDelay??0,de=m.useCallback(e=>{let t=e?.isIntersecting;if(!(t??le===`intent`)){t===!1&&P(i);return}if(!ue){ta(r,D);return}N.has(i)||N.set(i,setTimeout(()=>{N.delete(i),ta(r,D)},ue))},[r,D,i,le,ue]);m.useEffect(()=>{le===`render`&&!ce.current&&(ce.current=!0,ta(r,D));let e;return le===`viewport`&&i.current&&typeof IntersectionObserver==`function`&&(e=new IntersectionObserver(e=>de(e.pop()),{rootMargin:`100px`}),e.observe(i.current)),()=>{e?.disconnect(),P(i)}},[r,D,le,de,i]);let fe=la(e,n);if(fe.ref=t?a:i,oe)return fe.href=oe,fe;let pe=e=>{let t=v??e.currentTarget.getAttribute(`target`);!se&&!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)&&!e.defaultPrevented&&(!t||t===`_self`)&&e.button===0&&(e.preventDefault(),r.navigate({...D,replace:d,resetScroll:p,hashScrollIntoView:u,startTransition:f,viewTransition:h,ignoreBlocker:g}))},me=()=>{le===`intent`&&ta(r,D)},he=()=>{le===`intent`&&P(i)};return fe.onClick=da(y,pe),fe.onBlur=da(b,he),fe.onFocus=da(x,de),fe.onMouseEnter=da(S,de),fe.onMouseLeave=da(C,he),fe.onTouchStart=da(w,me),ua(fe,e,ae,ie,se,n)}var oa={},sa={className:`active`},ca=new Set([`to`,`params`,`search`,`hash`,`state`,`mask`,`from`,`unsafeRelative`,`_fromLocation`,`reloadDocument`,`preload`,`preloadDelay`,`preloadIntentProximity`,`hashScrollIntoView`,`replace`,`startTransition`,`resetScroll`,`viewTransition`,`ignoreBlocker`,`activeProps`,`inactiveProps`,`activeOptions`,`_asChild`]);function la(e,t){let n={};for(let r in e)ca.has(r)||r===`type`&&t!==void 0||r===`disabled`&&t===`a`||(n[r]=e[r]);return n}function ua(e,t,n,r,i,a){let{activeProps:o,inactiveProps:s,className:c,style:l,target:u}=t,d=dt(n?o:s,{})??(n?sa:oa);Object.assign(e,d),e.href=r,a!==`a`&&(e.disabled=i),e.target=u;let f=d.style;(l||f)&&(e.style=l&&f?{...l,...f}:l||f);let p=d.className;return(c||p)&&(e.className=c?p?`${c} ${p}`:c:p),i&&(e.role=`link`,e[`aria-disabled`]=!0),n&&(e[`data-status`]=`active`,e[`aria-current`]=`page`),e}var N=new WeakMap,P=e=>{clearTimeout(N.get(e)),N.delete(e)},da=(e,t)=>e?n=>n.defaultPrevented||(e(n),n.defaultPrevented||t(n)):t;function fa(e,t,n){if(n)return;let r=e.maskedLocation??e,i=r.external?r.publicHref:t.history.createHref(r.publicHref)||`/`;if(!r.external&&i===r.publicHref||!Et(i,t.protocolAllowlist))return i}var pa=m.memo(m.forwardRef((e,t)=>{let n=e._asChild||`a`,r=aa(e,t,n),i=typeof e.children==`function`?e.children({isActive:r[`data-status`]===`active`}):e.children;return m.createElement(n,r,i)}),ma);function ma(e,t){let n=0;for(let r in t)if(n++,e[r]!==t[r]&&(!ca.has(r)||!vt(e[r],t[r],!1,!0)))return!1;for(let t in e)n--;return n===0}var ha=class extends si{constructor(e){super(e),this.useMatch=e=>Ki({...e,from:this.id}),this.useRouteContext=e=>$i({...e,from:this.id}),this.useSearch=e=>Xi({...e,from:this.id}),this.useParams=e=>Yi({...e,from:this.id}),this.useLoaderDeps=e=>Ji({...e,from:this.id}),this.useLoaderData=e=>qi({...e,from:this.id}),this.useNavigate=()=>Zi({from:this.fullPath}),this.Link=m.forwardRef((e,t)=>(0,h.jsx)(pa,{ref:t,from:this.fullPath,...e}))}};function ga(e){return new ha(e)}var _a=class extends ci{constructor(e){super(e),this.useMatch=e=>Ki({...e,from:this.id}),this.useRouteContext=e=>$i({...e,from:this.id}),this.useSearch=e=>Xi({...e,from:this.id}),this.useParams=e=>Yi({...e,from:this.id}),this.useLoaderDeps=e=>Ji({...e,from:this.id}),this.useLoaderData=e=>qi({...e,from:this.id}),this.useNavigate=()=>Zi({from:this.fullPath}),this.Link=m.forwardRef((e,t)=>(0,h.jsx)(pa,{ref:t,from:this.fullPath,...e}))}};function va(e){return new _a(e)}function ya(e,t){let n,r,i,a=()=>(n||=(i=void 0,e().then(e=>{n=void 0,o.preload=void 0,r=e[t??`default`]}).catch(e=>{n=void 0,i=e})),n),o=function(e){if(i){if(yt(i)&&typeof sessionStorage<`u`){let e=`tanstack_router_reload:${i.message}`;if(!sessionStorage.getItem(e))throw sessionStorage.setItem(e,`1`),window.location.reload(),new Promise(()=>{})}throw i}if(!r){if(ct)ct(a());else throw a()}return m.createElement(r,e)};return o.preload=a,o}function ba(e){let t=_i(),n=`not-found-${Ui(t.stores.location,e=>e.pathname)}-${Ui(t.stores.status)}`;return(0,h.jsx)(li,{getResetKey:()=>n,onCatch:(t,n)=>{if(Vt(t))e.onCatch?.(t,n);else throw t},errorComponent:({error:t})=>{if(Vt(t))return e.fallback?.(t);throw t},children:e.children})}function xa(){return(0,h.jsx)(`p`,{children:`Not Found`})}function Sa(e){return(0,h.jsx)(h.Fragment,{children:e.children})}function Ca(e,t,n){return t.options.notFoundComponent?(0,h.jsx)(t.options.notFoundComponent,{...n}):e.options.defaultNotFoundComponent?(0,h.jsx)(e.options.defaultNotFoundComponent,{...n}):(0,h.jsx)(xa,{})}function wa(e,t){let n=t?.options.pendingComponent??e.options.defaultPendingComponent;return n?(0,h.jsx)(n,{}):null}var Ta=(e,t)=>e[0]===t[0]&&e[1]===t[1],Ea=(e,t,n)=>!t.isRoot||t.options.shellComponent||t.options.wrapInSuspense||n===!1||n===`data-only`||!e.ssr,Da=m.memo(function({routeId:e}){let t=_i();return(0,h.jsx)(Oa,{router:t,match:Ui(t.stores.getMatchStore(e))})});function Oa({router:e,match:t}){let n=e.routesById[t.routeId],r=wa(e,n),i=n.options.errorComponent??e.options.defaultErrorComponent,a=n.options.onCatch??e.options.defaultOnCatch,o=n.isRoot?n.options.notFoundComponent??e.options.notFoundRoute?.options.component:n.options.notFoundComponent,s=t.ssr===!1||t.ssr===`data-only`,c=Ea(e,n,t.ssr)&&(n.options.wrapInSuspense??r??(n.options.errorComponent?.preload||s))?m.Suspense:Sa,l=i?li:Sa,u=o?ba:Sa;return(0,h.jsxs)(n.isRoot?n.options.shellComponent??Sa:Sa,{children:[(0,h.jsx)(vi.Provider,{value:t.routeId,children:(0,h.jsx)(c,{fallback:r,children:(0,h.jsx)(l,{getResetKey:()=>t,errorComponent:i,onCatch:(e,n)=>{if(Vt(e))throw e.routeId??=t.routeId,e;a?.(e,n)},children:(0,h.jsx)(u,{fallback:e=>{if(e.routeId??=t.routeId,e.routeId!==t.routeId)throw e;return m.createElement(o,e)},children:s?(0,h.jsx)(pi,{fallback:r,children:(0,h.jsx)(ka,{match:t})}):(0,h.jsx)(ka,{match:t})})})})}),null]})}var ka=m.memo(function({match:e}){let t=_i(),n=e.routeId,r=t.routesById[n],i=m.useMemo(()=>{let i=(r.options.remountDeps??t.options.defaultRemountDeps)?.({routeId:n,loaderDeps:e.loaderDeps,params:e._strictParams,search:e._strictSearch});return i?JSON.stringify(i):void 0},[n,e.loaderDeps,e._strictParams,e._strictSearch,r.options.remountDeps,t.options.defaultRemountDeps]),a=m.useMemo(()=>{let e=r.options.component??t.options.defaultComponent;return e?(0,h.jsx)(e,{},i):(0,h.jsx)(Aa,{})},[i,r.options.component,t.options.defaultComponent]);if(e.status===`pending`){if(t.ssr&&!Ea(t,r,e.ssr))return a;if(t._tx)throw t._tx[5];return wa(t,r)}if(e.status===`notFound`)return Ca(t,r,e.error);if(e.status===`error`)throw e.error;return a}),Aa=m.memo(function(){let e=_i(),t=m.useContext(vi),n,r,i;{let a=e.stores.getMatchStore(t);[n,r]=Ui(a,e=>[!!e._notFound,e.error],{compare:Ta}),i=Ui(e.stores.ids,e=>e[e.indexOf(t)+1])}if(n)return Ca(e,e.routesById[t],r);if(!i)return null;let a=(0,h.jsx)(Da,{routeId:i});return t===`__root__`?(0,h.jsx)(m.Suspense,{fallback:wa(e),children:a}):a});function ja(e,t){let n=e[1];e.length=0,n?.(t)}function Ma({t:e}){let t=_i(),n=t._rendered??=[];return t.startTransition=(r,i)=>new Promise(a=>{ja(n,!1),n.push(i,a),e(t),m.startTransition(r)}),lt(()=>{let e=t.history.subscribe(t.load);t.updateLatestLocation();let r=t.latestLocation,i=t.buildLocation({to:r.pathname,search:!0,params:!0,hash:!0,state:!0,_includeValidateSearch:!0});if(Nt(r.publicHref)!==Nt(i.publicHref))return t.commitLocation({...i,replace:!0,ignoreBlocker:!0}),e;let a=t.stores.resolvedLocation.get();return a?.href===r.href&&a.state.__TSR_key===r.state.__TSR_key?n.push(t.stores.matches.get(),e=>{e&&t.emit({type:`onRendered`,...$n(a,a)})}):t._tx||t.load({sync:!0}).catch(console.error),e},[t,t.history]),null}function Na(){let e=_i(),t=e.routesById[un],n=wa(e,t),r=e.ssr?Sa:m.Suspense,i=(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(Ma,{t:m.useState()[1]}),(0,h.jsx)(r,{fallback:n,children:(0,h.jsx)(Pa,{})})]});return e.options.InnerWrap?(0,h.jsx)(e.options.InnerWrap,{children:i}):i}function Pa(){let e=_i(),t=e._rendered,n=Ui(e.stores.matches,e=>t[0]??e),r=n[0],i=r?.routeId;lt(()=>{t[0]===n&&ja(t,!0)},[t,n]);let a=i?(0,h.jsx)(Da,{routeId:i}):null;return(0,h.jsx)(vi.Provider,{value:i,children:e.options.disableGlobalCatchBoundary?a:(0,h.jsx)(li,{getResetKey:()=>r,onCatch:void 0,children:a})})}var Fa=e=>({createMutableStore:Ii,createReadonlyStore:Ii,batch:Ni}),Ia=e=>new La(e),La=class extends rr{constructor(e){super(e,Fa)}};function Ra({router:e,children:t,...n}){pt(n)&&e.update({...e.options,...n,context:{...e.options.context,...n.context}});let r=(0,h.jsx)(gi.Provider,{value:e,children:t});return e.options.Wrap?(0,h.jsx)(e.options.Wrap,{children:r}):r}function za({router:e,...t}){return(0,h.jsx)(Ra,{router:e,...t,children:(0,h.jsx)(Na,{})})}var Ba=p(),F=s();function Va(e){let t=(0,F.c)(6),{error:n}=e,r;t[0]===Symbol.for(`react.memo_cache_sentinel`)?(r=(0,h.jsx)(`p`,{className:`schild text-lg text-rot`,children:`Diese Ansicht ist abgestürzt`}),t[0]=r):r=t[0];let i=n instanceof Error?n.message:String(n),a;t[1]===i?a=t[2]:(a=(0,h.jsx)(`p`,{className:`text-[15px]`,children:i}),t[1]=i,t[2]=a);let o;t[3]===Symbol.for(`react.memo_cache_sentinel`)?(o=(0,h.jsx)(`button`,{type:`button`,onClick:Ha,className:`schild h-11 rounded-lg border border-rot-rand px-5 text-sm text-foreground hover:bg-[#3a1512]`,children:`Neu laden`}),t[3]=o):o=t[3];let s;return t[4]===a?s=t[5]:(s=(0,h.jsxs)(`div`,{role:`alert`,className:`flex flex-col items-start gap-3 rounded-2xl border border-rot-rand bg-rot-grund p-6 text-rot-text`,children:[r,a,o]}),t[4]=a,t[5]=s),s}function Ha(){return window.location.reload()}var Ua={name:`cpu`,size:24,node:[[`path`,{d:`M12 20v2`,key:`1lh1kg`}],[`path`,{d:`M12 2v2`,key:`tus03m`}],[`path`,{d:`M17 20v2`,key:`1rnc9c`}],[`path`,{d:`M17 2v2`,key:`11trls`}],[`path`,{d:`M2 12h2`,key:`1t8f8n`}],[`path`,{d:`M2 17h2`,key:`7oei6x`}],[`path`,{d:`M2 7h2`,key:`asdhe0`}],[`path`,{d:`M20 12h2`,key:`1q8mjw`}],[`path`,{d:`M20 17h2`,key:`1fpfkl`}],[`path`,{d:`M20 7h2`,key:`1o8tra`}],[`path`,{d:`M7 20v2`,key:`4gnj0m`}],[`path`,{d:`M7 2v2`,key:`1i4yhu`}],[`rect`,{x:`4`,y:`4`,width:`16`,height:`16`,rx:`2`,key:`1vbyd7`}],[`rect`,{x:`8`,y:`8`,width:`8`,height:`8`,rx:`1`,key:`z9xiuo`}]]};Ua.node;var Wa=o(Ua),Ga={name:`ellipsis`,size:24,node:[[`circle`,{cx:`12`,cy:`12`,r:`1`,key:`41hilf`}],[`circle`,{cx:`19`,cy:`12`,r:`1`,key:`1wjl8i`}],[`circle`,{cx:`5`,cy:`12`,r:`1`,key:`1pcz8c`}]],aliases:[`more-horizontal`]};Ga.node;var Ka=o(Ga),qa={name:`external-link`,size:24,node:[[`path`,{d:`M15 3h6v6`,key:`1q9fwt`}],[`path`,{d:`M10 14 21 3`,key:`gplh6r`}],[`path`,{d:`M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6`,key:`a6xqqp`}]]};qa.node;var Ja=o(qa),Ya={name:`house`,size:24,node:[[`path`,{d:`M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8`,key:`5wwlr5`}],[`path`,{d:`M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z`,key:`r6nss1`}]],aliases:[`home`]};Ya.node;var Xa=o(Ya),Za={name:`refresh-cw`,size:24,node:[[`path`,{d:`M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8`,key:`v9h5vc`}],[`path`,{d:`M21 3v5h-5`,key:`1q7to0`}],[`path`,{d:`M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16`,key:`3uifl3`}],[`path`,{d:`M8 16H3v5`,key:`1cv678`}]]};Za.node;var Qa=o(Za),$a={name:`scroll-text`,size:24,node:[[`path`,{d:`M15 12h-5`,key:`r7krc0`}],[`path`,{d:`M15 8h-5`,key:`1khuty`}],[`path`,{d:`M19 17V5a2 2 0 0 0-2-2H4`,key:`zz82l3`}],[`path`,{d:`M8 21h12a2 2 0 0 0 2-2v-1a1 1 0 0 0-1-1H11a1 1 0 0 0-1 1v1a2 2 0 1 1-4 0V5a2 2 0 1 0-4 0v2a1 1 0 0 0 1 1h3`,key:`1ph1d7`}]]};$a.node;var eo=o($a),to={name:`settings`,size:24,node:[[`path`,{d:`M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915`,key:`1i5ecw`}],[`circle`,{cx:`12`,cy:`12`,r:`3`,key:`1v7zrd`}]]};to.node;var no=o(to),ro=`verbinde`,io=null,ao=new Set,oo=()=>ao.forEach(e=>e());function so(e){return ao.add(e),()=>{ao.delete(e)}}var co=()=>ro===`live`,lo=()=>(0,m.useSyncExternalStore)(so,ho),uo=()=>(0,m.useSyncExternalStore)(so,go);function fo(e){io=e,oo()}function po(e){e!==ro&&(ro=e,oo())}function mo(){let e=_();(0,m.useEffect)(()=>{let t=new EventSource(`/api/stream`);return t.onopen=()=>{po(`live`),e.invalidateQueries()},t.onerror=()=>po(`getrennt`),t.addEventListener(`invalidate`,t=>{try{let n=JSON.parse(t.data)?.keys??[];for(let t of n)e.invalidateQueries({queryKey:[t]})}catch{}}),t.addEventListener(`metrik`,e=>{try{fo(JSON.parse(e.data))}catch{}}),()=>{t.close(),po(`getrennt`)}},[e])}function ho(){return ro}function go(){return io}var _o=[],vo=1,yo=new Set,bo=()=>yo.forEach(e=>e());function xo(e,t){let n=vo++;_o=[..._o,{id:n,art:e,text:t}].slice(-4),bo(),e!==`fehler`&&window.setTimeout(()=>So(n),6e3)}function So(e){_o=_o.filter(t=>t.id!==e),bo()}var Co=()=>(0,m.useSyncExternalStore)(wo,To);function wo(e){return yo.add(e),()=>{yo.delete(e)}}function To(){return _o}var Eo={erfolg:`border-gruen-rand bg-gruen-grund text-gruen-text`,fehler:`border-rot-rand bg-rot-grund text-rot-text`,info:`border-cyan-rand bg-cyan-grund text-cyan-text`};function Do(){let e=(0,F.c)(4),t=Co(),n;e[0]===t?n=e[1]:(n=t.map(Oo),e[0]=t,e[1]=n);let r;return e[2]===n?r=e[3]:(r=(0,h.jsx)(`div`,{"aria-live":`polite`,className:`pointer-events-none fixed right-4 bottom-24 left-4 z-50 flex flex-col items-end gap-2 md:bottom-6 md:left-auto md:w-[420px]`,children:n}),e[2]=n,e[3]=r),r}function Oo(t){return(0,h.jsxs)(`div`,{role:t.art===`fehler`?`alert`:`status`,className:i(`pointer-events-auto flex w-full items-start gap-3 rounded-xl border px-4 py-3 text-[15px] shadow-lg`,Eo[t.art]),children:[(0,h.jsx)(`span`,{className:`min-w-0 flex-1`,children:t.text}),(0,h.jsx)(`button`,{type:`button`,onClick:()=>So(t.id),"aria-label":`Meldung schließen`,className:`-m-2 p-2 opacity-70 hover:opacity-100`,children:(0,h.jsx)(e,{className:`size-4`})})]},t.id)}var ko=`modulepreload`,Ao=function(e){return`/`+e},jo={},Mo=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}function s(e){return import.meta.resolve?import.meta.resolve(e):new URL(e,import.meta.url).href}r=o(t.map(t=>{if(t=Ao(t,n),t=s(t),t in jo)return;jo[t]=!0;let r=t.endsWith(`.css`);for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}let i=document.createElement(`link`);if(i.rel=r?`stylesheet`:ko,r||(i.as=`script`),i.crossOrigin=``,i.href=t,a&&i.setAttribute(`nonce`,a),document.head.appendChild(i),r)return new Promise((e,n)=>{i.addEventListener(`load`,e),i.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}).filter(e=>e!==void 0))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})},No=(0,m.lazy)(()=>Mo(()=>import(`./Dienste-QEbMZv2T.js`).then(e=>({default:e.Dienste})),__vite__mapDeps([0,1,2,3]))),Po=(0,m.lazy)(()=>Mo(()=>import(`./Einstellungen-DMWgWLUo.js`).then(e=>({default:e.Einstellungen})),__vite__mapDeps([4,1,2,3]))),Fo=(0,m.lazy)(()=>Mo(()=>import(`./MehrMenue-gZV9ubEU.js`).then(e=>({default:e.MehrMenue})),__vite__mapDeps([5,1,2,3]))),Io=[{to:`/`,label:`Start`,Icon:Xa},{to:`/updates`,label:`Updates`,Icon:Qa},{to:`/modelle`,label:`Modelle`,Icon:Wa}],Lo=new Intl.DateTimeFormat(`de-DE`,{hour:`2-digit`,minute:`2-digit`,timeZone:`Europe/Berlin`}),Ro=new Intl.DateTimeFormat(`de-DE`,{weekday:`short`,day:`2-digit`,month:`2-digit`,timeZone:`Europe/Berlin`});function zo(){let e=(0,F.c)(13),[t,n]=(0,m.useState)(Bo),r,i;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(r=()=>{let e=window.setInterval(()=>n(new Date),2e4);return()=>window.clearInterval(e)},i=[],e[0]=r,e[1]=i):(r=e[0],i=e[1]),(0,m.useEffect)(r,i);let a;e[2]===t?a=e[3]:(a=Lo.format(t),e[2]=t,e[3]=a);let o;e[4]===a?o=e[5]:(o=(0,h.jsx)(`span`,{className:`ziffern text-2xl font-medium`,children:a}),e[4]=a,e[5]=o);let s;e[6]===t?s=e[7]:(s=Ro.format(t).replace(`,`,``),e[6]=t,e[7]=s);let c;e[8]===s?c=e[9]:(c=(0,h.jsx)(`span`,{className:`schild text-[13px] text-text-3`,children:s}),e[8]=s,e[9]=c);let l;return e[10]!==o||e[11]!==c?(l=(0,h.jsxs)(`div`,{className:`flex flex-col items-end leading-tight`,children:[o,c]}),e[10]=o,e[11]=c,e[12]=l):l=e[12],l}function Bo(){return new Date}function Vo(){let e=(0,F.c)(9),t=lo(),n=t===`live`,r=n?`bg-gruen shadow-[0_0_8px_rgba(61,220,138,0.7)]`:`bg-bernstein`,a;e[0]===r?a=e[1]:(a=i(`size-2 rounded-full`,r),e[0]=r,e[1]=a);let o;e[2]===a?o=e[3]:(o=(0,h.jsx)(`span`,{className:a}),e[2]=a,e[3]=o);let s=n?`Box online`:t===`verbinde`?`Verbinde`:`Getrennt`,c;e[4]===s?c=e[5]:(c=(0,h.jsx)(`span`,{children:s}),e[4]=s,e[5]=c);let l;return e[6]!==o||e[7]!==c?(l=(0,h.jsxs)(`div`,{className:`schild flex items-center gap-2 text-[15px] text-text-3`,"aria-live":`polite`,children:[o,c]}),e[6]=o,e[7]=c,e[8]=l):l=e[8],l}function Ho(){let e=(0,F.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t=(0,h.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,h.jsxs)(`svg`,{width:`34`,height:`34`,viewBox:`0 0 34 34`,fill:`none`,"aria-hidden":!0,children:[(0,h.jsx)(`rect`,{x:`1.5`,y:`1.5`,width:`31`,height:`31`,rx:`8`,stroke:`var(--linie-stark)`,strokeWidth:`2`}),(0,h.jsx)(`path`,{d:`M7 18h5l3-7 4 13 3-6h5`,stroke:`var(--bernstein)`,strokeWidth:`2.2`,strokeLinecap:`round`,strokeLinejoin:`round`})]}),(0,h.jsx)(`span`,{className:`font-anzeige text-[28px] leading-none font-bold tracking-[0.06em]`,children:`MC2`}),(0,h.jsx)(`span`,{className:`hidden h-6 w-px bg-linie sm:block`}),(0,h.jsx)(`span`,{className:`schild hidden text-base tracking-[0.22em] text-text-3 sm:block`,children:`Box-Wart`})]}),e[0]=t):t=e[0],t}function Uo(){let e=(0,F.c)(26);mo();let[t,n]=(0,m.useState)(null),r;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(r=()=>n(null),e[0]=r):r=e[0];let i=r,a;e[1]===Symbol.for(`react.memo_cache_sentinel`)?(a=(0,h.jsx)(Ho,{}),e[1]=a):a=e[1];let o;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(o=(0,h.jsx)(`nav`,{"aria-label":`Hauptnavigation`,className:`hidden gap-1 rounded-xl border border-linie bg-[#121518] p-1 md:flex`,children:Io.map(Go)}),e[2]=o):o=e[2];let s;e[3]===Symbol.for(`react.memo_cache_sentinel`)?(s=(0,h.jsx)(`div`,{className:`hidden lg:block`,children:(0,h.jsx)(Vo,{})}),e[3]=s):s=e[3];let c;e[4]===Symbol.for(`react.memo_cache_sentinel`)?(c=(0,h.jsx)(`a`,{href:`/hermes-ui/`,target:`_blank`,rel:`noopener`,className:`flex size-11 items-center justify-center rounded-lg text-text-2 hover:bg-erhaben hover:text-foreground`,title:`Hermes-Dashboard öffnen`,"aria-label":`Hermes-Dashboard öffnen`,children:(0,h.jsx)(Ja,{className:`size-5`})}),e[4]=c):c=e[4];let l;e[5]===Symbol.for(`react.memo_cache_sentinel`)?(l=()=>n(`dienste`),e[5]=l):l=e[5];let u;e[6]===Symbol.for(`react.memo_cache_sentinel`)?(u=(0,h.jsx)(`button`,{type:`button`,onClick:l,className:`flex size-11 items-center justify-center rounded-lg text-text-2 hover:bg-erhaben hover:text-foreground`,title:`Dienste und Protokolle`,"aria-label":`Dienste und Protokolle`,children:(0,h.jsx)(eo,{className:`size-5`})}),e[6]=u):u=e[6];let d;e[7]===Symbol.for(`react.memo_cache_sentinel`)?(d=()=>n(`einstellungen`),e[7]=d):d=e[7];let f;e[8]===Symbol.for(`react.memo_cache_sentinel`)?(f=(0,h.jsxs)(`header`,{className:`flex items-center justify-between gap-4 md:gap-6`,children:[a,o,(0,h.jsxs)(`div`,{className:`flex items-center gap-4 md:gap-5`,children:[s,(0,h.jsxs)(`div`,{className:`hidden items-center gap-1 md:flex`,children:[c,u,(0,h.jsx)(`button`,{type:`button`,onClick:d,className:`flex size-11 items-center justify-center rounded-lg text-text-2 hover:bg-erhaben hover:text-foreground`,title:`Einstellungen`,"aria-label":`Einstellungen`,children:(0,h.jsx)(no,{className:`size-5`})})]}),(0,h.jsx)(zo,{})]})]}),e[8]=f):f=e[8];let p;e[9]===Symbol.for(`react.memo_cache_sentinel`)?(p=(0,h.jsx)(`main`,{className:`flex min-w-0 flex-col gap-5 md:gap-6`,children:(0,h.jsx)(Aa,{})}),e[9]=p):p=e[9];let g;e[10]===Symbol.for(`react.memo_cache_sentinel`)?(g=Io.map(Wo),e[10]=g):g=e[10];let _;e[11]===Symbol.for(`react.memo_cache_sentinel`)?(_=()=>n(`mehr`),e[11]=_):_=e[11];let v;e[12]===Symbol.for(`react.memo_cache_sentinel`)?(v=(0,h.jsxs)(`nav`,{"aria-label":`Hauptnavigation`,className:`fixed inset-x-0 bottom-0 z-40 grid grid-cols-4 gap-1 border-t border-linie bg-[#0e1119]/95 px-2 pt-2 pb-[calc(0.75rem+env(safe-area-inset-bottom))] backdrop-blur md:hidden`,children:[g,(0,h.jsxs)(`button`,{type:`button`,onClick:_,className:`schild flex h-14 flex-col items-center justify-center gap-1 rounded-lg text-xs text-text-3`,children:[(0,h.jsx)(Ka,{className:`size-5`,"aria-hidden":!0}),`Mehr`]})]}),e[12]=v):v=e[12];let y;e[13]===t?y=e[14]:(y=t===`mehr`&&(0,h.jsx)(Fo,{verbindung:(0,h.jsx)(Vo,{}),onDienste:()=>n(`dienste`),onEinstellungen:()=>n(`einstellungen`),onSchliessen:i}),e[13]=t,e[14]=y);let b;e[15]===t?b=e[16]:(b=t===`dienste`&&(0,h.jsx)(No,{offen:!0,onSchliessen:i}),e[15]=t,e[16]=b);let x;e[17]===t?x=e[18]:(x=t===`einstellungen`&&(0,h.jsx)(Po,{offen:!0,onSchliessen:i}),e[17]=t,e[18]=x);let S;e[19]!==y||e[20]!==b||e[21]!==x?(S=(0,h.jsxs)(m.Suspense,{fallback:null,children:[y,b,x]}),e[19]=y,e[20]=b,e[21]=x,e[22]=S):S=e[22];let C;e[23]===Symbol.for(`react.memo_cache_sentinel`)?(C=(0,h.jsx)(Do,{}),e[23]=C):C=e[23];let w;return e[24]===S?w=e[25]:(w=(0,h.jsxs)(`div`,{className:`mx-auto flex min-h-dvh w-full max-w-[1440px] flex-col gap-5 px-4 pt-4 pb-28 sm:px-6 md:gap-6 md:px-10 md:pt-8 md:pb-10`,children:[f,p,v,S,C]}),e[24]=S,e[25]=w),w}function Wo(e){let{to:t,label:n,Icon:r}=e;return(0,h.jsxs)(pa,{to:t,className:`schild flex h-14 flex-col items-center justify-center gap-1 rounded-lg text-xs text-text-3`,activeProps:{className:`bg-erhaben !text-foreground`},activeOptions:{exact:!0},children:[(0,h.jsx)(r,{className:`size-5`,"aria-hidden":!0}),n]},t)}function Go(e){let{to:t,label:n}=e;return(0,h.jsx)(pa,{to:t,className:`schild flex h-11 items-center rounded-[9px] border border-transparent px-5 text-base text-text-3 hover:text-foreground`,activeProps:{className:`!border-linie-stark bg-erhaben !text-foreground`},activeOptions:{exact:!0},children:n},t)}var Ko=class extends Error{status;detail;constructor(e,t){super(t),this.status=e,this.detail=t,this.name=`ApiFehler`}};function qo(e,t){if(e&&typeof e==`object`&&`detail`in e){let t=e.detail;if(typeof t==`string`)return t;if(Array.isArray(t))return t.map(e=>e.msg??String(e)).join(`; `)}return`Die Box antwortet mit Fehler ${t}.`}async function I(e,t={}){let n;try{n=await fetch(e,{...t,headers:{"Content-Type":`application/json`,Accept:`application/json`,...t.headers}})}catch{throw new Ko(0,`MC2 ist nicht erreichbar. Läuft die Box?`)}let r=await n.text(),i=r?L(r):null;if(!n.ok)throw new Ko(n.status,qo(i,n.status));if(typeof i==`string`)throw new Ko(n.status,`Die Box antwortet nicht mit Daten.`);return i}function L(e){try{return JSON.parse(e)}catch{return e}}var R=(e,t)=>I(e,{method:`POST`,body:t===void 0?void 0:JSON.stringify(t)}),Jo=e=>()=>co()?e*5:e,Yo=()=>{let e=(0,F.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={queryKey:[`start`],queryFn:ms,refetchInterval:hs},e[0]=t):t=e[0],ot(t)},Xo=()=>{let e=(0,F.c)(2),t;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t=[`models`],e[0]=t):t=e[0];let n;return e[1]===Symbol.for(`react.memo_cache_sentinel`)?(n={queryKey:t,queryFn:gs,refetchInterval:Jo(3e4)},e[1]=n):n=e[1],ot(n)},Zo=()=>{let e=(0,F.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={queryKey:[`nutzung`],queryFn:_s,refetchInterval:6e5},e[0]=t):t=e[0],ot(t)},Qo=()=>{let e=(0,F.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={queryKey:[`radar`],queryFn:vs,retry:!1,refetchInterval:3e5},e[0]=t):t=e[0],ot(t)},$o=()=>{let e=(0,F.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={queryKey:[`jobs`],queryFn:ys,refetchInterval:xs},e[0]=t):t=e[0],ot(t)},es=()=>{let e=(0,F.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={queryKey:[`sicherungen`],queryFn:Ss},e[0]=t):t=e[0],ot(t)},z=e=>{let t=(0,F.c)(7),n,r;t[0]===e?(n=t[1],r=t[2]):(n=[`update-details`,e],r=()=>I(`/api/maintenance/update-details?kind=${e}`),t[0]=e,t[1]=n,t[2]=r);let i=!!e,a;return t[3]!==n||t[4]!==r||t[5]!==i?(a={queryKey:n,queryFn:r,enabled:i,staleTime:6e5},t[3]=n,t[4]=r,t[5]=i,t[6]=a):a=t[6],ot(a)},ts=()=>{let e=(0,F.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={queryKey:[`updates-verlauf`],queryFn:Cs},e[0]=t):t=e[0],ot(t)},ns=e=>{let t=(0,F.c)(7),n,r;t[0]===e?(n=t[1],r=t[2]):(n=[`protokoll`,e],r=()=>I(`/api/maintenance/logs?service=${encodeURIComponent(e??``)}&lines=200`),t[0]=e,t[1]=n,t[2]=r);let i=!!e,a;return t[3]!==n||t[4]!==r||t[5]!==i?(a={queryKey:n,queryFn:r,enabled:i},t[3]=n,t[4]=r,t[5]=i,t[6]=a):a=t[6],ot(a)},rs=()=>{let e=(0,F.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={queryKey:[`dienste`],queryFn:ws},e[0]=t):t=e[0],ot(t)};function is(e,t){let n=(0,F.c)(6),r=_(),i;n[0]!==t||n[1]!==r?(i=(e,n)=>{let i=e;i&&i.ok===!1?xo(`fehler`,i.detail||i.err||`Das hat nicht geklappt.`):xo(`erfolg`,t.erfolg(n,e));for(let e of t.neuLaden)r.invalidateQueries({queryKey:[e]})},n[0]=t,n[1]=r,n[2]=i):i=n[2];let a;return n[3]!==e||n[4]!==i?(a={mutationFn:e,onSuccess:i,onError:as},n[3]=e,n[4]=i,n[5]=a):a=n[5],st(a)}function as(e){return xo(`fehler`,e.message)}var os=()=>{let e=(0,F.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={erfolg:Es,neuLaden:[`start`]},e[0]=t):t=e[0],is(Ts,t)},ss={alle:`/api/maintenance/update-all`,pruefen:`/api/maintenance/check-updates`,os:`/api/maintenance/os-update`,engine:`/api/maintenance/engine-update`,swap:`/api/maintenance/swap-update`,hermes:`/api/maintenance/hermes-update`},cs=()=>{let e=(0,F.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={erfolg:Os,neuLaden:[`jobs`,`start`]},e[0]=t):t=e[0],is(Ds,t)},ls=()=>{let e=(0,F.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={erfolg:As,neuLaden:[`start`]},e[0]=t):t=e[0],is(ks,t)},B=()=>{let e=(0,F.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={erfolg:Ms,neuLaden:[`sicherungen`,`start`]},e[0]=t):t=e[0],is(js,t)},us=()=>{let e=(0,F.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={erfolg:Ps,neuLaden:[`sicherungen`]},e[0]=t):t=e[0],is(Ns,t)},ds=()=>{let e=(0,F.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={erfolg:Is,neuLaden:[`models`,`start`]},e[0]=t):t=e[0],is(Fs,t)},fs=()=>{let e=(0,F.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={erfolg:Rs,neuLaden:[`radar`,`models`,`start`]},e[0]=t):t=e[0],is(Ls,t)},ps=()=>{let e=(0,F.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={erfolg:Bs,neuLaden:[`radar`]},e[0]=t):t=e[0],is(zs,t)};function ms(){return I(`/api/start`)}function hs(e){return e.state.data&&!e.state.data.updates.gelesen?4e3:Jo(2e4)()}function gs(){return I(`/api/models`)}function _s(){return I(`/api/modelle/nutzung`)}function vs(){return I(`/api/radar`)}function ys(){return I(`/api/jobs`)}function bs(e){return e.state===`running`||e.state===`queued`}function xs(e){return e.state.data?.jobs.some(bs)?2e3:Jo(3e4)()}function Ss(){return I(`/api/zeitmaschine`)}function Cs(){return I(`/api/updates/verlauf`)}function ws(){return I(`/api/system/services`)}function Ts(e){let{hinweis:t,aktion:n}=e;return R(`/api/hinweise/${encodeURIComponent(t)}/aktion/${n}`)}function Es(e){return`${e.label}: erledigt. Der Wächter prüft in einer Minute nach.`}function Ds(e){return R(ss[e])}function Os(e){return e===`pruefen`?`Suche nach Neuem läuft.`:`Update läuft. Den Fortschritt siehst du unten.`}function ks(e){return R(`/api/updates/festgehalten/${encodeURIComponent(e)}/freigeben`)}function As(e,t){return t.text??`Freigegeben.`}function js(){return R(`/api/system/backup`)}function Ms(){return`Sicherung erstellt.`}function Ns(e){return R(`/api/zeitmaschine/restore`,{file:e})}function Ps(){return`Zurückspielen läuft. Die Dienste starten gleich neu.`}function Fs(e){return R(`/api/models/${encodeURIComponent(e)}/load`)}function Is(e){return`${e} wird geladen.`}function Ls(e){let{id:t,aktion:n}=e;return R(`/api/radar/${encodeURIComponent(t)}/${n}`)}function Rs(e){return e.aktion===`uebernehmen`?`${e.name} übernommen.`:`${e.name} verworfen.`}function zs(){return R(`/api/radar/suche`)}function Bs(){return`Radar sucht nach neuen Modellen.`}var Vs=`Europe/Berlin`,Hs=new Intl.DateTimeFormat(`de-DE`,{hour:`2-digit`,minute:`2-digit`,timeZone:Vs}),Us=new Intl.DateTimeFormat(`de-DE`,{weekday:`short`,timeZone:Vs}),Ws=new Intl.DateTimeFormat(`de-DE`,{day:`2-digit`,month:`2-digit`,timeZone:Vs}),Gs=new Intl.DateTimeFormat(`en-CA`,{timeZone:Vs});function Ks(e){return Gs.format(e)}function qs(e,t=new Date){let n=new Date(e);if(Number.isNaN(n.getTime()))return`–`;let r=Ks(t),i=Ks(new Date(t.getTime()-864e5)),a=Ks(new Date(t.getTime()+864e5)),o=Ks(n),s=Hs.format(n);return o===r?`HEUTE ${s}`:o===i?`GESTERN ${s}`:o===a?`MORGEN ${s}`:Math.abs(n.getTime()-t.getTime())<5616e5?`${Us.format(n).replace(`.`,``).toUpperCase()} ${s}`:`${Ws.format(n)} ${s}`}function Js(e,t=new Date){let n=new Date(e*1e3);return Ks(n)===Ks(t)?`seit heute ${Hs.format(n)}`:`seit ${Ws.format(n)}, ${Hs.format(n)}`}function Ys(e,t=Date.now()){let n=Math.max(0,Math.round(t/1e3-e));if(n<60)return`vor ${n} s`;if(n<3600)return`vor ${Math.round(n/60)} min`;if(n<86400)return`vor ${Math.round(n/3600)} h`;let r=Math.round(n/86400);return`vor ${r} ${r===1?`Tag`:`Tagen`}`}function Xs(e){return e==null||e<0?null:[Math.floor(e/86400),Math.floor(e%86400/3600)]}var Zs=e=>e==null?null:e/1024**3;function Qs(e,t=0){let n=Zs(e);return n==null?`–`:n>=1e3?`${(n/1024).toFixed(1).replace(`.`,`,`)} TB`:`${n.toFixed(t).replace(`.`,`,`)} GB`}var $s=e=>e.toLocaleString(`de-DE`),ec=(0,m.lazy)(()=>Mo(()=>import(`./Protokollfenster-CDb28asU.js`).then(e=>({default:e.Protokollfenster})),__vite__mapDeps([6,1,2,3])));function tc({h:e}){let t=os(),[n,r]=(0,m.useState)(null),a=e.stufe===`rot`;async function o(n,i){if(n===`protokoll`){try{let t=await R(`/api/hinweise/${encodeURIComponent(e.id)}/aktion/protokoll`);r({titel:e.titel,text:t.text||t.out||t.err||`Kein Protokoll vorhanden.`})}catch(e){xo(`fehler`,e.message)}return}t.mutate({hinweis:e.id,aktion:n,label:i})}return(0,h.jsxs)(`article`,{className:`flex flex-col gap-2.5 border-t border-linie pt-4`,children:[(0,h.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,h.jsx)(`h3`,{className:`min-w-0 font-sans text-[17px] leading-snug font-semibold`,children:e.titel}),(0,h.jsx)(`span`,{"aria-hidden":!0,className:`hidden h-0 flex-grow border-b-2 border-dotted border-linie-stark sm:block`}),(0,h.jsx)(`span`,{className:i(`schild shrink-0 text-base`,a?`text-rot`:`text-bernstein`),children:a?`Jetzt`:`Prüfen`})]}),(0,h.jsxs)(`p`,{className:`ziffern text-[13px] text-text-3`,children:[Js(e.seit),` · zuletzt `,Ys(e.zuletzt)]}),e.text&&(0,h.jsx)(`p`,{className:`text-[15px] leading-relaxed break-words text-text-2`,children:e.text}),e.aktionen.length>0&&(0,h.jsx)(`div`,{className:`flex flex-wrap gap-2.5 pt-1`,children:e.aktionen.map((e,n)=>(0,h.jsx)(c,{variant:n===0&&e.id!==`protokoll`?`default`:`outline`,size:`sm`,disabled:t.isPending,onClick:()=>o(e.id,e.label),children:e.label},e.id))}),n&&(0,h.jsx)(m.Suspense,{fallback:null,children:(0,h.jsx)(ec,{offen:!0,titel:n.titel,text:n.text,onSchliessen:()=>r(null)})})]})}function nc(e){let t=(0,F.c)(12),{hinweise:n,verlauf:r}=e,i;t[0]===Symbol.for(`react.memo_cache_sentinel`)?(i=new Date().toDateString(),t[0]=i):i=t[0];let a=i,o;if(t[1]!==n.length||t[2]!==r){o=Symbol.for(`react.early_return_sentinel`);bb0:{let e;t[4]===Symbol.for(`react.memo_cache_sentinel`)?(e=e=>(e.art===`erledigt`||e.art===`auto`)&&new Date(e.ts*1e3).toDateString()===a,t[4]=e):e=t[4];let i=r.filter(e);if(n.length===0){let e;t[5]===Symbol.for(`react.memo_cache_sentinel`)?(e=(0,h.jsx)(`p`,{className:`text-[15px] text-text-2`,children:`Keine offenen Punkte. Der Wächter prüft jede Minute.`}),t[5]=e):e=t[5];let n=i.length>0&&(0,h.jsx)(`ul`,{className:`flex flex-col gap-1 text-sm text-text-3`,children:i.slice(0,4).map(ic)}),r;t[6]===n?r=t[7]:(r=(0,h.jsxs)(`div`,{className:`flex flex-col gap-2 border-t border-linie pt-4`,children:[e,n]}),t[6]=n,t[7]=r),o=r;break bb0}}t[1]=n.length,t[2]=r,t[3]=o}else o=t[3];if(o!==Symbol.for(`react.early_return_sentinel`))return o;let s;t[8]===n?s=t[9]:(s=n.map(rc),t[8]=n,t[9]=s);let c;return t[10]===s?c=t[11]:(c=(0,h.jsx)(`div`,{className:`flex flex-col gap-4`,children:s}),t[10]=s,t[11]=c),c}function rc(e){return(0,h.jsx)(tc,{h:e},e.id)}function ic(e){return(0,h.jsxs)(`li`,{children:[(0,h.jsx)(`span`,{className:`ziffern`,children:Ys(e.ts)}),` · `,e.text]},`${e.id}-${e.ts}`)}var ac={gruen:`border-gruen-rand bg-gruen-grund text-gruen`,bernstein:`border-bernstein/60 bg-bernstein-grund text-bernstein`,cyan:`border-cyan-rand bg-cyan-grund text-cyan`,rot:`border-rot-rand bg-rot-grund text-rot-text`,grau:`border-linie bg-erhaben text-text-2`};function oc(e){let t=(0,F.c)(5),{art:n,children:r}=e,a=ac[n===void 0?`grau`:n],o;t[0]===a?o=t[1]:(o=i(`schild inline-flex h-7 items-center rounded-full border px-2.5 text-xs whitespace-nowrap`,a),t[0]=a,t[1]=o);let s;return t[2]!==r||t[3]!==o?(s=(0,h.jsx)(`span`,{className:o,children:r}),t[2]=r,t[3]=o,t[4]=s):s=t[4],s}function sc(e){let t=(0,F.c)(6),{fehler:n,text:r}=e,a=n?`alert`:`status`,o=n?`border-rot-rand bg-rot-grund text-rot-text`:`border-linie bg-panel text-text-2`,s;t[0]===o?s=t[1]:(s=i(`rounded-2xl border px-5 py-8 text-center text-[15px]`,o),t[0]=o,t[1]=s);let c;return t[2]!==a||t[3]!==s||t[4]!==r?(c=(0,h.jsx)(`div`,{role:a,className:s,children:r}),t[2]=a,t[3]=s,t[4]=r,t[5]=c):c=t[5],c}var cc={erledigt:{text:`Erledigt`,farbe:`text-gruen`},fehler:{text:`Fehler`,farbe:`text-rot`},geplant:{text:`Geplant`,farbe:`text-text-3`}};function lc(e){let t=(0,F.c)(18),{e:n}=e,r=cc[n.status]??cc.geplant,a=n.status===`geplant`&&/update/i.test(n.titel)?`text-cyan`:r.farbe,o;t[0]===n.zeit?o=t[1]:(o=qs(n.zeit),t[0]=n.zeit,t[1]=o);let s;t[2]===o?s=t[3]:(s=(0,h.jsx)(`span`,{className:`ziffern text-sm text-text-3`,children:o}),t[2]=o,t[3]=s);let c;t[4]===n.text?c=t[5]:(c=n.text&&(0,h.jsxs)(`span`,{className:`text-text-3`,children:[`, `,n.text]}),t[4]=n.text,t[5]=c);let l;t[6]!==n.titel||t[7]!==c?(l=(0,h.jsxs)(`span`,{className:`min-w-0 text-base`,children:[n.titel,c]}),t[6]=n.titel,t[7]=c,t[8]=l):l=t[8];let u;t[9]===a?u=t[10]:(u=i(`schild text-[13px]`,a),t[9]=a,t[10]=u);let d;t[11]!==r.text||t[12]!==u?(d=(0,h.jsx)(`span`,{className:u,children:r.text}),t[11]=r.text,t[12]=u,t[13]=d):d=t[13];let f;return t[14]!==s||t[15]!==l||t[16]!==d?(f=(0,h.jsxs)(`li`,{className:`grid grid-cols-[112px_minmax(0,1fr)_auto] items-center gap-3 border-t border-linie py-2.5`,children:[s,l,d]}),t[14]=s,t[15]=l,t[16]=d,t[17]=f):f=t[17],f}function uc(e){let t=(0,F.c)(6),{gelaufen:n,geplant:r}=e,i;t[0]!==n||t[1]!==r?(i=[...n,...r.slice(0,5)],t[0]=n,t[1]=r,t[2]=i):i=t[2];let a=i;if(a.length===0){let e;return t[3]===Symbol.for(`react.memo_cache_sentinel`)?(e=(0,h.jsx)(`p`,{className:`text-[15px] text-text-2`,children:`Heute ist noch nichts gelaufen, und nichts ist geplant.`}),t[3]=e):e=t[3],e}let o;return t[4]===a?o=t[5]:(o=(0,h.jsx)(`ol`,{className:`m-0 flex list-none flex-col p-0`,children:a.map(dc)}),t[4]=a,t[5]=o),o}function dc(e){return(0,h.jsx)(lc,{e},`${e.titel}-${e.zeit}`)}var fc=100,pc=95,mc=210,hc=240;function gc(e,t){let n=e*Math.PI/180;return[fc+t*Math.cos(n),pc-t*Math.sin(n)]}var _c=e=>Math.round(e*100)/100;function vc(e,t,n){let r=Math.max(0,Math.min(1,e)),i=Math.max(r,Math.min(1,t)),[a,o]=gc(mc-hc*r,n),[s,c]=gc(mc-hc*i,n),l=+((i-r)*hc>180);return`M ${_c(a)} ${_c(o)} A ${n} ${n} 0 ${l} 1 ${_c(s)} ${_c(c)}`}function yc(e){return e==null?`var(--text-3)`:e>=85?`var(--rot)`:e>=70?`var(--bernstein)`:`var(--gruen)`}function bc(e){if(!e.waechter_wach)return{art:`stumm`,oben:`Wächter`,mitte:`SCHWEIGT`,unten:`Seit über 5 Minuten kein Prüflauf`};if(e.update_laeuft)return{art:`info`,oben:`Wartung`,mitte:`UPDATE LÄUFT`,unten:`Hinweise ruhen bis zum Ende`};if(e.anzahl===0)return{art:`ok`,oben:`Alles`,mitte:`IN ORDNUNG`,unten:`Keine offenen Hinweise`};let t=`${e.anzahl} HINWEIS${e.anzahl===1?``:`E`}`;return e.stufe===`rot`?{art:`rot`,oben:`Störung`,mitte:t,unten:`Drücken zum Ansehen`}:{art:`gelb`,oben:`Achtung`,mitte:t,unten:`Drücken zum Ansehen`}}function xc(e,t){if(!t)return{laeuft:`…`,neu:null};if(e===`os`)return{laeuft:`Ubuntu`,neu:t.count?`${t.count} Pakete`:null};if(e===`hermes`)return{laeuft:t.installed_version?`v${t.installed_version}`:`–`,neu:t.behind?`+${t.behind.toLocaleString(`de-DE`)} Änderungen`:null};let n=e===`engine`?`b`:`v`;return{laeuft:t.installed_build==null?`–`:`${n}${t.installed_build}`,neu:t.latest_build!=null&&t.installed_build!=null&&t.latest_build>t.installed_build?`${n}${t.latest_build}`:null}}function Sc(e){let t=e.aliases.map(e=>e.toLowerCase());return t.includes(`hermes`)||t.includes(`fast`)?`hirn`:t.includes(`coder`)?`coder`:null}function Cc(e){let t=(0,F.c)(25),{anteil:n,farbe:r,zonen:i,mitte:a,unter:o,beschriftung:s,ariaText:c}=e,l=r===void 0?`var(--cyan)`:r,u;t[0]===i?u=t[1]:(u=i===void 0?[]:i,t[0]=i,t[1]=u);let d=u,f=n!=null&&n>.004,p;t[2]===Symbol.for(`react.memo_cache_sentinel`)?(p=(0,h.jsx)(`path`,{d:vc(0,1,75),fill:`none`,stroke:`var(--linie)`,strokeWidth:12,strokeLinecap:`round`}),t[2]=p):p=t[2];let m;t[3]===d?m=t[4]:(m=d.map(wc),t[3]=d,t[4]=m);let g;t[5]!==n||t[6]!==l||t[7]!==f?(g=f&&(0,h.jsx)(`path`,{d:vc(0,n,75),fill:`none`,stroke:l,strokeWidth:12,strokeLinecap:`round`}),t[5]=n,t[6]=l,t[7]=f,t[8]=g):g=t[8];let _;t[9]===Symbol.for(`react.memo_cache_sentinel`)?(_={fontSize:34,fontWeight:500,fill:`var(--foreground)`},t[9]=_):_=t[9];let v;t[10]===a?v=t[11]:(v=(0,h.jsx)(`text`,{x:`100`,y:`100`,textAnchor:`middle`,className:`ziffern`,style:_,children:a}),t[10]=a,t[11]=v);let y;t[12]===o?y=t[13]:(y=o&&(0,h.jsx)(`text`,{x:`100`,y:`122`,textAnchor:`middle`,style:{fontFamily:`var(--font-anzeige)`,fontSize:14,fontWeight:600,letterSpacing:`0.12em`,fill:`var(--text-3)`},children:o.toUpperCase()}),t[12]=o,t[13]=y);let b;t[14]!==c||t[15]!==m||t[16]!==g||t[17]!==v||t[18]!==y?(b=(0,h.jsxs)(`svg`,{viewBox:`0 0 200 150`,className:`h-auto w-full max-w-[200px]`,role:`img`,"aria-label":c,children:[p,m,g,v,y]}),t[14]=c,t[15]=m,t[16]=g,t[17]=v,t[18]=y,t[19]=b):b=t[19];let x;t[20]===s?x=t[21]:(x=(0,h.jsx)(`figcaption`,{className:`schild text-[15px] text-text-3`,children:s}),t[20]=s,t[21]=x);let S;return t[22]!==b||t[23]!==x?(S=(0,h.jsxs)(`figure`,{className:`m-0 flex min-w-0 flex-col items-center gap-1`,children:[b,x]}),t[22]=b,t[23]=x,t[24]=S):S=t[24],S}function wc(e){return(0,h.jsx)(`path`,{d:vc(e.von,e.bis,86),fill:`none`,stroke:e.farbe,strokeWidth:4,strokeLinecap:`round`},`${e.von}-${e.bis}`)}function Tc(e){let t=(0,F.c)(11),{titel:n,rechts:r,children:a,className:o,id:s}=e,c;t[0]===o?c=t[1]:(c=i(`flex min-w-0 flex-col gap-4 rounded-2xl border border-linie bg-panel p-5 sm:p-6`,o),t[0]=o,t[1]=c);let l;t[2]!==r||t[3]!==n?(l=(n||r)&&(0,h.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3`,children:[n&&(0,h.jsx)(`h2`,{className:`schild text-lg font-bold tracking-[0.22em] text-foreground`,children:n}),r]}),t[2]=r,t[3]=n,t[4]=l):l=t[4];let u;return t[5]!==a||t[6]!==s||t[7]!==c||t[8]!==l||t[9]!==n?(u=(0,h.jsxs)(`section`,{id:s,"aria-label":n,className:c,children:[l,a]}),t[5]=a,t[6]=s,t[7]=c,t[8]=l,t[9]=n,t[10]=u):u=t[10],u}var Ec={ok:{feld:`border-gruen-rand bg-gruen-grund`,name:`text-gruen`,wert:`text-gruen-text`},aus:{feld:`border-aus-rand bg-aus-grund`,name:`text-aus-text`,wert:`text-text-3`},warn:{feld:`border-bernstein bg-bernstein-lampe lampe-atmet`,name:`text-bernstein`,wert:`text-[#f2c46b]`},info:{feld:`border-cyan-rand bg-cyan-grund`,name:`text-cyan`,wert:`text-cyan-text`},fehler:{feld:`border-rot bg-rot-grund shadow-[0_0_18px_rgba(255,90,79,0.35)]`,name:`text-rot`,wert:`text-rot-text`}},Dc={ok:`in Ordnung`,aus:`aus`,warn:`braucht Aufmerksamkeit`,info:`Info`,fehler:`Störung`};function Oc(e){let t=(0,F.c)(19),{lampe:n}=e,r=Ec[n.zustand]??Ec.aus,a;t[0]===r.feld?a=t[1]:(a=i(`flex min-h-[58px] flex-col items-center justify-center gap-0.5 rounded-lg border px-2 py-2 text-center`,r.feld),t[0]=r.feld,t[1]=a);let o;t[2]===r.name?o=t[3]:(o=i(`schild text-[17px] leading-none font-bold tracking-[0.18em]`,r.name),t[2]=r.name,t[3]=o);let s;t[4]!==n.label||t[5]!==o?(s=(0,h.jsx)(`span`,{className:o,children:n.label}),t[4]=n.label,t[5]=o,t[6]=s):s=t[6];let c;t[7]===r.wert?c=t[8]:(c=i(`ziffern text-xs uppercase`,r.wert),t[7]=r.wert,t[8]=c);let l;t[9]!==n.wert||t[10]!==c?(l=(0,h.jsx)(`span`,{className:c,children:n.wert}),t[9]=n.wert,t[10]=c,t[11]=l):l=t[11];let u=Dc[n.zustand],d;t[12]===u?d=t[13]:(d=(0,h.jsx)(`span`,{className:`sr-only`,children:u}),t[12]=u,t[13]=d);let f;return t[14]!==a||t[15]!==s||t[16]!==l||t[17]!==d?(f=(0,h.jsxs)(`li`,{className:a,children:[s,l,d]}),t[14]=a,t[15]=s,t[16]=l,t[17]=d,t[18]=f):f=t[18],f}var kc={ok:`border-gruen-rand bg-gruen-grund text-gruen`,info:`border-cyan-rand bg-cyan-grund text-cyan`,stumm:`border-aus-rand bg-aus-grund text-aus-text`,gelb:`border-2 border-bernstein bg-bernstein-grund text-bernstein-hell lampe-atmet`,rot:`border-2 border-rot bg-rot-grund text-rot shadow-[0_0_32px_rgba(255,90,79,0.3)]`};function Ac(e){let t=(0,F.c)(26),{zustand:n,lampen:r,onAnsehen:a}=e,o;t[0]===n?o=t[1]:(o=bc(n),t[0]=n,t[1]=o);let s=o,c=s.art===`gelb`||s.art===`rot`,l=!c,u=`${s.oben} ${s.mitte}`,d=kc[s.art],f=c?`cursor-pointer`:`cursor-default`,p;t[2]!==d||t[3]!==f?(p=i(`flex min-h-[130px] flex-col items-center justify-center gap-1 rounded-2xl border px-4 py-4 font-anzeige transition-colors`,d,f),t[2]=d,t[3]=f,t[4]=p):p=t[4];let m;t[5]===s.oben?m=t[6]:(m=(0,h.jsx)(`span`,{className:`schild text-sm tracking-[0.26em]`,children:s.oben}),t[5]=s.oben,t[6]=m);let g;t[7]===s.mitte?g=t[8]:(g=(0,h.jsx)(`span`,{className:`text-[40px] leading-none font-bold tracking-[0.04em] sm:text-[44px]`,children:s.mitte}),t[7]=s.mitte,t[8]=g);let _;t[9]===s.unten?_=t[10]:(_=(0,h.jsx)(`span`,{className:`font-sans text-sm opacity-80`,children:s.unten}),t[9]=s.unten,t[10]=_);let v;t[11]!==a||t[12]!==l||t[13]!==u||t[14]!==p||t[15]!==m||t[16]!==g||t[17]!==_?(v=(0,h.jsxs)(`button`,{type:`button`,onClick:a,disabled:l,"aria-label":u,className:p,children:[m,g,_]}),t[11]=a,t[12]=l,t[13]=u,t[14]=p,t[15]=m,t[16]=g,t[17]=_,t[18]=v):v=t[18];let y;t[19]===r?y=t[20]:(y=r.map(jc),t[19]=r,t[20]=y);let b;t[21]===y?b=t[22]:(b=(0,h.jsx)(`ul`,{className:`grid grid-cols-2 gap-2.5 rounded-2xl border border-linie bg-panel p-3 sm:grid-cols-4`,children:y}),t[21]=y,t[22]=b);let x;return t[23]!==v||t[24]!==b?(x=(0,h.jsxs)(`section`,{"aria-label":`Warnpanel`,className:`grid gap-4 md:grid-cols-[260px_minmax(0,1fr)] md:gap-5`,children:[v,b]}),t[23]=v,t[24]=b,t[25]=x):x=t[25],x}function jc(e){return(0,h.jsx)(Oc,{lampe:e},e.id)}function Mc(e){let t=(0,F.c)(2),{z:n}=e,r;return t[0]===n?r=t[1]:(r=(0,h.jsx)(`span`,{className:`ziffern inline-flex h-14 w-[38px] items-center justify-center rounded-md border border-[#2a3036] bg-[#0b0d0f] text-[32px] font-medium`,children:n}),t[0]=n,t[1]=r),r}function Nc(e){let t=(0,F.c)(25),{sekunden:n}=e,r;t[0]===n?r=t[1]:(r=Xs(n),t[0]=n,t[1]=r);let i=r,a=String(Math.min(i?.[0]??0,99)),o;t[2]===a?o=t[3]:(o=a.padStart(2,`0`),t[2]=a,t[3]=o);let s=o,c=String(i?.[1]??0),l;t[4]===c?l=t[5]:(l=c.padStart(2,`0`),t[4]=c,t[5]=l);let u=l,d=i?`Laufzeit ohne Neustart: ${i[0]} Tage, ${i[1]} Stunden`:`Laufzeit unbekannt`,f=i?s[0]:`–`,p;t[6]===f?p=t[7]:(p=(0,h.jsx)(Mc,{z:f}),t[6]=f,t[7]=p);let m=i?s[1]:`–`,g;t[8]===m?g=t[9]:(g=(0,h.jsx)(Mc,{z:m}),t[8]=m,t[9]=g);let _;t[10]===Symbol.for(`react.memo_cache_sentinel`)?(_=(0,h.jsx)(`span`,{className:`schild mr-2 ml-0.5 text-lg font-bold text-text-3`,children:`T`}),t[10]=_):_=t[10];let v=i?u[0]:`–`,y;t[11]===v?y=t[12]:(y=(0,h.jsx)(Mc,{z:v}),t[11]=v,t[12]=y);let b=i?u[1]:`–`,x;t[13]===b?x=t[14]:(x=(0,h.jsx)(Mc,{z:b}),t[13]=b,t[14]=x);let S;t[15]===Symbol.for(`react.memo_cache_sentinel`)?(S=(0,h.jsx)(`span`,{className:`schild ml-0.5 text-lg font-bold text-text-3`,children:`H`}),t[15]=S):S=t[15];let C;t[16]!==y||t[17]!==x||t[18]!==p||t[19]!==g||t[20]!==d?(C=(0,h.jsxs)(`div`,{"aria-label":d,role:`img`,className:`flex h-[150px] max-w-full items-center gap-1.5 pb-5`,children:[p,g,_,y,x,S]}),t[16]=y,t[17]=x,t[18]=p,t[19]=g,t[20]=d,t[21]=C):C=t[21];let w;t[22]===Symbol.for(`react.memo_cache_sentinel`)?(w=(0,h.jsx)(`figcaption`,{className:`schild text-[15px] text-text-3`,children:`Ohne Neustart`}),t[22]=w):w=t[22];let T;return t[23]===C?T=t[24]:(T=(0,h.jsxs)(`figure`,{className:`m-0 flex min-w-0 flex-col items-center justify-end gap-1`,children:[C,w]}),t[23]=C,t[24]=T),T}function Pc(e){let t=(0,F.c)(47),{box:n}=e,r=uo(),i=r?.ram_used??n.ram_used,a=r?.ram_total??n.ram_total,o=r?.temp_cpu??n.temp_cpu,s=r?.temp_gpu??n.temp_gpu,c=n.platte,l=r?.uptime_s??n.uptime_s,u=i!=null&&a?i/a:null,d;t[0]===i?d=t[1]:(d=i==null?`–`:String(Math.round(Zs(i)??0)),t[0]=i,t[1]=d);let f;t[2]===a?f=t[3]:(f=a?`von ${Math.round(Zs(a)??0)} GB`:void 0,t[2]=a,t[3]=f);let p;t[4]!==u||t[5]!==i||t[6]!==a?(p=u==null?`Speicher unbekannt`:`Speicher: ${Qs(i)} von ${Qs(a)} belegt`,t[4]=u,t[5]=i,t[6]=a,t[7]=p):p=t[7];let m;t[8]!==u||t[9]!==d||t[10]!==f||t[11]!==p?(m=(0,h.jsx)(Cc,{beschriftung:`Speicher`,anteil:u,mitte:d,unter:f,ariaText:p}),t[8]=u,t[9]=d,t[10]=f,t[11]=p,t[12]=m):m=t[12];let g=o==null?null:o/100,_;t[13]===o?_=t[14]:(_=yc(o),t[13]=o,t[14]=_);let v;t[15]===Symbol.for(`react.memo_cache_sentinel`)?(v=[{von:.7,bis:.85,farbe:`var(--bernstein)`},{von:.85,bis:1,farbe:`var(--rot)`}],t[15]=v):v=t[15];let y;t[16]===o?y=t[17]:(y=o==null?`–`:`${Math.round(o)}°`,t[16]=o,t[17]=y);let b;t[18]===s?b=t[19]:(b=s==null?void 0:`GPU ${Math.round(s)}°`,t[18]=s,t[19]=b);let x;t[20]===o?x=t[21]:(x=o==null?`Temperatur unbekannt`:`Temperatur ${Math.round(o)} Grad`,t[20]=o,t[21]=x);let S;t[22]!==x||t[23]!==g||t[24]!==_||t[25]!==y||t[26]!==b?(S=(0,h.jsx)(Cc,{beschriftung:`Temperatur`,anteil:g,farbe:_,zonen:v,mitte:y,unter:b,ariaText:x}),t[22]=x,t[23]=g,t[24]=_,t[25]=y,t[26]=b,t[27]=S):S=t[27];let C=c?c.percent/100:null,w=c&&c.percent>=90?`var(--rot)`:c&&c.percent>=80?`var(--bernstein)`:`var(--cyan)`,T;t[28]===c?T=t[29]:(T=c?`${Math.round(c.percent)}%`:`–`,t[28]=c,t[29]=T);let ee;t[30]===c?ee=t[31]:(ee=c?`${Qs(c.used)} / ${Qs(c.total)}`:void 0,t[30]=c,t[31]=ee);let E;t[32]===c?E=t[33]:(E=c?`Platte zu ${Math.round(c.percent)} Prozent belegt`:`Platte unbekannt`,t[32]=c,t[33]=E);let te;t[34]!==C||t[35]!==w||t[36]!==T||t[37]!==ee||t[38]!==E?(te=(0,h.jsx)(Cc,{beschriftung:`Platte`,anteil:C,farbe:w,mitte:T,unter:ee,ariaText:E}),t[34]=C,t[35]=w,t[36]=T,t[37]=ee,t[38]=E,t[39]=te):te=t[39];let D;t[40]===l?D=t[41]:(D=(0,h.jsx)(Nc,{sekunden:l}),t[40]=l,t[41]=D);let ne;return t[42]!==S||t[43]!==te||t[44]!==D||t[45]!==m?(ne=(0,h.jsxs)(`section`,{"aria-label":`Instrumente`,className:`grid grid-cols-2 gap-x-4 gap-y-6 rounded-2xl border border-linie bg-panel px-4 py-5 lg:grid-cols-4 lg:px-6`,children:[m,S,te,D]}),t[42]=S,t[43]=te,t[44]=D,t[45]=m,t[46]=ne):ne=t[46],ne}var Fc={bestanden:`gruen`,durchgefallen:`rot`,wartet:`cyan`,neu:`cyan`};function Ic(e){let t=(0,F.c)(14),{radar:n}=e;if(!n?.kandidaten)return null;let r,i;t[0]===n.kandidaten?(r=t[1],i=t[2]):(r=n.kandidaten.filter(Rc),i=r.find(Lc)??r[0],t[0]=n.kandidaten,t[1]=r,t[2]=i);let a=i,o=r.length===1?``:`en`,s;t[3]!==r.length||t[4]!==o?(s=(0,h.jsxs)(`span`,{className:`schild text-sm text-cyan`,children:[`Radar · `,r.length,` Kandidat`,o]}),t[3]=r.length,t[4]=o,t[5]=s):s=t[5];let l;t[6]===a?l=t[7]:(l=a?(0,h.jsxs)(`span`,{className:`flex flex-wrap items-center gap-2 text-[15px]`,children:[(0,h.jsx)(`span`,{className:`ziffern`,children:a.name}),(0,h.jsxs)(`span`,{className:`text-text-2`,children:[`fürs `,a.rolle===`hirn`?`Hirn`:`Coden`]}),(0,h.jsx)(oc,{art:Fc[a.status]??`grau`,children:a.status})]}):(0,h.jsx)(`span`,{className:`text-[15px] text-text-2`,children:`Nichts Besseres in Sicht.`}),t[6]=a,t[7]=l);let u;t[8]!==s||t[9]!==l?(u=(0,h.jsxs)(`div`,{className:`flex min-w-0 flex-col gap-1`,children:[s,l]}),t[8]=s,t[9]=l,t[10]=u):u=t[10];let d;t[11]===Symbol.for(`react.memo_cache_sentinel`)?(d=(0,h.jsx)(c,{variant:`info`,size:`sm`,asChild:!0,children:(0,h.jsx)(pa,{to:`/modelle`,hash:`radar`,children:`Ansehen`})}),t[11]=d):d=t[11];let f;return t[12]===u?f=t[13]:(f=(0,h.jsxs)(`div`,{className:`mt-auto flex flex-wrap items-center justify-between gap-3 rounded-xl border border-cyan-rand bg-cyan-grund px-4 py-3.5`,children:[u,d]}),t[12]=u,t[13]=f),f}function Lc(e){return e.status===`bestanden`}function Rc(e){return[`bestanden`,`wartet`,`neu`].includes(e.status)}function zc(){let e=(0,F.c)(32),{data:t,error:n,isPending:r}=Yo(),i=Qo();if(r){let t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t=(0,h.jsx)(sc,{text:`Die Box meldet sich gleich …`}),e[0]=t):t=e[0],t}if(n||!t){let t=`MC2 antwortet nicht: ${n?.message??`keine Daten`}`,r;return e[1]===t?r=e[2]:(r=(0,h.jsx)(sc,{fehler:!0,text:t}),e[1]=t,e[2]=r),r}let a=t.hinweise.length,o;e[3]!==t.lampen||e[4]!==t.zustand?(o=(0,h.jsx)(Ac,{zustand:t.zustand,lampen:t.lampen,onAnsehen:Bc}),e[3]=t.lampen,e[4]=t.zustand,e[5]=o):o=e[5];let s;e[6]===t.box?s=e[7]:(s=(0,h.jsx)(Pc,{box:t.box}),e[6]=t.box,e[7]=s);let c=a?`ziffern text-sm text-bernstein`:`ziffern text-sm text-gruen`,l=a?`${a} offen`:`alles erledigt`,u;e[8]!==c||e[9]!==l?(u=(0,h.jsx)(`span`,{className:c,children:l}),e[8]=c,e[9]=l,e[10]=u):u=e[10];let d;e[11]!==t.hinweise||e[12]!==t.verlauf?(d=(0,h.jsx)(nc,{hinweise:t.hinweise,verlauf:t.verlauf}),e[11]=t.hinweise,e[12]=t.verlauf,e[13]=d):d=e[13];let f;e[14]!==u||e[15]!==d?(f=(0,h.jsx)(Tc,{titel:`Checkliste`,id:`checkliste`,rechts:u,children:d}),e[14]=u,e[15]=d,e[16]=f):f=e[16];let p;e[17]!==t.flugplan.gelaufen||e[18]!==t.flugplan.geplant?(p=(0,h.jsx)(uc,{gelaufen:t.flugplan.gelaufen,geplant:t.flugplan.geplant}),e[17]=t.flugplan.gelaufen,e[18]=t.flugplan.geplant,e[19]=p):p=e[19];let m;e[20]===i.data?m=e[21]:(m=(0,h.jsx)(Ic,{radar:i.data}),e[20]=i.data,e[21]=m);let g;e[22]!==p||e[23]!==m?(g=(0,h.jsxs)(Tc,{titel:`Flugplan`,children:[p,m]}),e[22]=p,e[23]=m,e[24]=g):g=e[24];let _;e[25]!==f||e[26]!==g?(_=(0,h.jsxs)(`div`,{className:`grid gap-5 lg:grid-cols-[minmax(0,1.35fr)_minmax(0,1fr)] md:gap-6`,children:[f,g]}),e[25]=f,e[26]=g,e[27]=_):_=e[27];let v;return e[28]!==o||e[29]!==s||e[30]!==_?(v=(0,h.jsxs)(h.Fragment,{children:[o,s,_]}),e[28]=o,e[29]=s,e[30]=_,e[31]=v):v=e[31],v}function Bc(){return document.getElementById(`checkliste`)?.scrollIntoView({behavior:`smooth`,block:`start`})}var Vc=va({component:Uo,notFoundComponent:()=>(0,h.jsx)(Qi,{to:`/`})}),Hc=ga({getParentRoute:()=>Vc,path:`/`,component:zc}),Uc=ga({getParentRoute:()=>Vc,path:`/updates`,component:ya(()=>Mo(()=>import(`./Updates-3PYj6oWY.js`),__vite__mapDeps([7,1,3])),`UpdatesSeite`)}),Wc=ga({getParentRoute:()=>Vc,path:`/modelle`,component:ya(()=>Mo(()=>import(`./Modelle-PWfbWtFC.js`),__vite__mapDeps([8,1,2,3])),`ModelleSeite`)}),Gc=Ia({routeTree:Vc.addChildren([Hc,Uc,Wc]),defaultPreload:`intent`,defaultErrorComponent:Va}),Kc=`mc_neuladen_wegen_version`;function qc(){window.addEventListener(`vite:preloadError`,e=>{sessionStorage.getItem(Kc)||(e.preventDefault(),sessionStorage.setItem(Kc,`1`),window.location.reload())}),window.addEventListener(`load`,()=>{window.setTimeout(()=>sessionStorage.removeItem(Kc),5e3)})}qc();var Jc=new qe({defaultOptions:{queries:{retry:1,refetchOnWindowFocus:!1,staleTime:5e3}}});(0,Ba.createRoot)(document.getElementById(`root`)).render((0,h.jsx)(m.StrictMode,{children:(0,h.jsx)(v,{client:Jc,children:(0,h.jsx)(za,{router:Gc})})}));export{uo as A,z as C,I as D,us as E,_ as F,eo as M,Ja as N,R as O,ot as P,Yo as S,ts as T,ns as _,sc as a,ps as b,Qs as c,ls as d,B as f,Zo as g,Xo as h,oc as i,no as j,xo as k,$s as l,ds as m,Sc as n,qs as o,$o as p,xc as r,Zs as s,Tc as t,rs as u,Qo as v,cs as w,es as x,fs as y}; \ No newline at end of file +\r`.includes(e)?``:encodeURIComponent(e))),Un(e)}function Gn(e){let t=e.getLocation(),n=new Set,r=r=>{t=e.getLocation(),n.forEach(e=>e({location:t,action:r}))},i=n=>{e.notifyOnIndexChange??!0?r(n):t=e.getLocation()},a=async({task:n,navigateOpts:r,...i})=>{if(r?.ignoreBlocker??!1){n();return}let a=e.getBlockers?.()??[],o=i.type===`PUSH`||i.type===`REPLACE`;if(typeof document<`u`&&a.length&&o)for(let n of a){let r=Jn(i.path,i.state);if(await n.blockerFn({currentLocation:t,nextLocation:r,action:i.type})){e.onBlocked?.();return}}n()};return{get location(){return t},get length(){return e.getLength()},subscribers:n,subscribe:e=>(n.add(e),()=>{n.delete(e)}),push:(n,i,o)=>{let s=t.state[zn];i=Kn(s+1,i),a({task:()=>{e.pushState(n,i),r({type:`PUSH`})},navigateOpts:o,type:`PUSH`,path:n,state:i})},replace:(n,i,o)=>{let s=t.state[zn];i=Kn(s,i),a({task:()=>{e.replaceState(n,i),r({type:`REPLACE`})},navigateOpts:o,type:`REPLACE`,path:n,state:i})},go:(t,n)=>{a({task:()=>{e.go(t,n?.ignoreBlocker??!1),i({type:`GO`,index:t})},navigateOpts:n,type:`GO`})},back:t=>{a({task:()=>{e.back(t?.ignoreBlocker??!1),i({type:`BACK`})},navigateOpts:t,type:`BACK`})},forward:t=>{a({task:()=>{e.forward(t?.ignoreBlocker??!1),i({type:`FORWARD`})},navigateOpts:t,type:`FORWARD`})},canGoBack:()=>t.state[zn]!==0,createHref:t=>e.createHref(t),block:t=>{if(!e.setBlockers)return()=>{};let n=e.getBlockers?.()??[];return e.setBlockers([...n,t]),()=>{let n=e.getBlockers?.()??[];e.setBlockers?.(n.filter(e=>e!==t))}},flush:()=>e.flush?.(),destroy:()=>e.destroy?.(),notify:r,_getBlockers:()=>e.getBlockers?.()??[]}}function Kn(e,t){let n=Yn();return{...t,key:n,__TSR_key:n,[zn]:e}}function qn(e){let t=e?.window??(typeof document<`u`?window:void 0),n=t.history.pushState,r=t.history.replaceState,i=[],a=()=>i,o=e=>i=e,s=t=>Wn(e?.createHref?e.createHref(t):t),c=e?.parseLocation??(()=>Jn(`${t.location.pathname}${t.location.search}${t.location.hash}`,t.history.state));if(!t.history.state?.__TSR_key&&!t.history.state?.key){let e=Yn();t.history.replaceState({[zn]:0,key:e,__TSR_key:e},``)}let l=c(),u,d=!1,f=!1,p=!1,m=!1,h=()=>l,g,_=()=>{g&&(S._ignoreSubscribers=!0,(g[2]?t.history.pushState:t.history.replaceState)(g[1],``,g[0]),S._ignoreSubscribers=!1,g=void 0,u=void 0)},v=(t,n,r)=>{let i=e?.createHref?s(n):void 0,a=!!g;a||(u=l),l=Jn(n,r),g=[i??l.href,r,g?.[2]||t],a||queueMicrotask(()=>_())},y=e=>{l=c(),S.notify({type:e})},b=async()=>{if(m=!1,f){f=!1;return}let e=c(),n=e.state[zn]-l.state[zn],r=n===1,i=n===-1,o=!r&&!i||d;d=!1;let s=o?`GO`:i?`BACK`:`FORWARD`,u=o?{type:`GO`,index:n}:{type:i?`BACK`:`FORWARD`};if(p)p=!1;else{let r=a();if(typeof document<`u`&&r.length){for(let i of r)if(await i.blockerFn({currentLocation:l,nextLocation:e,action:s})){f=!0,t.history.go(-n),S.notify(u);return}}}l=c(),S.notify(u)},x=e=>{if(m){m=!1;return}let t=!1,n=a();if(typeof document<`u`&&n.length)for(let e of n){let n=e.enableBeforeUnload??!0;if(n===!0){t=!0;break}if(typeof n==`function`&&n()===!0){t=!0;break}}if(t)return e.preventDefault(),e.returnValue=``},S=Gn({getLocation:h,getLength:()=>t.history.length,pushState:(e,t)=>v(!0,e,t),replaceState:(e,t)=>v(!1,e,t),back:e=>(e&&(p=!0,m=!0),t.history.back()),forward:e=>{e&&(p=!0,m=!0),t.history.forward()},go:(e,n)=>{d=!0,n&&(p=!0,m=!0),t.history.go(e)},createHref:e=>s(e),flush:_,destroy:()=>{t.history.pushState=n,t.history.replaceState=r,t.removeEventListener(Vn,x,{capture:!0}),t.removeEventListener(Bn,b)},onBlocked:()=>{u&&l!==u&&(l=u)},getBlockers:a,setBlockers:o,notifyOnIndexChange:!1});return S._ignoreNextBeforeUnload=e=>{m=!1;try{e=new URL(e,t.document.baseURI).href,m=/^https?:/.test(e)&&(!e.includes(`#`)||e.split(`#`)[0]!==t.location.href.split(`#`)[0])}catch{}},t.addEventListener(Vn,x,{capture:!0}),t.addEventListener(Bn,b),t.history.pushState=function(...e){let r=n.apply(t.history,e);return S._ignoreSubscribers||y(`PUSH`),r},t.history.replaceState=function(...e){let n=r.apply(t.history,e);return S._ignoreSubscribers||y(`REPLACE`),n},S}function Jn(e,t){let n=Wn(e),r=n.indexOf(`#`),i=n.indexOf(`?`);if(!t){let e=Yn();t={[zn]:0,key:e,__TSR_key:e}}return{href:n,pathname:n.substring(0,r>0?i>0?Math.min(r,i):r:i>0?i:n.length),hash:r>-1?n.substring(r):``,search:i>-1?n.slice(i,r===-1?void 0:r):``,state:t}}function Yn(){return(Math.random()+1).toString(36).substring(7)}function Xn(e,t){return e.protocol!==`http:`&&e.protocol!==`https:`||e.origin!==t||!!e.username||!!e.password}function Zn(e){return e.pathname+e.search+e.hash}function Qn(e){return e.options.loader||e.options.beforeLoad||e.lazyFn||e.options.component?.preload||e.options.pendingComponent?.preload}function $n(e,t){return{fromLocation:t,toLocation:e,pathChanged:t?.pathname!==e.pathname,hrefChanged:t?.href!==e.href,hashChanged:t?.hash!==e.hash}}function er({key:e,__TSR_key:t,__TSR_index:n,__hashScrollIntoViewOptions:r,...i}){return i}function tr(e){return e.findIndex(e=>e.status===`error`||e.status===`notFound`||e._notFound)+1}function nr(e,t,n,r,i,a){r&&(t=t.slice(0,r)),i&&(n=n.slice(0,i));for(let r of t){if(a&&e._tx!==a)return;n.some(e=>e.routeId===r.routeId)||e.routesById[r.routeId].options.onLeave?.(r)}for(let r of n){if(a&&e._tx!==a)return;e.routesById[r.routeId].options[t.some(e=>e.routeId===r.routeId)?`onStay`:`onEnter`]?.(r)}}var rr=class{constructor(e,t){this.tempLocationKey=`${Math.round(Math.random()*1e7)}`,this._scroll={next:!0},this.subscribers=new Set,this._cache=new Map,this._committed=[],this.startTransition=async e=>(e(),!1),this.update=e=>{let t=this.options;this.options={...t,...e},this.isServer=this.options.isServer??!1??typeof document>`u`,this.staticLocations=new WeakMap,this.protocolAllowlist=new Set(this.options.protocolAllowlist),(!this.history||this.options.history&&this.options.history!==this.history)&&(this.history=this.options.history?this.options.history:qn()),this.origin=this.options.origin,this.origin||=window?.origin&&window.origin!==`null`?window.origin:`http://localhost`;let n=this.options.basepath??`/`,r=this.options.rewrite,i=this.basepath!==n||t?.rewrite!==r||t?.caseSensitive!==this.options.caseSensitive;if(i&&(this.basepath=n,this.rewrite=n!==`/`&&Pt(n)?Fn(n,this.options.caseSensitive,r):r),this.history&&this.updateLatestLocation(),this.options.routeTree!==this.routeTree){this.routeTree=this.options.routeTree;let e;e=this.buildRouteTree(),this.setRoutes(e)}if(this.stores)i&&this.stores.location.set(this.latestLocation);else if(this.latestLocation){let e=this.getStoreConfig(this);this.batch=e.batch,this.stores=Rn(this.latestLocation,e),en(this)}},this.updateLatestLocation=()=>{this.latestLocation=this.parseLocation(this.history.location,this.latestLocation)},this.buildRouteTree=()=>{let e=Tn(this.routeTree,this.options.caseSensitive);return this.options.routeMasks&&xn(this.options.routeMasks,e.processedTree),{...e,resolvePathCache:pn(1e3)}},this.subscribe=(e,t)=>{let n={eventType:e,fn:t};return this.subscribers.add(n),()=>{this.subscribers.delete(n)}},this.emit=e=>{for(let t of this.subscribers)if(t.eventType===e.type)try{t.fn(e)}catch(e){console.error(e)}},this.parseLocation=(e,t)=>{let n=({pathname:e,search:n,hash:r,href:i},a)=>{if(!this.rewrite&&!/[ \x00-\x1f\x7f\u0080-\uffff]/.test(e)){let i=this.options.parseSearch(n),o=this.options.stringifySearch(i);return{href:e+o+r,publicHref:e+o+r,pathname:Dt(e),external:!1,searchStr:o,search:ht(t?.search,i),hash:Dt(r.slice(1)),state:gt(t?.state,a)}}let o=In(this.rewrite,new URL(i,this.origin)),s=this.options.parseSearch(o.search),c=this.options.stringifySearch(s);return o.search=c,{href:o.href.replace(o.origin,``),publicHref:i,pathname:Dt(Un(o.pathname)),external:!!this.rewrite&&Xn(o,this.origin),searchStr:c,search:ht(t?.search,s),hash:Dt(o.hash.slice(1)),state:gt(t?.state,a)}},r=n(e,e.state),{__tempLocation:i,__tempKey:a}=r.state;if(i&&(!a||a===this.tempLocationKey)){let e=n(i,{...i.state,__tempLocation:void 0,key:r.state.key,__TSR_key:r.state.__TSR_key});return e.maskedLocation=r,e}return r},this.matchRoutes=(e,t,n)=>typeof e==`string`?this.matchRoutesInternal({pathname:e,search:t},n):this.matchRoutesInternal(e,t),this.getMatchedRoutes=e=>{let t=Object.create(null),n=wn(Nt(e),this.processedTree,!0);return n&&Object.assign(t,n.rawParams),[n?.branch||[this.routesById.__root__],t,n?.route]},this.buildLocation=e=>{{let t=this.staticLocations.get(e);if(t)return t}let t=!1,n=(n={})=>{if(n.href){let e=Jn(n.href,{});n={...n,to:In(this.rewrite,new URL(e.pathname,this.origin)).pathname,search:this.options.parseSearch(e.search),hash:e.hash.slice(1)}}let r=n._fromLocation||this._pendingLocation||this.latestLocation,i,a=()=>(t=!0,r),o=()=>(t=!0,i??=this.matchRoutesLightweight(r)),s=n.to?`${n.to}`:`.`,c=It(s[0]===`/`?``:n.unsafeRelative===`path`?a().pathname:n.from??o()[1],s,this.options.trailingSlash,this.resolvePathCache),l=this.routesByPath[Nt(c)],u=c.includes(`$`),d;if(l)d=l._branch??=On(l);else if(u)d=[];else{let[e,t,n]=this.getMatchedRoutes(c);d=e,this.options.notFoundRoute&&(!n||n.path!==`/`&&t[`**`])&&(d=[...d,this.options.notFoundRoute])}let f=u?l?._interpolation??vn(!1,{fullPath:c},0):void 0,p;for(let e of d){let t=e.options.params?.stringify??e.options.stringifyParams;if(t){let e=o()[3];if(p??=cr(n.params,e),!pt(p))break;p===e&&(p=Object.assign(mt(),p));try{Object.assign(p,t(p))}catch{}}}p??=cr(n.params,lr(n.params,f)?o()[3]:ur);let m=e.leaveParams?c:Un(Dt(f?Bt(c,f,p,this.pathParamsDecoder):c)),h=dr(d,e._includeValidateSearch),g=()=>{let t=o()[2];if(e._includeValidateSearch&&this.options.search?.strict){let e={};d.forEach(n=>{if(n.options.validateSearch)try{Object.assign(e,sr(n.options.validateSearch,{...e,...t}))}catch{}}),t=e}return t},_=h.length?fr(h,g(),n):n.search===!0?g():typeof n.search==`function`?n.search(g()):n.search||ur,v=this.options.stringifySearch(_),y=n.hash===!0?a().hash:typeof n.hash==`function`?n.hash(a().hash):n.hash||void 0,b=y?`#${y}`:``,x=n.state?n.state===!0?a().state:typeof n.state==`function`?n.state(a().state):n.state:ur,S=`${m}${v}${b}`,C,w,T=!1;if(this.rewrite){let e=new URL(S,this.origin),t=e.origin,n=Ln(this.rewrite,e);C=Zn(e),Xn(n,t)?(w=n.href,T=!0):w=Un(Zn(n))}else C=Ot(S),w=C;return{publicHref:w,href:C,pathname:m,search:_,searchStr:v,state:x,hash:y??``,external:T,unmaskOnReload:n.unmaskOnReload}},r=n(e);if(e.mask)r.maskedLocation=n({from:e.from,...e.mask});else if(this.options.routeMasks){let t=Sn(r.pathname,this.processedTree);if(t){let i=Object.assign(mt(),t.rawParams),{from:a,params:o,...s}=t.route,c=cr(o,i);r.maskedLocation=n({from:e.from,...s,params:c})}}return!t&&e._fromLocation&&!r.maskedLocation&&this.staticLocations.set(e,r),r},this.commitLocation=async({viewTransition:e,ignoreBlocker:t,...n})=>{let r=n.maskedLocation??n;if(r.external)return ir(this,r.publicHref,{replace:n.replace,ignoreBlocker:t});let i,a=Nt(this.latestLocation.href)===Nt(n.href)&&vt(er(n.state),er(this.latestLocation.state)),o=this._commitPromise,s,c=new Promise(e=>{s=e});if(c.resolve=()=>{s(),o?.resolve()},this._commitPromise=c,a)this.load();else{let{maskedLocation:r,hashScrollIntoView:a,...o}=n;r&&(o={...r,state:{...r.state,__tempKey:void 0,__tempLocation:{...o,search:o.searchStr,state:{...o.state,__tempKey:void 0,__tempLocation:void 0,__TSR_key:void 0,key:void 0}}}},(o.unmaskOnReload??this.options.unmaskOnReload??!1)&&(o.state.__tempKey=this.tempLocationKey)),o.state={...o.state,__hashScrollIntoViewOptions:a??this.options.defaultHashScrollIntoView??!0},this.shouldViewTransition=e,i=n.replace?`REPLACE`:`PUSH`,this.history[i===`REPLACE`?`replace`:`push`](o.publicHref,o.state,{ignoreBlocker:t}),this.history.subscribers.size||this.load({action:{type:i}})}return this._scroll.next=n.resetScroll??!0,this._commitPromise},this.buildAndCommitLocation=({replace:e,resetScroll:t,hashScrollIntoView:n,viewTransition:r,ignoreBlocker:i,...a}={})=>{let o=this.buildLocation({...a,_includeValidateSearch:!0});this._pendingLocation=o;let s=this.commitLocation({...o,viewTransition:r,replace:e,resetScroll:t,hashScrollIntoView:n,ignoreBlocker:i});return queueMicrotask(()=>{this._pendingLocation===o&&(this._pendingLocation=void 0)}),s},this.navigate=async({to:e,reloadDocument:t,href:n,publicHref:r,...i})=>{let a=n?wt(n):void 0;if(a||t){if(e!==void 0||!n){let t=this.buildLocation({to:e,...i}),a=t.maskedLocation??t;n??=a.publicHref,r??=a.publicHref}let t=!a&&r?r:n;return ir(this,t,i)}return this.buildAndCommitLocation({...i,href:n,to:e,_isNavigate:!0})},this.load=async e=>{this.updateLatestLocation(),e?.action&&(this._scroll.hash=e.action.type===`PUSH`||e.action.type===`REPLACE`),await ii(this,e)},this.startViewTransition=e=>{let t=this.shouldViewTransition??this.options.defaultViewTransition;if(this.shouldViewTransition=void 0,t&&typeof document.startViewTransition==`function`){let n;if(typeof t==`object`&&window.CSS?.supports?.(`selector(:active-view-transition-type(a))`)){let r=this.latestLocation,i=this.stores.resolvedLocation.get(),a=typeof t.types==`function`?t.types($n(r,i)):t.types;if(a===!1)return e();n={update:e,types:a}}else n=e;return document.startViewTransition(n).updateCallbackDone}return e()},this.invalidate=e=>{let t=this._committed,n=e?.filter,r=this._preloads,i=new Set,a=e=>{(!n||n(e))&&i.add(e.id)};t.forEach(a),this._cache.forEach(a),r?.forEach(e=>e.forEach(a)),this._tx?.[3].forEach(a);let o=[];for(let[e,t]of r??[])t.some(e=>i.has(e.id))&&(r.delete(e),o.push(e));let s=t=>{if(i.has(t.id)){let n=this.routesById[t.routeId],r={...t,invalid:!0,...(e?.forcePending||t.status===`error`||t.status===`notFound`)&&Qn(n)?{status:`pending`,error:void 0}:void 0};return t._flight=void 0,r}return t};this._committed=t.map(s);for(let[t,n]of this._cache)i.has(t)&&(n.invalid=!0,e?.forcePending&&(n.status=`pending`));for(let e of i)this._flights?.delete(e);for(let e of o)e.abort();return this.shouldViewTransition=!1,this.load({sync:e?.sync})},this.resolveRedirect=e=>{let t=e.options,n=e.headers.get(`Location`)||t.href;if(!n){let e=this.buildLocation(t);n=(e.maskedLocation??e).publicHref||`/`}let r;if(Tt.test(n)||(r=wt(n))&&!this.protocolAllowlist.has(r))throw Error(`Redirect blocked: unsafe protocol`);if(r===`http:`||r===`https:`){let e=new URL(n);e.pathname.startsWith(`//`)?n=e.href:Xn(e,this.origin)||(n=Zn(e),r=void 0)}return r&&(t.reloadDocument=!0),t.href=n,e.headers.set(`Location`,n),e},this.clearCache=e=>{let t=this._cache,n=this._preloads,r=e?.filter,i=[],a=[];for(let[e,n]of t)(!r||r(n))&&(a.push(e),i.push(n));let o=[];for(let[e,t]of n??[])(!r||t.some(r))&&(o.push(e),i.push(...t));for(let e of a)t.delete(e);for(let e of o)n.delete(e);for(let e of i){let t=e._flight;e._flight=void 0,t&&!--t[2]&&(this._flights?.get(e.id)===t&&this._flights.delete(e.id),o.push(t[1]))}for(let e of o)e.abort()},this.loadRouteChunk=_r,this.preloadRoute=e=>ai(this,e),this.matchRoute=(e,t)=>{let n={...e,to:e.to?It(e.from||``,e.to,this.options.trailingSlash,this.resolvePathCache):void 0,params:e.params||{},leaveParams:!0},r=this.buildLocation(n),i=this.stores.status.get()===`pending`;if(t?.pending&&!i)return!1;let a=t?.pending??!i?this.latestLocation:this.stores.resolvedLocation.get()||this.stores.location.get(),o=Cn(r.pathname,t?.caseSensitive??!1,t?.fuzzy??!1,a.pathname,this.processedTree);return!o||e.params&&!vt(o.rawParams,e.params,!0)?!1:t?.includeSearch??!0?vt(a.search,r.search,!0)?o.rawParams:!1:o.rawParams},this.getStoreConfig=t,e.pathParamsAllowedCharacters?.length&&(this.pathParamsDecoder=Lt(e.pathParamsAllowedCharacters)),this.update({defaultPreloadDelay:50,defaultPendingMs:1e3,defaultPendingMinMs:500,context:void 0,...e,caseSensitive:e.caseSensitive??!1,notFoundMode:e.notFoundMode??`fuzzy`,stringifySearch:e.stringifySearch??sn,parseSearch:e.parseSearch??on,protocolAllowlist:e.protocolAllowlist??Ct}),self.__TSR_ROUTER__=this}isShell(){return!!this.options.isShell}get state(){return this.stores.__store.get()}setRoutes(e){Object.assign(this,e),this.lightweightCache=new WeakMap,this.staticLocations=new WeakMap;let t=this.options.notFoundRoute;t&&(t.init(99999999999),this.routesById[t.id]!==t&&(t._interpolation=vn(!1,t,0)),this.routesById[t.id]=t)}matchRoutesInternal(e,t){let[n,r,i]=this.getMatchedRoutes(e.pathname),a=n,o=!1;(i?i.path!==`/`&&r[`**`]:Nt(e.pathname))&&(this.options.notFoundRoute?a=[...a,this.options.notFoundRoute]:o=!0);let s=o?pr(this.options.notFoundMode,a):void 0,c=Array(a.length),l=this._committed,u=(e,t)=>{let n=l[t];return n?.routeId===e.id?n:e===this.options.notFoundRoute?l.find(t=>t.routeId===e.id):void 0},d;for(let n=0;ntypeof t!=`string`&&!ft.call(e,t[1]))}var ur=Object.freeze({});function dr(e,t){let n=[];for(let r=0;r{let n=t(i.preSearchFilters?i.preSearchFilters.reduce((e,t)=>t(e),e):e);return i.postSearchFilters?i.postSearchFilters.reduce((e,t)=>t(e),n):n});let a=i.validateSearch;t&&a&&n.push(({search:e,next:t,meta:n})=>{let r=t(e);try{let e=sr(a,r);if(n&&e)for(let t in e)t in r||(n.defaulted||=new Map).set(t,e[t]);return{...r,...e}}catch{}return r})}return n}function fr(e,t,n){let r=(t,i,a)=>{if(t>=e.length){if(!n.search)return{};if(n.search===!0)return i;let e=dt(n.search,i);return a&&(a.explicit=e),e}return e[t]({search:i,next:(e,n)=>{if(n){let n=a||{};return{search:r(t+1,e,n),meta:n}}return r(t+1,e,a)},meta:a})};return r(0,t)}function pr(e,t){if(e!==`root`){let e;for(let n=t.length-1;n>=0;n--){let r=t[n];if(r.options.notFoundComponent)return r.id;e||=r.children&&r.id}if(e)return e}return un}function mr(e,t){let n=e.options.params?.parse??e.options.parseParams;n&&Object.assign(t,n(t))}function hr(e,t){return e.options[t]?.preload?.()}function gr(e,t){let n=hr(e,`component`),r=hr(e,`pendingComponent`);return t&&(r?r=r.then(t):t()),n&&r?Promise.all([n,r]).then(()=>{}):n??r}function _r(e,t,n){let r=()=>t===!1?void 0:t?hr(e,t):gr(e,n),i=e._lazy;if(i)return i===!0?r():i.then(r);if(!e.lazyFn)return r();let a=e.lazyFn().then(t=>{{let{id:n,...r}=t.options;Object.assign(e.options,r),e._lazy=!0}},t=>{throw e._lazy=void 0,t});return e._lazy=a,a.then(r)}function vr(e){let t=e.findIndex(e=>e.status!==`success`||e._notFound)+1;return t&&t{let i=()=>r(t);t.addEventListener(`abort`,i,{once:!0}),Promise.resolve(e).then(n,r).then(()=>t.removeEventListener(`abort`,i))})}function Er(e,t){return e.routesById[t.routeId]}function Dr(e,t,n){return fn(e)?[Sr,e]:Vt(e)?(e.routeId||=n,[xr,e]):t?(typeof e?.then==`function`&&(e=Error(`A Promise was thrown`,{cause:e})),[br,e]):[yr,e]}function Or(e,t){let n=Dr(t,!0,e.id);if(n[0]!==br)return n;try{e.options.onError?.(n[1])}catch(t){n=Dr(t,!0,e.id)}return n}function kr(e,t,n,r,i){return i[0].signal.aborted?Cr:Gr(e,t,n,Or(n,r),i)}async function Ar(e,t,n,r,i,a){let[o,s]=t,c=n[0].signal,l=!!n[3];for(let i=n[6]??0;ie.navigate({...t,_fromLocation:o}),buildLocation:e.buildLocation,cause:l?`preload`:r.cause,abortController:n[0],preload:l,matches:s,routeId:u.id};try{let e=r._ctx||=u.options.context?u.options.context({...f,deps:r.loaderDeps,context:d})||{}:void 0;r.context={...d,...e}}catch(a){return Mr(e,r),[i,kr(e,t,u,a,n)]}if(c.aborted)return[i,Cr];let p=r.paramsError??r.searchError;if(p!==void 0)return Mr(e,r),[i,kr(e,t,u,p,n)];let m=u.options.beforeLoad;if(!m)continue;let h=r.status;i>=a&&(r.status=`pending`,n[7]?.());try{Fr(e,r,`beforeLoad`,n[0]);let a=m({...f,search:r.search,context:r.context,...e.options.additionalContext}),o=await(typeof a?.then==`function`?Tr(a,c):a);if(c.aborted)return[i,Cr];let s=Gr(e,t,u,Dr(o,!1,u.id),n);if(s[0]!==yr)return Mr(e,r),[i,s];r.context={...r.context,...o}}catch(a){return Mr(e,r),[i,kr(e,t,u,a,n)]}finally{r.status=h,Fr(e,r,!1,n[0])}}i()}function jr(e,t,n){if(!(!n||--n[2])){if(e._flights?.get(t.id)===n){let n=e._tx;if(n&&!n[0].signal.aborted&&!n[3].includes(t)&&n[3].some(e=>e.id===t.id)&&n[3].some(e=>e.isFetching===`beforeLoad`))return;e._flights.delete(t.id)}return n[1]}}function Mr(e,t){let n=t._flight;t._flight=void 0,jr(e,t,n)?.abort()}function Nr(e,t,n,r){let i=[];for(let a of t)if(!n?.includes(a)){let t=a._flight;if(a._flight=void 0,r&&t?.[2]===1&&e._flights?.get(a.id)===t&&n?.some(e=>e.id===a.id))t[2]=0;else{let n=jr(e,a,t);n&&i.push(n)}}for(let e of i)e.abort()}function Pr(e){for(let t of e){let e=t._flight;e&&e[2]++}}function Fr(e,t,n,r){if(t.isFetching=n,r&&e._tx?.[0]!==r)return;let i=e.stores.byRoute.get(t.routeId),a=i?.get();a?.id===t.id&&i.set({...a,isFetching:n})}function Ir(e,t,n,r,i,a,o){let s=t[0];return{params:n.params,location:s,navigate:t=>e.navigate({...t,_fromLocation:s}),cause:o?`preload`:n.cause,abortController:i,preload:o,deps:n.loaderDeps,parentMatchPromise:a,context:n.context,route:r,...e.options.additionalContext}}async function Lr(e,t,n,r,i,a,o){let s=o[0],c=s.signal;if(c.aborted)return Cr;if(!i)return[yr,void 0];let l=n._flight;Fr(e,n,`loader`,s);try{if(!l){let s=new AbortController;l=[Promise.resolve().then(()=>i(Ir(e,t,n,r,s,a,!!o[3]))).then(e=>Dr(e,!1,r.id),e=>Dr(e,!0,r.id)).then(t=>(t[0]!==yr&&e._flights?.get(n.id)===l&&(e._flights.delete(n.id),l[2]||s.abort()),t[0]===br&&l[2]?Or(r,t[1]):t)),s,1],(e._flights??=new Map).set(n.id,l)}return n._flight=l,n.abortController=l[1],Gr(e,t,r,await Tr(l[0],c),o)}catch(t){if(t!==c||!c.aborted)throw t;return Mr(e,n),Cr}finally{Fr(e,n,!1,s)}}function Rr(e,t,n){t[0]!==Sr&&(e.status=`success`,e.error=void 0,t[0]===yr?(e.loaderData=t[1],e.invalid=!1,e.updatedAt=Date.now(),e.preload=n):e.invalid=!0)}function zr(e,t,n){let r=e._cache.get(t.id);if(r!==n||e._committed.some(e=>e.id===t.id&&e._flight===t._flight))return;let i={...t,_notFound:void 0,context:{}};i._flight&&i._flight[2]++,e._cache.set(t.id,i),r&&Mr(e,r)}function Br(e,t){return t[0]===br||t[0]===xr?{...e,status:t[0]===br?`error`:`notFound`,error:t[1],_flight:void 0}:e}function Vr(e,t,n,r,i,a,o){let s=t[1][n],c=Er(e,s),l=!!a[3],u=e._cache.get(s.id),d,f=!1,p;try{if(s.status===`success`&&(d=c.options.shouldReload,typeof d==`function`&&(d=d(Ir(e,t,s,c,a[0],i,l))),a[0].signal.aborted&&(p=Cr)),!p){if(s.status!==`success`)f=!0;else{let t=l||s.preload?c.options.preloadStaleTime??e.options.defaultPreloadStaleTime??3e4:c.options.staleTime??e.options.defaultStaleTime??0;f=!!(s.invalid||d||d===void 0&&Date.now()-s.updatedAt>=t&&(a[5]||s.cause===`enter`||a[2].some(e=>e.routeId===s.routeId&&e.id!==s.id)))}}}catch(n){s.invalid=!0,Mr(e,s),p=kr(e,t,c,n,a)}let m=c.options.loader,h=typeof m==`function`,g=h?m:m?.handler,_=!l||c.options.preload!==!1,v=_&&m?e._flights?.get(s.id):void 0;v===s._flight||p?v=void 0:v&&!f&&!l&&d===void 0?f=!0:f||(v=void 0);let y=!(!m||!f||s.status!==`success`||l||a[4]||((h?void 0:m.staleReloadMode)??e.options.defaultStaleReloadMode)===`blocking`),b=f&&_,x=b&&!y&&(s.status!==`success`||!!m),S=n>=o?a[7]:void 0,C=c.lazyFn&&c._lazy!==!0?S:void 0;if(b&&!m&&(s.invalid=!1,s.updatedAt=Date.now()),v&&v[2]++,x){let t=s._flight;s._flight=v,jr(e,s,t)?.abort(),n>=o&&(s.status=`pending`),S?.()}b||(s.isFetching=!1);let w=!p&&x?Lr(e,t,s,c,g,i,a).then(t=>(Rr(s,t,l),t[0]===yr&&(m&&!a[0].signal.aborted&&zr(e,s,u),n>=o&&(s.status=`pending`)),t)):Promise.resolve(p??[yr,s.loaderData]),T=(async()=>{try{let e=_r(c,void 0,C);e&&await Tr(e,a[0].signal)}catch(r){if(!t[1].some((e,t)=>t<=n&&(e.status===`error`||e.status===`notFound`||e._notFound)))return[n,kr(e,t,c,r,a)]}let r=await w;x&&r[0]===yr&&s.status===`pending`&&!a[0].signal.aborted&&(s.status=`success`,S?.())})();if(r.push([n,w,T]),!y)return w.then(e=>Br(s,e));let ee={...s,status:`pending`,preload:!1,_flight:v};s.invalid=!1,s.isFetching=`loader`;let E=Lr(e,t,ee,c,g,i,a).then(e=>(s.isFetching=!1,Rr(ee,e,!1),e));return(t[2]??=[]).push([n,E,T,ee]),E.then(e=>Br(ee,e))}async function Hr(e,t,n,r,i=0){let a=n?.[1][1],o=a?.routeId?t.findIndex(e=>e.routeId===a.routeId):n?.[0]??t.length-1;o<0&&(o=0);for(let n=o;n>=0;n--){let i=Er(e,t[n]);try{let e=_r(i,!1);e&&await Tr(e,r)}catch(e){if(e===r&&r.aborted)throw e}if(i.options.notFoundComponent)return n}return a?.routeId?o:i}function Ur(e,t){t[2]&&=(Nr(e,t[2].map(e=>e[3])),void 0)}async function Wr(e,t,n,r){let i;try{await Promise.all(e.map(e=>e[1].then(async t=>{let a=e[0];if(!(r&&a>=await r)){if(t[0]>=Sr)throw[a,t];!i&&t[0]!==yr&&(i=[a,t],await Promise.all((n??[]).map(e=>{if(!(e[0]<=a))return e[1].then(t=>{if(t[0]===Sr)throw[e[0],t]})})))}})))}catch(e){return e}return t??i}function Gr(e,t,n,r,i,a){for(;r[0]===Sr;){let o=r[1],s=o.options;try{if((s.href||o.headers.has(`Location`))&&(e.resolveRedirect(o),s.reloadDocument)||(s.reloadDocument?i[3]:i[1]>=20))return r;let n=e.buildLocation({...s,_fromLocation:t[0],_includeValidateSearch:!0}),a=n.maskedLocation??n;if(a.external){let t=o.clone();return t.options={...s},t.headers.set(`Location`,a.publicHref),e.resolveRedirect(t),i[3]?[Sr,t]:[Sr,t,a]}return[Sr,o,n]}catch(e){r=a?[br,e]:Or(n,e),a=!0}}return r}async function Kr(e,t,n,r,i,a){let o=t[1],s=await i,c=!1,l=o.findIndex(e=>e._notFound),u=t=>t[1][0]===xr?Hr(e,o,t,r.signal):t[0],d=l<0?o.length:l;if((s?.[1][0]??0)>=Sr)d=0;else if(s){d=s[2]??=await u(s);for(let e of n){if(e[0]>=d)break;let t=await e[1];if(t[0]!==yr&&t[0]=d)break;let t=await e[2];if(t){s=t;break}}if((s?.[1][0]??0)>=Sr){let n=s[1];if(n[0]!==Sr||n[1].options.reloadDocument||n[2])return Ur(e,t),n;c=!0,s=[0,[br,Error(`Too many redirects`)]]}let f=s?s[2]??await u(s):l;if(f>=0){let i=s?.[1],l=i?.[0],u=o[f],d=i?.[1],p=()=>{i&&(u._notFound=void 0,l===br?u.status=`error`:(d.routeId=u.routeId,u.routeId===e.routeTree.id?(u.status=`success`,u._notFound=!0):u.status=`notFound`),u.error=d,u.isFetching=!1)};p(),i||a?.();let m=Er(e,u);try{await Tr(i?Promise.resolve().then(()=>_r(m,l===br?`errorComponent`:`notFoundComponent`)):Promise.all([_r(m),_r(m,`notFoundComponent`)]),r.signal)}catch(n){if(n===r.signal&&r.signal.aborted)return Ur(e,t),Cr}i?c&&(r.abort(),await Promise.all([...n.map(e=>e[1]),...n.map(e=>e[2]),...(t[2]??[]).map(e=>e[1])]),Ur(e,t),Nr(e,o),p()):u.status=`success`}return t}async function qr(e,t,n,r=0,i=t[1].length){let a=t[1];for(let t=r;te._notFound);if(e.options.notFoundMode!==`root`&&s>=0){let t=await Hr(e,n,void 0,a,s);n[s]._notFound=void 0,n[t]._notFound=!0,s=t}let c=s<0?n.length:s+1,l=0;for(;l{for(let t=d;t=Sr&&(c=0);p()}if(!a.aborted&&!r[3]){let t=[];for(let[n,r]of e._flights??[])r[2]||(e._flights.delete(n),t.push(r[1]));for(let e of t)e.abort()}let h=Kr(e,i,u,r[0],Wr(u,m,i[2]),r[7]);i[2]?.length&&(i[3]=Wr(i[2],void 0,void 0,h.then(e=>wr(e)?0:vr(n).length,()=>0))),o=await h}catch(t){if(Ur(e,i),t===a&&a.aborted)return Cr;throw t}return wr(o)?o:qr(e,o,a,r[6]===n.length?r[6]:0)}function Yr(e,t){if(e._tx!==t)return;let n=t[3],r=e.stores.matches.get(),i=e._pending;for(let a=0;a0){i[3]=setTimeout(()=>Yr(e,t),n);return}i[2]=0}let m=n.map(e=>({...e,_flight:void 0}));m[a].status=`pending`;let h=i[4]=e.startTransition(()=>e.stores.setMatches(m),m).then(t=>(t&&e._pending===i&&i[4]===h&&!i[2]&&(i[2]=Date.now()+f),t));return}}function Xr(e,t){let n=e._pending;(e._tx===t||!e._tx?.[3].some(e=>e.id===n?.[1]))&&(clearTimeout(n?.[3]),e._pending=void 0)}async function Zr(e,t){let n=e._pending;if(!n)return;clearTimeout(n[3]);let r=n[2]-Date.now();if(!n[4]||r<=0||!vr(t[3]).some(e=>e.id===n[1]))return;let i;try{await Tr(new Promise(e=>{i=setTimeout(e,r)}),t[0].signal)}catch{}clearTimeout(i)}function Qr(e,t){e._committed=t,e.stores.setMatches(t)}function $r(e,t,n,r){let i=e._committed,a=e._lifecycleEnd,o=e._cache;for(let e of n)e.preload=!1,r&&(e._assetEnd=void 0);let s=vr(n).length,c=new Map;{let t=Date.now(),r=new Set;for(let e=0;e=(n.preload?i.options.preloadGcTime??e.options.defaultPreloadGcTime??3e5:i.options.gcTime??e.options.defaultGcTime??3e5)||c.set(n.id,o.get(n.id)===n?n:{...n,_flight:void 0,isFetching:!1,context:{}})}}t[3]=[],e._cache=c;let l=e._lifecycleEnd=tr(n);Qr(e,n),Nr(e,[...o.values(),...i].filter(e=>e._flight&&c.get(e.id)!==e),n),nr(e,i,n,a,l,t)}async function ei(e,t){let n=e._tx;for(;n&&n!==t;)t=n,await n[5],n=e._tx}function ti(e,t,n){let r=n[1].options,i=n[2];if(!i)return e.navigate({...r,replace:!0,ignoreBlocker:!0});if(r.reloadDocument)return e.navigate({href:(i.maskedLocation??i).publicHref,reloadDocument:!0,replace:!0,ignoreBlocker:!0});i._redirects=t[1]+1,e._pendingLocation=i;let a=e.commitLocation({...i,viewTransition:r.viewTransition,replace:!0,resetScroll:r.resetScroll,hashScrollIntoView:r.hashScrollIntoView,ignoreBlocker:!0});return queueMicrotask(()=>{e._pendingLocation===i&&(e._pendingLocation=void 0)}),a}async function ni(e,t,n,r,i){let a=n.map(e=>({...e}));Pr(a);for(let t of r)Mr(e,a[t[0]]),a[t[0]]=t[3];let o=[t[2],a],s;try{s=await Kr(e,o,r,t[0],i)}catch(t){throw Nr(e,a),t}if(wr(s)){Nr(e,a),s[0]===Sr&&e._tx===t&&e._committed===n&&await ti(e,t,s);return}if(await qr(e,s,t[0].signal),e._tx!==t||e._committed!==n){Nr(e,a);return}for(let t of a){let n=e._cache.get(t.id);n?._flight&&n._flight===t._flight&&(e._cache.delete(t.id),Mr(e,n))}Qr(e,a),Nr(e,n,a)}async function ri(e,t,n,r,i,a){let o=await Jr(e,t[2],t[3],[t[0],t[1],e._committed,void 0,i,n,a,r]);if(wr(o)){let n=o[0]===Sr&&e._tx===t;if((!n||o[1].options.reloadDocument)&&Xr(e,t),Nr(e,t[3]),t[3]=[],!n)return;if(e._tx!==t){Xr(e,t);return}await ti(e,t,o);return}let s=o[1];if(e._tx===t&&await Zr(e,t),e._tx!==t){Xr(e,t),Nr(e,s),Ur(e,o);return}let c=t[2],l=$n(c,e.stores.resolvedLocation.get()),u=o[2];await e.startViewTransition(async()=>{if(e._tx===t&&await Zr(e,t),e._tx!==t){Xr(e,t),Nr(e,s),Ur(e,o);return}let n=await e.startTransition(()=>{Xr(e,t),$r(e,t,s,a),e._tx===t&&(e.emit({type:`onLoad`,...l}),e._tx===t&&e.emit({type:`onBeforeRouteMount`,...l}))},s);if(e._tx!==t){Ur(e,o);return}u?.length&&ni(e,t,s,u,o[3]).catch(console.error),e.batch(()=>{e.stores.resolvedLocation.set(c),e.stores.status.set(`idle`),e._tx===t&&e.emit({type:`onResolved`,...l}),n&&e._tx===t&&e.emit({type:`onRendered`,...l})}),e._tx===t&&(e._commitPromise?.resolve(),e._commitPromise=void 0)})}async function ii(e,t){let n=e._tx,r=e.stores.resolvedLocation.get(),i=r??e.stores.location.get(),a=e.latestLocation,o=e._pendingLocation,s=o?.href===a.href?o._redirects??0:0,c=e._handoff,l=c?.[0](),u=new AbortController,d=e._preflight;if(e._preflight=u,l||c?.[1](),d?.abort(),!u.signal.aborted){let t=$n(a,r);e.emit({type:`onBeforeNavigate`,...t}),u.signal.aborted||e.emit({type:`onBeforeLoad`,...t})}if(u.signal.aborted){await ei(e,n);return}let f=i.href===a.href,p=u,m=e.matchRoutes(a,{_controller:u});Pr(m);let h=l?c[1](m):void 0;if(h?p=l:l?.abort(),u.signal.aborted){Nr(e,m),await ei(e,n);return}e._preflight=void 0;let g,_=()=>ri(e,y,f,()=>Yr(e,y),t?.sync,h),v=t?.sync?new Promise(e=>g=e):Promise.resolve().then(_),y=[p,s,a,m,Date.now(),v.then(()=>ei(e,y))];if(e._tx=y,n){for(let t of e.stores.matches.get()){if(e._tx!==y)break;t.isFetching&&Fr(e,t,!1)}n[0].abort(),Nr(e,n[3],y[3],!0)}if(e._tx!==y){Nr(e,y[3]),y[3]=[],g?.(),await ei(e,y);return}e.batch(()=>{e.stores.status.set(`pending`),e.stores.location.set(a)}),(h||!e._committed.length&&m[0]?.status!==`success`&&!m.some(e=>e._notFound))&&Yr(e,y),g?.(_()),await y[5]}async function ai(e,t){let n=e.buildLocation(t);for(let t=0;;t++){let r=e._committed,i=new AbortController,a,o,s;try{try{a=e.matchRoutes(n,{_controller:i}),Pr(a),o=(e._preloads??=new Map).set(i,a),s=await Jr(e,n,a,[i,t,r,!0])}finally{o&&(o=o.delete(i),Nr(e,a)),i.abort()}if(!wr(s))return s[1];if(!o||s.length<3)return;n=s[2]}catch(e){Vt(e)||console.error(e);return}}}var oi=`Error preloading route! ☝️`,si=class{get to(){return this._to}get id(){return this._id}get path(){return this._path}get fullPath(){return this._fullPath}constructor(e){if(this.init=e=>{this.originalIndex=e,this._branch=void 0;let t=this.options,n=!t?.path&&!t?.id;this.parentRoute=this.options.getParentRoute?.(),n?this._path=un:this.parentRoute||At();let r=n?un:t?.path;r&&r!==`/`&&(r=Mt(r));let i=t?.id||r,a=n?un:jt((this.parentRoute.id===`__root__`?``:this.parentRoute.id)+`/`+(i??``));r===`__root__`&&(r=`/`);let o=a===`__root__`?`/`:r===void 0?this.parentRoute.fullPath:jt(this.parentRoute.fullPath+`/`+r);this._path=r,this._id=a,this._fullPath=o,this._to=Nt(o)},this.addChildren=e=>this._addFileChildren(e),this._addFileChildren=e=>(Array.isArray(e)&&(this.children=e),typeof e==`object`&&e&&(this.children=Object.values(e)),this),this._addFileTypes=()=>this,this.updateLoader=e=>(Object.assign(this.options,e),this),this.update=e=>(Object.assign(this.options,e),this),this.lazy=e=>(this.lazyFn=e,this),this.redirect=e=>dn({from:this.fullPath,...e}),this.options=e||{},this.isRoot=!e?.getParentRoute,e?.id&&e?.path)throw Error(`Route cannot have both an 'id' and a 'path' option.`)}},ci=class extends si{constructor(e){super(e)}},li=class extends m.Component{constructor(...e){super(...e),this.state={error:0},this.reset=()=>{this.setState({error:0})}}static getDerivedStateFromProps(e,t){let n=e.getResetKey();return t.error&&t.resetKey!==n?{resetKey:n,error:0}:{resetKey:n}}static getDerivedStateFromError(e){return{error:[e]}}componentDidCatch(e,t){this.props.onCatch?.(e,t)}render(){let e=this.state.error;return e?m.createElement(this.props.errorComponent??ui,{error:e[0],reset:this.reset}):this.props.children}};function ui({error:e}){let[t,n]=m.useState(!1);return(0,h.jsxs)(`div`,{style:{padding:`.5rem`,maxWidth:`100%`},children:[(0,h.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:`.5rem`},children:[(0,h.jsx)(`strong`,{style:{fontSize:`1rem`},children:`Something went wrong!`}),(0,h.jsx)(`button`,{style:{appearance:`none`,fontSize:`.6em`,border:`1px solid currentColor`,padding:`.1rem .2rem`,fontWeight:`bold`,borderRadius:`.25rem`},onClick:()=>n(e=>!e),children:t?`Hide Error`:`Show Error`})]}),(0,h.jsx)(`div`,{style:{height:`.25rem`}}),t?(0,h.jsx)(`div`,{children:(0,h.jsx)(`pre`,{style:{fontSize:`.7em`,border:`1px solid red`,borderRadius:`.25rem`,padding:`.3rem`,color:`red`,overflow:`auto`},children:e?.message?(0,h.jsx)(`code`,{children:e.message}):null})}):null]})}var di=()=>!0,fi=()=>!1;function pi({children:e,fallback:t=null}){return(0,h.jsx)(m.Fragment,{children:mi()?e:t})}function mi(e=!0){return m.useSyncExternalStore(hi,di,e?fi:di)}function hi(){return()=>{}}var gi=m.createContext(null);function _i(e){return m.useContext(gi)}var vi=m.createContext(void 0),yi=m.createContext(void 0);function bi({update:e,notify:t,unwatched:n}){return{link:r,unlink:i,propagate:a,checkDirty:o,shallowPropagate:s};function r(e,t,n){let r=t.depsTail;if(r!==void 0&&r.dep===e)return;let i=r===void 0?t.deps:r.nextDep;if(i!==void 0&&i.dep===e){i.version=n,t.depsTail=i;return}let a=e.subsTail;if(a!==void 0&&a.version===n&&a.sub===t)return;let o=t.depsTail=e.subsTail={version:n,dep:e,sub:t,prevDep:r,nextDep:i,prevSub:a,nextSub:void 0};i!==void 0&&(i.prevDep=o),r===void 0?t.deps=o:r.nextDep=o,a===void 0?e.subs=o:a.nextSub=o}function i(e,t=e.sub){let r=e.dep,i=e.prevDep,a=e.nextDep,o=e.nextSub,s=e.prevSub;return a===void 0?t.depsTail=i:a.prevDep=i,i===void 0?t.deps=a:i.nextDep=a,o===void 0?r.subsTail=s:o.prevSub=s,s===void 0?(r.subs=o)===void 0&&n(r):s.nextSub=o,a}function a(e){let n=e.nextSub,r;top:do{let i=e.sub,a=i.flags;if(a&60?a&12?a&4?!(a&48)&&c(e,i)?(i.flags=a|40,a&=1):a=0:i.flags=a&-9|32:a=0:i.flags=a|32,a&2&&t(i),a&1){let t=i.subs;if(t!==void 0){let i=(e=t).nextSub;i!==void 0&&(r={value:n,prev:r},n=i);continue}}if((e=n)!==void 0){n=e.nextSub;continue}for(;r!==void 0;)if(e=r.value,r=r.prev,e!==void 0){n=e.nextSub;continue top}break}while(1)}function o(t,n){let r,i=0,a=!1;top:do{let o=t.dep,c=o.flags;if(n.flags&16)a=!0;else if((c&17)==17){if(e(o)){let e=o.subs;e.nextSub!==void 0&&s(e),a=!0}}else if((c&33)==33){(t.nextSub!==void 0||t.prevSub!==void 0)&&(r={value:t,prev:r}),t=o.deps,n=o,++i;continue}if(!a){let e=t.nextDep;if(e!==void 0){t=e;continue}}for(;i--;){let i=n.subs,o=i.nextSub!==void 0;if(o?(t=r.value,r=r.prev):t=i,a){if(e(n)){o&&s(i),n=t.sub;continue}a=!1}else n.flags&=-33;n=t.sub;let c=t.nextDep;if(c!==void 0){t=c;continue top}}return a}while(1)}function s(e){do{let n=e.sub,r=n.flags;(r&48)==32&&(n.flags=r|16,(r&6)==2&&t(n))}while((e=e.nextSub)!==void 0)}function c(e,t){let n=t.depsTail;for(;n!==void 0;){if(n===e)return!0;n=n.prevDep}return!1}}function xi(e,t,n){let r=typeof e==`object`,i=r?e:void 0;return{next:(r?e.next:e)?.bind(i),error:(r?e.error:t)?.bind(i),complete:(r?e.complete:n)?.bind(i)}}var Si=[],Ci=0,{link:wi,unlink:Ti,propagate:Ei,checkDirty:Di,shallowPropagate:Oi}=bi({update(e){return e._update()},notify(e){Si[Ai++]=e,e.flags&=-3},unwatched(e){e.depsTail!==void 0&&(e.depsTail=void 0,e.flags=17,Pi(e))}}),ki=0,Ai=0,ji,Mi=0;function Ni(e){try{++Mi,e()}finally{--Mi||Fi()}}function Pi(e){let t=e.depsTail,n=t===void 0?e.deps:t.nextDep;for(;n!==void 0;)n=Ti(n,e)}function Fi(){if(!(Mi>0)){for(;ki{i.get(),n.current?t.next?.(i._snapshot):n.current=!0});return{unsubscribe:()=>{r.stop()}}},_update(e){let a=ji,o=t?.compare??Object.is;if(n)ji=i,++Ci,i.depsTail=void 0;else if(e===void 0)return!1;n&&(i.flags=5);try{let t=i._snapshot,a=typeof e==`function`?e(t):e===void 0&&n?r(t):e;return t===void 0||!o(t,a)?(i._snapshot=a,!0):!1}finally{ji=a,n&&(i.flags&=-5),Pi(i)}}};return n?(i.flags=17,i.get=function(){let e=i.flags;if(e&16||e&32&&Di(i.deps,i)){if(i._update()){let e=i.subs;e!==void 0&&Oi(e)}}else e&32&&(i.flags=e&-33);return ji!==void 0&&wi(i,ji,Ci),i._snapshot}):i.set=function(e){if(i._update(e)){let e=i.subs;e!==void 0&&(Ei(e),Oi(e),Fi())}},i}function Li(e){let t=()=>{let t=ji;ji=n,++Ci,n.depsTail=void 0,n.flags=6;try{return e()}finally{ji=t,n.flags&=-5,Pi(n)}},n={deps:void 0,depsTail:void 0,subs:void 0,subsTail:void 0,flags:6,notify(){let e=this.flags;e&16||e&32&&Di(this.deps,this)?t():this.flags=2},stop(){this.flags=0,this.depsTail=void 0,Pi(this)}};return t(),n}var Ri=n((e=>{var t=l();function n(e,t){return e===t&&(e!==0||1/e==1/t)||e!==e&&t!==t}var r=typeof Object.is==`function`?Object.is:n,i=t.useState,a=t.useEffect,o=t.useLayoutEffect,s=t.useDebugValue;function c(e,t){var n=t(),r=i({inst:{value:n,getSnapshot:t}}),c=r[0].inst,l=r[1];return o(function(){c.value=n,c.getSnapshot=t,u(c)&&l({inst:c})},[e,n,t]),a(function(){return u(c)&&l({inst:c}),e(function(){u(c)&&l({inst:c})})},[e]),s(n),n}function u(e){var t=e.getSnapshot;e=e.value;try{var n=t();return!r(e,n)}catch{return!0}}function d(e,t){return t()}var f=typeof window>`u`||window.document===void 0||window.document.createElement===void 0?d:c;e.useSyncExternalStore=t.useSyncExternalStore===void 0?f:t.useSyncExternalStore})),zi=n(((e,t)=>{t.exports=Ri()})),Bi=n((e=>{var t=l(),n=zi();function r(e,t){return e===t&&(e!==0||1/e==1/t)||e!==e&&t!==t}var i=typeof Object.is==`function`?Object.is:r,a=n.useSyncExternalStore,o=t.useRef,s=t.useEffect,c=t.useMemo,u=t.useDebugValue;e.useSyncExternalStoreWithSelector=function(e,t,n,r,l){var d=o(null);if(d.current===null){var f={hasValue:!1,value:null};d.current=f}else f=d.current;d=c(function(){function e(e){if(!a){if(a=!0,o=e,e=r(e),l!==void 0&&f.hasValue){var t=f.value;if(l(t,e))return s=t}return s=e}if(t=s,i(o,e))return t;var n=r(e);return l!==void 0&&l(t,n)?(o=e,t):(o=e,s=n)}var a=!1,o,s,c=n===void 0?null:n;return[function(){return e(t())},c===null?void 0:function(){return e(c())}]},[t,n,r,l]);var p=a(e,d[0],d[1]);return s(function(){f.hasValue=!0,f.value=p},[p]),u(p),p}})),Vi=n(((e,t)=>{t.exports=Bi()}))();function Hi(e,t){return e===t}function Ui(e,t=e=>e,n){let r=n?.compare??Hi,i=(0,m.useCallback)(t=>{let{unsubscribe:n}=e.subscribe(t);return n},[e]),a=(0,m.useCallback)(()=>e.get(),[e]);return(0,Vi.useSyncExternalStoreWithSelector)(i,a,a,t,r)}var Wi={};function Gi(e,t){let n=m.useRef();return r=>{let i=e?.select?e.select(r):r;return e?.structuralSharing??t.options.defaultStructuralSharing?n.current=gt(n.current,i):i}}function Ki(e){let t=_i(),n=m.useContext(e.from?yi:vi),r=e.from??n,i=t.stores.getMatchStore(r),a=Gi(e,t),o=Ui(i,e=>e?a(e):Wi);if(o!==Wi)return o;(e.shouldThrow??!0)&&At()}function qi(e){return Ki({from:e.from,strict:e.strict,structuralSharing:e.structuralSharing,select:t=>e.select?e.select(t.loaderData):t.loaderData})}function Ji(e){let{select:t,...n}=e;return Ki({...n,select:e=>t?t(e.loaderDeps):e.loaderDeps})}function Yi(e){return Ki({from:e.from,shouldThrow:e.shouldThrow,structuralSharing:e.structuralSharing,strict:e.strict,select:t=>{let n=e.strict===!1?t.params:t._strictParams;return e.select?e.select(n):n}})}function Xi(e){return Ki({from:e.from,strict:e.strict,shouldThrow:e.shouldThrow,structuralSharing:e.structuralSharing,select:t=>e.select?e.select(t.search):t.search})}function Zi(e){let t=_i();return m.useCallback(n=>t.navigate({...n,from:n.from??e?.from}),[e?.from,t])}function Qi(e){let t=_i(),n=Zi(),r=m.useRef(null);return lt(()=>{r.current!==e&&(n(e),r.current=e)},[t,e,n]),null}function $i(e){return Ki({...e,select:t=>e.select?e.select(t.context):t.context})}function ea(...e){let t=m.useRef(e),n=t.current;return e.forEach((e,t)=>{vt(n[t],e,!1,!0)||(n[t]=e)}),t.current}function ta(e,t){e.preloadRoute(t).catch(e=>{console.warn(e),console.warn(oi)})}var na={compare:(e,t)=>e[0]===t[0]&&e[1]===t[1]};function ra(e,t){let n=typeof e==`string`&&wt(e);if(n)return t.has(n)?e:null}function ia(e,t,n,r,i){let a=Ft(e.pathname,r),o=Ft(t.pathname,r);return(n?.exact?a!==o:!a.startsWith(o)||a.length!==o.length&&a[o.length]!==`/`)||(n?.includeSearch??!0)&&!vt(e.search,t.search,!n?.exact,n?.explicitUndefined)?!1:!n?.includeHash||i&&e.hash===t.hash}function aa(e,t,n){let r=_i(),i=m.useRef(null),a=m.useCallback(e=>{if(i.current=e,typeof t==`function`)return t(e);t&&(t.current=e)},[t]),{activeOptions:o,to:s,preload:c,preloadDelay:l,hashScrollIntoView:u,replace:d,startTransition:f,resetScroll:p,viewTransition:h,ignoreBlocker:g,disabled:_,target:v,onClick:y,onBlur:b,onFocus:x,onMouseEnter:S,onMouseLeave:C,onTouchStart:w}=e,T=mi(!!o?.includeHash),[ee,E,te]=ea(e.search,e.params,o),[D,ne]=m.useMemo(()=>[e,{...e}],[r,e.from,e._fromLocation,e.hash,e.to,ee,E,e.state,e.mask,e.unsafeRelative]),re=m.useCallback(e=>{let t=ra(s,r.protocolAllowlist);if(t!==void 0)return[t??void 0];D._fromLocation||(ne._fromLocation=e);let n=r.buildLocation(ne),i=fa(n,r,_);return[i,!_&&(!i||wt(i))?void 0:ia(e,n,te,r.basepath,T)]},[te,_,T,D,ne,r,s]),[ie,ae]=Ui(r.stores.location,re,na),oe=ae===void 0?ie:void 0,se=_||ie===void 0,ce=m.useRef(!1),le=e.reloadDocument||oe||se?!1:c??r.options.defaultPreload,ue=l??r.options.defaultPreloadDelay??0,de=m.useCallback(e=>{let t=e?.isIntersecting;if(!(t??le===`intent`)){t===!1&&P(i);return}if(!ue){ta(r,D);return}N.has(i)||N.set(i,setTimeout(()=>{N.delete(i),ta(r,D)},ue))},[r,D,i,le,ue]);m.useEffect(()=>{le===`render`&&!ce.current&&(ce.current=!0,ta(r,D));let e;return le===`viewport`&&i.current&&typeof IntersectionObserver==`function`&&(e=new IntersectionObserver(e=>de(e.pop()),{rootMargin:`100px`}),e.observe(i.current)),()=>{e?.disconnect(),P(i)}},[r,D,le,de,i]);let fe=la(e,n);if(fe.ref=t?a:i,oe)return fe.href=oe,fe;let pe=e=>{let t=v??e.currentTarget.getAttribute(`target`);!se&&!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)&&!e.defaultPrevented&&(!t||t===`_self`)&&e.button===0&&(e.preventDefault(),r.navigate({...D,replace:d,resetScroll:p,hashScrollIntoView:u,startTransition:f,viewTransition:h,ignoreBlocker:g}))},me=()=>{le===`intent`&&ta(r,D)},he=()=>{le===`intent`&&P(i)};return fe.onClick=da(y,pe),fe.onBlur=da(b,he),fe.onFocus=da(x,de),fe.onMouseEnter=da(S,de),fe.onMouseLeave=da(C,he),fe.onTouchStart=da(w,me),ua(fe,e,ae,ie,se,n)}var oa={},sa={className:`active`},ca=new Set([`to`,`params`,`search`,`hash`,`state`,`mask`,`from`,`unsafeRelative`,`_fromLocation`,`reloadDocument`,`preload`,`preloadDelay`,`preloadIntentProximity`,`hashScrollIntoView`,`replace`,`startTransition`,`resetScroll`,`viewTransition`,`ignoreBlocker`,`activeProps`,`inactiveProps`,`activeOptions`,`_asChild`]);function la(e,t){let n={};for(let r in e)ca.has(r)||r===`type`&&t!==void 0||r===`disabled`&&t===`a`||(n[r]=e[r]);return n}function ua(e,t,n,r,i,a){let{activeProps:o,inactiveProps:s,className:c,style:l,target:u}=t,d=dt(n?o:s,{})??(n?sa:oa);Object.assign(e,d),e.href=r,a!==`a`&&(e.disabled=i),e.target=u;let f=d.style;(l||f)&&(e.style=l&&f?{...l,...f}:l||f);let p=d.className;return(c||p)&&(e.className=c?p?`${c} ${p}`:c:p),i&&(e.role=`link`,e[`aria-disabled`]=!0),n&&(e[`data-status`]=`active`,e[`aria-current`]=`page`),e}var N=new WeakMap,P=e=>{clearTimeout(N.get(e)),N.delete(e)},da=(e,t)=>e?n=>n.defaultPrevented||(e(n),n.defaultPrevented||t(n)):t;function fa(e,t,n){if(n)return;let r=e.maskedLocation??e,i=r.external?r.publicHref:t.history.createHref(r.publicHref)||`/`;if(!r.external&&i===r.publicHref||!Et(i,t.protocolAllowlist))return i}var pa=m.memo(m.forwardRef((e,t)=>{let n=e._asChild||`a`,r=aa(e,t,n),i=typeof e.children==`function`?e.children({isActive:r[`data-status`]===`active`}):e.children;return m.createElement(n,r,i)}),ma);function ma(e,t){let n=0;for(let r in t)if(n++,e[r]!==t[r]&&(!ca.has(r)||!vt(e[r],t[r],!1,!0)))return!1;for(let t in e)n--;return n===0}var ha=class extends si{constructor(e){super(e),this.useMatch=e=>Ki({...e,from:this.id}),this.useRouteContext=e=>$i({...e,from:this.id}),this.useSearch=e=>Xi({...e,from:this.id}),this.useParams=e=>Yi({...e,from:this.id}),this.useLoaderDeps=e=>Ji({...e,from:this.id}),this.useLoaderData=e=>qi({...e,from:this.id}),this.useNavigate=()=>Zi({from:this.fullPath}),this.Link=m.forwardRef((e,t)=>(0,h.jsx)(pa,{ref:t,from:this.fullPath,...e}))}};function ga(e){return new ha(e)}var _a=class extends ci{constructor(e){super(e),this.useMatch=e=>Ki({...e,from:this.id}),this.useRouteContext=e=>$i({...e,from:this.id}),this.useSearch=e=>Xi({...e,from:this.id}),this.useParams=e=>Yi({...e,from:this.id}),this.useLoaderDeps=e=>Ji({...e,from:this.id}),this.useLoaderData=e=>qi({...e,from:this.id}),this.useNavigate=()=>Zi({from:this.fullPath}),this.Link=m.forwardRef((e,t)=>(0,h.jsx)(pa,{ref:t,from:this.fullPath,...e}))}};function va(e){return new _a(e)}function ya(e,t){let n,r,i,a=()=>(n||=(i=void 0,e().then(e=>{n=void 0,o.preload=void 0,r=e[t??`default`]}).catch(e=>{n=void 0,i=e})),n),o=function(e){if(i){if(yt(i)&&typeof sessionStorage<`u`){let e=`tanstack_router_reload:${i.message}`;if(!sessionStorage.getItem(e))throw sessionStorage.setItem(e,`1`),window.location.reload(),new Promise(()=>{})}throw i}if(!r){if(ct)ct(a());else throw a()}return m.createElement(r,e)};return o.preload=a,o}function ba(e){let t=_i(),n=`not-found-${Ui(t.stores.location,e=>e.pathname)}-${Ui(t.stores.status)}`;return(0,h.jsx)(li,{getResetKey:()=>n,onCatch:(t,n)=>{if(Vt(t))e.onCatch?.(t,n);else throw t},errorComponent:({error:t})=>{if(Vt(t))return e.fallback?.(t);throw t},children:e.children})}function xa(){return(0,h.jsx)(`p`,{children:`Not Found`})}function Sa(e){return(0,h.jsx)(h.Fragment,{children:e.children})}function Ca(e,t,n){return t.options.notFoundComponent?(0,h.jsx)(t.options.notFoundComponent,{...n}):e.options.defaultNotFoundComponent?(0,h.jsx)(e.options.defaultNotFoundComponent,{...n}):(0,h.jsx)(xa,{})}function wa(e,t){let n=t?.options.pendingComponent??e.options.defaultPendingComponent;return n?(0,h.jsx)(n,{}):null}var Ta=(e,t)=>e[0]===t[0]&&e[1]===t[1],Ea=(e,t,n)=>!t.isRoot||t.options.shellComponent||t.options.wrapInSuspense||n===!1||n===`data-only`||!e.ssr,Da=m.memo(function({routeId:e}){let t=_i();return(0,h.jsx)(Oa,{router:t,match:Ui(t.stores.getMatchStore(e))})});function Oa({router:e,match:t}){let n=e.routesById[t.routeId],r=wa(e,n),i=n.options.errorComponent??e.options.defaultErrorComponent,a=n.options.onCatch??e.options.defaultOnCatch,o=n.isRoot?n.options.notFoundComponent??e.options.notFoundRoute?.options.component:n.options.notFoundComponent,s=t.ssr===!1||t.ssr===`data-only`,c=Ea(e,n,t.ssr)&&(n.options.wrapInSuspense??r??(n.options.errorComponent?.preload||s))?m.Suspense:Sa,l=i?li:Sa,u=o?ba:Sa;return(0,h.jsxs)(n.isRoot?n.options.shellComponent??Sa:Sa,{children:[(0,h.jsx)(vi.Provider,{value:t.routeId,children:(0,h.jsx)(c,{fallback:r,children:(0,h.jsx)(l,{getResetKey:()=>t,errorComponent:i,onCatch:(e,n)=>{if(Vt(e))throw e.routeId??=t.routeId,e;a?.(e,n)},children:(0,h.jsx)(u,{fallback:e=>{if(e.routeId??=t.routeId,e.routeId!==t.routeId)throw e;return m.createElement(o,e)},children:s?(0,h.jsx)(pi,{fallback:r,children:(0,h.jsx)(ka,{match:t})}):(0,h.jsx)(ka,{match:t})})})})}),null]})}var ka=m.memo(function({match:e}){let t=_i(),n=e.routeId,r=t.routesById[n],i=m.useMemo(()=>{let i=(r.options.remountDeps??t.options.defaultRemountDeps)?.({routeId:n,loaderDeps:e.loaderDeps,params:e._strictParams,search:e._strictSearch});return i?JSON.stringify(i):void 0},[n,e.loaderDeps,e._strictParams,e._strictSearch,r.options.remountDeps,t.options.defaultRemountDeps]),a=m.useMemo(()=>{let e=r.options.component??t.options.defaultComponent;return e?(0,h.jsx)(e,{},i):(0,h.jsx)(Aa,{})},[i,r.options.component,t.options.defaultComponent]);if(e.status===`pending`){if(t.ssr&&!Ea(t,r,e.ssr))return a;if(t._tx)throw t._tx[5];return wa(t,r)}if(e.status===`notFound`)return Ca(t,r,e.error);if(e.status===`error`)throw e.error;return a}),Aa=m.memo(function(){let e=_i(),t=m.useContext(vi),n,r,i;{let a=e.stores.getMatchStore(t);[n,r]=Ui(a,e=>[!!e._notFound,e.error],{compare:Ta}),i=Ui(e.stores.ids,e=>e[e.indexOf(t)+1])}if(n)return Ca(e,e.routesById[t],r);if(!i)return null;let a=(0,h.jsx)(Da,{routeId:i});return t===`__root__`?(0,h.jsx)(m.Suspense,{fallback:wa(e),children:a}):a});function ja(e,t){let n=e[1];e.length=0,n?.(t)}function Ma({t:e}){let t=_i(),n=t._rendered??=[];return t.startTransition=(r,i)=>new Promise(a=>{ja(n,!1),n.push(i,a),e(t),m.startTransition(r)}),lt(()=>{let e=t.history.subscribe(t.load);t.updateLatestLocation();let r=t.latestLocation,i=t.buildLocation({to:r.pathname,search:!0,params:!0,hash:!0,state:!0,_includeValidateSearch:!0});if(Nt(r.publicHref)!==Nt(i.publicHref))return t.commitLocation({...i,replace:!0,ignoreBlocker:!0}),e;let a=t.stores.resolvedLocation.get();return a?.href===r.href&&a.state.__TSR_key===r.state.__TSR_key?n.push(t.stores.matches.get(),e=>{e&&t.emit({type:`onRendered`,...$n(a,a)})}):t._tx||t.load({sync:!0}).catch(console.error),e},[t,t.history]),null}function Na(){let e=_i(),t=e.routesById[un],n=wa(e,t),r=e.ssr?Sa:m.Suspense,i=(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(Ma,{t:m.useState()[1]}),(0,h.jsx)(r,{fallback:n,children:(0,h.jsx)(Pa,{})})]});return e.options.InnerWrap?(0,h.jsx)(e.options.InnerWrap,{children:i}):i}function Pa(){let e=_i(),t=e._rendered,n=Ui(e.stores.matches,e=>t[0]??e),r=n[0],i=r?.routeId;lt(()=>{t[0]===n&&ja(t,!0)},[t,n]);let a=i?(0,h.jsx)(Da,{routeId:i}):null;return(0,h.jsx)(vi.Provider,{value:i,children:e.options.disableGlobalCatchBoundary?a:(0,h.jsx)(li,{getResetKey:()=>r,onCatch:void 0,children:a})})}var Fa=e=>({createMutableStore:Ii,createReadonlyStore:Ii,batch:Ni}),Ia=e=>new La(e),La=class extends rr{constructor(e){super(e,Fa)}};function Ra({router:e,children:t,...n}){pt(n)&&e.update({...e.options,...n,context:{...e.options.context,...n.context}});let r=(0,h.jsx)(gi.Provider,{value:e,children:t});return e.options.Wrap?(0,h.jsx)(e.options.Wrap,{children:r}):r}function za({router:e,...t}){return(0,h.jsx)(Ra,{router:e,...t,children:(0,h.jsx)(Na,{})})}var Ba=p(),F=s();function Va(e){let t=(0,F.c)(6),{error:n}=e,r;t[0]===Symbol.for(`react.memo_cache_sentinel`)?(r=(0,h.jsx)(`p`,{className:`schild text-lg text-rot`,children:`Diese Ansicht ist abgestürzt`}),t[0]=r):r=t[0];let i=n instanceof Error?n.message:String(n),a;t[1]===i?a=t[2]:(a=(0,h.jsx)(`p`,{className:`text-[15px]`,children:i}),t[1]=i,t[2]=a);let o;t[3]===Symbol.for(`react.memo_cache_sentinel`)?(o=(0,h.jsx)(`button`,{type:`button`,onClick:Ha,className:`schild h-11 rounded-lg border border-rot-rand px-5 text-sm text-foreground hover:bg-[#3a1512]`,children:`Neu laden`}),t[3]=o):o=t[3];let s;return t[4]===a?s=t[5]:(s=(0,h.jsxs)(`div`,{role:`alert`,className:`flex flex-col items-start gap-3 rounded-2xl border border-rot-rand bg-rot-grund p-6 text-rot-text`,children:[r,a,o]}),t[4]=a,t[5]=s),s}function Ha(){return window.location.reload()}var Ua={name:`cpu`,size:24,node:[[`path`,{d:`M12 20v2`,key:`1lh1kg`}],[`path`,{d:`M12 2v2`,key:`tus03m`}],[`path`,{d:`M17 20v2`,key:`1rnc9c`}],[`path`,{d:`M17 2v2`,key:`11trls`}],[`path`,{d:`M2 12h2`,key:`1t8f8n`}],[`path`,{d:`M2 17h2`,key:`7oei6x`}],[`path`,{d:`M2 7h2`,key:`asdhe0`}],[`path`,{d:`M20 12h2`,key:`1q8mjw`}],[`path`,{d:`M20 17h2`,key:`1fpfkl`}],[`path`,{d:`M20 7h2`,key:`1o8tra`}],[`path`,{d:`M7 20v2`,key:`4gnj0m`}],[`path`,{d:`M7 2v2`,key:`1i4yhu`}],[`rect`,{x:`4`,y:`4`,width:`16`,height:`16`,rx:`2`,key:`1vbyd7`}],[`rect`,{x:`8`,y:`8`,width:`8`,height:`8`,rx:`1`,key:`z9xiuo`}]]};Ua.node;var Wa=o(Ua),Ga={name:`ellipsis`,size:24,node:[[`circle`,{cx:`12`,cy:`12`,r:`1`,key:`41hilf`}],[`circle`,{cx:`19`,cy:`12`,r:`1`,key:`1wjl8i`}],[`circle`,{cx:`5`,cy:`12`,r:`1`,key:`1pcz8c`}]],aliases:[`more-horizontal`]};Ga.node;var Ka=o(Ga),qa={name:`external-link`,size:24,node:[[`path`,{d:`M15 3h6v6`,key:`1q9fwt`}],[`path`,{d:`M10 14 21 3`,key:`gplh6r`}],[`path`,{d:`M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6`,key:`a6xqqp`}]]};qa.node;var Ja=o(qa),Ya={name:`house`,size:24,node:[[`path`,{d:`M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8`,key:`5wwlr5`}],[`path`,{d:`M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z`,key:`r6nss1`}]],aliases:[`home`]};Ya.node;var Xa=o(Ya),Za={name:`refresh-cw`,size:24,node:[[`path`,{d:`M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8`,key:`v9h5vc`}],[`path`,{d:`M21 3v5h-5`,key:`1q7to0`}],[`path`,{d:`M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16`,key:`3uifl3`}],[`path`,{d:`M8 16H3v5`,key:`1cv678`}]]};Za.node;var Qa=o(Za),$a={name:`scroll-text`,size:24,node:[[`path`,{d:`M15 12h-5`,key:`r7krc0`}],[`path`,{d:`M15 8h-5`,key:`1khuty`}],[`path`,{d:`M19 17V5a2 2 0 0 0-2-2H4`,key:`zz82l3`}],[`path`,{d:`M8 21h12a2 2 0 0 0 2-2v-1a1 1 0 0 0-1-1H11a1 1 0 0 0-1 1v1a2 2 0 1 1-4 0V5a2 2 0 1 0-4 0v2a1 1 0 0 0 1 1h3`,key:`1ph1d7`}]]};$a.node;var eo=o($a),to={name:`settings`,size:24,node:[[`path`,{d:`M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915`,key:`1i5ecw`}],[`circle`,{cx:`12`,cy:`12`,r:`3`,key:`1v7zrd`}]]};to.node;var no=o(to),ro=`verbinde`,io=null,ao=new Set,oo=()=>ao.forEach(e=>e());function so(e){return ao.add(e),()=>{ao.delete(e)}}var co=()=>ro===`live`,lo=()=>(0,m.useSyncExternalStore)(so,ho),uo=()=>(0,m.useSyncExternalStore)(so,go);function fo(e){io=e,oo()}function po(e){e!==ro&&(ro=e,oo())}function mo(){let e=_();(0,m.useEffect)(()=>{let t=new EventSource(`/api/stream`);return t.onopen=()=>{po(`live`),e.invalidateQueries()},t.onerror=()=>po(`getrennt`),t.addEventListener(`invalidate`,t=>{try{let n=JSON.parse(t.data)?.keys??[];for(let t of n)e.invalidateQueries({queryKey:[t]})}catch{}}),t.addEventListener(`metrik`,e=>{try{fo(JSON.parse(e.data))}catch{}}),()=>{t.close(),po(`getrennt`)}},[e])}function ho(){return ro}function go(){return io}var _o=[],vo=1,yo=new Set,bo=()=>yo.forEach(e=>e());function xo(e,t){let n=vo++;_o=[..._o,{id:n,art:e,text:t}].slice(-4),bo(),e!==`fehler`&&window.setTimeout(()=>So(n),6e3)}function So(e){_o=_o.filter(t=>t.id!==e),bo()}var Co=()=>(0,m.useSyncExternalStore)(wo,To);function wo(e){return yo.add(e),()=>{yo.delete(e)}}function To(){return _o}var Eo={erfolg:`border-gruen-rand bg-gruen-grund text-gruen-text`,fehler:`border-rot-rand bg-rot-grund text-rot-text`,info:`border-cyan-rand bg-cyan-grund text-cyan-text`};function Do(){let e=(0,F.c)(4),t=Co(),n;e[0]===t?n=e[1]:(n=t.map(Oo),e[0]=t,e[1]=n);let r;return e[2]===n?r=e[3]:(r=(0,h.jsx)(`div`,{"aria-live":`polite`,className:`pointer-events-none fixed right-4 bottom-24 left-4 z-50 flex flex-col items-end gap-2 md:bottom-6 md:left-auto md:w-[420px]`,children:n}),e[2]=n,e[3]=r),r}function Oo(t){return(0,h.jsxs)(`div`,{role:t.art===`fehler`?`alert`:`status`,className:i(`pointer-events-auto flex w-full items-start gap-3 rounded-xl border px-4 py-3 text-[15px] shadow-lg`,Eo[t.art]),children:[(0,h.jsx)(`span`,{className:`min-w-0 flex-1`,children:t.text}),(0,h.jsx)(`button`,{type:`button`,onClick:()=>So(t.id),"aria-label":`Meldung schließen`,className:`-m-2 p-2 opacity-70 hover:opacity-100`,children:(0,h.jsx)(e,{className:`size-4`})})]},t.id)}var ko=`modulepreload`,Ao=function(e){return`/`+e},jo={},Mo=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}function s(e){return import.meta.resolve?import.meta.resolve(e):new URL(e,import.meta.url).href}r=o(t.map(t=>{if(t=Ao(t,n),t=s(t),t in jo)return;jo[t]=!0;let r=t.endsWith(`.css`);for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}let i=document.createElement(`link`);if(i.rel=r?`stylesheet`:ko,r||(i.as=`script`),i.crossOrigin=``,i.href=t,a&&i.setAttribute(`nonce`,a),document.head.appendChild(i),r)return new Promise((e,n)=>{i.addEventListener(`load`,e),i.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}).filter(e=>e!==void 0))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})},No=(0,m.lazy)(()=>Mo(()=>import(`./Dienste-DEn0Zjkq.js`).then(e=>({default:e.Dienste})),__vite__mapDeps([0,1,2,3]))),Po=(0,m.lazy)(()=>Mo(()=>import(`./Einstellungen-BwCmWl9x.js`).then(e=>({default:e.Einstellungen})),__vite__mapDeps([4,1,2,3]))),Fo=(0,m.lazy)(()=>Mo(()=>import(`./MehrMenue-CXteqmy8.js`).then(e=>({default:e.MehrMenue})),__vite__mapDeps([5,1,2,3]))),Io=[{to:`/`,label:`Start`,Icon:Xa},{to:`/updates`,label:`Updates`,Icon:Qa},{to:`/modelle`,label:`Modelle`,Icon:Wa}],Lo=new Intl.DateTimeFormat(`de-DE`,{hour:`2-digit`,minute:`2-digit`,timeZone:`Europe/Berlin`}),Ro=new Intl.DateTimeFormat(`de-DE`,{weekday:`short`,day:`2-digit`,month:`2-digit`,timeZone:`Europe/Berlin`});function zo(){let e=(0,F.c)(13),[t,n]=(0,m.useState)(Bo),r,i;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(r=()=>{let e=window.setInterval(()=>n(new Date),2e4);return()=>window.clearInterval(e)},i=[],e[0]=r,e[1]=i):(r=e[0],i=e[1]),(0,m.useEffect)(r,i);let a;e[2]===t?a=e[3]:(a=Lo.format(t),e[2]=t,e[3]=a);let o;e[4]===a?o=e[5]:(o=(0,h.jsx)(`span`,{className:`ziffern text-2xl font-medium`,children:a}),e[4]=a,e[5]=o);let s;e[6]===t?s=e[7]:(s=Ro.format(t).replace(`,`,``),e[6]=t,e[7]=s);let c;e[8]===s?c=e[9]:(c=(0,h.jsx)(`span`,{className:`schild text-[13px] text-text-3`,children:s}),e[8]=s,e[9]=c);let l;return e[10]!==o||e[11]!==c?(l=(0,h.jsxs)(`div`,{className:`flex flex-col items-end leading-tight`,children:[o,c]}),e[10]=o,e[11]=c,e[12]=l):l=e[12],l}function Bo(){return new Date}function Vo(){let e=(0,F.c)(9),t=lo(),n=t===`live`,r=n?`bg-gruen shadow-[0_0_8px_rgba(61,220,138,0.7)]`:`bg-bernstein`,a;e[0]===r?a=e[1]:(a=i(`size-2 rounded-full`,r),e[0]=r,e[1]=a);let o;e[2]===a?o=e[3]:(o=(0,h.jsx)(`span`,{className:a}),e[2]=a,e[3]=o);let s=n?`Box online`:t===`verbinde`?`Verbinde`:`Getrennt`,c;e[4]===s?c=e[5]:(c=(0,h.jsx)(`span`,{children:s}),e[4]=s,e[5]=c);let l;return e[6]!==o||e[7]!==c?(l=(0,h.jsxs)(`div`,{className:`schild flex items-center gap-2 text-[15px] text-text-3`,"aria-live":`polite`,children:[o,c]}),e[6]=o,e[7]=c,e[8]=l):l=e[8],l}function Ho(){let e=(0,F.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t=(0,h.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,h.jsxs)(`svg`,{width:`34`,height:`34`,viewBox:`0 0 34 34`,fill:`none`,"aria-hidden":!0,children:[(0,h.jsx)(`rect`,{x:`1.5`,y:`1.5`,width:`31`,height:`31`,rx:`8`,stroke:`var(--linie-stark)`,strokeWidth:`2`}),(0,h.jsx)(`path`,{d:`M7 18h5l3-7 4 13 3-6h5`,stroke:`var(--bernstein)`,strokeWidth:`2.2`,strokeLinecap:`round`,strokeLinejoin:`round`})]}),(0,h.jsx)(`span`,{className:`font-anzeige text-[28px] leading-none font-bold tracking-[0.06em]`,children:`MC2`}),(0,h.jsx)(`span`,{className:`hidden h-6 w-px bg-linie sm:block`}),(0,h.jsx)(`span`,{className:`schild hidden text-base tracking-[0.22em] text-text-3 sm:block`,children:`Box-Wart`})]}),e[0]=t):t=e[0],t}function Uo(){let e=(0,F.c)(26);mo();let[t,n]=(0,m.useState)(null),r;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(r=()=>n(null),e[0]=r):r=e[0];let i=r,a;e[1]===Symbol.for(`react.memo_cache_sentinel`)?(a=(0,h.jsx)(Ho,{}),e[1]=a):a=e[1];let o;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(o=(0,h.jsx)(`nav`,{"aria-label":`Hauptnavigation`,className:`hidden gap-1 rounded-xl border border-linie bg-[#121518] p-1 md:flex`,children:Io.map(Go)}),e[2]=o):o=e[2];let s;e[3]===Symbol.for(`react.memo_cache_sentinel`)?(s=(0,h.jsx)(`div`,{className:`hidden lg:block`,children:(0,h.jsx)(Vo,{})}),e[3]=s):s=e[3];let c;e[4]===Symbol.for(`react.memo_cache_sentinel`)?(c=(0,h.jsx)(`a`,{href:`/hermes-ui/`,target:`_blank`,rel:`noopener`,className:`flex size-11 items-center justify-center rounded-lg text-text-2 hover:bg-erhaben hover:text-foreground`,title:`Hermes-Dashboard öffnen`,"aria-label":`Hermes-Dashboard öffnen`,children:(0,h.jsx)(Ja,{className:`size-5`})}),e[4]=c):c=e[4];let l;e[5]===Symbol.for(`react.memo_cache_sentinel`)?(l=()=>n(`dienste`),e[5]=l):l=e[5];let u;e[6]===Symbol.for(`react.memo_cache_sentinel`)?(u=(0,h.jsx)(`button`,{type:`button`,onClick:l,className:`flex size-11 items-center justify-center rounded-lg text-text-2 hover:bg-erhaben hover:text-foreground`,title:`Dienste und Protokolle`,"aria-label":`Dienste und Protokolle`,children:(0,h.jsx)(eo,{className:`size-5`})}),e[6]=u):u=e[6];let d;e[7]===Symbol.for(`react.memo_cache_sentinel`)?(d=()=>n(`einstellungen`),e[7]=d):d=e[7];let f;e[8]===Symbol.for(`react.memo_cache_sentinel`)?(f=(0,h.jsxs)(`header`,{className:`flex items-center justify-between gap-4 md:gap-6`,children:[a,o,(0,h.jsxs)(`div`,{className:`flex items-center gap-4 md:gap-5`,children:[s,(0,h.jsxs)(`div`,{className:`hidden items-center gap-1 md:flex`,children:[c,u,(0,h.jsx)(`button`,{type:`button`,onClick:d,className:`flex size-11 items-center justify-center rounded-lg text-text-2 hover:bg-erhaben hover:text-foreground`,title:`Einstellungen`,"aria-label":`Einstellungen`,children:(0,h.jsx)(no,{className:`size-5`})})]}),(0,h.jsx)(zo,{})]})]}),e[8]=f):f=e[8];let p;e[9]===Symbol.for(`react.memo_cache_sentinel`)?(p=(0,h.jsx)(`main`,{className:`flex min-w-0 flex-col gap-5 md:gap-6`,children:(0,h.jsx)(Aa,{})}),e[9]=p):p=e[9];let g;e[10]===Symbol.for(`react.memo_cache_sentinel`)?(g=Io.map(Wo),e[10]=g):g=e[10];let _;e[11]===Symbol.for(`react.memo_cache_sentinel`)?(_=()=>n(`mehr`),e[11]=_):_=e[11];let v;e[12]===Symbol.for(`react.memo_cache_sentinel`)?(v=(0,h.jsxs)(`nav`,{"aria-label":`Hauptnavigation`,className:`fixed inset-x-0 bottom-0 z-40 grid grid-cols-4 gap-1 border-t border-linie bg-[#0e1119]/95 px-2 pt-2 pb-[calc(0.75rem+env(safe-area-inset-bottom))] backdrop-blur md:hidden`,children:[g,(0,h.jsxs)(`button`,{type:`button`,onClick:_,className:`schild flex h-14 flex-col items-center justify-center gap-1 rounded-lg text-xs text-text-3`,children:[(0,h.jsx)(Ka,{className:`size-5`,"aria-hidden":!0}),`Mehr`]})]}),e[12]=v):v=e[12];let y;e[13]===t?y=e[14]:(y=t===`mehr`&&(0,h.jsx)(Fo,{verbindung:(0,h.jsx)(Vo,{}),onDienste:()=>n(`dienste`),onEinstellungen:()=>n(`einstellungen`),onSchliessen:i}),e[13]=t,e[14]=y);let b;e[15]===t?b=e[16]:(b=t===`dienste`&&(0,h.jsx)(No,{offen:!0,onSchliessen:i}),e[15]=t,e[16]=b);let x;e[17]===t?x=e[18]:(x=t===`einstellungen`&&(0,h.jsx)(Po,{offen:!0,onSchliessen:i}),e[17]=t,e[18]=x);let S;e[19]!==y||e[20]!==b||e[21]!==x?(S=(0,h.jsxs)(m.Suspense,{fallback:null,children:[y,b,x]}),e[19]=y,e[20]=b,e[21]=x,e[22]=S):S=e[22];let C;e[23]===Symbol.for(`react.memo_cache_sentinel`)?(C=(0,h.jsx)(Do,{}),e[23]=C):C=e[23];let w;return e[24]===S?w=e[25]:(w=(0,h.jsxs)(`div`,{className:`mx-auto flex min-h-dvh w-full max-w-[1440px] flex-col gap-5 px-4 pt-4 pb-28 sm:px-6 md:gap-6 md:px-10 md:pt-8 md:pb-10`,children:[f,p,v,S,C]}),e[24]=S,e[25]=w),w}function Wo(e){let{to:t,label:n,Icon:r}=e;return(0,h.jsxs)(pa,{to:t,className:`schild flex h-14 flex-col items-center justify-center gap-1 rounded-lg text-xs text-text-3`,activeProps:{className:`bg-erhaben !text-foreground`},activeOptions:{exact:!0},children:[(0,h.jsx)(r,{className:`size-5`,"aria-hidden":!0}),n]},t)}function Go(e){let{to:t,label:n}=e;return(0,h.jsx)(pa,{to:t,className:`schild flex h-11 items-center rounded-[9px] border border-transparent px-5 text-base text-text-3 hover:text-foreground`,activeProps:{className:`!border-linie-stark bg-erhaben !text-foreground`},activeOptions:{exact:!0},children:n},t)}var Ko=class extends Error{status;detail;constructor(e,t){super(t),this.status=e,this.detail=t,this.name=`ApiFehler`}};function qo(e,t){if(e&&typeof e==`object`&&`detail`in e){let t=e.detail;if(typeof t==`string`)return t;if(Array.isArray(t))return t.map(e=>e.msg??String(e)).join(`; `)}return`Die Box antwortet mit Fehler ${t}.`}async function I(e,t={}){let n;try{n=await fetch(e,{...t,headers:{"Content-Type":`application/json`,Accept:`application/json`,...t.headers}})}catch{throw new Ko(0,`MC2 ist nicht erreichbar. Läuft die Box?`)}let r=await n.text(),i=r?L(r):null;if(!n.ok)throw new Ko(n.status,qo(i,n.status));if(typeof i==`string`)throw new Ko(n.status,`Die Box antwortet nicht mit Daten.`);return i}function L(e){try{return JSON.parse(e)}catch{return e}}var R=(e,t)=>I(e,{method:`POST`,body:t===void 0?void 0:JSON.stringify(t)}),Jo=e=>()=>co()?e*5:e,Yo=()=>{let e=(0,F.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={queryKey:[`start`],queryFn:ms,refetchInterval:hs},e[0]=t):t=e[0],ot(t)},Xo=()=>{let e=(0,F.c)(2),t;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t=[`models`],e[0]=t):t=e[0];let n;return e[1]===Symbol.for(`react.memo_cache_sentinel`)?(n={queryKey:t,queryFn:gs,refetchInterval:Jo(3e4)},e[1]=n):n=e[1],ot(n)},Zo=()=>{let e=(0,F.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={queryKey:[`nutzung`],queryFn:_s,refetchInterval:6e5},e[0]=t):t=e[0],ot(t)},Qo=()=>{let e=(0,F.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={queryKey:[`radar`],queryFn:vs,retry:!1,refetchInterval:3e5},e[0]=t):t=e[0],ot(t)},$o=()=>{let e=(0,F.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={queryKey:[`jobs`],queryFn:ys,refetchInterval:xs},e[0]=t):t=e[0],ot(t)},es=()=>{let e=(0,F.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={queryKey:[`sicherungen`],queryFn:Ss},e[0]=t):t=e[0],ot(t)},z=e=>{let t=(0,F.c)(7),n,r;t[0]===e?(n=t[1],r=t[2]):(n=[`update-details`,e],r=()=>I(`/api/maintenance/update-details?kind=${e}`),t[0]=e,t[1]=n,t[2]=r);let i=!!e,a;return t[3]!==n||t[4]!==r||t[5]!==i?(a={queryKey:n,queryFn:r,enabled:i,staleTime:6e5},t[3]=n,t[4]=r,t[5]=i,t[6]=a):a=t[6],ot(a)},ts=()=>{let e=(0,F.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={queryKey:[`updates-verlauf`],queryFn:Cs},e[0]=t):t=e[0],ot(t)},ns=e=>{let t=(0,F.c)(7),n,r;t[0]===e?(n=t[1],r=t[2]):(n=[`protokoll`,e],r=()=>I(`/api/maintenance/logs?service=${encodeURIComponent(e??``)}&lines=200`),t[0]=e,t[1]=n,t[2]=r);let i=!!e,a;return t[3]!==n||t[4]!==r||t[5]!==i?(a={queryKey:n,queryFn:r,enabled:i},t[3]=n,t[4]=r,t[5]=i,t[6]=a):a=t[6],ot(a)},rs=()=>{let e=(0,F.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={queryKey:[`dienste`],queryFn:ws},e[0]=t):t=e[0],ot(t)};function is(e,t){let n=(0,F.c)(6),r=_(),i;n[0]!==t||n[1]!==r?(i=(e,n)=>{let i=e;i&&i.ok===!1?xo(`fehler`,i.detail||i.err||`Das hat nicht geklappt.`):xo(`erfolg`,t.erfolg(n,e));for(let e of t.neuLaden)r.invalidateQueries({queryKey:[e]})},n[0]=t,n[1]=r,n[2]=i):i=n[2];let a;return n[3]!==e||n[4]!==i?(a={mutationFn:e,onSuccess:i,onError:as},n[3]=e,n[4]=i,n[5]=a):a=n[5],st(a)}function as(e){return xo(`fehler`,e.message)}var os=()=>{let e=(0,F.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={erfolg:Es,neuLaden:[`start`]},e[0]=t):t=e[0],is(Ts,t)},ss={alle:`/api/maintenance/update-all`,pruefen:`/api/maintenance/check-updates`,os:`/api/maintenance/os-update`,engine:`/api/maintenance/engine-update`,swap:`/api/maintenance/swap-update`,hermes:`/api/maintenance/hermes-update`},cs=()=>{let e=(0,F.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={erfolg:Os,neuLaden:[`jobs`,`start`]},e[0]=t):t=e[0],is(Ds,t)},ls=()=>{let e=(0,F.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={erfolg:As,neuLaden:[`start`]},e[0]=t):t=e[0],is(ks,t)},B=()=>{let e=(0,F.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={erfolg:Ms,neuLaden:[`sicherungen`,`start`]},e[0]=t):t=e[0],is(js,t)},us=()=>{let e=(0,F.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={erfolg:Ps,neuLaden:[`sicherungen`]},e[0]=t):t=e[0],is(Ns,t)},ds=()=>{let e=(0,F.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={erfolg:Is,neuLaden:[`models`,`start`]},e[0]=t):t=e[0],is(Fs,t)},fs=()=>{let e=(0,F.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={erfolg:Rs,neuLaden:[`radar`,`models`,`start`]},e[0]=t):t=e[0],is(Ls,t)},ps=()=>{let e=(0,F.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={erfolg:Bs,neuLaden:[`radar`]},e[0]=t):t=e[0],is(zs,t)};function ms(){return I(`/api/start`)}function hs(e){return e.state.data&&!e.state.data.updates.gelesen?4e3:Jo(2e4)()}function gs(){return I(`/api/models`)}function _s(){return I(`/api/modelle/nutzung`)}function vs(){return I(`/api/radar`)}function ys(){return I(`/api/jobs`)}function bs(e){return e.state===`running`||e.state===`queued`}function xs(e){return e.state.data?.jobs.some(bs)?2e3:Jo(3e4)()}function Ss(){return I(`/api/zeitmaschine`)}function Cs(){return I(`/api/updates/verlauf`)}function ws(){return I(`/api/system/services`)}function Ts(e){let{hinweis:t,aktion:n}=e;return R(`/api/hinweise/${encodeURIComponent(t)}/aktion/${n}`)}function Es(e){return`${e.label}: erledigt. Der Wächter prüft in einer Minute nach.`}function Ds(e){return R(ss[e])}function Os(e){return e===`pruefen`?`Suche nach Neuem läuft.`:`Update läuft. Den Fortschritt siehst du unten.`}function ks(e){return R(`/api/updates/festgehalten/${encodeURIComponent(e)}/freigeben`)}function As(e,t){return t.text??`Freigegeben.`}function js(){return R(`/api/system/backup`)}function Ms(){return`Sicherung erstellt.`}function Ns(e){return R(`/api/zeitmaschine/restore`,{file:e})}function Ps(){return`Zurückspielen läuft. Die Dienste starten gleich neu.`}function Fs(e){return R(`/api/models/${encodeURIComponent(e)}/load`)}function Is(e){return`${e} wird geladen.`}function Ls(e){let{id:t,aktion:n}=e;return R(`/api/radar/${encodeURIComponent(t)}/${n}`)}function Rs(e){return e.aktion===`uebernehmen`?`${e.name} übernommen.`:`${e.name} verworfen.`}function zs(){return R(`/api/radar/suche`)}function Bs(){return`Radar sucht nach neuen Modellen.`}var Vs=`Europe/Berlin`,Hs=new Intl.DateTimeFormat(`de-DE`,{hour:`2-digit`,minute:`2-digit`,timeZone:Vs}),Us=new Intl.DateTimeFormat(`de-DE`,{weekday:`short`,timeZone:Vs}),Ws=new Intl.DateTimeFormat(`de-DE`,{day:`2-digit`,month:`2-digit`,timeZone:Vs}),Gs=new Intl.DateTimeFormat(`en-CA`,{timeZone:Vs});function Ks(e){return Gs.format(e)}function qs(e,t=new Date){let n=new Date(e);if(Number.isNaN(n.getTime()))return`–`;let r=Ks(t),i=Ks(new Date(t.getTime()-864e5)),a=Ks(new Date(t.getTime()+864e5)),o=Ks(n),s=Hs.format(n);return o===r?`HEUTE ${s}`:o===i?`GESTERN ${s}`:o===a?`MORGEN ${s}`:Math.abs(n.getTime()-t.getTime())<5616e5?`${Us.format(n).replace(`.`,``).toUpperCase()} ${s}`:`${Ws.format(n)} ${s}`}function Js(e,t=new Date){let n=new Date(e*1e3);return Ks(n)===Ks(t)?`seit heute ${Hs.format(n)}`:`seit ${Ws.format(n)}, ${Hs.format(n)}`}function Ys(e,t=Date.now()){let n=Math.max(0,Math.round(t/1e3-e));if(n<60)return`vor ${n} s`;if(n<3600)return`vor ${Math.round(n/60)} min`;if(n<86400)return`vor ${Math.round(n/3600)} h`;let r=Math.round(n/86400);return`vor ${r} ${r===1?`Tag`:`Tagen`}`}function Xs(e){return e==null||e<0?null:[Math.floor(e/86400),Math.floor(e%86400/3600)]}var Zs=e=>e==null?null:e/1024**3;function Qs(e,t=0){let n=Zs(e);return n==null?`–`:n>=1e3?`${(n/1024).toFixed(1).replace(`.`,`,`)} TB`:`${n.toFixed(t).replace(`.`,`,`)} GB`}var $s=e=>e.toLocaleString(`de-DE`),ec=(0,m.lazy)(()=>Mo(()=>import(`./Protokollfenster-CDb28asU.js`).then(e=>({default:e.Protokollfenster})),__vite__mapDeps([6,1,2,3])));function tc({h:e}){let t=os(),[n,r]=(0,m.useState)(null),a=e.stufe===`rot`;async function o(n,i){if(n===`protokoll`){try{let t=await R(`/api/hinweise/${encodeURIComponent(e.id)}/aktion/protokoll`);r({titel:e.titel,text:t.text||t.out||t.err||`Kein Protokoll vorhanden.`})}catch(e){xo(`fehler`,e.message)}return}t.mutate({hinweis:e.id,aktion:n,label:i})}return(0,h.jsxs)(`article`,{className:`flex flex-col gap-2.5 border-t border-linie pt-4`,children:[(0,h.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,h.jsx)(`h3`,{className:`min-w-0 font-sans text-[17px] leading-snug font-semibold`,children:e.titel}),(0,h.jsx)(`span`,{"aria-hidden":!0,className:`hidden h-0 flex-grow border-b-2 border-dotted border-linie-stark sm:block`}),(0,h.jsx)(`span`,{className:i(`schild shrink-0 text-base`,a?`text-rot`:`text-bernstein`),children:a?`Jetzt`:`Prüfen`})]}),(0,h.jsxs)(`p`,{className:`ziffern text-[13px] text-text-3`,children:[Js(e.seit),` · zuletzt `,Ys(e.zuletzt)]}),e.text&&(0,h.jsx)(`p`,{className:`text-[15px] leading-relaxed break-words text-text-2`,children:e.text}),e.aktionen.length>0&&(0,h.jsx)(`div`,{className:`flex flex-wrap gap-2.5 pt-1`,children:e.aktionen.map((e,n)=>(0,h.jsx)(c,{variant:n===0&&e.id!==`protokoll`?`default`:`outline`,size:`sm`,disabled:t.isPending,onClick:()=>o(e.id,e.label),children:e.label},e.id))}),n&&(0,h.jsx)(m.Suspense,{fallback:null,children:(0,h.jsx)(ec,{offen:!0,titel:n.titel,text:n.text,onSchliessen:()=>r(null)})})]})}function nc(e){let t=(0,F.c)(12),{hinweise:n,verlauf:r}=e,i;t[0]===Symbol.for(`react.memo_cache_sentinel`)?(i=new Date().toDateString(),t[0]=i):i=t[0];let a=i,o;if(t[1]!==n.length||t[2]!==r){o=Symbol.for(`react.early_return_sentinel`);bb0:{let e;t[4]===Symbol.for(`react.memo_cache_sentinel`)?(e=e=>(e.art===`erledigt`||e.art===`auto`)&&new Date(e.ts*1e3).toDateString()===a,t[4]=e):e=t[4];let i=r.filter(e);if(n.length===0){let e;t[5]===Symbol.for(`react.memo_cache_sentinel`)?(e=(0,h.jsx)(`p`,{className:`text-[15px] text-text-2`,children:`Keine offenen Punkte. Der Wächter prüft jede Minute.`}),t[5]=e):e=t[5];let n=i.length>0&&(0,h.jsx)(`ul`,{className:`flex flex-col gap-1 text-sm text-text-3`,children:i.slice(0,4).map(ic)}),r;t[6]===n?r=t[7]:(r=(0,h.jsxs)(`div`,{className:`flex flex-col gap-2 border-t border-linie pt-4`,children:[e,n]}),t[6]=n,t[7]=r),o=r;break bb0}}t[1]=n.length,t[2]=r,t[3]=o}else o=t[3];if(o!==Symbol.for(`react.early_return_sentinel`))return o;let s;t[8]===n?s=t[9]:(s=n.map(rc),t[8]=n,t[9]=s);let c;return t[10]===s?c=t[11]:(c=(0,h.jsx)(`div`,{className:`flex flex-col gap-4`,children:s}),t[10]=s,t[11]=c),c}function rc(e){return(0,h.jsx)(tc,{h:e},e.id)}function ic(e){return(0,h.jsxs)(`li`,{children:[(0,h.jsx)(`span`,{className:`ziffern`,children:Ys(e.ts)}),` · `,e.text]},`${e.id}-${e.ts}`)}var ac={gruen:`border-gruen-rand bg-gruen-grund text-gruen`,bernstein:`border-bernstein/60 bg-bernstein-grund text-bernstein`,cyan:`border-cyan-rand bg-cyan-grund text-cyan`,rot:`border-rot-rand bg-rot-grund text-rot-text`,grau:`border-linie bg-erhaben text-text-2`};function oc(e){let t=(0,F.c)(5),{art:n,children:r}=e,a=ac[n===void 0?`grau`:n],o;t[0]===a?o=t[1]:(o=i(`schild inline-flex h-7 items-center rounded-full border px-2.5 text-xs whitespace-nowrap`,a),t[0]=a,t[1]=o);let s;return t[2]!==r||t[3]!==o?(s=(0,h.jsx)(`span`,{className:o,children:r}),t[2]=r,t[3]=o,t[4]=s):s=t[4],s}function sc(e){let t=(0,F.c)(6),{fehler:n,text:r}=e,a=n?`alert`:`status`,o=n?`border-rot-rand bg-rot-grund text-rot-text`:`border-linie bg-panel text-text-2`,s;t[0]===o?s=t[1]:(s=i(`rounded-2xl border px-5 py-8 text-center text-[15px]`,o),t[0]=o,t[1]=s);let c;return t[2]!==a||t[3]!==s||t[4]!==r?(c=(0,h.jsx)(`div`,{role:a,className:s,children:r}),t[2]=a,t[3]=s,t[4]=r,t[5]=c):c=t[5],c}var cc={erledigt:{text:`Erledigt`,farbe:`text-gruen`},fehler:{text:`Fehler`,farbe:`text-rot`},geplant:{text:`Geplant`,farbe:`text-text-3`}};function lc(e){let t=(0,F.c)(18),{e:n}=e,r=cc[n.status]??cc.geplant,a=n.status===`geplant`&&/update/i.test(n.titel)?`text-cyan`:r.farbe,o;t[0]===n.zeit?o=t[1]:(o=qs(n.zeit),t[0]=n.zeit,t[1]=o);let s;t[2]===o?s=t[3]:(s=(0,h.jsx)(`span`,{className:`ziffern text-sm text-text-3`,children:o}),t[2]=o,t[3]=s);let c;t[4]===n.text?c=t[5]:(c=n.text&&(0,h.jsxs)(`span`,{className:`text-text-3`,children:[`, `,n.text]}),t[4]=n.text,t[5]=c);let l;t[6]!==n.titel||t[7]!==c?(l=(0,h.jsxs)(`span`,{className:`min-w-0 text-base`,children:[n.titel,c]}),t[6]=n.titel,t[7]=c,t[8]=l):l=t[8];let u;t[9]===a?u=t[10]:(u=i(`schild text-[13px]`,a),t[9]=a,t[10]=u);let d;t[11]!==r.text||t[12]!==u?(d=(0,h.jsx)(`span`,{className:u,children:r.text}),t[11]=r.text,t[12]=u,t[13]=d):d=t[13];let f;return t[14]!==s||t[15]!==l||t[16]!==d?(f=(0,h.jsxs)(`li`,{className:`grid grid-cols-[112px_minmax(0,1fr)_auto] items-center gap-3 border-t border-linie py-2.5`,children:[s,l,d]}),t[14]=s,t[15]=l,t[16]=d,t[17]=f):f=t[17],f}function uc(e){let t=(0,F.c)(6),{gelaufen:n,geplant:r}=e,i;t[0]!==n||t[1]!==r?(i=[...n,...r.slice(0,5)],t[0]=n,t[1]=r,t[2]=i):i=t[2];let a=i;if(a.length===0){let e;return t[3]===Symbol.for(`react.memo_cache_sentinel`)?(e=(0,h.jsx)(`p`,{className:`text-[15px] text-text-2`,children:`Heute ist noch nichts gelaufen, und nichts ist geplant.`}),t[3]=e):e=t[3],e}let o;return t[4]===a?o=t[5]:(o=(0,h.jsx)(`ol`,{className:`m-0 flex list-none flex-col p-0`,children:a.map(dc)}),t[4]=a,t[5]=o),o}function dc(e){return(0,h.jsx)(lc,{e},`${e.titel}-${e.zeit}`)}var fc=100,pc=95,mc=210,hc=240;function gc(e,t){let n=e*Math.PI/180;return[fc+t*Math.cos(n),pc-t*Math.sin(n)]}var _c=e=>Math.round(e*100)/100;function vc(e,t,n){let r=Math.max(0,Math.min(1,e)),i=Math.max(r,Math.min(1,t)),[a,o]=gc(mc-hc*r,n),[s,c]=gc(mc-hc*i,n),l=+((i-r)*hc>180);return`M ${_c(a)} ${_c(o)} A ${n} ${n} 0 ${l} 1 ${_c(s)} ${_c(c)}`}function yc(e){return e==null?`var(--text-3)`:e>=85?`var(--rot)`:e>=70?`var(--bernstein)`:`var(--gruen)`}function bc(e){if(!e.waechter_wach)return{art:`stumm`,oben:`Wächter`,mitte:`SCHWEIGT`,unten:`Seit über 5 Minuten kein Prüflauf`};if(e.update_laeuft)return{art:`info`,oben:`Wartung`,mitte:`UPDATE LÄUFT`,unten:`Hinweise ruhen bis zum Ende`};if(e.anzahl===0)return{art:`ok`,oben:`Alles`,mitte:`IN ORDNUNG`,unten:`Keine offenen Hinweise`};let t=`${e.anzahl} HINWEIS${e.anzahl===1?``:`E`}`;return e.stufe===`rot`?{art:`rot`,oben:`Störung`,mitte:t,unten:`Drücken zum Ansehen`}:{art:`gelb`,oben:`Achtung`,mitte:t,unten:`Drücken zum Ansehen`}}function xc(e,t){if(!t)return{laeuft:`…`,neu:null};if(e===`os`)return{laeuft:`Ubuntu`,neu:t.count?`${t.count} Pakete`:null};if(e===`hermes`)return{laeuft:t.installed_version?`v${t.installed_version}`:`–`,neu:t.behind?`+${t.behind.toLocaleString(`de-DE`)} Änderungen`:null};let n=e===`engine`?`b`:`v`;return{laeuft:t.installed_build==null?`–`:`${n}${t.installed_build}`,neu:t.latest_build!=null&&t.installed_build!=null&&t.latest_build>t.installed_build?`${n}${t.latest_build}`:null}}function Sc(e){let t=e.aliases.map(e=>e.toLowerCase());return t.includes(`hermes`)||t.includes(`fast`)?`hirn`:t.includes(`coder`)?`coder`:null}var Cc={neu:`Neu`,wartet:`Wartet`,getestet:`Gemessen`,bestanden:`Bestanden`,durchgefallen:`Durchgefallen`,uebernommen:`Übernommen`,verworfen:`Verworfen`};function wc(e,t=``){if(e==null||e===``)return`–`;let n=typeof e==`number`?e.toLocaleString(`de-DE`,{maximumFractionDigits:+(e<10)}):String(e);return t?`${n} ${t}`:n}function Tc(e){let t=(0,F.c)(25),{anteil:n,farbe:r,zonen:i,mitte:a,unter:o,beschriftung:s,ariaText:c}=e,l=r===void 0?`var(--cyan)`:r,u;t[0]===i?u=t[1]:(u=i===void 0?[]:i,t[0]=i,t[1]=u);let d=u,f=n!=null&&n>.004,p;t[2]===Symbol.for(`react.memo_cache_sentinel`)?(p=(0,h.jsx)(`path`,{d:vc(0,1,75),fill:`none`,stroke:`var(--linie)`,strokeWidth:12,strokeLinecap:`round`}),t[2]=p):p=t[2];let m;t[3]===d?m=t[4]:(m=d.map(Ec),t[3]=d,t[4]=m);let g;t[5]!==n||t[6]!==l||t[7]!==f?(g=f&&(0,h.jsx)(`path`,{d:vc(0,n,75),fill:`none`,stroke:l,strokeWidth:12,strokeLinecap:`round`}),t[5]=n,t[6]=l,t[7]=f,t[8]=g):g=t[8];let _;t[9]===Symbol.for(`react.memo_cache_sentinel`)?(_={fontSize:34,fontWeight:500,fill:`var(--foreground)`},t[9]=_):_=t[9];let v;t[10]===a?v=t[11]:(v=(0,h.jsx)(`text`,{x:`100`,y:`100`,textAnchor:`middle`,className:`ziffern`,style:_,children:a}),t[10]=a,t[11]=v);let y;t[12]===o?y=t[13]:(y=o&&(0,h.jsx)(`text`,{x:`100`,y:`122`,textAnchor:`middle`,style:{fontFamily:`var(--font-anzeige)`,fontSize:14,fontWeight:600,letterSpacing:`0.12em`,fill:`var(--text-3)`},children:o.toUpperCase()}),t[12]=o,t[13]=y);let b;t[14]!==c||t[15]!==m||t[16]!==g||t[17]!==v||t[18]!==y?(b=(0,h.jsxs)(`svg`,{viewBox:`0 0 200 150`,className:`h-auto w-full max-w-[200px]`,role:`img`,"aria-label":c,children:[p,m,g,v,y]}),t[14]=c,t[15]=m,t[16]=g,t[17]=v,t[18]=y,t[19]=b):b=t[19];let x;t[20]===s?x=t[21]:(x=(0,h.jsx)(`figcaption`,{className:`schild text-[15px] text-text-3`,children:s}),t[20]=s,t[21]=x);let S;return t[22]!==b||t[23]!==x?(S=(0,h.jsxs)(`figure`,{className:`m-0 flex min-w-0 flex-col items-center gap-1`,children:[b,x]}),t[22]=b,t[23]=x,t[24]=S):S=t[24],S}function Ec(e){return(0,h.jsx)(`path`,{d:vc(e.von,e.bis,86),fill:`none`,stroke:e.farbe,strokeWidth:4,strokeLinecap:`round`},`${e.von}-${e.bis}`)}function Dc(e){let t=(0,F.c)(11),{titel:n,rechts:r,children:a,className:o,id:s}=e,c;t[0]===o?c=t[1]:(c=i(`flex min-w-0 flex-col gap-4 rounded-2xl border border-linie bg-panel p-5 sm:p-6`,o),t[0]=o,t[1]=c);let l;t[2]!==r||t[3]!==n?(l=(n||r)&&(0,h.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3`,children:[n&&(0,h.jsx)(`h2`,{className:`schild text-lg font-bold tracking-[0.22em] text-foreground`,children:n}),r]}),t[2]=r,t[3]=n,t[4]=l):l=t[4];let u;return t[5]!==a||t[6]!==s||t[7]!==c||t[8]!==l||t[9]!==n?(u=(0,h.jsxs)(`section`,{id:s,"aria-label":n,className:c,children:[l,a]}),t[5]=a,t[6]=s,t[7]=c,t[8]=l,t[9]=n,t[10]=u):u=t[10],u}var Oc={ok:{feld:`border-gruen-rand bg-gruen-grund`,name:`text-gruen`,wert:`text-gruen-text`},aus:{feld:`border-aus-rand bg-aus-grund`,name:`text-aus-text`,wert:`text-text-3`},warn:{feld:`border-bernstein bg-bernstein-lampe lampe-atmet`,name:`text-bernstein`,wert:`text-[#f2c46b]`},info:{feld:`border-cyan-rand bg-cyan-grund`,name:`text-cyan`,wert:`text-cyan-text`},fehler:{feld:`border-rot bg-rot-grund shadow-[0_0_18px_rgba(255,90,79,0.35)]`,name:`text-rot`,wert:`text-rot-text`}},kc={ok:`in Ordnung`,aus:`aus`,warn:`braucht Aufmerksamkeit`,info:`Info`,fehler:`Störung`};function Ac(e){let t=(0,F.c)(19),{lampe:n}=e,r=Oc[n.zustand]??Oc.aus,a;t[0]===r.feld?a=t[1]:(a=i(`flex min-h-[58px] flex-col items-center justify-center gap-0.5 rounded-lg border px-2 py-2 text-center`,r.feld),t[0]=r.feld,t[1]=a);let o;t[2]===r.name?o=t[3]:(o=i(`schild text-[17px] leading-none font-bold tracking-[0.18em]`,r.name),t[2]=r.name,t[3]=o);let s;t[4]!==n.label||t[5]!==o?(s=(0,h.jsx)(`span`,{className:o,children:n.label}),t[4]=n.label,t[5]=o,t[6]=s):s=t[6];let c;t[7]===r.wert?c=t[8]:(c=i(`ziffern text-xs uppercase`,r.wert),t[7]=r.wert,t[8]=c);let l;t[9]!==n.wert||t[10]!==c?(l=(0,h.jsx)(`span`,{className:c,children:n.wert}),t[9]=n.wert,t[10]=c,t[11]=l):l=t[11];let u=kc[n.zustand],d;t[12]===u?d=t[13]:(d=(0,h.jsx)(`span`,{className:`sr-only`,children:u}),t[12]=u,t[13]=d);let f;return t[14]!==a||t[15]!==s||t[16]!==l||t[17]!==d?(f=(0,h.jsxs)(`li`,{className:a,children:[s,l,d]}),t[14]=a,t[15]=s,t[16]=l,t[17]=d,t[18]=f):f=t[18],f}var jc={ok:`border-gruen-rand bg-gruen-grund text-gruen`,info:`border-cyan-rand bg-cyan-grund text-cyan`,stumm:`border-aus-rand bg-aus-grund text-aus-text`,gelb:`border-2 border-bernstein bg-bernstein-grund text-bernstein-hell lampe-atmet`,rot:`border-2 border-rot bg-rot-grund text-rot shadow-[0_0_32px_rgba(255,90,79,0.3)]`};function Mc(e){let t=(0,F.c)(26),{zustand:n,lampen:r,onAnsehen:a}=e,o;t[0]===n?o=t[1]:(o=bc(n),t[0]=n,t[1]=o);let s=o,c=s.art===`gelb`||s.art===`rot`,l=!c,u=`${s.oben} ${s.mitte}`,d=jc[s.art],f=c?`cursor-pointer`:`cursor-default`,p;t[2]!==d||t[3]!==f?(p=i(`flex min-h-[130px] flex-col items-center justify-center gap-1 rounded-2xl border px-4 py-4 font-anzeige transition-colors`,d,f),t[2]=d,t[3]=f,t[4]=p):p=t[4];let m;t[5]===s.oben?m=t[6]:(m=(0,h.jsx)(`span`,{className:`schild text-sm tracking-[0.26em]`,children:s.oben}),t[5]=s.oben,t[6]=m);let g;t[7]===s.mitte?g=t[8]:(g=(0,h.jsx)(`span`,{className:`text-[40px] leading-none font-bold tracking-[0.04em] sm:text-[44px]`,children:s.mitte}),t[7]=s.mitte,t[8]=g);let _;t[9]===s.unten?_=t[10]:(_=(0,h.jsx)(`span`,{className:`font-sans text-sm opacity-80`,children:s.unten}),t[9]=s.unten,t[10]=_);let v;t[11]!==a||t[12]!==l||t[13]!==u||t[14]!==p||t[15]!==m||t[16]!==g||t[17]!==_?(v=(0,h.jsxs)(`button`,{type:`button`,onClick:a,disabled:l,"aria-label":u,className:p,children:[m,g,_]}),t[11]=a,t[12]=l,t[13]=u,t[14]=p,t[15]=m,t[16]=g,t[17]=_,t[18]=v):v=t[18];let y;t[19]===r?y=t[20]:(y=r.map(Nc),t[19]=r,t[20]=y);let b;t[21]===y?b=t[22]:(b=(0,h.jsx)(`ul`,{className:`grid grid-cols-2 gap-2.5 rounded-2xl border border-linie bg-panel p-3 sm:grid-cols-4`,children:y}),t[21]=y,t[22]=b);let x;return t[23]!==v||t[24]!==b?(x=(0,h.jsxs)(`section`,{"aria-label":`Warnpanel`,className:`grid gap-4 md:grid-cols-[260px_minmax(0,1fr)] md:gap-5`,children:[v,b]}),t[23]=v,t[24]=b,t[25]=x):x=t[25],x}function Nc(e){return(0,h.jsx)(Ac,{lampe:e},e.id)}function Pc(e){let t=(0,F.c)(2),{z:n}=e,r;return t[0]===n?r=t[1]:(r=(0,h.jsx)(`span`,{className:`ziffern inline-flex h-14 w-[38px] items-center justify-center rounded-md border border-[#2a3036] bg-[#0b0d0f] text-[32px] font-medium`,children:n}),t[0]=n,t[1]=r),r}function Fc(e){let t=(0,F.c)(25),{sekunden:n}=e,r;t[0]===n?r=t[1]:(r=Xs(n),t[0]=n,t[1]=r);let i=r,a=String(Math.min(i?.[0]??0,99)),o;t[2]===a?o=t[3]:(o=a.padStart(2,`0`),t[2]=a,t[3]=o);let s=o,c=String(i?.[1]??0),l;t[4]===c?l=t[5]:(l=c.padStart(2,`0`),t[4]=c,t[5]=l);let u=l,d=i?`Laufzeit ohne Neustart: ${i[0]} Tage, ${i[1]} Stunden`:`Laufzeit unbekannt`,f=i?s[0]:`–`,p;t[6]===f?p=t[7]:(p=(0,h.jsx)(Pc,{z:f}),t[6]=f,t[7]=p);let m=i?s[1]:`–`,g;t[8]===m?g=t[9]:(g=(0,h.jsx)(Pc,{z:m}),t[8]=m,t[9]=g);let _;t[10]===Symbol.for(`react.memo_cache_sentinel`)?(_=(0,h.jsx)(`span`,{className:`schild mr-2 ml-0.5 text-lg font-bold text-text-3`,children:`T`}),t[10]=_):_=t[10];let v=i?u[0]:`–`,y;t[11]===v?y=t[12]:(y=(0,h.jsx)(Pc,{z:v}),t[11]=v,t[12]=y);let b=i?u[1]:`–`,x;t[13]===b?x=t[14]:(x=(0,h.jsx)(Pc,{z:b}),t[13]=b,t[14]=x);let S;t[15]===Symbol.for(`react.memo_cache_sentinel`)?(S=(0,h.jsx)(`span`,{className:`schild ml-0.5 text-lg font-bold text-text-3`,children:`H`}),t[15]=S):S=t[15];let C;t[16]!==y||t[17]!==x||t[18]!==p||t[19]!==g||t[20]!==d?(C=(0,h.jsxs)(`div`,{"aria-label":d,role:`img`,className:`flex h-[150px] max-w-full items-center gap-1.5 pb-5`,children:[p,g,_,y,x,S]}),t[16]=y,t[17]=x,t[18]=p,t[19]=g,t[20]=d,t[21]=C):C=t[21];let w;t[22]===Symbol.for(`react.memo_cache_sentinel`)?(w=(0,h.jsx)(`figcaption`,{className:`schild text-[15px] text-text-3`,children:`Ohne Neustart`}),t[22]=w):w=t[22];let T;return t[23]===C?T=t[24]:(T=(0,h.jsxs)(`figure`,{className:`m-0 flex min-w-0 flex-col items-center justify-end gap-1`,children:[C,w]}),t[23]=C,t[24]=T),T}function Ic(e){let t=(0,F.c)(47),{box:n}=e,r=uo(),i=r?.ram_used??n.ram_used,a=r?.ram_total??n.ram_total,o=r?.temp_cpu??n.temp_cpu,s=r?.temp_gpu??n.temp_gpu,c=n.platte,l=r?.uptime_s??n.uptime_s,u=i!=null&&a?i/a:null,d;t[0]===i?d=t[1]:(d=i==null?`–`:String(Math.round(Zs(i)??0)),t[0]=i,t[1]=d);let f;t[2]===a?f=t[3]:(f=a?`von ${Math.round(Zs(a)??0)} GB`:void 0,t[2]=a,t[3]=f);let p;t[4]!==u||t[5]!==i||t[6]!==a?(p=u==null?`Speicher unbekannt`:`Speicher: ${Qs(i)} von ${Qs(a)} belegt`,t[4]=u,t[5]=i,t[6]=a,t[7]=p):p=t[7];let m;t[8]!==u||t[9]!==d||t[10]!==f||t[11]!==p?(m=(0,h.jsx)(Tc,{beschriftung:`Speicher`,anteil:u,mitte:d,unter:f,ariaText:p}),t[8]=u,t[9]=d,t[10]=f,t[11]=p,t[12]=m):m=t[12];let g=o==null?null:o/100,_;t[13]===o?_=t[14]:(_=yc(o),t[13]=o,t[14]=_);let v;t[15]===Symbol.for(`react.memo_cache_sentinel`)?(v=[{von:.7,bis:.85,farbe:`var(--bernstein)`},{von:.85,bis:1,farbe:`var(--rot)`}],t[15]=v):v=t[15];let y;t[16]===o?y=t[17]:(y=o==null?`–`:`${Math.round(o)}°`,t[16]=o,t[17]=y);let b;t[18]===s?b=t[19]:(b=s==null?void 0:`GPU ${Math.round(s)}°`,t[18]=s,t[19]=b);let x;t[20]===o?x=t[21]:(x=o==null?`Temperatur unbekannt`:`Temperatur ${Math.round(o)} Grad`,t[20]=o,t[21]=x);let S;t[22]!==x||t[23]!==g||t[24]!==_||t[25]!==y||t[26]!==b?(S=(0,h.jsx)(Tc,{beschriftung:`Temperatur`,anteil:g,farbe:_,zonen:v,mitte:y,unter:b,ariaText:x}),t[22]=x,t[23]=g,t[24]=_,t[25]=y,t[26]=b,t[27]=S):S=t[27];let C=c?c.percent/100:null,w=c&&c.percent>=90?`var(--rot)`:c&&c.percent>=80?`var(--bernstein)`:`var(--cyan)`,T;t[28]===c?T=t[29]:(T=c?`${Math.round(c.percent)}%`:`–`,t[28]=c,t[29]=T);let ee;t[30]===c?ee=t[31]:(ee=c?`${Qs(c.used)} / ${Qs(c.total)}`:void 0,t[30]=c,t[31]=ee);let E;t[32]===c?E=t[33]:(E=c?`Platte zu ${Math.round(c.percent)} Prozent belegt`:`Platte unbekannt`,t[32]=c,t[33]=E);let te;t[34]!==C||t[35]!==w||t[36]!==T||t[37]!==ee||t[38]!==E?(te=(0,h.jsx)(Tc,{beschriftung:`Platte`,anteil:C,farbe:w,mitte:T,unter:ee,ariaText:E}),t[34]=C,t[35]=w,t[36]=T,t[37]=ee,t[38]=E,t[39]=te):te=t[39];let D;t[40]===l?D=t[41]:(D=(0,h.jsx)(Fc,{sekunden:l}),t[40]=l,t[41]=D);let ne;return t[42]!==S||t[43]!==te||t[44]!==D||t[45]!==m?(ne=(0,h.jsxs)(`section`,{"aria-label":`Instrumente`,className:`grid grid-cols-2 gap-x-4 gap-y-6 rounded-2xl border border-linie bg-panel px-4 py-5 lg:grid-cols-4 lg:px-6`,children:[m,S,te,D]}),t[42]=S,t[43]=te,t[44]=D,t[45]=m,t[46]=ne):ne=t[46],ne}var Lc={bestanden:`gruen`,durchgefallen:`rot`,wartet:`cyan`,neu:`cyan`};function Rc(e){let t=(0,F.c)(14),{radar:n}=e;if(!n?.kandidaten)return null;let r,i;t[0]===n.kandidaten?(r=t[1],i=t[2]):(r=n.kandidaten.filter(Bc),i=r.find(zc)??r[0],t[0]=n.kandidaten,t[1]=r,t[2]=i);let a=i,o=r.length===1?``:`en`,s;t[3]!==r.length||t[4]!==o?(s=(0,h.jsxs)(`span`,{className:`schild text-sm text-cyan`,children:[`Radar · `,r.length,` Kandidat`,o]}),t[3]=r.length,t[4]=o,t[5]=s):s=t[5];let l;t[6]===a?l=t[7]:(l=a?(0,h.jsxs)(`span`,{className:`flex flex-wrap items-center gap-2 text-[15px]`,children:[(0,h.jsx)(`span`,{className:`ziffern`,children:a.name}),(0,h.jsxs)(`span`,{className:`text-text-2`,children:[`fürs `,a.rolle===`hirn`?`Hirn`:`Coden`]}),(0,h.jsx)(oc,{art:Lc[a.status]??`grau`,children:Cc[a.status]??a.status})]}):(0,h.jsx)(`span`,{className:`text-[15px] text-text-2`,children:`Nichts Besseres in Sicht.`}),t[6]=a,t[7]=l);let u;t[8]!==s||t[9]!==l?(u=(0,h.jsxs)(`div`,{className:`flex min-w-0 flex-col gap-1`,children:[s,l]}),t[8]=s,t[9]=l,t[10]=u):u=t[10];let d;t[11]===Symbol.for(`react.memo_cache_sentinel`)?(d=(0,h.jsx)(c,{variant:`info`,size:`sm`,asChild:!0,children:(0,h.jsx)(pa,{to:`/modelle`,hash:`radar`,children:`Ansehen`})}),t[11]=d):d=t[11];let f;return t[12]===u?f=t[13]:(f=(0,h.jsxs)(`div`,{className:`mt-auto flex flex-wrap items-center justify-between gap-3 rounded-xl border border-cyan-rand bg-cyan-grund px-4 py-3.5`,children:[u,d]}),t[12]=u,t[13]=f),f}function zc(e){return e.status===`bestanden`}function Bc(e){return[`bestanden`,`wartet`,`neu`].includes(e.status)}function Vc(){let e=(0,F.c)(32),{data:t,error:n,isPending:r}=Yo(),i=Qo();if(r){let t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t=(0,h.jsx)(sc,{text:`Die Box meldet sich gleich …`}),e[0]=t):t=e[0],t}if(n||!t){let t=`MC2 antwortet nicht: ${n?.message??`keine Daten`}`,r;return e[1]===t?r=e[2]:(r=(0,h.jsx)(sc,{fehler:!0,text:t}),e[1]=t,e[2]=r),r}let a=t.hinweise.length,o;e[3]!==t.lampen||e[4]!==t.zustand?(o=(0,h.jsx)(Mc,{zustand:t.zustand,lampen:t.lampen,onAnsehen:Hc}),e[3]=t.lampen,e[4]=t.zustand,e[5]=o):o=e[5];let s;e[6]===t.box?s=e[7]:(s=(0,h.jsx)(Ic,{box:t.box}),e[6]=t.box,e[7]=s);let c=a?`ziffern text-sm text-bernstein`:`ziffern text-sm text-gruen`,l=a?`${a} offen`:`alles erledigt`,u;e[8]!==c||e[9]!==l?(u=(0,h.jsx)(`span`,{className:c,children:l}),e[8]=c,e[9]=l,e[10]=u):u=e[10];let d;e[11]!==t.hinweise||e[12]!==t.verlauf?(d=(0,h.jsx)(nc,{hinweise:t.hinweise,verlauf:t.verlauf}),e[11]=t.hinweise,e[12]=t.verlauf,e[13]=d):d=e[13];let f;e[14]!==u||e[15]!==d?(f=(0,h.jsx)(Dc,{titel:`Checkliste`,id:`checkliste`,rechts:u,children:d}),e[14]=u,e[15]=d,e[16]=f):f=e[16];let p;e[17]!==t.flugplan.gelaufen||e[18]!==t.flugplan.geplant?(p=(0,h.jsx)(uc,{gelaufen:t.flugplan.gelaufen,geplant:t.flugplan.geplant}),e[17]=t.flugplan.gelaufen,e[18]=t.flugplan.geplant,e[19]=p):p=e[19];let m;e[20]===i.data?m=e[21]:(m=(0,h.jsx)(Rc,{radar:i.data}),e[20]=i.data,e[21]=m);let g;e[22]!==p||e[23]!==m?(g=(0,h.jsxs)(Dc,{titel:`Flugplan`,children:[p,m]}),e[22]=p,e[23]=m,e[24]=g):g=e[24];let _;e[25]!==f||e[26]!==g?(_=(0,h.jsxs)(`div`,{className:`grid gap-5 lg:grid-cols-[minmax(0,1.35fr)_minmax(0,1fr)] md:gap-6`,children:[f,g]}),e[25]=f,e[26]=g,e[27]=_):_=e[27];let v;return e[28]!==o||e[29]!==s||e[30]!==_?(v=(0,h.jsxs)(h.Fragment,{children:[o,s,_]}),e[28]=o,e[29]=s,e[30]=_,e[31]=v):v=e[31],v}function Hc(){return document.getElementById(`checkliste`)?.scrollIntoView({behavior:`smooth`,block:`start`})}var Uc=va({component:Uo,notFoundComponent:()=>(0,h.jsx)(Qi,{to:`/`})}),Wc=ga({getParentRoute:()=>Uc,path:`/`,component:Vc}),Gc=ga({getParentRoute:()=>Uc,path:`/updates`,component:ya(()=>Mo(()=>import(`./Updates-DPFIId2v.js`),__vite__mapDeps([7,1,8,3])),`UpdatesSeite`)}),Kc=ga({getParentRoute:()=>Uc,path:`/modelle`,component:ya(()=>Mo(()=>import(`./Modelle-CHK2sw1N.js`),__vite__mapDeps([9,1,2,3,8])),`ModelleSeite`)}),qc=Ia({routeTree:Uc.addChildren([Wc,Gc,Kc]),defaultPreload:`intent`,defaultErrorComponent:Va}),Jc=`mc_neuladen_wegen_version`;function Yc(){window.addEventListener(`vite:preloadError`,e=>{sessionStorage.getItem(Jc)||(e.preventDefault(),sessionStorage.setItem(Jc,`1`),window.location.reload())}),window.addEventListener(`load`,()=>{window.setTimeout(()=>sessionStorage.removeItem(Jc),5e3)})}Yc();var Xc=new qe({defaultOptions:{queries:{retry:1,refetchOnWindowFocus:!1,staleTime:5e3}}});(0,Ba.createRoot)(document.getElementById(`root`)).render((0,h.jsx)(m.StrictMode,{children:(0,h.jsx)(v,{client:Xc,children:(0,h.jsx)(za,{router:qc})})}));export{R as A,es as C,ts as D,cs as E,Ja as F,ot as I,_ as L,uo as M,no as N,us as O,eo as P,ps as S,z as T,Xo as _,xc as a,Qo as b,qs as c,$s as d,rs as f,ds as g,$o as h,Sc as i,xo as j,I as k,Zs as l,B as m,Cc as n,oc as o,ls as p,wc as r,sc as s,Dc as t,Qs as u,Zo as v,Yo as w,fs as x,ns as y}; \ No newline at end of file diff --git a/frontend/dist/index.html b/frontend/dist/index.html index 2900192..b80ed26 100644 --- a/frontend/dist/index.html +++ b/frontend/dist/index.html @@ -7,9 +7,9 @@ MC2 · Box-Wart - + - +
diff --git a/frontend/src/lib/anzeige.ts b/frontend/src/lib/anzeige.ts index c3686fb..01df897 100644 --- a/frontend/src/lib/anzeige.ts +++ b/frontend/src/lib/anzeige.ts @@ -83,3 +83,20 @@ export function rolleVon(m: Modell): "hirn" | "coder" | null { if (a.includes("coder")) return "coder" return null } + +// --- Modell-Radar --------------------------------------------------------------------- + +/** Status eines Radar-Kandidaten in Worten fürs Cockpit. */ +export const RADAR_STATUS_TEXT: Record = { + neu: "Neu", wartet: "Wartet", getestet: "Gemessen", bestanden: "Bestanden", + durchgefallen: "Durchgefallen", uebernommen: "Übernommen", verworfen: "Verworfen", +} + +/** Messwert des Radar-Vergleichs lesbar machen (Zahlen deutsch, eine Nachkommastelle). */ +export function messwert(wert: unknown, einheit = ""): string { + if (wert == null || wert === "") return "–" + const text = typeof wert === "number" + ? wert.toLocaleString("de-DE", { maximumFractionDigits: wert < 10 ? 1 : 0 }) + : String(wert) + return einheit ? `${text} ${einheit}` : text +} diff --git a/frontend/src/views/Modelle.tsx b/frontend/src/views/Modelle.tsx index 46bed15..7f55b5f 100644 --- a/frontend/src/views/Modelle.tsx +++ b/frontend/src/views/Modelle.tsx @@ -1,14 +1,15 @@ import { useState } from "react" import { Search } from "lucide-react" +import { Bestaetigen } from "@/components/cockpit/Bestaetigen" import { Chip, type ChipArt, Zustandsfeld } from "@/components/cockpit/Chip" import { Panel } from "@/components/cockpit/Panel" import { Button } from "@/components/ui/button" import { useModellLaden, useModelle, useNutzung, useRadar, useRadarAktion, useRadarSuche, useStart, } from "@/lib/abfragen" -import { rolleVon } from "@/lib/anzeige" +import { messwert, RADAR_STATUS_TEXT, rolleVon } from "@/lib/anzeige" import { useLetzteMetrik } from "@/lib/strom" -import type { Modell, Nutzung, RadarKandidat } from "@/lib/typen" +import type { Modell, Nutzung, RadarKandidat, RadarTest } from "@/lib/typen" import { flugplanZeit, gb, gbText, zahl } from "@/lib/zeit" import { ModellSuche } from "./ModellSuche" @@ -122,39 +123,94 @@ function NutzungsPanel({ nutzung }: { nutzung: Nutzung | undefined }) { const STATUS_ART: Record = { bestanden: "gruen", durchgefallen: "rot", wartet: "cyan", neu: "cyan", getestet: "grau", uebernommen: "gruen", verworfen: "grau", } +const URTEIL_FARBE: Record = { besser: "text-gruen", schlechter: "text-rot-text", gleich: "text-text-2" } -function Kandidat({ k }: { k: RadarKandidat }) { +type Vergleichszeile = { kandidat: unknown; baseline: unknown; einheit?: string; urteil?: string } + +/** Die Messwerte hinter dem Urteil: Kandidat gegen das heutige Modell der Rolle. */ +function Vergleich({ test }: { test: RadarTest }) { + const zeilen = Object.entries(test.vergleich ?? {}) as [string, Vergleichszeile][] + if (zeilen.length === 0) return null + return ( +
+
+ Messwert + Kandidat + Heute +
+ {zeilen.map(([name, z]) => ( +
+ {name} + + {messwert(z.kandidat, z.einheit)} + + {messwert(z.baseline, z.einheit)} +
+ ))} +
+ ) +} + +function Kandidat({ k, test, heute }: { k: RadarKandidat; test: RadarTest | undefined; heute: string | undefined }) { const aktion = useRadarAktion() - const offen = ["bestanden", "wartet", "neu"].includes(k.status) + const [frage, setFrage] = useState(null) + const offen = ["bestanden", "wartet", "neu", "getestet"].includes(k.status) + const hirn = k.rolle === "hirn" return (
  • {k.name} - {k.rolle === "hirn" ? "fürs Hirn" : "fürs Coden"} + {hirn ? "fürs Hirn" : "fürs Coden"} {k.eng ? "passt knapp" : k.passt ? "passt" : "passt nicht"} - {k.status} + {RADAR_STATUS_TEXT[k.status] ?? k.status}

    {k.groesse_gb != null ? `${k.groesse_gb.toLocaleString("de-DE")} GB. ` : ""} {k.begruendung}

    + {test && ["bestanden", "durchgefallen"].includes(k.status) && } {offen && (
    {k.status === "bestanden" && ( - )} -
    )} + setFrage(null)} + onJa={() => { + aktion.mutate({ id: k.id, aktion: "uebernehmen", name: k.name }) + setFrage(null) + }} + /> + setFrage(null)} + onJa={() => { + aktion.mutate({ id: k.id, aktion: "verwerfen", name: k.name }) + setFrage(null) + }} + />
  • ) } -function RadarPanel() { +function RadarPanel({ hirn, coder }: { hirn: string | undefined; coder: string | undefined }) { const radar = useRadar() const suche = useRadarSuche() if (radar.isError) { @@ -181,7 +237,14 @@ function RadarPanel() {

    Nichts Besseres in Sicht.

    ) : (
      - {d.kandidaten.map((k) => )} + {d.kandidaten.map((k) => ( + t.kandidat === k.id)} + heute={k.rolle === "hirn" ? hirn : coder} + /> + ))}
    )} {d && d.tests.length > 0 && ( @@ -223,7 +286,7 @@ export function ModelleSeite() {
    - +
    {vorn.name} fürs {vorn.rolle === "hirn" ? "Hirn" : "Coden"} - {vorn.status} + {RADAR_STATUS_TEXT[vorn.status] ?? vorn.status} ) : ( Nichts Besseres in Sicht.