diff --git a/backend/glossa_lab/api/signs.py b/backend/glossa_lab/api/signs.py new file mode 100644 index 00000000..9b844ff1 --- /dev/null +++ b/backend/glossa_lab/api/signs.py @@ -0,0 +1,298 @@ +"""Signs API — unified sign index with anchored cross-references. + +Data sources (merged on startup): + 1. ``INDUS_FINAL_ANCHORS.json`` — the authoritative anchor file + 2. ``anchor_sets`` DB table — user-created named anchor sets + 3. ``anchor_staging.json`` / ``anchor_staging_archive.json`` — staging pipeline + +Endpoints (mounted at ``/api/v1/signs``): + GET /signs — paginated, filterable sign list + GET /signs/summary — aggregate counts + GET /signs/{sign_id} — full detail for one sign +""" +from __future__ import annotations + +import json +import logging +import re +from pathlib import Path +from typing import Any + +from fastapi import APIRouter, HTTPException, Query + +router = APIRouter(prefix="/api/v1/signs", tags=["signs"]) +_log = logging.getLogger("glossa_lab.api.signs") + +# ── In-memory sign index ────────────────────────────────────────────────── +# Built lazily on first request from all available sources. + +_SIGNS_INDEX: dict[str, dict[str, Any]] = {} +_INDEX_BUILT = False + +_BACKEND_DIR = Path(__file__).resolve().parent.parent.parent # backend/ +_REPORTS_DIR = _BACKEND_DIR / "reports" +_OUTPUTS_DIR = _BACKEND_DIR / "outputs" + + +def _parse_phase(source_exp: str) -> int | None: + """Extract phase number from an experiment id like 'indus_anchored_sa_dravidian_p257'.""" + m = re.search(r"[_pP](\d+)", source_exp or "") + return int(m.group(1)) if m else None + + +def _build_sign_entry( + sign_id: str, + reading: str, + confidence: str, + *, + basis: str = "", + source_experiment: str = "", + evidence_score: float = 0.0, + evidence_type: str = "", + dedr: str = "", + dedr_source: str = "", + phase_upgraded: int | None = None, + corpus_freq: int = 0, + in_corpus: bool = True, + wells_ids: list[str] | None = None, + mahadevan_ids: list[str] | None = None, + numbering_system: str = "wells", + gloss: str = "", + extra: dict[str, Any] | None = None, +) -> dict[str, Any]: + phase = phase_upgraded or _parse_phase(source_experiment) + return { + "sign_id": sign_id, + "reading": reading, + "confidence": confidence.upper(), + "in_corpus": in_corpus, + "corpus_freq": corpus_freq, + "evidence_type": evidence_type, + "evidence_score": evidence_score, + "basis": basis, + "gloss": gloss, + "source": { + "experiment": source_experiment, + "phase": phase, + "job_id": None, + "report_ref": f"Phase {phase} Anchored SA" if phase else "", + "staging_entry": None, + "dedr_ref": f"DEDR {dedr}" if dedr else "", + "dedr_source": dedr_source, + }, + "wells_ids": wells_ids or [], + "mahadevan_ids": mahadevan_ids or [], + "numbering_system": numbering_system, + **(extra or {}), + } + + +def _load_final_anchors() -> None: + """Load INDUS_FINAL_ANCHORS.json into the index.""" + path = _REPORTS_DIR / "INDUS_FINAL_ANCHORS.json" + if not path.exists(): + return + try: + data = json.loads(path.read_text(encoding="utf-8")) + anchors = data.get("anchors") or {} + for sid, info in anchors.items(): + reading = info.get("reading", "") + confidence = (info.get("confidence") or "LOW").upper() + source = info.get("source", "") + dedr = info.get("dedr", "") + dedr_source = info.get("dedr_source", "") + phase_upgraded = info.get("phase_upgraded") + gloss = info.get("gloss", "") + basis = info.get("basis", "") + + entry = _build_sign_entry( + sign_id=sid, + reading=reading, + confidence=confidence, + basis=basis, + source_experiment=source, + dedr=str(dedr) if dedr else "", + dedr_source=dedr_source, + phase_upgraded=int(phase_upgraded) if phase_upgraded else None, + gloss=gloss, + ) + _SIGNS_INDEX[sid] = entry + _log.info("Loaded %d signs from INDUS_FINAL_ANCHORS.json", len(anchors)) + except Exception: # noqa: BLE001 + _log.warning("Failed to load INDUS_FINAL_ANCHORS.json", exc_info=True) + + +def _load_staging_files() -> None: + """Load anchor_staging.json and anchor_staging_archive.json if present.""" + for fname in ("anchor_staging.json", "anchor_staging_archive.json"): + path = _OUTPUTS_DIR / fname + if not path.exists(): + continue + try: + items = json.loads(path.read_text(encoding="utf-8")) + if not isinstance(items, list): + continue + count = 0 + for item in items: + sid = item.get("sign") or item.get("sign_id", "") + if not sid or sid in _SIGNS_INDEX: + continue + status = (item.get("review_status") or "").lower() + if status not in ("approved", "verified", "accepted"): + continue + entry = _build_sign_entry( + sign_id=sid, + reading=item.get("proposed_reading", ""), + confidence=(item.get("confidence") or "LOW").upper(), + evidence_type=item.get("evidence_type", ""), + evidence_score=float(item.get("evidence_score", 0)), + source_experiment=item.get("source_experiment", ""), + ) + entry["staging_source"] = fname + _SIGNS_INDEX[sid] = entry + count += 1 + if count: + _log.info("Loaded %d signs from %s", count, fname) + except Exception: # noqa: BLE001 + _log.warning("Failed to load %s", fname, exc_info=True) + + +async def _load_anchor_sets() -> None: + """Load pairs from the anchor_sets DB table.""" + try: + from glossa_lab.database import get_db # noqa: PLC0415 + + db = get_db() + if db is None: + return + sets = await db.list_anchor_sets() + count = 0 + for aset in sets: + pairs = aset.get("pairs") + if isinstance(pairs, str): + try: + pairs = json.loads(pairs) + except Exception: # noqa: BLE001 + continue + if not isinstance(pairs, list): + continue + for pair in pairs: + cipher = pair.get("cipher", "") + target = pair.get("target", "") + if not cipher or cipher in _SIGNS_INDEX: + continue + conf = (pair.get("confidence") or "medium").upper() + entry = _build_sign_entry( + sign_id=cipher, + reading=target, + confidence=conf, + source_experiment=f"anchor_set:{aset.get('id', '')}", + ) + entry["anchor_set_name"] = aset.get("name", "") + _SIGNS_INDEX[cipher] = entry + count += 1 + if count: + _log.info("Loaded %d signs from anchor_sets table", count) + except Exception: # noqa: BLE001 + _log.warning("Failed to load anchor_sets", exc_info=True) + + +async def _ensure_index() -> None: + """Build the index once on first access.""" + global _INDEX_BUILT # noqa: PLW0603 + if _INDEX_BUILT: + return + _load_final_anchors() + _load_staging_files() + await _load_anchor_sets() + _INDEX_BUILT = True + _log.info("Signs index ready: %d total entries", len(_SIGNS_INDEX)) + + +# ── Endpoints ───────────────────────────────────────────────────────────── + + +@router.get("/summary") +async def signs_summary() -> dict[str, Any]: + """Aggregate counts: total, deciphered, undeciphered, by confidence, etc.""" + await _ensure_index() + signs = list(_SIGNS_INDEX.values()) + total = len(signs) + high = sum(1 for s in signs if s["confidence"] == "HIGH") + medium = sum(1 for s in signs if s["confidence"] == "MEDIUM") + low = sum(1 for s in signs if s["confidence"] == "LOW") + in_corpus = sum(1 for s in signs if s.get("in_corpus")) + deciphered = high + medium + low # all with readings + # ICIT reference: 713 known signs total + icit_total = 713 + undeciphered = max(0, icit_total - deciphered) + return { + "total": total, + "deciphered": deciphered, + "undeciphered": undeciphered, + "icit_total": icit_total, + "high": high, + "medium": medium, + "low": low, + "in_corpus": in_corpus, + } + + +@router.get("") +async def list_signs( + deciphered: bool | None = Query(None), + confidence: str | None = Query(None), + in_corpus: bool | None = Query(None), + search: str | None = Query(None), + limit: int = Query(50, ge=1, le=500), + offset: int = Query(0, ge=0), +) -> dict[str, Any]: + """Paginated, filterable sign list.""" + await _ensure_index() + results = list(_SIGNS_INDEX.values()) + + # Filters + if confidence and confidence.upper() != "ANY": + conf_set = {c.strip().upper() for c in confidence.split(",")} + results = [s for s in results if s["confidence"] in conf_set] + + if in_corpus is not None: + results = [s for s in results if s.get("in_corpus") == in_corpus] + + if deciphered is not None: + if deciphered: + results = [s for s in results if s.get("reading")] + else: + results = [s for s in results if not s.get("reading")] + + if search: + q = search.lower() + results = [ + s for s in results + if q in s["sign_id"].lower() + or q in (s.get("reading") or "").lower() + or q in (s.get("basis") or "").lower() + ] + + # Sort by confidence rank then sign_id + conf_rank = {"HIGH": 0, "MEDIUM": 1, "LOW": 2, "UNCERTAIN": 3} + results.sort(key=lambda s: (conf_rank.get(s["confidence"], 9), s["sign_id"])) + + total = len(results) + page = results[offset: offset + limit] + return { + "items": page, + "total": total, + "limit": limit, + "offset": offset, + } + + +@router.get("/{sign_id}") +async def get_sign(sign_id: str) -> dict[str, Any]: + """Full detail for one sign including cross-references.""" + await _ensure_index() + entry = _SIGNS_INDEX.get(sign_id) + if entry is None: + raise HTTPException(status_code=404, detail=f"Sign '{sign_id}' not found") + return entry diff --git a/backend/glossa_lab/main.py b/backend/glossa_lab/main.py index 55ef1992..b31dc8ef 100644 --- a/backend/glossa_lab/main.py +++ b/backend/glossa_lab/main.py @@ -55,6 +55,7 @@ from glossa_lab.api.studies import router as studies_router from glossa_lab.api.system import router as system_router from glossa_lab.api.terminal import router as terminal_router +from glossa_lab.api.signs import router as signs_router from glossa_lab.api.texts import router as texts_router from glossa_lab.config import get_settings from glossa_lab.database import close_db, init_db @@ -378,6 +379,7 @@ def create_app() -> FastAPI: application.include_router(model_intelligence_router) # /api/v1/model-intelligence application.include_router(indus_evidence_router) # already prefixed at /api/v1/indus-evidence application.include_router(research_loop_router) # already prefixed at /api/v1/research-loop + application.include_router(signs_router) # already prefixed at /api/v1/signs # Serve built frontend # Skipped silently in dev if the dist directory does not yet exist. diff --git a/backend/scripts/seed_canonical_signs.py b/backend/scripts/seed_canonical_signs.py new file mode 100644 index 00000000..834e3117 --- /dev/null +++ b/backend/scripts/seed_canonical_signs.py @@ -0,0 +1,238 @@ +#!/usr/bin/env python3 +"""Seed the canonical_signs table from all available anchor sources. + +Sources (in priority order): + 1. backend/reports/INDUS_FINAL_ANCHORS.json — authoritative anchor file + 2. anchor_sets DB table — user-created named anchor sets (pairs JSON) + 3. backend/outputs/anchor_staging_archive.json — archived/verified candidates + 4. backend/outputs/anchor_staging.json — approved staged candidates + +Usage: + python backend/scripts/seed_canonical_signs.py +""" +from __future__ import annotations + +import json +import re +import sqlite3 +import sys +from pathlib import Path + +# Resolve paths relative to repo root +_SCRIPT_DIR = Path(__file__).resolve().parent +_BACKEND_DIR = _SCRIPT_DIR.parent +_REPO_ROOT = _BACKEND_DIR.parent +_REPORTS_DIR = _BACKEND_DIR / "reports" +_OUTPUTS_DIR = _BACKEND_DIR / "outputs" +_DB_PATH = _BACKEND_DIR / "data" / "glossa.db" + + +def _parse_phase(source_exp: str) -> int: + """Extract phase number from experiment id.""" + m = re.search(r"[_pP](\d+)", source_exp or "") + return int(m.group(1)) if m else 0 + + +def main() -> None: + signs: dict[str, dict] = {} # sign_id → sign data + + # ── 1. INDUS_FINAL_ANCHORS.json ───────────────────────────────────── + fa_path = _REPORTS_DIR / "INDUS_FINAL_ANCHORS.json" + fa_count = 0 + if fa_path.exists(): + data = json.loads(fa_path.read_text(encoding="utf-8")) + anchors = data.get("anchors") or {} + for sid, info in anchors.items(): + reading = info.get("reading", "") + confidence = (info.get("confidence") or "LOW").upper() + dedr = str(info.get("dedr", "")) + phase = info.get("phase_upgraded", 0) or _parse_phase(info.get("source", "")) + signs[sid] = { + "internal_id": sid, + "sign_id": sid, + "numbering_system": "wells", + "description": reading, + "wells_ids": "", + "mahadevan_ids": "", + "parpola_allographs": "", + "icit_function": info.get("gloss", ""), + "corpus_freq": 0, + "start_rate": 0.0, + "end_rate": 0.0, + "internal_rate": 0.0, + "in_corpus": 1, + "n_feature_dims": 0, + "_confidence": confidence, + "_reading": reading, + "_dedr": dedr, + "_phase": phase, + "_source": info.get("source", ""), + "_basis": info.get("basis", ""), + } + fa_count += 1 + print(f" INDUS_FINAL_ANCHORS.json: {fa_count} signs") + else: + print(f" INDUS_FINAL_ANCHORS.json: not found at {fa_path}") + + # ── 2. anchor_sets DB table ───────────────────────────────────────── + db_count = 0 + if _DB_PATH.exists(): + conn = sqlite3.connect(str(_DB_PATH)) + conn.row_factory = sqlite3.Row + try: + rows = conn.execute("SELECT * FROM anchor_sets").fetchall() + for row in rows: + pairs_raw = row["pairs"] + try: + pairs = json.loads(pairs_raw) if isinstance(pairs_raw, str) else pairs_raw + except Exception: + continue + if not isinstance(pairs, list): + continue + for pair in pairs: + cipher = pair.get("cipher", "") + target = pair.get("target", "") + if not cipher or cipher in signs: + continue + conf = (pair.get("confidence") or "medium").upper() + signs[cipher] = { + "internal_id": cipher, + "sign_id": cipher, + "numbering_system": "wells", + "description": target, + "wells_ids": "", + "mahadevan_ids": "", + "parpola_allographs": "", + "icit_function": "", + "corpus_freq": 0, + "start_rate": 0.0, + "end_rate": 0.0, + "internal_rate": 0.0, + "in_corpus": 1, + "n_feature_dims": 0, + "_confidence": conf, + "_reading": target, + "_dedr": "", + "_phase": 0, + "_source": f"anchor_set:{row['id']}", + "_basis": f"From anchor set: {row['name']}", + } + db_count += 1 + print(f" anchor_sets table: {db_count} new signs ({len(rows)} sets scanned)") + except Exception as exc: + print(f" anchor_sets table: error — {exc}") + finally: + conn.close() + else: + print(f" Database not found at {_DB_PATH}") + + # ── 3. Staging files ──────────────────────────────────────────────── + for fname in ("anchor_staging_archive.json", "anchor_staging.json"): + path = _OUTPUTS_DIR / fname + if not path.exists(): + print(f" {fname}: not found (skipped)") + continue + try: + items = json.loads(path.read_text(encoding="utf-8")) + if not isinstance(items, list): + print(f" {fname}: not a list (skipped)") + continue + stg_count = 0 + for item in items: + sid = item.get("sign") or item.get("sign_id", "") + if not sid or sid in signs: + continue + status = (item.get("review_status") or "").lower() + if status not in ("approved", "verified", "accepted"): + continue + signs[sid] = { + "internal_id": sid, + "sign_id": sid, + "numbering_system": "wells", + "description": item.get("proposed_reading", ""), + "wells_ids": "", + "mahadevan_ids": "", + "parpola_allographs": "", + "icit_function": "", + "corpus_freq": 0, + "start_rate": 0.0, + "end_rate": 0.0, + "internal_rate": 0.0, + "in_corpus": 1, + "n_feature_dims": 0, + "_confidence": (item.get("confidence") or "LOW").upper(), + "_reading": item.get("proposed_reading", ""), + "_dedr": "", + "_phase": _parse_phase(item.get("source_experiment", "")), + "_source": item.get("source_experiment", ""), + "_basis": item.get("evidence_type", ""), + } + stg_count += 1 + print(f" {fname}: {stg_count} new signs") + except Exception as exc: + print(f" {fname}: error — {exc}") + + # ── Insert into DB ────────────────────────────────────────────────── + if not _DB_PATH.exists(): + print(f"\nERROR: Database not found at {_DB_PATH}") + sys.exit(1) + + conn = sqlite3.connect(str(_DB_PATH)) + conn.execute("PRAGMA journal_mode=WAL") + conn.execute("PRAGMA busy_timeout=5000") + + # Count existing + try: + existing_count = conn.execute("SELECT COUNT(*) FROM canonical_signs").fetchone()[0] + except Exception: + existing_count = 0 + + inserted = 0 + updated = 0 + for sid, s in signs.items(): + try: + existing = conn.execute( + "SELECT internal_id FROM canonical_signs WHERE internal_id=? OR sign_id=?", + (sid, sid), + ).fetchone() + if existing: + conn.execute( + """UPDATE canonical_signs SET + description=?, icit_function=?, in_corpus=? + WHERE internal_id=? OR sign_id=?""", + (s["description"], s["icit_function"], s["in_corpus"], sid, sid), + ) + updated += 1 + else: + conn.execute( + """INSERT INTO canonical_signs + (internal_id, sign_id, numbering_system, description, + wells_ids, mahadevan_ids, parpola_allographs, icit_function, + corpus_freq, start_rate, end_rate, internal_rate, + in_corpus, n_feature_dims) + VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)""", + ( + s["internal_id"], s["sign_id"], s["numbering_system"], + s["description"], s["wells_ids"], s["mahadevan_ids"], + s["parpola_allographs"], s["icit_function"], + s["corpus_freq"], s["start_rate"], s["end_rate"], + s["internal_rate"], s["in_corpus"], s["n_feature_dims"], + ), + ) + inserted += 1 + except Exception as exc: + print(f" Warning: failed to insert/update {sid}: {exc}") + + conn.commit() + total = conn.execute("SELECT COUNT(*) FROM canonical_signs").fetchone()[0] + conn.close() + + print(f"\n{'=' * 50}") + print(f"Inserted {inserted} signs, updated {updated}, total {total}") + print(f"Previously in DB: {existing_count}") + print(f"{'=' * 50}") + + +if __name__ == "__main__": + print("Seeding canonical_signs from available sources...\n") + main() diff --git a/frontend/dist/assets/index-BXsZCCru.js b/frontend/dist/assets/index-CzGnXCY6.js similarity index 52% rename from frontend/dist/assets/index-BXsZCCru.js rename to frontend/dist/assets/index-CzGnXCY6.js index c349e9f9..29a488f4 100644 --- a/frontend/dist/assets/index-BXsZCCru.js +++ b/frontend/dist/assets/index-CzGnXCY6.js @@ -1,4 +1,4 @@ -(function(){const o=document.createElement("link").relList;if(o&&o.supports&&o.supports("modulepreload"))return;for(const c of document.querySelectorAll('link[rel="modulepreload"]'))l(c);new MutationObserver(c=>{for(const d of c)if(d.type==="childList")for(const u of d.addedNodes)u.tagName==="LINK"&&u.rel==="modulepreload"&&l(u)}).observe(document,{childList:!0,subtree:!0});function r(c){const d={};return c.integrity&&(d.integrity=c.integrity),c.referrerPolicy&&(d.referrerPolicy=c.referrerPolicy),c.crossOrigin==="use-credentials"?d.credentials="include":c.crossOrigin==="anonymous"?d.credentials="omit":d.credentials="same-origin",d}function l(c){if(c.ep)return;c.ep=!0;const d=r(c);fetch(c.href,d)}})();function cb(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var Cf={exports:{}},fa={};/** +(function(){const o=document.createElement("link").relList;if(o&&o.supports&&o.supports("modulepreload"))return;for(const c of document.querySelectorAll('link[rel="modulepreload"]'))l(c);new MutationObserver(c=>{for(const d of c)if(d.type==="childList")for(const u of d.addedNodes)u.tagName==="LINK"&&u.rel==="modulepreload"&&l(u)}).observe(document,{childList:!0,subtree:!0});function r(c){const d={};return c.integrity&&(d.integrity=c.integrity),c.referrerPolicy&&(d.referrerPolicy=c.referrerPolicy),c.crossOrigin==="use-credentials"?d.credentials="include":c.crossOrigin==="anonymous"?d.credentials="omit":d.credentials="same-origin",d}function l(c){if(c.ep)return;c.ep=!0;const d=r(c);fetch(c.href,d)}})();function db(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var Tf={exports:{}},fa={};/** * @license React * react-jsx-runtime.production.js * @@ -6,7 +6,7 @@ * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. - */var Hx;function Yw(){if(Hx)return fa;Hx=1;var t=Symbol.for("react.transitional.element"),o=Symbol.for("react.fragment");function r(l,c,d){var u=null;if(d!==void 0&&(u=""+d),c.key!==void 0&&(u=""+c.key),"key"in c){d={};for(var p in c)p!=="key"&&(d[p]=c[p])}else d=c;return c=d.ref,{$$typeof:t,type:l,key:u,ref:c!==void 0?c:null,props:d}}return fa.Fragment=o,fa.jsx=r,fa.jsxs=r,fa}var Wx;function Vw(){return Wx||(Wx=1,Cf.exports=Yw()),Cf.exports}var n=Vw(),Tf={exports:{}},Xe={};/** + */var $x;function Jw(){if($x)return fa;$x=1;var t=Symbol.for("react.transitional.element"),o=Symbol.for("react.fragment");function r(l,c,d){var u=null;if(d!==void 0&&(u=""+d),c.key!==void 0&&(u=""+c.key),"key"in c){d={};for(var p in c)p!=="key"&&(d[p]=c[p])}else d=c;return c=d.ref,{$$typeof:t,type:l,key:u,ref:c!==void 0?c:null,props:d}}return fa.Fragment=o,fa.jsx=r,fa.jsxs=r,fa}var Hx;function Kw(){return Hx||(Hx=1,Tf.exports=Jw()),Tf.exports}var n=Kw(),zf={exports:{}},Xe={};/** * @license React * react.production.js * @@ -14,7 +14,7 @@ * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. - */var Ux;function Xw(){if(Ux)return Xe;Ux=1;var t=Symbol.for("react.transitional.element"),o=Symbol.for("react.portal"),r=Symbol.for("react.fragment"),l=Symbol.for("react.strict_mode"),c=Symbol.for("react.profiler"),d=Symbol.for("react.consumer"),u=Symbol.for("react.context"),p=Symbol.for("react.forward_ref"),g=Symbol.for("react.suspense"),h=Symbol.for("react.memo"),v=Symbol.for("react.lazy"),y=Symbol.for("react.activity"),b=Symbol.iterator;function S(N){return N===null||typeof N!="object"?null:(N=b&&N[b]||N["@@iterator"],typeof N=="function"?N:null)}var k={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},_=Object.assign,T={};function w(N,O,$){this.props=N,this.context=O,this.refs=T,this.updater=$||k}w.prototype.isReactComponent={},w.prototype.setState=function(N,O){if(typeof N!="object"&&typeof N!="function"&&N!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,N,O,"setState")},w.prototype.forceUpdate=function(N){this.updater.enqueueForceUpdate(this,N,"forceUpdate")};function C(){}C.prototype=w.prototype;function j(N,O,$){this.props=N,this.context=O,this.refs=T,this.updater=$||k}var L=j.prototype=new C;L.constructor=j,_(L,w.prototype),L.isPureReactComponent=!0;var W=Array.isArray;function P(){}var z={H:null,A:null,T:null,S:null},M=Object.prototype.hasOwnProperty;function q(N,O,$){var F=$.ref;return{$$typeof:t,type:N,key:O,ref:F!==void 0?F:null,props:$}}function K(N,O){return q(N.type,O,N.props)}function D(N){return typeof N=="object"&&N!==null&&N.$$typeof===t}function Y(N){var O={"=":"=0",":":"=2"};return"$"+N.replace(/[=:]/g,function($){return O[$]})}var H=/\/+/g;function A(N,O){return typeof N=="object"&&N!==null&&N.key!=null?Y(""+N.key):O.toString(36)}function G(N){switch(N.status){case"fulfilled":return N.value;case"rejected":throw N.reason;default:switch(typeof N.status=="string"?N.then(P,P):(N.status="pending",N.then(function(O){N.status==="pending"&&(N.status="fulfilled",N.value=O)},function(O){N.status==="pending"&&(N.status="rejected",N.reason=O)})),N.status){case"fulfilled":return N.value;case"rejected":throw N.reason}}throw N}function R(N,O,$,F,I){var J=typeof N;(J==="undefined"||J==="boolean")&&(N=null);var ne=!1;if(N===null)ne=!0;else switch(J){case"bigint":case"string":case"number":ne=!0;break;case"object":switch(N.$$typeof){case t:case o:ne=!0;break;case v:return ne=N._init,R(ne(N._payload),O,$,F,I)}}if(ne)return I=I(N),ne=F===""?"."+A(N,0):F,W(I)?($="",ne!=null&&($=ne.replace(H,"$&/")+"/"),R(I,O,$,"",function(_e){return _e})):I!=null&&(D(I)&&(I=K(I,$+(I.key==null||N&&N.key===I.key?"":(""+I.key).replace(H,"$&/")+"/")+ne)),O.push(I)),1;ne=0;var se=F===""?".":F+":";if(W(N))for(var pe=0;pe>>1,Q=R[V];if(0>>1;Vc($,B))Fc(I,$)?(R[V]=I,R[F]=B,V=F):(R[V]=$,R[O]=B,V=O);else if(Fc(I,B))R[V]=I,R[F]=B,V=F;else break e}}return X}function c(R,X){var B=R.sortIndex-X.sortIndex;return B!==0?B:R.id-X.id}if(t.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var d=performance;t.unstable_now=function(){return d.now()}}else{var u=Date,p=u.now();t.unstable_now=function(){return u.now()-p}}var g=[],h=[],v=1,y=null,b=3,S=!1,k=!1,_=!1,T=!1,w=typeof setTimeout=="function"?setTimeout:null,C=typeof clearTimeout=="function"?clearTimeout:null,j=typeof setImmediate<"u"?setImmediate:null;function L(R){for(var X=r(h);X!==null;){if(X.callback===null)l(h);else if(X.startTime<=R)l(h),X.sortIndex=X.expirationTime,o(g,X);else break;X=r(h)}}function W(R){if(_=!1,L(R),!k)if(r(g)!==null)k=!0,P||(P=!0,Y());else{var X=r(h);X!==null&&G(W,X.startTime-R)}}var P=!1,z=-1,M=5,q=-1;function K(){return T?!0:!(t.unstable_now()-qR&&K());){var V=y.callback;if(typeof V=="function"){y.callback=null,b=y.priorityLevel;var Q=V(y.expirationTime<=R);if(R=t.unstable_now(),typeof Q=="function"){y.callback=Q,L(R),X=!0;break t}y===r(g)&&l(g),L(R)}else l(g);y=r(g)}if(y!==null)X=!0;else{var N=r(h);N!==null&&G(W,N.startTime-R),X=!1}}break e}finally{y=null,b=B,S=!1}X=void 0}}finally{X?Y():P=!1}}}var Y;if(typeof j=="function")Y=function(){j(D)};else if(typeof MessageChannel<"u"){var H=new MessageChannel,A=H.port2;H.port1.onmessage=D,Y=function(){A.postMessage(null)}}else Y=function(){w(D,0)};function G(R,X){z=w(function(){R(t.unstable_now())},X)}t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(R){R.callback=null},t.unstable_forceFrameRate=function(R){0>R||125V?(R.sortIndex=B,o(h,R),r(g)===null&&R===r(h)&&(_?(C(z),z=-1):_=!0,G(W,B-V))):(R.sortIndex=Q,o(g,R),k||S||(k=!0,P||(P=!0,Y()))),R},t.unstable_shouldYield=K,t.unstable_wrapCallback=function(R){var X=b;return function(){var B=b;b=X;try{return R.apply(this,arguments)}finally{b=B}}}})(Rf)),Rf}var Px;function Qw(){return Px||(Px=1,Ef.exports=Kw()),Ef.exports}var Af={exports:{}},mn={};/** + */var Gx;function e2(){return Gx||(Gx=1,(function(t){function o(R,J){var N=R.length;R.push(J);e:for(;0>>1,Q=R[X];if(0>>1;Xc($,N))Yc(O,$)?(R[X]=O,R[Y]=N,X=Y):(R[X]=$,R[B]=N,X=B);else if(Yc(O,N))R[X]=O,R[Y]=N,X=Y;else break e}}return J}function c(R,J){var N=R.sortIndex-J.sortIndex;return N!==0?N:R.id-J.id}if(t.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var d=performance;t.unstable_now=function(){return d.now()}}else{var u=Date,p=u.now();t.unstable_now=function(){return u.now()-p}}var g=[],h=[],b=1,y=null,v=3,w=!1,j=!1,_=!1,C=!1,S=typeof setTimeout=="function"?setTimeout:null,E=typeof clearTimeout=="function"?clearTimeout:null,k=typeof setImmediate<"u"?setImmediate:null;function D(R){for(var J=r(h);J!==null;){if(J.callback===null)l(h);else if(J.startTime<=R)l(h),J.sortIndex=J.expirationTime,o(g,J);else break;J=r(h)}}function H(R){if(_=!1,D(R),!j)if(r(g)!==null)j=!0,G||(G=!0,V());else{var J=r(h);J!==null&&q(H,J.startTime-R)}}var G=!1,T=-1,P=5,F=-1;function W(){return C?!0:!(t.unstable_now()-FR&&W());){var X=y.callback;if(typeof X=="function"){y.callback=null,v=y.priorityLevel;var Q=X(y.expirationTime<=R);if(R=t.unstable_now(),typeof Q=="function"){y.callback=Q,D(R),J=!0;break t}y===r(g)&&l(g),D(R)}else l(g);y=r(g)}if(y!==null)J=!0;else{var L=r(h);L!==null&&q(H,L.startTime-R),J=!1}}break e}finally{y=null,v=N,w=!1}J=void 0}}finally{J?V():G=!1}}}var V;if(typeof k=="function")V=function(){k(M)};else if(typeof MessageChannel<"u"){var I=new MessageChannel,A=I.port2;I.port1.onmessage=M,V=function(){A.postMessage(null)}}else V=function(){S(M,0)};function q(R,J){T=S(function(){R(t.unstable_now())},J)}t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(R){R.callback=null},t.unstable_forceFrameRate=function(R){0>R||125X?(R.sortIndex=N,o(h,R),r(g)===null&&R===r(h)&&(_?(E(T),T=-1):_=!0,q(H,N-X))):(R.sortIndex=Q,o(g,R),j||w||(j=!0,G||(G=!0,V()))),R},t.unstable_shouldYield=W,t.unstable_wrapCallback=function(R){var J=v;return function(){var N=v;v=J;try{return R.apply(this,arguments)}finally{v=N}}}})(Af)),Af}var Px;function t2(){return Px||(Px=1,Rf.exports=e2()),Rf.exports}var Mf={exports:{}},mn={};/** * @license React * react-dom.production.js * @@ -30,7 +30,7 @@ * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. - */var Fx;function Zw(){if(Fx)return mn;Fx=1;var t=Fa();function o(g){var h="https://react.dev/errors/"+g;if(1"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(t)}catch(o){console.error(o)}}return t(),Af.exports=Zw(),Af.exports}/** + */var qx;function n2(){if(qx)return mn;qx=1;var t=Ya();function o(g){var h="https://react.dev/errors/"+g;if(1"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(t)}catch(o){console.error(o)}}return t(),Mf.exports=n2(),Mf.exports}/** * @license React * react-dom-client.production.js * @@ -38,41 +38,41 @@ * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. - */var Vx;function e2(){if(Vx)return pa;Vx=1;var t=Qw(),o=Fa(),r=db();function l(e){var i="https://react.dev/errors/"+e;if(1Q||(e.current=V[Q],V[Q]=null,Q--)}function $(e,i){Q++,V[Q]=e.current,e.current=i}var F=N(null),I=N(null),J=N(null),ne=N(null);function se(e,i){switch($(J,i),$(I,e),$(F,null),i.nodeType){case 9:case 11:e=(e=i.documentElement)&&(e=e.namespaceURI)?cx(e):0;break;default:if(e=i.tagName,i=i.namespaceURI)i=cx(i),e=dx(i,e);else switch(e){case"svg":e=1;break;case"math":e=2;break;default:e=0}}O(F),$(F,e)}function pe(){O(F),O(I),O(J)}function _e(e){e.memoizedState!==null&&$(ne,e);var i=F.current,s=dx(i,e.type);i!==s&&($(I,e),$(F,s))}function we(e){I.current===e&&(O(F),O(I)),ne.current===e&&(O(ne),la._currentValue=B)}var ke,te;function de(e){if(ke===void 0)try{throw Error()}catch(s){var i=s.stack.trim().match(/\n( *(at )?)/);ke=i&&i[1]||"",te=-1Q||(e.current=X[Q],X[Q]=null,Q--)}function $(e,i){Q++,X[Q]=e.current,e.current=i}var Y=L(null),O=L(null),K=L(null),ne=L(null);function se(e,i){switch($(K,i),$(O,e),$(Y,null),i.nodeType){case 9:case 11:e=(e=i.documentElement)&&(e=e.namespaceURI)?lx(e):0;break;default:if(e=i.tagName,i=i.namespaceURI)i=lx(i),e=cx(i,e);else switch(e){case"svg":e=1;break;case"math":e=2;break;default:e=0}}B(Y),$(Y,e)}function pe(){B(Y),B(O),B(K)}function _e(e){e.memoizedState!==null&&$(ne,e);var i=Y.current,s=cx(i,e.type);i!==s&&($(O,e),$(Y,s))}function Se(e){O.current===e&&(B(Y),B(O)),ne.current===e&&(B(ne),la._currentValue=N)}var ke,te;function de(e){if(ke===void 0)try{throw Error()}catch(s){var i=s.stack.trim().match(/\n( *(at )?)/);ke=i&&i[1]||"",te=-1)":-1f||Z[a]!==ce[f]){var be=` `+Z[a].replace(" at new "," at ");return e.displayName&&be.includes("")&&(be=be.replace("",e.displayName)),be}while(1<=a&&0<=f);break}}}finally{Ce=!1,Error.prepareStackTrace=s}return(s=e?e.displayName||e.name:"")?de(s):""}function ve(e,i){switch(e.tag){case 26:case 27:case 5:return de(e.type);case 16:return de("Lazy");case 13:return e.child!==i&&i!==null?de("Suspense Fallback"):de("Suspense");case 19:return de("SuspenseList");case 0:case 15:return ze(e.type,!1);case 11:return ze(e.type.render,!1);case 1:return ze(e.type,!0);case 31:return de("Activity");default:return""}}function De(e){try{var i="",s=null;do i+=ve(e,s),s=e,e=e.return;while(e);return i}catch(a){return` Error generating stack: `+a.message+` -`+a.stack}}var Me=Object.prototype.hasOwnProperty,Ve=t.unstable_scheduleCallback,Le=t.unstable_cancelCallback,Ae=t.unstable_shouldYield,Ue=t.unstable_requestPaint,Oe=t.unstable_now,dt=t.unstable_getCurrentPriorityLevel,it=t.unstable_ImmediatePriority,lt=t.unstable_UserBlockingPriority,Je=t.unstable_NormalPriority,yt=t.unstable_LowPriority,Jt=t.unstable_IdlePriority,rn=t.log,zt=t.unstable_setDisableYieldValue,ae=null,He=null;function Ze(e){if(typeof rn=="function"&&zt(e),He&&typeof He.setStrictMode=="function")try{He.setStrictMode(ae,e)}catch{}}var ut=Math.clz32?Math.clz32:yn,Ut=Math.log,Nt=Math.LN2;function yn(e){return e>>>=0,e===0?32:31-(Ut(e)/Nt|0)|0}var fe=256,ft=262144,Et=4194304;function qt(e){var i=e&42;if(i!==0)return i;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&261888;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 Gt(e,i,s){var a=e.pendingLanes;if(a===0)return 0;var f=0,m=e.suspendedLanes,E=e.pingedLanes;e=e.warmLanes;var U=a&134217727;return U!==0?(a=U&~m,a!==0?f=qt(a):(E&=U,E!==0?f=qt(E):s||(s=U&~e,s!==0&&(f=qt(s))))):(U=a&~m,U!==0?f=qt(U):E!==0?f=qt(E):s||(s=a&~e,s!==0&&(f=qt(s)))),f===0?0:i!==0&&i!==f&&(i&m)===0&&(m=f&-f,s=i&-i,m>=s||m===32&&(s&4194048)!==0)?i:f}function Ct(e,i){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&i)===0}function oe(e,i){switch(e){case 1:case 2:case 4:case 8:case 64:return i+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return i+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function Ne(){var e=Et;return Et<<=1,(Et&62914560)===0&&(Et=4194304),e}function We(e){for(var i=[],s=0;31>s;s++)i.push(e);return i}function mt(e,i){e.pendingLanes|=i,i!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function St(e,i,s,a,f,m){var E=e.pendingLanes;e.pendingLanes=s,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=s,e.entangledLanes&=s,e.errorRecoveryDisabledLanes&=s,e.shellSuspendCounter=0;var U=e.entanglements,Z=e.expirationTimes,ce=e.hiddenUpdates;for(s=E&~s;0"u")return null;try{return e.activeElement||e.body}catch{return e.body}}var Yt=/[\n"\\]/g;function At(e){return e.replace(Yt,function(i){return"\\"+i.charCodeAt(0).toString(16)+" "})}function Wt(e,i,s,a,f,m,E,U){e.name="",E!=null&&typeof E!="function"&&typeof E!="symbol"&&typeof E!="boolean"?e.type=E:e.removeAttribute("type"),i!=null?E==="number"?(i===0&&e.value===""||e.value!=i)&&(e.value=""+Te(i)):e.value!==""+Te(i)&&(e.value=""+Te(i)):E!=="submit"&&E!=="reset"||e.removeAttribute("value"),i!=null?cn(e,E,Te(i)):s!=null?cn(e,E,Te(s)):a!=null&&e.removeAttribute("value"),f==null&&m!=null&&(e.defaultChecked=!!m),f!=null&&(e.checked=f&&typeof f!="function"&&typeof f!="symbol"),U!=null&&typeof U!="function"&&typeof U!="symbol"&&typeof U!="boolean"?e.name=""+Te(U):e.removeAttribute("name")}function Qt(e,i,s,a,f,m,E,U){if(m!=null&&typeof m!="function"&&typeof m!="symbol"&&typeof m!="boolean"&&(e.type=m),i!=null||s!=null){if(!(m!=="submit"&&m!=="reset"||i!=null)){Pe(e);return}s=s!=null?""+Te(s):"",i=i!=null?""+Te(i):s,U||i===e.value||(e.value=i),e.defaultValue=i}a=a??f,a=typeof a!="function"&&typeof a!="symbol"&&!!a,e.checked=U?e.checked:!!a,e.defaultChecked=!!a,E!=null&&typeof E!="function"&&typeof E!="symbol"&&typeof E!="boolean"&&(e.name=E),Pe(e)}function cn(e,i,s){i==="number"&&wt(e.ownerDocument)===e||e.defaultValue===""+s||(e.defaultValue=""+s)}function Mt(e,i,s,a){if(e=e.options,i){i={};for(var f=0;f"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),_d=!1;if(zi)try{var Cr={};Object.defineProperty(Cr,"passive",{get:function(){_d=!0}}),window.addEventListener("test",Cr,Cr),window.removeEventListener("test",Cr,Cr)}catch{_d=!1}var eo=null,Cd=null,ol=null;function dh(){if(ol)return ol;var e,i=Cd,s=i.length,a,f="value"in eo?eo.value:eo.textContent,m=f.length;for(e=0;e=Er),mh=" ",xh=!1;function yh(e,i){switch(e){case"keyup":return gS.indexOf(i.keyCode)!==-1;case"keydown":return i.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function bh(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var ms=!1;function xS(e,i){switch(e){case"compositionend":return bh(i);case"keypress":return i.which!==32?null:(xh=!0,mh);case"textInput":return e=i.data,e===mh&&xh?null:e;default:return null}}function yS(e,i){if(ms)return e==="compositionend"||!Ad&&yh(e,i)?(e=dh(),ol=Cd=eo=null,ms=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(i.ctrlKey||i.altKey||i.metaKey)||i.ctrlKey&&i.altKey){if(i.char&&1=i)return{node:s,offset:i-e};e=a}e:{for(;s;){if(s.nextSibling){s=s.nextSibling;break e}s=s.parentNode}s=void 0}s=Th(s)}}function Eh(e,i){return e&&i?e===i?!0:e&&e.nodeType===3?!1:i&&i.nodeType===3?Eh(e,i.parentNode):"contains"in e?e.contains(i):e.compareDocumentPosition?!!(e.compareDocumentPosition(i)&16):!1:!1}function Rh(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var i=wt(e.document);i instanceof e.HTMLIFrameElement;){try{var s=typeof i.contentWindow.location.href=="string"}catch{s=!1}if(s)e=i.contentWindow;else break;i=wt(e.document)}return i}function Ld(e){var i=e&&e.nodeName&&e.nodeName.toLowerCase();return i&&(i==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||i==="textarea"||e.contentEditable==="true")}var CS=zi&&"documentMode"in document&&11>=document.documentMode,xs=null,Nd=null,Dr=null,Bd=!1;function Ah(e,i,s){var a=s.window===s?s.document:s.nodeType===9?s:s.ownerDocument;Bd||xs==null||xs!==wt(a)||(a=xs,"selectionStart"in a&&Ld(a)?a={start:a.selectionStart,end:a.selectionEnd}:(a=(a.ownerDocument&&a.ownerDocument.defaultView||window).getSelection(),a={anchorNode:a.anchorNode,anchorOffset:a.anchorOffset,focusNode:a.focusNode,focusOffset:a.focusOffset}),Dr&&Mr(Dr,a)||(Dr=a,a=Kl(Nd,"onSelect"),0>=E,f-=E,gi=1<<32-ut(i)+f|s<Qe?(rt=$e,$e=null):rt=$e.sibling;var gt=ue(re,$e,le[Qe],Se);if(gt===null){$e===null&&($e=rt);break}e&&$e&>.alternate===null&&i(re,$e),ie=m(gt,ie,Qe),ht===null?Ge=gt:ht.sibling=gt,ht=gt,$e=rt}if(Qe===le.length)return s(re,$e),ct&&Ri(re,Qe),Ge;if($e===null){for(;QeQe?(rt=$e,$e=null):rt=$e.sibling;var jo=ue(re,$e,gt.value,Se);if(jo===null){$e===null&&($e=rt);break}e&&$e&&jo.alternate===null&&i(re,$e),ie=m(jo,ie,Qe),ht===null?Ge=jo:ht.sibling=jo,ht=jo,$e=rt}if(gt.done)return s(re,$e),ct&&Ri(re,Qe),Ge;if($e===null){for(;!gt.done;Qe++,gt=le.next())gt=je(re,gt.value,Se),gt!==null&&(ie=m(gt,ie,Qe),ht===null?Ge=gt:ht.sibling=gt,ht=gt);return ct&&Ri(re,Qe),Ge}for($e=a($e);!gt.done;Qe++,gt=le.next())gt=ge($e,re,Qe,gt.value,Se),gt!==null&&(e&>.alternate!==null&&$e.delete(gt.key===null?Qe:gt.key),ie=m(gt,ie,Qe),ht===null?Ge=gt:ht.sibling=gt,ht=gt);return e&&$e.forEach(function(Fw){return i(re,Fw)}),ct&&Ri(re,Qe),Ge}function _t(re,ie,le,Se){if(typeof le=="object"&&le!==null&&le.type===_&&le.key===null&&(le=le.props.children),typeof le=="object"&&le!==null){switch(le.$$typeof){case S:e:{for(var Ge=le.key;ie!==null;){if(ie.key===Ge){if(Ge=le.type,Ge===_){if(ie.tag===7){s(re,ie.sibling),Se=f(ie,le.props.children),Se.return=re,re=Se;break e}}else if(ie.elementType===Ge||typeof Ge=="object"&&Ge!==null&&Ge.$$typeof===M&&Wo(Ge)===ie.type){s(re,ie.sibling),Se=f(ie,le.props),$r(Se,le),Se.return=re,re=Se;break e}s(re,ie);break}else i(re,ie);ie=ie.sibling}le.type===_?(Se=Bo(le.props.children,re.mode,Se,le.key),Se.return=re,re=Se):(Se=hl(le.type,le.key,le.props,null,re.mode,Se),$r(Se,le),Se.return=re,re=Se)}return E(re);case k:e:{for(Ge=le.key;ie!==null;){if(ie.key===Ge)if(ie.tag===4&&ie.stateNode.containerInfo===le.containerInfo&&ie.stateNode.implementation===le.implementation){s(re,ie.sibling),Se=f(ie,le.children||[]),Se.return=re,re=Se;break e}else{s(re,ie);break}else i(re,ie);ie=ie.sibling}Se=qd(le,re.mode,Se),Se.return=re,re=Se}return E(re);case M:return le=Wo(le),_t(re,ie,le,Se)}if(G(le))return Be(re,ie,le,Se);if(Y(le)){if(Ge=Y(le),typeof Ge!="function")throw Error(l(150));return le=Ge.call(le),Fe(re,ie,le,Se)}if(typeof le.then=="function")return _t(re,ie,Sl(le),Se);if(le.$$typeof===j)return _t(re,ie,xl(re,le),Se);wl(re,le)}return typeof le=="string"&&le!==""||typeof le=="number"||typeof le=="bigint"?(le=""+le,ie!==null&&ie.tag===6?(s(re,ie.sibling),Se=f(ie,le),Se.return=re,re=Se):(s(re,ie),Se=Ud(le,re.mode,Se),Se.return=re,re=Se),E(re)):s(re,ie)}return function(re,ie,le,Se){try{Ir=0;var Ge=_t(re,ie,le,Se);return zs=null,Ge}catch($e){if($e===Ts||$e===bl)throw $e;var ht=Dn(29,$e,null,re.mode);return ht.lanes=Se,ht.return=re,ht}finally{}}}var qo=eg(!0),tg=eg(!1),so=!1;function tu(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function nu(e,i){e=e.updateQueue,i.updateQueue===e&&(i.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,callbacks:null})}function ro(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function ao(e,i,s){var a=e.updateQueue;if(a===null)return null;if(a=a.shared,(xt&2)!==0){var f=a.pending;return f===null?i.next=i:(i.next=f.next,f.next=i),a.pending=i,i=pl(e),Ih(e,null,s),i}return fl(e,a,i,s),pl(e)}function Hr(e,i,s){if(i=i.updateQueue,i!==null&&(i=i.shared,(s&4194048)!==0)){var a=i.lanes;a&=e.pendingLanes,s|=a,i.lanes=s,Kt(e,s)}}function iu(e,i){var s=e.updateQueue,a=e.alternate;if(a!==null&&(a=a.updateQueue,s===a)){var f=null,m=null;if(s=s.firstBaseUpdate,s!==null){do{var E={lane:s.lane,tag:s.tag,payload:s.payload,callback:null,next:null};m===null?f=m=E:m=m.next=E,s=s.next}while(s!==null);m===null?f=m=i:m=m.next=i}else f=m=i;s={baseState:a.baseState,firstBaseUpdate:f,lastBaseUpdate:m,shared:a.shared,callbacks:a.callbacks},e.updateQueue=s;return}e=s.lastBaseUpdate,e===null?s.firstBaseUpdate=i:e.next=i,s.lastBaseUpdate=i}var ou=!1;function Wr(){if(ou){var e=Cs;if(e!==null)throw e}}function Ur(e,i,s,a){ou=!1;var f=e.updateQueue;so=!1;var m=f.firstBaseUpdate,E=f.lastBaseUpdate,U=f.shared.pending;if(U!==null){f.shared.pending=null;var Z=U,ce=Z.next;Z.next=null,E===null?m=ce:E.next=ce,E=Z;var be=e.alternate;be!==null&&(be=be.updateQueue,U=be.lastBaseUpdate,U!==E&&(U===null?be.firstBaseUpdate=ce:U.next=ce,be.lastBaseUpdate=Z))}if(m!==null){var je=f.baseState;E=0,be=ce=Z=null,U=m;do{var ue=U.lane&-536870913,ge=ue!==U.lane;if(ge?(st&ue)===ue:(a&ue)===ue){ue!==0&&ue===_s&&(ou=!0),be!==null&&(be=be.next={lane:0,tag:U.tag,payload:U.payload,callback:null,next:null});e:{var Be=e,Fe=U;ue=i;var _t=s;switch(Fe.tag){case 1:if(Be=Fe.payload,typeof Be=="function"){je=Be.call(_t,je,ue);break e}je=Be;break e;case 3:Be.flags=Be.flags&-65537|128;case 0:if(Be=Fe.payload,ue=typeof Be=="function"?Be.call(_t,je,ue):Be,ue==null)break e;je=y({},je,ue);break e;case 2:so=!0}}ue=U.callback,ue!==null&&(e.flags|=64,ge&&(e.flags|=8192),ge=f.callbacks,ge===null?f.callbacks=[ue]:ge.push(ue))}else ge={lane:ue,tag:U.tag,payload:U.payload,callback:U.callback,next:null},be===null?(ce=be=ge,Z=je):be=be.next=ge,E|=ue;if(U=U.next,U===null){if(U=f.shared.pending,U===null)break;ge=U,U=ge.next,ge.next=null,f.lastBaseUpdate=ge,f.shared.pending=null}}while(!0);be===null&&(Z=je),f.baseState=Z,f.firstBaseUpdate=ce,f.lastBaseUpdate=be,m===null&&(f.shared.lanes=0),po|=E,e.lanes=E,e.memoizedState=je}}function ng(e,i){if(typeof e!="function")throw Error(l(191,e));e.call(i)}function ig(e,i){var s=e.callbacks;if(s!==null)for(e.callbacks=null,e=0;em?m:8;var E=R.T,U={};R.T=U,ju(e,!1,i,s);try{var Z=f(),ce=R.S;if(ce!==null&&ce(U,Z),Z!==null&&typeof Z=="object"&&typeof Z.then=="function"){var be=NS(Z,a);Pr(e,i,be,In(e))}else Pr(e,i,a,In(e))}catch(je){Pr(e,i,{then:function(){},status:"rejected",reason:je},In())}finally{X.p=m,E!==null&&U.types!==null&&(E.types=U.types),R.T=E}}function WS(){}function Su(e,i,s,a){if(e.tag!==5)throw Error(l(476));var f=Ng(e).queue;Lg(e,f,i,B,s===null?WS:function(){return Bg(e),s(a)})}function Ng(e){var i=e.memoizedState;if(i!==null)return i;i={memoizedState:B,baseState:B,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Li,lastRenderedState:B},next:null};var s={};return i.next={memoizedState:s,baseState:s,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Li,lastRenderedState:s},next:null},e.memoizedState=i,e=e.alternate,e!==null&&(e.memoizedState=i),i}function Bg(e){var i=Ng(e);i.next===null&&(i=e.alternate.memoizedState),Pr(e,i.next.queue,{},In())}function wu(){return un(la)}function Og(){return Xt().memoizedState}function Ig(){return Xt().memoizedState}function US(e){for(var i=e.return;i!==null;){switch(i.tag){case 24:case 3:var s=In();e=ro(s);var a=ao(i,e,s);a!==null&&(En(a,i,s),Hr(a,i,s)),i={cache:Kd()},e.payload=i;return}i=i.return}}function qS(e,i,s){var a=In();s={lane:a,revertLane:0,gesture:null,action:s,hasEagerState:!1,eagerState:null,next:null},Ml(e)?Hg(i,s):(s=Hd(e,i,s,a),s!==null&&(En(s,e,a),Wg(s,i,a)))}function $g(e,i,s){var a=In();Pr(e,i,s,a)}function Pr(e,i,s,a){var f={lane:a,revertLane:0,gesture:null,action:s,hasEagerState:!1,eagerState:null,next:null};if(Ml(e))Hg(i,f);else{var m=e.alternate;if(e.lanes===0&&(m===null||m.lanes===0)&&(m=i.lastRenderedReducer,m!==null))try{var E=i.lastRenderedState,U=m(E,s);if(f.hasEagerState=!0,f.eagerState=U,Mn(U,E))return fl(e,i,f,0),Tt===null&&ul(),!1}catch{}finally{}if(s=Hd(e,i,f,a),s!==null)return En(s,e,a),Wg(s,i,a),!0}return!1}function ju(e,i,s,a){if(a={lane:2,revertLane:tf(),gesture:null,action:a,hasEagerState:!1,eagerState:null,next:null},Ml(e)){if(i)throw Error(l(479))}else i=Hd(e,s,a,2),i!==null&&En(i,e,2)}function Ml(e){var i=e.alternate;return e===Ke||i!==null&&i===Ke}function Hg(e,i){Rs=_l=!0;var s=e.pending;s===null?i.next=i:(i.next=s.next,s.next=i),e.pending=i}function Wg(e,i,s){if((s&4194048)!==0){var a=i.lanes;a&=e.pendingLanes,s|=a,i.lanes=s,Kt(e,s)}}var Fr={readContext:un,use:zl,useCallback:Pt,useContext:Pt,useEffect:Pt,useImperativeHandle:Pt,useLayoutEffect:Pt,useInsertionEffect:Pt,useMemo:Pt,useReducer:Pt,useRef:Pt,useState:Pt,useDebugValue:Pt,useDeferredValue:Pt,useTransition:Pt,useSyncExternalStore:Pt,useId:Pt,useHostTransitionStatus:Pt,useFormState:Pt,useActionState:Pt,useOptimistic:Pt,useMemoCache:Pt,useCacheRefresh:Pt};Fr.useEffectEvent=Pt;var Ug={readContext:un,use:zl,useCallback:function(e,i){return vn().memoizedState=[e,i===void 0?null:i],e},useContext:un,useEffect:_g,useImperativeHandle:function(e,i,s){s=s!=null?s.concat([e]):null,Rl(4194308,4,Eg.bind(null,i,e),s)},useLayoutEffect:function(e,i){return Rl(4194308,4,e,i)},useInsertionEffect:function(e,i){Rl(4,2,e,i)},useMemo:function(e,i){var s=vn();i=i===void 0?null:i;var a=e();if(Go){Ze(!0);try{e()}finally{Ze(!1)}}return s.memoizedState=[a,i],a},useReducer:function(e,i,s){var a=vn();if(s!==void 0){var f=s(i);if(Go){Ze(!0);try{s(i)}finally{Ze(!1)}}}else f=i;return a.memoizedState=a.baseState=f,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:f},a.queue=e,e=e.dispatch=qS.bind(null,Ke,e),[a.memoizedState,e]},useRef:function(e){var i=vn();return e={current:e},i.memoizedState=e},useState:function(e){e=mu(e);var i=e.queue,s=$g.bind(null,Ke,i);return i.dispatch=s,[e.memoizedState,s]},useDebugValue:bu,useDeferredValue:function(e,i){var s=vn();return vu(s,e,i)},useTransition:function(){var e=mu(!1);return e=Lg.bind(null,Ke,e.queue,!0,!1),vn().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,i,s){var a=Ke,f=vn();if(ct){if(s===void 0)throw Error(l(407));s=s()}else{if(s=i(),Tt===null)throw Error(l(349));(st&127)!==0||cg(a,i,s)}f.memoizedState=s;var m={value:s,getSnapshot:i};return f.queue=m,_g(ug.bind(null,a,m,e),[e]),a.flags|=2048,Ms(9,{destroy:void 0},dg.bind(null,a,m,s,i),null),s},useId:function(){var e=vn(),i=Tt.identifierPrefix;if(ct){var s=mi,a=gi;s=(a&~(1<<32-ut(a)-1)).toString(32)+s,i="_"+i+"R_"+s,s=Cl++,0<\/script>",m=m.removeChild(m.firstChild);break;case"select":m=typeof a.is=="string"?E.createElement("select",{is:a.is}):E.createElement("select"),a.multiple?m.multiple=!0:a.size&&(m.size=a.size);break;default:m=typeof a.is=="string"?E.createElement(f,{is:a.is}):E.createElement(f)}}m[Rt]=i,m[an]=a;e:for(E=i.child;E!==null;){if(E.tag===5||E.tag===6)m.appendChild(E.stateNode);else if(E.tag!==4&&E.tag!==27&&E.child!==null){E.child.return=E,E=E.child;continue}if(E===i)break e;for(;E.sibling===null;){if(E.return===null||E.return===i)break e;E=E.return}E.sibling.return=E.return,E=E.sibling}i.stateNode=m;e:switch(pn(m,f,a),f){case"button":case"input":case"select":case"textarea":a=!!a.autoFocus;break e;case"img":a=!0;break e;default:a=!1}a&&Bi(i)}}return Lt(i),Ou(i,i.type,e===null?null:e.memoizedProps,i.pendingProps,s),null;case 6:if(e&&i.stateNode!=null)e.memoizedProps!==a&&Bi(i);else{if(typeof a!="string"&&i.stateNode===null)throw Error(l(166));if(e=J.current,js(i)){if(e=i.stateNode,s=i.memoizedProps,a=null,f=dn,f!==null)switch(f.tag){case 27:case 5:a=f.memoizedProps}e[Rt]=i,e=!!(e.nodeValue===s||a!==null&&a.suppressHydrationWarning===!0||ax(e.nodeValue,s)),e||io(i,!0)}else e=Ql(e).createTextNode(a),e[Rt]=i,i.stateNode=e}return Lt(i),null;case 31:if(s=i.memoizedState,e===null||e.memoizedState!==null){if(a=js(i),s!==null){if(e===null){if(!a)throw Error(l(318));if(e=i.memoizedState,e=e!==null?e.dehydrated:null,!e)throw Error(l(557));e[Rt]=i}else Oo(),(i.flags&128)===0&&(i.memoizedState=null),i.flags|=4;Lt(i),e=!1}else s=Yd(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=s),e=!0;if(!e)return i.flags&256?(Nn(i),i):(Nn(i),null);if((i.flags&128)!==0)throw Error(l(558))}return Lt(i),null;case 13:if(a=i.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(f=js(i),a!==null&&a.dehydrated!==null){if(e===null){if(!f)throw Error(l(318));if(f=i.memoizedState,f=f!==null?f.dehydrated:null,!f)throw Error(l(317));f[Rt]=i}else Oo(),(i.flags&128)===0&&(i.memoizedState=null),i.flags|=4;Lt(i),f=!1}else f=Yd(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=f),f=!0;if(!f)return i.flags&256?(Nn(i),i):(Nn(i),null)}return Nn(i),(i.flags&128)!==0?(i.lanes=s,i):(s=a!==null,e=e!==null&&e.memoizedState!==null,s&&(a=i.child,f=null,a.alternate!==null&&a.alternate.memoizedState!==null&&a.alternate.memoizedState.cachePool!==null&&(f=a.alternate.memoizedState.cachePool.pool),m=null,a.memoizedState!==null&&a.memoizedState.cachePool!==null&&(m=a.memoizedState.cachePool.pool),m!==f&&(a.flags|=2048)),s!==e&&s&&(i.child.flags|=8192),Ol(i,i.updateQueue),Lt(i),null);case 4:return pe(),e===null&&rf(i.stateNode.containerInfo),Lt(i),null;case 10:return Mi(i.type),Lt(i),null;case 19:if(O(Vt),a=i.memoizedState,a===null)return Lt(i),null;if(f=(i.flags&128)!==0,m=a.rendering,m===null)if(f)Vr(a,!1);else{if(Ft!==0||e!==null&&(e.flags&128)!==0)for(e=i.child;e!==null;){if(m=kl(e),m!==null){for(i.flags|=128,Vr(a,!1),e=m.updateQueue,i.updateQueue=e,Ol(i,e),i.subtreeFlags=0,e=s,s=i.child;s!==null;)$h(s,e),s=s.sibling;return $(Vt,Vt.current&1|2),ct&&Ri(i,a.treeForkCount),i.child}e=e.sibling}a.tail!==null&&Oe()>Ul&&(i.flags|=128,f=!0,Vr(a,!1),i.lanes=4194304)}else{if(!f)if(e=kl(m),e!==null){if(i.flags|=128,f=!0,e=e.updateQueue,i.updateQueue=e,Ol(i,e),Vr(a,!0),a.tail===null&&a.tailMode==="hidden"&&!m.alternate&&!ct)return Lt(i),null}else 2*Oe()-a.renderingStartTime>Ul&&s!==536870912&&(i.flags|=128,f=!0,Vr(a,!1),i.lanes=4194304);a.isBackwards?(m.sibling=i.child,i.child=m):(e=a.last,e!==null?e.sibling=m:i.child=m,a.last=m)}return a.tail!==null?(e=a.tail,a.rendering=e,a.tail=e.sibling,a.renderingStartTime=Oe(),e.sibling=null,s=Vt.current,$(Vt,f?s&1|2:s&1),ct&&Ri(i,a.treeForkCount),e):(Lt(i),null);case 22:case 23:return Nn(i),ru(),a=i.memoizedState!==null,e!==null?e.memoizedState!==null!==a&&(i.flags|=8192):a&&(i.flags|=8192),a?(s&536870912)!==0&&(i.flags&128)===0&&(Lt(i),i.subtreeFlags&6&&(i.flags|=8192)):Lt(i),s=i.updateQueue,s!==null&&Ol(i,s.retryQueue),s=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(s=e.memoizedState.cachePool.pool),a=null,i.memoizedState!==null&&i.memoizedState.cachePool!==null&&(a=i.memoizedState.cachePool.pool),a!==s&&(i.flags|=2048),e!==null&&O(Ho),null;case 24:return s=null,e!==null&&(s=e.memoizedState.cache),i.memoizedState.cache!==s&&(i.flags|=2048),Mi(Zt),Lt(i),null;case 25:return null;case 30:return null}throw Error(l(156,i.tag))}function VS(e,i){switch(Pd(i),i.tag){case 1:return e=i.flags,e&65536?(i.flags=e&-65537|128,i):null;case 3:return Mi(Zt),pe(),e=i.flags,(e&65536)!==0&&(e&128)===0?(i.flags=e&-65537|128,i):null;case 26:case 27:case 5:return we(i),null;case 31:if(i.memoizedState!==null){if(Nn(i),i.alternate===null)throw Error(l(340));Oo()}return e=i.flags,e&65536?(i.flags=e&-65537|128,i):null;case 13:if(Nn(i),e=i.memoizedState,e!==null&&e.dehydrated!==null){if(i.alternate===null)throw Error(l(340));Oo()}return e=i.flags,e&65536?(i.flags=e&-65537|128,i):null;case 19:return O(Vt),null;case 4:return pe(),null;case 10:return Mi(i.type),null;case 22:case 23:return Nn(i),ru(),e!==null&&O(Ho),e=i.flags,e&65536?(i.flags=e&-65537|128,i):null;case 24:return Mi(Zt),null;case 25:return null;default:return null}}function fm(e,i){switch(Pd(i),i.tag){case 3:Mi(Zt),pe();break;case 26:case 27:case 5:we(i);break;case 4:pe();break;case 31:i.memoizedState!==null&&Nn(i);break;case 13:Nn(i);break;case 19:O(Vt);break;case 10:Mi(i.type);break;case 22:case 23:Nn(i),ru(),e!==null&&O(Ho);break;case 24:Mi(Zt)}}function Xr(e,i){try{var s=i.updateQueue,a=s!==null?s.lastEffect:null;if(a!==null){var f=a.next;s=f;do{if((s.tag&e)===e){a=void 0;var m=s.create,E=s.inst;a=m(),E.destroy=a}s=s.next}while(s!==f)}}catch(U){vt(i,i.return,U)}}function uo(e,i,s){try{var a=i.updateQueue,f=a!==null?a.lastEffect:null;if(f!==null){var m=f.next;a=m;do{if((a.tag&e)===e){var E=a.inst,U=E.destroy;if(U!==void 0){E.destroy=void 0,f=i;var Z=s,ce=U;try{ce()}catch(be){vt(f,Z,be)}}}a=a.next}while(a!==m)}}catch(be){vt(i,i.return,be)}}function pm(e){var i=e.updateQueue;if(i!==null){var s=e.stateNode;try{ig(i,s)}catch(a){vt(e,e.return,a)}}}function hm(e,i,s){s.props=Po(e.type,e.memoizedProps),s.state=e.memoizedState;try{s.componentWillUnmount()}catch(a){vt(e,i,a)}}function Jr(e,i){try{var s=e.ref;if(s!==null){switch(e.tag){case 26:case 27:case 5:var a=e.stateNode;break;case 30:a=e.stateNode;break;default:a=e.stateNode}typeof s=="function"?e.refCleanup=s(a):s.current=a}}catch(f){vt(e,i,f)}}function xi(e,i){var s=e.ref,a=e.refCleanup;if(s!==null)if(typeof a=="function")try{a()}catch(f){vt(e,i,f)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof s=="function")try{s(null)}catch(f){vt(e,i,f)}else s.current=null}function gm(e){var i=e.type,s=e.memoizedProps,a=e.stateNode;try{e:switch(i){case"button":case"input":case"select":case"textarea":s.autoFocus&&a.focus();break e;case"img":s.src?a.src=s.src:s.srcSet&&(a.srcset=s.srcSet)}}catch(f){vt(e,e.return,f)}}function Iu(e,i,s){try{var a=e.stateNode;mw(a,e.type,s,i),a[an]=i}catch(f){vt(e,e.return,f)}}function mm(e){return e.tag===5||e.tag===3||e.tag===26||e.tag===27&&yo(e.type)||e.tag===4}function $u(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||mm(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.tag===27&&yo(e.type)||e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function Hu(e,i,s){var a=e.tag;if(a===5||a===6)e=e.stateNode,i?(s.nodeType===9?s.body:s.nodeName==="HTML"?s.ownerDocument.body:s).insertBefore(e,i):(i=s.nodeType===9?s.body:s.nodeName==="HTML"?s.ownerDocument.body:s,i.appendChild(e),s=s._reactRootContainer,s!=null||i.onclick!==null||(i.onclick=Ti));else if(a!==4&&(a===27&&yo(e.type)&&(s=e.stateNode,i=null),e=e.child,e!==null))for(Hu(e,i,s),e=e.sibling;e!==null;)Hu(e,i,s),e=e.sibling}function Il(e,i,s){var a=e.tag;if(a===5||a===6)e=e.stateNode,i?s.insertBefore(e,i):s.appendChild(e);else if(a!==4&&(a===27&&yo(e.type)&&(s=e.stateNode),e=e.child,e!==null))for(Il(e,i,s),e=e.sibling;e!==null;)Il(e,i,s),e=e.sibling}function xm(e){var i=e.stateNode,s=e.memoizedProps;try{for(var a=e.type,f=i.attributes;f.length;)i.removeAttributeNode(f[0]);pn(i,a,s),i[Rt]=e,i[an]=s}catch(m){vt(e,e.return,m)}}var Oi=!1,nn=!1,Wu=!1,ym=typeof WeakSet=="function"?WeakSet:Set,ln=null;function XS(e,i){if(e=e.containerInfo,cf=sc,e=Rh(e),Ld(e)){if("selectionStart"in e)var s={start:e.selectionStart,end:e.selectionEnd};else e:{s=(s=e.ownerDocument)&&s.defaultView||window;var a=s.getSelection&&s.getSelection();if(a&&a.rangeCount!==0){s=a.anchorNode;var f=a.anchorOffset,m=a.focusNode;a=a.focusOffset;try{s.nodeType,m.nodeType}catch{s=null;break e}var E=0,U=-1,Z=-1,ce=0,be=0,je=e,ue=null;t:for(;;){for(var ge;je!==s||f!==0&&je.nodeType!==3||(U=E+f),je!==m||a!==0&&je.nodeType!==3||(Z=E+a),je.nodeType===3&&(E+=je.nodeValue.length),(ge=je.firstChild)!==null;)ue=je,je=ge;for(;;){if(je===e)break t;if(ue===s&&++ce===f&&(U=E),ue===m&&++be===a&&(Z=E),(ge=je.nextSibling)!==null)break;je=ue,ue=je.parentNode}je=ge}s=U===-1||Z===-1?null:{start:U,end:Z}}else s=null}s=s||{start:0,end:0}}else s=null;for(df={focusedElem:e,selectionRange:s},sc=!1,ln=i;ln!==null;)if(i=ln,e=i.child,(i.subtreeFlags&1028)!==0&&e!==null)e.return=i,ln=e;else for(;ln!==null;){switch(i=ln,m=i.alternate,e=i.flags,i.tag){case 0:if((e&4)!==0&&(e=i.updateQueue,e=e!==null?e.events:null,e!==null))for(s=0;s title"))),pn(m,a,s),m[Rt]=e,Bt(m),a=m;break e;case"link":var E=kx("link","href",f).get(a+(s.href||""));if(E){for(var U=0;U_t&&(E=_t,_t=Fe,Fe=E);var re=zh(U,Fe),ie=zh(U,_t);if(re&&ie&&(ge.rangeCount!==1||ge.anchorNode!==re.node||ge.anchorOffset!==re.offset||ge.focusNode!==ie.node||ge.focusOffset!==ie.offset)){var le=je.createRange();le.setStart(re.node,re.offset),ge.removeAllRanges(),Fe>_t?(ge.addRange(le),ge.extend(ie.node,ie.offset)):(le.setEnd(ie.node,ie.offset),ge.addRange(le))}}}}for(je=[],ge=U;ge=ge.parentNode;)ge.nodeType===1&&je.push({element:ge,left:ge.scrollLeft,top:ge.scrollTop});for(typeof U.focus=="function"&&U.focus(),U=0;Us?32:s,R.T=null,s=Vu,Vu=null;var m=go,E=Ui;if(sn=0,Os=go=null,Ui=0,(xt&6)!==0)throw Error(l(331));var U=xt;if(xt|=4,Em(m.current),Cm(m,m.current,E,s),xt=U,na(0,!1),He&&typeof He.onPostCommitFiberRoot=="function")try{He.onPostCommitFiberRoot(ae,m)}catch{}return!0}finally{X.p=f,R.T=a,Ym(e,i)}}function Xm(e,i,s){i=qn(s,i),i=Tu(e.stateNode,i,2),e=ao(e,i,2),e!==null&&(mt(e,2),yi(e))}function vt(e,i,s){if(e.tag===3)Xm(e,e,s);else for(;i!==null;){if(i.tag===3){Xm(i,e,s);break}else if(i.tag===1){var a=i.stateNode;if(typeof i.type.getDerivedStateFromError=="function"||typeof a.componentDidCatch=="function"&&(ho===null||!ho.has(a))){e=qn(s,e),s=Jg(2),a=ao(i,s,2),a!==null&&(Kg(s,a,i,e),mt(a,2),yi(a));break}}i=i.return}}function Qu(e,i,s){var a=e.pingCache;if(a===null){a=e.pingCache=new QS;var f=new Set;a.set(i,f)}else f=a.get(i),f===void 0&&(f=new Set,a.set(i,f));f.has(s)||(Gu=!0,f.add(s),e=iw.bind(null,e,i,s),i.then(e,e))}function iw(e,i,s){var a=e.pingCache;a!==null&&a.delete(i),e.pingedLanes|=e.suspendedLanes&s,e.warmLanes&=~s,Tt===e&&(st&s)===s&&(Ft===4||Ft===3&&(st&62914560)===st&&300>Oe()-Wl?(xt&2)===0&&Is(e,0):Pu|=s,Bs===st&&(Bs=0)),yi(e)}function Jm(e,i){i===0&&(i=Ne()),e=No(e,i),e!==null&&(mt(e,i),yi(e))}function ow(e){var i=e.memoizedState,s=0;i!==null&&(s=i.retryLane),Jm(e,s)}function sw(e,i){var s=0;switch(e.tag){case 31:case 13:var a=e.stateNode,f=e.memoizedState;f!==null&&(s=f.retryLane);break;case 19:a=e.stateNode;break;case 22:a=e.stateNode._retryCache;break;default:throw Error(l(314))}a!==null&&a.delete(i),Jm(e,s)}function rw(e,i){return Ve(e,i)}var Vl=null,Hs=null,Zu=!1,Xl=!1,ef=!1,xo=0;function yi(e){e!==Hs&&e.next===null&&(Hs===null?Vl=Hs=e:Hs=Hs.next=e),Xl=!0,Zu||(Zu=!0,lw())}function na(e,i){if(!ef&&Xl){ef=!0;do for(var s=!1,a=Vl;a!==null;){if(e!==0){var f=a.pendingLanes;if(f===0)var m=0;else{var E=a.suspendedLanes,U=a.pingedLanes;m=(1<<31-ut(42|e)+1)-1,m&=f&~(E&~U),m=m&201326741?m&201326741|1:m?m|2:0}m!==0&&(s=!0,ex(a,m))}else m=st,m=Gt(a,a===Tt?m:0,a.cancelPendingCommit!==null||a.timeoutHandle!==-1),(m&3)===0||Ct(a,m)||(s=!0,ex(a,m));a=a.next}while(s);ef=!1}}function aw(){Km()}function Km(){Xl=Zu=!1;var e=0;xo!==0&&yw()&&(e=xo);for(var i=Oe(),s=null,a=Vl;a!==null;){var f=a.next,m=Qm(a,i);m===0?(a.next=null,s===null?Vl=f:s.next=f,f===null&&(Hs=s)):(s=a,(e!==0||(m&3)!==0)&&(Xl=!0)),a=f}sn!==0&&sn!==5||na(e),xo!==0&&(xo=0)}function Qm(e,i){for(var s=e.suspendedLanes,a=e.pingedLanes,f=e.expirationTimes,m=e.pendingLanes&-62914561;0U)break;var be=Z.transferSize,je=Z.initiatorType;be&&lx(je)&&(Z=Z.responseEnd,E+=be*(Z"u"?null:document;function vx(e,i,s){var a=Ws;if(a&&typeof i=="string"&&i){var f=At(i);f='link[rel="'+e+'"][href="'+f+'"]',typeof s=="string"&&(f+='[crossorigin="'+s+'"]'),bx.has(f)||(bx.add(f),e={rel:e,crossOrigin:s,href:i},a.querySelector(f)===null&&(i=a.createElement("link"),pn(i,"link",e),Bt(i),a.head.appendChild(i)))}}function Tw(e){qi.D(e),vx("dns-prefetch",e,null)}function zw(e,i){qi.C(e,i),vx("preconnect",e,i)}function Ew(e,i,s){qi.L(e,i,s);var a=Ws;if(a&&e&&i){var f='link[rel="preload"][as="'+At(i)+'"]';i==="image"&&s&&s.imageSrcSet?(f+='[imagesrcset="'+At(s.imageSrcSet)+'"]',typeof s.imageSizes=="string"&&(f+='[imagesizes="'+At(s.imageSizes)+'"]')):f+='[href="'+At(e)+'"]';var m=f;switch(i){case"style":m=Us(e);break;case"script":m=qs(e)}Xn.has(m)||(e=y({rel:"preload",href:i==="image"&&s&&s.imageSrcSet?void 0:e,as:i},s),Xn.set(m,e),a.querySelector(f)!==null||i==="style"&&a.querySelector(ra(m))||i==="script"&&a.querySelector(aa(m))||(i=a.createElement("link"),pn(i,"link",e),Bt(i),a.head.appendChild(i)))}}function Rw(e,i){qi.m(e,i);var s=Ws;if(s&&e){var a=i&&typeof i.as=="string"?i.as:"script",f='link[rel="modulepreload"][as="'+At(a)+'"][href="'+At(e)+'"]',m=f;switch(a){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":m=qs(e)}if(!Xn.has(m)&&(e=y({rel:"modulepreload",href:e},i),Xn.set(m,e),s.querySelector(f)===null)){switch(a){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(s.querySelector(aa(m)))return}a=s.createElement("link"),pn(a,"link",e),Bt(a),s.head.appendChild(a)}}}function Aw(e,i,s){qi.S(e,i,s);var a=Ws;if(a&&e){var f=pi(a).hoistableStyles,m=Us(e);i=i||"default";var E=f.get(m);if(!E){var U={loading:0,preload:null};if(E=a.querySelector(ra(m)))U.loading=5;else{e=y({rel:"stylesheet",href:e,"data-precedence":i},s),(s=Xn.get(m))&&xf(e,s);var Z=E=a.createElement("link");Bt(Z),pn(Z,"link",e),Z._p=new Promise(function(ce,be){Z.onload=ce,Z.onerror=be}),Z.addEventListener("load",function(){U.loading|=1}),Z.addEventListener("error",function(){U.loading|=2}),U.loading|=4,ec(E,i,a)}E={type:"stylesheet",instance:E,count:1,state:U},f.set(m,E)}}}function Mw(e,i){qi.X(e,i);var s=Ws;if(s&&e){var a=pi(s).hoistableScripts,f=qs(e),m=a.get(f);m||(m=s.querySelector(aa(f)),m||(e=y({src:e,async:!0},i),(i=Xn.get(f))&&yf(e,i),m=s.createElement("script"),Bt(m),pn(m,"link",e),s.head.appendChild(m)),m={type:"script",instance:m,count:1,state:null},a.set(f,m))}}function Dw(e,i){qi.M(e,i);var s=Ws;if(s&&e){var a=pi(s).hoistableScripts,f=qs(e),m=a.get(f);m||(m=s.querySelector(aa(f)),m||(e=y({src:e,async:!0,type:"module"},i),(i=Xn.get(f))&&yf(e,i),m=s.createElement("script"),Bt(m),pn(m,"link",e),s.head.appendChild(m)),m={type:"script",instance:m,count:1,state:null},a.set(f,m))}}function Sx(e,i,s,a){var f=(f=J.current)?Zl(f):null;if(!f)throw Error(l(446));switch(e){case"meta":case"title":return null;case"style":return typeof s.precedence=="string"&&typeof s.href=="string"?(i=Us(s.href),s=pi(f).hoistableStyles,a=s.get(i),a||(a={type:"style",instance:null,count:0,state:null},s.set(i,a)),a):{type:"void",instance:null,count:0,state:null};case"link":if(s.rel==="stylesheet"&&typeof s.href=="string"&&typeof s.precedence=="string"){e=Us(s.href);var m=pi(f).hoistableStyles,E=m.get(e);if(E||(f=f.ownerDocument||f,E={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},m.set(e,E),(m=f.querySelector(ra(e)))&&!m._p&&(E.instance=m,E.state.loading=5),Xn.has(e)||(s={rel:"preload",as:"style",href:s.href,crossOrigin:s.crossOrigin,integrity:s.integrity,media:s.media,hrefLang:s.hrefLang,referrerPolicy:s.referrerPolicy},Xn.set(e,s),m||Lw(f,e,s,E.state))),i&&a===null)throw Error(l(528,""));return E}if(i&&a!==null)throw Error(l(529,""));return null;case"script":return i=s.async,s=s.src,typeof s=="string"&&i&&typeof i!="function"&&typeof i!="symbol"?(i=qs(s),s=pi(f).hoistableScripts,a=s.get(i),a||(a={type:"script",instance:null,count:0,state:null},s.set(i,a)),a):{type:"void",instance:null,count:0,state:null};default:throw Error(l(444,e))}}function Us(e){return'href="'+At(e)+'"'}function ra(e){return'link[rel="stylesheet"]['+e+"]"}function wx(e){return y({},e,{"data-precedence":e.precedence,precedence:null})}function Lw(e,i,s,a){e.querySelector('link[rel="preload"][as="style"]['+i+"]")?a.loading=1:(i=e.createElement("link"),a.preload=i,i.addEventListener("load",function(){return a.loading|=1}),i.addEventListener("error",function(){return a.loading|=2}),pn(i,"link",s),Bt(i),e.head.appendChild(i))}function qs(e){return'[src="'+At(e)+'"]'}function aa(e){return"script[async]"+e}function jx(e,i,s){if(i.count++,i.instance===null)switch(i.type){case"style":var a=e.querySelector('style[data-href~="'+At(s.href)+'"]');if(a)return i.instance=a,Bt(a),a;var f=y({},s,{"data-href":s.href,"data-precedence":s.precedence,href:null,precedence:null});return a=(e.ownerDocument||e).createElement("style"),Bt(a),pn(a,"style",f),ec(a,s.precedence,e),i.instance=a;case"stylesheet":f=Us(s.href);var m=e.querySelector(ra(f));if(m)return i.state.loading|=4,i.instance=m,Bt(m),m;a=wx(s),(f=Xn.get(f))&&xf(a,f),m=(e.ownerDocument||e).createElement("link"),Bt(m);var E=m;return E._p=new Promise(function(U,Z){E.onload=U,E.onerror=Z}),pn(m,"link",a),i.state.loading|=4,ec(m,s.precedence,e),i.instance=m;case"script":return m=qs(s.src),(f=e.querySelector(aa(m)))?(i.instance=f,Bt(f),f):(a=s,(f=Xn.get(m))&&(a=y({},s),yf(a,f)),e=e.ownerDocument||e,f=e.createElement("script"),Bt(f),pn(f,"link",a),e.head.appendChild(f),i.instance=f);case"void":return null;default:throw Error(l(443,i.type))}else i.type==="stylesheet"&&(i.state.loading&4)===0&&(a=i.instance,i.state.loading|=4,ec(a,s.precedence,e));return i.instance}function ec(e,i,s){for(var a=s.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),f=a.length?a[a.length-1]:null,m=f,E=0;E title"):null)}function Nw(e,i,s){if(s===1||i.itemProp!=null)return!1;switch(e){case"meta":case"title":return!0;case"style":if(typeof i.precedence!="string"||typeof i.href!="string"||i.href==="")break;return!0;case"link":if(typeof i.rel!="string"||typeof i.href!="string"||i.href===""||i.onLoad||i.onError)break;switch(i.rel){case"stylesheet":return e=i.disabled,typeof i.precedence=="string"&&e==null;default:return!0}case"script":if(i.async&&typeof i.async!="function"&&typeof i.async!="symbol"&&!i.onLoad&&!i.onError&&i.src&&typeof i.src=="string")return!0}return!1}function Cx(e){return!(e.type==="stylesheet"&&(e.state.loading&3)===0)}function Bw(e,i,s,a){if(s.type==="stylesheet"&&(typeof a.media!="string"||matchMedia(a.media).matches!==!1)&&(s.state.loading&4)===0){if(s.instance===null){var f=Us(a.href),m=i.querySelector(ra(f));if(m){i=m._p,i!==null&&typeof i=="object"&&typeof i.then=="function"&&(e.count++,e=nc.bind(e),i.then(e,e)),s.state.loading|=4,s.instance=m,Bt(m);return}m=i.ownerDocument||i,a=wx(a),(f=Xn.get(f))&&xf(a,f),m=m.createElement("link"),Bt(m);var E=m;E._p=new Promise(function(U,Z){E.onload=U,E.onerror=Z}),pn(m,"link",a),s.instance=m}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(s,i),(i=s.state.preload)&&(s.state.loading&3)===0&&(e.count++,s=nc.bind(e),i.addEventListener("load",s),i.addEventListener("error",s))}}var bf=0;function Ow(e,i){return e.stylesheets&&e.count===0&&oc(e,e.stylesheets),0bf?50:800)+i);return e.unsuspend=s,function(){e.unsuspend=null,clearTimeout(a),clearTimeout(f)}}:null}function nc(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)oc(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}}var ic=null;function oc(e,i){e.stylesheets=null,e.unsuspend!==null&&(e.count++,ic=new Map,i.forEach(Iw,e),ic=null,nc.call(e))}function Iw(e,i){if(!(i.state.loading&4)){var s=ic.get(e);if(s)var a=s.get(null);else{s=new Map,ic.set(e,s);for(var f=e.querySelectorAll("link[data-precedence],style[data-precedence]"),m=0;m"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(t)}catch(o){console.error(o)}}return t(),zf.exports=e2(),zf.exports}var n2=t2();const ds="/api/v1";function i2(t,o,r=""){const l=`HTTP ${t}${r?" "+r:""}`;if(!o)return l;let c;try{c=JSON.parse(o)}catch{return`${l}: ${o.slice(0,200)}`}if(c&&typeof c=="object"){const d=c,u=d.detail;if(typeof u=="string")return u;if(Array.isArray(u)){const p=u.map(g=>{if(g&&typeof g=="object"){const h=g,v=Array.isArray(h.loc)?h.loc.filter(b=>b!=="body").join("."):"",y=typeof h.msg=="string"?h.msg:JSON.stringify(g);return v?`${v}: ${y}`:y}return String(g)}).filter(Boolean);if(p.length)return p.join("; ")}if(typeof d.message=="string")return d.message;if(typeof d.error=="string")return d.error}return`${l}: ${o.slice(0,200)}`}function ub(t,o,r,l,c){const d=i2(r,c,l),u=new Error(`${t} ${o} — ${d}`);return u.status=r,u.body=c,u}async function me(t,o,r,l){const c={method:t,headers:{"Content-Type":"application/json"},signal:l};r!==void 0&&(c.body=JSON.stringify(r));const d=await fetch(`${ds}${o}`,c);if(!d.ok){const u=await d.text().catch(()=>"");throw ub(t,o,d.status,d.statusText,u)}return d.json()}const o2={sequences:"#059669",freq_map:"#2563eb",profiles:"#7c3aed",clusters:"#d97706",number:"#dc2626",text:"#0d9488",json:"#4f46e5",any:"#64748b",claims:"#b45309",papers:"#0891b2"},s2=()=>me("GET","/experiment-graphs/catalog"),fb=()=>me("GET","/experiment-graphs"),Jx=t=>me("GET",`/experiment-graphs/${t}`),Mf=t=>me("POST","/experiment-graphs",t),r2=(t,o)=>me("PUT",`/experiment-graphs/${t}`,o),a2=t=>me("DELETE",`/experiment-graphs/${t}`),Na=()=>me("GET","/health"),l2=()=>me("GET","/status"),rd=()=>me("GET","/texts"),c2=t=>me("GET",`/texts/${t}`),d2=t=>me("POST","/texts",t),u2=(t,o)=>me("PUT",`/texts/${t}`,o),f2=t=>me("DELETE",`/texts/${t}`),p2=(t,o,r=!0)=>me("POST",`/texts/${t}/detect-direction`,{words:null,update_field:r}),Ba=()=>me("GET","/jobs"),Gc=t=>me("POST","/jobs",t),fp=t=>me("DELETE",`/jobs/${t}`),pp=(t=!1)=>me("DELETE",t?"/jobs?finished_only=true":"/jobs"),pb=t=>me("POST",`/jobs/${t}/pause`),hb=t=>me("POST",`/jobs/${t}/resume`),gb=()=>me("POST","/jobs/pause-all"),mb=()=>me("POST","/jobs/resume-all"),h2=()=>me("POST","/jobs/clear-cache");function g2(){localStorage.removeItem("geb_run_cache"),localStorage.removeItem("glossa_seq_run_queue"),localStorage.removeItem("glossa_dashboard_insight_v2")}const xb=t=>me("GET",`/jobs/${t}/results`),ad=()=>me("GET","/settings"),m2=(t,o)=>me("POST","/settings/verify-key",{key_name:t,key_value:null}),sr=t=>me("PUT","/settings",t),x2=()=>me("GET","/catalog"),yb=()=>me("GET","/catalog/pipelines"),y2=t=>me("GET",`/reports${t?`?project_id=${t}`:""}`),b2=t=>me("DELETE",`/reports/${t}`),Df=t=>`/api/v1/reports/${t}/download`,v2=()=>me("GET","/reports/templates"),S2=t=>me("POST","/reports/generate",{template_id:t}),w2=t=>me("POST",`/reports/${t}/open-folder`),j2=(t,o)=>me("POST",`/pipelines/${t}/duplicate`,{new_id:o}),k2=t=>me("DELETE",`/pipelines/${t}`),_2=t=>me("POST","/pipelines/import",{source_path:t}),Ip=()=>me("GET","/studies");async function*C2(t,o){if(!t.ok){const d=await t.text().catch(()=>"");throw ub("POST",new URL(t.url).pathname,t.status,t.statusText,d)}const r=t.body.getReader(),l=new TextDecoder;let c="";try{for(;!(o!=null&&o.aborted);){const{done:d,value:u}=await r.read();if(d)break;c+=l.decode(u,{stream:!0});const p=c.split(` -`);c=p.pop()??"";for(const g of p)if(g.startsWith("data: ")&&g.length>6)try{yield JSON.parse(g.slice(6))}catch{}}}finally{r.releaseLock()}}async function*hp(t,o={},r,l=!1){const c=await fetch(`${ds}/experiment-graphs/${t}/run`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({kwargs:o,notify:l}),signal:r});yield*C2(c,r)}const $p=()=>me("GET","/experiments"),Lc=t=>me("GET",`/texts/${t}/entropy`),T2=(t,o=2,r=50)=>me("GET",`/texts/${t}/ngrams?n=${o}&limit=${r}`),z2=(t,o,r=5)=>me("GET",`/texts/${t}/concordance?q=${encodeURIComponent(o)}&w=${r}`),Kx=(t,o)=>`/api/v1/texts/${t}/export?fmt=${o}`,E2=t=>me("GET",`/hypotheses${t?`?project_id=${t}`:""}`),Ta=t=>me("POST","/hypotheses",t),ja=(t,o)=>me("PUT",`/hypotheses/${t}`,o),R2=t=>me("DELETE",`/hypotheses/${t}`),A2=t=>me("GET",`/notebooks${t?`?project_id=${t}`:""}`),M2=t=>me("POST","/notebooks",t),D2=(t,o)=>me("PUT",`/notebooks/${t}`,o),L2=t=>me("DELETE",`/notebooks/${t}`),N2=()=>me("GET","/citations"),Qx=t=>me("POST","/citations",t),B2=(t,o)=>me("PUT",`/citations/${t}`,o),O2=t=>me("DELETE",`/citations/${t}`),gp=(t,o)=>me("POST","/ai/chat",t,o),bb=t=>me("POST","/ai/execute-action",t),I2=t=>me("POST","/ai/decipher",t),$2=t=>me("POST","/ai/draft-section",t),vb=t=>me("POST","/ai/hypotheses/generate",t),Sb=t=>me("POST","/ai/experiment-chain",t),H2=t=>me("POST","/ai/synthesize",t),wb=t=>me("POST","/ai/sign-reading",t),W2=()=>me("GET","/ai/research-context"),jb=t=>me("POST","/ai/report-synthesis",t),U2=()=>me("POST","/system/peaks/clear"),q2=()=>"/api/v1/system/metrics/stream",G2=()=>me("GET","/ollama/library"),P2=()=>me("GET","/ollama/recommend"),F2=t=>me("DELETE",`/ollama/models/${encodeURIComponent(t)}`),Y2="glossa_ollama_ctx",V2=()=>parseInt(localStorage.getItem(Y2)??"4096",10)||4096,X2=()=>me("GET","/report-templates"),J2=t=>me("POST","/report-templates",t),K2=t=>me("DELETE",`/report-templates/${t}`),Q2=t=>me("GET","/anchor-sets"),Z2=t=>me("POST","/anchor-sets",t),ej=t=>me("DELETE",`/anchor-sets/${t}`),tj=t=>{const r=new URLSearchParams().toString();return me("GET",`/corpus-catalogue${r?`?${r}`:""}`)},nj=t=>me("POST",`/corpus-catalogue/${t}/import`),kb=()=>me("GET","/env/status"),ij=()=>me("GET","/env/packages"),oj=()=>fetch(`${ds}/env/setup`,{method:"POST"}),sj=()=>fetch(`${ds}/env/rebuild`,{method:"POST"}),rj=()=>fetch(`${ds}/env/upgrade`,{method:"POST"}),aj=()=>"/api/v1/terminal/log/stream",lj=()=>me("POST","/terminal/log/purge"),cj=(t,o)=>fetch(`${ds}/terminal/run`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({command:t,cwd:o,use_venv:!0})});function dj(t){const o=new URLSearchParams;for(const[l,c]of Object.entries(t))c==null||c===""||o.set(l,String(c));const r=o.toString();return r?`?${r}`:""}const uj=(t={})=>me("GET",`/discovery/items${dj(t)}`),fj=(t,o,r)=>me("POST",`/discovery/items/${encodeURIComponent(t)}/status`,{status:o,notes:r}),_b=()=>me("GET","/discovery/topics"),Cb=()=>me("GET","/discovery/sources"),Lf=(t="status")=>me("GET",`/discovery/stats?group=${t}`),Pc=t=>me("POST","/discovery/fetch",t),Hp=t=>me("POST","/discovery/mine",t),pj=(t={})=>{const o=new URLSearchParams;t.days!==void 0&&o.set("days",String(t.days)),t.limit!==void 0&&o.set("limit",String(t.limit)),t.include_ai!==void 0&&o.set("include_ai",String(t.include_ai)),t.project_id&&o.set("project_id",t.project_id);const r=o.toString();return me("GET",`/dashboard/highlights${r?"?"+r:""}`)},hj=(t={})=>{const o=new URLSearchParams;t.days!==void 0&&o.set("days",String(t.days)),t.limit!==void 0&&o.set("limit",String(t.limit)),t.project_id&&o.set("project_id",t.project_id);const r=o.toString();return me("POST",`/dashboard/insight${r?"?"+r:""}`)},gj=()=>me("GET","/dashboard/decipherment"),mj=()=>me("GET","/dashboard/latest-insight"),xj=()=>me("GET","/notifications/recipients"),yj=t=>me("POST","/notifications/recipients",t),Zx=(t,o)=>me("PATCH",`/notifications/recipients/${encodeURIComponent(t)}`,o),bj=t=>me("DELETE",`/notifications/recipients/${encodeURIComponent(t)}`),Tb=()=>me("GET","/notifications/status"),vj=(t=100)=>me("GET",`/notifications/log?limit=${t}`),Sj=()=>me("POST","/notifications/test"),wj=()=>me("POST","/notifications/graph/start"),jj=t=>me("POST","/notifications/graph/poll",{session_id:t}),kj=()=>me("POST","/notifications/graph/disconnect"),zb=()=>me("GET","/discovery/scheduler/status"),Eb=()=>me("POST","/discovery/scheduler/start"),Rb=()=>me("POST","/discovery/scheduler/stop"),Ab=()=>me("GET","/projects"),_j=()=>me("GET","/projects/active"),fc=(t,o)=>me("PUT",`/projects/${t}`,o),Mb=t=>me("POST",`/projects/${t}/activate`),Cj=t=>me("DELETE",`/projects/${t}`),Tj=t=>me("GET",`/correspondences${t?`?project_id=${t}`:""}`),ey=t=>me("POST","/correspondences",t),ty=(t,o)=>me("PUT",`/correspondences/${t}`,o),zj=t=>me("DELETE",`/correspondences/${t}`),Ej=t=>me("POST","/correspondences/parse",t),Db=(t=!1,o)=>{const r=new URLSearchParams;t&&r.set("enabled_only","true");const l=r.toString();return me("GET",`/providers${l?`?${l}`:""}`)},Rj=t=>me("POST","/providers",t),ny=(t,o)=>me("PATCH",`/providers/${t}`,o),Aj=t=>me("DELETE",`/providers/${t}`),Mj=t=>me("POST",`/providers/${t}/test`),Dj=()=>me("GET","/providers/detect-ollama"),Lj=()=>me("GET","/providers/cloud-providers"),Nj=()=>me("GET","/model-assignments"),Bj=(t,o)=>me("PUT",`/model-assignments/${t}`,o),Oj=(t="mixed")=>me("POST",`/model-assignments/auto-configure?profile=${t}`),Lb=t=>me("GET","/model-intelligence/scores"),Nb=()=>me("POST","/model-intelligence/sync"),Ij=()=>me("POST","/model-intelligence/test-hf"),Nf=[{id:"outlook365_oauth",label:"Outlook 365 (Microsoft Graph OAuth) — recommended",category:"oauth",recommended:!0,notes:"Modern SSO via device-code flow. Works with personal and work/school accounts. No app password needed."},{id:"resend_api",label:"Resend (HTTPS API) — no SMTP, no mailbox, no domain",category:"api",recommended:!0,notes:"Sign up at resend.com, generate an API key, paste it here. Sends from onboarding@resend.dev (free, 100/day, 3000/month) without any DNS setup. Verify your own domain in Resend later for branded From: addresses."},{id:"microsoft365_smtp",label:"Microsoft 365 SMTP (legacy / basic auth)",category:"smtp",smtp_host:"smtp.office365.com",smtp_port:587,smtp_use_tls:!0,notes:"Only works if your tenant still allows SMTP AUTH. Most do not — use the OAuth option above instead."},{id:"outlook_com",label:"Outlook.com / Hotmail / Live",category:"smtp",smtp_host:"smtp-mail.outlook.com",smtp_port:587,smtp_use_tls:!0,notes:"Use your full email as username and an app password (account.live.com → Security → App passwords)."},{id:"gmail",label:"Gmail / Google Workspace",category:"smtp",smtp_host:"smtp.gmail.com",smtp_port:587,smtp_use_tls:!0,notes:"Requires an app password (myaccount.google.com → Security → 2-Step Verification → App passwords)."},{id:"yahoo",label:"Yahoo Mail",category:"smtp",smtp_host:"smtp.mail.yahoo.com",smtp_port:587,smtp_use_tls:!0,notes:"Requires an app password (login.yahoo.com → Account Security → Generate app password)."},{id:"icloud",label:"Apple iCloud Mail",category:"smtp",smtp_host:"smtp.mail.me.com",smtp_port:587,smtp_use_tls:!0,notes:"Requires an app-specific password (appleid.apple.com → Sign-In and Security → App-Specific Passwords)."},{id:"zoho",label:"Zoho Mail",category:"smtp",smtp_host:"smtp.zoho.com",smtp_port:587,smtp_use_tls:!0,notes:"For zoho.eu users use smtp.zoho.eu. Generate an app-specific password in your Zoho Mail account."},{id:"infomaniak",label:"Infomaniak (incl. swissmail.io)",category:"smtp",smtp_host:"mail.infomaniak.com",smtp_port:465,smtp_use_tls:!0,notes:"Common Swiss research provider. Port 465 = SSL on connect; some setups also allow 587 STARTTLS."},{id:"protonmail_bridge",label:"ProtonMail (Bridge)",category:"smtp",smtp_host:"127.0.0.1",smtp_port:1025,smtp_use_tls:!0,notes:"Run ProtonMail Bridge locally; it exposes a local SMTP relay on 127.0.0.1:1025."},{id:"sendgrid",label:"SendGrid",category:"smtp",smtp_host:"smtp.sendgrid.net",smtp_port:587,smtp_use_tls:!0,notes:"Use 'apikey' as the username and your SendGrid API key as the password."},{id:"mailgun",label:"Mailgun",category:"smtp",smtp_host:"smtp.mailgun.org",smtp_port:587,smtp_use_tls:!0,notes:"Use the SMTP credentials shown in your Mailgun domain dashboard."},{id:"university",label:"University / research-institution SMTP",category:"smtp",smtp_port:587,smtp_use_tls:!0,notes:"Most universities expose smtp..edu on port 587 STARTTLS. Check your IT pages — some require VPN or institutional MFA app passwords."},{id:"custom",label:"Custom SMTP",category:"smtp",smtp_port:587,smtp_use_tls:!0,notes:"Fill in your provider's host, port, and TLS settings manually."}],$j=(t={})=>{const o=new URLSearchParams;t.q&&o.set("q",t.q),t.status&&o.set("status",t.status),t.limit!==void 0&&o.set("limit",String(t.limit)),t.offset!==void 0&&o.set("offset",String(t.offset));const r=o.toString();return me("GET",`/indus-evidence/library${r?`?${r}`:""}`)},Hj=(t={})=>{const o=new URLSearchParams;Object.entries(t).forEach(([l,c])=>{c!==void 0&&c!==""&&o.set(l,String(c))});const r=o.toString();return me("GET",`/indus-evidence/claims${r?`?${r}`:""}`)},Wj=()=>me("GET","/indus-evidence/hypotheses"),Uj=()=>me("GET","/indus-evidence/sweep/config"),qj=t=>me("PUT","/indus-evidence/sweep/config",t),Gj=()=>me("POST","/indus-evidence/sweep/run"),Pj=()=>me("GET","/indus-evidence/sweep/candidates"),Bb=t=>me("POST","/indus-evidence/sweep/intake",t),Fj=t=>me("POST","/indus-evidence/import-url",t),Yj=()=>me("POST","/indus-evidence/intake/run"),Vj=t=>{const o=new FormData;return o.append("file",t),fetch(`${ds}/indus-evidence/upload`,{method:"POST",body:o})},Ob=x.createContext({toast:()=>{},notifications:[],unreadCount:0,markAllRead:()=>{},clearNotification:()=>{},clearAllNotifications:()=>{}});let Xj=0;function Jj({children:t}){const[o,r]=x.useState([]),[l,c]=x.useState([]),d=x.useRef(new Map),u=x.useCallback(S=>{r(_=>_.filter(T=>T.id!==S));const k=d.current.get(S);k&&(clearTimeout(k),d.current.delete(S))},[]),p=x.useCallback((S,k="info",_=3500)=>{const T=++Xj;r(C=>[...C.slice(-5),{id:T,message:S,type:k}]),c(C=>[{id:T,message:S,type:k,timestamp:Date.now(),read:!1},...C.slice(0,99)]);const w=setTimeout(()=>u(T),_);d.current.set(T,w)},[u]),g=x.useCallback(()=>c(S=>S.map(k=>({...k,read:!0}))),[]),h=x.useCallback(S=>c(k=>k.filter(_=>_.id!==S)),[]),v=x.useCallback(()=>c([]),[]),y=l.filter(S=>!S.read).length;x.useEffect(()=>()=>{d.current.forEach(clearTimeout)},[]);const b={success:"#16a34a",error:"#dc2626",info:"#2563eb",warning:"#d97706"};return n.jsxs(Ob.Provider,{value:{toast:p,notifications:l,unreadCount:y,markAllRead:g,clearNotification:h,clearAllNotifications:v},children:[t,n.jsx("div",{style:{position:"fixed",bottom:20,right:20,display:"flex",flexDirection:"column",gap:8,zIndex:9999,pointerEvents:"none"},children:o.map(S=>n.jsxs("div",{style:{background:b[S.type],color:"#fff",padding:"10px 16px",borderRadius:8,fontSize:13,fontWeight:500,boxShadow:"0 4px 16px rgba(0,0,0,0.18)",display:"flex",alignItems:"center",gap:10,pointerEvents:"auto",cursor:"pointer",animation:"slideIn 0.2s ease",maxWidth:360},onClick:()=>u(S.id),children:[n.jsx("span",{style:{flex:1},children:S.message}),n.jsx("span",{style:{opacity:.7,fontSize:16,flexShrink:0},children:"×"})]},S.id))}),n.jsx("style",{children:"@keyframes slideIn{from{transform:translateX(100%);opacity:0}to{transform:translateX(0);opacity:1}}"})]})}function et(){return x.useContext(Ob)}const Kj=60;function Vo({value:t,max:o=100,label:r,sub:l="",color:c="#2563eb",peak:d}){const u=Math.min(100,t/o*100),p=d!==void 0?Math.min(100,d/o*100):void 0,g=u>80,v=u>95?"#dc2626":g?"#d97706":c;return n.jsxs("div",{style:{padding:"12px 14px",borderRadius:8,border:"1px solid #e5e7eb",background:"#fafafa",flex:1,minWidth:140},children:[n.jsx("div",{style:{fontSize:10,fontWeight:700,color:"#9ca3af",textTransform:"uppercase",letterSpacing:.5,marginBottom:6},children:r}),n.jsxs("div",{style:{fontSize:22,fontWeight:800,color:v,fontFamily:"monospace",marginBottom:4,lineHeight:1},children:[t.toFixed(t<10?1:0),n.jsx("span",{style:{fontSize:11,fontWeight:400,color:"#9ca3af",marginLeft:2},children:o===100?"%":""})]}),l&&n.jsx("div",{style:{fontSize:11,color:"#6b7280",marginBottom:6},children:l}),n.jsxs("div",{style:{height:5,background:"#f3f4f6",borderRadius:3,overflow:"visible",position:"relative"},children:[n.jsx("div",{style:{height:"100%",width:`${u}%`,background:v,borderRadius:3,transition:"width 0.4s ease"}}),p!==void 0&&n.jsx("div",{style:{position:"absolute",top:-1,left:`${p}%`,width:2,height:7,background:"#9ca3af",borderRadius:1,transform:"translateX(-50%)"},title:`Peak: ${d==null?void 0:d.toFixed(1)}`})]}),p!==void 0&&n.jsxs("div",{style:{fontSize:10,color:"#9ca3af",marginTop:3},children:["Peak ",d==null?void 0:d.toFixed(1),o===100?"%":""]})]})}function Xo({values:t,color:o="#2563eb",height:r=32}){if(t.length<2)return n.jsx("div",{style:{height:r}});const l=Math.max(...t,1),c=200,d=c/(t.length-1),u=t.map((p,g)=>`${g*d},${r-p/l*(r-2)-1}`).join(" ");return n.jsxs("svg",{viewBox:`0 0 ${c} ${r}`,style:{width:"100%",height:r,display:"block"},children:[n.jsx("polyline",{points:u,fill:"none",stroke:o,strokeWidth:1.5,opacity:.8}),n.jsx("circle",{cx:(t.length-1)*d,cy:r-t[t.length-1]/l*(r-2)-1,r:2.5,fill:o})]})}function Ps({label:t,current:o,unit:r,peak:l,color:c="#6b7280"}){return n.jsxs("div",{style:{display:"flex",gap:8,padding:"4px 0",borderBottom:"1px solid #f3f4f6",alignItems:"center",fontSize:12},children:[n.jsx("span",{style:{color:"#9ca3af",width:120,flexShrink:0},children:t}),n.jsxs("span",{style:{fontFamily:"monospace",fontWeight:600,color:c},children:[o,n.jsx("span",{style:{color:"#9ca3af",marginLeft:2,fontSize:10},children:r})]}),l&&n.jsxs("span",{style:{marginLeft:"auto",fontSize:10,color:"#9ca3af"},children:["↑ ",l,r]})]})}function Qj({values:t}){return n.jsx("div",{style:{display:"flex",flexWrap:"wrap",gap:3,marginTop:8},children:t.map((o,r)=>{const l=o>80?"#dc2626":o>50?"#d97706":"#16a34a";return n.jsx("div",{title:`Core ${r}: ${o}%`,style:{width:20,height:20,borderRadius:3,background:l+"20",border:`1px solid ${l}40`,display:"flex",alignItems:"center",justifyContent:"center",fontSize:7,fontWeight:700,color:l},children:Math.round(o)},r)})})}function Zj(){const{toast:t}=et(),[o,r]=x.useState(null),[l,c]=x.useState(null),[d,u]=x.useState(null),[p,g]=x.useState(null),[h,v]=x.useState(null),[y,b]=x.useState(null),[S,k]=x.useState(!1),_=x.useRef({cpu:[],ram:[],gpu:[],disk_read:[],disk_write:[],net_send:[],net_recv:[]}),T=x.useCallback((M,q)=>{const K=_.current[M]??[];K.push(q),K.length>Kj&&K.shift(),_.current[M]=K},[]);x.useEffect(()=>{const M=async()=>{try{const[K,D]=await Promise.all([Na(),l2()]);r(K),c(D),b(null),x2().then(u).catch(()=>{}),Ip().then(Y=>g(Y.length)).catch(()=>{})}catch(K){b(K instanceof Error?K.message:"Connection failed")}};M();const q=setInterval(M,8e3);return()=>clearInterval(q)},[]);const w=x.useRef(null),[C,j]=x.useState(!1),L=x.useCallback(()=>{if(w.current)return;const M=new EventSource(q2());w.current=M,j(!0),M.onmessage=q=>{var K;try{const D=JSON.parse(q.data);v(D),T("cpu",D.cpu.percent),T("ram",D.ram.percent),T("gpu",((K=D.gpu[0])==null?void 0:K.utilization_pct)??0),T("disk_read",D.disk.read_mbps),T("disk_write",D.disk.write_mbps),T("net_send",D.network.send_mbps*1e3),T("net_recv",D.network.recv_mbps*1e3)}catch{}},M.onerror=()=>{M.close(),w.current=null,j(!1),setTimeout(L,3e3)}},[T]);x.useEffect(()=>(L(),()=>{var M;(M=w.current)==null||M.close(),w.current=null}),[L]);const W=async()=>{k(!0);try{await U2(),t("Peaks cleared","success")}catch{t("Failed to clear peaks","error")}finally{k(!1)}},P=(o==null?void 0:o.status)==="healthy",z=h;return n.jsxs("div",{children:[n.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:"1rem"},children:[n.jsx("h2",{style:{margin:0},children:"System Status"}),n.jsxs("div",{style:{display:"flex",gap:8,alignItems:"center"},children:[C&&n.jsxs("span",{style:{fontSize:11,color:"#16a34a",display:"flex",alignItems:"center",gap:4},children:[n.jsx("span",{style:{width:7,height:7,borderRadius:"50%",background:"#16a34a",display:"inline-block",animation:"healthPulse 1.5s infinite"}}),"Live"]}),n.jsx("button",{onClick:W,disabled:S,style:{padding:"4px 12px",border:"1px solid #e5e7eb",borderRadius:4,background:"#f9fafb",cursor:"pointer",fontSize:12,color:"#6b7280"},children:S?"…":"Clear Peaks"})]})]}),n.jsx("div",{style:{padding:"12px 16px",borderRadius:8,border:`1px solid ${P?"#bbf7d0":"#fca5a5"}`,background:P?"#f0fdf4":"#fef2f2",marginBottom:"1.5rem"},children:n.jsxs("div",{style:{display:"flex",gap:12,alignItems:"center",flexWrap:"wrap"},children:[n.jsx("span",{style:{fontSize:10,fontWeight:700,color:"#9ca3af",textTransform:"uppercase"},children:"Backend"}),n.jsx("span",{style:{fontWeight:700,color:P?"#16a34a":"#dc2626"},children:y?`Offline — ${y}`:(o==null?void 0:o.status)??"Loading…"}),o&&n.jsxs(n.Fragment,{children:[n.jsxs("span",{style:{fontSize:12,color:"#6b7280"},children:["v",o.version]}),n.jsxs("span",{style:{fontSize:12,color:"#6b7280"},children:["up ",Math.round(o.uptime_seconds),"s"]})]}),d&&n.jsx(n.Fragment,{children:Object.entries(d.counts).map(([M,q])=>n.jsxs("span",{style:{fontSize:11,padding:"1px 7px",borderRadius:6,background:"#f3f4f6",color:"#374151"},children:[M,": ",q]},M))}),p!==null&&n.jsxs("span",{style:{fontSize:11,padding:"1px 7px",borderRadius:6,background:"#f3f4f6",color:"#374151"},children:["studies: ",p]})]})}),!z&&n.jsxs("div",{style:{textAlign:"center",padding:"3rem",color:"#9ca3af"},children:[n.jsx("div",{style:{fontSize:28,marginBottom:8},children:"⚙️"}),n.jsx("div",{children:"Connecting to metrics stream…"})]}),z&&n.jsxs(n.Fragment,{children:[n.jsxs("section",{style:Jo,children:[n.jsxs("div",{style:Fs,children:[n.jsx("span",{style:Ys,children:"CPU"}),n.jsxs("span",{style:{fontSize:11,color:"#6b7280"},children:[z.cpu.count_physical,"C / ",z.cpu.count_logical,"T",z.cpu.freq_mhz&&` · ${z.cpu.freq_mhz} MHz`,z.cpu.freq_max_mhz&&` (max ${z.cpu.freq_max_mhz} MHz)`]})]}),n.jsx("div",{style:{display:"flex",gap:8,flexWrap:"wrap",marginBottom:10},children:n.jsx(Vo,{value:z.cpu.percent,label:"Utilization",color:"#2563eb",peak:z.cpu.peak_pct,sub:`${z.cpu.count_logical} logical cores`})}),n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("div",{style:{fontSize:10,fontWeight:700,color:"#9ca3af",textTransform:"uppercase",letterSpacing:.5,marginBottom:4},children:"60s History"}),n.jsx(Xo,{values:_.current.cpu,color:"#2563eb",height:36})]}),n.jsx(Qj,{values:z.cpu.per_core_pct})]}),n.jsxs("section",{style:Jo,children:[n.jsxs("div",{style:Fs,children:[n.jsx("span",{style:Ys,children:"Memory"}),n.jsxs("span",{style:{fontSize:11,color:"#6b7280"},children:[z.ram.total_gb," GB total"]})]}),n.jsxs("div",{style:{display:"flex",gap:8,flexWrap:"wrap",marginBottom:10},children:[n.jsx(Vo,{value:z.ram.percent,label:"RAM Usage",color:"#7c3aed",peak:z.ram.peak_pct,sub:`${z.ram.used_gb} / ${z.ram.total_gb} GB used`}),z.ram.swap_total_gb>0&&n.jsx(Vo,{value:z.ram.swap_used_gb/z.ram.swap_total_gb*100,label:"Swap",color:"#d97706",sub:`${z.ram.swap_used_gb.toFixed(1)} / ${z.ram.swap_total_gb} GB`})]}),n.jsx(Xo,{values:_.current.ram,color:"#7c3aed",height:36}),n.jsxs("div",{style:{marginTop:6},children:[n.jsx(Ps,{label:"Available",current:z.ram.available_gb.toString(),unit:" GB",color:"#16a34a"}),n.jsx(Ps,{label:"Used",current:z.ram.used_gb.toString(),unit:" GB"})]})]}),z.gpu.length>0&&n.jsxs("section",{style:Jo,children:[n.jsxs("div",{style:Fs,children:[n.jsx("span",{style:Ys,children:"GPU"}),n.jsx("span",{style:{fontSize:11,color:"#6b7280"},children:z.gpu[0].name})]}),z.gpu.map((M,q)=>n.jsx("div",{style:{marginBottom:10},children:n.jsxs("div",{style:{display:"flex",gap:8,flexWrap:"wrap",marginBottom:10},children:[n.jsx(Vo,{value:M.utilization_pct,label:"GPU Util",color:"#16a34a",peak:z.gpu_peaks.utilization_pct,sub:`${M.temperature_c!==null?M.temperature_c+"°C":""}`}),n.jsx(Vo,{value:M.memory_utilization_pct,label:"VRAM %",color:"#d97706",peak:z.gpu_peaks.memory_utilization_pct,sub:`${M.memory_used_mb} / ${M.memory_total_mb} MB`}),n.jsx(Vo,{value:M.memory_used_mb/M.memory_total_mb*100,label:"VRAM Used",color:"#d97706",sub:`${(M.memory_used_mb/1024).toFixed(1)} / ${(M.memory_total_mb/1024).toFixed(1)} GB`})]})},q)),n.jsx(Xo,{values:_.current.gpu,color:"#16a34a",height:36})]}),z.gpu.length===0&&n.jsx("section",{style:{...Jo,padding:"12px 16px"},children:n.jsx("div",{style:{color:"#9ca3af",fontSize:13},children:"🎮 No NVIDIA GPU detected — nvidia-smi not available or no GPU present."})}),n.jsxs("section",{style:Jo,children:[n.jsxs("div",{style:Fs,children:[n.jsx("span",{style:Ys,children:"Disk"}),n.jsxs("span",{style:{fontSize:11,color:"#6b7280"},children:[z.disk.total_gb," GB total · ",z.disk.free_gb," GB free"]})]}),n.jsx("div",{style:{display:"flex",gap:8,flexWrap:"wrap",marginBottom:10},children:n.jsx(Vo,{value:z.disk.percent,label:"Disk Used",color:"#dc2626",sub:`${z.disk.used_gb} / ${z.disk.total_gb} GB`})}),n.jsxs("div",{style:{display:"flex",gap:16,marginBottom:8},children:[n.jsxs("div",{style:{flex:1},children:[n.jsx("div",{style:{fontSize:10,color:"#9ca3af",marginBottom:2},children:"Read MB/s"}),n.jsx(Xo,{values:_.current.disk_read,color:"#2563eb",height:28})]}),n.jsxs("div",{style:{flex:1},children:[n.jsx("div",{style:{fontSize:10,color:"#9ca3af",marginBottom:2},children:"Write MB/s"}),n.jsx(Xo,{values:_.current.disk_write,color:"#dc2626",height:28})]})]}),n.jsxs("div",{children:[n.jsx(Ps,{label:"Read",current:z.disk.read_mbps.toFixed(2),unit:" MB/s",color:"#2563eb",peak:z.disk.peak_read_mbps.toFixed(2)}),n.jsx(Ps,{label:"Write",current:z.disk.write_mbps.toFixed(2),unit:" MB/s",color:"#dc2626",peak:z.disk.peak_write_mbps.toFixed(2)})]})]}),n.jsxs("section",{style:Jo,children:[n.jsxs("div",{style:Fs,children:[n.jsx("span",{style:Ys,children:"Network"}),n.jsxs("span",{style:{fontSize:11,color:"#6b7280"},children:["↑ ",z.network.total_sent_gb.toFixed(2)," GB sent · ↓ ",z.network.total_recv_gb.toFixed(2)," GB recv"]})]}),n.jsxs("div",{style:{display:"flex",gap:16,marginBottom:8},children:[n.jsxs("div",{style:{flex:1},children:[n.jsx("div",{style:{fontSize:10,color:"#9ca3af",marginBottom:2},children:"Upload KB/s"}),n.jsx(Xo,{values:_.current.net_send,color:"#7c3aed",height:28})]}),n.jsxs("div",{style:{flex:1},children:[n.jsx("div",{style:{fontSize:10,color:"#9ca3af",marginBottom:2},children:"Download KB/s"}),n.jsx(Xo,{values:_.current.net_recv,color:"#16a34a",height:28})]})]}),n.jsxs("div",{children:[n.jsx(Ps,{label:"Upload",current:(z.network.send_mbps*1e3).toFixed(1),unit:" KB/s",color:"#7c3aed",peak:(z.network.peak_send_mbps*1e3).toFixed(1)}),n.jsx(Ps,{label:"Download",current:(z.network.recv_mbps*1e3).toFixed(1),unit:" KB/s",color:"#16a34a",peak:(z.network.peak_recv_mbps*1e3).toFixed(1)})]})]}),(l==null?void 0:l.pipelines)&&l.pipelines.length>0&&n.jsxs("section",{style:Jo,children:[n.jsx("div",{style:Fs,children:n.jsx("span",{style:Ys,children:"Registered Pipelines"})}),n.jsx("ul",{style:{columnCount:2,paddingLeft:"1.2rem",margin:0,fontSize:12},children:l.pipelines.map(M=>n.jsx("li",{style:{fontFamily:"monospace",marginBottom:2},children:M},M))})]})]}),n.jsx("style",{children:"@keyframes healthPulse { 0%,100%{opacity:1} 50%{opacity:0.3} }"})]})}const Jo={marginBottom:"1rem",padding:"14px 16px",border:"1px solid #e5e7eb",borderRadius:8},Fs={display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:12},Ys={fontSize:12,fontWeight:700,color:"#374151",textTransform:"uppercase",letterSpacing:.5};function ek(){const[t,o]=x.useState(null),r=x.useCallback((c,d)=>{c.preventDefault(),c.stopPropagation();const u=Math.min(c.clientX,window.innerWidth-180),p=Math.min(c.clientY,window.innerHeight-d.length*34-8);o({x:u,y:p,items:d})},[]),l=x.useCallback(()=>o(null),[]);return x.useEffect(()=>{if(!t)return;const c=()=>o(null);return window.addEventListener("click",c,{once:!0}),window.addEventListener("keydown",d=>{d.key==="Escape"&&o(null)},{once:!0}),()=>window.removeEventListener("click",c)},[t]),{menu:t,show:r,close:l}}function tk({menu:t,onClose:o}){return t?n.jsx("div",{style:{position:"fixed",left:t.x,top:t.y,background:"#fff",border:"1px solid #e5e7eb",borderRadius:6,boxShadow:"0 8px 24px rgba(0,0,0,0.12)",zIndex:8e3,minWidth:160,padding:"4px 0",fontSize:13},onClick:r=>r.stopPropagation(),children:t.items.map((r,l)=>n.jsxs("div",{onClick:()=>{r.disabled||(r.action(),o())},style:{padding:"7px 14px",cursor:r.disabled?"not-allowed":"pointer",display:"flex",alignItems:"center",gap:8,color:r.disabled?"#9ca3af":"#111827",background:"transparent"},onMouseEnter:c=>{r.disabled||(c.currentTarget.style.background="#f3f4f6")},onMouseLeave:c=>{c.currentTarget.style.background="transparent"},children:[r.icon&&n.jsx("span",{style:{fontSize:14,width:16},children:r.icon}),r.label]},l))}):null}function nk(t,o="Copy"){return[{label:o,icon:"⎘",action:()=>navigator.clipboard.writeText(t).catch(()=>{})},{label:"Copy All (plain text)",icon:"📋",action:()=>navigator.clipboard.writeText(t).catch(()=>{})}]}const Ib=x.createContext({isOpen:!1,request:null,openChat:()=>{},closeChat:()=>{},toggleChat:()=>{},isDocked:!1,setDocked:()=>{}});function ik({children:t}){const[o,r]=x.useState(!1),[l,c]=x.useState(null),[d,u]=x.useState(!1),p=x.useCallback(v=>{v&&c(v),r(!0),window.dispatchEvent(new CustomEvent("glossa:open-ai-panel"))},[]),g=x.useCallback(()=>r(!1),[]),h=x.useCallback(()=>{r(v=>!v),o||c(null)},[o]);return n.jsx(Ib.Provider,{value:{isOpen:o,request:l,openChat:p,closeChat:g,toggleChat:h,isDocked:d,setDocked:u},children:t})}function us(){return x.useContext(Ib)}const $b=["linguistic","ancient","dna","code","random","other"],Hb=[{value:"unknown",label:"Unknown"},{value:"ltr",label:"LTR — Left to Right"},{value:"rtl",label:"RTL — Right to Left"}],iy={ltr:{label:"LTR",color:"#065f46",bg:"#d1fae5"},rtl:{label:"RTL",color:"#7c2d12",bg:"#fee2e2"},unknown:{label:"?",color:"#6b7280",bg:"#f3f4f6"}},Bf=200;function oy({data:t,xKey:o,yKey:r,color:l="#2563eb",height:c=100}){if(!t.length)return null;const d=t.map(g=>Number(g[r])||0),u=Math.max(...d,1),p=Math.max(8,Math.floor(560/t.length));return n.jsx("svg",{viewBox:`0 0 ${t.length*p} ${c}`,style:{width:"100%",height:c,overflow:"visible"},children:t.map((g,h)=>{const v=Number(g[r])||0,y=Math.max(1,v/u*(c-16));return n.jsxs("g",{children:[n.jsx("rect",{x:h*p+1,y:c-y-12,width:Math.max(2,p-2),height:y,fill:l,opacity:.8,rx:1}),t.length<=20&&n.jsx("text",{x:h*p+p/2,y:c-2,textAnchor:"middle",fontSize:Math.min(9,p-1),fill:"#6b7280",children:String(g[o]).slice(0,4)})]},h)})})}function ok({values:t,color:o="#2563eb"}){if(t.length<2)return null;const r=40,l=300,c=Math.max(...t,1),d=Math.min(...t,0),u=c-d||1,p=l/(t.length-1),g=t.map((h,v)=>`${v*p},${r-(h-d)/u*r}`).join(" ");return n.jsx("svg",{viewBox:`0 0 ${l} ${r}`,style:{width:"100%",height:r},children:n.jsx("polyline",{points:g,fill:"none",stroke:o,strokeWidth:1.5})})}function Vs({label:t,value:o,color:r="#374151"}){return n.jsxs("div",{style:{padding:"6px 12px",borderRadius:6,background:"#f9fafb",border:"1px solid #e5e7eb",textAlign:"center",minWidth:90},children:[n.jsx("div",{style:{fontSize:18,fontWeight:700,color:r,fontFamily:"monospace"},children:o}),n.jsx("div",{style:{fontSize:10,color:"#6b7280",textTransform:"uppercase",letterSpacing:.5},children:t})]})}function sk(t){let o=!1,r=!1,l=!1,c=!1;for(const u of t){const p=u.codePointAt(0)??0;if(p>=48&&p<=57){o=!0;continue}if(p>=65&&p<=90||p>=97&&p<=122){r=!0;continue}if(!(p===45||p===95||p===32)){if(p<128){c=!0;continue}l=!0}}return[o,r,l,c].filter(Boolean).length>1?"mixed":l?"ancient":r?"latin":c?"punctuation":"numeric"}const rk={numeric:{label:"Numeric codes",color:"#2563eb",bg:"#dbeafe",desc:"Tokens like 066 or 066-069 (sign codes)"},latin:{label:"Latin / ASCII",color:"#16a34a",bg:"#dcfce7",desc:"Latin letter tokens"},ancient:{label:"Non-Latin Unicode",color:"#7c3aed",bg:"#ede9fe",desc:"Ancient script glyphs (Geez, Hebrew, etc.)"},punctuation:{label:"Punctuation",color:"#d97706",bg:"#fef3c7",desc:"Punctuation-only tokens"},mixed:{label:"Mixed (⚠ noise)",color:"#dc2626",bg:"#fee2e2",desc:"Tokens mixing Latin + non-Latin + punctuation"}};function ak({tokens:t}){const o={numeric:0,latin:0,ancient:0,punctuation:0,mixed:0};for(const u of t)o[sk(u)]++;const r=t.length||1,l=o.mixed/r*100,c=l>5,d=Object.entries(o).filter(([,u])=>u>0);return n.jsxs("div",{style:{marginTop:16,padding:"10px 12px",border:"1px solid #e5e7eb",borderRadius:6,background:"#f9fafb"},children:[n.jsx("div",{style:{fontSize:10,fontWeight:700,color:"#7c3aed",textTransform:"uppercase",letterSpacing:.5,marginBottom:8},children:"Token-Type Breakdown"}),c&&n.jsxs("div",{style:{padding:"4px 8px",background:"#fef2f2",border:"1px solid #fca5a5",borderRadius:4,fontSize:11,color:"#991b1b",marginBottom:8},children:["⚠ ",l.toFixed(1),"% mixed-category tokens detected. Consider using a ",n.jsx("strong",{children:"TokenFilter"})," node to sanitize this corpus before analysis."]}),n.jsx("div",{style:{display:"flex",flexDirection:"column",gap:5},children:d.map(([u,p])=>{const g=rk[u],h=p/r*100;return n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[n.jsx("div",{style:{width:130,fontSize:11,color:g.color,fontWeight:600,flexShrink:0},title:g.desc,children:g.label}),n.jsx("div",{style:{flex:1,background:"#e5e7eb",borderRadius:3,height:10,overflow:"hidden"},children:n.jsx("div",{style:{width:`${h}%`,background:g.color,height:"100%",borderRadius:3,opacity:.85}})}),n.jsxs("div",{style:{width:60,fontSize:11,color:"#6b7280",textAlign:"right",flexShrink:0},children:[p.toLocaleString()," (",h.toFixed(1),"%)"]})]},u)})})]})}function lk({text:t,onUpdated:o,onDeleted:r,allTexts:l}){const{toast:c}=et(),[d,u]=x.useState(!1),[p,g]=x.useState("browse"),[h,v]=x.useState(0),[y,b]=x.useState(""),[S,k]=x.useState(t.name),[_,T]=x.useState(t.corpus_type),[w,C]=x.useState(t.content.join(" ")),[j,L]=x.useState("space"),[W,P]=x.useState(t.reading_direction??"unknown"),[z,M]=x.useState(!1),[q,K]=x.useState(!1),[D,Y]=x.useState(2),[H,A]=x.useState(null),[G,R]=x.useState(!1),[X,B]=x.useState(""),[V,Q]=x.useState(null),[N,O]=x.useState(!1),[$,F]=x.useState(null),[I,J]=x.useState(!1),[ne,se]=x.useState("analyze"),[pe,_e]=x.useState(""),[we,ke]=x.useState(null),[te,de]=x.useState(null),[Ce,ze]=x.useState(!1),ve=x.useRef(null),{menu:De,show:Me,close:Ve}=ek(),{openChat:Le}=us(),Ae=y?t.content.filter(fe=>fe.toLowerCase().includes(y.toLowerCase())):t.content,Ue=Math.ceil(Ae.length/Bf),Oe=Ae.slice(h*Bf,(h+1)*Bf),dt=async()=>{K(!0);try{let fe;j==="line"?fe=w.split(` -`).map(Et=>Et.trim()).filter(Boolean):j==="char"?fe=w.replace(/\s/g,"").split(""):fe=w.trim().split(/\s+/).filter(Boolean);const ft=await u2(t.id,{name:S.trim(),corpus_type:_,content:fe,reading_direction:W});o(ft),c("Corpus updated","success")}catch(fe){c(fe instanceof Error?fe.message:"Save failed","error")}finally{K(!1)}},it=async()=>{M(!0);try{const fe=await p2(t.id);P(fe.inferred_direction);const ft=await c2(t.id);o(ft);const Et=fe.confidence==="high"?"high confidence":fe.confidence==="medium"?"medium confidence":"low confidence";c(`Detected: ${fe.inferred_direction.toUpperCase()} (${Et}, ${fe.n_words} words)`,"info")}catch(fe){c(fe instanceof Error?fe.message:"Detection failed","error")}finally{M(!1)}},[lt,Je]=x.useState(!1),yt=()=>{navigator.clipboard.writeText(t.content.join(" ")).then(()=>{Je(!0),setTimeout(()=>Je(!1),1400)})},Jt=fe=>{var qt;const ft=(qt=fe.target.files)==null?void 0:qt[0];if(!ft)return;const Et=new FileReader;Et.onload=Gt=>{var oe;const Ct=(oe=Gt.target)==null?void 0:oe.result;if(ft.name.endsWith(".json"))try{const Ne=JSON.parse(Ct);C(Array.isArray(Ne)?Ne.join(" "):(Ne.content??[]).join(" ")||Ct)}catch{C(Ct)}else C(Ct);g("edit")},Et.readAsText(ft),fe.target.value=""},rn=async()=>{R(!0);try{A(await T2(t.id,D))}catch(fe){c(fe instanceof Error?fe.message:"Error","error")}finally{R(!1)}},zt=async()=>{if(X.trim()){O(!0);try{Q(await z2(t.id,X.trim()))}catch(fe){c(fe instanceof Error?fe.message:"Error","error")}finally{O(!1)}}},ae=x.useCallback(async()=>{if(!$){J(!0);try{F(await Lc(t.id))}catch(fe){c(fe instanceof Error?fe.message:"Error","error")}finally{J(!1)}}},[$,t.id,c]),He=()=>{const fe={analyze:`Please analyze the corpus "${t.name}" (${t.corpus_type}, ${t.content.length.toLocaleString()} tokens, alphabet ${t.alphabet_size}). Provide: summary, linguistic characteristics, Indus Script relevance, key insights, and suggested experiments.`,anomalies:`Please detect anomalies in the corpus "${t.name}" (${t.corpus_type}, ${t.content.length.toLocaleString()} tokens). Look for statistical anomalies, unusual patterns, structural breaks, and data quality issues.`,critique:`Please critique the corpus "${t.name}" (${t.corpus_type}, ${t.content.length.toLocaleString()} tokens, alphabet ${t.alphabet_size}) for research use. Evaluate coverage, bias, completeness, and suitability for Indus Script entropy analysis.`};Le({contextType:"corpus",contextId:t.id,contextLabel:t.name,initialPrompt:fe[ne]})},Ze=async()=>{if(pe){ze(!0);try{const[fe,ft]=await Promise.all([Lc(t.id),Lc(pe)]);de(fe),ke(ft)}catch(fe){c(fe instanceof Error?fe.message:"Error","error")}finally{ze(!1)}}};x.useEffect(()=>{d&&p==="stats"&&ae()},[d,p,ae]);const Ut={linguistic:"#2563eb",ancient:"#7c3aed",dna:"#16a34a",code:"#d97706",random:"#6b7280"}[t.corpus_type]??"#374151",Nt=[{id:"browse",label:"Browse"},{id:"edit",label:"Edit"},{id:"stats",label:"Stats"},{id:"ngrams",label:"N-grams"},{id:"concordance",label:"Concordance"},{id:"ai",label:"✨ AI"},{id:"compare",label:"Compare"}],yn=()=>{const fe=!d;u(fe),fe&&window.dispatchEvent(new CustomEvent("glossa:context",{detail:{type:"corpus",id:t.id,name:t.name}}))};return n.jsxs("div",{style:{border:"1px solid #e5e7eb",borderRadius:8,overflow:"hidden",marginBottom:8,boxShadow:"0 1px 3px rgba(0,0,0,0.04)"},children:[n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10,padding:"10px 14px",background:"#fafafa",cursor:"pointer",borderBottom:d?"1px solid #e5e7eb":"none"},onClick:yn,children:[n.jsx("span",{style:{fontSize:11,padding:"1px 7px",borderRadius:8,background:Ut+"20",color:Ut,fontWeight:700,whiteSpace:"nowrap"},children:t.corpus_type}),(()=>{const fe=t.reading_direction??"unknown";if(fe==="unknown")return null;const ft=iy[fe]??iy.ltr;return n.jsx("span",{title:`Reading direction: ${fe.toUpperCase()}`,style:{fontSize:10,padding:"1px 6px",borderRadius:8,background:ft.bg,color:ft.color,fontWeight:700,whiteSpace:"nowrap",border:`1px solid ${ft.color}33`},children:ft.label})})(),n.jsx("span",{style:{flex:1,fontWeight:600,fontSize:13,color:"#111827"},children:t.name}),n.jsxs("span",{style:{fontSize:11,color:"#9ca3af"},children:[t.content.length.toLocaleString()," tokens"]}),n.jsxs("span",{style:{fontSize:11,color:"#9ca3af"},children:["Σ ",t.alphabet_size]}),n.jsx("span",{style:{fontSize:11,color:"#9ca3af"},children:t.created_at.slice(0,10)}),n.jsxs("span",{onClick:fe=>fe.stopPropagation(),style:{display:"flex",gap:4},children:[n.jsx("button",{onClick:yt,title:"Copy",style:{...or,background:lt?"#dcfce7":void 0,color:lt?"#16a34a":void 0,transition:"background 0.2s"},children:lt?"✓":"⎘"}),n.jsx("a",{href:Kx(t.id,"txt"),download:!0,onClick:fe=>fe.stopPropagation(),style:{...or,textDecoration:"none"},children:"↓txt"}),n.jsx("a",{href:Kx(t.id,"csv"),download:!0,onClick:fe=>fe.stopPropagation(),style:{...or,textDecoration:"none"},children:"↓csv"}),n.jsx("button",{onClick:()=>{var fe;return(fe=ve.current)==null?void 0:fe.click()},title:"Import file",style:or,children:"↑ file"}),n.jsx("button",{onClick:async fe=>{if(fe.stopPropagation(),!!confirm(`Delete "${t.name}"?`))try{await f2(t.id),r(t.id),c("Deleted","info")}catch{c("Delete failed","error")}},style:{...or,color:"#dc2626",borderColor:"#fca5a5"},children:"🗑"})]}),n.jsx("input",{ref:ve,type:"file",accept:".txt,.csv,.json",style:{display:"none"},onChange:Jt}),n.jsx("span",{style:{fontSize:14,color:"#9ca3af",marginLeft:2},children:d?"▲":"▼"})]}),d&&n.jsxs("div",{children:[n.jsx("div",{style:{display:"flex",borderBottom:"1px solid #e5e7eb",background:"#f9fafb"},children:Nt.map(fe=>n.jsx("button",{onClick:ft=>{ft.stopPropagation(),g(fe.id)},style:{padding:"7px 14px",border:"none",borderBottom:p===fe.id?"2px solid #1e3a5f":"2px solid transparent",background:"none",cursor:"pointer",fontSize:12,fontWeight:p===fe.id?700:400,color:p===fe.id?"#1e3a5f":"#6b7280"},children:fe.label},fe.id))}),n.jsxs("div",{style:{padding:"14px 16px"},onClick:fe=>fe.stopPropagation(),children:[p==="browse"&&n.jsxs("div",{children:[n.jsxs("div",{style:{display:"flex",gap:8,marginBottom:10,alignItems:"center"},children:[n.jsx("input",{placeholder:"Search tokens…",value:y,onChange:fe=>{b(fe.target.value),v(0)},style:{...hn,flex:1}}),n.jsxs("span",{style:{fontSize:11,color:"#9ca3af",whiteSpace:"nowrap"},children:[Ae.length.toLocaleString()," / ",t.content.length.toLocaleString()]})]}),n.jsx("pre",{style:{background:"#1e293b",color:"#e2e8f0",borderRadius:6,padding:"10px 14px",fontSize:11,overflowX:"auto",maxHeight:220,margin:0,lineHeight:1.8,cursor:"context-menu"},onContextMenu:fe=>Me(fe,[...nk(Oe.join(" "),"Copy page"),{label:"Copy all tokens",icon:"📄",action:()=>navigator.clipboard.writeText(t.content.join(" ")).catch(()=>{})}]),children:Oe.join(" ")}),n.jsx(tk,{menu:De,onClose:Ve}),Ue>1&&n.jsxs("div",{style:{display:"flex",gap:6,marginTop:8,alignItems:"center"},children:[n.jsx("button",{onClick:()=>v(fe=>Math.max(0,fe-1)),disabled:h===0,style:xn,children:"← Prev"}),n.jsxs("span",{style:{fontSize:12,color:"#6b7280"},children:["Page ",h+1," / ",Ue]}),n.jsx("button",{onClick:()=>v(fe=>Math.min(Ue-1,fe+1)),disabled:h>=Ue-1,style:xn,children:"Next →"})]})]}),p==="edit"&&n.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:10,maxWidth:560},children:[n.jsxs("div",{children:[n.jsx("label",{style:$n,children:"Name"}),n.jsx("input",{value:S,onChange:fe=>k(fe.target.value),style:hn})]}),n.jsxs("div",{children:[n.jsx("label",{style:$n,children:"Type"}),n.jsx("select",{value:_,onChange:fe=>T(fe.target.value),style:hn,children:$b.map(fe=>n.jsx("option",{children:fe},fe))})]}),n.jsxs("div",{children:[n.jsx("label",{style:$n,children:"Reading Direction"}),n.jsxs("div",{style:{display:"flex",gap:8,alignItems:"center"},children:[n.jsx("select",{value:W,onChange:fe=>P(fe.target.value),style:{...hn,flex:1},children:Hb.map(fe=>n.jsx("option",{value:fe.value,children:fe.label},fe.value))}),n.jsx("button",{onClick:it,disabled:z,style:{...Nc,whiteSpace:"nowrap"},title:"Auto-detect reading direction using Ashraf & Sinha (2018) positional entropy method",children:z?"Detecting…":"🔍 Auto-detect"})]}),n.jsx("div",{style:{fontSize:10,color:"#6b7280",marginTop:3},children:"Auto-detect applies the Ashraf & Sinha (2018) positional entropy method. Lower entropy at word-end indicates the reading direction."})]}),n.jsxs("div",{children:[n.jsx("label",{style:$n,children:"Tokenisation mode (for re-parsing)"}),n.jsxs("select",{value:j,onChange:fe=>L(fe.target.value),style:hn,children:[n.jsx("option",{value:"space",children:"Space-separated"}),n.jsx("option",{value:"line",children:"Line-per-token"}),n.jsx("option",{value:"char",children:"Character-level"})]})]}),n.jsxs("div",{children:[n.jsxs("label",{style:$n,children:["Content (",t.content.length.toLocaleString()," tokens)"]}),n.jsx("textarea",{value:w,onChange:fe=>C(fe.target.value),rows:8,style:{...hn,fontFamily:"monospace",resize:"vertical",fontSize:11}})]}),n.jsxs("div",{style:{display:"flex",gap:8},children:[n.jsx("button",{onClick:dt,disabled:q,style:es,children:q?"Saving…":"Save"}),n.jsx("button",{onClick:yt,style:Nc,children:"Copy All"}),n.jsx("button",{onClick:()=>{var fe;return(fe=ve.current)==null?void 0:fe.click()},style:Nc,children:"Import File"})]})]}),p==="stats"&&n.jsxs("div",{children:[I&&n.jsx("p",{style:{color:"#6b7280",fontSize:13},children:"Computing metrics…"}),$&&n.jsxs(n.Fragment,{children:[n.jsxs("div",{style:{display:"flex",gap:8,flexWrap:"wrap",marginBottom:14},children:[n.jsx(Vs,{label:"H1 (bits)",value:$.h1,color:"#2563eb"}),n.jsx(Vs,{label:"H2/H1",value:$.h2_h1_ratio??"—",color:"#7c3aed"}),n.jsx(Vs,{label:"Cond H",value:$.conditional_h,color:"#d97706"}),n.jsx(Vs,{label:"TTR",value:$.type_token_ratio.toFixed(3),color:"#16a34a"}),n.jsx(Vs,{label:"Zipf ρ",value:$.zipf_correlation.toFixed(3),color:"#6b7280"}),n.jsx(Vs,{label:"Hapax",value:$.hapax_count.toLocaleString()})]}),n.jsxs("div",{style:{marginBottom:10},children:[n.jsxs("div",{style:sy,children:["Token frequency (top ",Math.min($.zipf_table.length,30),")"]}),n.jsx(oy,{data:$.zipf_table.slice(0,30),xKey:"token",yKey:"freq",height:90})]}),n.jsxs("div",{children:[n.jsx("div",{style:sy,children:"Zipf log-rank vs log-freq"}),n.jsx(ok,{values:$.zipf_table.map(fe=>fe.log_freq),color:"#7c3aed"})]})]}),n.jsx(ak,{tokens:t.content})]}),p==="ngrams"&&n.jsxs("div",{children:[n.jsxs("div",{style:{display:"flex",gap:6,marginBottom:10,alignItems:"center"},children:[n.jsx("span",{style:{fontSize:12,color:"#374151"},children:"n ="}),[1,2,3,4].map(fe=>n.jsx("button",{onClick:()=>Y(fe),style:{...xn,background:D===fe?"#1e3a5f":"#f3f4f6",color:D===fe?"#fff":"#374151"},children:fe},fe)),n.jsx("button",{onClick:rn,disabled:G,style:es,children:G?"Loading…":"Load"})]}),H&&n.jsxs(n.Fragment,{children:[n.jsx(oy,{data:H.slice(0,30).map(fe=>({k:fe.ngram.slice(0,6),count:fe.count})),xKey:"k",yKey:"count",height:90,color:"#7c3aed"}),n.jsxs("table",{style:{borderCollapse:"collapse",width:"100%",marginTop:10,fontSize:12},children:[n.jsx("thead",{children:n.jsxs("tr",{children:[n.jsx("th",{style:Xs,children:"N-gram"}),n.jsx("th",{style:Xs,children:"Count"})]})}),n.jsx("tbody",{children:H.slice(0,50).map(fe=>n.jsxs("tr",{children:[n.jsx("td",{style:Js,children:n.jsx("code",{children:fe.ngram})}),n.jsx("td",{style:Js,children:fe.count.toLocaleString()})]},fe.ngram))})]})]})]}),p==="concordance"&&n.jsxs("div",{children:[n.jsxs("div",{style:{display:"flex",gap:8,marginBottom:10},children:[n.jsx("input",{placeholder:"Token (exact match)…",value:X,onChange:fe=>B(fe.target.value),onKeyDown:fe=>{fe.key==="Enter"&&zt()},style:{...hn,flex:1}}),n.jsx("button",{onClick:zt,disabled:N,style:es,children:N?"…":"Search"})]}),V&&n.jsxs("div",{children:[n.jsxs("div",{style:{fontSize:12,color:"#6b7280",marginBottom:8},children:[V.total.toLocaleString()," occurrences of ",n.jsxs("code",{children:['"',V.query,'"']})]}),n.jsx("div",{style:{maxHeight:300,overflowY:"auto"},children:V.hits.slice(0,100).map((fe,ft)=>n.jsxs("div",{style:{display:"flex",gap:4,padding:"3px 0",borderBottom:"1px solid #f3f4f6",fontSize:12,fontFamily:"monospace"},children:[n.jsx("span",{style:{color:"#9ca3af",width:50,flexShrink:0,textAlign:"right",fontSize:10},children:fe.position}),n.jsx("span",{style:{color:"#6b7280"},children:fe.left.join(" ")}),n.jsx("span",{style:{background:"#fef3c7",padding:"0 2px",borderRadius:2,fontWeight:700,color:"#92400e"},children:fe.match}),n.jsx("span",{style:{color:"#6b7280"},children:fe.right.join(" ")})]},ft))})]})]}),p==="ai"&&n.jsx("div",{children:n.jsxs("div",{style:{display:"flex",gap:6,marginBottom:12,flexWrap:"wrap"},children:[["analyze","anomalies","critique"].map(fe=>n.jsx("button",{onClick:()=>se(fe),style:{...xn,background:ne===fe?"#7c3aed":"#f3f4f6",color:ne===fe?"#fff":"#374151"},children:fe==="analyze"?"Corpus Analysis":fe==="anomalies"?"Anomaly Detection":"Critique"},fe)),n.jsx("button",{onClick:He,style:{...es,background:"#7c3aed",marginLeft:"auto"},children:"✨ Ask AI"})]})}),p==="compare"&&n.jsxs("div",{children:[n.jsxs("div",{style:{display:"flex",gap:8,marginBottom:12,alignItems:"center"},children:[n.jsx("label",{style:{fontSize:12,color:"#374151",whiteSpace:"nowrap"},children:"Compare with:"}),n.jsxs("select",{value:pe,onChange:fe=>_e(fe.target.value),style:{...hn,flex:1},children:[n.jsx("option",{value:"",children:"— select corpus —"}),l.filter(fe=>fe.id!==t.id).map(fe=>n.jsxs("option",{value:fe.id,children:[fe.name," (",fe.corpus_type,")"]},fe.id))]}),n.jsx("button",{onClick:Ze,disabled:!pe||Ce,style:es,children:Ce?"Loading…":"Compare"})]}),te&&we&&(()=>{const fe=l.find(Et=>Et.id===pe),ft=[["H1 (bits)","h1"],["H2/H1","h2_h1_ratio"],["Cond H","conditional_h"],["TTR","type_token_ratio"],["Zipf ρ","zipf_correlation"],["Tokens","token_count"],["Alphabet","type_count"],["Hapax","hapax_count"]];return n.jsxs("table",{style:{borderCollapse:"collapse",width:"100%",fontSize:12},children:[n.jsx("thead",{children:n.jsxs("tr",{children:[n.jsx("th",{style:Xs,children:"Metric"}),n.jsx("th",{style:Xs,children:t.name.slice(0,20)}),n.jsx("th",{style:Xs,children:(fe==null?void 0:fe.name.slice(0,20))??pe}),n.jsx("th",{style:Xs,children:"Δ"})]})}),n.jsx("tbody",{children:ft.map(([Et,qt])=>{const Gt=te[qt]??0,Ct=we[qt]??0,oe=typeof Gt=="number"&&typeof Ct=="number"?Gt-Ct:null,Ne=oe!==null&&Math.abs(oe)>.05*Math.max(Math.abs(Gt),Math.abs(Ct),.001);return n.jsxs("tr",{children:[n.jsx("td",{style:{...Js,fontWeight:600},children:Et}),n.jsx("td",{style:Js,children:typeof Gt=="number"?Number.isInteger(Gt)?Gt.toLocaleString():Gt.toFixed(3):"—"}),n.jsx("td",{style:Js,children:typeof Ct=="number"?Number.isInteger(Ct)?Ct.toLocaleString():Ct.toFixed(3):"—"}),n.jsx("td",{style:{...Js,color:Ne?oe>0?"#16a34a":"#dc2626":"#9ca3af",fontWeight:Ne?700:400},children:oe!==null?(oe>0?"+":"")+oe.toFixed(3):"—"})]},qt)})})]})})()]})]})]})]})}function ck({onCreated:t}){const{toast:o}=et(),[r,l]=x.useState(""),[c,d]=x.useState("linguistic"),[u,p]=x.useState("space"),[g,h]=x.useState("unknown"),[v,y]=x.useState(""),[b,S]=x.useState(!1),k=x.useRef(null),_=C=>u==="char"?C.replace(/\s+/g,"").split(""):u==="line"?C.split(` -`).map(j=>j.trim()).filter(Boolean):C.trim().split(/\s+/).filter(Boolean),T=async()=>{if(!r.trim()||!v.trim()){o("Name and content required","warning");return}const C=_(v);if(!C.length){o("Content cannot be empty","warning");return}S(!0);try{const j=await d2({name:r.trim(),corpus_type:c,content:C,reading_direction:g});t(j),l(""),y(""),h("unknown"),o("Corpus created","success")}catch(j){o(j instanceof Error?j.message:"Upload failed","error")}finally{S(!1)}},w=C=>{var W;const j=(W=C.target.files)==null?void 0:W[0];if(!j)return;r||l(j.name.replace(/\.[^.]+$/,""));const L=new FileReader;L.onload=P=>{var M;const z=(M=P.target)==null?void 0:M.result;if(j.name.endsWith(".json"))try{const q=JSON.parse(z);y(Array.isArray(q)?q.join(" "):(q.content??[]).join(" ")||z)}catch{y(z)}else y(z)},L.readAsText(j),C.target.value=""};return n.jsxs("details",{style:{marginBottom:"1.5rem"},children:[n.jsx("summary",{style:{cursor:"pointer",fontWeight:600,fontSize:13,padding:"8px 0"},children:"+ Upload / import corpus"}),n.jsxs("div",{style:{marginTop:10,padding:"1rem",border:"1px solid #e5e7eb",borderRadius:8,maxWidth:560},children:[n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("label",{style:$n,children:"Name"}),n.jsx("input",{value:r,onChange:C=>l(C.target.value),placeholder:"e.g. Moby Dick",style:hn})]}),n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("label",{style:$n,children:"Type"}),n.jsx("select",{value:c,onChange:C=>d(C.target.value),style:hn,children:$b.map(C=>n.jsx("option",{children:C},C))})]}),n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("label",{style:$n,children:"Reading Direction"}),n.jsx("select",{value:g,onChange:C=>h(C.target.value),style:hn,children:Hb.map(C=>n.jsx("option",{value:C.value,children:C.label},C.value))})]}),n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("label",{style:$n,children:"Tokenisation"}),n.jsxs("select",{value:u,onChange:C=>p(C.target.value),style:hn,children:[n.jsx("option",{value:"space",children:"Space-separated"}),n.jsx("option",{value:"line",children:"Line-per-token"}),n.jsx("option",{value:"char",children:"Character-level"})]})]}),n.jsxs("div",{style:{marginBottom:10},children:[n.jsx("label",{style:$n,children:"Paste text content"}),n.jsx("textarea",{value:v,onChange:C=>y(C.target.value),rows:5,style:{...hn,fontFamily:"monospace",resize:"vertical",fontSize:11},placeholder:"Paste text here…"})]}),n.jsxs("div",{style:{display:"flex",gap:8},children:[n.jsx("button",{onClick:T,disabled:b,style:es,children:b?"Uploading…":"Upload"}),n.jsx("button",{onClick:()=>{var C;return(C=k.current)==null?void 0:C.click()},style:Nc,children:"↑ Import File (.txt/.csv/.json)"}),n.jsx("input",{ref:k,type:"file",accept:".txt,.csv,.json",style:{display:"none"},onChange:w})]})]})]})}function dk({onImported:t}){const{toast:o}=et(),[r,l]=x.useState([]),[c,d]=x.useState(!1),[u,p]=x.useState(null),[g,h]=x.useState(""),[v,y]=x.useState("all"),[b,S]=x.useState("all"),[k,_]=x.useState("all"),T=async()=>{d(!0);try{l(await tj())}catch(q){o(q instanceof Error?q.message:"Failed to load catalogue","error")}finally{d(!1)}},w=async q=>{var K;if(!q.local_module){o(`No bundled module for '${q.name}'. Download from the source URL and upload manually via + Upload / import corpus.`,"warning");return}p(q.id);try{const D=await nj(q.id);D.imported?(l(Y=>Y.map(H=>H.id===q.id?{...H,already_imported:!0}:H)),o(`Imported '${D.name}' (${(K=D.tokens)==null?void 0:K.toLocaleString()} tokens)`,"success"),t()):o(`'${D.name}' already in your corpora`,"info")}catch(D){o(D instanceof Error?D.message:"Import failed","error")}finally{p(null)}},C=Array.from(new Set(r.map(q=>q.script_type).filter(Boolean))).sort(),j=r.filter(q=>{const K=!g||q.name.toLowerCase().includes(g.toLowerCase())||q.language.toLowerCase().includes(g.toLowerCase())||q.language_family.toLowerCase().includes(g.toLowerCase()),D=v==="all"||(v==="undeciphered"?!!q.is_undeciphered:!q.is_undeciphered),Y=b==="all"||q.script_type===b,H=k==="all"||(k==="bundled"?!!q.local_module:!q.local_module);return K&&D&&Y&&H}),L={};for(const q of j){const K=q.language_family||"Other";(L[K]=L[K]||[]).push(q)}const W={abjad:"#7c3aed",syllabary:"#059669",logosyllabic:"#d97706",logographic:"#dc2626",alphabet:"#2563eb",unknown:"#6b7280"},P={abjad:"Abjad",syllabary:"Syllabary",logosyllabic:"Logo-syllabic",logographic:"Logographic",alphabet:"Alphabet",unknown:"Unknown"},z={ltr:{label:"LTR",color:"#065f46",bg:"#d1fae5",title:"Left to Right"},rtl:{label:"RTL",color:"#7c2d12",bg:"#fee2e2",title:"Right to Left"},bidi:{label:"BIDI",color:"#5b21b6",bg:"#ede9fe",title:"Boustrophedon (alternating)"},unknown:{label:"?",color:"#6b7280",bg:"#f3f4f6",title:"Reading direction unknown"}},M=q=>q>0?`~${q>=1e3?`${(q/1e3).toFixed(q>=1e4?0:1)}K`:q.toString()} tokens`:"—";return n.jsxs("details",{style:{marginBottom:"1.5rem"},children:[n.jsx("summary",{style:{cursor:"pointer",fontWeight:600,fontSize:13,padding:"8px 0",color:"#059669"},onClick:()=>r.length===0&&void T(),children:"🌍 Browse World Language Corpus Catalogue"}),n.jsxs("div",{style:{marginTop:10,padding:"1rem",border:"1px solid #d1fae5",borderRadius:8,background:"#f0fdf4"},children:[n.jsxs("div",{style:{display:"flex",gap:6,marginBottom:6,flexWrap:"wrap",alignItems:"center"},children:[n.jsx("input",{placeholder:"Search name, language, family…",value:g,onChange:q=>h(q.target.value),style:{...hn,width:220}}),["all","undeciphered","deciphered"].map(q=>n.jsx("button",{onClick:()=>y(q),style:{...xn,background:v===q?"#059669":void 0,color:v===q?"#fff":void 0},children:q==="all"?"All":q==="undeciphered"?"🔓 Undeciphered":"✓ Deciphered"},q)),n.jsx("div",{style:{display:"flex",gap:4},children:["all","bundled","manual"].map(q=>n.jsx("button",{onClick:()=>_(q),style:{...xn,background:k===q?"#2563eb":void 0,color:k===q?"#fff":void 0},title:q==="bundled"?"One-click import available":q==="manual"?"Manual upload required":"All",children:q==="all"?"⬇ Any":q==="bundled"?"⬇ 1-click":"✎ Manual"},q))}),n.jsx("button",{onClick:()=>void T(),style:xn,title:"Reload catalogue",children:"⟳"}),n.jsxs("span",{style:{fontSize:11,color:"#6b7280",marginLeft:"auto"},children:[j.length," entries"]})]}),C.length>0&&n.jsxs("div",{style:{display:"flex",gap:4,marginBottom:10,flexWrap:"wrap"},children:[n.jsx("button",{onClick:()=>S("all"),style:{...xn,padding:"2px 8px",background:b==="all"?"#374151":void 0,color:b==="all"?"#fff":void 0,fontSize:10},children:"All types"}),C.map(q=>{const K=W[q]??"#6b7280";return n.jsx("button",{onClick:()=>S(b===q?"all":q),style:{...xn,padding:"2px 8px",fontSize:10,background:b===q?K:K+"15",color:b===q?"#fff":K,border:`1px solid ${K}40`,fontWeight:b===q?700:400},children:P[q]??q},q)})]}),c&&n.jsx("p",{style:{color:"#6b7280",fontSize:13},children:"Loading catalogue…"}),Object.entries(L).sort(([q],[K])=>q.localeCompare(K)).map(([q,K])=>n.jsxs("div",{style:{marginBottom:10},children:[n.jsxs("div",{style:{fontSize:10,fontWeight:700,color:"#374151",textTransform:"uppercase",letterSpacing:.5,marginBottom:3,paddingBottom:2,borderBottom:"1px solid #d1fae5"},children:[q," ",n.jsxs("span",{style:{fontWeight:400,opacity:.6},children:["(",K.length,")"]})]}),K.map(D=>{const Y=W[D.script_type]??"#6b7280",H=!!D.local_module,A=M(D.tokens_approx);return n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,padding:"5px 0",borderBottom:"1px solid #ecfdf5"},children:[n.jsxs("div",{style:{flex:1,minWidth:0},children:[n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:5,flexWrap:"wrap"},children:[n.jsx("span",{style:{fontWeight:600,fontSize:12,color:D.is_undeciphered?"#7c2d12":"#1e3a5f"},children:D.name}),n.jsx("span",{style:{fontSize:9,padding:"1px 5px",borderRadius:8,background:Y+"18",color:Y,fontWeight:700},children:P[D.script_type]??D.script_type}),(()=>{const G=D.reading_direction??"unknown",R=z[G]??z.unknown;return n.jsx("span",{style:{fontSize:9,padding:"1px 5px",borderRadius:8,background:R.bg,color:R.color,fontWeight:700,letterSpacing:.2},title:R.title,children:R.label})})(),D.is_undeciphered&&n.jsx("span",{style:{fontSize:9,color:"#dc2626",fontWeight:700},children:"🔓"}),H&&!D.already_imported&&n.jsx("span",{style:{fontSize:9,color:"#059669",fontWeight:600},children:"⬇ bundled"})]}),n.jsxs("div",{style:{fontSize:10,color:"#6b7280",marginTop:1},children:[D.language," · ",D.period," · ",A," · ",D.license]})]}),n.jsx("div",{style:{display:"flex",gap:4,flexShrink:0},children:D.already_imported?n.jsx("span",{style:{fontSize:10,color:"#059669",fontWeight:700},children:"✓ Imported"}):H?n.jsx("button",{onClick:()=>void w(D),disabled:u===D.id,style:{...xn,background:u===D.id?"#d1d5db":"#059669",color:"#fff",border:"none",fontSize:10},children:u===D.id?"⏳":"↓ Import"}):n.jsx("a",{href:D.source_url,target:"_blank",rel:"noopener noreferrer",style:{...xn,textDecoration:"none",fontSize:10,color:"#374151"},title:`Source: ${D.source_url}`,children:"Source ↗"})})]},D.id)})]},q)),!c&&j.length===0&&r.length>0&&n.jsx("p",{style:{color:"#6b7280",fontSize:13},children:"No entries match your filters."}),!c&&r.length===0&&n.jsx("p",{style:{color:"#6b7280",fontSize:13},children:"Click ⟳ to load the catalogue."})]})]})}function uk(){const{toast:t}=et(),[o,r]=x.useState([]),[l,c]=x.useState(!1),[d,u]=x.useState(!1),[p,g]=x.useState(""),[h,v]=x.useState(""),[y,b]=x.useState(""),S=async()=>{c(!0);try{r(await Q2())}catch(w){t(w instanceof Error?w.message:"Failed to load","error")}finally{c(!1)}},k=w=>w.split(` -`).map(C=>C.trim()).filter(Boolean).map(C=>{const[j,L,W,...P]=C.split(/\s+|\t/);return{cipher:j??"",target:L??"",confidence:W??"high",note:P.join(" ")}}).filter(C=>C.cipher&&C.target),_=async()=>{if(!p.trim()){t("Name required","warning");return}try{const w=await Z2({name:p.trim(),language:h.trim(),pairs:k(y)});r(C=>[w,...C]),u(!1),g(""),v(""),b(""),t("Anchor set created","success")}catch(w){t(w instanceof Error?w.message:"Create failed","error")}},T=async w=>{if(confirm("Delete this anchor set?"))try{await ej(w),r(C=>C.filter(j=>j.id!==w))}catch(C){t(C instanceof Error?C.message:"Delete failed","error")}};return x.useEffect(()=>{S()},[]),n.jsxs("details",{style:{marginBottom:"1.5rem"},children:[n.jsxs("summary",{style:{cursor:"pointer",fontWeight:600,fontSize:13,padding:"8px 0",color:"#7c3aed"},children:["⚓ Anchor Sets (",o.length,")"]}),n.jsxs("div",{style:{marginTop:10,padding:"1rem",border:"1px solid #ede9fe",borderRadius:8,background:"#faf5ff"},children:[n.jsxs("div",{style:{display:"flex",gap:8,marginBottom:10},children:[n.jsx("button",{onClick:()=>u(w=>!w),style:{...xn,background:"#7c3aed",color:"#fff",border:"none"},children:"+ New Set"}),n.jsx("button",{onClick:()=>void S(),style:xn,children:"⟳ Refresh"})]}),d&&n.jsxs("div",{style:{padding:12,border:"1px solid #a78bfa",borderRadius:6,marginBottom:12,background:"#fff"},children:[n.jsxs("div",{style:{display:"flex",gap:8,marginBottom:8},children:[n.jsxs("div",{style:{flex:2},children:[n.jsx("label",{style:$n,children:"Set Name"}),n.jsx("input",{value:p,onChange:w=>g(w.target.value),placeholder:"e.g. Fuls Ugaritic Anchors",style:hn})]}),n.jsxs("div",{style:{flex:1},children:[n.jsx("label",{style:$n,children:"Language (optional)"}),n.jsx("input",{value:h,onChange:w=>v(w.target.value),placeholder:"e.g. Ugaritic",style:hn})]})]}),n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("label",{style:$n,children:"Anchor Pairs (one per line: cipher target confidence note)"}),n.jsx("textarea",{value:y,onChange:w=>b(w.target.value),rows:5,style:{...hn,fontFamily:"monospace",fontSize:11,resize:"vertical"},placeholder:`004 T high Fuls verified +`+a.stack}}var Me=Object.prototype.hasOwnProperty,Ve=t.unstable_scheduleCallback,Le=t.unstable_cancelCallback,Ae=t.unstable_shouldYield,Ue=t.unstable_requestPaint,Oe=t.unstable_now,dt=t.unstable_getCurrentPriorityLevel,it=t.unstable_ImmediatePriority,lt=t.unstable_UserBlockingPriority,Je=t.unstable_NormalPriority,yt=t.unstable_LowPriority,Jt=t.unstable_IdlePriority,rn=t.log,zt=t.unstable_setDisableYieldValue,ae=null,He=null;function Ze(e){if(typeof rn=="function"&&zt(e),He&&typeof He.setStrictMode=="function")try{He.setStrictMode(ae,e)}catch{}}var ut=Math.clz32?Math.clz32:yn,Ut=Math.log,Nt=Math.LN2;function yn(e){return e>>>=0,e===0?32:31-(Ut(e)/Nt|0)|0}var fe=256,ft=262144,Et=4194304;function Gt(e){var i=e&42;if(i!==0)return i;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&261888;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,i,s){var a=e.pendingLanes;if(a===0)return 0;var f=0,m=e.suspendedLanes,z=e.pingedLanes;e=e.warmLanes;var U=a&134217727;return U!==0?(a=U&~m,a!==0?f=Gt(a):(z&=U,z!==0?f=Gt(z):s||(s=U&~e,s!==0&&(f=Gt(s))))):(U=a&~m,U!==0?f=Gt(U):z!==0?f=Gt(z):s||(s=a&~e,s!==0&&(f=Gt(s)))),f===0?0:i!==0&&i!==f&&(i&m)===0&&(m=f&-f,s=i&-i,m>=s||m===32&&(s&4194048)!==0)?i:f}function Ct(e,i){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&i)===0}function oe(e,i){switch(e){case 1:case 2:case 4:case 8:case 64:return i+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return i+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function Ne(){var e=Et;return Et<<=1,(Et&62914560)===0&&(Et=4194304),e}function We(e){for(var i=[],s=0;31>s;s++)i.push(e);return i}function mt(e,i){e.pendingLanes|=i,i!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function St(e,i,s,a,f,m){var z=e.pendingLanes;e.pendingLanes=s,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=s,e.entangledLanes&=s,e.errorRecoveryDisabledLanes&=s,e.shellSuspendCounter=0;var U=e.entanglements,Z=e.expirationTimes,ce=e.hiddenUpdates;for(s=z&~s;0"u")return null;try{return e.activeElement||e.body}catch{return e.body}}var Yt=/[\n"\\]/g;function At(e){return e.replace(Yt,function(i){return"\\"+i.charCodeAt(0).toString(16)+" "})}function Wt(e,i,s,a,f,m,z,U){e.name="",z!=null&&typeof z!="function"&&typeof z!="symbol"&&typeof z!="boolean"?e.type=z:e.removeAttribute("type"),i!=null?z==="number"?(i===0&&e.value===""||e.value!=i)&&(e.value=""+Te(i)):e.value!==""+Te(i)&&(e.value=""+Te(i)):z!=="submit"&&z!=="reset"||e.removeAttribute("value"),i!=null?cn(e,z,Te(i)):s!=null?cn(e,z,Te(s)):a!=null&&e.removeAttribute("value"),f==null&&m!=null&&(e.defaultChecked=!!m),f!=null&&(e.checked=f&&typeof f!="function"&&typeof f!="symbol"),U!=null&&typeof U!="function"&&typeof U!="symbol"&&typeof U!="boolean"?e.name=""+Te(U):e.removeAttribute("name")}function Qt(e,i,s,a,f,m,z,U){if(m!=null&&typeof m!="function"&&typeof m!="symbol"&&typeof m!="boolean"&&(e.type=m),i!=null||s!=null){if(!(m!=="submit"&&m!=="reset"||i!=null)){qe(e);return}s=s!=null?""+Te(s):"",i=i!=null?""+Te(i):s,U||i===e.value||(e.value=i),e.defaultValue=i}a=a??f,a=typeof a!="function"&&typeof a!="symbol"&&!!a,e.checked=U?e.checked:!!a,e.defaultChecked=!!a,z!=null&&typeof z!="function"&&typeof z!="symbol"&&typeof z!="boolean"&&(e.name=z),qe(e)}function cn(e,i,s){i==="number"&&wt(e.ownerDocument)===e||e.defaultValue===""+s||(e.defaultValue=""+s)}function Mt(e,i,s,a){if(e=e.options,i){i={};for(var f=0;f"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),Cd=!1;if(zi)try{var Cr={};Object.defineProperty(Cr,"passive",{get:function(){Cd=!0}}),window.addEventListener("test",Cr,Cr),window.removeEventListener("test",Cr,Cr)}catch{Cd=!1}var eo=null,Td=null,sl=null;function ch(){if(sl)return sl;var e,i=Td,s=i.length,a,f="value"in eo?eo.value:eo.textContent,m=f.length;for(e=0;e=Er),gh=" ",mh=!1;function xh(e,i){switch(e){case"keyup":return yS.indexOf(i.keyCode)!==-1;case"keydown":return i.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function yh(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var xs=!1;function vS(e,i){switch(e){case"compositionend":return yh(i);case"keypress":return i.which!==32?null:(mh=!0,gh);case"textInput":return e=i.data,e===gh&&mh?null:e;default:return null}}function SS(e,i){if(xs)return e==="compositionend"||!Md&&xh(e,i)?(e=ch(),sl=Td=eo=null,xs=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(i.ctrlKey||i.altKey||i.metaKey)||i.ctrlKey&&i.altKey){if(i.char&&1=i)return{node:s,offset:i-e};e=a}e:{for(;s;){if(s.nextSibling){s=s.nextSibling;break e}s=s.parentNode}s=void 0}s=Ch(s)}}function zh(e,i){return e&&i?e===i?!0:e&&e.nodeType===3?!1:i&&i.nodeType===3?zh(e,i.parentNode):"contains"in e?e.contains(i):e.compareDocumentPosition?!!(e.compareDocumentPosition(i)&16):!1:!1}function Eh(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var i=wt(e.document);i instanceof e.HTMLIFrameElement;){try{var s=typeof i.contentWindow.location.href=="string"}catch{s=!1}if(s)e=i.contentWindow;else break;i=wt(e.document)}return i}function Nd(e){var i=e&&e.nodeName&&e.nodeName.toLowerCase();return i&&(i==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||i==="textarea"||e.contentEditable==="true")}var ES=zi&&"documentMode"in document&&11>=document.documentMode,ys=null,Bd=null,Dr=null,Od=!1;function Rh(e,i,s){var a=s.window===s?s.document:s.nodeType===9?s:s.ownerDocument;Od||ys==null||ys!==wt(a)||(a=ys,"selectionStart"in a&&Nd(a)?a={start:a.selectionStart,end:a.selectionEnd}:(a=(a.ownerDocument&&a.ownerDocument.defaultView||window).getSelection(),a={anchorNode:a.anchorNode,anchorOffset:a.anchorOffset,focusNode:a.focusNode,focusOffset:a.focusOffset}),Dr&&Mr(Dr,a)||(Dr=a,a=Ql(Bd,"onSelect"),0>=z,f-=z,gi=1<<32-ut(i)+f|s<Qe?(rt=$e,$e=null):rt=$e.sibling;var gt=ue(re,$e,le[Qe],we);if(gt===null){$e===null&&($e=rt);break}e&&$e&>.alternate===null&&i(re,$e),ie=m(gt,ie,Qe),ht===null?Pe=gt:ht.sibling=gt,ht=gt,$e=rt}if(Qe===le.length)return s(re,$e),ct&&Ri(re,Qe),Pe;if($e===null){for(;QeQe?(rt=$e,$e=null):rt=$e.sibling;var jo=ue(re,$e,gt.value,we);if(jo===null){$e===null&&($e=rt);break}e&&$e&&jo.alternate===null&&i(re,$e),ie=m(jo,ie,Qe),ht===null?Pe=jo:ht.sibling=jo,ht=jo,$e=rt}if(gt.done)return s(re,$e),ct&&Ri(re,Qe),Pe;if($e===null){for(;!gt.done;Qe++,gt=le.next())gt=je(re,gt.value,we),gt!==null&&(ie=m(gt,ie,Qe),ht===null?Pe=gt:ht.sibling=gt,ht=gt);return ct&&Ri(re,Qe),Pe}for($e=a($e);!gt.done;Qe++,gt=le.next())gt=ge($e,re,Qe,gt.value,we),gt!==null&&(e&>.alternate!==null&&$e.delete(gt.key===null?Qe:gt.key),ie=m(gt,ie,Qe),ht===null?Pe=gt:ht.sibling=gt,ht=gt);return e&&$e.forEach(function(Xw){return i(re,Xw)}),ct&&Ri(re,Qe),Pe}function _t(re,ie,le,we){if(typeof le=="object"&&le!==null&&le.type===_&&le.key===null&&(le=le.props.children),typeof le=="object"&&le!==null){switch(le.$$typeof){case w:e:{for(var Pe=le.key;ie!==null;){if(ie.key===Pe){if(Pe=le.type,Pe===_){if(ie.tag===7){s(re,ie.sibling),we=f(ie,le.props.children),we.return=re,re=we;break e}}else if(ie.elementType===Pe||typeof Pe=="object"&&Pe!==null&&Pe.$$typeof===P&&Wo(Pe)===ie.type){s(re,ie.sibling),we=f(ie,le.props),$r(we,le),we.return=re,re=we;break e}s(re,ie);break}else i(re,ie);ie=ie.sibling}le.type===_?(we=Bo(le.props.children,re.mode,we,le.key),we.return=re,re=we):(we=gl(le.type,le.key,le.props,null,re.mode,we),$r(we,le),we.return=re,re=we)}return z(re);case j:e:{for(Pe=le.key;ie!==null;){if(ie.key===Pe)if(ie.tag===4&&ie.stateNode.containerInfo===le.containerInfo&&ie.stateNode.implementation===le.implementation){s(re,ie.sibling),we=f(ie,le.children||[]),we.return=re,re=we;break e}else{s(re,ie);break}else i(re,ie);ie=ie.sibling}we=Pd(le,re.mode,we),we.return=re,re=we}return z(re);case P:return le=Wo(le),_t(re,ie,le,we)}if(q(le))return Be(re,ie,le,we);if(V(le)){if(Pe=V(le),typeof Pe!="function")throw Error(l(150));return le=Pe.call(le),Fe(re,ie,le,we)}if(typeof le.then=="function")return _t(re,ie,wl(le),we);if(le.$$typeof===k)return _t(re,ie,yl(re,le),we);jl(re,le)}return typeof le=="string"&&le!==""||typeof le=="number"||typeof le=="bigint"?(le=""+le,ie!==null&&ie.tag===6?(s(re,ie.sibling),we=f(ie,le),we.return=re,re=we):(s(re,ie),we=Gd(le,re.mode,we),we.return=re,re=we),z(re)):s(re,ie)}return function(re,ie,le,we){try{Ir=0;var Pe=_t(re,ie,le,we);return Es=null,Pe}catch($e){if($e===zs||$e===vl)throw $e;var ht=Dn(29,$e,null,re.mode);return ht.lanes=we,ht.return=re,ht}finally{}}}var Go=Zh(!0),eg=Zh(!1),so=!1;function nu(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function iu(e,i){e=e.updateQueue,i.updateQueue===e&&(i.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,callbacks:null})}function ro(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function ao(e,i,s){var a=e.updateQueue;if(a===null)return null;if(a=a.shared,(xt&2)!==0){var f=a.pending;return f===null?i.next=i:(i.next=f.next,f.next=i),a.pending=i,i=hl(e),Oh(e,null,s),i}return pl(e,a,i,s),hl(e)}function Hr(e,i,s){if(i=i.updateQueue,i!==null&&(i=i.shared,(s&4194048)!==0)){var a=i.lanes;a&=e.pendingLanes,s|=a,i.lanes=s,Kt(e,s)}}function ou(e,i){var s=e.updateQueue,a=e.alternate;if(a!==null&&(a=a.updateQueue,s===a)){var f=null,m=null;if(s=s.firstBaseUpdate,s!==null){do{var z={lane:s.lane,tag:s.tag,payload:s.payload,callback:null,next:null};m===null?f=m=z:m=m.next=z,s=s.next}while(s!==null);m===null?f=m=i:m=m.next=i}else f=m=i;s={baseState:a.baseState,firstBaseUpdate:f,lastBaseUpdate:m,shared:a.shared,callbacks:a.callbacks},e.updateQueue=s;return}e=s.lastBaseUpdate,e===null?s.firstBaseUpdate=i:e.next=i,s.lastBaseUpdate=i}var su=!1;function Wr(){if(su){var e=Ts;if(e!==null)throw e}}function Ur(e,i,s,a){su=!1;var f=e.updateQueue;so=!1;var m=f.firstBaseUpdate,z=f.lastBaseUpdate,U=f.shared.pending;if(U!==null){f.shared.pending=null;var Z=U,ce=Z.next;Z.next=null,z===null?m=ce:z.next=ce,z=Z;var be=e.alternate;be!==null&&(be=be.updateQueue,U=be.lastBaseUpdate,U!==z&&(U===null?be.firstBaseUpdate=ce:U.next=ce,be.lastBaseUpdate=Z))}if(m!==null){var je=f.baseState;z=0,be=ce=Z=null,U=m;do{var ue=U.lane&-536870913,ge=ue!==U.lane;if(ge?(st&ue)===ue:(a&ue)===ue){ue!==0&&ue===Cs&&(su=!0),be!==null&&(be=be.next={lane:0,tag:U.tag,payload:U.payload,callback:null,next:null});e:{var Be=e,Fe=U;ue=i;var _t=s;switch(Fe.tag){case 1:if(Be=Fe.payload,typeof Be=="function"){je=Be.call(_t,je,ue);break e}je=Be;break e;case 3:Be.flags=Be.flags&-65537|128;case 0:if(Be=Fe.payload,ue=typeof Be=="function"?Be.call(_t,je,ue):Be,ue==null)break e;je=y({},je,ue);break e;case 2:so=!0}}ue=U.callback,ue!==null&&(e.flags|=64,ge&&(e.flags|=8192),ge=f.callbacks,ge===null?f.callbacks=[ue]:ge.push(ue))}else ge={lane:ue,tag:U.tag,payload:U.payload,callback:U.callback,next:null},be===null?(ce=be=ge,Z=je):be=be.next=ge,z|=ue;if(U=U.next,U===null){if(U=f.shared.pending,U===null)break;ge=U,U=ge.next,ge.next=null,f.lastBaseUpdate=ge,f.shared.pending=null}}while(!0);be===null&&(Z=je),f.baseState=Z,f.firstBaseUpdate=ce,f.lastBaseUpdate=be,m===null&&(f.shared.lanes=0),po|=z,e.lanes=z,e.memoizedState=je}}function tg(e,i){if(typeof e!="function")throw Error(l(191,e));e.call(i)}function ng(e,i){var s=e.callbacks;if(s!==null)for(e.callbacks=null,e=0;em?m:8;var z=R.T,U={};R.T=U,ku(e,!1,i,s);try{var Z=f(),ce=R.S;if(ce!==null&&ce(U,Z),Z!==null&&typeof Z=="object"&&typeof Z.then=="function"){var be=IS(Z,a);qr(e,i,be,In(e))}else qr(e,i,a,In(e))}catch(je){qr(e,i,{then:function(){},status:"rejected",reason:je},In())}finally{J.p=m,z!==null&&U.types!==null&&(z.types=U.types),R.T=z}}function PS(){}function wu(e,i,s,a){if(e.tag!==5)throw Error(l(476));var f=Lg(e).queue;Dg(e,f,i,N,s===null?PS:function(){return Ng(e),s(a)})}function Lg(e){var i=e.memoizedState;if(i!==null)return i;i={memoizedState:N,baseState:N,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Li,lastRenderedState:N},next:null};var s={};return i.next={memoizedState:s,baseState:s,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Li,lastRenderedState:s},next:null},e.memoizedState=i,e=e.alternate,e!==null&&(e.memoizedState=i),i}function Ng(e){var i=Lg(e);i.next===null&&(i=e.alternate.memoizedState),qr(e,i.next.queue,{},In())}function ju(){return un(la)}function Bg(){return Xt().memoizedState}function Og(){return Xt().memoizedState}function qS(e){for(var i=e.return;i!==null;){switch(i.tag){case 24:case 3:var s=In();e=ro(s);var a=ao(i,e,s);a!==null&&(En(a,i,s),Hr(a,i,s)),i={cache:Qd()},e.payload=i;return}i=i.return}}function FS(e,i,s){var a=In();s={lane:a,revertLane:0,gesture:null,action:s,hasEagerState:!1,eagerState:null,next:null},Dl(e)?$g(i,s):(s=Wd(e,i,s,a),s!==null&&(En(s,e,a),Hg(s,i,a)))}function Ig(e,i,s){var a=In();qr(e,i,s,a)}function qr(e,i,s,a){var f={lane:a,revertLane:0,gesture:null,action:s,hasEagerState:!1,eagerState:null,next:null};if(Dl(e))$g(i,f);else{var m=e.alternate;if(e.lanes===0&&(m===null||m.lanes===0)&&(m=i.lastRenderedReducer,m!==null))try{var z=i.lastRenderedState,U=m(z,s);if(f.hasEagerState=!0,f.eagerState=U,Mn(U,z))return pl(e,i,f,0),Tt===null&&fl(),!1}catch{}finally{}if(s=Wd(e,i,f,a),s!==null)return En(s,e,a),Hg(s,i,a),!0}return!1}function ku(e,i,s,a){if(a={lane:2,revertLane:nf(),gesture:null,action:a,hasEagerState:!1,eagerState:null,next:null},Dl(e)){if(i)throw Error(l(479))}else i=Wd(e,s,a,2),i!==null&&En(i,e,2)}function Dl(e){var i=e.alternate;return e===Ke||i!==null&&i===Ke}function $g(e,i){As=Cl=!0;var s=e.pending;s===null?i.next=i:(i.next=s.next,s.next=i),e.pending=i}function Hg(e,i,s){if((s&4194048)!==0){var a=i.lanes;a&=e.pendingLanes,s|=a,i.lanes=s,Kt(e,s)}}var Fr={readContext:un,use:El,useCallback:qt,useContext:qt,useEffect:qt,useImperativeHandle:qt,useLayoutEffect:qt,useInsertionEffect:qt,useMemo:qt,useReducer:qt,useRef:qt,useState:qt,useDebugValue:qt,useDeferredValue:qt,useTransition:qt,useSyncExternalStore:qt,useId:qt,useHostTransitionStatus:qt,useFormState:qt,useActionState:qt,useOptimistic:qt,useMemoCache:qt,useCacheRefresh:qt};Fr.useEffectEvent=qt;var Wg={readContext:un,use:El,useCallback:function(e,i){return vn().memoizedState=[e,i===void 0?null:i],e},useContext:un,useEffect:kg,useImperativeHandle:function(e,i,s){s=s!=null?s.concat([e]):null,Al(4194308,4,zg.bind(null,i,e),s)},useLayoutEffect:function(e,i){return Al(4194308,4,e,i)},useInsertionEffect:function(e,i){Al(4,2,e,i)},useMemo:function(e,i){var s=vn();i=i===void 0?null:i;var a=e();if(Po){Ze(!0);try{e()}finally{Ze(!1)}}return s.memoizedState=[a,i],a},useReducer:function(e,i,s){var a=vn();if(s!==void 0){var f=s(i);if(Po){Ze(!0);try{s(i)}finally{Ze(!1)}}}else f=i;return a.memoizedState=a.baseState=f,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:f},a.queue=e,e=e.dispatch=FS.bind(null,Ke,e),[a.memoizedState,e]},useRef:function(e){var i=vn();return e={current:e},i.memoizedState=e},useState:function(e){e=xu(e);var i=e.queue,s=Ig.bind(null,Ke,i);return i.dispatch=s,[e.memoizedState,s]},useDebugValue:vu,useDeferredValue:function(e,i){var s=vn();return Su(s,e,i)},useTransition:function(){var e=xu(!1);return e=Dg.bind(null,Ke,e.queue,!0,!1),vn().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,i,s){var a=Ke,f=vn();if(ct){if(s===void 0)throw Error(l(407));s=s()}else{if(s=i(),Tt===null)throw Error(l(349));(st&127)!==0||lg(a,i,s)}f.memoizedState=s;var m={value:s,getSnapshot:i};return f.queue=m,kg(dg.bind(null,a,m,e),[e]),a.flags|=2048,Ds(9,{destroy:void 0},cg.bind(null,a,m,s,i),null),s},useId:function(){var e=vn(),i=Tt.identifierPrefix;if(ct){var s=mi,a=gi;s=(a&~(1<<32-ut(a)-1)).toString(32)+s,i="_"+i+"R_"+s,s=Tl++,0<\/script>",m=m.removeChild(m.firstChild);break;case"select":m=typeof a.is=="string"?z.createElement("select",{is:a.is}):z.createElement("select"),a.multiple?m.multiple=!0:a.size&&(m.size=a.size);break;default:m=typeof a.is=="string"?z.createElement(f,{is:a.is}):z.createElement(f)}}m[Rt]=i,m[an]=a;e:for(z=i.child;z!==null;){if(z.tag===5||z.tag===6)m.appendChild(z.stateNode);else if(z.tag!==4&&z.tag!==27&&z.child!==null){z.child.return=z,z=z.child;continue}if(z===i)break e;for(;z.sibling===null;){if(z.return===null||z.return===i)break e;z=z.return}z.sibling.return=z.return,z=z.sibling}i.stateNode=m;e:switch(pn(m,f,a),f){case"button":case"input":case"select":case"textarea":a=!!a.autoFocus;break e;case"img":a=!0;break e;default:a=!1}a&&Bi(i)}}return Lt(i),Iu(i,i.type,e===null?null:e.memoizedProps,i.pendingProps,s),null;case 6:if(e&&i.stateNode!=null)e.memoizedProps!==a&&Bi(i);else{if(typeof a!="string"&&i.stateNode===null)throw Error(l(166));if(e=K.current,ks(i)){if(e=i.stateNode,s=i.memoizedProps,a=null,f=dn,f!==null)switch(f.tag){case 27:case 5:a=f.memoizedProps}e[Rt]=i,e=!!(e.nodeValue===s||a!==null&&a.suppressHydrationWarning===!0||rx(e.nodeValue,s)),e||io(i,!0)}else e=Zl(e).createTextNode(a),e[Rt]=i,i.stateNode=e}return Lt(i),null;case 31:if(s=i.memoizedState,e===null||e.memoizedState!==null){if(a=ks(i),s!==null){if(e===null){if(!a)throw Error(l(318));if(e=i.memoizedState,e=e!==null?e.dehydrated:null,!e)throw Error(l(557));e[Rt]=i}else Oo(),(i.flags&128)===0&&(i.memoizedState=null),i.flags|=4;Lt(i),e=!1}else s=Vd(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=s),e=!0;if(!e)return i.flags&256?(Nn(i),i):(Nn(i),null);if((i.flags&128)!==0)throw Error(l(558))}return Lt(i),null;case 13:if(a=i.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(f=ks(i),a!==null&&a.dehydrated!==null){if(e===null){if(!f)throw Error(l(318));if(f=i.memoizedState,f=f!==null?f.dehydrated:null,!f)throw Error(l(317));f[Rt]=i}else Oo(),(i.flags&128)===0&&(i.memoizedState=null),i.flags|=4;Lt(i),f=!1}else f=Vd(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=f),f=!0;if(!f)return i.flags&256?(Nn(i),i):(Nn(i),null)}return Nn(i),(i.flags&128)!==0?(i.lanes=s,i):(s=a!==null,e=e!==null&&e.memoizedState!==null,s&&(a=i.child,f=null,a.alternate!==null&&a.alternate.memoizedState!==null&&a.alternate.memoizedState.cachePool!==null&&(f=a.alternate.memoizedState.cachePool.pool),m=null,a.memoizedState!==null&&a.memoizedState.cachePool!==null&&(m=a.memoizedState.cachePool.pool),m!==f&&(a.flags|=2048)),s!==e&&s&&(i.child.flags|=8192),Il(i,i.updateQueue),Lt(i),null);case 4:return pe(),e===null&&af(i.stateNode.containerInfo),Lt(i),null;case 10:return Mi(i.type),Lt(i),null;case 19:if(B(Vt),a=i.memoizedState,a===null)return Lt(i),null;if(f=(i.flags&128)!==0,m=a.rendering,m===null)if(f)Vr(a,!1);else{if(Ft!==0||e!==null&&(e.flags&128)!==0)for(e=i.child;e!==null;){if(m=_l(e),m!==null){for(i.flags|=128,Vr(a,!1),e=m.updateQueue,i.updateQueue=e,Il(i,e),i.subtreeFlags=0,e=s,s=i.child;s!==null;)Ih(s,e),s=s.sibling;return $(Vt,Vt.current&1|2),ct&&Ri(i,a.treeForkCount),i.child}e=e.sibling}a.tail!==null&&Oe()>Gl&&(i.flags|=128,f=!0,Vr(a,!1),i.lanes=4194304)}else{if(!f)if(e=_l(m),e!==null){if(i.flags|=128,f=!0,e=e.updateQueue,i.updateQueue=e,Il(i,e),Vr(a,!0),a.tail===null&&a.tailMode==="hidden"&&!m.alternate&&!ct)return Lt(i),null}else 2*Oe()-a.renderingStartTime>Gl&&s!==536870912&&(i.flags|=128,f=!0,Vr(a,!1),i.lanes=4194304);a.isBackwards?(m.sibling=i.child,i.child=m):(e=a.last,e!==null?e.sibling=m:i.child=m,a.last=m)}return a.tail!==null?(e=a.tail,a.rendering=e,a.tail=e.sibling,a.renderingStartTime=Oe(),e.sibling=null,s=Vt.current,$(Vt,f?s&1|2:s&1),ct&&Ri(i,a.treeForkCount),e):(Lt(i),null);case 22:case 23:return Nn(i),au(),a=i.memoizedState!==null,e!==null?e.memoizedState!==null!==a&&(i.flags|=8192):a&&(i.flags|=8192),a?(s&536870912)!==0&&(i.flags&128)===0&&(Lt(i),i.subtreeFlags&6&&(i.flags|=8192)):Lt(i),s=i.updateQueue,s!==null&&Il(i,s.retryQueue),s=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(s=e.memoizedState.cachePool.pool),a=null,i.memoizedState!==null&&i.memoizedState.cachePool!==null&&(a=i.memoizedState.cachePool.pool),a!==s&&(i.flags|=2048),e!==null&&B(Ho),null;case 24:return s=null,e!==null&&(s=e.memoizedState.cache),i.memoizedState.cache!==s&&(i.flags|=2048),Mi(Zt),Lt(i),null;case 25:return null;case 30:return null}throw Error(l(156,i.tag))}function KS(e,i){switch(Fd(i),i.tag){case 1:return e=i.flags,e&65536?(i.flags=e&-65537|128,i):null;case 3:return Mi(Zt),pe(),e=i.flags,(e&65536)!==0&&(e&128)===0?(i.flags=e&-65537|128,i):null;case 26:case 27:case 5:return Se(i),null;case 31:if(i.memoizedState!==null){if(Nn(i),i.alternate===null)throw Error(l(340));Oo()}return e=i.flags,e&65536?(i.flags=e&-65537|128,i):null;case 13:if(Nn(i),e=i.memoizedState,e!==null&&e.dehydrated!==null){if(i.alternate===null)throw Error(l(340));Oo()}return e=i.flags,e&65536?(i.flags=e&-65537|128,i):null;case 19:return B(Vt),null;case 4:return pe(),null;case 10:return Mi(i.type),null;case 22:case 23:return Nn(i),au(),e!==null&&B(Ho),e=i.flags,e&65536?(i.flags=e&-65537|128,i):null;case 24:return Mi(Zt),null;case 25:return null;default:return null}}function um(e,i){switch(Fd(i),i.tag){case 3:Mi(Zt),pe();break;case 26:case 27:case 5:Se(i);break;case 4:pe();break;case 31:i.memoizedState!==null&&Nn(i);break;case 13:Nn(i);break;case 19:B(Vt);break;case 10:Mi(i.type);break;case 22:case 23:Nn(i),au(),e!==null&&B(Ho);break;case 24:Mi(Zt)}}function Xr(e,i){try{var s=i.updateQueue,a=s!==null?s.lastEffect:null;if(a!==null){var f=a.next;s=f;do{if((s.tag&e)===e){a=void 0;var m=s.create,z=s.inst;a=m(),z.destroy=a}s=s.next}while(s!==f)}}catch(U){vt(i,i.return,U)}}function uo(e,i,s){try{var a=i.updateQueue,f=a!==null?a.lastEffect:null;if(f!==null){var m=f.next;a=m;do{if((a.tag&e)===e){var z=a.inst,U=z.destroy;if(U!==void 0){z.destroy=void 0,f=i;var Z=s,ce=U;try{ce()}catch(be){vt(f,Z,be)}}}a=a.next}while(a!==m)}}catch(be){vt(i,i.return,be)}}function fm(e){var i=e.updateQueue;if(i!==null){var s=e.stateNode;try{ng(i,s)}catch(a){vt(e,e.return,a)}}}function pm(e,i,s){s.props=qo(e.type,e.memoizedProps),s.state=e.memoizedState;try{s.componentWillUnmount()}catch(a){vt(e,i,a)}}function Jr(e,i){try{var s=e.ref;if(s!==null){switch(e.tag){case 26:case 27:case 5:var a=e.stateNode;break;case 30:a=e.stateNode;break;default:a=e.stateNode}typeof s=="function"?e.refCleanup=s(a):s.current=a}}catch(f){vt(e,i,f)}}function xi(e,i){var s=e.ref,a=e.refCleanup;if(s!==null)if(typeof a=="function")try{a()}catch(f){vt(e,i,f)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof s=="function")try{s(null)}catch(f){vt(e,i,f)}else s.current=null}function hm(e){var i=e.type,s=e.memoizedProps,a=e.stateNode;try{e:switch(i){case"button":case"input":case"select":case"textarea":s.autoFocus&&a.focus();break e;case"img":s.src?a.src=s.src:s.srcSet&&(a.srcset=s.srcSet)}}catch(f){vt(e,e.return,f)}}function $u(e,i,s){try{var a=e.stateNode;bw(a,e.type,s,i),a[an]=i}catch(f){vt(e,e.return,f)}}function gm(e){return e.tag===5||e.tag===3||e.tag===26||e.tag===27&&yo(e.type)||e.tag===4}function Hu(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||gm(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.tag===27&&yo(e.type)||e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function Wu(e,i,s){var a=e.tag;if(a===5||a===6)e=e.stateNode,i?(s.nodeType===9?s.body:s.nodeName==="HTML"?s.ownerDocument.body:s).insertBefore(e,i):(i=s.nodeType===9?s.body:s.nodeName==="HTML"?s.ownerDocument.body:s,i.appendChild(e),s=s._reactRootContainer,s!=null||i.onclick!==null||(i.onclick=Ti));else if(a!==4&&(a===27&&yo(e.type)&&(s=e.stateNode,i=null),e=e.child,e!==null))for(Wu(e,i,s),e=e.sibling;e!==null;)Wu(e,i,s),e=e.sibling}function $l(e,i,s){var a=e.tag;if(a===5||a===6)e=e.stateNode,i?s.insertBefore(e,i):s.appendChild(e);else if(a!==4&&(a===27&&yo(e.type)&&(s=e.stateNode),e=e.child,e!==null))for($l(e,i,s),e=e.sibling;e!==null;)$l(e,i,s),e=e.sibling}function mm(e){var i=e.stateNode,s=e.memoizedProps;try{for(var a=e.type,f=i.attributes;f.length;)i.removeAttributeNode(f[0]);pn(i,a,s),i[Rt]=e,i[an]=s}catch(m){vt(e,e.return,m)}}var Oi=!1,nn=!1,Uu=!1,xm=typeof WeakSet=="function"?WeakSet:Set,ln=null;function QS(e,i){if(e=e.containerInfo,df=rc,e=Eh(e),Nd(e)){if("selectionStart"in e)var s={start:e.selectionStart,end:e.selectionEnd};else e:{s=(s=e.ownerDocument)&&s.defaultView||window;var a=s.getSelection&&s.getSelection();if(a&&a.rangeCount!==0){s=a.anchorNode;var f=a.anchorOffset,m=a.focusNode;a=a.focusOffset;try{s.nodeType,m.nodeType}catch{s=null;break e}var z=0,U=-1,Z=-1,ce=0,be=0,je=e,ue=null;t:for(;;){for(var ge;je!==s||f!==0&&je.nodeType!==3||(U=z+f),je!==m||a!==0&&je.nodeType!==3||(Z=z+a),je.nodeType===3&&(z+=je.nodeValue.length),(ge=je.firstChild)!==null;)ue=je,je=ge;for(;;){if(je===e)break t;if(ue===s&&++ce===f&&(U=z),ue===m&&++be===a&&(Z=z),(ge=je.nextSibling)!==null)break;je=ue,ue=je.parentNode}je=ge}s=U===-1||Z===-1?null:{start:U,end:Z}}else s=null}s=s||{start:0,end:0}}else s=null;for(uf={focusedElem:e,selectionRange:s},rc=!1,ln=i;ln!==null;)if(i=ln,e=i.child,(i.subtreeFlags&1028)!==0&&e!==null)e.return=i,ln=e;else for(;ln!==null;){switch(i=ln,m=i.alternate,e=i.flags,i.tag){case 0:if((e&4)!==0&&(e=i.updateQueue,e=e!==null?e.events:null,e!==null))for(s=0;s title"))),pn(m,a,s),m[Rt]=e,Bt(m),a=m;break e;case"link":var z=jx("link","href",f).get(a+(s.href||""));if(z){for(var U=0;U_t&&(z=_t,_t=Fe,Fe=z);var re=Th(U,Fe),ie=Th(U,_t);if(re&&ie&&(ge.rangeCount!==1||ge.anchorNode!==re.node||ge.anchorOffset!==re.offset||ge.focusNode!==ie.node||ge.focusOffset!==ie.offset)){var le=je.createRange();le.setStart(re.node,re.offset),ge.removeAllRanges(),Fe>_t?(ge.addRange(le),ge.extend(ie.node,ie.offset)):(le.setEnd(ie.node,ie.offset),ge.addRange(le))}}}}for(je=[],ge=U;ge=ge.parentNode;)ge.nodeType===1&&je.push({element:ge,left:ge.scrollLeft,top:ge.scrollTop});for(typeof U.focus=="function"&&U.focus(),U=0;Us?32:s,R.T=null,s=Xu,Xu=null;var m=go,z=Ui;if(sn=0,Is=go=null,Ui=0,(xt&6)!==0)throw Error(l(331));var U=xt;if(xt|=4,zm(m.current),_m(m,m.current,z,s),xt=U,na(0,!1),He&&typeof He.onPostCommitFiberRoot=="function")try{He.onPostCommitFiberRoot(ae,m)}catch{}return!0}finally{J.p=f,R.T=a,Fm(e,i)}}function Vm(e,i,s){i=Gn(s,i),i=zu(e.stateNode,i,2),e=ao(e,i,2),e!==null&&(mt(e,2),yi(e))}function vt(e,i,s){if(e.tag===3)Vm(e,e,s);else for(;i!==null;){if(i.tag===3){Vm(i,e,s);break}else if(i.tag===1){var a=i.stateNode;if(typeof i.type.getDerivedStateFromError=="function"||typeof a.componentDidCatch=="function"&&(ho===null||!ho.has(a))){e=Gn(s,e),s=Xg(2),a=ao(i,s,2),a!==null&&(Jg(s,a,i,e),mt(a,2),yi(a));break}}i=i.return}}function Zu(e,i,s){var a=e.pingCache;if(a===null){a=e.pingCache=new tw;var f=new Set;a.set(i,f)}else f=a.get(i),f===void 0&&(f=new Set,a.set(i,f));f.has(s)||(qu=!0,f.add(s),e=rw.bind(null,e,i,s),i.then(e,e))}function rw(e,i,s){var a=e.pingCache;a!==null&&a.delete(i),e.pingedLanes|=e.suspendedLanes&s,e.warmLanes&=~s,Tt===e&&(st&s)===s&&(Ft===4||Ft===3&&(st&62914560)===st&&300>Oe()-Ul?(xt&2)===0&&$s(e,0):Fu|=s,Os===st&&(Os=0)),yi(e)}function Xm(e,i){i===0&&(i=Ne()),e=No(e,i),e!==null&&(mt(e,i),yi(e))}function aw(e){var i=e.memoizedState,s=0;i!==null&&(s=i.retryLane),Xm(e,s)}function lw(e,i){var s=0;switch(e.tag){case 31:case 13:var a=e.stateNode,f=e.memoizedState;f!==null&&(s=f.retryLane);break;case 19:a=e.stateNode;break;case 22:a=e.stateNode._retryCache;break;default:throw Error(l(314))}a!==null&&a.delete(i),Xm(e,s)}function cw(e,i){return Ve(e,i)}var Xl=null,Ws=null,ef=!1,Jl=!1,tf=!1,xo=0;function yi(e){e!==Ws&&e.next===null&&(Ws===null?Xl=Ws=e:Ws=Ws.next=e),Jl=!0,ef||(ef=!0,uw())}function na(e,i){if(!tf&&Jl){tf=!0;do for(var s=!1,a=Xl;a!==null;){if(e!==0){var f=a.pendingLanes;if(f===0)var m=0;else{var z=a.suspendedLanes,U=a.pingedLanes;m=(1<<31-ut(42|e)+1)-1,m&=f&~(z&~U),m=m&201326741?m&201326741|1:m?m|2:0}m!==0&&(s=!0,Zm(a,m))}else m=st,m=Pt(a,a===Tt?m:0,a.cancelPendingCommit!==null||a.timeoutHandle!==-1),(m&3)===0||Ct(a,m)||(s=!0,Zm(a,m));a=a.next}while(s);tf=!1}}function dw(){Jm()}function Jm(){Jl=ef=!1;var e=0;xo!==0&&Sw()&&(e=xo);for(var i=Oe(),s=null,a=Xl;a!==null;){var f=a.next,m=Km(a,i);m===0?(a.next=null,s===null?Xl=f:s.next=f,f===null&&(Ws=s)):(s=a,(e!==0||(m&3)!==0)&&(Jl=!0)),a=f}sn!==0&&sn!==5||na(e),xo!==0&&(xo=0)}function Km(e,i){for(var s=e.suspendedLanes,a=e.pingedLanes,f=e.expirationTimes,m=e.pendingLanes&-62914561;0U)break;var be=Z.transferSize,je=Z.initiatorType;be&&ax(je)&&(Z=Z.responseEnd,z+=be*(Z"u"?null:document;function bx(e,i,s){var a=Us;if(a&&typeof i=="string"&&i){var f=At(i);f='link[rel="'+e+'"][href="'+f+'"]',typeof s=="string"&&(f+='[crossorigin="'+s+'"]'),yx.has(f)||(yx.add(f),e={rel:e,crossOrigin:s,href:i},a.querySelector(f)===null&&(i=a.createElement("link"),pn(i,"link",e),Bt(i),a.head.appendChild(i)))}}function Rw(e){Gi.D(e),bx("dns-prefetch",e,null)}function Aw(e,i){Gi.C(e,i),bx("preconnect",e,i)}function Mw(e,i,s){Gi.L(e,i,s);var a=Us;if(a&&e&&i){var f='link[rel="preload"][as="'+At(i)+'"]';i==="image"&&s&&s.imageSrcSet?(f+='[imagesrcset="'+At(s.imageSrcSet)+'"]',typeof s.imageSizes=="string"&&(f+='[imagesizes="'+At(s.imageSizes)+'"]')):f+='[href="'+At(e)+'"]';var m=f;switch(i){case"style":m=Gs(e);break;case"script":m=Ps(e)}Xn.has(m)||(e=y({rel:"preload",href:i==="image"&&s&&s.imageSrcSet?void 0:e,as:i},s),Xn.set(m,e),a.querySelector(f)!==null||i==="style"&&a.querySelector(ra(m))||i==="script"&&a.querySelector(aa(m))||(i=a.createElement("link"),pn(i,"link",e),Bt(i),a.head.appendChild(i)))}}function Dw(e,i){Gi.m(e,i);var s=Us;if(s&&e){var a=i&&typeof i.as=="string"?i.as:"script",f='link[rel="modulepreload"][as="'+At(a)+'"][href="'+At(e)+'"]',m=f;switch(a){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":m=Ps(e)}if(!Xn.has(m)&&(e=y({rel:"modulepreload",href:e},i),Xn.set(m,e),s.querySelector(f)===null)){switch(a){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(s.querySelector(aa(m)))return}a=s.createElement("link"),pn(a,"link",e),Bt(a),s.head.appendChild(a)}}}function Lw(e,i,s){Gi.S(e,i,s);var a=Us;if(a&&e){var f=pi(a).hoistableStyles,m=Gs(e);i=i||"default";var z=f.get(m);if(!z){var U={loading:0,preload:null};if(z=a.querySelector(ra(m)))U.loading=5;else{e=y({rel:"stylesheet",href:e,"data-precedence":i},s),(s=Xn.get(m))&&yf(e,s);var Z=z=a.createElement("link");Bt(Z),pn(Z,"link",e),Z._p=new Promise(function(ce,be){Z.onload=ce,Z.onerror=be}),Z.addEventListener("load",function(){U.loading|=1}),Z.addEventListener("error",function(){U.loading|=2}),U.loading|=4,tc(z,i,a)}z={type:"stylesheet",instance:z,count:1,state:U},f.set(m,z)}}}function Nw(e,i){Gi.X(e,i);var s=Us;if(s&&e){var a=pi(s).hoistableScripts,f=Ps(e),m=a.get(f);m||(m=s.querySelector(aa(f)),m||(e=y({src:e,async:!0},i),(i=Xn.get(f))&&bf(e,i),m=s.createElement("script"),Bt(m),pn(m,"link",e),s.head.appendChild(m)),m={type:"script",instance:m,count:1,state:null},a.set(f,m))}}function Bw(e,i){Gi.M(e,i);var s=Us;if(s&&e){var a=pi(s).hoistableScripts,f=Ps(e),m=a.get(f);m||(m=s.querySelector(aa(f)),m||(e=y({src:e,async:!0,type:"module"},i),(i=Xn.get(f))&&bf(e,i),m=s.createElement("script"),Bt(m),pn(m,"link",e),s.head.appendChild(m)),m={type:"script",instance:m,count:1,state:null},a.set(f,m))}}function vx(e,i,s,a){var f=(f=K.current)?ec(f):null;if(!f)throw Error(l(446));switch(e){case"meta":case"title":return null;case"style":return typeof s.precedence=="string"&&typeof s.href=="string"?(i=Gs(s.href),s=pi(f).hoistableStyles,a=s.get(i),a||(a={type:"style",instance:null,count:0,state:null},s.set(i,a)),a):{type:"void",instance:null,count:0,state:null};case"link":if(s.rel==="stylesheet"&&typeof s.href=="string"&&typeof s.precedence=="string"){e=Gs(s.href);var m=pi(f).hoistableStyles,z=m.get(e);if(z||(f=f.ownerDocument||f,z={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},m.set(e,z),(m=f.querySelector(ra(e)))&&!m._p&&(z.instance=m,z.state.loading=5),Xn.has(e)||(s={rel:"preload",as:"style",href:s.href,crossOrigin:s.crossOrigin,integrity:s.integrity,media:s.media,hrefLang:s.hrefLang,referrerPolicy:s.referrerPolicy},Xn.set(e,s),m||Ow(f,e,s,z.state))),i&&a===null)throw Error(l(528,""));return z}if(i&&a!==null)throw Error(l(529,""));return null;case"script":return i=s.async,s=s.src,typeof s=="string"&&i&&typeof i!="function"&&typeof i!="symbol"?(i=Ps(s),s=pi(f).hoistableScripts,a=s.get(i),a||(a={type:"script",instance:null,count:0,state:null},s.set(i,a)),a):{type:"void",instance:null,count:0,state:null};default:throw Error(l(444,e))}}function Gs(e){return'href="'+At(e)+'"'}function ra(e){return'link[rel="stylesheet"]['+e+"]"}function Sx(e){return y({},e,{"data-precedence":e.precedence,precedence:null})}function Ow(e,i,s,a){e.querySelector('link[rel="preload"][as="style"]['+i+"]")?a.loading=1:(i=e.createElement("link"),a.preload=i,i.addEventListener("load",function(){return a.loading|=1}),i.addEventListener("error",function(){return a.loading|=2}),pn(i,"link",s),Bt(i),e.head.appendChild(i))}function Ps(e){return'[src="'+At(e)+'"]'}function aa(e){return"script[async]"+e}function wx(e,i,s){if(i.count++,i.instance===null)switch(i.type){case"style":var a=e.querySelector('style[data-href~="'+At(s.href)+'"]');if(a)return i.instance=a,Bt(a),a;var f=y({},s,{"data-href":s.href,"data-precedence":s.precedence,href:null,precedence:null});return a=(e.ownerDocument||e).createElement("style"),Bt(a),pn(a,"style",f),tc(a,s.precedence,e),i.instance=a;case"stylesheet":f=Gs(s.href);var m=e.querySelector(ra(f));if(m)return i.state.loading|=4,i.instance=m,Bt(m),m;a=Sx(s),(f=Xn.get(f))&&yf(a,f),m=(e.ownerDocument||e).createElement("link"),Bt(m);var z=m;return z._p=new Promise(function(U,Z){z.onload=U,z.onerror=Z}),pn(m,"link",a),i.state.loading|=4,tc(m,s.precedence,e),i.instance=m;case"script":return m=Ps(s.src),(f=e.querySelector(aa(m)))?(i.instance=f,Bt(f),f):(a=s,(f=Xn.get(m))&&(a=y({},s),bf(a,f)),e=e.ownerDocument||e,f=e.createElement("script"),Bt(f),pn(f,"link",a),e.head.appendChild(f),i.instance=f);case"void":return null;default:throw Error(l(443,i.type))}else i.type==="stylesheet"&&(i.state.loading&4)===0&&(a=i.instance,i.state.loading|=4,tc(a,s.precedence,e));return i.instance}function tc(e,i,s){for(var a=s.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),f=a.length?a[a.length-1]:null,m=f,z=0;z title"):null)}function Iw(e,i,s){if(s===1||i.itemProp!=null)return!1;switch(e){case"meta":case"title":return!0;case"style":if(typeof i.precedence!="string"||typeof i.href!="string"||i.href==="")break;return!0;case"link":if(typeof i.rel!="string"||typeof i.href!="string"||i.href===""||i.onLoad||i.onError)break;switch(i.rel){case"stylesheet":return e=i.disabled,typeof i.precedence=="string"&&e==null;default:return!0}case"script":if(i.async&&typeof i.async!="function"&&typeof i.async!="symbol"&&!i.onLoad&&!i.onError&&i.src&&typeof i.src=="string")return!0}return!1}function _x(e){return!(e.type==="stylesheet"&&(e.state.loading&3)===0)}function $w(e,i,s,a){if(s.type==="stylesheet"&&(typeof a.media!="string"||matchMedia(a.media).matches!==!1)&&(s.state.loading&4)===0){if(s.instance===null){var f=Gs(a.href),m=i.querySelector(ra(f));if(m){i=m._p,i!==null&&typeof i=="object"&&typeof i.then=="function"&&(e.count++,e=ic.bind(e),i.then(e,e)),s.state.loading|=4,s.instance=m,Bt(m);return}m=i.ownerDocument||i,a=Sx(a),(f=Xn.get(f))&&yf(a,f),m=m.createElement("link"),Bt(m);var z=m;z._p=new Promise(function(U,Z){z.onload=U,z.onerror=Z}),pn(m,"link",a),s.instance=m}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(s,i),(i=s.state.preload)&&(s.state.loading&3)===0&&(e.count++,s=ic.bind(e),i.addEventListener("load",s),i.addEventListener("error",s))}}var vf=0;function Hw(e,i){return e.stylesheets&&e.count===0&&sc(e,e.stylesheets),0vf?50:800)+i);return e.unsuspend=s,function(){e.unsuspend=null,clearTimeout(a),clearTimeout(f)}}:null}function ic(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)sc(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}}var oc=null;function sc(e,i){e.stylesheets=null,e.unsuspend!==null&&(e.count++,oc=new Map,i.forEach(Ww,e),oc=null,ic.call(e))}function Ww(e,i){if(!(i.state.loading&4)){var s=oc.get(e);if(s)var a=s.get(null);else{s=new Map,oc.set(e,s);for(var f=e.querySelectorAll("link[data-precedence],style[data-precedence]"),m=0;m"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(t)}catch(o){console.error(o)}}return t(),Ef.exports=i2(),Ef.exports}var s2=o2();const us="/api/v1";function r2(t,o,r=""){const l=`HTTP ${t}${r?" "+r:""}`;if(!o)return l;let c;try{c=JSON.parse(o)}catch{return`${l}: ${o.slice(0,200)}`}if(c&&typeof c=="object"){const d=c,u=d.detail;if(typeof u=="string")return u;if(Array.isArray(u)){const p=u.map(g=>{if(g&&typeof g=="object"){const h=g,b=Array.isArray(h.loc)?h.loc.filter(v=>v!=="body").join("."):"",y=typeof h.msg=="string"?h.msg:JSON.stringify(g);return b?`${b}: ${y}`:y}return String(g)}).filter(Boolean);if(p.length)return p.join("; ")}if(typeof d.message=="string")return d.message;if(typeof d.error=="string")return d.error}return`${l}: ${o.slice(0,200)}`}function fb(t,o,r,l,c){const d=r2(r,c,l),u=new Error(`${t} ${o} — ${d}`);return u.status=r,u.body=c,u}async function me(t,o,r,l){const c={method:t,headers:{"Content-Type":"application/json"},signal:l};r!==void 0&&(c.body=JSON.stringify(r));const d=await fetch(`${us}${o}`,c);if(!d.ok){const u=await d.text().catch(()=>"");throw fb(t,o,d.status,d.statusText,u)}return d.json()}const a2={sequences:"#059669",freq_map:"#2563eb",profiles:"#7c3aed",clusters:"#d97706",number:"#dc2626",text:"#0d9488",json:"#4f46e5",any:"#64748b",claims:"#b45309",papers:"#0891b2"},l2=()=>me("GET","/experiment-graphs/catalog"),pb=()=>me("GET","/experiment-graphs"),Xx=t=>me("GET",`/experiment-graphs/${t}`),Df=t=>me("POST","/experiment-graphs",t),c2=(t,o)=>me("PUT",`/experiment-graphs/${t}`,o),d2=t=>me("DELETE",`/experiment-graphs/${t}`),Ba=()=>me("GET","/health"),u2=()=>me("GET","/status"),ad=()=>me("GET","/texts"),f2=t=>me("GET",`/texts/${t}`),p2=t=>me("POST","/texts",t),h2=(t,o)=>me("PUT",`/texts/${t}`,o),g2=t=>me("DELETE",`/texts/${t}`),m2=(t,o,r=!0)=>me("POST",`/texts/${t}/detect-direction`,{words:null,update_field:r}),Oa=()=>me("GET","/jobs"),qc=t=>me("POST","/jobs",t),up=t=>me("DELETE",`/jobs/${t}`),fp=(t=!1)=>me("DELETE",t?"/jobs?finished_only=true":"/jobs"),hb=t=>me("POST",`/jobs/${t}/pause`),gb=t=>me("POST",`/jobs/${t}/resume`),mb=()=>me("POST","/jobs/pause-all"),xb=()=>me("POST","/jobs/resume-all"),x2=()=>me("POST","/jobs/clear-cache");function y2(){localStorage.removeItem("geb_run_cache"),localStorage.removeItem("glossa_seq_run_queue"),localStorage.removeItem("glossa_dashboard_insight_v2")}const yb=t=>me("GET",`/jobs/${t}/results`),ld=()=>me("GET","/settings"),b2=(t,o)=>me("POST","/settings/verify-key",{key_name:t,key_value:null}),sr=t=>me("PUT","/settings",t),v2=()=>me("GET","/catalog"),bb=()=>me("GET","/catalog/pipelines"),S2=t=>me("GET",`/reports${t?`?project_id=${t}`:""}`),w2=t=>me("DELETE",`/reports/${t}`),Lf=t=>`/api/v1/reports/${t}/download`,j2=()=>me("GET","/reports/templates"),k2=t=>me("POST","/reports/generate",{template_id:t}),_2=t=>me("POST",`/reports/${t}/open-folder`),C2=(t,o)=>me("POST",`/pipelines/${t}/duplicate`,{new_id:o}),T2=t=>me("DELETE",`/pipelines/${t}`),z2=t=>me("POST","/pipelines/import",{source_path:t}),Op=()=>me("GET","/studies");async function*E2(t,o){if(!t.ok){const d=await t.text().catch(()=>"");throw fb("POST",new URL(t.url).pathname,t.status,t.statusText,d)}const r=t.body.getReader(),l=new TextDecoder;let c="";try{for(;!(o!=null&&o.aborted);){const{done:d,value:u}=await r.read();if(d)break;c+=l.decode(u,{stream:!0});const p=c.split(` +`);c=p.pop()??"";for(const g of p)if(g.startsWith("data: ")&&g.length>6)try{yield JSON.parse(g.slice(6))}catch{}}}finally{r.releaseLock()}}async function*pp(t,o={},r,l=!1){const c=await fetch(`${us}/experiment-graphs/${t}/run`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({kwargs:o,notify:l}),signal:r});yield*E2(c,r)}const Ip=()=>me("GET","/experiments"),Bc=t=>me("GET",`/texts/${t}/entropy`),R2=(t,o=2,r=50)=>me("GET",`/texts/${t}/ngrams?n=${o}&limit=${r}`),A2=(t,o,r=5)=>me("GET",`/texts/${t}/concordance?q=${encodeURIComponent(o)}&w=${r}`),Jx=(t,o)=>`/api/v1/texts/${t}/export?fmt=${o}`,M2=t=>me("GET",`/hypotheses${t?`?project_id=${t}`:""}`),za=t=>me("POST","/hypotheses",t),ka=(t,o)=>me("PUT",`/hypotheses/${t}`,o),D2=t=>me("DELETE",`/hypotheses/${t}`),L2=t=>me("GET",`/notebooks${t?`?project_id=${t}`:""}`),N2=t=>me("POST","/notebooks",t),B2=(t,o)=>me("PUT",`/notebooks/${t}`,o),O2=t=>me("DELETE",`/notebooks/${t}`),I2=()=>me("GET","/citations"),Kx=t=>me("POST","/citations",t),$2=(t,o)=>me("PUT",`/citations/${t}`,o),H2=t=>me("DELETE",`/citations/${t}`),hp=(t,o)=>me("POST","/ai/chat",t,o),vb=t=>me("POST","/ai/execute-action",t),W2=t=>me("POST","/ai/decipher",t),U2=t=>me("POST","/ai/draft-section",t),Sb=t=>me("POST","/ai/hypotheses/generate",t),wb=t=>me("POST","/ai/experiment-chain",t),G2=t=>me("POST","/ai/synthesize",t),P2=t=>me("POST","/ai/sign-reading",t),q2=()=>me("GET","/ai/research-context"),jb=t=>me("POST","/ai/report-synthesis",t),F2=()=>me("POST","/system/peaks/clear"),Y2=()=>"/api/v1/system/metrics/stream",V2=()=>me("GET","/ollama/library"),X2=()=>me("GET","/ollama/recommend"),J2=t=>me("DELETE",`/ollama/models/${encodeURIComponent(t)}`),K2="glossa_ollama_ctx",Q2=()=>parseInt(localStorage.getItem(K2)??"4096",10)||4096,Z2=()=>me("GET","/report-templates"),ej=t=>me("POST","/report-templates",t),tj=t=>me("DELETE",`/report-templates/${t}`),nj=t=>me("GET","/anchor-sets"),ij=t=>me("POST","/anchor-sets",t),oj=t=>me("DELETE",`/anchor-sets/${t}`),kb=t=>{const r=new URLSearchParams().toString();return me("GET",`/corpus-catalogue${r?`?${r}`:""}`)},sj=t=>me("POST",`/corpus-catalogue/${t}/import`),_b=()=>me("GET","/env/status"),rj=()=>me("GET","/env/packages"),aj=()=>fetch(`${us}/env/setup`,{method:"POST"}),lj=()=>fetch(`${us}/env/rebuild`,{method:"POST"}),cj=()=>fetch(`${us}/env/upgrade`,{method:"POST"}),dj=()=>"/api/v1/terminal/log/stream",uj=()=>me("POST","/terminal/log/purge"),fj=(t,o)=>fetch(`${us}/terminal/run`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({command:t,cwd:o,use_venv:!0})});function pj(t){const o=new URLSearchParams;for(const[l,c]of Object.entries(t))c==null||c===""||o.set(l,String(c));const r=o.toString();return r?`?${r}`:""}const hj=(t={})=>me("GET",`/discovery/items${pj(t)}`),gj=(t,o,r)=>me("POST",`/discovery/items/${encodeURIComponent(t)}/status`,{status:o,notes:r}),Cb=()=>me("GET","/discovery/topics"),Tb=()=>me("GET","/discovery/sources"),Nf=(t="status")=>me("GET",`/discovery/stats?group=${t}`),Fc=t=>me("POST","/discovery/fetch",t),$p=t=>me("POST","/discovery/mine",t),mj=(t={})=>{const o=new URLSearchParams;t.days!==void 0&&o.set("days",String(t.days)),t.limit!==void 0&&o.set("limit",String(t.limit)),t.include_ai!==void 0&&o.set("include_ai",String(t.include_ai)),t.project_id&&o.set("project_id",t.project_id);const r=o.toString();return me("GET",`/dashboard/highlights${r?"?"+r:""}`)},xj=(t={})=>{const o=new URLSearchParams;t.days!==void 0&&o.set("days",String(t.days)),t.limit!==void 0&&o.set("limit",String(t.limit)),t.project_id&&o.set("project_id",t.project_id);const r=o.toString();return me("POST",`/dashboard/insight${r?"?"+r:""}`)},yj=()=>me("GET","/dashboard/decipherment"),bj=()=>me("GET","/dashboard/latest-insight"),vj=()=>me("GET","/notifications/recipients"),Sj=t=>me("POST","/notifications/recipients",t),Qx=(t,o)=>me("PATCH",`/notifications/recipients/${encodeURIComponent(t)}`,o),wj=t=>me("DELETE",`/notifications/recipients/${encodeURIComponent(t)}`),zb=()=>me("GET","/notifications/status"),jj=(t=100)=>me("GET",`/notifications/log?limit=${t}`),kj=()=>me("POST","/notifications/test"),_j=()=>me("POST","/notifications/graph/start"),Cj=t=>me("POST","/notifications/graph/poll",{session_id:t}),Tj=()=>me("POST","/notifications/graph/disconnect"),Eb=()=>me("GET","/discovery/scheduler/status"),Rb=()=>me("POST","/discovery/scheduler/start"),Ab=()=>me("POST","/discovery/scheduler/stop"),Mb=()=>me("GET","/projects"),zj=()=>me("GET","/projects/active"),pc=(t,o)=>me("PUT",`/projects/${t}`,o),Db=t=>me("POST",`/projects/${t}/activate`),Ej=t=>me("DELETE",`/projects/${t}`),Rj=t=>me("GET",`/correspondences${t?`?project_id=${t}`:""}`),Zx=t=>me("POST","/correspondences",t),ey=(t,o)=>me("PUT",`/correspondences/${t}`,o),Aj=t=>me("DELETE",`/correspondences/${t}`),Mj=t=>me("POST","/correspondences/parse",t),Lb=(t=!1,o)=>{const r=new URLSearchParams;t&&r.set("enabled_only","true");const l=r.toString();return me("GET",`/providers${l?`?${l}`:""}`)},Dj=t=>me("POST","/providers",t),ty=(t,o)=>me("PATCH",`/providers/${t}`,o),Lj=t=>me("DELETE",`/providers/${t}`),Nj=t=>me("POST",`/providers/${t}/test`),Bj=()=>me("GET","/providers/detect-ollama"),Oj=()=>me("GET","/providers/cloud-providers"),Ij=()=>me("GET","/model-assignments"),$j=(t,o)=>me("PUT",`/model-assignments/${t}`,o),Hj=(t="mixed")=>me("POST",`/model-assignments/auto-configure?profile=${t}`),Nb=t=>me("GET","/model-intelligence/scores"),Bb=()=>me("POST","/model-intelligence/sync"),Wj=()=>me("POST","/model-intelligence/test-hf"),Bf=[{id:"outlook365_oauth",label:"Outlook 365 (Microsoft Graph OAuth) — recommended",category:"oauth",recommended:!0,notes:"Modern SSO via device-code flow. Works with personal and work/school accounts. No app password needed."},{id:"resend_api",label:"Resend (HTTPS API) — no SMTP, no mailbox, no domain",category:"api",recommended:!0,notes:"Sign up at resend.com, generate an API key, paste it here. Sends from onboarding@resend.dev (free, 100/day, 3000/month) without any DNS setup. Verify your own domain in Resend later for branded From: addresses."},{id:"microsoft365_smtp",label:"Microsoft 365 SMTP (legacy / basic auth)",category:"smtp",smtp_host:"smtp.office365.com",smtp_port:587,smtp_use_tls:!0,notes:"Only works if your tenant still allows SMTP AUTH. Most do not — use the OAuth option above instead."},{id:"outlook_com",label:"Outlook.com / Hotmail / Live",category:"smtp",smtp_host:"smtp-mail.outlook.com",smtp_port:587,smtp_use_tls:!0,notes:"Use your full email as username and an app password (account.live.com → Security → App passwords)."},{id:"gmail",label:"Gmail / Google Workspace",category:"smtp",smtp_host:"smtp.gmail.com",smtp_port:587,smtp_use_tls:!0,notes:"Requires an app password (myaccount.google.com → Security → 2-Step Verification → App passwords)."},{id:"yahoo",label:"Yahoo Mail",category:"smtp",smtp_host:"smtp.mail.yahoo.com",smtp_port:587,smtp_use_tls:!0,notes:"Requires an app password (login.yahoo.com → Account Security → Generate app password)."},{id:"icloud",label:"Apple iCloud Mail",category:"smtp",smtp_host:"smtp.mail.me.com",smtp_port:587,smtp_use_tls:!0,notes:"Requires an app-specific password (appleid.apple.com → Sign-In and Security → App-Specific Passwords)."},{id:"zoho",label:"Zoho Mail",category:"smtp",smtp_host:"smtp.zoho.com",smtp_port:587,smtp_use_tls:!0,notes:"For zoho.eu users use smtp.zoho.eu. Generate an app-specific password in your Zoho Mail account."},{id:"infomaniak",label:"Infomaniak (incl. swissmail.io)",category:"smtp",smtp_host:"mail.infomaniak.com",smtp_port:465,smtp_use_tls:!0,notes:"Common Swiss research provider. Port 465 = SSL on connect; some setups also allow 587 STARTTLS."},{id:"protonmail_bridge",label:"ProtonMail (Bridge)",category:"smtp",smtp_host:"127.0.0.1",smtp_port:1025,smtp_use_tls:!0,notes:"Run ProtonMail Bridge locally; it exposes a local SMTP relay on 127.0.0.1:1025."},{id:"sendgrid",label:"SendGrid",category:"smtp",smtp_host:"smtp.sendgrid.net",smtp_port:587,smtp_use_tls:!0,notes:"Use 'apikey' as the username and your SendGrid API key as the password."},{id:"mailgun",label:"Mailgun",category:"smtp",smtp_host:"smtp.mailgun.org",smtp_port:587,smtp_use_tls:!0,notes:"Use the SMTP credentials shown in your Mailgun domain dashboard."},{id:"university",label:"University / research-institution SMTP",category:"smtp",smtp_port:587,smtp_use_tls:!0,notes:"Most universities expose smtp..edu on port 587 STARTTLS. Check your IT pages — some require VPN or institutional MFA app passwords."},{id:"custom",label:"Custom SMTP",category:"smtp",smtp_port:587,smtp_use_tls:!0,notes:"Fill in your provider's host, port, and TLS settings manually."}],Uj=(t={})=>{const o=new URLSearchParams;t.q&&o.set("q",t.q),t.status&&o.set("status",t.status),t.limit!==void 0&&o.set("limit",String(t.limit)),t.offset!==void 0&&o.set("offset",String(t.offset));const r=o.toString();return me("GET",`/indus-evidence/library${r?`?${r}`:""}`)},Gj=(t={})=>{const o=new URLSearchParams;Object.entries(t).forEach(([l,c])=>{c!==void 0&&c!==""&&o.set(l,String(c))});const r=o.toString();return me("GET",`/indus-evidence/claims${r?`?${r}`:""}`)},Pj=()=>me("GET","/indus-evidence/hypotheses"),qj=()=>me("GET","/indus-evidence/sweep/config"),Fj=t=>me("PUT","/indus-evidence/sweep/config",t),Yj=()=>me("POST","/indus-evidence/sweep/run"),Vj=()=>me("GET","/indus-evidence/sweep/candidates"),Ob=t=>me("POST","/indus-evidence/sweep/intake",t),Xj=t=>me("POST","/indus-evidence/import-url",t),Jj=()=>me("POST","/indus-evidence/intake/run"),Kj=t=>{const o=new FormData;return o.append("file",t),fetch(`${us}/indus-evidence/upload`,{method:"POST",body:o})},Qj=()=>me("GET","/signs/summary"),Zj=(t={})=>{const o=new URLSearchParams;t.deciphered!==void 0&&o.set("deciphered",String(t.deciphered)),t.confidence&&o.set("confidence",t.confidence),t.in_corpus!==void 0&&o.set("in_corpus",String(t.in_corpus)),t.search&&o.set("search",t.search),t.limit!==void 0&&o.set("limit",String(t.limit)),t.offset!==void 0&&o.set("offset",String(t.offset));const r=o.toString();return me("GET",`/signs${r?`?${r}`:""}`)},Ib=x.createContext({toast:()=>{},notifications:[],unreadCount:0,markAllRead:()=>{},clearNotification:()=>{},clearAllNotifications:()=>{}});let ek=0;function tk({children:t}){const[o,r]=x.useState([]),[l,c]=x.useState([]),d=x.useRef(new Map),u=x.useCallback(w=>{r(_=>_.filter(C=>C.id!==w));const j=d.current.get(w);j&&(clearTimeout(j),d.current.delete(w))},[]),p=x.useCallback((w,j="info",_=3500)=>{const C=++ek;r(E=>[...E.slice(-5),{id:C,message:w,type:j}]),c(E=>[{id:C,message:w,type:j,timestamp:Date.now(),read:!1},...E.slice(0,99)]);const S=setTimeout(()=>u(C),_);d.current.set(C,S)},[u]),g=x.useCallback(()=>c(w=>w.map(j=>({...j,read:!0}))),[]),h=x.useCallback(w=>c(j=>j.filter(_=>_.id!==w)),[]),b=x.useCallback(()=>c([]),[]),y=l.filter(w=>!w.read).length;x.useEffect(()=>()=>{d.current.forEach(clearTimeout)},[]);const v={success:"#16a34a",error:"#dc2626",info:"#2563eb",warning:"#d97706"};return n.jsxs(Ib.Provider,{value:{toast:p,notifications:l,unreadCount:y,markAllRead:g,clearNotification:h,clearAllNotifications:b},children:[t,n.jsx("div",{style:{position:"fixed",bottom:20,right:20,display:"flex",flexDirection:"column",gap:8,zIndex:9999,pointerEvents:"none"},children:o.map(w=>n.jsxs("div",{style:{background:v[w.type],color:"#fff",padding:"10px 16px",borderRadius:8,fontSize:13,fontWeight:500,boxShadow:"0 4px 16px rgba(0,0,0,0.18)",display:"flex",alignItems:"center",gap:10,pointerEvents:"auto",cursor:"pointer",animation:"slideIn 0.2s ease",maxWidth:360},onClick:()=>u(w.id),children:[n.jsx("span",{style:{flex:1},children:w.message}),n.jsx("span",{style:{opacity:.7,fontSize:16,flexShrink:0},children:"×"})]},w.id))}),n.jsx("style",{children:"@keyframes slideIn{from{transform:translateX(100%);opacity:0}to{transform:translateX(0);opacity:1}}"})]})}function nt(){return x.useContext(Ib)}const nk=60;function Vo({value:t,max:o=100,label:r,sub:l="",color:c="#2563eb",peak:d}){const u=Math.min(100,t/o*100),p=d!==void 0?Math.min(100,d/o*100):void 0,g=u>80,b=u>95?"#dc2626":g?"#d97706":c;return n.jsxs("div",{style:{padding:"12px 14px",borderRadius:8,border:"1px solid #e5e7eb",background:"#fafafa",flex:1,minWidth:140},children:[n.jsx("div",{style:{fontSize:10,fontWeight:700,color:"#9ca3af",textTransform:"uppercase",letterSpacing:.5,marginBottom:6},children:r}),n.jsxs("div",{style:{fontSize:22,fontWeight:800,color:b,fontFamily:"monospace",marginBottom:4,lineHeight:1},children:[t.toFixed(t<10?1:0),n.jsx("span",{style:{fontSize:11,fontWeight:400,color:"#9ca3af",marginLeft:2},children:o===100?"%":""})]}),l&&n.jsx("div",{style:{fontSize:11,color:"#6b7280",marginBottom:6},children:l}),n.jsxs("div",{style:{height:5,background:"#f3f4f6",borderRadius:3,overflow:"visible",position:"relative"},children:[n.jsx("div",{style:{height:"100%",width:`${u}%`,background:b,borderRadius:3,transition:"width 0.4s ease"}}),p!==void 0&&n.jsx("div",{style:{position:"absolute",top:-1,left:`${p}%`,width:2,height:7,background:"#9ca3af",borderRadius:1,transform:"translateX(-50%)"},title:`Peak: ${d==null?void 0:d.toFixed(1)}`})]}),p!==void 0&&n.jsxs("div",{style:{fontSize:10,color:"#9ca3af",marginTop:3},children:["Peak ",d==null?void 0:d.toFixed(1),o===100?"%":""]})]})}function Xo({values:t,color:o="#2563eb",height:r=32}){if(t.length<2)return n.jsx("div",{style:{height:r}});const l=Math.max(...t,1),c=200,d=c/(t.length-1),u=t.map((p,g)=>`${g*d},${r-p/l*(r-2)-1}`).join(" ");return n.jsxs("svg",{viewBox:`0 0 ${c} ${r}`,style:{width:"100%",height:r,display:"block"},children:[n.jsx("polyline",{points:u,fill:"none",stroke:o,strokeWidth:1.5,opacity:.8}),n.jsx("circle",{cx:(t.length-1)*d,cy:r-t[t.length-1]/l*(r-2)-1,r:2.5,fill:o})]})}function Fs({label:t,current:o,unit:r,peak:l,color:c="#6b7280"}){return n.jsxs("div",{style:{display:"flex",gap:8,padding:"4px 0",borderBottom:"1px solid #f3f4f6",alignItems:"center",fontSize:12},children:[n.jsx("span",{style:{color:"#9ca3af",width:120,flexShrink:0},children:t}),n.jsxs("span",{style:{fontFamily:"monospace",fontWeight:600,color:c},children:[o,n.jsx("span",{style:{color:"#9ca3af",marginLeft:2,fontSize:10},children:r})]}),l&&n.jsxs("span",{style:{marginLeft:"auto",fontSize:10,color:"#9ca3af"},children:["↑ ",l,r]})]})}function ik({values:t}){return n.jsx("div",{style:{display:"flex",flexWrap:"wrap",gap:3,marginTop:8},children:t.map((o,r)=>{const l=o>80?"#dc2626":o>50?"#d97706":"#16a34a";return n.jsx("div",{title:`Core ${r}: ${o}%`,style:{width:20,height:20,borderRadius:3,background:l+"20",border:`1px solid ${l}40`,display:"flex",alignItems:"center",justifyContent:"center",fontSize:7,fontWeight:700,color:l},children:Math.round(o)},r)})})}function ok(){const{toast:t}=nt(),[o,r]=x.useState(null),[l,c]=x.useState(null),[d,u]=x.useState(null),[p,g]=x.useState(null),[h,b]=x.useState(null),[y,v]=x.useState(null),[w,j]=x.useState(!1),_=x.useRef({cpu:[],ram:[],gpu:[],disk_read:[],disk_write:[],net_send:[],net_recv:[]}),C=x.useCallback((P,F)=>{const W=_.current[P]??[];W.push(F),W.length>nk&&W.shift(),_.current[P]=W},[]);x.useEffect(()=>{const P=async()=>{try{const[W,M]=await Promise.all([Ba(),u2()]);r(W),c(M),v(null),v2().then(u).catch(()=>{}),Op().then(V=>g(V.length)).catch(()=>{})}catch(W){v(W instanceof Error?W.message:"Connection failed")}};P();const F=setInterval(P,8e3);return()=>clearInterval(F)},[]);const S=x.useRef(null),[E,k]=x.useState(!1),D=x.useCallback(()=>{if(S.current)return;const P=new EventSource(Y2());S.current=P,k(!0),P.onmessage=F=>{var W;try{const M=JSON.parse(F.data);b(M),C("cpu",M.cpu.percent),C("ram",M.ram.percent),C("gpu",((W=M.gpu[0])==null?void 0:W.utilization_pct)??0),C("disk_read",M.disk.read_mbps),C("disk_write",M.disk.write_mbps),C("net_send",M.network.send_mbps*1e3),C("net_recv",M.network.recv_mbps*1e3)}catch{}},P.onerror=()=>{P.close(),S.current=null,k(!1),setTimeout(D,3e3)}},[C]);x.useEffect(()=>(D(),()=>{var P;(P=S.current)==null||P.close(),S.current=null}),[D]);const H=async()=>{j(!0);try{await F2(),t("Peaks cleared","success")}catch{t("Failed to clear peaks","error")}finally{j(!1)}},G=(o==null?void 0:o.status)==="healthy",T=h;return n.jsxs("div",{children:[n.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:"1rem"},children:[n.jsx("h2",{style:{margin:0},children:"System Status"}),n.jsxs("div",{style:{display:"flex",gap:8,alignItems:"center"},children:[E&&n.jsxs("span",{style:{fontSize:11,color:"#16a34a",display:"flex",alignItems:"center",gap:4},children:[n.jsx("span",{style:{width:7,height:7,borderRadius:"50%",background:"#16a34a",display:"inline-block",animation:"healthPulse 1.5s infinite"}}),"Live"]}),n.jsx("button",{onClick:H,disabled:w,style:{padding:"4px 12px",border:"1px solid #e5e7eb",borderRadius:4,background:"#f9fafb",cursor:"pointer",fontSize:12,color:"#6b7280"},children:w?"…":"Clear Peaks"})]})]}),n.jsx("div",{style:{padding:"12px 16px",borderRadius:8,border:`1px solid ${G?"#bbf7d0":"#fca5a5"}`,background:G?"#f0fdf4":"#fef2f2",marginBottom:"1.5rem"},children:n.jsxs("div",{style:{display:"flex",gap:12,alignItems:"center",flexWrap:"wrap"},children:[n.jsx("span",{style:{fontSize:10,fontWeight:700,color:"#9ca3af",textTransform:"uppercase"},children:"Backend"}),n.jsx("span",{style:{fontWeight:700,color:G?"#16a34a":"#dc2626"},children:y?`Offline — ${y}`:(o==null?void 0:o.status)??"Loading…"}),o&&n.jsxs(n.Fragment,{children:[n.jsxs("span",{style:{fontSize:12,color:"#6b7280"},children:["v",o.version]}),n.jsxs("span",{style:{fontSize:12,color:"#6b7280"},children:["up ",Math.round(o.uptime_seconds),"s"]})]}),d&&n.jsx(n.Fragment,{children:Object.entries(d.counts).map(([P,F])=>n.jsxs("span",{style:{fontSize:11,padding:"1px 7px",borderRadius:6,background:"#f3f4f6",color:"#374151"},children:[P,": ",F]},P))}),p!==null&&n.jsxs("span",{style:{fontSize:11,padding:"1px 7px",borderRadius:6,background:"#f3f4f6",color:"#374151"},children:["studies: ",p]})]})}),!T&&n.jsxs("div",{style:{textAlign:"center",padding:"3rem",color:"#9ca3af"},children:[n.jsx("div",{style:{fontSize:28,marginBottom:8},children:"⚙️"}),n.jsx("div",{children:"Connecting to metrics stream…"})]}),T&&n.jsxs(n.Fragment,{children:[n.jsxs("section",{style:Jo,children:[n.jsxs("div",{style:Ys,children:[n.jsx("span",{style:Vs,children:"CPU"}),n.jsxs("span",{style:{fontSize:11,color:"#6b7280"},children:[T.cpu.count_physical,"C / ",T.cpu.count_logical,"T",T.cpu.freq_mhz&&` · ${T.cpu.freq_mhz} MHz`,T.cpu.freq_max_mhz&&` (max ${T.cpu.freq_max_mhz} MHz)`]})]}),n.jsx("div",{style:{display:"flex",gap:8,flexWrap:"wrap",marginBottom:10},children:n.jsx(Vo,{value:T.cpu.percent,label:"Utilization",color:"#2563eb",peak:T.cpu.peak_pct,sub:`${T.cpu.count_logical} logical cores`})}),n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("div",{style:{fontSize:10,fontWeight:700,color:"#9ca3af",textTransform:"uppercase",letterSpacing:.5,marginBottom:4},children:"60s History"}),n.jsx(Xo,{values:_.current.cpu,color:"#2563eb",height:36})]}),n.jsx(ik,{values:T.cpu.per_core_pct})]}),n.jsxs("section",{style:Jo,children:[n.jsxs("div",{style:Ys,children:[n.jsx("span",{style:Vs,children:"Memory"}),n.jsxs("span",{style:{fontSize:11,color:"#6b7280"},children:[T.ram.total_gb," GB total"]})]}),n.jsxs("div",{style:{display:"flex",gap:8,flexWrap:"wrap",marginBottom:10},children:[n.jsx(Vo,{value:T.ram.percent,label:"RAM Usage",color:"#7c3aed",peak:T.ram.peak_pct,sub:`${T.ram.used_gb} / ${T.ram.total_gb} GB used`}),T.ram.swap_total_gb>0&&n.jsx(Vo,{value:T.ram.swap_used_gb/T.ram.swap_total_gb*100,label:"Swap",color:"#d97706",sub:`${T.ram.swap_used_gb.toFixed(1)} / ${T.ram.swap_total_gb} GB`})]}),n.jsx(Xo,{values:_.current.ram,color:"#7c3aed",height:36}),n.jsxs("div",{style:{marginTop:6},children:[n.jsx(Fs,{label:"Available",current:T.ram.available_gb.toString(),unit:" GB",color:"#16a34a"}),n.jsx(Fs,{label:"Used",current:T.ram.used_gb.toString(),unit:" GB"})]})]}),T.gpu.length>0&&n.jsxs("section",{style:Jo,children:[n.jsxs("div",{style:Ys,children:[n.jsx("span",{style:Vs,children:"GPU"}),n.jsx("span",{style:{fontSize:11,color:"#6b7280"},children:T.gpu[0].name})]}),T.gpu.map((P,F)=>n.jsx("div",{style:{marginBottom:10},children:n.jsxs("div",{style:{display:"flex",gap:8,flexWrap:"wrap",marginBottom:10},children:[n.jsx(Vo,{value:P.utilization_pct,label:"GPU Util",color:"#16a34a",peak:T.gpu_peaks.utilization_pct,sub:`${P.temperature_c!==null?P.temperature_c+"°C":""}`}),n.jsx(Vo,{value:P.memory_utilization_pct,label:"VRAM %",color:"#d97706",peak:T.gpu_peaks.memory_utilization_pct,sub:`${P.memory_used_mb} / ${P.memory_total_mb} MB`}),n.jsx(Vo,{value:P.memory_used_mb/P.memory_total_mb*100,label:"VRAM Used",color:"#d97706",sub:`${(P.memory_used_mb/1024).toFixed(1)} / ${(P.memory_total_mb/1024).toFixed(1)} GB`})]})},F)),n.jsx(Xo,{values:_.current.gpu,color:"#16a34a",height:36})]}),T.gpu.length===0&&n.jsx("section",{style:{...Jo,padding:"12px 16px"},children:n.jsx("div",{style:{color:"#9ca3af",fontSize:13},children:"🎮 No NVIDIA GPU detected — nvidia-smi not available or no GPU present."})}),n.jsxs("section",{style:Jo,children:[n.jsxs("div",{style:Ys,children:[n.jsx("span",{style:Vs,children:"Disk"}),n.jsxs("span",{style:{fontSize:11,color:"#6b7280"},children:[T.disk.total_gb," GB total · ",T.disk.free_gb," GB free"]})]}),n.jsx("div",{style:{display:"flex",gap:8,flexWrap:"wrap",marginBottom:10},children:n.jsx(Vo,{value:T.disk.percent,label:"Disk Used",color:"#dc2626",sub:`${T.disk.used_gb} / ${T.disk.total_gb} GB`})}),n.jsxs("div",{style:{display:"flex",gap:16,marginBottom:8},children:[n.jsxs("div",{style:{flex:1},children:[n.jsx("div",{style:{fontSize:10,color:"#9ca3af",marginBottom:2},children:"Read MB/s"}),n.jsx(Xo,{values:_.current.disk_read,color:"#2563eb",height:28})]}),n.jsxs("div",{style:{flex:1},children:[n.jsx("div",{style:{fontSize:10,color:"#9ca3af",marginBottom:2},children:"Write MB/s"}),n.jsx(Xo,{values:_.current.disk_write,color:"#dc2626",height:28})]})]}),n.jsxs("div",{children:[n.jsx(Fs,{label:"Read",current:T.disk.read_mbps.toFixed(2),unit:" MB/s",color:"#2563eb",peak:T.disk.peak_read_mbps.toFixed(2)}),n.jsx(Fs,{label:"Write",current:T.disk.write_mbps.toFixed(2),unit:" MB/s",color:"#dc2626",peak:T.disk.peak_write_mbps.toFixed(2)})]})]}),n.jsxs("section",{style:Jo,children:[n.jsxs("div",{style:Ys,children:[n.jsx("span",{style:Vs,children:"Network"}),n.jsxs("span",{style:{fontSize:11,color:"#6b7280"},children:["↑ ",T.network.total_sent_gb.toFixed(2)," GB sent · ↓ ",T.network.total_recv_gb.toFixed(2)," GB recv"]})]}),n.jsxs("div",{style:{display:"flex",gap:16,marginBottom:8},children:[n.jsxs("div",{style:{flex:1},children:[n.jsx("div",{style:{fontSize:10,color:"#9ca3af",marginBottom:2},children:"Upload KB/s"}),n.jsx(Xo,{values:_.current.net_send,color:"#7c3aed",height:28})]}),n.jsxs("div",{style:{flex:1},children:[n.jsx("div",{style:{fontSize:10,color:"#9ca3af",marginBottom:2},children:"Download KB/s"}),n.jsx(Xo,{values:_.current.net_recv,color:"#16a34a",height:28})]})]}),n.jsxs("div",{children:[n.jsx(Fs,{label:"Upload",current:(T.network.send_mbps*1e3).toFixed(1),unit:" KB/s",color:"#7c3aed",peak:(T.network.peak_send_mbps*1e3).toFixed(1)}),n.jsx(Fs,{label:"Download",current:(T.network.recv_mbps*1e3).toFixed(1),unit:" KB/s",color:"#16a34a",peak:(T.network.peak_recv_mbps*1e3).toFixed(1)})]})]}),(l==null?void 0:l.pipelines)&&l.pipelines.length>0&&n.jsxs("section",{style:Jo,children:[n.jsx("div",{style:Ys,children:n.jsx("span",{style:Vs,children:"Registered Pipelines"})}),n.jsx("ul",{style:{columnCount:2,paddingLeft:"1.2rem",margin:0,fontSize:12},children:l.pipelines.map(P=>n.jsx("li",{style:{fontFamily:"monospace",marginBottom:2},children:P},P))})]})]}),n.jsx("style",{children:"@keyframes healthPulse { 0%,100%{opacity:1} 50%{opacity:0.3} }"})]})}const Jo={marginBottom:"1rem",padding:"14px 16px",border:"1px solid #e5e7eb",borderRadius:8},Ys={display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:12},Vs={fontSize:12,fontWeight:700,color:"#374151",textTransform:"uppercase",letterSpacing:.5};function sk(){const[t,o]=x.useState(null),r=x.useCallback((c,d)=>{c.preventDefault(),c.stopPropagation();const u=Math.min(c.clientX,window.innerWidth-180),p=Math.min(c.clientY,window.innerHeight-d.length*34-8);o({x:u,y:p,items:d})},[]),l=x.useCallback(()=>o(null),[]);return x.useEffect(()=>{if(!t)return;const c=()=>o(null);return window.addEventListener("click",c,{once:!0}),window.addEventListener("keydown",d=>{d.key==="Escape"&&o(null)},{once:!0}),()=>window.removeEventListener("click",c)},[t]),{menu:t,show:r,close:l}}function rk({menu:t,onClose:o}){return t?n.jsx("div",{style:{position:"fixed",left:t.x,top:t.y,background:"#fff",border:"1px solid #e5e7eb",borderRadius:6,boxShadow:"0 8px 24px rgba(0,0,0,0.12)",zIndex:8e3,minWidth:160,padding:"4px 0",fontSize:13},onClick:r=>r.stopPropagation(),children:t.items.map((r,l)=>n.jsxs("div",{onClick:()=>{r.disabled||(r.action(),o())},style:{padding:"7px 14px",cursor:r.disabled?"not-allowed":"pointer",display:"flex",alignItems:"center",gap:8,color:r.disabled?"#9ca3af":"#111827",background:"transparent"},onMouseEnter:c=>{r.disabled||(c.currentTarget.style.background="#f3f4f6")},onMouseLeave:c=>{c.currentTarget.style.background="transparent"},children:[r.icon&&n.jsx("span",{style:{fontSize:14,width:16},children:r.icon}),r.label]},l))}):null}function ak(t,o="Copy"){return[{label:o,icon:"⎘",action:()=>navigator.clipboard.writeText(t).catch(()=>{})},{label:"Copy All (plain text)",icon:"📋",action:()=>navigator.clipboard.writeText(t).catch(()=>{})}]}const $b=x.createContext({isOpen:!1,request:null,openChat:()=>{},closeChat:()=>{},toggleChat:()=>{},isDocked:!1,setDocked:()=>{}});function lk({children:t}){const[o,r]=x.useState(!1),[l,c]=x.useState(null),[d,u]=x.useState(!1),p=x.useCallback(b=>{b&&c(b),r(!0),window.dispatchEvent(new CustomEvent("glossa:open-ai-panel"))},[]),g=x.useCallback(()=>r(!1),[]),h=x.useCallback(()=>{r(b=>!b),o||c(null)},[o]);return n.jsx($b.Provider,{value:{isOpen:o,request:l,openChat:p,closeChat:g,toggleChat:h,isDocked:d,setDocked:u},children:t})}function fs(){return x.useContext($b)}const Hb=["linguistic","ancient","dna","code","random","other"],Wb=[{value:"unknown",label:"Unknown"},{value:"ltr",label:"LTR — Left to Right"},{value:"rtl",label:"RTL — Right to Left"}],ny={ltr:{label:"LTR",color:"#065f46",bg:"#d1fae5"},rtl:{label:"RTL",color:"#7c2d12",bg:"#fee2e2"},unknown:{label:"?",color:"#6b7280",bg:"#f3f4f6"}},Of=200;function iy({data:t,xKey:o,yKey:r,color:l="#2563eb",height:c=100}){if(!t.length)return null;const d=t.map(g=>Number(g[r])||0),u=Math.max(...d,1),p=Math.max(8,Math.floor(560/t.length));return n.jsx("svg",{viewBox:`0 0 ${t.length*p} ${c}`,style:{width:"100%",height:c,overflow:"visible"},children:t.map((g,h)=>{const b=Number(g[r])||0,y=Math.max(1,b/u*(c-16));return n.jsxs("g",{children:[n.jsx("rect",{x:h*p+1,y:c-y-12,width:Math.max(2,p-2),height:y,fill:l,opacity:.8,rx:1}),t.length<=20&&n.jsx("text",{x:h*p+p/2,y:c-2,textAnchor:"middle",fontSize:Math.min(9,p-1),fill:"#6b7280",children:String(g[o]).slice(0,4)})]},h)})})}function ck({values:t,color:o="#2563eb"}){if(t.length<2)return null;const r=40,l=300,c=Math.max(...t,1),d=Math.min(...t,0),u=c-d||1,p=l/(t.length-1),g=t.map((h,b)=>`${b*p},${r-(h-d)/u*r}`).join(" ");return n.jsx("svg",{viewBox:`0 0 ${l} ${r}`,style:{width:"100%",height:r},children:n.jsx("polyline",{points:g,fill:"none",stroke:o,strokeWidth:1.5})})}function Xs({label:t,value:o,color:r="#374151"}){return n.jsxs("div",{style:{padding:"6px 12px",borderRadius:6,background:"#f9fafb",border:"1px solid #e5e7eb",textAlign:"center",minWidth:90},children:[n.jsx("div",{style:{fontSize:18,fontWeight:700,color:r,fontFamily:"monospace"},children:o}),n.jsx("div",{style:{fontSize:10,color:"#6b7280",textTransform:"uppercase",letterSpacing:.5},children:t})]})}function dk(t){let o=!1,r=!1,l=!1,c=!1;for(const u of t){const p=u.codePointAt(0)??0;if(p>=48&&p<=57){o=!0;continue}if(p>=65&&p<=90||p>=97&&p<=122){r=!0;continue}if(!(p===45||p===95||p===32)){if(p<128){c=!0;continue}l=!0}}return[o,r,l,c].filter(Boolean).length>1?"mixed":l?"ancient":r?"latin":c?"punctuation":"numeric"}const uk={numeric:{label:"Numeric codes",color:"#2563eb",bg:"#dbeafe",desc:"Tokens like 066 or 066-069 (sign codes)"},latin:{label:"Latin / ASCII",color:"#16a34a",bg:"#dcfce7",desc:"Latin letter tokens"},ancient:{label:"Non-Latin Unicode",color:"#7c3aed",bg:"#ede9fe",desc:"Ancient script glyphs (Geez, Hebrew, etc.)"},punctuation:{label:"Punctuation",color:"#d97706",bg:"#fef3c7",desc:"Punctuation-only tokens"},mixed:{label:"Mixed (⚠ noise)",color:"#dc2626",bg:"#fee2e2",desc:"Tokens mixing Latin + non-Latin + punctuation"}};function fk({tokens:t}){const o={numeric:0,latin:0,ancient:0,punctuation:0,mixed:0};for(const u of t)o[dk(u)]++;const r=t.length||1,l=o.mixed/r*100,c=l>5,d=Object.entries(o).filter(([,u])=>u>0);return n.jsxs("div",{style:{marginTop:16,padding:"10px 12px",border:"1px solid #e5e7eb",borderRadius:6,background:"#f9fafb"},children:[n.jsx("div",{style:{fontSize:10,fontWeight:700,color:"#7c3aed",textTransform:"uppercase",letterSpacing:.5,marginBottom:8},children:"Token-Type Breakdown"}),c&&n.jsxs("div",{style:{padding:"4px 8px",background:"#fef2f2",border:"1px solid #fca5a5",borderRadius:4,fontSize:11,color:"#991b1b",marginBottom:8},children:["⚠ ",l.toFixed(1),"% mixed-category tokens detected. Consider using a ",n.jsx("strong",{children:"TokenFilter"})," node to sanitize this corpus before analysis."]}),n.jsx("div",{style:{display:"flex",flexDirection:"column",gap:5},children:d.map(([u,p])=>{const g=uk[u],h=p/r*100;return n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[n.jsx("div",{style:{width:130,fontSize:11,color:g.color,fontWeight:600,flexShrink:0},title:g.desc,children:g.label}),n.jsx("div",{style:{flex:1,background:"#e5e7eb",borderRadius:3,height:10,overflow:"hidden"},children:n.jsx("div",{style:{width:`${h}%`,background:g.color,height:"100%",borderRadius:3,opacity:.85}})}),n.jsxs("div",{style:{width:60,fontSize:11,color:"#6b7280",textAlign:"right",flexShrink:0},children:[p.toLocaleString()," (",h.toFixed(1),"%)"]})]},u)})})]})}function pk({text:t,onUpdated:o,onDeleted:r,allTexts:l}){const{toast:c}=nt(),[d,u]=x.useState(!1),[p,g]=x.useState("browse"),[h,b]=x.useState(0),[y,v]=x.useState(""),[w,j]=x.useState(t.name),[_,C]=x.useState(t.corpus_type),[S,E]=x.useState(t.content.join(" ")),[k,D]=x.useState("space"),[H,G]=x.useState(t.reading_direction??"unknown"),[T,P]=x.useState(!1),[F,W]=x.useState(!1),[M,V]=x.useState(2),[I,A]=x.useState(null),[q,R]=x.useState(!1),[J,N]=x.useState(""),[X,Q]=x.useState(null),[L,B]=x.useState(!1),[$,Y]=x.useState(null),[O,K]=x.useState(!1),[ne,se]=x.useState("analyze"),[pe,_e]=x.useState(""),[Se,ke]=x.useState(null),[te,de]=x.useState(null),[Ce,ze]=x.useState(!1),ve=x.useRef(null),{menu:De,show:Me,close:Ve}=sk(),{openChat:Le}=fs(),Ae=y?t.content.filter(fe=>fe.toLowerCase().includes(y.toLowerCase())):t.content,Ue=Math.ceil(Ae.length/Of),Oe=Ae.slice(h*Of,(h+1)*Of),dt=async()=>{W(!0);try{let fe;k==="line"?fe=S.split(` +`).map(Et=>Et.trim()).filter(Boolean):k==="char"?fe=S.replace(/\s/g,"").split(""):fe=S.trim().split(/\s+/).filter(Boolean);const ft=await h2(t.id,{name:w.trim(),corpus_type:_,content:fe,reading_direction:H});o(ft),c("Corpus updated","success")}catch(fe){c(fe instanceof Error?fe.message:"Save failed","error")}finally{W(!1)}},it=async()=>{P(!0);try{const fe=await m2(t.id);G(fe.inferred_direction);const ft=await f2(t.id);o(ft);const Et=fe.confidence==="high"?"high confidence":fe.confidence==="medium"?"medium confidence":"low confidence";c(`Detected: ${fe.inferred_direction.toUpperCase()} (${Et}, ${fe.n_words} words)`,"info")}catch(fe){c(fe instanceof Error?fe.message:"Detection failed","error")}finally{P(!1)}},[lt,Je]=x.useState(!1),yt=()=>{navigator.clipboard.writeText(t.content.join(" ")).then(()=>{Je(!0),setTimeout(()=>Je(!1),1400)})},Jt=fe=>{var Gt;const ft=(Gt=fe.target.files)==null?void 0:Gt[0];if(!ft)return;const Et=new FileReader;Et.onload=Pt=>{var oe;const Ct=(oe=Pt.target)==null?void 0:oe.result;if(ft.name.endsWith(".json"))try{const Ne=JSON.parse(Ct);E(Array.isArray(Ne)?Ne.join(" "):(Ne.content??[]).join(" ")||Ct)}catch{E(Ct)}else E(Ct);g("edit")},Et.readAsText(ft),fe.target.value=""},rn=async()=>{R(!0);try{A(await R2(t.id,M))}catch(fe){c(fe instanceof Error?fe.message:"Error","error")}finally{R(!1)}},zt=async()=>{if(J.trim()){B(!0);try{Q(await A2(t.id,J.trim()))}catch(fe){c(fe instanceof Error?fe.message:"Error","error")}finally{B(!1)}}},ae=x.useCallback(async()=>{if(!$){K(!0);try{Y(await Bc(t.id))}catch(fe){c(fe instanceof Error?fe.message:"Error","error")}finally{K(!1)}}},[$,t.id,c]),He=()=>{const fe={analyze:`Please analyze the corpus "${t.name}" (${t.corpus_type}, ${t.content.length.toLocaleString()} tokens, alphabet ${t.alphabet_size}). Provide: summary, linguistic characteristics, Indus Script relevance, key insights, and suggested experiments.`,anomalies:`Please detect anomalies in the corpus "${t.name}" (${t.corpus_type}, ${t.content.length.toLocaleString()} tokens). Look for statistical anomalies, unusual patterns, structural breaks, and data quality issues.`,critique:`Please critique the corpus "${t.name}" (${t.corpus_type}, ${t.content.length.toLocaleString()} tokens, alphabet ${t.alphabet_size}) for research use. Evaluate coverage, bias, completeness, and suitability for Indus Script entropy analysis.`};Le({contextType:"corpus",contextId:t.id,contextLabel:t.name,initialPrompt:fe[ne]})},Ze=async()=>{if(pe){ze(!0);try{const[fe,ft]=await Promise.all([Bc(t.id),Bc(pe)]);de(fe),ke(ft)}catch(fe){c(fe instanceof Error?fe.message:"Error","error")}finally{ze(!1)}}};x.useEffect(()=>{d&&p==="stats"&&ae()},[d,p,ae]);const Ut={linguistic:"#2563eb",ancient:"#7c3aed",dna:"#16a34a",code:"#d97706",random:"#6b7280"}[t.corpus_type]??"#374151",Nt=[{id:"browse",label:"Browse"},{id:"edit",label:"Edit"},{id:"stats",label:"Stats"},{id:"ngrams",label:"N-grams"},{id:"concordance",label:"Concordance"},{id:"ai",label:"✨ AI"},{id:"compare",label:"Compare"}],yn=()=>{const fe=!d;u(fe),fe&&window.dispatchEvent(new CustomEvent("glossa:context",{detail:{type:"corpus",id:t.id,name:t.name}}))};return n.jsxs("div",{style:{border:"1px solid #e5e7eb",borderRadius:8,overflow:"hidden",marginBottom:8,boxShadow:"0 1px 3px rgba(0,0,0,0.04)"},children:[n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10,padding:"10px 14px",background:"#fafafa",cursor:"pointer",borderBottom:d?"1px solid #e5e7eb":"none"},onClick:yn,children:[n.jsx("span",{style:{fontSize:11,padding:"1px 7px",borderRadius:8,background:Ut+"20",color:Ut,fontWeight:700,whiteSpace:"nowrap"},children:t.corpus_type}),(()=>{const fe=t.reading_direction??"unknown";if(fe==="unknown")return null;const ft=ny[fe]??ny.ltr;return n.jsx("span",{title:`Reading direction: ${fe.toUpperCase()}`,style:{fontSize:10,padding:"1px 6px",borderRadius:8,background:ft.bg,color:ft.color,fontWeight:700,whiteSpace:"nowrap",border:`1px solid ${ft.color}33`},children:ft.label})})(),n.jsx("span",{style:{flex:1,fontWeight:600,fontSize:13,color:"#111827"},children:t.name}),n.jsxs("span",{style:{fontSize:11,color:"#9ca3af"},children:[t.content.length.toLocaleString()," tokens"]}),n.jsxs("span",{style:{fontSize:11,color:"#9ca3af"},children:["Σ ",t.alphabet_size]}),n.jsx("span",{style:{fontSize:11,color:"#9ca3af"},children:t.created_at.slice(0,10)}),n.jsxs("span",{onClick:fe=>fe.stopPropagation(),style:{display:"flex",gap:4},children:[n.jsx("button",{onClick:yt,title:"Copy",style:{...or,background:lt?"#dcfce7":void 0,color:lt?"#16a34a":void 0,transition:"background 0.2s"},children:lt?"✓":"⎘"}),n.jsx("a",{href:Jx(t.id,"txt"),download:!0,onClick:fe=>fe.stopPropagation(),style:{...or,textDecoration:"none"},children:"↓txt"}),n.jsx("a",{href:Jx(t.id,"csv"),download:!0,onClick:fe=>fe.stopPropagation(),style:{...or,textDecoration:"none"},children:"↓csv"}),n.jsx("button",{onClick:()=>{var fe;return(fe=ve.current)==null?void 0:fe.click()},title:"Import file",style:or,children:"↑ file"}),n.jsx("button",{onClick:async fe=>{if(fe.stopPropagation(),!!confirm(`Delete "${t.name}"?`))try{await g2(t.id),r(t.id),c("Deleted","info")}catch{c("Delete failed","error")}},style:{...or,color:"#dc2626",borderColor:"#fca5a5"},children:"🗑"})]}),n.jsx("input",{ref:ve,type:"file",accept:".txt,.csv,.json",style:{display:"none"},onChange:Jt}),n.jsx("span",{style:{fontSize:14,color:"#9ca3af",marginLeft:2},children:d?"▲":"▼"})]}),d&&n.jsxs("div",{children:[n.jsx("div",{style:{display:"flex",borderBottom:"1px solid #e5e7eb",background:"#f9fafb"},children:Nt.map(fe=>n.jsx("button",{onClick:ft=>{ft.stopPropagation(),g(fe.id)},style:{padding:"7px 14px",border:"none",borderBottom:p===fe.id?"2px solid #1e3a5f":"2px solid transparent",background:"none",cursor:"pointer",fontSize:12,fontWeight:p===fe.id?700:400,color:p===fe.id?"#1e3a5f":"#6b7280"},children:fe.label},fe.id))}),n.jsxs("div",{style:{padding:"14px 16px"},onClick:fe=>fe.stopPropagation(),children:[p==="browse"&&n.jsxs("div",{children:[n.jsxs("div",{style:{display:"flex",gap:8,marginBottom:10,alignItems:"center"},children:[n.jsx("input",{placeholder:"Search tokens…",value:y,onChange:fe=>{v(fe.target.value),b(0)},style:{...hn,flex:1}}),n.jsxs("span",{style:{fontSize:11,color:"#9ca3af",whiteSpace:"nowrap"},children:[Ae.length.toLocaleString()," / ",t.content.length.toLocaleString()]})]}),n.jsx("pre",{style:{background:"#1e293b",color:"#e2e8f0",borderRadius:6,padding:"10px 14px",fontSize:11,overflowX:"auto",maxHeight:220,margin:0,lineHeight:1.8,cursor:"context-menu"},onContextMenu:fe=>Me(fe,[...ak(Oe.join(" "),"Copy page"),{label:"Copy all tokens",icon:"📄",action:()=>navigator.clipboard.writeText(t.content.join(" ")).catch(()=>{})}]),children:Oe.join(" ")}),n.jsx(rk,{menu:De,onClose:Ve}),Ue>1&&n.jsxs("div",{style:{display:"flex",gap:6,marginTop:8,alignItems:"center"},children:[n.jsx("button",{onClick:()=>b(fe=>Math.max(0,fe-1)),disabled:h===0,style:xn,children:"← Prev"}),n.jsxs("span",{style:{fontSize:12,color:"#6b7280"},children:["Page ",h+1," / ",Ue]}),n.jsx("button",{onClick:()=>b(fe=>Math.min(Ue-1,fe+1)),disabled:h>=Ue-1,style:xn,children:"Next →"})]})]}),p==="edit"&&n.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:10,maxWidth:560},children:[n.jsxs("div",{children:[n.jsx("label",{style:$n,children:"Name"}),n.jsx("input",{value:w,onChange:fe=>j(fe.target.value),style:hn})]}),n.jsxs("div",{children:[n.jsx("label",{style:$n,children:"Type"}),n.jsx("select",{value:_,onChange:fe=>C(fe.target.value),style:hn,children:Hb.map(fe=>n.jsx("option",{children:fe},fe))})]}),n.jsxs("div",{children:[n.jsx("label",{style:$n,children:"Reading Direction"}),n.jsxs("div",{style:{display:"flex",gap:8,alignItems:"center"},children:[n.jsx("select",{value:H,onChange:fe=>G(fe.target.value),style:{...hn,flex:1},children:Wb.map(fe=>n.jsx("option",{value:fe.value,children:fe.label},fe.value))}),n.jsx("button",{onClick:it,disabled:T,style:{...Oc,whiteSpace:"nowrap"},title:"Auto-detect reading direction using Ashraf & Sinha (2018) positional entropy method",children:T?"Detecting…":"🔍 Auto-detect"})]}),n.jsx("div",{style:{fontSize:10,color:"#6b7280",marginTop:3},children:"Auto-detect applies the Ashraf & Sinha (2018) positional entropy method. Lower entropy at word-end indicates the reading direction."})]}),n.jsxs("div",{children:[n.jsx("label",{style:$n,children:"Tokenisation mode (for re-parsing)"}),n.jsxs("select",{value:k,onChange:fe=>D(fe.target.value),style:hn,children:[n.jsx("option",{value:"space",children:"Space-separated"}),n.jsx("option",{value:"line",children:"Line-per-token"}),n.jsx("option",{value:"char",children:"Character-level"})]})]}),n.jsxs("div",{children:[n.jsxs("label",{style:$n,children:["Content (",t.content.length.toLocaleString()," tokens)"]}),n.jsx("textarea",{value:S,onChange:fe=>E(fe.target.value),rows:8,style:{...hn,fontFamily:"monospace",resize:"vertical",fontSize:11}})]}),n.jsxs("div",{style:{display:"flex",gap:8},children:[n.jsx("button",{onClick:dt,disabled:F,style:ts,children:F?"Saving…":"Save"}),n.jsx("button",{onClick:yt,style:Oc,children:"Copy All"}),n.jsx("button",{onClick:()=>{var fe;return(fe=ve.current)==null?void 0:fe.click()},style:Oc,children:"Import File"})]})]}),p==="stats"&&n.jsxs("div",{children:[O&&n.jsx("p",{style:{color:"#6b7280",fontSize:13},children:"Computing metrics…"}),$&&n.jsxs(n.Fragment,{children:[n.jsxs("div",{style:{display:"flex",gap:8,flexWrap:"wrap",marginBottom:14},children:[n.jsx(Xs,{label:"H1 (bits)",value:$.h1,color:"#2563eb"}),n.jsx(Xs,{label:"H2/H1",value:$.h2_h1_ratio??"—",color:"#7c3aed"}),n.jsx(Xs,{label:"Cond H",value:$.conditional_h,color:"#d97706"}),n.jsx(Xs,{label:"TTR",value:$.type_token_ratio.toFixed(3),color:"#16a34a"}),n.jsx(Xs,{label:"Zipf ρ",value:$.zipf_correlation.toFixed(3),color:"#6b7280"}),n.jsx(Xs,{label:"Hapax",value:$.hapax_count.toLocaleString()})]}),n.jsxs("div",{style:{marginBottom:10},children:[n.jsxs("div",{style:oy,children:["Token frequency (top ",Math.min($.zipf_table.length,30),")"]}),n.jsx(iy,{data:$.zipf_table.slice(0,30),xKey:"token",yKey:"freq",height:90})]}),n.jsxs("div",{children:[n.jsx("div",{style:oy,children:"Zipf log-rank vs log-freq"}),n.jsx(ck,{values:$.zipf_table.map(fe=>fe.log_freq),color:"#7c3aed"})]})]}),n.jsx(fk,{tokens:t.content})]}),p==="ngrams"&&n.jsxs("div",{children:[n.jsxs("div",{style:{display:"flex",gap:6,marginBottom:10,alignItems:"center"},children:[n.jsx("span",{style:{fontSize:12,color:"#374151"},children:"n ="}),[1,2,3,4].map(fe=>n.jsx("button",{onClick:()=>V(fe),style:{...xn,background:M===fe?"#1e3a5f":"#f3f4f6",color:M===fe?"#fff":"#374151"},children:fe},fe)),n.jsx("button",{onClick:rn,disabled:q,style:ts,children:q?"Loading…":"Load"})]}),I&&n.jsxs(n.Fragment,{children:[n.jsx(iy,{data:I.slice(0,30).map(fe=>({k:fe.ngram.slice(0,6),count:fe.count})),xKey:"k",yKey:"count",height:90,color:"#7c3aed"}),n.jsxs("table",{style:{borderCollapse:"collapse",width:"100%",marginTop:10,fontSize:12},children:[n.jsx("thead",{children:n.jsxs("tr",{children:[n.jsx("th",{style:Js,children:"N-gram"}),n.jsx("th",{style:Js,children:"Count"})]})}),n.jsx("tbody",{children:I.slice(0,50).map(fe=>n.jsxs("tr",{children:[n.jsx("td",{style:Ks,children:n.jsx("code",{children:fe.ngram})}),n.jsx("td",{style:Ks,children:fe.count.toLocaleString()})]},fe.ngram))})]})]})]}),p==="concordance"&&n.jsxs("div",{children:[n.jsxs("div",{style:{display:"flex",gap:8,marginBottom:10},children:[n.jsx("input",{placeholder:"Token (exact match)…",value:J,onChange:fe=>N(fe.target.value),onKeyDown:fe=>{fe.key==="Enter"&&zt()},style:{...hn,flex:1}}),n.jsx("button",{onClick:zt,disabled:L,style:ts,children:L?"…":"Search"})]}),X&&n.jsxs("div",{children:[n.jsxs("div",{style:{fontSize:12,color:"#6b7280",marginBottom:8},children:[X.total.toLocaleString()," occurrences of ",n.jsxs("code",{children:['"',X.query,'"']})]}),n.jsx("div",{style:{maxHeight:300,overflowY:"auto"},children:X.hits.slice(0,100).map((fe,ft)=>n.jsxs("div",{style:{display:"flex",gap:4,padding:"3px 0",borderBottom:"1px solid #f3f4f6",fontSize:12,fontFamily:"monospace"},children:[n.jsx("span",{style:{color:"#9ca3af",width:50,flexShrink:0,textAlign:"right",fontSize:10},children:fe.position}),n.jsx("span",{style:{color:"#6b7280"},children:fe.left.join(" ")}),n.jsx("span",{style:{background:"#fef3c7",padding:"0 2px",borderRadius:2,fontWeight:700,color:"#92400e"},children:fe.match}),n.jsx("span",{style:{color:"#6b7280"},children:fe.right.join(" ")})]},ft))})]})]}),p==="ai"&&n.jsx("div",{children:n.jsxs("div",{style:{display:"flex",gap:6,marginBottom:12,flexWrap:"wrap"},children:[["analyze","anomalies","critique"].map(fe=>n.jsx("button",{onClick:()=>se(fe),style:{...xn,background:ne===fe?"#7c3aed":"#f3f4f6",color:ne===fe?"#fff":"#374151"},children:fe==="analyze"?"Corpus Analysis":fe==="anomalies"?"Anomaly Detection":"Critique"},fe)),n.jsx("button",{onClick:He,style:{...ts,background:"#7c3aed",marginLeft:"auto"},children:"✨ Ask AI"})]})}),p==="compare"&&n.jsxs("div",{children:[n.jsxs("div",{style:{display:"flex",gap:8,marginBottom:12,alignItems:"center"},children:[n.jsx("label",{style:{fontSize:12,color:"#374151",whiteSpace:"nowrap"},children:"Compare with:"}),n.jsxs("select",{value:pe,onChange:fe=>_e(fe.target.value),style:{...hn,flex:1},children:[n.jsx("option",{value:"",children:"— select corpus —"}),l.filter(fe=>fe.id!==t.id).map(fe=>n.jsxs("option",{value:fe.id,children:[fe.name," (",fe.corpus_type,")"]},fe.id))]}),n.jsx("button",{onClick:Ze,disabled:!pe||Ce,style:ts,children:Ce?"Loading…":"Compare"})]}),te&&Se&&(()=>{const fe=l.find(Et=>Et.id===pe),ft=[["H1 (bits)","h1"],["H2/H1","h2_h1_ratio"],["Cond H","conditional_h"],["TTR","type_token_ratio"],["Zipf ρ","zipf_correlation"],["Tokens","token_count"],["Alphabet","type_count"],["Hapax","hapax_count"]];return n.jsxs("table",{style:{borderCollapse:"collapse",width:"100%",fontSize:12},children:[n.jsx("thead",{children:n.jsxs("tr",{children:[n.jsx("th",{style:Js,children:"Metric"}),n.jsx("th",{style:Js,children:t.name.slice(0,20)}),n.jsx("th",{style:Js,children:(fe==null?void 0:fe.name.slice(0,20))??pe}),n.jsx("th",{style:Js,children:"Δ"})]})}),n.jsx("tbody",{children:ft.map(([Et,Gt])=>{const Pt=te[Gt]??0,Ct=Se[Gt]??0,oe=typeof Pt=="number"&&typeof Ct=="number"?Pt-Ct:null,Ne=oe!==null&&Math.abs(oe)>.05*Math.max(Math.abs(Pt),Math.abs(Ct),.001);return n.jsxs("tr",{children:[n.jsx("td",{style:{...Ks,fontWeight:600},children:Et}),n.jsx("td",{style:Ks,children:typeof Pt=="number"?Number.isInteger(Pt)?Pt.toLocaleString():Pt.toFixed(3):"—"}),n.jsx("td",{style:Ks,children:typeof Ct=="number"?Number.isInteger(Ct)?Ct.toLocaleString():Ct.toFixed(3):"—"}),n.jsx("td",{style:{...Ks,color:Ne?oe>0?"#16a34a":"#dc2626":"#9ca3af",fontWeight:Ne?700:400},children:oe!==null?(oe>0?"+":"")+oe.toFixed(3):"—"})]},Gt)})})]})})()]})]})]})]})}function hk({onCreated:t}){const{toast:o}=nt(),[r,l]=x.useState(""),[c,d]=x.useState("linguistic"),[u,p]=x.useState("space"),[g,h]=x.useState("unknown"),[b,y]=x.useState(""),[v,w]=x.useState(!1),j=x.useRef(null),_=E=>u==="char"?E.replace(/\s+/g,"").split(""):u==="line"?E.split(` +`).map(k=>k.trim()).filter(Boolean):E.trim().split(/\s+/).filter(Boolean),C=async()=>{if(!r.trim()||!b.trim()){o("Name and content required","warning");return}const E=_(b);if(!E.length){o("Content cannot be empty","warning");return}w(!0);try{const k=await p2({name:r.trim(),corpus_type:c,content:E,reading_direction:g});t(k),l(""),y(""),h("unknown"),o("Corpus created","success")}catch(k){o(k instanceof Error?k.message:"Upload failed","error")}finally{w(!1)}},S=E=>{var H;const k=(H=E.target.files)==null?void 0:H[0];if(!k)return;r||l(k.name.replace(/\.[^.]+$/,""));const D=new FileReader;D.onload=G=>{var P;const T=(P=G.target)==null?void 0:P.result;if(k.name.endsWith(".json"))try{const F=JSON.parse(T);y(Array.isArray(F)?F.join(" "):(F.content??[]).join(" ")||T)}catch{y(T)}else y(T)},D.readAsText(k),E.target.value=""};return n.jsxs("details",{style:{marginBottom:"1.5rem"},children:[n.jsx("summary",{style:{cursor:"pointer",fontWeight:600,fontSize:13,padding:"8px 0"},children:"+ Upload / import corpus"}),n.jsxs("div",{style:{marginTop:10,padding:"1rem",border:"1px solid #e5e7eb",borderRadius:8,maxWidth:560},children:[n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("label",{style:$n,children:"Name"}),n.jsx("input",{value:r,onChange:E=>l(E.target.value),placeholder:"e.g. Moby Dick",style:hn})]}),n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("label",{style:$n,children:"Type"}),n.jsx("select",{value:c,onChange:E=>d(E.target.value),style:hn,children:Hb.map(E=>n.jsx("option",{children:E},E))})]}),n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("label",{style:$n,children:"Reading Direction"}),n.jsx("select",{value:g,onChange:E=>h(E.target.value),style:hn,children:Wb.map(E=>n.jsx("option",{value:E.value,children:E.label},E.value))})]}),n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("label",{style:$n,children:"Tokenisation"}),n.jsxs("select",{value:u,onChange:E=>p(E.target.value),style:hn,children:[n.jsx("option",{value:"space",children:"Space-separated"}),n.jsx("option",{value:"line",children:"Line-per-token"}),n.jsx("option",{value:"char",children:"Character-level"})]})]}),n.jsxs("div",{style:{marginBottom:10},children:[n.jsx("label",{style:$n,children:"Paste text content"}),n.jsx("textarea",{value:b,onChange:E=>y(E.target.value),rows:5,style:{...hn,fontFamily:"monospace",resize:"vertical",fontSize:11},placeholder:"Paste text here…"})]}),n.jsxs("div",{style:{display:"flex",gap:8},children:[n.jsx("button",{onClick:C,disabled:v,style:ts,children:v?"Uploading…":"Upload"}),n.jsx("button",{onClick:()=>{var E;return(E=j.current)==null?void 0:E.click()},style:Oc,children:"↑ Import File (.txt/.csv/.json)"}),n.jsx("input",{ref:j,type:"file",accept:".txt,.csv,.json",style:{display:"none"},onChange:S})]})]})]})}function gk({onImported:t}){const{toast:o}=nt(),[r,l]=x.useState([]),[c,d]=x.useState(!1),[u,p]=x.useState(null),[g,h]=x.useState(""),[b,y]=x.useState("all"),[v,w]=x.useState("all"),[j,_]=x.useState("all"),C=async()=>{d(!0);try{l(await kb())}catch(F){o(F instanceof Error?F.message:"Failed to load catalogue","error")}finally{d(!1)}},S=async F=>{var W;if(!F.local_module){o(`No bundled module for '${F.name}'. Download from the source URL and upload manually via + Upload / import corpus.`,"warning");return}p(F.id);try{const M=await sj(F.id);M.imported?(l(V=>V.map(I=>I.id===F.id?{...I,already_imported:!0}:I)),o(`Imported '${M.name}' (${(W=M.tokens)==null?void 0:W.toLocaleString()} tokens)`,"success"),t()):o(`'${M.name}' already in your corpora`,"info")}catch(M){o(M instanceof Error?M.message:"Import failed","error")}finally{p(null)}},E=Array.from(new Set(r.map(F=>F.script_type).filter(Boolean))).sort(),k=r.filter(F=>{const W=!g||F.name.toLowerCase().includes(g.toLowerCase())||F.language.toLowerCase().includes(g.toLowerCase())||F.language_family.toLowerCase().includes(g.toLowerCase()),M=b==="all"||(b==="undeciphered"?!!F.is_undeciphered:!F.is_undeciphered),V=v==="all"||F.script_type===v,I=j==="all"||(j==="bundled"?!!F.local_module:!F.local_module);return W&&M&&V&&I}),D={};for(const F of k){const W=F.language_family||"Other";(D[W]=D[W]||[]).push(F)}const H={abjad:"#7c3aed",syllabary:"#059669",logosyllabic:"#d97706",logographic:"#dc2626",alphabet:"#2563eb",unknown:"#6b7280"},G={abjad:"Abjad",syllabary:"Syllabary",logosyllabic:"Logo-syllabic",logographic:"Logographic",alphabet:"Alphabet",unknown:"Unknown"},T={ltr:{label:"LTR",color:"#065f46",bg:"#d1fae5",title:"Left to Right"},rtl:{label:"RTL",color:"#7c2d12",bg:"#fee2e2",title:"Right to Left"},bidi:{label:"BIDI",color:"#5b21b6",bg:"#ede9fe",title:"Boustrophedon (alternating)"},unknown:{label:"?",color:"#6b7280",bg:"#f3f4f6",title:"Reading direction unknown"}},P=F=>F>0?`~${F>=1e3?`${(F/1e3).toFixed(F>=1e4?0:1)}K`:F.toString()} tokens`:"—";return n.jsxs("details",{style:{marginBottom:"1.5rem"},children:[n.jsx("summary",{style:{cursor:"pointer",fontWeight:600,fontSize:13,padding:"8px 0",color:"#059669"},onClick:()=>r.length===0&&void C(),children:"🌍 Browse World Language Corpus Catalogue"}),n.jsxs("div",{style:{marginTop:10,padding:"1rem",border:"1px solid #d1fae5",borderRadius:8,background:"#f0fdf4"},children:[n.jsxs("div",{style:{display:"flex",gap:6,marginBottom:6,flexWrap:"wrap",alignItems:"center"},children:[n.jsx("input",{placeholder:"Search name, language, family…",value:g,onChange:F=>h(F.target.value),style:{...hn,width:220}}),["all","undeciphered","deciphered"].map(F=>n.jsx("button",{onClick:()=>y(F),style:{...xn,background:b===F?"#059669":void 0,color:b===F?"#fff":void 0},children:F==="all"?"All":F==="undeciphered"?"🔓 Undeciphered":"✓ Deciphered"},F)),n.jsx("div",{style:{display:"flex",gap:4},children:["all","bundled","manual"].map(F=>n.jsx("button",{onClick:()=>_(F),style:{...xn,background:j===F?"#2563eb":void 0,color:j===F?"#fff":void 0},title:F==="bundled"?"One-click import available":F==="manual"?"Manual upload required":"All",children:F==="all"?"⬇ Any":F==="bundled"?"⬇ 1-click":"✎ Manual"},F))}),n.jsx("button",{onClick:()=>void C(),style:xn,title:"Reload catalogue",children:"⟳"}),n.jsxs("span",{style:{fontSize:11,color:"#6b7280",marginLeft:"auto"},children:[k.length," entries"]})]}),E.length>0&&n.jsxs("div",{style:{display:"flex",gap:4,marginBottom:10,flexWrap:"wrap"},children:[n.jsx("button",{onClick:()=>w("all"),style:{...xn,padding:"2px 8px",background:v==="all"?"#374151":void 0,color:v==="all"?"#fff":void 0,fontSize:10},children:"All types"}),E.map(F=>{const W=H[F]??"#6b7280";return n.jsx("button",{onClick:()=>w(v===F?"all":F),style:{...xn,padding:"2px 8px",fontSize:10,background:v===F?W:W+"15",color:v===F?"#fff":W,border:`1px solid ${W}40`,fontWeight:v===F?700:400},children:G[F]??F},F)})]}),c&&n.jsx("p",{style:{color:"#6b7280",fontSize:13},children:"Loading catalogue…"}),Object.entries(D).sort(([F],[W])=>F.localeCompare(W)).map(([F,W])=>n.jsxs("div",{style:{marginBottom:10},children:[n.jsxs("div",{style:{fontSize:10,fontWeight:700,color:"#374151",textTransform:"uppercase",letterSpacing:.5,marginBottom:3,paddingBottom:2,borderBottom:"1px solid #d1fae5"},children:[F," ",n.jsxs("span",{style:{fontWeight:400,opacity:.6},children:["(",W.length,")"]})]}),W.map(M=>{const V=H[M.script_type]??"#6b7280",I=!!M.local_module,A=P(M.tokens_approx);return n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,padding:"5px 0",borderBottom:"1px solid #ecfdf5"},children:[n.jsxs("div",{style:{flex:1,minWidth:0},children:[n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:5,flexWrap:"wrap"},children:[n.jsx("span",{style:{fontWeight:600,fontSize:12,color:M.is_undeciphered?"#7c2d12":"#1e3a5f"},children:M.name}),n.jsx("span",{style:{fontSize:9,padding:"1px 5px",borderRadius:8,background:V+"18",color:V,fontWeight:700},children:G[M.script_type]??M.script_type}),(()=>{const q=M.reading_direction??"unknown",R=T[q]??T.unknown;return n.jsx("span",{style:{fontSize:9,padding:"1px 5px",borderRadius:8,background:R.bg,color:R.color,fontWeight:700,letterSpacing:.2},title:R.title,children:R.label})})(),M.is_undeciphered&&n.jsx("span",{style:{fontSize:9,color:"#dc2626",fontWeight:700},children:"🔓"}),I&&!M.already_imported&&n.jsx("span",{style:{fontSize:9,color:"#059669",fontWeight:600},children:"⬇ bundled"})]}),n.jsxs("div",{style:{fontSize:10,color:"#6b7280",marginTop:1},children:[M.language," · ",M.period," · ",A," · ",M.license]})]}),n.jsx("div",{style:{display:"flex",gap:4,flexShrink:0},children:M.already_imported?n.jsx("span",{style:{fontSize:10,color:"#059669",fontWeight:700},children:"✓ Imported"}):I?n.jsx("button",{onClick:()=>void S(M),disabled:u===M.id,style:{...xn,background:u===M.id?"#d1d5db":"#059669",color:"#fff",border:"none",fontSize:10},children:u===M.id?"⏳":"↓ Import"}):n.jsx("a",{href:M.source_url,target:"_blank",rel:"noopener noreferrer",style:{...xn,textDecoration:"none",fontSize:10,color:"#374151"},title:`Source: ${M.source_url}`,children:"Source ↗"})})]},M.id)})]},F)),!c&&k.length===0&&r.length>0&&n.jsx("p",{style:{color:"#6b7280",fontSize:13},children:"No entries match your filters."}),!c&&r.length===0&&n.jsx("p",{style:{color:"#6b7280",fontSize:13},children:"Click ⟳ to load the catalogue."})]})]})}function mk(){const{toast:t}=nt(),[o,r]=x.useState([]),[l,c]=x.useState(!1),[d,u]=x.useState(!1),[p,g]=x.useState(""),[h,b]=x.useState(""),[y,v]=x.useState(""),w=async()=>{c(!0);try{r(await nj())}catch(S){t(S instanceof Error?S.message:"Failed to load","error")}finally{c(!1)}},j=S=>S.split(` +`).map(E=>E.trim()).filter(Boolean).map(E=>{const[k,D,H,...G]=E.split(/\s+|\t/);return{cipher:k??"",target:D??"",confidence:H??"high",note:G.join(" ")}}).filter(E=>E.cipher&&E.target),_=async()=>{if(!p.trim()){t("Name required","warning");return}try{const S=await ij({name:p.trim(),language:h.trim(),pairs:j(y)});r(E=>[S,...E]),u(!1),g(""),b(""),v(""),t("Anchor set created","success")}catch(S){t(S instanceof Error?S.message:"Create failed","error")}},C=async S=>{if(confirm("Delete this anchor set?"))try{await oj(S),r(E=>E.filter(k=>k.id!==S))}catch(E){t(E instanceof Error?E.message:"Delete failed","error")}};return x.useEffect(()=>{w()},[]),n.jsxs("details",{style:{marginBottom:"1.5rem"},children:[n.jsxs("summary",{style:{cursor:"pointer",fontWeight:600,fontSize:13,padding:"8px 0",color:"#7c3aed"},children:["⚓ Anchor Sets (",o.length,")"]}),n.jsxs("div",{style:{marginTop:10,padding:"1rem",border:"1px solid #ede9fe",borderRadius:8,background:"#faf5ff"},children:[n.jsxs("div",{style:{display:"flex",gap:8,marginBottom:10},children:[n.jsx("button",{onClick:()=>u(S=>!S),style:{...xn,background:"#7c3aed",color:"#fff",border:"none"},children:"+ New Set"}),n.jsx("button",{onClick:()=>void w(),style:xn,children:"⟳ Refresh"})]}),d&&n.jsxs("div",{style:{padding:12,border:"1px solid #a78bfa",borderRadius:6,marginBottom:12,background:"#fff"},children:[n.jsxs("div",{style:{display:"flex",gap:8,marginBottom:8},children:[n.jsxs("div",{style:{flex:2},children:[n.jsx("label",{style:$n,children:"Set Name"}),n.jsx("input",{value:p,onChange:S=>g(S.target.value),placeholder:"e.g. Fuls Ugaritic Anchors",style:hn})]}),n.jsxs("div",{style:{flex:1},children:[n.jsx("label",{style:$n,children:"Language (optional)"}),n.jsx("input",{value:h,onChange:S=>b(S.target.value),placeholder:"e.g. Ugaritic",style:hn})]})]}),n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("label",{style:$n,children:"Anchor Pairs (one per line: cipher target confidence note)"}),n.jsx("textarea",{value:y,onChange:S=>v(S.target.value),rows:5,style:{...hn,fontFamily:"monospace",fontSize:11,resize:"vertical"},placeholder:`004 T high Fuls verified 066 m high Fuls verified -208 n high Fuls verified`}),n.jsx("div",{style:{fontSize:10,color:"#6b7280",marginTop:2},children:"Format: cipher_sign target confidence(high/medium/low) note"})]}),n.jsxs("div",{style:{display:"flex",gap:8},children:[n.jsx("button",{onClick:()=>void _(),style:{...xn,background:"#7c3aed",color:"#fff",border:"none"},children:"Create"}),n.jsx("button",{onClick:()=>u(!1),style:xn,children:"Cancel"})]})]}),l&&n.jsx("p",{style:{fontSize:13,color:"#6b7280"},children:"Loading…"}),o.length===0&&!l&&n.jsx("p",{style:{fontSize:13,color:"#6b7280"},children:"No anchor sets yet. Create one above."}),o.map(w=>n.jsxs("div",{style:{border:"1px solid #ede9fe",borderRadius:6,padding:"8px 12px",marginBottom:6,background:"#fff"},children:[n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[n.jsxs("div",{style:{flex:1},children:[n.jsx("span",{style:{fontWeight:600,fontSize:12},children:w.name}),w.language&&n.jsx("span",{style:{fontSize:11,color:"#7c3aed",marginLeft:6},children:w.language}),n.jsxs("span",{style:{fontSize:11,color:"#9ca3af",marginLeft:6},children:[w.pairs.length," pairs"]})]}),n.jsx("button",{onClick:()=>T(w.id),style:{...or,color:"#dc2626",borderColor:"#fca5a5"},children:"Delete"})]}),w.pairs.length>0&&n.jsxs("div",{style:{marginTop:4,display:"flex",gap:4,flexWrap:"wrap"},children:[w.pairs.slice(0,8).map((C,j)=>n.jsxs("span",{style:{fontSize:10,padding:"1px 5px",borderRadius:4,background:C.confidence==="high"?"#d1fae5":C.confidence==="medium"?"#fef3c7":"#fee2e2",color:"#374151"},children:[C.cipher,"→",C.target]},j)),w.pairs.length>8&&n.jsxs("span",{style:{fontSize:10,color:"#9ca3af"},children:["+",w.pairs.length-8," more"]})]})]},w.id))]})]})}function fk({onSelect:t}){const[o,r]=x.useState([]),[l,c]=x.useState(!0),[d,u]=x.useState(null),p=async()=>{c(!0);try{r(await rd()),u(null)}catch(g){u(g instanceof Error?g.message:"Failed to load")}finally{c(!1)}};return x.useEffect(()=>{p()},[]),n.jsxs("div",{children:[n.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:"0.75rem"},children:[n.jsx("h2",{style:{margin:0},children:"Corpora"}),n.jsx("button",{onClick:p,style:{...es,background:"#6b7280",padding:"4px 12px",fontSize:12},children:"⟳ Refresh"})]}),n.jsx(ck,{onCreated:g=>r(h=>[g,...h])}),n.jsx(dk,{onImported:()=>void p()}),n.jsx(uk,{}),l&&n.jsx("p",{style:{color:"#6b7280",fontSize:13},children:"Loading…"}),d&&n.jsx("p",{style:{color:"#dc2626",fontSize:13},children:d}),!l&&!d&&o.length===0&&n.jsx("p",{style:{color:"#6b7280",fontSize:13},children:"No corpora yet. Upload or import one above."}),!l&&o.length>0&&n.jsxs("div",{children:[n.jsxs("div",{style:{fontSize:12,color:"#9ca3af",marginBottom:8},children:[o.length," corpus entries — click any row to expand"]}),o.map(g=>n.jsx(lk,{text:g,allTexts:o,onUpdated:h=>r(v=>v.map(y=>y.id===h.id?h:y)),onDeleted:h=>r(v=>v.filter(y=>y.id!==h))},g.id))]}),t&&o.length>0&&n.jsxs("div",{style:{marginTop:12},children:[n.jsx("div",{style:{fontSize:12,color:"#6b7280",marginBottom:6},children:"Quick-select:"}),n.jsx("div",{style:{display:"flex",gap:6,flexWrap:"wrap"},children:o.map(g=>n.jsx("button",{onClick:()=>t(g.id,g.name),style:xn,children:g.name},g.id))})]})]})}const sy={fontSize:10,fontWeight:700,color:"#7c3aed",textTransform:"uppercase",letterSpacing:.5,marginBottom:4},hn={width:"100%",padding:"5px 8px",border:"1px solid #d1d5db",borderRadius:4,fontSize:13,boxSizing:"border-box",display:"block"},$n={display:"block",fontWeight:600,fontSize:12,color:"#374151",marginBottom:3},es={background:"#2563eb",color:"#fff",border:"none",borderRadius:4,padding:"6px 14px",fontSize:12,cursor:"pointer",fontWeight:600,whiteSpace:"nowrap"},Nc={background:"#fff",color:"#374151",border:"1px solid #d1d5db",borderRadius:4,padding:"6px 14px",fontSize:12,cursor:"pointer",whiteSpace:"nowrap"},xn={padding:"3px 10px",border:"1px solid #e5e7eb",borderRadius:4,cursor:"pointer",fontSize:11,background:"#f9fafb",color:"#374151"},or={padding:"2px 7px",border:"1px solid #e5e7eb",borderRadius:4,cursor:"pointer",fontSize:10,background:"#f9fafb",color:"#374151"},Xs={textAlign:"left",padding:"4px 10px 4px 0",borderBottom:"2px solid #e5e7eb",color:"#374151"},Js={padding:"3px 10px 3px 0",borderBottom:"1px solid #f3f4f6",verticalAlign:"top"};function pk(t){const o=typeof t=="string"?new Date(t):t;return isNaN(o.getTime())?String(t):o.toLocaleTimeString(void 0,{hour:"numeric",minute:"2-digit",timeZoneName:"short"})}function Fc(t){const o=typeof t=="string"?new Date(t):t;if(isNaN(o.getTime()))return String(t);const r=new Date,l=o.getFullYear()===r.getFullYear();return o.toLocaleString(void 0,{month:"short",day:"numeric",...l?{}:{year:"numeric"},hour:"numeric",minute:"2-digit"})}function za(t){const o=Math.max(0,Math.round(t)),r=Math.floor(o/3600),l=Math.floor(o%3600/60),c=o%60;return`${String(r).padStart(2,"0")}:${String(l).padStart(2,"0")}:${String(c).padStart(2,"0")}`}const hk=new Set(["node_count","nodes_done","stall_reason"]);function gk(t){return Object.fromEntries(Object.entries(t).filter(([o])=>!o.startsWith("_")&&!hk.has(o)))}function mk(t){return t.replace(/_/g," ").replace(/\b\w/g,o=>o.toUpperCase())}function xk(t){return t==null?"—":typeof t=="boolean"?t?"Yes":"No":typeof t=="object"?JSON.stringify(t):String(t)}function yk(t){if(!t)return null;try{const o=JSON.parse(t);return typeof o=="object"&&o!==null?o:null}catch{return null}}function bk(t){const o=t.toLowerCase();return o.includes("no module")||o.includes("import")||o.includes("attribute")?{label:"Code / Import Error",color:"#7c3aed"}:o.includes("timeout")||o.includes("unreachable")||o.includes("network")?{label:"Network / Timeout",color:"#d97706"}:o.includes("database")||o.includes("sqlite")||o.includes("sql")?{label:"Database Error",color:"#0369a1"}:o.includes("key")||o.includes("auth")||o.includes("permission")?{label:"Auth / Permission",color:"#b45309"}:o.includes("assertion")||o.includes("assert")?{label:"Assertion Failed",color:"#9f1239"}:{label:"Experiment Error",color:"#991b1b"}}function Wb({title:t,message:o,detail:r,params:l,job:c,onRetry:d,onClose:u}){const p=`${t} +208 n high Fuls verified`}),n.jsx("div",{style:{fontSize:10,color:"#6b7280",marginTop:2},children:"Format: cipher_sign target confidence(high/medium/low) note"})]}),n.jsxs("div",{style:{display:"flex",gap:8},children:[n.jsx("button",{onClick:()=>void _(),style:{...xn,background:"#7c3aed",color:"#fff",border:"none"},children:"Create"}),n.jsx("button",{onClick:()=>u(!1),style:xn,children:"Cancel"})]})]}),l&&n.jsx("p",{style:{fontSize:13,color:"#6b7280"},children:"Loading…"}),o.length===0&&!l&&n.jsx("p",{style:{fontSize:13,color:"#6b7280"},children:"No anchor sets yet. Create one above."}),o.map(S=>n.jsxs("div",{style:{border:"1px solid #ede9fe",borderRadius:6,padding:"8px 12px",marginBottom:6,background:"#fff"},children:[n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[n.jsxs("div",{style:{flex:1},children:[n.jsx("span",{style:{fontWeight:600,fontSize:12},children:S.name}),S.language&&n.jsx("span",{style:{fontSize:11,color:"#7c3aed",marginLeft:6},children:S.language}),n.jsxs("span",{style:{fontSize:11,color:"#9ca3af",marginLeft:6},children:[S.pairs.length," pairs"]})]}),n.jsx("button",{onClick:()=>C(S.id),style:{...or,color:"#dc2626",borderColor:"#fca5a5"},children:"Delete"})]}),S.pairs.length>0&&n.jsxs("div",{style:{marginTop:4,display:"flex",gap:4,flexWrap:"wrap"},children:[S.pairs.slice(0,8).map((E,k)=>n.jsxs("span",{style:{fontSize:10,padding:"1px 5px",borderRadius:4,background:E.confidence==="high"?"#d1fae5":E.confidence==="medium"?"#fef3c7":"#fee2e2",color:"#374151"},children:[E.cipher,"→",E.target]},k)),S.pairs.length>8&&n.jsxs("span",{style:{fontSize:10,color:"#9ca3af"},children:["+",S.pairs.length-8," more"]})]})]},S.id))]})]})}function xk({onSelect:t}){const[o,r]=x.useState([]),[l,c]=x.useState(!0),[d,u]=x.useState(null),p=async()=>{c(!0);try{r(await ad()),u(null)}catch(g){u(g instanceof Error?g.message:"Failed to load")}finally{c(!1)}};return x.useEffect(()=>{p()},[]),n.jsxs("div",{children:[n.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:"0.75rem"},children:[n.jsx("h2",{style:{margin:0},children:"Corpora"}),n.jsx("button",{onClick:p,style:{...ts,background:"#6b7280",padding:"4px 12px",fontSize:12},children:"⟳ Refresh"})]}),n.jsx(hk,{onCreated:g=>r(h=>[g,...h])}),n.jsx(gk,{onImported:()=>void p()}),n.jsx(mk,{}),l&&n.jsx("p",{style:{color:"#6b7280",fontSize:13},children:"Loading…"}),d&&n.jsx("p",{style:{color:"#dc2626",fontSize:13},children:d}),!l&&!d&&o.length===0&&n.jsx("p",{style:{color:"#6b7280",fontSize:13},children:"No corpora yet. Upload or import one above."}),!l&&o.length>0&&n.jsxs("div",{children:[n.jsxs("div",{style:{fontSize:12,color:"#9ca3af",marginBottom:8},children:[o.length," corpus entries — click any row to expand"]}),o.map(g=>n.jsx(pk,{text:g,allTexts:o,onUpdated:h=>r(b=>b.map(y=>y.id===h.id?h:y)),onDeleted:h=>r(b=>b.filter(y=>y.id!==h))},g.id))]}),t&&o.length>0&&n.jsxs("div",{style:{marginTop:12},children:[n.jsx("div",{style:{fontSize:12,color:"#6b7280",marginBottom:6},children:"Quick-select:"}),n.jsx("div",{style:{display:"flex",gap:6,flexWrap:"wrap"},children:o.map(g=>n.jsx("button",{onClick:()=>t(g.id,g.name),style:xn,children:g.name},g.id))})]})]})}const oy={fontSize:10,fontWeight:700,color:"#7c3aed",textTransform:"uppercase",letterSpacing:.5,marginBottom:4},hn={width:"100%",padding:"5px 8px",border:"1px solid #d1d5db",borderRadius:4,fontSize:13,boxSizing:"border-box",display:"block"},$n={display:"block",fontWeight:600,fontSize:12,color:"#374151",marginBottom:3},ts={background:"#2563eb",color:"#fff",border:"none",borderRadius:4,padding:"6px 14px",fontSize:12,cursor:"pointer",fontWeight:600,whiteSpace:"nowrap"},Oc={background:"#fff",color:"#374151",border:"1px solid #d1d5db",borderRadius:4,padding:"6px 14px",fontSize:12,cursor:"pointer",whiteSpace:"nowrap"},xn={padding:"3px 10px",border:"1px solid #e5e7eb",borderRadius:4,cursor:"pointer",fontSize:11,background:"#f9fafb",color:"#374151"},or={padding:"2px 7px",border:"1px solid #e5e7eb",borderRadius:4,cursor:"pointer",fontSize:10,background:"#f9fafb",color:"#374151"},Js={textAlign:"left",padding:"4px 10px 4px 0",borderBottom:"2px solid #e5e7eb",color:"#374151"},Ks={padding:"3px 10px 3px 0",borderBottom:"1px solid #f3f4f6",verticalAlign:"top"};function yk(t){const o=typeof t=="string"?new Date(t):t;return isNaN(o.getTime())?String(t):o.toLocaleTimeString(void 0,{hour:"numeric",minute:"2-digit",timeZoneName:"short"})}function Yc(t){const o=typeof t=="string"?new Date(t):t;if(isNaN(o.getTime()))return String(t);const r=new Date,l=o.getFullYear()===r.getFullYear();return o.toLocaleString(void 0,{month:"short",day:"numeric",...l?{}:{year:"numeric"},hour:"numeric",minute:"2-digit"})}function Ea(t){const o=Math.max(0,Math.round(t)),r=Math.floor(o/3600),l=Math.floor(o%3600/60),c=o%60;return`${String(r).padStart(2,"0")}:${String(l).padStart(2,"0")}:${String(c).padStart(2,"0")}`}const bk=new Set(["node_count","nodes_done","stall_reason"]);function vk(t){return Object.fromEntries(Object.entries(t).filter(([o])=>!o.startsWith("_")&&!bk.has(o)))}function Sk(t){return t.replace(/_/g," ").replace(/\b\w/g,o=>o.toUpperCase())}function wk(t){return t==null?"—":typeof t=="boolean"?t?"Yes":"No":typeof t=="object"?JSON.stringify(t):String(t)}function jk(t){if(!t)return null;try{const o=JSON.parse(t);return typeof o=="object"&&o!==null?o:null}catch{return null}}function kk(t){const o=t.toLowerCase();return o.includes("no module")||o.includes("import")||o.includes("attribute")?{label:"Code / Import Error",color:"#7c3aed"}:o.includes("timeout")||o.includes("unreachable")||o.includes("network")?{label:"Network / Timeout",color:"#d97706"}:o.includes("database")||o.includes("sqlite")||o.includes("sql")?{label:"Database Error",color:"#0369a1"}:o.includes("key")||o.includes("auth")||o.includes("permission")?{label:"Auth / Permission",color:"#b45309"}:o.includes("assertion")||o.includes("assert")?{label:"Assertion Failed",color:"#9f1239"}:{label:"Experiment Error",color:"#991b1b"}}function Ub({title:t,message:o,detail:r,params:l,job:c,onRetry:d,onClose:u}){const p=`${t} ${o}${r?` -`+r:""}`,[g,h]=x.useState(!1),[v,y]=x.useState(!1),b=()=>{navigator.clipboard.writeText(p).then(()=>{h(!0),setTimeout(()=>h(!1),1500)})},S=yk(o),k=S?S.error??S.message??JSON.stringify(S,null,2):o,_=bk(k||""),T=r??null;return n.jsx("div",{style:{position:"fixed",inset:0,background:"rgba(0,0,0,0.55)",zIndex:12e3,display:"flex",alignItems:"center",justifyContent:"center",padding:20},onClick:u,children:n.jsxs("div",{style:{background:"#fff",borderRadius:12,maxWidth:720,width:"100%",maxHeight:"85vh",display:"flex",flexDirection:"column",boxShadow:"0 24px 64px rgba(0,0,0,0.4)"},onClick:w=>w.stopPropagation(),children:[n.jsxs("div",{style:{padding:"16px 20px",borderBottom:"1px solid #fee2e2",background:"#fef2f2",borderRadius:"12px 12px 0 0",display:"flex",alignItems:"center",gap:10},children:[n.jsx("span",{style:{fontSize:22},children:"⚠️"}),n.jsxs("div",{style:{flex:1,minWidth:0},children:[n.jsx("div",{style:{fontWeight:700,fontSize:14,color:"#991b1b",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},title:t,children:t}),n.jsx("span",{style:{fontSize:11,padding:"1px 7px",borderRadius:8,background:_.color+"20",color:_.color,fontWeight:600},children:_.label})]}),n.jsx("button",{onClick:b,style:{padding:"4px 10px",border:"1px solid #fca5a5",borderRadius:5,background:g?"#fee2e2":"#fff",cursor:"pointer",fontSize:11,color:g?"#16a34a":"#dc2626"},children:g?"✓ Copied":"📋 Copy"}),n.jsx("button",{onClick:u,style:{border:"none",background:"none",cursor:"pointer",fontSize:22,color:"#9ca3af",lineHeight:1,padding:"0 4px"},children:"×"})]}),n.jsxs("div",{style:{flex:1,overflowY:"auto"},children:[n.jsxs("div",{style:{padding:"14px 20px",borderBottom:"1px solid #f3f4f6"},children:[n.jsx("div",{style:{fontSize:12,fontWeight:600,color:"#374151",marginBottom:6,textTransform:"uppercase",letterSpacing:"0.05em"},children:"What went wrong"}),n.jsx("div",{style:{fontSize:13,color:"#111827",lineHeight:1.7,background:"#fef2f2",padding:"10px 14px",borderRadius:7,border:"1px solid #fecaca",whiteSpace:"pre-wrap",wordBreak:"break-word"},children:k||"No error message available."})]}),l&&Object.keys(l).filter(w=>!w.startsWith("_")).length>0&&n.jsxs("div",{style:{padding:"12px 20px",borderBottom:"1px solid #f3f4f6"},children:[n.jsx("div",{style:{fontSize:12,fontWeight:600,color:"#374151",marginBottom:8,textTransform:"uppercase",letterSpacing:"0.05em"},children:"Job parameters"}),n.jsx("table",{style:{width:"100%",borderCollapse:"collapse",fontSize:12},children:n.jsx("tbody",{children:Object.entries(l).filter(([w])=>!w.startsWith("_")&&w!=="traceback").map(([w,C])=>n.jsxs("tr",{style:{borderBottom:"1px solid #f3f4f6"},children:[n.jsx("td",{style:{padding:"4px 10px 4px 0",color:"#6b7280",fontWeight:500,whiteSpace:"nowrap",verticalAlign:"top",width:"35%"},children:mk(w)}),n.jsx("td",{style:{padding:"4px 0",color:"#111827",wordBreak:"break-all",fontFamily:typeof C=="string"?"inherit":"monospace"},children:xk(C)})]},w))})})]}),T&&n.jsxs("div",{style:{padding:"12px 20px"},children:[n.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:6},children:[n.jsx("div",{style:{fontSize:12,fontWeight:600,color:"#374151",textTransform:"uppercase",letterSpacing:"0.05em"},children:"Stack trace"}),n.jsx("button",{onClick:()=>y(!v),style:{fontSize:11,border:"1px solid #e5e7eb",background:"#f9fafb",borderRadius:4,cursor:"pointer",padding:"2px 8px",color:"#6b7280"},children:v?"Hide":"Show"})]}),v&&n.jsx("pre",{style:{fontFamily:"monospace",fontSize:11,color:"#374151",background:"#f8fafc",padding:"10px 14px",borderRadius:7,border:"1px solid #e5e7eb",lineHeight:1.6,whiteSpace:"pre-wrap",wordBreak:"break-word",margin:0,maxHeight:260,overflowY:"auto"},children:T})]})]}),n.jsxs("div",{style:{padding:"12px 20px",borderTop:"1px solid #f3f4f6",display:"flex",justifyContent:"space-between",alignItems:"center",gap:8},children:[c&&n.jsxs("div",{style:{fontSize:10,color:"#9ca3af",fontFamily:"monospace"},children:["Job ID: ",c.id.slice(0,12),"… · ",c.pipeline]}),n.jsxs("div",{style:{display:"flex",gap:8,marginLeft:"auto"},children:[d&&n.jsx("button",{onClick:()=>{d(),u()},style:{padding:"6px 16px",border:"none",borderRadius:6,background:"#2563eb",color:"#fff",cursor:"pointer",fontSize:13,fontWeight:600},title:"Re-submit this job with the same parameters",children:"↻ Retry"}),n.jsx("button",{onClick:u,style:{padding:"6px 18px",border:"1px solid #d1d5db",borderRadius:6,background:"#fff",cursor:"pointer",fontSize:13},children:"Close"})]})]})]})})}function vk(){const[t,o]=x.useState([]),[r,l]=x.useState(!0),[c,d]=x.useState(!1),[u,p]=x.useState(null),[g,h]=x.useState(null),[v,y]=x.useState([]),[b,S]=x.useState(!1),[k,_]=x.useState(new Set),T=x.useRef(new Map),[w,C]=x.useState(""),[j,L]=x.useState("block_entropy"),[W,P]=x.useState('{"text_id": ""}'),[z,M]=x.useState(!1),[q,K]=x.useState(null),[D,Y]=x.useState(null),H=x.useCallback(async(I=!1)=>{I&&d(!0);try{const J=await Ba();o(J.sort((ne,se)=>se.created_at.localeCompare(ne.created_at))),p(new Date),h(null)}catch(J){h(J instanceof Error?J.message:"Failed to load jobs")}finally{l(!1),I&&d(!1)}},[]);x.useEffect(()=>{H();const I=setInterval(H,3e3);return yb().then(y).catch(()=>{}),()=>clearInterval(I)},[H]);const A=x.useCallback(I=>async()=>{try{await Gc({name:`${I.name} (retry)`,pipeline:I.pipeline,params:gk(I.params??{})}),await H()}catch(J){alert(J instanceof Error?J.message:"Retry failed")}},[H]),G=async()=>{if(confirm("Delete all jobs and results?")){S(!0);try{await pp(),await H()}finally{S(!1)}}},R=async()=>{if(!w.trim()){K("Job name is required");return}let I;try{I=JSON.parse(W)}catch{K("Params must be valid JSON");return}try{M(!0),K(null),await Gc({name:w.trim(),pipeline:j,params:I}),C(""),await H()}catch(J){K(J instanceof Error?J.message:"Submit failed")}finally{M(!1)}},X=async I=>{var pe,_e;const J=((pe=I.params)==null?void 0:pe.exp_id)??"",ne=((_e=I.params)==null?void 0:_e.result_file)??"",se=J?`${J}.json`:ne;if(I.status==="failed"){const we={};for(const[ke,te]of Object.entries(I.params??{}))!ke.startsWith("_")&&ke!=="traceback"&&(we[ke]=te);try{const te=await xb(I.id),de=te.error??te.message??te.detail??JSON.stringify(te).slice(0,300),Ce=te.traceback??null;Y({title:I.name,message:de||"Unknown error — see stack trace below.",detail:Ce??void 0,params:Object.keys(we).length?we:null,job:I,onRetry:A(I)})}catch{Y({title:I.name,message:"Job failed — no error details stored in the database.",detail:void 0,params:Object.keys(we).length?we:null,job:I,onRetry:A(I)})}return}window.dispatchEvent(new CustomEvent("glossa:navigate",{detail:{view:"reports"}})),se&&setTimeout(()=>{window.dispatchEvent(new CustomEvent("glossa:reports_highlight",{detail:{tab:"data",search:se}}))},120)},B=async I=>{try{await fp(I),await H()}catch(J){alert(J instanceof Error?J.message:"Cancel failed")}},V=async I=>{_(J=>new Set([...J,I]));try{await pb(I),await H()}catch(J){alert(J instanceof Error?J.message:"Pause failed")}finally{_(J=>{const ne=new Set(J);return ne.delete(I),ne})}},Q=async I=>{_(J=>new Set([...J,I]));try{await hb(I),await H()}catch(J){alert(J instanceof Error?J.message:"Resume failed")}finally{_(J=>{const ne=new Set(J);return ne.delete(I),ne})}},N=async()=>{try{await gb(),await H()}catch(I){alert(I instanceof Error?I.message:"Pause all failed")}},O=async()=>{try{await mb(),await H()}catch(I){alert(I instanceof Error?I.message:"Resume all failed")}},$=I=>I==="completed"?"#16a34a":I==="failed"?"#dc2626":I==="running"?"#2563eb":I==="pending"?"#d97706":I==="paused"?"#92400e":"#6b7280",F=I=>I==="completed"?"#dcfce7":I==="failed"?"#fee2e2":I==="running"?"#dbeafe":I==="pending"||I==="paused"?"#fef3c7":"#f3f4f6";return n.jsxs("div",{children:[n.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:4},children:[n.jsxs("div",{style:{display:"flex",alignItems:"baseline",gap:10},children:[n.jsx("h2",{style:{margin:0},children:"Jobs"}),u&&n.jsxs("span",{style:{fontSize:11,color:"#9ca3af"},children:["updated ",pk(u)]})]}),n.jsxs("div",{style:{display:"flex",gap:6},children:[n.jsx("button",{onClick:()=>H(!0),disabled:c,style:{...bi,background:"#f3f4f6",color:"#374151",fontSize:12,padding:"4px 12px"},title:"Manually refresh the job list",children:c?"Refreshing…":"⟳ Refresh"}),n.jsx("button",{onClick:N,disabled:t.filter(I=>I.status==="pending"||I.status==="running").length===0,style:{...bi,background:"#d97706",fontSize:12,padding:"4px 12px"},title:"Pause all pending and running jobs",children:"⏸ Pause All"}),n.jsx("button",{onClick:O,disabled:t.filter(I=>I.status==="paused").length===0,style:{...bi,background:"#059669",fontSize:12,padding:"4px 12px"},title:"Resume all paused jobs",children:"▶ Resume All"}),n.jsx("button",{onClick:G,disabled:b||t.length===0,style:{...bi,background:"#6b7280",fontSize:12,padding:"4px 12px"},children:b?"Clearing…":"Delete All"})]})]}),n.jsxs("details",{style:{marginBottom:"1.5rem"},children:[n.jsx("summary",{style:{cursor:"pointer",fontWeight:600},children:"+ Submit new job"}),n.jsxs("div",{style:{marginTop:"0.75rem",padding:"1rem",border:"1px solid #e5e7eb",borderRadius:6,maxWidth:560},children:[n.jsx(Of,{label:"Job name",children:n.jsx("input",{value:w,onChange:I=>C(I.target.value),placeholder:"e.g. Entropy analysis — English",style:If})}),n.jsx(Of,{label:"Pipeline",children:n.jsx("select",{value:j,onChange:I=>{L(I.target.value);const J=v.find(ne=>ne.id===I.target.value);P(J?JSON.stringify(J.default_params,null,2):'{"text_id": ""}')},style:If,children:(v.length>0?v.map(I=>I.id):[j]).map(I=>n.jsx("option",{value:I,children:I},I))})}),n.jsx(Of,{label:"Parameters (JSON)",children:n.jsx("textarea",{value:W,onChange:I=>P(I.target.value),rows:4,style:{...If,fontFamily:"monospace",resize:"vertical"}})}),q&&n.jsx("p",{style:{color:"#dc2626",margin:"4px 0"},children:q}),n.jsx("button",{onClick:R,disabled:z,style:bi,children:z?"Submitting…":"Submit"})]})]}),r&&n.jsx("p",{children:"Loading…"}),g&&n.jsx("p",{style:{color:"#dc2626"},children:g}),!r&&t.length===0&&n.jsxs("div",{style:{padding:"1.25rem 1.5rem",background:"#f8fafc",border:"1px solid #e2e8f0",borderRadius:8,maxWidth:560},children:[n.jsx("p",{style:{margin:"0 0 8px",fontWeight:600,color:"#374151",fontSize:13},children:"No pipeline jobs yet"}),n.jsxs("p",{style:{margin:"0 0 6px",fontSize:12,color:"#6b7280",lineHeight:1.6},children:["This tab tracks analysis pipelines submitted through the",n.jsx("strong",{children:" Submit new job"})," panel above. Pipeline jobs run corpus analysis (block entropy, NWSP, hypothesis engine, etc.) on corpora you upload to the Corpora tab."]}),n.jsxs("p",{style:{margin:0,fontSize:12,color:"#6b7280",lineHeight:1.6},children:[n.jsx("strong",{children:"Note:"})," background scripts like OCR run separately and do not appear here — check the ",n.jsx("strong",{children:"Experiments"})," tab to run or stream those."]})]}),t.length>0&&n.jsxs("table",{style:{borderCollapse:"collapse",width:"100%"},children:[n.jsx("thead",{children:n.jsx("tr",{children:["Name","Pipeline","Device","Status","Created","Actions"].map(I=>n.jsx(Sk,{children:I},I))})}),n.jsx("tbody",{children:t.map(I=>{var Oe,dt,it,lt,Je,yt,Jt;const J=((Oe=I.params)==null?void 0:Oe.compute_device)??"",ne=((dt=I.params)==null?void 0:dt.compute_device_label)??"",se=J==="gpu",pe=((it=I.params)==null?void 0:it.source)==="cli",_e=((lt=I.params)==null?void 0:lt.source)==="ai_action",we=J?{bg:se?"#dbeafe":"#f3f4f6",color:se?"#1e40af":"#374151",text:se?`⚡ ${ne||"GPU"}`:`⚙️ ${ne||"CPU"}`}:null,ke=((Je=I.params)==null?void 0:Je.node_count)??0,te=((yt=I.params)==null?void 0:yt.nodes_done)??0,de=ke>0?Math.round(te/ke*100):null,Ce=I.pipeline==="exp_run",ze=((Jt=I.params)==null?void 0:Jt.resource_wait)??null,ve=I.status==="running"?Math.round((Date.now()-new Date(I.created_at).getTime())/1e3):null,De=(()=>{const rn=t.filter(ae=>ae.status==="completed"&&ae.pipeline===I.pipeline&&ae.id!==I.id&&ae.updated_at);if(rn.length===0)return null;const zt=rn.map(ae=>(new Date(ae.updated_at).getTime()-new Date(ae.created_at).getTime())/1e3).filter(ae=>ae>0);return zt.length>0?zt.reduce((ae,He)=>ae+He,0)/zt.length:null})(),Me=ve!==null&&de!==null?de>=15?Math.round(ve/de*(100-de)):De!==null?Math.max(0,Math.round(De-ve)):null:null,Ve=Date.now(),Le=T.current.get(I.id);(!Le||Le.done!==te)&&T.current.set(I.id,{done:te,since:Ve});const Ae=Le&&Le.done===te?Ve-Le.since:0,Ue=Ce&&I.status==="running"&&ke>0&&Ae>18e4&&Me!==null&&ve!==null&&Me>ve*1.5?`node ${te+1}/${ke} computing…`:null;return n.jsxs("tr",{children:[n.jsxs(Ks,{children:[n.jsx("div",{style:{fontWeight:500},children:I.name}),n.jsxs("div",{style:{fontSize:11,color:"#6b7280",fontFamily:"monospace"},children:[I.id.slice(0,8),"…"]}),I.status==="pending"&&ze&&n.jsxs("div",{style:{marginTop:4,fontSize:10,color:"#92400e",background:"#fef3c7",border:"1px solid #fcd34d",borderRadius:4,padding:"2px 7px",display:"flex",alignItems:"center",gap:4},children:[n.jsx("span",{children:"⏳"}),n.jsx("span",{children:ze})]}),I.status==="running"&&Ce&&ke>0&&n.jsxs("div",{style:{marginTop:4,display:"flex",alignItems:"center",gap:6},children:[n.jsx("div",{style:{flex:1,height:4,background:"#e5e7eb",borderRadius:2,overflow:"hidden"},children:n.jsx("div",{style:{height:"100%",width:`${de??0}%`,background:"#2563eb",borderRadius:2,transition:"width 0.5s"}})}),n.jsxs("span",{style:{fontSize:10,color:"#6b7280",whiteSpace:"nowrap"},children:[te,"/",ke," nodes",de!==null?` (${de}%)`:"",ve!==null&&` · ${za(ve)}`,Ue?` · ${Ue}`:Me!==null?` · ~${za(Me)} left`:""]})]})]}),n.jsx(Ks,{children:n.jsx("code",{style:{fontSize:12},children:I.pipeline})}),n.jsx(Ks,{children:n.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:3},children:[we&&n.jsx("span",{style:{fontSize:11,padding:"2px 7px",borderRadius:6,background:we.bg,color:we.color,fontWeight:600,whiteSpace:"nowrap"},children:we.text}),pe&&n.jsx("span",{style:{fontSize:11,padding:"2px 7px",borderRadius:6,background:"#f0fdf4",color:"#15803d",fontWeight:600,whiteSpace:"nowrap"},title:"Run from CLI (terminal/script)",children:"💻 CLI"}),_e&&n.jsx("span",{style:{fontSize:11,padding:"2px 7px",borderRadius:6,background:"#fdf4ff",color:"#7e22ce",fontWeight:600,whiteSpace:"nowrap"},title:"Triggered by AI assistant",children:"✨ AI"}),!we&&!pe&&!_e&&n.jsx("span",{style:{fontSize:11,color:"#9ca3af"},children:"—"})]})}),n.jsxs(Ks,{children:[n.jsx("span",{style:{display:"inline-block",padding:"1px 7px",borderRadius:10,background:F(I.status),color:$(I.status),fontWeight:700,fontSize:11},children:I.status}),I.status==="running"&&ve!==null&&!Ce&&n.jsxs("div",{style:{fontSize:10,color:"#9ca3af"},children:[za(ve??0)," elapsed"]})]}),n.jsx(Ks,{children:Fc(I.created_at)}),n.jsx(Ks,{children:n.jsxs("span",{style:{display:"flex",gap:6,flexWrap:"wrap"},children:[I.status==="completed"&&n.jsx("button",{style:{...bi,padding:"2px 10px",fontSize:12,background:"#059669"},onClick:()=>X(I),title:"Open result in Reports → Data tab",children:"📂 View in Reports"}),I.status==="failed"&&n.jsx("button",{style:{...bi,padding:"2px 10px",fontSize:12,background:"#dc2626"},onClick:()=>X(I),title:"View error details",children:"⚠ Error Details"}),I.status==="cancelled"&&n.jsx("span",{style:{fontSize:11,color:"#6b7280",fontStyle:"italic"},children:"cancelled"}),(I.status==="pending"||I.status==="running")&&n.jsxs(n.Fragment,{children:[n.jsx("button",{style:{...bi,padding:"2px 10px",fontSize:12,background:"#d97706"},onClick:()=>V(I.id),disabled:k.has(I.id),title:"Pause this job",children:k.has(I.id)?"…":"⏸ Pause"}),n.jsx("button",{style:{...bi,padding:"2px 10px",fontSize:12,background:I.status==="running"?"#ea580c":"#6b7280"},onClick:()=>B(I.id),title:I.status==="running"?"Abort this running job":"Cancel this queued job",children:I.status==="running"?"❌ Abort":"⏸ Cancel"})]}),I.status==="paused"&&n.jsx("button",{style:{...bi,padding:"2px 10px",fontSize:12,background:"#059669"},onClick:()=>Q(I.id),disabled:k.has(I.id),title:"Resume this paused job",children:k.has(I.id)?"…":"▶ Resume"})]})})]},I.id)})})]}),D&&n.jsx(Wb,{title:D.title,message:D.message,detail:D.detail,params:D.params,job:D.job,onRetry:D.onRetry,onClose:()=>Y(null)})]})}function Of({label:t,children:o}){return n.jsxs("div",{style:{marginBottom:"0.6rem"},children:[n.jsx("label",{style:{display:"block",fontWeight:500,marginBottom:2,fontSize:13},children:t}),o]})}function Sk({children:t}){return n.jsx("th",{style:{textAlign:"left",padding:"4px 12px 4px 0",borderBottom:"2px solid #e5e7eb",fontSize:13,color:"#374151",whiteSpace:"nowrap"},children:t})}function Ks({children:t}){return n.jsx("td",{style:{padding:"5px 12px 5px 0",borderBottom:"1px solid #f3f4f6",fontSize:13,verticalAlign:"top"},children:t})}const If={width:"100%",padding:"5px 8px",border:"1px solid #d1d5db",borderRadius:4,fontSize:13,boxSizing:"border-box"},bi={background:"#2563eb",color:"#fff",border:"none",borderRadius:4,padding:"6px 16px",fontSize:13,cursor:"pointer"},wk=[{id:"block_entropy",label:"Block Entropy",group:"Statistical (no LM)",description:"Computes H_n (normalized) for n = 1..max_n. Sub-linear growth is the hallmark of natural language (Rao 2009). Used to confirm Indus H1 = 0.739.",inputs:"text_id, max_n (default 6)",outputs:"block_entropies[], normalized values, linguistic classification",defaultParams:'{"text_id": "", "max_n": 6}',needsLM:!1},{id:"char_freq",label:"Character Frequency",group:"Statistical (no LM)",description:"Sign frequency distribution with Zipf exponent fit. Yadav (2010) found Indus follows Zipf-Mandelbrot with α≈1.00; we measured 1.555 from Fuls catalog.",inputs:"text_id",outputs:"frequencies, rank_frequency[], zipf_exponent",defaultParams:'{"text_id": ""}',needsLM:!1},{id:"positional",label:"Positional Analysis",group:"Statistical (no LM)",description:"For each sign: initial_rate, medial_rate, terminal_rate. Identifies dominant positional preferences. Validated against known TMK/INITIAL signs in Fuls catalog.",inputs:"text_id",outputs:"profiles[] per sign with dominant_position",defaultParams:'{"text_id": ""}',needsLM:!1},{id:"nwsp",label:"NWSP — Fuls Method",group:"Statistical (no LM)",description:"Exact implementation of Fuls (2013) Normalized Weighted Sign Position. NWP(p,L) = (p-1)/(L-1)*9+1, weight=L. Classifies signs as ITM/TMK/INITIAL/NUM/CON/MED. Maps to Fuls' ICIT function codes.",inputs:"text_id, min_occurrences (default 4)",outputs:"signs[] with histogram, classification, ICIT code mapping",defaultParams:'{"text_id": "", "min_occurrences": 4}',needsLM:!1},{id:"sign_polyvalence",label:"Sign Polyvalence",group:"Statistical (no LM)",description:"Detects signs with bimodal positional histograms — the hallmark of polyvalent signs serving dual functions. Reproduces Fuls' sign 550 analysis. 74% of Indus signs show bimodal patterns (logo-syllabic expected).",inputs:"text_id, min_freq (default 5)",outputs:"candidates[] sorted by bimodality_score",defaultParams:'{"text_id": "", "min_freq": 5}',needsLM:!1},{id:"sign_cluster",label:"Sign Clustering",group:"Statistical (no LM)",description:"Distributional clustering: groups signs by similar co-occurrence contexts. Signs appearing before/after the same other signs cluster together.",inputs:"text_id, min_freq, top_n",outputs:"clusters[] with member signs",defaultParams:'{"text_id": "", "min_freq": 3, "top_n": 20}',needsLM:!1},{id:"cooccurrence",label:"Co-occurrence Network",group:"Statistical (no LM)",description:"Builds a sign co-occurrence graph and detects communities using the Louvain algorithm. Community structure reveals semantic groupings.",inputs:"text_id, window (default 2), min_freq, min_edge_weight",outputs:"node_count, edge_count, community_count, communities[]",defaultParams:'{"text_id": "", "window": 2, "min_freq": 3, "min_edge_weight": 2}',needsLM:!1},{id:"paradigm",label:"Paradigm Detection",group:"Statistical (no LM)",description:"Finds paradigmatic alternations: same stem, different suffix. High paradigm count indicates rich morphological system. Indus: 102 paradigms vs Ugaritic: 2.",inputs:"text_id, min_stem_freq, min_variants",outputs:"paradigm_count, paradigms[]",defaultParams:'{"text_id": "", "min_stem_freq": 2, "min_variants": 2}',needsLM:!1},{id:"structural_fingerprint",label:"Structural Fingerprint",group:"Statistical (no LM)",description:"10-dimensional fingerprint: H1, H2/H1, Zipf-α, V/N, hapax%, mean positional entropy, polyvalence%, inscription length, boundary-bias variance, paradigmatic rate. GPU-accelerated comparison against database of 9 known writing systems.",inputs:"text_id, compare_to_db (default true)",outputs:"vector[10], dimensions{}, nearest_scripts[], notes[]",defaultParams:'{"text_id": "", "compare_to_db": true}',needsLM:!1},{id:"sign_function_estimator",label:"Sign Function Estimator",group:"Statistical (no LM)",description:"Probabilistic classifier: P(numeral), P(determinative), P(logogram), P(phonetic), P(boundary_marker) per sign. Uses 9 distributional features. Calibration note: undercalibrated for short-inscription corpora.",inputs:"text_id, min_freq (default 3)",outputs:"signs[] with probabilities, system_summary, interpretation",defaultParams:'{"text_id": "", "min_freq": 3}',needsLM:!1},{id:"numerals",label:"Numeral Detection",group:"Statistical (no LM)",description:"Identifies likely numeral signs by positional context and frequency patterns. Numerals appear before commodity signs at consistent positions.",inputs:"text_id",outputs:"numeral_candidates[], numeral_patterns[]",defaultParams:'{"text_id": ""}',needsLM:!1},{id:"word_structure_hypothesis",label:"Word-Structure Typology",group:"Statistical (no LM)",description:"Tests inscription length distribution against 6 language family profiles. No phoneme assumptions. Result: Proto-Dravidian ranks first for Indus (KL=0.444 vs Sumerian 0.742). Validated on Ugaritic, Linear B, Sumerian.",inputs:"text_id",outputs:"ranked_hypotheses[], winner, margin",defaultParams:'{"text_id": ""}',needsLM:!1},{id:"distributional_decipherment",label:"Distributional Decipherment",group:"Statistical (no LM)",description:"Jensen-Shannon divergence clustering and Ventris grid method without language assumptions. Groups signs by vowel class (similar left context) and consonant class (similar right context). GPU-backed N×N cosine similarity matrix.",inputs:"text_id, target_language",outputs:"vowel_clusters[], consonant_clusters[], sign_classification{}",defaultParams:'{"text_id": "", "target_language": "generic"}',needsLM:!1},{id:"logosyllabic",label:"Logosyllabic Analysis (Ventris)",group:"Statistical (no LM)",description:"Full Ventris-style analysis: sign classification (logogram/syllabogram/determinative) + affinity clustering (GPU cosine, complete-linkage) + candidate CV readings + vocabulary matching.",inputs:"text_id, target_language (sumerian|linear_b|generic)",outputs:"sign_classification{}, affinity{}, proposed_readings{}, candidate_words[]",defaultParams:'{"text_id": "", "target_language": "generic"}',needsLM:!1},{id:"kandles",label:"Kandles Fingerprint",group:"Language Model Required",description:"phonetic distribution (US ) phonological colour fingerprint. Maps signs to 8 colour groups by initial sound. Compares grid distributions via cosine similarity. Language-specific bias profiles for Luwian, Hurrian, Semitic, Dravidian.",inputs:"text_id, mode (color_code|grid|compare), profile",outputs:"color_distribution{}, similarity score",defaultParams:'{"text_id": "", "mode": "grid"}',needsLM:!0},{id:"decipher",label:"Decipher (SA + Structural Constraints)",group:"Language Model Required",description:"Simulated-annealing substitution cipher solver with Semitic structural constraints and cognate anchors. Constraints: use_word_bigrams, ocp_weight, root_prior_weight (root co-occurrence prior), positional_weight. anchors: dict of locked cipher→target sign correspondences (e.g. pan-Semitic cognates). Validated: Tier 1b 100%, Tier 2B 66.7%, Tier 1a 6.7% mean (best 20% at 25 restarts). See also: beam_decipher_benchmark for systematic search.",inputs:"text_id, target_text_id, max_iterations, restarts, use_word_bigrams, ocp_weight, root_prior_weight, positional_weight, anchors",outputs:"proposed_mapping{}, kandles_confidence, score",defaultParams:'{"text_id": "", "target_text_id": "", "max_iterations": 12000, "restarts": 8, "use_word_bigrams": false, "ocp_weight": 0.0, "positional_weight": 0.005}',needsLM:!0},{id:"hypothesis",label:"Hypothesis Engine",group:"Language Model Required",description:"Iterative hypothesize-test-score-learn loop over multiple language family hypotheses. Tests Dravidian vs Sanskrit vs Luwian vs Semitic. Includes Kandles bias profiles per language family.",inputs:"text_id, max_iterations",outputs:"results[] with scores per hypothesis, suggested_next[]",defaultParams:'{"text_id": "", "max_iterations": 5000}',needsLM:!0}],Ub={"Statistical (no LM)":"#16a34a","Language Model Required":"#dc2626"};function jk(){const[t,o]=x.useState("all"),[r,l]=x.useState(null),[c,d]=x.useState(wk),[u,p]=x.useState([]),[g,h]=x.useState(""),[v,y]=x.useState(!1),[b,S]=x.useState(null),[k,_]=x.useState(!1),T=W=>d(P=>P.filter(z=>z.id!==W)),w=async()=>{if(g.trim()){y(!0),S(null);try{const W=await _2(g.trim());S({ok:!0,text:`Imported: ${W.file??g}`}),h(""),C()}catch(W){S({ok:!1,text:W instanceof Error?W.message:String(W)})}finally{y(!1)}}},C=()=>{yb().then(W=>d(W.map(P=>({...P,needsLM:P.needs_lm,defaultParams:JSON.stringify(P.default_params,null,2),custom:!P.registered})))).catch(()=>{})};x.useEffect(()=>{C(),rd().then(p).catch(()=>{})},[]);const j=["all",...Array.from(new Set(c.map(W=>W.group)))],L=t==="all"?c:c.filter(W=>W.group===t);return n.jsxs("div",{children:[n.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"baseline",marginBottom:"0.25rem"},children:[n.jsx("h2",{style:{marginTop:0},children:"Pipelines"}),n.jsx("button",{onClick:()=>{_(W=>!W),S(null)},style:{padding:"5px 12px",border:"1px solid #d1d5db",borderRadius:5,cursor:"pointer",fontSize:12,background:k?"#f3f4f6":"#fff",color:"#374151"},children:k?"× Cancel":"+ Import"})]}),k&&n.jsxs("div",{style:{background:"#f8fafc",border:"1px solid #e5e7eb",borderRadius:8,padding:"12px 16px",marginBottom:"1rem"},children:[n.jsxs("p",{style:{margin:"0 0 8px",fontSize:13,color:"#374151"},children:["Enter the absolute path of a Python file that defines a class inheriting from ",n.jsx("code",{children:"PipelineBase"}),". It will be copied into the pipelines directory."]}),n.jsxs("div",{style:{display:"flex",gap:8},children:[n.jsx("input",{value:g,onChange:W=>h(W.target.value),onKeyDown:W=>{W.key==="Enter"&&w()},placeholder:"C:\\path\\to\\my_pipeline.py",style:{flex:1,padding:"7px 10px",border:"1px solid #d1d5db",borderRadius:5,fontSize:12,outline:"none",fontFamily:"monospace"}}),n.jsx("button",{onClick:()=>void w(),disabled:v||!g.trim(),style:{padding:"7px 16px",border:"none",borderRadius:5,cursor:"pointer",fontSize:12,fontWeight:600,background:"#1e3a5f",color:"#fff"},children:v?"Importing…":"Import"})]}),b&&n.jsx("div",{style:{marginTop:8,fontSize:12,padding:"6px 10px",borderRadius:5,background:b.ok?"#f0fdf4":"#fef2f2",color:b.ok?"#16a34a":"#b91c1c",border:`1px solid ${b.ok?"#86efac":"#fca5a5"}`},children:b.text})]}),n.jsxs("p",{style:{fontSize:13,color:"#6b7280",marginTop:0,marginBottom:"1.25rem"},children:[c.length," registered analysis pipelines. Statistical pipelines require no language model — all results are vocabulary-free and circularity-free. Select a pipeline to launch a job from the Jobs tab."]}),n.jsx("nav",{style:{display:"flex",gap:6,marginBottom:"1.5rem",flexWrap:"wrap"},children:j.map(W=>{const P=Ub[W]??"#1e3a5f";return n.jsx("button",{onClick:()=>o(W),style:{padding:"4px 14px",border:"1px solid",borderRadius:20,cursor:"pointer",fontSize:12,fontWeight:t===W?600:400,background:t===W?P:"#fff",borderColor:t===W?P:"#d1d5db",color:t===W?"#fff":"#374151"},children:W==="all"?`All (${c.length})`:`${W} (${c.filter(z=>z.group===W).length})`},W)})}),n.jsx("div",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fill, minmax(320px, 1fr))",gap:"0.75rem"},children:L.map(W=>n.jsx(kk,{pipeline:W,expanded:r===W.id,onToggle:()=>l(r===W.id?null:W.id),onDeleted:T,onDuplicated:C,corpora:u},W.id))}),n.jsxs("div",{style:{marginTop:"1.5rem",padding:"12px 16px",background:"#f9fafb",borderRadius:8,fontSize:12,color:"#6b7280"},children:[n.jsx("strong",{style:{color:"#374151"},children:"Scientific note:"}),' All 14 statistical pipelines are safe to run on any corpus without language assumptions. The 3 pipelines marked "Language Model Required" use bigram statistics from a target language — these must use separate training/test corpora to avoid circularity (Fuls 2013; Snyder 2010 protocol).']})]})}function kk({pipeline:t,expanded:o,onToggle:r,onDeleted:l,onDuplicated:c,corpora:d}){const u=Ub[t.group]??"#6b7280",[p,g]=x.useState(!1),[h,v]=x.useState(!1),[y,b]=x.useState(!1),[S,k]=x.useState(null),[_,T]=x.useState(!1),[w,C]=x.useState(""),[j,L]=x.useState(""),[W,P]=x.useState(""),[z,M]=x.useState(!1),[q,K]=x.useState(null),D=async A=>{var G;if(A.stopPropagation(),!w&&!W.trim()){K({ok:!1,text:"Select a corpus or enter a job name"});return}M(!0),K(null);try{const R={...JSON.parse(t.defaultParams||"{}")};w&&(R.text_id=w),j&&(R.target_text_id=j);const X=await Gc({name:W.trim()||`${t.label} — ${((G=d.find(B=>B.id===w))==null?void 0:G.name)??(w||"quick run")}`,pipeline:t.id,params:R});K({ok:!0,text:`Job submitted: ${X.id.slice(0,8)}… — check Jobs panel`}),window.dispatchEvent(new CustomEvent("glossa:running",{detail:{builder:"study",running:!0}}))}catch(R){K({ok:!1,text:R instanceof Error?R.message:"Submit failed"})}finally{M(!1)}},Y=async A=>{A.stopPropagation(),g(!0);try{await j2(t.id),c()}catch(G){k(G instanceof Error?G.message:String(G))}finally{g(!1)}},H=async A=>{if(A.stopPropagation(),!y){b(!0);return}v(!0);try{await k2(t.id),l(t.id)}catch(G){k(G instanceof Error?G.message:String(G)),v(!1),b(!1)}};return n.jsxs("div",{style:{border:`1px solid ${o?u:"#e5e7eb"}`,borderRadius:8,overflow:"hidden",transition:"border-color 0.15s"},children:[n.jsxs("div",{style:{padding:"12px 14px",background:o?u+"08":"#fff",cursor:"pointer"},onClick:r,children:[n.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"flex-start",marginBottom:4},children:[n.jsx("code",{style:{fontSize:13,fontWeight:700,color:"#1e3a5f"},children:t.id}),n.jsxs("div",{style:{display:"flex",gap:4,alignItems:"center"},children:[t.custom&&n.jsx("span",{style:{fontSize:9,padding:"1px 5px",borderRadius:6,background:"#f3f4f6",color:"#6b7280",fontWeight:600},children:"custom"}),n.jsx("span",{style:{fontSize:10,padding:"1px 6px",borderRadius:8,background:u+"20",color:u,fontWeight:600,whiteSpace:"nowrap"},children:t.needsLM?"LM":"No LM"}),n.jsx("button",{onClick:Y,disabled:p,title:"Duplicate pipeline",style:ry,children:p?"…":"⎘"}),t.custom&&n.jsx("button",{onClick:H,disabled:h,title:y?"Click again to confirm":"Delete pipeline",style:{...ry,background:y?"#fef2f2":void 0,color:y?"#b91c1c":void 0},children:h?"…":y?"Confirm?":"🗑"})]})]}),n.jsx("div",{style:{fontSize:13,fontWeight:600,color:"#111827",marginBottom:4},children:t.label}),n.jsx("p",{style:{margin:0,fontSize:12,color:"#6b7280",lineHeight:1.5},children:o?t.description:t.description.slice(0,100)+(t.description.length>100?"…":"")})]}),S&&n.jsx("div",{style:{padding:"6px 14px",fontSize:12,color:"#b91c1c",background:"#fef2f2"},children:S}),o&&n.jsxs("div",{style:{padding:"0 14px 14px",borderTop:`1px solid ${u}30`,marginTop:8},children:[n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("span",{style:Qs,children:"Inputs:"}),n.jsx("code",{style:_k,children:t.inputs})]}),n.jsxs("div",{style:{marginBottom:10},children:[n.jsx("span",{style:Qs,children:"Outputs:"}),n.jsx("span",{style:{fontSize:12,color:"#374151"},children:t.outputs})]}),n.jsxs("div",{style:{marginBottom:10},children:[n.jsx("span",{style:Qs,children:"Default params:"}),n.jsx("pre",{style:{background:"#1e293b",color:"#e2e8f0",padding:"6px 10px",borderRadius:4,fontSize:11,fontFamily:"monospace",margin:"4px 0 0",overflowX:"auto"},children:t.defaultParams})]}),t.module&&n.jsxs("div",{style:{fontSize:11,color:"#9ca3af",marginBottom:8},children:["Module: ",n.jsx("code",{children:t.module})]}),n.jsxs("div",{style:{marginTop:10,paddingTop:10,borderTop:`1px solid ${u}20`},children:[n.jsx("button",{onClick:A=>{A.stopPropagation(),T(G=>!G),K(null)},style:{padding:"4px 12px",border:"none",borderRadius:5,cursor:"pointer",background:_?"#f3f4f6":u,color:_?"#374151":"#fff",fontSize:12,fontWeight:600},children:_?"× Cancel":"▶ Quick Run"}),_&&n.jsxs("div",{style:{marginTop:8,display:"flex",flexDirection:"column",gap:6},onClick:A=>A.stopPropagation(),children:[n.jsxs("div",{style:{display:"flex",gap:6,flexWrap:"wrap"},children:[n.jsxs("div",{style:{flex:2,minWidth:160},children:[n.jsx("div",{style:Qs,children:"Corpus (text_id)"}),n.jsxs("select",{value:w,onChange:A=>C(A.target.value),style:{width:"100%",padding:"4px 8px",border:"1px solid #d1d5db",borderRadius:4,fontSize:12},children:[n.jsx("option",{value:"",children:"— select corpus —"}),d.map(A=>n.jsxs("option",{value:A.id,children:[A.name," (",A.corpus_type,", ",A.content.length.toLocaleString()," tokens)"]},A.id))]})]}),t.needsLM&&n.jsxs("div",{style:{flex:2,minWidth:160},children:[n.jsx("div",{style:Qs,children:"Target corpus (target_text_id)"}),n.jsxs("select",{value:j,onChange:A=>L(A.target.value),style:{width:"100%",padding:"4px 8px",border:"1px solid #d1d5db",borderRadius:4,fontSize:12},children:[n.jsx("option",{value:"",children:"— select target LM corpus —"}),d.map(A=>n.jsx("option",{value:A.id,children:A.name},A.id))]})]})]}),n.jsxs("div",{children:[n.jsx("div",{style:Qs,children:"Job name (optional)"}),n.jsx("input",{value:W,onChange:A=>P(A.target.value),placeholder:`${t.label} run…`,style:{width:"100%",padding:"4px 8px",border:"1px solid #d1d5db",borderRadius:4,fontSize:12,boxSizing:"border-box"}})]}),n.jsx("button",{onClick:A=>void D(A),disabled:z||!w&&!W.trim(),style:{alignSelf:"flex-start",padding:"5px 16px",border:"none",borderRadius:5,background:z?"#6b7280":u,color:"#fff",cursor:z?"not-allowed":"pointer",fontSize:12,fontWeight:700},children:z?"⏳ Submitting…":"▶ Submit Job"}),q&&n.jsx("div",{style:{fontSize:11,padding:"4px 8px",borderRadius:4,background:q.ok?"#f0fdf4":"#fef2f2",color:q.ok?"#16a34a":"#b91c1c"},children:q.text})]})]})]})]})}const Qs={fontSize:11,fontWeight:600,color:"#6b7280",display:"block",marginBottom:2,textTransform:"uppercase",letterSpacing:"0.05em"},_k={fontSize:11,color:"#374151",fontFamily:"monospace"},ry={padding:"2px 7px",border:"1px solid #e5e7eb",borderRadius:4,cursor:"pointer",fontSize:11,fontWeight:600,background:"#fff",color:"#374151"},ay="glossa_email_provider_preset",$f="onboarding@resend.dev",Ck="onboarding@resend.dev";function Tk(){const{toast:t}=et(),[o,r]=x.useState(null),[l,c]=x.useState([]),[d,u]=x.useState([]),[p,g]=x.useState(null),[h,v]=x.useState(!0),[y,b]=x.useState(!1),[S,k]=x.useState(""),[_,T]=x.useState(""),[w,C]=x.useState(()=>localStorage.getItem(ay)??"outlook365_oauth"),j=x.useMemo(()=>Nf.find(ae=>ae.id===w)??Nf[0],[w]),[L,W]=x.useState(""),[P,z]=x.useState(587),[M,q]=x.useState(""),[K,D]=x.useState(""),[Y,H]=x.useState(""),[A,G]=x.useState(!0),[R,X]=x.useState(""),[B,V]=x.useState($f),[Q,N]=x.useState(!0),[O,$]=x.useState(null),[F,I]=x.useState(!1),[J,ne]=x.useState(""),[se,pe]=x.useState(""),[_e,we]=x.useState("common"),ke=x.useRef(!1),te=x.useCallback(async()=>{v(!0);try{const[ae,He,Ze,ut,Ut]=await Promise.all([Tb(),xj(),vj(20),zb().catch(()=>null),ad().catch(()=>null)]);r(ae),c(He.recipients),u(Ze.entries),g(ut),W(ae.host||""),z(ae.port||587),H(ae.from||""),G(ae.use_tls??!0),we(ae.graph_tenant||"common"),Ut&&!ae.graph_client_id_set&&pe(""),V(ae.resend_from||$f),N(ae.resend_configured!==void 0)}catch(ae){t(ae instanceof Error?ae.message:"Failed to load notifications","error")}finally{v(!1)}},[t]);x.useEffect(()=>{te()},[te]),x.useEffect(()=>{localStorage.setItem(ay,j.id),j.category==="smtp"&&(j.smtp_host!==void 0&&W(j.smtp_host),j.smtp_port!==void 0&&z(j.smtp_port),j.smtp_use_tls!==void 0&&G(j.smtp_use_tls))},[j.id]);const de=async()=>{const ae=S.trim();if(ae){b(!0);try{await yj({email:ae,label:_.trim(),active:!0}),k(""),T(""),t("Recipient added","success"),await te()}catch(He){t(He instanceof Error?He.message:"Could not add recipient","error")}finally{b(!1)}}},Ce=async ae=>{try{await Zx(ae.id,{active:!ae.active}),await te()}catch(He){t(He instanceof Error?He.message:"Update failed","error")}},ze=async ae=>{const He=window.prompt("Label:",ae.label);if(He!==null)try{await Zx(ae.id,{label:He}),await te()}catch(Ze){t(Ze instanceof Error?Ze.message:"Update failed","error")}},ve=async ae=>{if(window.confirm(`Remove ${ae.email} from notifications?`))try{await bj(ae.id),t("Recipient removed","info"),await te()}catch(He){t(He instanceof Error?He.message:"Delete failed","error")}},De=async()=>{b(!0);try{const ae=await Sj();t(`Test sent: ${ae.sent} ok / ${ae.failed} failed`,ae.failed?"warning":"success"),await te()}catch(ae){t(ae instanceof Error?ae.message:"Test failed","error")}finally{b(!1)}},Me=async()=>{const ae=R.trim(),He=B.trim(),Ze=((o==null?void 0:o.resend_from)||"").trim(),ut=He.length>0&&He!==Ze,Ut=!!(o!=null&&o.resend_configured);if(!ae&&!ut){Ut?t("Nothing to save — edit the From address or paste a new key","info"):t("Paste your Resend API key first","warning");return}if(!ae&&!Ut){t("Paste your Resend API key first","warning");return}b(!0);try{const Nt={};ae&&(Nt.resend_api_key=ae),ut&&(Nt.resend_from=He);const yn=await sr(Nt),ft=Object.keys(Nt).filter(qt=>!yn.updated.includes(qt));if(ft.length>0){t(`Backend ignored ${ft.join(", ")} — it's likely running an older build. Restart the backend (setup-os.cmd restart) and try again.`,"error");return}const Et=[];ae&&Et.push("API key updated"),ut&&Et.push(`From set to ${He}`),t(`Resend: ${Et.join(" · ")}`,"success"),X(""),await te()}catch(Nt){t(Nt instanceof Error?Nt.message:"Save failed","error")}finally{b(!1)}},Ve=async()=>{if(window.confirm("Clear the Resend API key? Email will fall back to SMTP/Outlook if configured, otherwise no transport.")){b(!0);try{await sr({resend_api_key:""}),t("Resend API key cleared","info"),await te()}catch(ae){t(ae instanceof Error?ae.message:"Clear failed","error")}finally{b(!1)}}},Le=async()=>{b(!0);try{const ae={smtp_host:L.trim(),smtp_port:String(P||587),smtp_from:Y.trim(),smtp_use_tls:A?"1":"0"};M.trim()&&(ae.smtp_username=M.trim()),K&&(ae.smtp_password=K),await sr(ae),t("SMTP settings saved","success"),D(""),await te()}catch(ae){t(ae instanceof Error?ae.message:"Save failed","error")}finally{b(!1)}},Ae=async()=>{b(!0);try{const ae={ms_graph_tenant_id:_e.trim()||"common"};se.trim()&&(ae.ms_graph_client_id=se.trim()),await sr(ae),t("Outlook 365 client config saved","success"),pe(""),await te()}catch(ae){t(ae instanceof Error?ae.message:"Save failed","error")}finally{b(!1)}},Ue=async()=>{ne(""),b(!0);try{const ae=await wj();$(ae),ke.current=!1,Oe(ae)}catch(ae){ne(ae instanceof Error?ae.message:"Could not start device flow"),t("Outlook connect failed — check ms_graph_client_id","error")}finally{b(!1)}},Oe=async ae=>{I(!0);const He=Math.max(2e3,ae.interval*1e3);for(;!ke.current&&(await new Promise(Ze=>setTimeout(Ze,He)),!ke.current);)try{const Ze=await jj(ae.session_id);if(Ze.status==="success"){t("Outlook 365 connected","success"),$(null),I(!1),await te();return}if(Ze.status==="failed"||Ze.status==="expired"){ne(Ze.error||Ze.status),I(!1);return}}catch(Ze){ne(Ze instanceof Error?Ze.message:"poll failed"),I(!1);return}I(!1)},dt=()=>{ke.current=!0,$(null),I(!1)},it=async()=>{if(window.confirm("Disconnect Outlook 365? You can reconnect anytime.")){b(!0);try{await kj(),t("Outlook 365 disconnected","info"),await te()}catch(ae){t(ae instanceof Error?ae.message:"Disconnect failed","error")}finally{b(!1)}}},lt=async ae=>{b(!0);try{const He=ae?await Eb():await Rb();g(He),t(ae?`Auto-start ON — fetch + mine + digest will run every ${Math.round(He.interval_seconds/3600)}h`:"Auto-start OFF","info")}catch(He){t(He instanceof Error?He.message:"Toggle failed","error")}finally{b(!1)}},Je=(o==null?void 0:o.configured)??!1,yt=(o==null?void 0:o.recipients_active)??0,Jt=(o==null?void 0:o.recipients_total)??0,rn=j.category==="oauth",zt=j.category==="api";return n.jsxs("section",{style:Ek,children:[n.jsx("h3",{style:Rk,children:"📬 Email & Notifications"}),n.jsx("p",{style:ly,children:"Pick a mail provider, fill in the credentials it needs, then add recipients. Outlook 365 uses Microsoft's modern OAuth (no app password) — recommended for anyone with a Microsoft 365 / school / work account."}),n.jsxs("div",{style:{marginTop:10,padding:"10px 14px",borderRadius:7,border:`1px solid ${Je?"#86efac":"#fcd34d"}`,background:Je?"#f0fdf4":"#fffbeb",display:"flex",alignItems:"center",gap:10,flexWrap:"wrap"},children:[n.jsx("span",{style:{fontSize:16},children:Je?"✅":"⚠️"}),n.jsxs("div",{style:{flex:1,minWidth:220},children:[n.jsx("div",{style:{fontSize:13,fontWeight:600,color:Je?"#15803d":"#92400e"},children:Je?(o==null?void 0:o.transport)==="graph"?"Outlook 365 (Microsoft Graph) configured":(o==null?void 0:o.transport)==="resend"?"Resend (HTTPS API) configured":"SMTP configured":"Email not configured"}),n.jsx("div",{style:{fontSize:11,color:"#6b7280",marginTop:2},children:Je?(o==null?void 0:o.transport)==="graph"?`Tenant ${o==null?void 0:o.graph_tenant} · ${yt}/${Jt} active recipients`:(o==null?void 0:o.transport)==="resend"?`From ${(o==null?void 0:o.resend_from)||"onboarding@resend.dev"} · ${yt}/${Jt} active recipients`:`Host ${o==null?void 0:o.host}:${o==null?void 0:o.port} · From ${(o==null?void 0:o.from)||"(unset)"} · ${yt}/${Jt} active`:"Choose a provider below and complete its setup."})]}),n.jsx("button",{onClick:()=>void De(),disabled:y||!Je||yt===0,title:yt===0?"Add an active recipient first":"Send a deliverability test email",style:{...pc,opacity:y||!Je||yt===0?.5:1,cursor:y||!Je||yt===0?"not-allowed":"pointer"},children:y?"Sending…":"✉ Send Test"}),n.jsx("button",{onClick:()=>void te(),title:"Reload",style:cy,children:"⟳"})]}),n.jsxs("div",{style:{marginTop:14},children:[n.jsx("div",{style:Wf,children:"1 · Mail provider"}),n.jsx("select",{value:w,onChange:ae=>C(ae.target.value),style:{...Jn,fontSize:13},children:Nf.map(ae=>n.jsxs("option",{value:ae.id,children:[ae.label,ae.recommended?" ⭐":""]},ae.id))}),n.jsx("p",{style:{...ly,marginTop:6},children:j.notes})]}),rn&&n.jsxs("div",{style:{marginTop:14,padding:"12px 14px",borderRadius:7,border:"1px solid #c7d2fe",background:"#eef2ff"},children:[n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10,flexWrap:"wrap"},children:[n.jsx("span",{style:{fontSize:16},children:"🪪"}),n.jsxs("div",{style:{flex:1,minWidth:240},children:[n.jsx("div",{style:{fontSize:13,fontWeight:700,color:"#3730a3"},children:"Outlook 365 (Microsoft Graph)"}),n.jsx("div",{style:{fontSize:11,color:"#4338ca",marginTop:2},children:o!=null&&o.graph_configured?`Connected. Tenant: ${o==null?void 0:o.graph_tenant}. Mail.Send delegated.`:o!=null&&o.graph_client_id_set?"Client ID set, but not yet authorised. Click Connect to start.":"Set the Application (client) ID below, then click Connect."})]}),o!=null&&o.graph_configured?n.jsx("button",{onClick:()=>void it(),disabled:y,style:ha,children:"Disconnect"}):n.jsx("button",{onClick:()=>void Ue(),disabled:y||!(o!=null&&o.graph_client_id_set)||F,title:o!=null&&o.graph_client_id_set?"Start the device-code OAuth flow":"Set the Application (client) ID first",style:{...pc,background:"#4338ca",cursor:y||!(o!=null&&o.graph_client_id_set)?"not-allowed":"pointer",opacity:y||!(o!=null&&o.graph_client_id_set)?.5:1},children:"🔗 Connect Outlook 365"})]}),!(o!=null&&o.graph_configured)&&n.jsxs("div",{style:{marginTop:10,display:"grid",gap:6},children:[n.jsx("input",{value:se,placeholder:o!=null&&o.graph_client_id_set?"●●●●●●●● (paste new Application (client) ID to replace)":"Application (client) ID (Azure AD app registration)",onChange:ae=>pe(ae.target.value),style:Jn}),n.jsx("input",{value:_e,placeholder:'Tenant ID (default "common" works for both work and personal accounts)',onChange:ae=>we(ae.target.value),style:Jn}),n.jsxs("div",{style:{display:"flex",gap:6,alignItems:"center"},children:[n.jsx("button",{onClick:()=>void Ae(),disabled:y,style:ha,children:"Save client config"}),n.jsx("span",{style:{fontSize:10,color:"#6b7280"},children:"Need help registering an app? entra.microsoft.com → App registrations → New → public client → Mail.Send delegated permission."})]})]}),O&&n.jsxs("div",{style:{marginTop:10,padding:"10px 12px",borderRadius:6,background:"#fff",border:"1px solid #c7d2fe"},children:[n.jsxs("div",{style:{fontSize:12,color:"#374151"},children:["1. Open ",n.jsx("a",{href:O.verification_uri,target:"_blank",rel:"noopener noreferrer",style:{color:"#4338ca"},children:O.verification_uri})]}),n.jsx("div",{style:{fontSize:12,color:"#374151",marginTop:4},children:"2. Paste this code:"}),n.jsx("div",{style:{marginTop:6,fontSize:22,fontWeight:800,fontFamily:"monospace",color:"#4338ca",letterSpacing:2,padding:"6px 10px",border:"2px dashed #c7d2fe",borderRadius:6,display:"inline-block"},children:O.user_code}),n.jsxs("div",{style:{fontSize:11,color:"#6b7280",marginTop:6},children:[F?"Waiting for approval…":"Polling stopped"," ","· Code expires in ",Math.round(O.expires_in/60)," min.",n.jsx("button",{onClick:dt,style:{...cy,marginLeft:8},children:"Cancel"})]})]}),J&&n.jsxs("div",{style:{marginTop:8,fontSize:11,color:"#b91c1c"},children:["⚠ ",J]})]}),zt&&n.jsxs("div",{style:{marginTop:14,padding:"12px 14px",borderRadius:7,border:"1px solid #bbf7d0",background:"#f0fdf4"},children:[n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10,flexWrap:"wrap"},children:[n.jsx("span",{style:{fontSize:16},children:"⚡"}),n.jsxs("div",{style:{flex:1,minWidth:240},children:[n.jsx("div",{style:{fontSize:13,fontWeight:700,color:"#15803d"},children:"Resend (HTTPS API)"}),n.jsx("div",{style:{fontSize:11,color:"#166534",marginTop:2},children:o!=null&&o.resend_configured?`Connected. Sends from ${(o==null?void 0:o.resend_from)||$f}.`:"Paste your Resend API key (starts with re_). No SMTP, no mailbox, no domain needed."})]}),(o==null?void 0:o.resend_configured)&&n.jsx("button",{onClick:()=>void Ve(),disabled:y,style:{...ha,color:"#15803d",borderColor:"#bbf7d0"},children:"Clear key"})]}),!Q&&n.jsxs("div",{style:{marginTop:10,padding:"8px 12px",borderRadius:6,border:"1px solid #fcd34d",background:"#fffbeb",fontSize:11,color:"#92400e"},children:["⚠ The running backend doesn’t expose Resend yet — saving the key here will be silently ignored. Restart the backend (",n.jsx("code",{children:"setup-os.cmd restart"}),") so the new transport loads, then come back to this screen."]}),Q&&(o==null?void 0:o.resend_configured)&&(o==null?void 0:o.transport)!=="resend"&&n.jsxs("div",{style:{marginTop:10,padding:"8px 12px",borderRadius:6,border:"1px solid #fcd34d",background:"#fffbeb",fontSize:11,color:"#92400e"},children:["⚠ Resend is configured but the active transport is",n.jsxs("b",{children:[" ",o==null?void 0:o.transport]}),". Microsoft Graph (Outlook OAuth) outranks Resend; if you don’t want that, click",n.jsx("b",{children:" Disconnect Outlook 365"})," above. Plain SMTP cannot outrank Resend, so if you see ",n.jsx("i",{children:"smtp"})," here despite Resend being configured, the backend hasn’t reloaded yet — restart it."]}),(()=>{var Ze;return(((Ze=B.match(/<([^>]+)>/))==null?void 0:Ze[1])??B).trim().toLowerCase()===Ck&&n.jsxs("div",{style:{marginTop:10,padding:"8px 12px",borderRadius:6,border:"1px solid #fde68a",background:"#fffbeb",fontSize:11,color:"#92400e"},children:["ℹ You’re using Resend’s free shared sender (",n.jsx("code",{children:"onboarding@resend.dev"}),"). Resend will only deliver to the email you signed up to Resend with. Recipients other than that one address get a 403. Verify your own domain at"," ",n.jsx("a",{href:"https://resend.com/domains",target:"_blank",rel:"noopener noreferrer",style:{color:"#92400e",textDecoration:"underline"},children:"resend.com/domains"})," ","and switch From to ",n.jsx("code",{children:"noreply@"}),"to send to anyone."]})})(),n.jsxs("div",{style:{display:"grid",gap:8,marginTop:10},children:[n.jsxs("label",{style:{fontSize:11,fontWeight:600,color:"#166534",display:"flex",flexDirection:"column",gap:4},children:["API key",n.jsx("input",{value:R,onChange:ae=>X(ae.target.value),placeholder:o!=null&&o.resend_configured?"●●●●●●●● (leave blank to keep current key)":"Resend API key (re_xxx…)",type:"password",autoComplete:"off",style:Jn})]}),n.jsxs("label",{style:{fontSize:11,fontWeight:600,color:"#166534",display:"flex",flexDirection:"column",gap:4},children:["From address (always editable)",n.jsx("input",{value:B,onChange:ae=>V(ae.target.value),placeholder:'"noreply@yourdomain.com" or "Glossa Lab " once a domain is verified at resend.com/domains.',style:Jn}),n.jsxs("span",{style:{fontSize:10,fontWeight:400,color:"#6b7280"},children:["Currently saved: ",n.jsx("code",{children:(o==null?void 0:o.resend_from)||"(unset)"})]})]}),(()=>{const ae=R.trim(),He=B.trim(),Ze=((o==null?void 0:o.resend_from)||"").trim(),ut=He.length>0&&He!==Ze,Ut=!!ae||!!(o!=null&&o.resend_configured)&&ut,Nt=y?"Saving…":o!=null&&o.resend_configured?ae&&ut?"Save key + From":ae?"Replace key":ut?"Save From address":"Save Resend settings":"Save Resend key";return n.jsxs("div",{style:{display:"flex",gap:6,flexWrap:"wrap"},children:[n.jsx("button",{onClick:()=>void Me(),disabled:y||!Ut,style:{...pc,opacity:y||!Ut?.5:1,cursor:y||!Ut?"not-allowed":"pointer"},children:Nt}),n.jsx("button",{onClick:()=>void De(),disabled:y||!Je||yt===0,style:{...ha,cursor:y||!Je||yt===0?"not-allowed":"pointer",opacity:y||!Je||yt===0?.5:1},children:"✉ Send test"}),n.jsx("a",{href:"https://resend.com/api-keys",target:"_blank",rel:"noopener noreferrer",style:{marginLeft:"auto",fontSize:11,color:"#15803d",alignSelf:"center"},children:"Get an API key →"})]})})()]})]}),!rn&&!zt&&n.jsxs("div",{style:{marginTop:14,padding:"12px 14px",borderRadius:7,border:"1px solid #e5e7eb",background:"#fafafa"},children:[n.jsx("div",{style:{...Wf,color:"#374151",margin:"0 0 8px"},children:"2 · SMTP credentials"}),n.jsxs("div",{style:{display:"grid",gridTemplateColumns:"2fr 1fr",gap:8},children:[n.jsx("input",{value:L,placeholder:"SMTP host (e.g. smtp.gmail.com)",onChange:ae=>W(ae.target.value),style:Jn}),n.jsx("input",{value:P||"",type:"number",placeholder:"Port (587)",onChange:ae=>z(parseInt(ae.target.value||"0",10)||587),style:Jn})]}),n.jsxs("div",{style:{display:"grid",gridTemplateColumns:"1fr 1fr",gap:8,marginTop:8},children:[n.jsx("input",{value:M,placeholder:"Username (usually your full email address)",onChange:ae=>q(ae.target.value),style:Jn,autoComplete:"off"}),n.jsx("input",{value:K,type:"password",placeholder:o!=null&&o.password_set?"●●●●●●●● (paste new app password)":"App password / SMTP password",onChange:ae=>D(ae.target.value),style:Jn,autoComplete:"off"})]}),n.jsx("input",{value:Y,placeholder:'From address (e.g. "Glossa Lab " or just an email)',onChange:ae=>H(ae.target.value),style:{...Jn,marginTop:8}}),n.jsxs("label",{style:{display:"flex",alignItems:"center",gap:6,marginTop:8,fontSize:12,color:"#374151"},children:[n.jsx("input",{type:"checkbox",checked:A,onChange:ae=>G(ae.target.checked)}),"Use STARTTLS (recommended)"]}),n.jsxs("div",{style:{display:"flex",gap:6,marginTop:10,flexWrap:"wrap"},children:[n.jsx("button",{onClick:()=>void Le(),disabled:y,style:pc,children:y?"Saving…":"Save SMTP settings"}),n.jsx("button",{onClick:()=>void De(),disabled:y||!Je||yt===0,style:{...ha,cursor:y||!Je||yt===0?"not-allowed":"pointer",opacity:y||!Je||yt===0?.5:1},children:"✉ Send test"})]})]}),n.jsxs("div",{style:{marginTop:14,padding:"12px 14px",borderRadius:7,border:`1px solid ${p!=null&&p.running?"#86efac":"#e5e7eb"}`,background:p!=null&&p.running?"#f0fdf4":"#fafafa",display:"flex",alignItems:"center",gap:10,flexWrap:"wrap"},children:[n.jsx("span",{style:{fontSize:16},children:p!=null&&p.running?"⏱️":"💤"}),n.jsxs("div",{style:{flex:1,minWidth:240},children:[n.jsxs("div",{style:{fontSize:13,fontWeight:600,color:p!=null&&p.running?"#15803d":"#374151"},children:["Auto-start discovery ",p!=null&&p.running?"— RUNNING":"— OFF"]}),n.jsx("div",{style:{fontSize:11,color:"#6b7280",marginTop:2},children:p?`Fetch + mine + digest every ${Math.round(p.interval_seconds/3600)}h. ${p.enabled?"Persisted; resumes on next backend boot.":"Not persisted."}`:"Loading scheduler status…"})]}),n.jsx("div",{onClick:()=>!y&&void lt(!(p!=null&&p.running)),title:p!=null&&p.running?"Stop scheduler + persist OFF":"Start scheduler + persist ON",style:{width:44,height:24,borderRadius:12,cursor:y?"not-allowed":"pointer",flexShrink:0,position:"relative",background:p!=null&&p.running?"#22c55e":"#d1d5db",opacity:y?.5:1,transition:"background 0.2s"},children:n.jsx("div",{style:{position:"absolute",top:3,left:p!=null&&p.running?23:3,width:18,height:18,borderRadius:"50%",background:"#fff",boxShadow:"0 1px 3px rgba(0,0,0,0.25)",transition:"left 0.2s"}})})]}),n.jsxs("div",{style:{marginTop:14},children:[n.jsxs("div",{style:Wf,children:["3 · Recipients (",l.length,")"]}),h?n.jsx("div",{style:{fontSize:12,color:"#6b7280"},children:"Loading…"}):l.length===0?n.jsx("div",{style:{fontSize:12,color:"#9ca3af",fontStyle:"italic"},children:"No recipients yet. Add at least one address below to start receiving emails."}):n.jsx("div",{style:{border:"1px solid #e5e7eb",borderRadius:6,overflow:"hidden"},children:l.map(ae=>n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,padding:"7px 12px",borderBottom:"1px solid #f1f5f9",background:ae.active?"#fff":"#fafafa"},children:[n.jsx("span",{title:ae.active?"Active":"Paused",style:{width:8,height:8,borderRadius:"50%",background:ae.active?"#22c55e":"#cbd5e1",flexShrink:0}}),n.jsxs("div",{style:{flex:1,minWidth:0},children:[n.jsx("div",{style:{fontSize:13,fontWeight:500,color:"#111827",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:ae.email}),ae.label&&n.jsx("div",{style:{fontSize:11,color:"#6b7280",marginTop:1},children:ae.label})]}),n.jsx("button",{onClick:()=>void Ce(ae),title:ae.active?"Pause notifications":"Resume notifications",style:Hf(ae.active?"#f59e0b":"#22c55e"),children:ae.active?"⏸":"▶"}),n.jsx("button",{onClick:()=>void ze(ae),title:"Edit label",style:Hf("#6b7280"),children:"✎"}),n.jsx("button",{onClick:()=>void ve(ae),title:"Remove",style:Hf("#dc2626"),children:"🗑"})]},ae.id))}),n.jsxs("div",{style:{display:"flex",gap:6,marginTop:8,flexWrap:"wrap"},children:[n.jsx("input",{value:S,onChange:ae=>k(ae.target.value),onKeyDown:ae=>{ae.key==="Enter"&&S.trim()&&de()},placeholder:"recipient@example.com",style:{...Jn,flex:2,minWidth:200}}),n.jsx("input",{value:_,onChange:ae=>T(ae.target.value),onKeyDown:ae=>{ae.key==="Enter"&&S.trim()&&de()},placeholder:"Label (optional, e.g. PI, lab)",style:{...Jn,flex:1,minWidth:140}}),n.jsx("button",{onClick:()=>void de(),disabled:y||!S.trim(),style:{...Ak,cursor:y||!S.trim()?"not-allowed":"pointer",opacity:y||!S.trim()?.5:1},children:"+ Add"})]})]}),n.jsxs("details",{style:{marginTop:16},children:[n.jsxs("summary",{style:{cursor:"pointer",fontWeight:600,fontSize:13,color:"#374151"},children:["📜 Recent send log (",d.length,")"]}),n.jsx("div",{style:{marginTop:8,maxHeight:220,overflowY:"auto",border:"1px solid #e5e7eb",borderRadius:6},children:d.length===0?n.jsx("div",{style:{fontSize:12,color:"#9ca3af",padding:"10px 14px",fontStyle:"italic"},children:"No emails sent yet."}):d.map(ae=>{const He=ae.status==="sent"?"#22c55e":ae.status==="failed"?"#dc2626":"#9ca3af";return n.jsxs("div",{style:{display:"flex",gap:8,padding:"6px 12px",borderBottom:"1px solid #f1f5f9",alignItems:"center"},children:[n.jsx("span",{style:{fontSize:9,fontWeight:700,color:He,background:He+"20",padding:"1px 6px",borderRadius:4,textTransform:"uppercase",flexShrink:0},children:ae.status}),n.jsxs("div",{style:{flex:1,minWidth:0},children:[n.jsx("div",{style:{fontSize:12,color:"#111827",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:ae.subject}),n.jsxs("div",{style:{fontSize:10,color:"#6b7280",marginTop:1},children:["to ",ae.recipient," · ",ae.kind," · ",zk(ae.sent_at),ae.item_count>0&&` · ${ae.item_count} items`]}),ae.error&&n.jsx("div",{style:{fontSize:10,color:"#dc2626",marginTop:1},children:ae.error})]})]},ae.id)})})]})]})}function Hf(t){return{border:"1px solid "+t+"40",borderRadius:4,background:"none",color:t,cursor:"pointer",fontSize:11,padding:"2px 7px"}}function zk(t){if(!t)return"";const o=new Date(t);return Number.isNaN(o.getTime())?t:o.toLocaleString()}const Ek={marginBottom:"2rem",padding:"1.25rem",border:"1px solid #e5e7eb",borderRadius:8},Rk={margin:"0 0 0.5rem 0",fontSize:15,fontWeight:600,color:"#111827"},ly={margin:0,fontSize:12,color:"#6b7280",lineHeight:1.5},Wf={fontSize:11,fontWeight:700,color:"#7c3aed",textTransform:"uppercase",letterSpacing:.5,marginBottom:6},Jn={padding:"6px 10px",border:"1px solid #d1d5db",borderRadius:5,fontSize:13,width:"100%",boxSizing:"border-box",outline:"none"},pc={padding:"5px 12px",border:"1px solid #2563eb",borderRadius:6,background:"#2563eb",color:"#fff",fontSize:12,fontWeight:600,cursor:"pointer"},Ak={padding:"6px 16px",border:"none",borderRadius:5,background:"#7c3aed",color:"#fff",fontSize:12,fontWeight:600,cursor:"pointer"},cy={padding:"5px 9px",border:"1px solid #d1d5db",borderRadius:5,background:"#fff",cursor:"pointer",fontSize:12},ha={padding:"5px 12px",border:"1px solid #c7d2fe",borderRadius:6,background:"#fff",color:"#4338ca",fontSize:12,fontWeight:600,cursor:"pointer"},Mk=[{id:"news_api_key",label:"NewsAPI",href:"https://newsapi.org/account",hint:"Global news articles. Free tier: 100 req/day."},{id:"serp_api_key",label:"SerpAPI",href:"https://serpapi.com/manage-api-key",hint:"Google search results. Free tier: 100 searches/month."},{id:"brave_search_api_key",label:"Brave Search",href:"https://api-dashboard.search.brave.com/",hint:"Web search. Free tier: 2,000 queries/month."},{id:"uspto_api_key",label:"USPTO (ODP)",href:"https://developer.uspto.gov/",hint:"US patent search via the Open Data Portal. Free key."}],Dk=[{id:"semantic_scholar_api_key",label:"Semantic Scholar",href:"https://www.semanticscholar.org/product/api#api-key-form",hint:"Removes the 100 req/5 min cap. Strongly recommended."},{id:"openalex_email",label:"OpenAlex (email)",href:"https://docs.openalex.org/how-to-use-the-api/rate-limits-and-authentication",hint:"Enter your email for priority access. Not a key — just an email."}];function Lk(){const{toast:t}=et(),[o,r]=x.useState(null),[l,c]=x.useState([]),[d,u]=x.useState([]),[p,g]=x.useState(null),[h,v]=x.useState(null),[y,b]=x.useState({}),[S,k]=x.useState({}),[_,T]=x.useState(!1),[w,C]=x.useState(!1),[j,L]=x.useState(!1),W=x.useCallback(async()=>{try{const[H,A,G,R,X]=await Promise.all([ad(),Cb(),_b(),zb().catch(()=>null),Tb().catch(()=>null)]);r(H),c(A.sources),u(G.topics),g(R),v(X)}catch(H){t(H instanceof Error?H.message:"Failed to load discovery state","error")}},[t]);x.useEffect(()=>{W()},[W]);const P=async H=>{const A=(y[H]??"").trim();if(!A){t("Paste a value first","warning");return}T(!0);try{await sr({[H]:A}),b(G=>({...G,[H]:""})),t(`${H} saved`,"success"),await W()}catch(G){t(G instanceof Error?G.message:"Save failed","error")}finally{T(!1)}},z=async H=>{k(A=>({...A,[H]:"loading"}));try{const A=await m2(H);k(G=>({...G,[H]:A}))}catch(A){k(G=>({...G,[H]:{valid:!1,provider:H,message:A instanceof Error?A.message:"verify failed"}}))}},M=async H=>{T(!0);try{const A=H?await Eb():await Rb();g(A),t(H?`Auto-start ON · every ${Math.round(A.interval_seconds/3600)}h`:"Auto-start OFF","info")}catch(A){t(A instanceof Error?A.message:"Toggle failed","error")}finally{T(!1)}},q=async()=>{C(!0);try{const H=await Pc({});t(`Fetch started · job ${H.job_id.slice(0,8)}`,"info")}catch(H){t(H instanceof Error?H.message:"Fetch failed to start","error")}finally{C(!1)}},K=async()=>{L(!0);try{const H=await Hp({limit:50});t(`Mine started · job ${H.job_id.slice(0,8)} · limit 50`,"info")}catch(H){t(H instanceof Error?H.message:"Mine failed to start","error")}finally{L(!1)}},D=l.filter(H=>H.configured).length,Y=l.length;return n.jsxs("section",{style:Nk,children:[n.jsx("h3",{style:Bk,children:"🔭 Auto Discovery"}),n.jsx("p",{style:ga,children:"The continuous-discovery loop fetches new findings from external sources, classifies + de-duplicates them via your AI provider, and surfaces them in the Discovery view + Dashboard. Configure the sources, toggle the schedule, and trigger manual runs from this panel."}),n.jsxs("div",{style:{marginTop:10,padding:"10px 14px",borderRadius:7,border:`1px solid ${p!=null&&p.running?"#86efac":"#fcd34d"}`,background:p!=null&&p.running?"#f0fdf4":"#fffbeb",display:"flex",alignItems:"center",gap:10,flexWrap:"wrap"},children:[n.jsx("span",{style:{fontSize:16},children:p!=null&&p.running?"⏱️":"💤"}),n.jsxs("div",{style:{flex:1,minWidth:220},children:[n.jsx("div",{style:{fontSize:13,fontWeight:600,color:p!=null&&p.running?"#15803d":"#92400e"},children:p!=null&&p.running?"Auto-discovery running":"Auto-discovery off"}),n.jsxs("div",{style:{fontSize:11,color:"#6b7280",marginTop:2},children:[D,"/",Y," sources configured",p?` · interval ${Math.round(p.interval_seconds/3600)}h`:"",p!=null&&p.enabled?" · persisted":p?" · not persisted":"",d.length>0?` · ${d.length} topic(s)`:""]})]}),n.jsx("div",{onClick:()=>!_&&void M(!(p!=null&&p.running)),title:p!=null&&p.running?"Stop scheduler":"Start scheduler + persist",style:{width:44,height:24,borderRadius:12,cursor:_?"not-allowed":"pointer",flexShrink:0,position:"relative",background:p!=null&&p.running?"#22c55e":"#d1d5db",opacity:_?.5:1,transition:"background 0.2s"},children:n.jsx("div",{style:{position:"absolute",top:3,left:p!=null&&p.running?23:3,width:18,height:18,borderRadius:"50%",background:"#fff",boxShadow:"0 1px 3px rgba(0,0,0,0.25)",transition:"left 0.2s"}})})]}),n.jsxs("div",{style:{marginTop:14},children:[n.jsx("div",{style:hc,children:"1 · Manual run"}),n.jsx("p",{style:{...ga,marginTop:4},children:"Trigger a fetch (pulls new items from every configured source for every topic) and/or a mine (LLM-classifies un-mined items in the queue). Both run as background jobs you can watch in the Jobs panel."}),n.jsxs("div",{style:{display:"flex",gap:8,flexWrap:"wrap"},children:[n.jsx("button",{onClick:()=>void q(),disabled:w,style:{...Ik,opacity:w?.5:1,cursor:w?"not-allowed":"pointer"},children:w?"⏳ Fetching…":"▶ Fetch now"}),n.jsx("button",{onClick:()=>void K(),disabled:j,style:{...$k,opacity:j?.5:1,cursor:j?"not-allowed":"pointer"},children:j?"⏳ Mining…":"✨ Mine now (50)"}),n.jsx("span",{style:{flex:1}}),n.jsx("a",{href:"#",onClick:H=>{H.preventDefault(),window.dispatchEvent(new CustomEvent("glossa:navigate",{detail:{view:"discovery"}}))},style:{alignSelf:"center",fontSize:11,color:"#2563eb",textDecoration:"underline"},children:"Open Discovery view →"})]}),n.jsxs("p",{style:{...ga,marginTop:8,fontSize:11},children:["Or from a shell: ",n.jsx("code",{children:"python -m glossa_lab.discovery fetch"})," / ",n.jsx("code",{children:"mine --limit 50"})," / ",n.jsx("code",{children:"daily --notify"})]})]}),n.jsxs("div",{style:{marginTop:14},children:[n.jsx("div",{style:hc,children:"2 · API keys"}),n.jsx("p",{style:{...ga,marginTop:4},children:"Sources that need a key are listed below. Keyless sources (arXiv, Crossref, OpenAlex, PubMed, Europe PMC, DOAJ, GDELT, PPUBS, RSS, Academia) are always on."}),n.jsx("div",{style:{marginTop:10,marginBottom:4},children:n.jsx("span",{style:uy,children:"🔑 Required — source won’t fetch without these"})}),n.jsx("div",{style:{display:"grid",gap:8},children:Mk.map(H=>n.jsx(dy,{k:H,settings:o,pendingKeys:y,setPendingKeys:b,verify:S,onSaveKey:P,onVerifyKey:z,busy:_},H.id))}),n.jsx("div",{style:{marginTop:14,marginBottom:4},children:n.jsx("span",{style:uy,children:"⚡ Optional upgrades — source works without, key removes rate limits"})}),n.jsx("div",{style:{display:"grid",gap:8},children:Dk.map(H=>n.jsx(dy,{k:H,settings:o,pendingKeys:y,setPendingKeys:b,verify:S,onSaveKey:P,onVerifyKey:z,busy:_},H.id))})]}),n.jsxs("div",{style:{marginTop:14},children:[n.jsx("div",{style:hc,children:"3 · Email digest on run"}),n.jsx("p",{style:{...ga,marginTop:4},children:"When notifications are configured (any active recipient + a working transport), every scheduled fetch+mine cycle sends a digest of new findings."}),n.jsxs("div",{style:{padding:10,borderRadius:7,border:`1px solid ${h!=null&&h.configured?"#86efac":"#fcd34d"}`,background:h!=null&&h.configured?"#f0fdf4":"#fffbeb",display:"flex",alignItems:"center",gap:10,flexWrap:"wrap"},children:[n.jsx("span",{style:{fontSize:14},children:h!=null&&h.configured?"✉":"⚠"}),n.jsxs("div",{style:{flex:1,minWidth:220},children:[n.jsx("div",{style:{fontSize:12,fontWeight:600,color:h!=null&&h.configured?"#15803d":"#92400e"},children:h!=null&&h.configured?`Transport: ${h==null?void 0:h.transport} · ${h==null?void 0:h.recipients_active}/${h==null?void 0:h.recipients_total} active recipient(s)`:"Email transport not configured"}),n.jsx("div",{style:{fontSize:10,color:"#6b7280",marginTop:2},children:h!=null&&h.configured?"Manage recipients + send a test in the Email & Notifications section below.":"Configure Resend, Outlook 365 OAuth, or SMTP in the Email & Notifications section below."})]})]})]}),n.jsxs("div",{style:{marginTop:14},children:[n.jsx("div",{style:hc,children:"4 · Sources detected by the backend"}),n.jsx("div",{style:{display:"flex",gap:6,flexWrap:"wrap",marginTop:6},children:l.map(H=>{const A=H,G=A.rate_limit,R=G==null?void 0:G.rate_limited,X=Number((G==null?void 0:G.errors_429)??0),B=Number((G==null?void 0:G.requests)??0),V=A.upgrade_hint,Q=A.upgrade_url,N=R?"#fef2f2":H.configured?"#f0fdf4":"#fafafa",O=R?"#fca5a5":H.configured?"#86efac":"#e5e7eb",$=R?"#b91c1c":H.configured?"#15803d":"#9ca3af";return n.jsxs("span",{title:R?`⚠ Rate limited (${X}/${B} requests returned 429)${V?`. ${V}`:""}`:B>0?`${B} requests, ${X} rate-limited`:H.disabled_reason||`${H.source} ready`,style:{padding:"3px 9px",borderRadius:12,border:"1px solid",background:N,borderColor:O,color:$,fontSize:11,fontWeight:500,cursor:Q?"pointer":"default"},onClick:()=>Q&&window.open(Q,"_blank"),children:[R?"⚠ ":H.configured?"✓ ":"✗ ",H.source,B>0&&n.jsxs("span",{style:{fontSize:9,marginLeft:4,opacity:.7},children:[B,"req",X>0?` · ${X}×429`:""]})]},H.source)})})]})]})}function dy({k:t,settings:o,pendingKeys:r,setPendingKeys:l,verify:c,onSaveKey:d,onVerifyKey:u,busy:p}){var y,b,S,k,_;const g=((y=o==null?void 0:o.keys[t.id])==null?void 0:y.set)??!1,h=((b=o==null?void 0:o.keys[t.id])==null?void 0:b.source)??null,v=c[t.id];return n.jsxs("div",{style:{padding:"8px 10px",border:"1px solid #e5e7eb",borderRadius:7,background:"#fff",display:"flex",flexDirection:"column",gap:5},children:[n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,flexWrap:"wrap"},children:[n.jsx("span",{style:{fontSize:13,fontWeight:600,color:"#111827"},children:t.label}),g?n.jsxs("span",{style:{fontSize:10,padding:"1px 7px",borderRadius:9,background:"#dcfce7",color:"#15803d",fontWeight:700},children:["SET (",h,")"]}):n.jsx("span",{style:{fontSize:10,padding:"1px 7px",borderRadius:9,background:"#fee2e2",color:"#b91c1c",fontWeight:700},children:"MISSING"}),t.hint&&n.jsxs("span",{style:{fontSize:10,color:"#6b7280"},children:["— ",t.hint]}),n.jsx("a",{href:t.href,target:"_blank",rel:"noopener noreferrer",style:{fontSize:11,color:"#2563eb",marginLeft:"auto"},children:"Get key →"})]}),n.jsxs("div",{style:{display:"flex",gap:6},children:[n.jsx("input",{value:r[t.id]??"",onChange:T=>l(w=>({...w,[t.id]:T.target.value})),placeholder:g?"●●●●●●●● (paste new value)":`Paste ${t.label} key`,type:"password",autoComplete:"off",style:Ok}),n.jsx("button",{onClick:()=>void d(t.id),disabled:p||!((S=r[t.id])!=null&&S.trim()),style:{...Wk,opacity:p||!((k=r[t.id])!=null&&k.trim())?.5:1,cursor:p||!((_=r[t.id])!=null&&_.trim())?"not-allowed":"pointer"},children:"Save"}),n.jsx("button",{onClick:()=>void u(t.id),disabled:!g||v==="loading",style:{...Hk,opacity:!g||v==="loading"?.5:1,cursor:!g||v==="loading"?"not-allowed":"pointer"},children:v==="loading"?"…":"Verify"})]}),v&&v!=="loading"&&n.jsxs("div",{style:{fontSize:11,color:v.valid?"#15803d":"#b91c1c"},children:[v.valid?"✓":"✗"," ",v.message]})]})}const Nk={marginBottom:"2rem",padding:"1.25rem",border:"1px solid #e5e7eb",borderRadius:8},Bk={margin:"0 0 0.5rem 0",fontSize:15,fontWeight:600,color:"#111827"},ga={margin:0,fontSize:12,color:"#6b7280",lineHeight:1.5},hc={fontSize:11,fontWeight:700,color:"#7c3aed",textTransform:"uppercase",letterSpacing:.5,marginBottom:6},uy={fontSize:11,fontWeight:600,color:"#374151"},Ok={flex:1,padding:"6px 10px",border:"1px solid #d1d5db",borderRadius:5,fontSize:13,boxSizing:"border-box",outline:"none"},Ik={padding:"6px 14px",border:"1px solid #2563eb",borderRadius:6,background:"#2563eb",color:"#fff",fontSize:12,fontWeight:600,cursor:"pointer"},$k={padding:"6px 14px",border:"1px solid #7c3aed",borderRadius:6,background:"#7c3aed",color:"#fff",fontSize:12,fontWeight:600,cursor:"pointer"},Hk={padding:"5px 10px",border:"1px solid #d1d5db",borderRadius:5,background:"#fff",cursor:"pointer",fontSize:12},Wk={padding:"5px 12px",border:"1px solid #c7d2fe",borderRadius:6,background:"#fff",color:"#4338ca",fontSize:12,fontWeight:600,cursor:"pointer"},Uk={cloud:"☁️",ollama:"🦙",byoe:"🔌",huggingface:"🤗"},fy={reachable:"#16a34a",unreachable:"#dc2626",untested:"#9ca3af"};function qk(){const{toast:t}=et(),[o,r]=x.useState([]),[l,c]=x.useState([]),[d,u]=x.useState(!0),[p,g]=x.useState({}),[h,v]=x.useState(!1),[y,b]=x.useState(null),[S,k]=x.useState({}),[_,T]=x.useState({}),[w,C]=x.useState("cloud"),[j,L]=x.useState(""),[W,P]=x.useState(""),[z,M]=x.useState(""),[q,K]=x.useState(""),[D,Y]=x.useState(!1),H=async()=>{u(!0);try{const O=await Db();r(O.providers)}catch{}finally{u(!1)}};x.useEffect(()=>{H(),Lj().then(O=>c(O.providers)).catch(()=>{})},[]);const A=async O=>{var F;const $=((F=o.find(I=>I.id===O))==null?void 0:F.name)??"provider";g(I=>({...I,[O]:!0})),t(`Testing '${$}'...`,"info");try{const I=await Mj(O);t(I.message,I.valid?"success":"error"),await H()}catch(I){t(I instanceof Error?I.message:"Test failed","error")}g(I=>({...I,[O]:!1}))},G=async(O,$)=>{if(window.confirm(`Delete provider "${$}"?`))try{await Aj(O),t(`${$} deleted`,"success"),b(null),await H()}catch(F){t(F instanceof Error?F.message:"Delete failed","error")}},R=async(O,$)=>{try{await ny(O,{enabled:$?1:0}),await H()}catch{}},X=async(O,$,F)=>{if($==="name"&&!F.trim()){t("Provider name cannot be empty","error");return}T(I=>({...I,[`${O}_${$}`]:!0}));try{await ny(O,{[$]:F}),t(`${$} updated`,"success"),k(I=>{const J={...I};return delete J[`${O}_${$}`],J}),await H()}catch(I){t(I instanceof Error?I.message:"Save failed","error")}T(I=>({...I,[`${O}_${$}`]:!1}))},B=async()=>{if(!W.trim()){t("Name is required","error");return}Y(!0);try{const O=l.find($=>$.id===j);await Rj({name:W,provider_type:w,provider_id:w==="cloud"?j:w,base_url:z||((O==null?void 0:O.base_url)??""),api_key:q}),t(`${W} added`,"success"),v(!1),P(""),M(""),K(""),L(""),await H()}catch(O){t(O instanceof Error?O.message:"Add failed","error")}Y(!1)},V=async()=>{t("Scanning for Ollama...","info");try{const O=await Dj();if(O.detected.length===0){t("No Ollama instances found","error");return}const $=O.detected[0];C("ollama"),P("Ollama"),M($.url),v(!0),t(`Found Ollama at ${$.url} with ${$.models.length} model(s)`,"success")}catch{t("Detection failed","error")}},Q=(O,$,F,I="text",J="")=>{const ne=`${O.id}_${$}`,se=ne in S,pe=S[ne]??"",_e=_[ne],we=$==="api_key"?"":O[$]||"",ke=se?pe:$==="api_key"?"":we,te=$==="name"&&se&&!pe.trim();return n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("label",{style:{fontSize:10,fontWeight:600,color:"#6b7280",display:"block",marginBottom:2},children:F}),n.jsxs("div",{style:{display:"flex",gap:4},children:[n.jsx("input",{type:I,value:ke,onChange:de=>k(Ce=>({...Ce,[ne]:de.target.value})),placeholder:$==="api_key"?O.api_key_set?"•••••••• (paste new to replace)":"Paste API key...":J||we,style:{flex:1,padding:"4px 8px",fontSize:12,borderRadius:4,border:`1px solid ${te?"#f87171":"#d1d5db"}`,fontFamily:I==="password"?"monospace":void 0}}),se&&n.jsx("button",{onClick:()=>X(O.id,$,pe),disabled:_e||te,style:{padding:"4px 10px",fontSize:11,border:"none",borderRadius:4,background:te?"#9ca3af":"#2563eb",color:"#fff",cursor:te?"not-allowed":"pointer",fontWeight:600},children:_e?"...":"Save"})]}),te&&n.jsx("div",{style:{fontSize:10,color:"#ef4444",marginTop:2},children:"Name cannot be empty"})]})},N={border:"1px solid #e5e7eb",borderRadius:8,padding:16,marginBottom:16,background:"#fff"};return n.jsxs("section",{style:N,children:[n.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:12},children:[n.jsx("h3",{style:{margin:0,fontSize:15,fontWeight:700},children:"🔗 Provider Registry"}),n.jsxs("div",{style:{display:"flex",gap:6},children:[n.jsx("button",{onClick:V,style:{padding:"4px 10px",fontSize:11,border:"1px solid #d1d5db",borderRadius:4,cursor:"pointer",background:"#fff"},children:"🦙 Detect Ollama"}),n.jsx("button",{onClick:()=>v(!0),style:{padding:"4px 10px",fontSize:11,border:"none",borderRadius:4,cursor:"pointer",background:"#2563eb",color:"#fff",fontWeight:600},children:"+ Add Provider"})]})]}),d&&n.jsx("div",{style:{color:"#9ca3af",fontSize:12},children:"Loading..."}),n.jsxs("div",{style:{display:"grid",gap:8},children:[o.map(O=>{const $=y===O.id;return n.jsxs("div",{style:{border:"1px solid #e5e7eb",borderRadius:6,overflow:"hidden",background:O.enabled?"#f0fdf4":"#fafafa"},children:[n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,padding:"8px 12px",cursor:"pointer"},onClick:()=>b($?null:O.id),children:[n.jsx("span",{style:{fontSize:16},children:Uk[O.provider_type]||"🔗"}),n.jsxs("div",{style:{flex:1,minWidth:0},children:[n.jsxs("div",{style:{display:"flex",gap:6,alignItems:"center"},children:[n.jsx("span",{style:{fontWeight:600,fontSize:13},children:O.name}),n.jsx("span",{style:{fontSize:10,padding:"1px 5px",borderRadius:3,background:`${fy[O.status]||"#9ca3af"}20`,color:fy[O.status]||"#9ca3af",fontWeight:700},children:O.status}),O.api_key_set&&n.jsx("span",{style:{fontSize:9,padding:"1px 4px",borderRadius:3,background:"#dcfce7",color:"#166534"},children:"key set"}),O.available_models.length>0&&n.jsxs("span",{style:{fontSize:10,color:"#6b7280"},children:[O.available_models.length," model(s)"]})]}),n.jsxs("div",{style:{fontSize:11,color:"#6b7280",marginTop:1},children:[(()=>{var J;const F=O.provider_type==="cloud"?((J=l.find(ne=>ne.id===O.provider_id))==null?void 0:J.label)??O.provider_id:O.provider_id,I=F&&F!==O.provider_type;return n.jsxs(n.Fragment,{children:[O.provider_type,I?` · ${F}`:""]})})(),O.base_url&&n.jsxs("span",{children:[" · ",O.base_url.replace(/https?:\/\//,"").slice(0,40)]})]})]}),n.jsx("input",{type:"checkbox",checked:!!O.enabled,onChange:F=>{F.stopPropagation(),R(O.id,F.target.checked)},style:{width:14,height:14,cursor:"pointer"}}),n.jsx("button",{onClick:F=>{F.stopPropagation(),A(O.id)},disabled:p[O.id],style:{padding:"3px 8px",fontSize:10,border:"1px solid #d1d5db",borderRadius:3,cursor:"pointer",background:"#fff"},children:p[O.id]?"...":"Test"}),n.jsx("span",{style:{fontSize:10,color:"#9ca3af",transform:$?"rotate(90deg)":"rotate(0deg)",transition:"transform 0.15s"},children:"▶"})]}),$&&n.jsxs("div",{style:{padding:"8px 12px 12px",borderTop:"1px solid #e5e7eb",background:"#f8fafc"},children:[Q(O,"name","Name","text","Provider name"),Q(O,"base_url","Base URL","text","https://api.openai.com/v1"),Q(O,"api_key","API Key","password","sk-..."),O.available_models.length>0&&n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("label",{style:{fontSize:10,fontWeight:600,color:"#6b7280",display:"block",marginBottom:4},children:"Available Models"}),n.jsxs("div",{style:{display:"flex",flexWrap:"wrap",gap:4},children:[O.available_models.slice(0,20).map(F=>n.jsx("span",{style:{fontSize:10,padding:"2px 6px",background:"#e0f2fe",color:"#0369a1",borderRadius:3,fontFamily:"monospace"},children:F},F)),O.available_models.length>20&&n.jsxs("span",{style:{fontSize:10,color:"#9ca3af"},children:["+",O.available_models.length-20," more"]})]})]}),n.jsxs("div",{style:{display:"flex",gap:6,marginTop:8},children:[n.jsx("button",{onClick:()=>A(O.id),disabled:p[O.id],style:{padding:"4px 12px",fontSize:11,border:"1px solid #d1d5db",borderRadius:4,cursor:"pointer",background:"#fff"},children:p[O.id]?"Testing...":"↻ Refresh Models"}),n.jsx("button",{onClick:()=>G(O.id,O.name),style:{padding:"4px 12px",fontSize:11,border:"1px solid #fca5a5",borderRadius:4,cursor:"pointer",background:"#fef2f2",color:"#dc2626",marginLeft:"auto"},children:"Delete Provider"})]})]})]},O.id)}),!d&&o.length===0&&n.jsx("div",{style:{textAlign:"center",padding:20,color:"#9ca3af",fontSize:12},children:'No providers configured. Click "Add Provider" to get started.'})]}),h&&n.jsx("div",{style:{position:"fixed",inset:0,background:"rgba(0,0,0,0.3)",zIndex:1e3,display:"flex",alignItems:"center",justifyContent:"center"},onClick:()=>v(!1),children:n.jsxs("div",{style:{background:"#fff",borderRadius:10,padding:24,width:440,maxHeight:"80vh",overflow:"auto"},onClick:O=>O.stopPropagation(),children:[n.jsx("h4",{style:{margin:"0 0 12px"},children:"Add Provider"}),n.jsx("label",{style:{fontSize:11,fontWeight:600,display:"block",marginBottom:4},children:"Type"}),n.jsxs("select",{value:w,onChange:O=>{C(O.target.value),L(""),M("")},style:{width:"100%",padding:"6px 8px",borderRadius:4,border:"1px solid #d1d5db",marginBottom:10,fontSize:13},children:[n.jsx("option",{value:"cloud",children:"☁️ Cloud (OpenAI, Anthropic, Mistral, ...)"}),n.jsx("option",{value:"ollama",children:"🦙 Ollama (local)"}),n.jsx("option",{value:"byoe",children:"🔌 BYOE (vLLM, LM Studio, custom endpoint)"}),n.jsx("option",{value:"huggingface",children:"🤗 HuggingFace Inference"})]}),w==="cloud"&&n.jsxs(n.Fragment,{children:[n.jsx("label",{style:{fontSize:11,fontWeight:600,display:"block",marginBottom:4},children:"Provider"}),n.jsxs("select",{value:j,onChange:O=>{const $=O.target.value;L($);const F=l.find(I=>I.id===$);F&&(P(F.label),M(F.base_url))},style:{width:"100%",padding:"6px 8px",borderRadius:4,border:"1px solid #d1d5db",marginBottom:10,fontSize:13},children:[n.jsx("option",{value:"",children:"Select..."}),l.map(O=>n.jsx("option",{value:O.id,children:O.label},O.id))]})]}),n.jsx("label",{style:{fontSize:11,fontWeight:600,display:"block",marginBottom:4},children:"Name"}),n.jsx("input",{value:W,onChange:O=>P(O.target.value),placeholder:"My vLLM server",style:{width:"100%",padding:"6px 8px",borderRadius:4,border:"1px solid #d1d5db",marginBottom:10,fontSize:13}}),n.jsx("label",{style:{fontSize:11,fontWeight:600,display:"block",marginBottom:4},children:"Base URL"}),n.jsx("input",{value:z,onChange:O=>M(O.target.value),placeholder:w==="ollama"?"http://localhost:11434":"http://BitConcepts:8000/v1",style:{width:"100%",padding:"6px 8px",borderRadius:4,border:"1px solid #d1d5db",marginBottom:10,fontSize:13}}),n.jsx("label",{style:{fontSize:11,fontWeight:600,display:"block",marginBottom:4},children:"API Key (optional)"}),n.jsx("input",{value:q,onChange:O=>K(O.target.value),type:"password",placeholder:"sk-...",style:{width:"100%",padding:"6px 8px",borderRadius:4,border:"1px solid #d1d5db",marginBottom:16,fontSize:13}}),n.jsxs("div",{style:{display:"flex",gap:8,justifyContent:"flex-end"},children:[n.jsx("button",{onClick:()=>v(!1),style:{padding:"6px 14px",borderRadius:4,border:"1px solid #d1d5db",cursor:"pointer",background:"#fff",fontSize:12},children:"Cancel"}),n.jsx("button",{onClick:B,disabled:D,style:{padding:"6px 14px",borderRadius:4,border:"none",cursor:"pointer",background:"#2563eb",color:"#fff",fontSize:12,fontWeight:600},children:D?"Saving...":"Add Provider"})]})]})})]})}const py={ollama:{icon:"🦙",label:"Ollama",bg:"#fef3c7",color:"#92400e"},cloud:{icon:"☁️",label:"Cloud",bg:"#dbeafe",color:"#1e40af"},byoe:{icon:"⚡",label:"vLLM/Custom",bg:"#f3e8ff",color:"#6b21a8"},huggingface:{icon:"🤗",label:"HuggingFace",bg:"#fce7f3",color:"#9d174d"}};function Gk(t,o){return t==="ollama"?"ollama":t==="huggingface"?"huggingface":o!=null&&o.includes(":11434")||o!=null&&o.toLowerCase().includes("ollama")?"ollama":t==="byoe"?"byoe":t}const Pk={reasoning:{label:"Reasoning",icon:"🧠",desc:"Decipher, hypotheses, experiment planning, discovery classification"},conversational:{label:"Conversational",icon:"💬",desc:"Chat, synthesis, general Q&A"},longform:{label:"Long-form",icon:"📝",desc:"Paper drafting, report generation"},global:{label:"Global Default",icon:"🌐",desc:"Used when no bucket-specific assignment exists"}};function Gi(t){return t?`${t.provider_registry_id}|${t.model}`:""}function Fk(){const{toast:t}=et(),[o,r]=x.useState([]),[l,c]=x.useState([]),[d,u]=x.useState([]),[p,g]=x.useState(!0),[h,v]=x.useState(!1),[y,b]=x.useState(!1),[S,k]=x.useState(!1),[_,T]=x.useState(!1),[w,C]=x.useState(!1),[j,L]=x.useState(()=>localStorage.getItem("glossa_assignment_filter")||"mixed"),W=F=>{L(F),localStorage.setItem("glossa_assignment_filter",F)},[P,z]=x.useState({}),M=[];for(const F of o)for(const I of F.available_models||[])M.push({providerId:F.id,providerName:F.name,model:I,providerType:Gk(F.provider_type,F.base_url),baseUrl:F.base_url});const q=M.filter(F=>j==="cloud"?F.providerType==="cloud":j==="local"?F.providerType==="ollama"||F.providerType==="byoe":!0),K=F=>{const I={};for(const J of F)I[`${J.bucket}_primary`]=Gi(J.primary),I[`${J.bucket}_fallback`]=Gi(J.fallback);return I},D=async()=>{g(!0);try{const[F,I,J]=await Promise.all([Db(!0),Nj(),Lb()]);r(F.providers),c(I.assignments),u(J.scores),z(K(I.assignments))}catch{}g(!1)};x.useEffect(()=>{D()},[]);const Y=(F,I)=>{const J=l.find(ne=>ne.bucket===F);return I==="primary"?J==null?void 0:J.primary:J==null?void 0:J.fallback},H=F=>{const I=[F];if(F.includes("/")&&I.push(F.split("/").slice(1).join("/")),F.includes(":")){const J=F.split(":")[0],ne=F.split(":")[1];I.push(`${J}-${ne}`),I.push(J)}I.push(F.replace(/\./g,"-").replace(/:/,"-")),I.push(F.replace(/\./g,"").replace(/:/,"-"));for(const J of I){const ne=d.find(se=>se.model_name===J||J.toLowerCase().includes(se.model_name.toLowerCase())||se.model_name.toLowerCase().includes(J.toLowerCase()));if(ne)return ne}},A=(()=>{for(const F of l){const I=`${F.bucket}_primary`,J=`${F.bucket}_fallback`;if(P[I]!==Gi(F.primary)||P[J]!==Gi(F.fallback))return!0}for(const F of Object.keys(P))if(P[F]){const[I,J]=F.split("_"),ne=l.find(pe=>pe.bucket===I),se=Gi(J==="primary"?ne==null?void 0:ne.primary:ne==null?void 0:ne.fallback);if(P[F]!==se)return!0}return!1})(),G=(F,I,J)=>{z(ne=>({...ne,[`${F}_${I}`]:J}))},R=async()=>{v(!0);const F=["reasoning","conversational","longform","global"];let I=!1;for(const J of F){const ne=P[`${J}_primary`]??"",se=P[`${J}_fallback`]??"",[pe,..._e]=ne.split("|"),we=_e.join("|"),[ke,...te]=se.split("|"),de=te.join("|"),Ce=l.find(De=>De.bucket===J),ze=Gi(Ce==null?void 0:Ce.primary),ve=Gi(Ce==null?void 0:Ce.fallback);if(!(ne===ze&&se===ve))try{await Bj(J,{primary_provider_id:pe||"",primary_model:we||"",fallback_provider_id:ke||"",fallback_model:de||""})}catch(De){t(`${J}: ${De instanceof Error?De.message:"Save failed"}`,"error"),I=!0}}await D(),I||t("Model assignments saved","success"),v(!1)},X=()=>{z(K(l)),t("Changes reverted","info")},B=async()=>{T(!0);try{const F=await Oj(j);F.configured?(t(`Auto-configured (${j}) model assignments`,"success"),await D()):t(F.message||"No models available","error")}catch(F){t(F instanceof Error?F.message:"Auto-configure failed","error")}T(!1)},V=F=>{const I=`${F}_primary`,J=`${F}_fallback`,ne=P[I]??"",se=P[J]??"";!ne&&!se||(z(pe=>({...pe,[I]:se,[J]:ne})),t(`${F} primary ↔ fallback swapped (not saved yet)`,"info"))},Q=async()=>{b(!0),t("🔄 Syncing model scores from HuggingFace...","info");try{const F=await Nb();t(F.message,F.message.includes("unreachable")||F.message.includes("static")?"info":"success"),await D()}catch(F){t(F instanceof Error?F.message:"Sync failed","error")}b(!1)},N=async()=>{k(!0);try{const F=await Ij();t(F.message,F.valid?"success":"error")}catch(F){t(F instanceof Error?F.message:"HF test failed","error")}k(!1)},O={section:{border:"1px solid #e5e7eb",borderRadius:8,padding:16,marginBottom:16,background:"#fff"}},$=(F,I)=>{const J=P[`${F}_${I}`]??"",ne=Gi(Y(F,I)),se=J!==ne,pe=h;return n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6,marginBottom:6},children:[n.jsxs("span",{style:{fontSize:10,fontWeight:600,color:I==="primary"?"#2563eb":"#9ca3af",width:55,flexShrink:0},children:[I==="primary"?"⚡ Primary":"⚠️ Fallback",se&&n.jsx("span",{style:{color:"#f59e0b",marginLeft:2},children:"●"})]}),n.jsxs("select",{value:J,onChange:_e=>G(F,I,_e.target.value),disabled:pe,style:{flex:1,minWidth:0,fontSize:12,padding:"4px 6px",borderRadius:4,border:"1px solid #d1d5db",background:pe?"#f3f4f6":"#fff",textOverflow:"ellipsis"},children:[n.jsx("option",{value:"",children:"— not set —"}),q.map(_e=>{const we=H(_e.model),te=we?we[F==="conversational"?"conversational_score":F==="longform"?"longform_score":"reasoning_score"]??0:0;return{..._e,scoreVal:te,hasScore:!!we}}).filter(_e=>!w||_e.hasScore).sort((_e,we)=>we.scoreVal-_e.scoreVal).map(_e=>{var we;return n.jsxs("option",{value:`${_e.providerId}|${_e.model}`,children:[((we=py[_e.providerType])==null?void 0:we.icon)??"🔌"," ",_e.scoreVal>0?`★${_e.scoreVal.toFixed(0)} `:_e.hasScore?"☆0 ":"",_e.providerName," · ",_e.model]},`${_e.providerId}|${_e.model}`)})]})]})};return n.jsxs("section",{style:O.section,children:[n.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:12},children:[n.jsx("h3",{style:{margin:0,fontSize:15,fontWeight:700},children:"🎯 Model Assignments"}),n.jsxs("div",{style:{display:"flex",gap:6},children:[n.jsx("button",{onClick:N,disabled:S,style:{padding:"4px 10px",fontSize:11,border:"1px solid #d1d5db",borderRadius:4,cursor:"pointer",background:"#fff"},children:S?"Testing...":"🤗 Test HF"}),n.jsx("button",{onClick:Q,disabled:y,style:{padding:"4px 10px",fontSize:11,border:"1px solid #d1d5db",borderRadius:4,cursor:"pointer",background:"#fff"},children:y?"Syncing...":"🔄 Sync Scores"}),n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:2},children:[n.jsx("span",{style:{fontSize:10,color:"#9ca3af",flexShrink:0},children:"Filter:"}),n.jsxs("select",{value:j,onChange:F=>W(F.target.value),style:{fontSize:11,padding:"3px 4px",borderRadius:4,border:"1px solid #d1d5db",background:"#fff"},children:[n.jsx("option",{value:"mixed",children:"🔀 All"}),n.jsx("option",{value:"cloud",children:"☁️ Cloud only"}),n.jsx("option",{value:"local",children:"🖥️ Local only"})]})]}),n.jsx("button",{onClick:B,disabled:_,style:{padding:"4px 10px",fontSize:11,border:"none",borderRadius:4,cursor:"pointer",background:"#7c3aed",color:"#fff",fontWeight:600},children:_?"Configuring...":"✨ Auto-Configure"})]})]}),p&&n.jsx("div",{style:{color:"#9ca3af",fontSize:12},children:"Loading..."}),M.length===0&&!p&&n.jsx("div",{style:{textAlign:"center",padding:16,color:"#9ca3af",fontSize:12,background:"#f9fafb",borderRadius:6},children:'No models available. Add providers above and click "Test" to fetch model lists.'}),n.jsx("div",{style:{display:"grid",gap:10,gridTemplateColumns:"1fr 1fr",minWidth:0},children:["reasoning","conversational","longform","global"].map(F=>{const I=Pk[F],J=!!(P[`${F}_primary`]||Y(F,"primary"))&&!!(P[`${F}_fallback`]||Y(F,"fallback"));return n.jsxs("div",{style:{border:"1px solid #e5e7eb",borderRadius:6,padding:12,background:"#fafafa",minWidth:0,overflow:"hidden"},children:[n.jsxs("div",{style:{display:"flex",gap:6,alignItems:"center",marginBottom:8},children:[n.jsx("span",{style:{fontSize:16},children:I.icon}),n.jsxs("div",{style:{flex:1,minWidth:0},children:[n.jsx("div",{style:{fontWeight:700,fontSize:13},children:I.label}),n.jsx("div",{style:{fontSize:10,color:"#6b7280"},children:I.desc})]}),J&&n.jsx("button",{onClick:()=>V(F),disabled:h,title:"Swap primary ↔ fallback (draft)",style:{padding:"2px 6px",fontSize:11,border:"1px solid #d1d5db",borderRadius:3,cursor:"pointer",background:"#fff",color:"#6b7280",flexShrink:0},children:"⇅"})]}),$(F,"primary"),$(F,"fallback")]},F)})}),n.jsxs("div",{style:{marginTop:10,display:"flex",alignItems:"center",gap:8,padding:"8px 12px",borderRadius:6,background:A?"#fffbeb":"#f9fafb",border:`1px solid ${A?"#fcd34d":"#e5e7eb"}`,transition:"background 0.2s, border-color 0.2s"},children:[n.jsx("span",{style:{fontSize:12,color:A?"#92400e":"#9ca3af",flex:1},children:A?"⚠️ Unsaved changes":"✓ All changes saved"}),n.jsx("button",{onClick:X,disabled:!A||h,style:{padding:"4px 12px",fontSize:12,border:"1px solid #d1d5db",borderRadius:4,cursor:A&&!h?"pointer":"not-allowed",background:"#fff",color:A?"#374151":"#9ca3af",opacity:A?1:.5},children:"Revert"}),n.jsx("button",{onClick:R,disabled:!A||h,style:{padding:"4px 16px",fontSize:12,border:"none",borderRadius:4,cursor:A&&!h?"pointer":"not-allowed",background:A?"#2563eb":"#93c5fd",color:"#fff",fontWeight:700,opacity:A?1:.6},children:h?"Saving…":"✓ Apply"})]}),n.jsxs("div",{style:{marginTop:12,display:"flex",alignItems:"center",gap:12,flexWrap:"wrap"},children:[d.length>0&&n.jsxs("span",{style:{fontSize:10,color:"#9ca3af"},children:["📊 ",d.length," model(s) scored · ★ = bucket fitness score (higher = better)"]}),n.jsxs("label",{style:{display:"flex",alignItems:"center",gap:4,fontSize:11,color:"#6b7280",cursor:"pointer"},children:[n.jsx("input",{type:"checkbox",checked:w,onChange:F=>C(F.target.checked)}),"Scored models only"]}),n.jsx("div",{style:{display:"flex",gap:4,marginLeft:"auto",flexWrap:"wrap"},children:Object.values(py).map(F=>n.jsxs("span",{style:{fontSize:10,padding:"2px 6px",borderRadius:3,background:F.bg,color:F.color,fontWeight:600},children:[F.icon," ",F.label]},F.label))})]})]})}const Ko=new Map,Yk=[{label:"All",max:999},{label:"≤ 4 GB",max:4},{label:"≤ 8 GB",max:8},{label:"≤ 12 GB",max:12},{label:"≤ 16 GB",max:16},{label:"≤ 24 GB",max:24}],Vk={excellent:"#16a34a",great:"#2563eb",good:"#ca8a04"};function Xk(){const{toast:t}=et(),[o,r]=x.useState([]),[l,c]=x.useState(null),[d,u]=x.useState([]),[p,g]=x.useState(!0),[h,v]=x.useState(!1),[y,b]=x.useState(-1),[S,k]=x.useState(()=>{const Y={};for(const[H,A]of Ko)Y[H]={pct:A.pct,status:A.status};return Y}),[_,T]=x.useState({set:!1,editing:!1,value:""}),w=async()=>{g(!0);try{const[Y,H,A]=await Promise.all([G2(),P2().catch(()=>null),Lb()]);r(Y.models),v(Y.running),c(H),u(A.scores);try{const G=await ad();T(R=>{var X,B;return{...R,set:((B=(X=G.keys)==null?void 0:X.hf_api_token)==null?void 0:B.set)??!1}})}catch{}H&&H.vram_gb>0&&y===-1?b(-1):y===-1&&b(999)}catch{}g(!1)};x.useEffect(()=>{w()},[]);const C=Y=>d.find(H=>H.model_name===Y||Y.includes(H.model_name)||H.model_name.includes(Y)),j=Y=>{if(Ko.has(Y))return;const H={pct:0,status:"connecting…"},A=new EventSource(`/api/v1/ollama/pull/${encodeURIComponent(Y)}`);Ko.set(Y,{es:A,...H}),k(G=>({...G,[Y]:H})),A.onmessage=G=>{try{const R=JSON.parse(G.data);if(R.error){t(`Pull failed: ${R.error}`,"error"),Ko.delete(Y),k(Q=>{const N={...Q};return delete N[Y],N}),A.close();return}if(R.status==="success"){t(`${Y} downloaded`,"success"),Ko.delete(Y),k(Q=>{const N={...Q};return delete N[Y],N}),A.close(),w();return}const X=R.total&&R.completed?Math.round(R.completed/R.total*100):0,B=R.status||"downloading…",V=Ko.get(Y);V&&(V.pct=X,V.status=B),k(Q=>({...Q,[Y]:{pct:X,status:B}}))}catch{}},A.onerror=()=>{Ko.delete(Y),k(G=>{const R={...G};return delete R[Y],R}),A.close()}},L=async()=>{try{await sr({hf_api_token:_.value}),T({set:!0,editing:!1,value:""}),t("HF token saved — click Sync Scores to fetch leaderboard data","success")}catch(Y){t(Y instanceof Error?Y.message:"Save failed","error")}},W=async()=>{try{const Y=await Nb();t(Y.message,"success"),w()}catch(Y){t(Y instanceof Error?Y.message:"Sync failed","error")}},P=async Y=>{if(confirm(`Delete ${Y}?`))try{await F2(Y),t(`${Y} deleted`,"success"),w()}catch(H){t(H instanceof Error?H.message:"Delete failed","error")}},z=(l==null?void 0:l.vram_gb)??0,M=y===-1?z:y,q=y!==999&&!(y===-1&&z===0),K=o.slice().sort((Y,H)=>{if(q){const A=Y.min_vram_gb<=M?0:1,G=H.min_vram_gb<=M?0:1;if(A!==G)return A-G}return H.glossa_score-Y.glossa_score||Y.min_vram_gb-H.min_vram_gb}),D={section:{border:"1px solid #e5e7eb",borderRadius:8,padding:16,marginBottom:16,background:"#fff"}};return n.jsxs("section",{style:D.section,children:[n.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:10},children:[n.jsx("h3",{style:{margin:0,fontSize:15,fontWeight:700},children:"🏪 Model Hub"}),n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6},children:[n.jsx("span",{style:{width:8,height:8,borderRadius:"50%",background:h?"#16a34a":"#ef4444"}}),n.jsx("span",{style:{fontSize:11,color:"#6b7280"},children:h?"Ollama running":"Ollama offline"})]})]}),n.jsxs("div",{style:{display:"flex",gap:6,alignItems:"center",marginBottom:10,fontSize:11},children:[n.jsx("span",{style:{color:"#6b7280"},children:"HuggingFace token:"}),_.editing?n.jsxs(n.Fragment,{children:[n.jsx("input",{value:_.value,onChange:Y=>T(H=>({...H,value:Y.target.value})),placeholder:"hf_...",type:"password",style:{flex:1,maxWidth:220,padding:"2px 6px",border:"1px solid #d1d5db",borderRadius:4,fontSize:11}}),n.jsx("button",{onClick:L,style:{padding:"2px 8px",fontSize:10,border:"none",borderRadius:4,background:"#2563eb",color:"#fff",cursor:"pointer"},children:"Save"}),n.jsx("button",{onClick:()=>T(Y=>({...Y,editing:!1,value:""})),style:{padding:"2px 8px",fontSize:10,border:"1px solid #d1d5db",borderRadius:4,background:"#fff",cursor:"pointer"},children:"Cancel"})]}):n.jsxs(n.Fragment,{children:[n.jsx("span",{style:{color:_.set?"#16a34a":"#9ca3af"},children:_.set?"set ✓":"not set"}),n.jsx("button",{onClick:()=>T(Y=>({...Y,editing:!0})),style:{padding:"2px 8px",fontSize:10,border:"1px solid #d1d5db",borderRadius:4,background:"#fff",cursor:"pointer"},children:_.set?"Change":"Add"}),n.jsx("button",{onClick:W,style:{padding:"2px 8px",fontSize:10,border:"1px solid #d1d5db",borderRadius:4,background:"#fff",cursor:"pointer"},children:"🔄 Sync from HF"}),!_.set&&n.jsx("span",{style:{color:"#9ca3af",fontSize:10},children:"Optional — free at huggingface.co/settings/tokens"})]})]}),l&&l.vram_gb>0&&n.jsxs("div",{style:{background:"#f0fdf4",border:"1px solid #86efac",borderRadius:6,padding:"8px 12px",marginBottom:10,fontSize:11,color:"#166534"},children:["🖥️ ",n.jsx("strong",{children:l.gpu_name})," — ",l.vram_gb," GB VRAM · Recommended: ",n.jsx("strong",{children:l.recommended.display})]}),n.jsxs("div",{style:{display:"flex",gap:4,marginBottom:12,flexWrap:"wrap"},children:[z>0&&n.jsxs("button",{onClick:()=>b(-1),style:{padding:"3px 10px",fontSize:11,border:"1px solid #d1d5db",borderRadius:4,cursor:"pointer",background:y===-1?"#16a34a":"#fff",color:y===-1?"#fff":"#374151",fontWeight:y===-1?700:400},children:["🖥️ My GPU (",z," GB)"]}),Yk.map(Y=>n.jsx("button",{onClick:()=>b(Y.max),style:{padding:"3px 10px",fontSize:11,border:"1px solid #d1d5db",borderRadius:4,cursor:"pointer",background:y===Y.max?"#2563eb":"#fff",color:y===Y.max?"#fff":"#374151",fontWeight:y===Y.max?700:400},children:Y.label},Y.max)),n.jsxs("span",{style:{fontSize:10,color:"#9ca3af",alignSelf:"center",marginLeft:4},children:[K.length," model",K.length!==1?"s":""]})]}),p&&n.jsx("div",{style:{color:"#9ca3af",fontSize:12,padding:16,textAlign:"center"},children:"Loading…"}),!p&&!h&&n.jsxs("div",{style:{textAlign:"center",padding:20,color:"#9ca3af",fontSize:12,background:"#fef2f2",border:"1px solid #fca5a5",borderRadius:6},children:["Ollama is not running. Install from ",n.jsx("a",{href:"https://ollama.com",target:"_blank",rel:"noopener noreferrer",children:"ollama.com"})," and start it to download models."]}),!p&&K.map(Y=>{const H=C(Y.name),A=S[Y.name],G=!q||Y.min_vram_gb<=M,R=q&&!G;return n.jsxs("div",{style:{display:"flex",gap:10,alignItems:"flex-start",padding:"10px 0",borderBottom:"1px solid #f3f4f6",opacity:R?.45:1},children:[n.jsxs("div",{style:{flex:1,minWidth:0},children:[n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6,flexWrap:"wrap"},children:[n.jsx("span",{style:{fontSize:13,fontWeight:700},children:Y.display}),n.jsx("span",{style:{fontSize:9,padding:"1px 5px",borderRadius:8,background:Vk[Y.quality]||"#6b7280",color:"#fff",fontWeight:600},children:Y.quality}),Y.installed&&n.jsx("span",{style:{fontSize:9,padding:"1px 5px",borderRadius:8,background:"#16a34a",color:"#fff",fontWeight:600},children:"installed"}),Y.tags.includes("top-pick")&&n.jsx("span",{style:{fontSize:9,padding:"1px 5px",borderRadius:8,background:"#f59e0b",color:"#78350f",fontWeight:700},children:"⭐ TOP PICK"}),Y.tags.includes("moe")&&n.jsx("span",{style:{fontSize:9,padding:"1px 5px",borderRadius:8,background:"#8b5cf6",color:"#fff",fontWeight:600},children:"MoE"}),R&&n.jsxs("span",{style:{fontSize:9,padding:"1px 5px",borderRadius:8,background:"#ef4444",color:"#fff",fontWeight:600},children:["needs ≥",Y.min_vram_gb," GB"]})]}),n.jsx("div",{style:{fontSize:11,color:"#6b7280",marginTop:2},children:Y.desc}),n.jsxs("div",{style:{display:"flex",gap:10,marginTop:3,fontSize:10,color:"#9ca3af"},children:[n.jsxs("span",{children:[Y.param_b,"B params"]}),n.jsxs("span",{children:[Y.size_gb," GB"]}),n.jsxs("span",{children:["≥",Y.min_vram_gb," GB VRAM"]}),H&&n.jsxs(n.Fragment,{children:[n.jsxs("span",{title:"Reasoning",children:["🧠",H.reasoning_score.toFixed(0)]}),n.jsxs("span",{title:"Conversational",children:["💬",H.conversational_score.toFixed(0)]}),n.jsxs("span",{title:"Long-form",children:["📝",H.longform_score.toFixed(0)]})]})]}),A&&n.jsxs("div",{style:{marginTop:4},children:[n.jsx("div",{style:{height:4,background:"#e5e7eb",borderRadius:2,overflow:"hidden"},children:n.jsx("div",{style:{height:"100%",width:`${A.pct}%`,background:"#2563eb",transition:"width 0.3s"}})}),n.jsxs("div",{style:{fontSize:9,color:"#6b7280",marginTop:1},children:[A.status," ",A.pct>0?`${A.pct}%`:""]})]})]}),n.jsx("div",{style:{display:"flex",gap:4,flexShrink:0,alignItems:"center"},children:Y.installed?n.jsx("button",{onClick:()=>P(Y.name),style:{padding:"3px 8px",fontSize:10,border:"1px solid #fca5a5",borderRadius:4,background:"#fff",color:"#dc2626",cursor:"pointer"},children:"🗑️ Delete"}):n.jsx("button",{onClick:()=>j(Y.name),disabled:!h||!!A,style:{padding:"3px 10px",fontSize:10,border:"none",borderRadius:4,cursor:h&&!A?"pointer":"not-allowed",background:h&&!A?"#2563eb":"#e5e7eb",color:h&&!A?"#fff":"#9ca3af",fontWeight:600},children:A?"Pulling…":"⬇ Pull"})})]},Y.name)}),h&&n.jsx(Jk,{onPull:j,pulling:S})]})}function Jk({onPull:t,pulling:o}){const[r,l]=x.useState("");return n.jsxs("div",{style:{marginTop:10,display:"flex",gap:6,alignItems:"center"},children:[n.jsx("input",{value:r,onChange:c=>l(c.target.value),placeholder:"any-model:tag",style:{flex:1,fontSize:11,padding:"4px 8px",border:"1px solid #d1d5db",borderRadius:4},onKeyDown:c=>{c.key==="Enter"&&r.trim()&&(t(r.trim()),l(""))}}),n.jsx("button",{onClick:()=>{r.trim()&&(t(r.trim()),l(""))},disabled:!r.trim()||!!o[r.trim()],style:{padding:"4px 10px",fontSize:10,border:"none",borderRadius:4,background:"#7c3aed",color:"#fff",cursor:"pointer",fontWeight:600},children:"Pull custom"})]})}function Kk(){const{toast:t}=et(),[o,r]=x.useState(null),[l,c]=x.useState(!0),[d,u]=x.useState(!1),[p,g]=x.useState([]),[h,v]=x.useState(null),[y,b]=x.useState(!0),[S,k]=x.useState(!0),_=x.useRef(null),T=async()=>{c(!0);try{r(await kb())}catch{}finally{c(!1)}};x.useEffect(()=>{T()},[]),x.useEffect(()=>{const z=_.current;z&&(z.scrollTop=z.scrollHeight)},[p]);const w=async(z,M)=>{u(!0),g([{text:`Running: ${M}…`,type:"info"}]);try{const q=await z();if(!q.body){g(H=>[...H,{text:"No response body",type:"error"}]);return}const K=q.body.getReader(),D=new TextDecoder;let Y="";for(;;){const{done:H,value:A}=await K.read();if(H)break;Y+=D.decode(A,{stream:!0});const G=Y.split(` +`+r:""}`,[g,h]=x.useState(!1),[b,y]=x.useState(!1),v=()=>{navigator.clipboard.writeText(p).then(()=>{h(!0),setTimeout(()=>h(!1),1500)})},w=jk(o),j=w?w.error??w.message??JSON.stringify(w,null,2):o,_=kk(j||""),C=r??null;return n.jsx("div",{style:{position:"fixed",inset:0,background:"rgba(0,0,0,0.55)",zIndex:12e3,display:"flex",alignItems:"center",justifyContent:"center",padding:20},onClick:u,children:n.jsxs("div",{style:{background:"#fff",borderRadius:12,maxWidth:720,width:"100%",maxHeight:"85vh",display:"flex",flexDirection:"column",boxShadow:"0 24px 64px rgba(0,0,0,0.4)"},onClick:S=>S.stopPropagation(),children:[n.jsxs("div",{style:{padding:"16px 20px",borderBottom:"1px solid #fee2e2",background:"#fef2f2",borderRadius:"12px 12px 0 0",display:"flex",alignItems:"center",gap:10},children:[n.jsx("span",{style:{fontSize:22},children:"⚠️"}),n.jsxs("div",{style:{flex:1,minWidth:0},children:[n.jsx("div",{style:{fontWeight:700,fontSize:14,color:"#991b1b",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},title:t,children:t}),n.jsx("span",{style:{fontSize:11,padding:"1px 7px",borderRadius:8,background:_.color+"20",color:_.color,fontWeight:600},children:_.label})]}),n.jsx("button",{onClick:v,style:{padding:"4px 10px",border:"1px solid #fca5a5",borderRadius:5,background:g?"#fee2e2":"#fff",cursor:"pointer",fontSize:11,color:g?"#16a34a":"#dc2626"},children:g?"✓ Copied":"📋 Copy"}),n.jsx("button",{onClick:u,style:{border:"none",background:"none",cursor:"pointer",fontSize:22,color:"#9ca3af",lineHeight:1,padding:"0 4px"},children:"×"})]}),n.jsxs("div",{style:{flex:1,overflowY:"auto"},children:[n.jsxs("div",{style:{padding:"14px 20px",borderBottom:"1px solid #f3f4f6"},children:[n.jsx("div",{style:{fontSize:12,fontWeight:600,color:"#374151",marginBottom:6,textTransform:"uppercase",letterSpacing:"0.05em"},children:"What went wrong"}),n.jsx("div",{style:{fontSize:13,color:"#111827",lineHeight:1.7,background:"#fef2f2",padding:"10px 14px",borderRadius:7,border:"1px solid #fecaca",whiteSpace:"pre-wrap",wordBreak:"break-word"},children:j||"No error message available."})]}),l&&Object.keys(l).filter(S=>!S.startsWith("_")).length>0&&n.jsxs("div",{style:{padding:"12px 20px",borderBottom:"1px solid #f3f4f6"},children:[n.jsx("div",{style:{fontSize:12,fontWeight:600,color:"#374151",marginBottom:8,textTransform:"uppercase",letterSpacing:"0.05em"},children:"Job parameters"}),n.jsx("table",{style:{width:"100%",borderCollapse:"collapse",fontSize:12},children:n.jsx("tbody",{children:Object.entries(l).filter(([S])=>!S.startsWith("_")&&S!=="traceback").map(([S,E])=>n.jsxs("tr",{style:{borderBottom:"1px solid #f3f4f6"},children:[n.jsx("td",{style:{padding:"4px 10px 4px 0",color:"#6b7280",fontWeight:500,whiteSpace:"nowrap",verticalAlign:"top",width:"35%"},children:Sk(S)}),n.jsx("td",{style:{padding:"4px 0",color:"#111827",wordBreak:"break-all",fontFamily:typeof E=="string"?"inherit":"monospace"},children:wk(E)})]},S))})})]}),C&&n.jsxs("div",{style:{padding:"12px 20px"},children:[n.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:6},children:[n.jsx("div",{style:{fontSize:12,fontWeight:600,color:"#374151",textTransform:"uppercase",letterSpacing:"0.05em"},children:"Stack trace"}),n.jsx("button",{onClick:()=>y(!b),style:{fontSize:11,border:"1px solid #e5e7eb",background:"#f9fafb",borderRadius:4,cursor:"pointer",padding:"2px 8px",color:"#6b7280"},children:b?"Hide":"Show"})]}),b&&n.jsx("pre",{style:{fontFamily:"monospace",fontSize:11,color:"#374151",background:"#f8fafc",padding:"10px 14px",borderRadius:7,border:"1px solid #e5e7eb",lineHeight:1.6,whiteSpace:"pre-wrap",wordBreak:"break-word",margin:0,maxHeight:260,overflowY:"auto"},children:C})]})]}),n.jsxs("div",{style:{padding:"12px 20px",borderTop:"1px solid #f3f4f6",display:"flex",justifyContent:"space-between",alignItems:"center",gap:8},children:[c&&n.jsxs("div",{style:{fontSize:10,color:"#9ca3af",fontFamily:"monospace"},children:["Job ID: ",c.id.slice(0,12),"… · ",c.pipeline]}),n.jsxs("div",{style:{display:"flex",gap:8,marginLeft:"auto"},children:[d&&n.jsx("button",{onClick:()=>{d(),u()},style:{padding:"6px 16px",border:"none",borderRadius:6,background:"#2563eb",color:"#fff",cursor:"pointer",fontSize:13,fontWeight:600},title:"Re-submit this job with the same parameters",children:"↻ Retry"}),n.jsx("button",{onClick:u,style:{padding:"6px 18px",border:"1px solid #d1d5db",borderRadius:6,background:"#fff",cursor:"pointer",fontSize:13},children:"Close"})]})]})]})})}function _k(){const[t,o]=x.useState([]),[r,l]=x.useState(!0),[c,d]=x.useState(!1),[u,p]=x.useState(null),[g,h]=x.useState(null),[b,y]=x.useState([]),[v,w]=x.useState(!1),[j,_]=x.useState(new Set),C=x.useRef(new Map),[S,E]=x.useState(""),[k,D]=x.useState("block_entropy"),[H,G]=x.useState('{"text_id": ""}'),[T,P]=x.useState(!1),[F,W]=x.useState(null),[M,V]=x.useState(null),I=x.useCallback(async(O=!1)=>{O&&d(!0);try{const K=await Oa();o(K.sort((ne,se)=>se.created_at.localeCompare(ne.created_at))),p(new Date),h(null)}catch(K){h(K instanceof Error?K.message:"Failed to load jobs")}finally{l(!1),O&&d(!1)}},[]);x.useEffect(()=>{I();const O=setInterval(I,3e3);return bb().then(y).catch(()=>{}),()=>clearInterval(O)},[I]);const A=x.useCallback(O=>async()=>{try{await qc({name:`${O.name} (retry)`,pipeline:O.pipeline,params:vk(O.params??{})}),await I()}catch(K){alert(K instanceof Error?K.message:"Retry failed")}},[I]),q=async()=>{if(confirm("Delete all jobs and results?")){w(!0);try{await fp(),await I()}finally{w(!1)}}},R=async()=>{if(!S.trim()){W("Job name is required");return}let O;try{O=JSON.parse(H)}catch{W("Params must be valid JSON");return}try{P(!0),W(null),await qc({name:S.trim(),pipeline:k,params:O}),E(""),await I()}catch(K){W(K instanceof Error?K.message:"Submit failed")}finally{P(!1)}},J=async O=>{var pe,_e;const K=((pe=O.params)==null?void 0:pe.exp_id)??"",ne=((_e=O.params)==null?void 0:_e.result_file)??"",se=K?`${K}.json`:ne;if(O.status==="failed"){const Se={};for(const[ke,te]of Object.entries(O.params??{}))!ke.startsWith("_")&&ke!=="traceback"&&(Se[ke]=te);try{const te=await yb(O.id),de=te.error??te.message??te.detail??JSON.stringify(te).slice(0,300),Ce=te.traceback??null;V({title:O.name,message:de||"Unknown error — see stack trace below.",detail:Ce??void 0,params:Object.keys(Se).length?Se:null,job:O,onRetry:A(O)})}catch{V({title:O.name,message:"Job failed — no error details stored in the database.",detail:void 0,params:Object.keys(Se).length?Se:null,job:O,onRetry:A(O)})}return}window.dispatchEvent(new CustomEvent("glossa:navigate",{detail:{view:"reports"}})),se&&setTimeout(()=>{window.dispatchEvent(new CustomEvent("glossa:reports_highlight",{detail:{tab:"data",search:se}}))},120)},N=async O=>{try{await up(O),await I()}catch(K){alert(K instanceof Error?K.message:"Cancel failed")}},X=async O=>{_(K=>new Set([...K,O]));try{await hb(O),await I()}catch(K){alert(K instanceof Error?K.message:"Pause failed")}finally{_(K=>{const ne=new Set(K);return ne.delete(O),ne})}},Q=async O=>{_(K=>new Set([...K,O]));try{await gb(O),await I()}catch(K){alert(K instanceof Error?K.message:"Resume failed")}finally{_(K=>{const ne=new Set(K);return ne.delete(O),ne})}},L=async()=>{try{await mb(),await I()}catch(O){alert(O instanceof Error?O.message:"Pause all failed")}},B=async()=>{try{await xb(),await I()}catch(O){alert(O instanceof Error?O.message:"Resume all failed")}},$=O=>O==="completed"?"#16a34a":O==="failed"?"#dc2626":O==="running"?"#2563eb":O==="pending"?"#d97706":O==="paused"?"#92400e":"#6b7280",Y=O=>O==="completed"?"#dcfce7":O==="failed"?"#fee2e2":O==="running"?"#dbeafe":O==="pending"||O==="paused"?"#fef3c7":"#f3f4f6";return n.jsxs("div",{children:[n.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:4},children:[n.jsxs("div",{style:{display:"flex",alignItems:"baseline",gap:10},children:[n.jsx("h2",{style:{margin:0},children:"Jobs"}),u&&n.jsxs("span",{style:{fontSize:11,color:"#9ca3af"},children:["updated ",yk(u)]})]}),n.jsxs("div",{style:{display:"flex",gap:6},children:[n.jsx("button",{onClick:()=>I(!0),disabled:c,style:{...bi,background:"#f3f4f6",color:"#374151",fontSize:12,padding:"4px 12px"},title:"Manually refresh the job list",children:c?"Refreshing…":"⟳ Refresh"}),n.jsx("button",{onClick:L,disabled:t.filter(O=>O.status==="pending"||O.status==="running").length===0,style:{...bi,background:"#d97706",fontSize:12,padding:"4px 12px"},title:"Pause all pending and running jobs",children:"⏸ Pause All"}),n.jsx("button",{onClick:B,disabled:t.filter(O=>O.status==="paused").length===0,style:{...bi,background:"#059669",fontSize:12,padding:"4px 12px"},title:"Resume all paused jobs",children:"▶ Resume All"}),n.jsx("button",{onClick:q,disabled:v||t.length===0,style:{...bi,background:"#6b7280",fontSize:12,padding:"4px 12px"},children:v?"Clearing…":"Delete All"})]})]}),n.jsxs("details",{style:{marginBottom:"1.5rem"},children:[n.jsx("summary",{style:{cursor:"pointer",fontWeight:600},children:"+ Submit new job"}),n.jsxs("div",{style:{marginTop:"0.75rem",padding:"1rem",border:"1px solid #e5e7eb",borderRadius:6,maxWidth:560},children:[n.jsx(If,{label:"Job name",children:n.jsx("input",{value:S,onChange:O=>E(O.target.value),placeholder:"e.g. Entropy analysis — English",style:$f})}),n.jsx(If,{label:"Pipeline",children:n.jsx("select",{value:k,onChange:O=>{D(O.target.value);const K=b.find(ne=>ne.id===O.target.value);G(K?JSON.stringify(K.default_params,null,2):'{"text_id": ""}')},style:$f,children:(b.length>0?b.map(O=>O.id):[k]).map(O=>n.jsx("option",{value:O,children:O},O))})}),n.jsx(If,{label:"Parameters (JSON)",children:n.jsx("textarea",{value:H,onChange:O=>G(O.target.value),rows:4,style:{...$f,fontFamily:"monospace",resize:"vertical"}})}),F&&n.jsx("p",{style:{color:"#dc2626",margin:"4px 0"},children:F}),n.jsx("button",{onClick:R,disabled:T,style:bi,children:T?"Submitting…":"Submit"})]})]}),r&&n.jsx("p",{children:"Loading…"}),g&&n.jsx("p",{style:{color:"#dc2626"},children:g}),!r&&t.length===0&&n.jsxs("div",{style:{padding:"1.25rem 1.5rem",background:"#f8fafc",border:"1px solid #e2e8f0",borderRadius:8,maxWidth:560},children:[n.jsx("p",{style:{margin:"0 0 8px",fontWeight:600,color:"#374151",fontSize:13},children:"No pipeline jobs yet"}),n.jsxs("p",{style:{margin:"0 0 6px",fontSize:12,color:"#6b7280",lineHeight:1.6},children:["This tab tracks analysis pipelines submitted through the",n.jsx("strong",{children:" Submit new job"})," panel above. Pipeline jobs run corpus analysis (block entropy, NWSP, hypothesis engine, etc.) on corpora you upload to the Corpora tab."]}),n.jsxs("p",{style:{margin:0,fontSize:12,color:"#6b7280",lineHeight:1.6},children:[n.jsx("strong",{children:"Note:"})," background scripts like OCR run separately and do not appear here — check the ",n.jsx("strong",{children:"Experiments"})," tab to run or stream those."]})]}),t.length>0&&n.jsxs("table",{style:{borderCollapse:"collapse",width:"100%"},children:[n.jsx("thead",{children:n.jsx("tr",{children:["Name","Pipeline","Device","Status","Created","Actions"].map(O=>n.jsx(Ck,{children:O},O))})}),n.jsx("tbody",{children:t.map(O=>{var Oe,dt,it,lt,Je,yt,Jt;const K=((Oe=O.params)==null?void 0:Oe.compute_device)??"",ne=((dt=O.params)==null?void 0:dt.compute_device_label)??"",se=K==="gpu",pe=((it=O.params)==null?void 0:it.source)==="cli",_e=((lt=O.params)==null?void 0:lt.source)==="ai_action",Se=K?{bg:se?"#dbeafe":"#f3f4f6",color:se?"#1e40af":"#374151",text:se?`⚡ ${ne||"GPU"}`:`⚙️ ${ne||"CPU"}`}:null,ke=((Je=O.params)==null?void 0:Je.node_count)??0,te=((yt=O.params)==null?void 0:yt.nodes_done)??0,de=ke>0?Math.round(te/ke*100):null,Ce=O.pipeline==="exp_run",ze=((Jt=O.params)==null?void 0:Jt.resource_wait)??null,ve=O.status==="running"?Math.round((Date.now()-new Date(O.created_at).getTime())/1e3):null,De=(()=>{const rn=t.filter(ae=>ae.status==="completed"&&ae.pipeline===O.pipeline&&ae.id!==O.id&&ae.updated_at);if(rn.length===0)return null;const zt=rn.map(ae=>(new Date(ae.updated_at).getTime()-new Date(ae.created_at).getTime())/1e3).filter(ae=>ae>0);return zt.length>0?zt.reduce((ae,He)=>ae+He,0)/zt.length:null})(),Me=ve!==null&&de!==null?de>=15?Math.round(ve/de*(100-de)):De!==null?Math.max(0,Math.round(De-ve)):null:null,Ve=Date.now(),Le=C.current.get(O.id);(!Le||Le.done!==te)&&C.current.set(O.id,{done:te,since:Ve});const Ae=Le&&Le.done===te?Ve-Le.since:0,Ue=Ce&&O.status==="running"&&ke>0&&Ae>18e4&&Me!==null&&ve!==null&&Me>ve*1.5?`node ${te+1}/${ke} computing…`:null;return n.jsxs("tr",{children:[n.jsxs(Qs,{children:[n.jsx("div",{style:{fontWeight:500},children:O.name}),n.jsxs("div",{style:{fontSize:11,color:"#6b7280",fontFamily:"monospace"},children:[O.id.slice(0,8),"…"]}),O.status==="pending"&&ze&&n.jsxs("div",{style:{marginTop:4,fontSize:10,color:"#92400e",background:"#fef3c7",border:"1px solid #fcd34d",borderRadius:4,padding:"2px 7px",display:"flex",alignItems:"center",gap:4},children:[n.jsx("span",{children:"⏳"}),n.jsx("span",{children:ze})]}),O.status==="running"&&Ce&&ke>0&&n.jsxs("div",{style:{marginTop:4,display:"flex",alignItems:"center",gap:6},children:[n.jsx("div",{style:{flex:1,height:4,background:"#e5e7eb",borderRadius:2,overflow:"hidden"},children:n.jsx("div",{style:{height:"100%",width:`${de??0}%`,background:"#2563eb",borderRadius:2,transition:"width 0.5s"}})}),n.jsxs("span",{style:{fontSize:10,color:"#6b7280",whiteSpace:"nowrap"},children:[te,"/",ke," nodes",de!==null?` (${de}%)`:"",ve!==null&&` · ${Ea(ve)}`,Ue?` · ${Ue}`:Me!==null?` · ~${Ea(Me)} left`:""]})]})]}),n.jsx(Qs,{children:n.jsx("code",{style:{fontSize:12},children:O.pipeline})}),n.jsx(Qs,{children:n.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:3},children:[Se&&n.jsx("span",{style:{fontSize:11,padding:"2px 7px",borderRadius:6,background:Se.bg,color:Se.color,fontWeight:600,whiteSpace:"nowrap"},children:Se.text}),pe&&n.jsx("span",{style:{fontSize:11,padding:"2px 7px",borderRadius:6,background:"#f0fdf4",color:"#15803d",fontWeight:600,whiteSpace:"nowrap"},title:"Run from CLI (terminal/script)",children:"💻 CLI"}),_e&&n.jsx("span",{style:{fontSize:11,padding:"2px 7px",borderRadius:6,background:"#fdf4ff",color:"#7e22ce",fontWeight:600,whiteSpace:"nowrap"},title:"Triggered by AI assistant",children:"✨ AI"}),!Se&&!pe&&!_e&&n.jsx("span",{style:{fontSize:11,color:"#9ca3af"},children:"—"})]})}),n.jsxs(Qs,{children:[n.jsx("span",{style:{display:"inline-block",padding:"1px 7px",borderRadius:10,background:Y(O.status),color:$(O.status),fontWeight:700,fontSize:11},children:O.status}),O.status==="running"&&ve!==null&&!Ce&&n.jsxs("div",{style:{fontSize:10,color:"#9ca3af"},children:[Ea(ve??0)," elapsed"]})]}),n.jsx(Qs,{children:Yc(O.created_at)}),n.jsx(Qs,{children:n.jsxs("span",{style:{display:"flex",gap:6,flexWrap:"wrap"},children:[O.status==="completed"&&n.jsx("button",{style:{...bi,padding:"2px 10px",fontSize:12,background:"#059669"},onClick:()=>J(O),title:"Open result in Reports → Data tab",children:"📂 View in Reports"}),O.status==="failed"&&n.jsx("button",{style:{...bi,padding:"2px 10px",fontSize:12,background:"#dc2626"},onClick:()=>J(O),title:"View error details",children:"⚠ Error Details"}),O.status==="cancelled"&&n.jsx("span",{style:{fontSize:11,color:"#6b7280",fontStyle:"italic"},children:"cancelled"}),(O.status==="pending"||O.status==="running")&&n.jsxs(n.Fragment,{children:[n.jsx("button",{style:{...bi,padding:"2px 10px",fontSize:12,background:"#d97706"},onClick:()=>X(O.id),disabled:j.has(O.id),title:"Pause this job",children:j.has(O.id)?"…":"⏸ Pause"}),n.jsx("button",{style:{...bi,padding:"2px 10px",fontSize:12,background:O.status==="running"?"#ea580c":"#6b7280"},onClick:()=>N(O.id),title:O.status==="running"?"Abort this running job":"Cancel this queued job",children:O.status==="running"?"❌ Abort":"⏸ Cancel"})]}),O.status==="paused"&&n.jsx("button",{style:{...bi,padding:"2px 10px",fontSize:12,background:"#059669"},onClick:()=>Q(O.id),disabled:j.has(O.id),title:"Resume this paused job",children:j.has(O.id)?"…":"▶ Resume"})]})})]},O.id)})})]}),M&&n.jsx(Ub,{title:M.title,message:M.message,detail:M.detail,params:M.params,job:M.job,onRetry:M.onRetry,onClose:()=>V(null)})]})}function If({label:t,children:o}){return n.jsxs("div",{style:{marginBottom:"0.6rem"},children:[n.jsx("label",{style:{display:"block",fontWeight:500,marginBottom:2,fontSize:13},children:t}),o]})}function Ck({children:t}){return n.jsx("th",{style:{textAlign:"left",padding:"4px 12px 4px 0",borderBottom:"2px solid #e5e7eb",fontSize:13,color:"#374151",whiteSpace:"nowrap"},children:t})}function Qs({children:t}){return n.jsx("td",{style:{padding:"5px 12px 5px 0",borderBottom:"1px solid #f3f4f6",fontSize:13,verticalAlign:"top"},children:t})}const $f={width:"100%",padding:"5px 8px",border:"1px solid #d1d5db",borderRadius:4,fontSize:13,boxSizing:"border-box"},bi={background:"#2563eb",color:"#fff",border:"none",borderRadius:4,padding:"6px 16px",fontSize:13,cursor:"pointer"},Tk=[{id:"block_entropy",label:"Block Entropy",group:"Statistical (no LM)",description:"Computes H_n (normalized) for n = 1..max_n. Sub-linear growth is the hallmark of natural language (Rao 2009). Used to confirm Indus H1 = 0.739.",inputs:"text_id, max_n (default 6)",outputs:"block_entropies[], normalized values, linguistic classification",defaultParams:'{"text_id": "", "max_n": 6}',needsLM:!1},{id:"char_freq",label:"Character Frequency",group:"Statistical (no LM)",description:"Sign frequency distribution with Zipf exponent fit. Yadav (2010) found Indus follows Zipf-Mandelbrot with α≈1.00; we measured 1.555 from Fuls catalog.",inputs:"text_id",outputs:"frequencies, rank_frequency[], zipf_exponent",defaultParams:'{"text_id": ""}',needsLM:!1},{id:"positional",label:"Positional Analysis",group:"Statistical (no LM)",description:"For each sign: initial_rate, medial_rate, terminal_rate. Identifies dominant positional preferences. Validated against known TMK/INITIAL signs in Fuls catalog.",inputs:"text_id",outputs:"profiles[] per sign with dominant_position",defaultParams:'{"text_id": ""}',needsLM:!1},{id:"nwsp",label:"NWSP — Fuls Method",group:"Statistical (no LM)",description:"Exact implementation of Fuls (2013) Normalized Weighted Sign Position. NWP(p,L) = (p-1)/(L-1)*9+1, weight=L. Classifies signs as ITM/TMK/INITIAL/NUM/CON/MED. Maps to Fuls' ICIT function codes.",inputs:"text_id, min_occurrences (default 4)",outputs:"signs[] with histogram, classification, ICIT code mapping",defaultParams:'{"text_id": "", "min_occurrences": 4}',needsLM:!1},{id:"sign_polyvalence",label:"Sign Polyvalence",group:"Statistical (no LM)",description:"Detects signs with bimodal positional histograms — the hallmark of polyvalent signs serving dual functions. Reproduces Fuls' sign 550 analysis. 74% of Indus signs show bimodal patterns (logo-syllabic expected).",inputs:"text_id, min_freq (default 5)",outputs:"candidates[] sorted by bimodality_score",defaultParams:'{"text_id": "", "min_freq": 5}',needsLM:!1},{id:"sign_cluster",label:"Sign Clustering",group:"Statistical (no LM)",description:"Distributional clustering: groups signs by similar co-occurrence contexts. Signs appearing before/after the same other signs cluster together.",inputs:"text_id, min_freq, top_n",outputs:"clusters[] with member signs",defaultParams:'{"text_id": "", "min_freq": 3, "top_n": 20}',needsLM:!1},{id:"cooccurrence",label:"Co-occurrence Network",group:"Statistical (no LM)",description:"Builds a sign co-occurrence graph and detects communities using the Louvain algorithm. Community structure reveals semantic groupings.",inputs:"text_id, window (default 2), min_freq, min_edge_weight",outputs:"node_count, edge_count, community_count, communities[]",defaultParams:'{"text_id": "", "window": 2, "min_freq": 3, "min_edge_weight": 2}',needsLM:!1},{id:"paradigm",label:"Paradigm Detection",group:"Statistical (no LM)",description:"Finds paradigmatic alternations: same stem, different suffix. High paradigm count indicates rich morphological system. Indus: 102 paradigms vs Ugaritic: 2.",inputs:"text_id, min_stem_freq, min_variants",outputs:"paradigm_count, paradigms[]",defaultParams:'{"text_id": "", "min_stem_freq": 2, "min_variants": 2}',needsLM:!1},{id:"structural_fingerprint",label:"Structural Fingerprint",group:"Statistical (no LM)",description:"10-dimensional fingerprint: H1, H2/H1, Zipf-α, V/N, hapax%, mean positional entropy, polyvalence%, inscription length, boundary-bias variance, paradigmatic rate. GPU-accelerated comparison against database of 9 known writing systems.",inputs:"text_id, compare_to_db (default true)",outputs:"vector[10], dimensions{}, nearest_scripts[], notes[]",defaultParams:'{"text_id": "", "compare_to_db": true}',needsLM:!1},{id:"sign_function_estimator",label:"Sign Function Estimator",group:"Statistical (no LM)",description:"Probabilistic classifier: P(numeral), P(determinative), P(logogram), P(phonetic), P(boundary_marker) per sign. Uses 9 distributional features. Calibration note: undercalibrated for short-inscription corpora.",inputs:"text_id, min_freq (default 3)",outputs:"signs[] with probabilities, system_summary, interpretation",defaultParams:'{"text_id": "", "min_freq": 3}',needsLM:!1},{id:"numerals",label:"Numeral Detection",group:"Statistical (no LM)",description:"Identifies likely numeral signs by positional context and frequency patterns. Numerals appear before commodity signs at consistent positions.",inputs:"text_id",outputs:"numeral_candidates[], numeral_patterns[]",defaultParams:'{"text_id": ""}',needsLM:!1},{id:"word_structure_hypothesis",label:"Word-Structure Typology",group:"Statistical (no LM)",description:"Tests inscription length distribution against 6 language family profiles. No phoneme assumptions. Result: Proto-Dravidian ranks first for Indus (KL=0.444 vs Sumerian 0.742). Validated on Ugaritic, Linear B, Sumerian.",inputs:"text_id",outputs:"ranked_hypotheses[], winner, margin",defaultParams:'{"text_id": ""}',needsLM:!1},{id:"distributional_decipherment",label:"Distributional Decipherment",group:"Statistical (no LM)",description:"Jensen-Shannon divergence clustering and Ventris grid method without language assumptions. Groups signs by vowel class (similar left context) and consonant class (similar right context). GPU-backed N×N cosine similarity matrix.",inputs:"text_id, target_language",outputs:"vowel_clusters[], consonant_clusters[], sign_classification{}",defaultParams:'{"text_id": "", "target_language": "generic"}',needsLM:!1},{id:"logosyllabic",label:"Logosyllabic Analysis (Ventris)",group:"Statistical (no LM)",description:"Full Ventris-style analysis: sign classification (logogram/syllabogram/determinative) + affinity clustering (GPU cosine, complete-linkage) + candidate CV readings + vocabulary matching.",inputs:"text_id, target_language (sumerian|linear_b|generic)",outputs:"sign_classification{}, affinity{}, proposed_readings{}, candidate_words[]",defaultParams:'{"text_id": "", "target_language": "generic"}',needsLM:!1},{id:"kandles",label:"Kandles Fingerprint",group:"Language Model Required",description:"phonetic distribution (US ) phonological colour fingerprint. Maps signs to 8 colour groups by initial sound. Compares grid distributions via cosine similarity. Language-specific bias profiles for Luwian, Hurrian, Semitic, Dravidian.",inputs:"text_id, mode (color_code|grid|compare), profile",outputs:"color_distribution{}, similarity score",defaultParams:'{"text_id": "", "mode": "grid"}',needsLM:!0},{id:"decipher",label:"Decipher (SA + Structural Constraints)",group:"Language Model Required",description:"Simulated-annealing substitution cipher solver with Semitic structural constraints and cognate anchors. Constraints: use_word_bigrams, ocp_weight, root_prior_weight (root co-occurrence prior), positional_weight. anchors: dict of locked cipher→target sign correspondences (e.g. pan-Semitic cognates). Validated: Tier 1b 100%, Tier 2B 66.7%, Tier 1a 6.7% mean (best 20% at 25 restarts). See also: beam_decipher_benchmark for systematic search.",inputs:"text_id, target_text_id, max_iterations, restarts, use_word_bigrams, ocp_weight, root_prior_weight, positional_weight, anchors",outputs:"proposed_mapping{}, kandles_confidence, score",defaultParams:'{"text_id": "", "target_text_id": "", "max_iterations": 12000, "restarts": 8, "use_word_bigrams": false, "ocp_weight": 0.0, "positional_weight": 0.005}',needsLM:!0},{id:"hypothesis",label:"Hypothesis Engine",group:"Language Model Required",description:"Iterative hypothesize-test-score-learn loop over multiple language family hypotheses. Tests Dravidian vs Sanskrit vs Luwian vs Semitic. Includes Kandles bias profiles per language family.",inputs:"text_id, max_iterations",outputs:"results[] with scores per hypothesis, suggested_next[]",defaultParams:'{"text_id": "", "max_iterations": 5000}',needsLM:!0}],Gb={"Statistical (no LM)":"#16a34a","Language Model Required":"#dc2626"};function zk(){const[t,o]=x.useState("all"),[r,l]=x.useState(null),[c,d]=x.useState(Tk),[u,p]=x.useState([]),[g,h]=x.useState(""),[b,y]=x.useState(!1),[v,w]=x.useState(null),[j,_]=x.useState(!1),C=H=>d(G=>G.filter(T=>T.id!==H)),S=async()=>{if(g.trim()){y(!0),w(null);try{const H=await z2(g.trim());w({ok:!0,text:`Imported: ${H.file??g}`}),h(""),E()}catch(H){w({ok:!1,text:H instanceof Error?H.message:String(H)})}finally{y(!1)}}},E=()=>{bb().then(H=>d(H.map(G=>({...G,needsLM:G.needs_lm,defaultParams:JSON.stringify(G.default_params,null,2),custom:!G.registered})))).catch(()=>{})};x.useEffect(()=>{E(),ad().then(p).catch(()=>{})},[]);const k=["all",...Array.from(new Set(c.map(H=>H.group)))],D=t==="all"?c:c.filter(H=>H.group===t);return n.jsxs("div",{children:[n.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"baseline",marginBottom:"0.25rem"},children:[n.jsx("h2",{style:{marginTop:0},children:"Pipelines"}),n.jsx("button",{onClick:()=>{_(H=>!H),w(null)},style:{padding:"5px 12px",border:"1px solid #d1d5db",borderRadius:5,cursor:"pointer",fontSize:12,background:j?"#f3f4f6":"#fff",color:"#374151"},children:j?"× Cancel":"+ Import"})]}),j&&n.jsxs("div",{style:{background:"#f8fafc",border:"1px solid #e5e7eb",borderRadius:8,padding:"12px 16px",marginBottom:"1rem"},children:[n.jsxs("p",{style:{margin:"0 0 8px",fontSize:13,color:"#374151"},children:["Enter the absolute path of a Python file that defines a class inheriting from ",n.jsx("code",{children:"PipelineBase"}),". It will be copied into the pipelines directory."]}),n.jsxs("div",{style:{display:"flex",gap:8},children:[n.jsx("input",{value:g,onChange:H=>h(H.target.value),onKeyDown:H=>{H.key==="Enter"&&S()},placeholder:"C:\\path\\to\\my_pipeline.py",style:{flex:1,padding:"7px 10px",border:"1px solid #d1d5db",borderRadius:5,fontSize:12,outline:"none",fontFamily:"monospace"}}),n.jsx("button",{onClick:()=>void S(),disabled:b||!g.trim(),style:{padding:"7px 16px",border:"none",borderRadius:5,cursor:"pointer",fontSize:12,fontWeight:600,background:"#1e3a5f",color:"#fff"},children:b?"Importing…":"Import"})]}),v&&n.jsx("div",{style:{marginTop:8,fontSize:12,padding:"6px 10px",borderRadius:5,background:v.ok?"#f0fdf4":"#fef2f2",color:v.ok?"#16a34a":"#b91c1c",border:`1px solid ${v.ok?"#86efac":"#fca5a5"}`},children:v.text})]}),n.jsxs("p",{style:{fontSize:13,color:"#6b7280",marginTop:0,marginBottom:"1.25rem"},children:[c.length," registered analysis pipelines. Statistical pipelines require no language model — all results are vocabulary-free and circularity-free. Select a pipeline to launch a job from the Jobs tab."]}),n.jsx("nav",{style:{display:"flex",gap:6,marginBottom:"1.5rem",flexWrap:"wrap"},children:k.map(H=>{const G=Gb[H]??"#1e3a5f";return n.jsx("button",{onClick:()=>o(H),style:{padding:"4px 14px",border:"1px solid",borderRadius:20,cursor:"pointer",fontSize:12,fontWeight:t===H?600:400,background:t===H?G:"#fff",borderColor:t===H?G:"#d1d5db",color:t===H?"#fff":"#374151"},children:H==="all"?`All (${c.length})`:`${H} (${c.filter(T=>T.group===H).length})`},H)})}),n.jsx("div",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fill, minmax(320px, 1fr))",gap:"0.75rem"},children:D.map(H=>n.jsx(Ek,{pipeline:H,expanded:r===H.id,onToggle:()=>l(r===H.id?null:H.id),onDeleted:C,onDuplicated:E,corpora:u},H.id))}),n.jsxs("div",{style:{marginTop:"1.5rem",padding:"12px 16px",background:"#f9fafb",borderRadius:8,fontSize:12,color:"#6b7280"},children:[n.jsx("strong",{style:{color:"#374151"},children:"Scientific note:"}),' All 14 statistical pipelines are safe to run on any corpus without language assumptions. The 3 pipelines marked "Language Model Required" use bigram statistics from a target language — these must use separate training/test corpora to avoid circularity (Fuls 2013; Snyder 2010 protocol).']})]})}function Ek({pipeline:t,expanded:o,onToggle:r,onDeleted:l,onDuplicated:c,corpora:d}){const u=Gb[t.group]??"#6b7280",[p,g]=x.useState(!1),[h,b]=x.useState(!1),[y,v]=x.useState(!1),[w,j]=x.useState(null),[_,C]=x.useState(!1),[S,E]=x.useState(""),[k,D]=x.useState(""),[H,G]=x.useState(""),[T,P]=x.useState(!1),[F,W]=x.useState(null),M=async A=>{var q;if(A.stopPropagation(),!S&&!H.trim()){W({ok:!1,text:"Select a corpus or enter a job name"});return}P(!0),W(null);try{const R={...JSON.parse(t.defaultParams||"{}")};S&&(R.text_id=S),k&&(R.target_text_id=k);const J=await qc({name:H.trim()||`${t.label} — ${((q=d.find(N=>N.id===S))==null?void 0:q.name)??(S||"quick run")}`,pipeline:t.id,params:R});W({ok:!0,text:`Job submitted: ${J.id.slice(0,8)}… — check Jobs panel`}),window.dispatchEvent(new CustomEvent("glossa:running",{detail:{builder:"study",running:!0}}))}catch(R){W({ok:!1,text:R instanceof Error?R.message:"Submit failed"})}finally{P(!1)}},V=async A=>{A.stopPropagation(),g(!0);try{await C2(t.id),c()}catch(q){j(q instanceof Error?q.message:String(q))}finally{g(!1)}},I=async A=>{if(A.stopPropagation(),!y){v(!0);return}b(!0);try{await T2(t.id),l(t.id)}catch(q){j(q instanceof Error?q.message:String(q)),b(!1),v(!1)}};return n.jsxs("div",{style:{border:`1px solid ${o?u:"#e5e7eb"}`,borderRadius:8,overflow:"hidden",transition:"border-color 0.15s"},children:[n.jsxs("div",{style:{padding:"12px 14px",background:o?u+"08":"#fff",cursor:"pointer"},onClick:r,children:[n.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"flex-start",marginBottom:4},children:[n.jsx("code",{style:{fontSize:13,fontWeight:700,color:"#1e3a5f"},children:t.id}),n.jsxs("div",{style:{display:"flex",gap:4,alignItems:"center"},children:[t.custom&&n.jsx("span",{style:{fontSize:9,padding:"1px 5px",borderRadius:6,background:"#f3f4f6",color:"#6b7280",fontWeight:600},children:"custom"}),n.jsx("span",{style:{fontSize:10,padding:"1px 6px",borderRadius:8,background:u+"20",color:u,fontWeight:600,whiteSpace:"nowrap"},children:t.needsLM?"LM":"No LM"}),n.jsx("button",{onClick:V,disabled:p,title:"Duplicate pipeline",style:sy,children:p?"…":"⎘"}),t.custom&&n.jsx("button",{onClick:I,disabled:h,title:y?"Click again to confirm":"Delete pipeline",style:{...sy,background:y?"#fef2f2":void 0,color:y?"#b91c1c":void 0},children:h?"…":y?"Confirm?":"🗑"})]})]}),n.jsx("div",{style:{fontSize:13,fontWeight:600,color:"#111827",marginBottom:4},children:t.label}),n.jsx("p",{style:{margin:0,fontSize:12,color:"#6b7280",lineHeight:1.5},children:o?t.description:t.description.slice(0,100)+(t.description.length>100?"…":"")})]}),w&&n.jsx("div",{style:{padding:"6px 14px",fontSize:12,color:"#b91c1c",background:"#fef2f2"},children:w}),o&&n.jsxs("div",{style:{padding:"0 14px 14px",borderTop:`1px solid ${u}30`,marginTop:8},children:[n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("span",{style:Zs,children:"Inputs:"}),n.jsx("code",{style:Rk,children:t.inputs})]}),n.jsxs("div",{style:{marginBottom:10},children:[n.jsx("span",{style:Zs,children:"Outputs:"}),n.jsx("span",{style:{fontSize:12,color:"#374151"},children:t.outputs})]}),n.jsxs("div",{style:{marginBottom:10},children:[n.jsx("span",{style:Zs,children:"Default params:"}),n.jsx("pre",{style:{background:"#1e293b",color:"#e2e8f0",padding:"6px 10px",borderRadius:4,fontSize:11,fontFamily:"monospace",margin:"4px 0 0",overflowX:"auto"},children:t.defaultParams})]}),t.module&&n.jsxs("div",{style:{fontSize:11,color:"#9ca3af",marginBottom:8},children:["Module: ",n.jsx("code",{children:t.module})]}),n.jsxs("div",{style:{marginTop:10,paddingTop:10,borderTop:`1px solid ${u}20`},children:[n.jsx("button",{onClick:A=>{A.stopPropagation(),C(q=>!q),W(null)},style:{padding:"4px 12px",border:"none",borderRadius:5,cursor:"pointer",background:_?"#f3f4f6":u,color:_?"#374151":"#fff",fontSize:12,fontWeight:600},children:_?"× Cancel":"▶ Quick Run"}),_&&n.jsxs("div",{style:{marginTop:8,display:"flex",flexDirection:"column",gap:6},onClick:A=>A.stopPropagation(),children:[n.jsxs("div",{style:{display:"flex",gap:6,flexWrap:"wrap"},children:[n.jsxs("div",{style:{flex:2,minWidth:160},children:[n.jsx("div",{style:Zs,children:"Corpus (text_id)"}),n.jsxs("select",{value:S,onChange:A=>E(A.target.value),style:{width:"100%",padding:"4px 8px",border:"1px solid #d1d5db",borderRadius:4,fontSize:12},children:[n.jsx("option",{value:"",children:"— select corpus —"}),d.map(A=>n.jsxs("option",{value:A.id,children:[A.name," (",A.corpus_type,", ",A.content.length.toLocaleString()," tokens)"]},A.id))]})]}),t.needsLM&&n.jsxs("div",{style:{flex:2,minWidth:160},children:[n.jsx("div",{style:Zs,children:"Target corpus (target_text_id)"}),n.jsxs("select",{value:k,onChange:A=>D(A.target.value),style:{width:"100%",padding:"4px 8px",border:"1px solid #d1d5db",borderRadius:4,fontSize:12},children:[n.jsx("option",{value:"",children:"— select target LM corpus —"}),d.map(A=>n.jsx("option",{value:A.id,children:A.name},A.id))]})]})]}),n.jsxs("div",{children:[n.jsx("div",{style:Zs,children:"Job name (optional)"}),n.jsx("input",{value:H,onChange:A=>G(A.target.value),placeholder:`${t.label} run…`,style:{width:"100%",padding:"4px 8px",border:"1px solid #d1d5db",borderRadius:4,fontSize:12,boxSizing:"border-box"}})]}),n.jsx("button",{onClick:A=>void M(A),disabled:T||!S&&!H.trim(),style:{alignSelf:"flex-start",padding:"5px 16px",border:"none",borderRadius:5,background:T?"#6b7280":u,color:"#fff",cursor:T?"not-allowed":"pointer",fontSize:12,fontWeight:700},children:T?"⏳ Submitting…":"▶ Submit Job"}),F&&n.jsx("div",{style:{fontSize:11,padding:"4px 8px",borderRadius:4,background:F.ok?"#f0fdf4":"#fef2f2",color:F.ok?"#16a34a":"#b91c1c"},children:F.text})]})]})]})]})}const Zs={fontSize:11,fontWeight:600,color:"#6b7280",display:"block",marginBottom:2,textTransform:"uppercase",letterSpacing:"0.05em"},Rk={fontSize:11,color:"#374151",fontFamily:"monospace"},sy={padding:"2px 7px",border:"1px solid #e5e7eb",borderRadius:4,cursor:"pointer",fontSize:11,fontWeight:600,background:"#fff",color:"#374151"},ry="glossa_email_provider_preset",Hf="onboarding@resend.dev",Ak="onboarding@resend.dev";function Mk(){const{toast:t}=nt(),[o,r]=x.useState(null),[l,c]=x.useState([]),[d,u]=x.useState([]),[p,g]=x.useState(null),[h,b]=x.useState(!0),[y,v]=x.useState(!1),[w,j]=x.useState(""),[_,C]=x.useState(""),[S,E]=x.useState(()=>localStorage.getItem(ry)??"outlook365_oauth"),k=x.useMemo(()=>Bf.find(ae=>ae.id===S)??Bf[0],[S]),[D,H]=x.useState(""),[G,T]=x.useState(587),[P,F]=x.useState(""),[W,M]=x.useState(""),[V,I]=x.useState(""),[A,q]=x.useState(!0),[R,J]=x.useState(""),[N,X]=x.useState(Hf),[Q,L]=x.useState(!0),[B,$]=x.useState(null),[Y,O]=x.useState(!1),[K,ne]=x.useState(""),[se,pe]=x.useState(""),[_e,Se]=x.useState("common"),ke=x.useRef(!1),te=x.useCallback(async()=>{b(!0);try{const[ae,He,Ze,ut,Ut]=await Promise.all([zb(),vj(),jj(20),Eb().catch(()=>null),ld().catch(()=>null)]);r(ae),c(He.recipients),u(Ze.entries),g(ut),H(ae.host||""),T(ae.port||587),I(ae.from||""),q(ae.use_tls??!0),Se(ae.graph_tenant||"common"),Ut&&!ae.graph_client_id_set&&pe(""),X(ae.resend_from||Hf),L(ae.resend_configured!==void 0)}catch(ae){t(ae instanceof Error?ae.message:"Failed to load notifications","error")}finally{b(!1)}},[t]);x.useEffect(()=>{te()},[te]),x.useEffect(()=>{localStorage.setItem(ry,k.id),k.category==="smtp"&&(k.smtp_host!==void 0&&H(k.smtp_host),k.smtp_port!==void 0&&T(k.smtp_port),k.smtp_use_tls!==void 0&&q(k.smtp_use_tls))},[k.id]);const de=async()=>{const ae=w.trim();if(ae){v(!0);try{await Sj({email:ae,label:_.trim(),active:!0}),j(""),C(""),t("Recipient added","success"),await te()}catch(He){t(He instanceof Error?He.message:"Could not add recipient","error")}finally{v(!1)}}},Ce=async ae=>{try{await Qx(ae.id,{active:!ae.active}),await te()}catch(He){t(He instanceof Error?He.message:"Update failed","error")}},ze=async ae=>{const He=window.prompt("Label:",ae.label);if(He!==null)try{await Qx(ae.id,{label:He}),await te()}catch(Ze){t(Ze instanceof Error?Ze.message:"Update failed","error")}},ve=async ae=>{if(window.confirm(`Remove ${ae.email} from notifications?`))try{await wj(ae.id),t("Recipient removed","info"),await te()}catch(He){t(He instanceof Error?He.message:"Delete failed","error")}},De=async()=>{v(!0);try{const ae=await kj();t(`Test sent: ${ae.sent} ok / ${ae.failed} failed`,ae.failed?"warning":"success"),await te()}catch(ae){t(ae instanceof Error?ae.message:"Test failed","error")}finally{v(!1)}},Me=async()=>{const ae=R.trim(),He=N.trim(),Ze=((o==null?void 0:o.resend_from)||"").trim(),ut=He.length>0&&He!==Ze,Ut=!!(o!=null&&o.resend_configured);if(!ae&&!ut){Ut?t("Nothing to save — edit the From address or paste a new key","info"):t("Paste your Resend API key first","warning");return}if(!ae&&!Ut){t("Paste your Resend API key first","warning");return}v(!0);try{const Nt={};ae&&(Nt.resend_api_key=ae),ut&&(Nt.resend_from=He);const yn=await sr(Nt),ft=Object.keys(Nt).filter(Gt=>!yn.updated.includes(Gt));if(ft.length>0){t(`Backend ignored ${ft.join(", ")} — it's likely running an older build. Restart the backend (setup-os.cmd restart) and try again.`,"error");return}const Et=[];ae&&Et.push("API key updated"),ut&&Et.push(`From set to ${He}`),t(`Resend: ${Et.join(" · ")}`,"success"),J(""),await te()}catch(Nt){t(Nt instanceof Error?Nt.message:"Save failed","error")}finally{v(!1)}},Ve=async()=>{if(window.confirm("Clear the Resend API key? Email will fall back to SMTP/Outlook if configured, otherwise no transport.")){v(!0);try{await sr({resend_api_key:""}),t("Resend API key cleared","info"),await te()}catch(ae){t(ae instanceof Error?ae.message:"Clear failed","error")}finally{v(!1)}}},Le=async()=>{v(!0);try{const ae={smtp_host:D.trim(),smtp_port:String(G||587),smtp_from:V.trim(),smtp_use_tls:A?"1":"0"};P.trim()&&(ae.smtp_username=P.trim()),W&&(ae.smtp_password=W),await sr(ae),t("SMTP settings saved","success"),M(""),await te()}catch(ae){t(ae instanceof Error?ae.message:"Save failed","error")}finally{v(!1)}},Ae=async()=>{v(!0);try{const ae={ms_graph_tenant_id:_e.trim()||"common"};se.trim()&&(ae.ms_graph_client_id=se.trim()),await sr(ae),t("Outlook 365 client config saved","success"),pe(""),await te()}catch(ae){t(ae instanceof Error?ae.message:"Save failed","error")}finally{v(!1)}},Ue=async()=>{ne(""),v(!0);try{const ae=await _j();$(ae),ke.current=!1,Oe(ae)}catch(ae){ne(ae instanceof Error?ae.message:"Could not start device flow"),t("Outlook connect failed — check ms_graph_client_id","error")}finally{v(!1)}},Oe=async ae=>{O(!0);const He=Math.max(2e3,ae.interval*1e3);for(;!ke.current&&(await new Promise(Ze=>setTimeout(Ze,He)),!ke.current);)try{const Ze=await Cj(ae.session_id);if(Ze.status==="success"){t("Outlook 365 connected","success"),$(null),O(!1),await te();return}if(Ze.status==="failed"||Ze.status==="expired"){ne(Ze.error||Ze.status),O(!1);return}}catch(Ze){ne(Ze instanceof Error?Ze.message:"poll failed"),O(!1);return}O(!1)},dt=()=>{ke.current=!0,$(null),O(!1)},it=async()=>{if(window.confirm("Disconnect Outlook 365? You can reconnect anytime.")){v(!0);try{await Tj(),t("Outlook 365 disconnected","info"),await te()}catch(ae){t(ae instanceof Error?ae.message:"Disconnect failed","error")}finally{v(!1)}}},lt=async ae=>{v(!0);try{const He=ae?await Rb():await Ab();g(He),t(ae?`Auto-start ON — fetch + mine + digest will run every ${Math.round(He.interval_seconds/3600)}h`:"Auto-start OFF","info")}catch(He){t(He instanceof Error?He.message:"Toggle failed","error")}finally{v(!1)}},Je=(o==null?void 0:o.configured)??!1,yt=(o==null?void 0:o.recipients_active)??0,Jt=(o==null?void 0:o.recipients_total)??0,rn=k.category==="oauth",zt=k.category==="api";return n.jsxs("section",{style:Lk,children:[n.jsx("h3",{style:Nk,children:"📬 Email & Notifications"}),n.jsx("p",{style:ay,children:"Pick a mail provider, fill in the credentials it needs, then add recipients. Outlook 365 uses Microsoft's modern OAuth (no app password) — recommended for anyone with a Microsoft 365 / school / work account."}),n.jsxs("div",{style:{marginTop:10,padding:"10px 14px",borderRadius:7,border:`1px solid ${Je?"#86efac":"#fcd34d"}`,background:Je?"#f0fdf4":"#fffbeb",display:"flex",alignItems:"center",gap:10,flexWrap:"wrap"},children:[n.jsx("span",{style:{fontSize:16},children:Je?"✅":"⚠️"}),n.jsxs("div",{style:{flex:1,minWidth:220},children:[n.jsx("div",{style:{fontSize:13,fontWeight:600,color:Je?"#15803d":"#92400e"},children:Je?(o==null?void 0:o.transport)==="graph"?"Outlook 365 (Microsoft Graph) configured":(o==null?void 0:o.transport)==="resend"?"Resend (HTTPS API) configured":"SMTP configured":"Email not configured"}),n.jsx("div",{style:{fontSize:11,color:"#6b7280",marginTop:2},children:Je?(o==null?void 0:o.transport)==="graph"?`Tenant ${o==null?void 0:o.graph_tenant} · ${yt}/${Jt} active recipients`:(o==null?void 0:o.transport)==="resend"?`From ${(o==null?void 0:o.resend_from)||"onboarding@resend.dev"} · ${yt}/${Jt} active recipients`:`Host ${o==null?void 0:o.host}:${o==null?void 0:o.port} · From ${(o==null?void 0:o.from)||"(unset)"} · ${yt}/${Jt} active`:"Choose a provider below and complete its setup."})]}),n.jsx("button",{onClick:()=>void De(),disabled:y||!Je||yt===0,title:yt===0?"Add an active recipient first":"Send a deliverability test email",style:{...hc,opacity:y||!Je||yt===0?.5:1,cursor:y||!Je||yt===0?"not-allowed":"pointer"},children:y?"Sending…":"✉ Send Test"}),n.jsx("button",{onClick:()=>void te(),title:"Reload",style:ly,children:"⟳"})]}),n.jsxs("div",{style:{marginTop:14},children:[n.jsx("div",{style:Uf,children:"1 · Mail provider"}),n.jsx("select",{value:S,onChange:ae=>E(ae.target.value),style:{...Jn,fontSize:13},children:Bf.map(ae=>n.jsxs("option",{value:ae.id,children:[ae.label,ae.recommended?" ⭐":""]},ae.id))}),n.jsx("p",{style:{...ay,marginTop:6},children:k.notes})]}),rn&&n.jsxs("div",{style:{marginTop:14,padding:"12px 14px",borderRadius:7,border:"1px solid #c7d2fe",background:"#eef2ff"},children:[n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10,flexWrap:"wrap"},children:[n.jsx("span",{style:{fontSize:16},children:"🪪"}),n.jsxs("div",{style:{flex:1,minWidth:240},children:[n.jsx("div",{style:{fontSize:13,fontWeight:700,color:"#3730a3"},children:"Outlook 365 (Microsoft Graph)"}),n.jsx("div",{style:{fontSize:11,color:"#4338ca",marginTop:2},children:o!=null&&o.graph_configured?`Connected. Tenant: ${o==null?void 0:o.graph_tenant}. Mail.Send delegated.`:o!=null&&o.graph_client_id_set?"Client ID set, but not yet authorised. Click Connect to start.":"Set the Application (client) ID below, then click Connect."})]}),o!=null&&o.graph_configured?n.jsx("button",{onClick:()=>void it(),disabled:y,style:ha,children:"Disconnect"}):n.jsx("button",{onClick:()=>void Ue(),disabled:y||!(o!=null&&o.graph_client_id_set)||Y,title:o!=null&&o.graph_client_id_set?"Start the device-code OAuth flow":"Set the Application (client) ID first",style:{...hc,background:"#4338ca",cursor:y||!(o!=null&&o.graph_client_id_set)?"not-allowed":"pointer",opacity:y||!(o!=null&&o.graph_client_id_set)?.5:1},children:"🔗 Connect Outlook 365"})]}),!(o!=null&&o.graph_configured)&&n.jsxs("div",{style:{marginTop:10,display:"grid",gap:6},children:[n.jsx("input",{value:se,placeholder:o!=null&&o.graph_client_id_set?"●●●●●●●● (paste new Application (client) ID to replace)":"Application (client) ID (Azure AD app registration)",onChange:ae=>pe(ae.target.value),style:Jn}),n.jsx("input",{value:_e,placeholder:'Tenant ID (default "common" works for both work and personal accounts)',onChange:ae=>Se(ae.target.value),style:Jn}),n.jsxs("div",{style:{display:"flex",gap:6,alignItems:"center"},children:[n.jsx("button",{onClick:()=>void Ae(),disabled:y,style:ha,children:"Save client config"}),n.jsx("span",{style:{fontSize:10,color:"#6b7280"},children:"Need help registering an app? entra.microsoft.com → App registrations → New → public client → Mail.Send delegated permission."})]})]}),B&&n.jsxs("div",{style:{marginTop:10,padding:"10px 12px",borderRadius:6,background:"#fff",border:"1px solid #c7d2fe"},children:[n.jsxs("div",{style:{fontSize:12,color:"#374151"},children:["1. Open ",n.jsx("a",{href:B.verification_uri,target:"_blank",rel:"noopener noreferrer",style:{color:"#4338ca"},children:B.verification_uri})]}),n.jsx("div",{style:{fontSize:12,color:"#374151",marginTop:4},children:"2. Paste this code:"}),n.jsx("div",{style:{marginTop:6,fontSize:22,fontWeight:800,fontFamily:"monospace",color:"#4338ca",letterSpacing:2,padding:"6px 10px",border:"2px dashed #c7d2fe",borderRadius:6,display:"inline-block"},children:B.user_code}),n.jsxs("div",{style:{fontSize:11,color:"#6b7280",marginTop:6},children:[Y?"Waiting for approval…":"Polling stopped"," ","· Code expires in ",Math.round(B.expires_in/60)," min.",n.jsx("button",{onClick:dt,style:{...ly,marginLeft:8},children:"Cancel"})]})]}),K&&n.jsxs("div",{style:{marginTop:8,fontSize:11,color:"#b91c1c"},children:["⚠ ",K]})]}),zt&&n.jsxs("div",{style:{marginTop:14,padding:"12px 14px",borderRadius:7,border:"1px solid #bbf7d0",background:"#f0fdf4"},children:[n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10,flexWrap:"wrap"},children:[n.jsx("span",{style:{fontSize:16},children:"⚡"}),n.jsxs("div",{style:{flex:1,minWidth:240},children:[n.jsx("div",{style:{fontSize:13,fontWeight:700,color:"#15803d"},children:"Resend (HTTPS API)"}),n.jsx("div",{style:{fontSize:11,color:"#166534",marginTop:2},children:o!=null&&o.resend_configured?`Connected. Sends from ${(o==null?void 0:o.resend_from)||Hf}.`:"Paste your Resend API key (starts with re_). No SMTP, no mailbox, no domain needed."})]}),(o==null?void 0:o.resend_configured)&&n.jsx("button",{onClick:()=>void Ve(),disabled:y,style:{...ha,color:"#15803d",borderColor:"#bbf7d0"},children:"Clear key"})]}),!Q&&n.jsxs("div",{style:{marginTop:10,padding:"8px 12px",borderRadius:6,border:"1px solid #fcd34d",background:"#fffbeb",fontSize:11,color:"#92400e"},children:["⚠ The running backend doesn’t expose Resend yet — saving the key here will be silently ignored. Restart the backend (",n.jsx("code",{children:"setup-os.cmd restart"}),") so the new transport loads, then come back to this screen."]}),Q&&(o==null?void 0:o.resend_configured)&&(o==null?void 0:o.transport)!=="resend"&&n.jsxs("div",{style:{marginTop:10,padding:"8px 12px",borderRadius:6,border:"1px solid #fcd34d",background:"#fffbeb",fontSize:11,color:"#92400e"},children:["⚠ Resend is configured but the active transport is",n.jsxs("b",{children:[" ",o==null?void 0:o.transport]}),". Microsoft Graph (Outlook OAuth) outranks Resend; if you don’t want that, click",n.jsx("b",{children:" Disconnect Outlook 365"})," above. Plain SMTP cannot outrank Resend, so if you see ",n.jsx("i",{children:"smtp"})," here despite Resend being configured, the backend hasn’t reloaded yet — restart it."]}),(()=>{var Ze;return(((Ze=N.match(/<([^>]+)>/))==null?void 0:Ze[1])??N).trim().toLowerCase()===Ak&&n.jsxs("div",{style:{marginTop:10,padding:"8px 12px",borderRadius:6,border:"1px solid #fde68a",background:"#fffbeb",fontSize:11,color:"#92400e"},children:["ℹ You’re using Resend’s free shared sender (",n.jsx("code",{children:"onboarding@resend.dev"}),"). Resend will only deliver to the email you signed up to Resend with. Recipients other than that one address get a 403. Verify your own domain at"," ",n.jsx("a",{href:"https://resend.com/domains",target:"_blank",rel:"noopener noreferrer",style:{color:"#92400e",textDecoration:"underline"},children:"resend.com/domains"})," ","and switch From to ",n.jsx("code",{children:"noreply@"}),"to send to anyone."]})})(),n.jsxs("div",{style:{display:"grid",gap:8,marginTop:10},children:[n.jsxs("label",{style:{fontSize:11,fontWeight:600,color:"#166534",display:"flex",flexDirection:"column",gap:4},children:["API key",n.jsx("input",{value:R,onChange:ae=>J(ae.target.value),placeholder:o!=null&&o.resend_configured?"●●●●●●●● (leave blank to keep current key)":"Resend API key (re_xxx…)",type:"password",autoComplete:"off",style:Jn})]}),n.jsxs("label",{style:{fontSize:11,fontWeight:600,color:"#166534",display:"flex",flexDirection:"column",gap:4},children:["From address (always editable)",n.jsx("input",{value:N,onChange:ae=>X(ae.target.value),placeholder:'"noreply@yourdomain.com" or "Glossa Lab " once a domain is verified at resend.com/domains.',style:Jn}),n.jsxs("span",{style:{fontSize:10,fontWeight:400,color:"#6b7280"},children:["Currently saved: ",n.jsx("code",{children:(o==null?void 0:o.resend_from)||"(unset)"})]})]}),(()=>{const ae=R.trim(),He=N.trim(),Ze=((o==null?void 0:o.resend_from)||"").trim(),ut=He.length>0&&He!==Ze,Ut=!!ae||!!(o!=null&&o.resend_configured)&&ut,Nt=y?"Saving…":o!=null&&o.resend_configured?ae&&ut?"Save key + From":ae?"Replace key":ut?"Save From address":"Save Resend settings":"Save Resend key";return n.jsxs("div",{style:{display:"flex",gap:6,flexWrap:"wrap"},children:[n.jsx("button",{onClick:()=>void Me(),disabled:y||!Ut,style:{...hc,opacity:y||!Ut?.5:1,cursor:y||!Ut?"not-allowed":"pointer"},children:Nt}),n.jsx("button",{onClick:()=>void De(),disabled:y||!Je||yt===0,style:{...ha,cursor:y||!Je||yt===0?"not-allowed":"pointer",opacity:y||!Je||yt===0?.5:1},children:"✉ Send test"}),n.jsx("a",{href:"https://resend.com/api-keys",target:"_blank",rel:"noopener noreferrer",style:{marginLeft:"auto",fontSize:11,color:"#15803d",alignSelf:"center"},children:"Get an API key →"})]})})()]})]}),!rn&&!zt&&n.jsxs("div",{style:{marginTop:14,padding:"12px 14px",borderRadius:7,border:"1px solid #e5e7eb",background:"#fafafa"},children:[n.jsx("div",{style:{...Uf,color:"#374151",margin:"0 0 8px"},children:"2 · SMTP credentials"}),n.jsxs("div",{style:{display:"grid",gridTemplateColumns:"2fr 1fr",gap:8},children:[n.jsx("input",{value:D,placeholder:"SMTP host (e.g. smtp.gmail.com)",onChange:ae=>H(ae.target.value),style:Jn}),n.jsx("input",{value:G||"",type:"number",placeholder:"Port (587)",onChange:ae=>T(parseInt(ae.target.value||"0",10)||587),style:Jn})]}),n.jsxs("div",{style:{display:"grid",gridTemplateColumns:"1fr 1fr",gap:8,marginTop:8},children:[n.jsx("input",{value:P,placeholder:"Username (usually your full email address)",onChange:ae=>F(ae.target.value),style:Jn,autoComplete:"off"}),n.jsx("input",{value:W,type:"password",placeholder:o!=null&&o.password_set?"●●●●●●●● (paste new app password)":"App password / SMTP password",onChange:ae=>M(ae.target.value),style:Jn,autoComplete:"off"})]}),n.jsx("input",{value:V,placeholder:'From address (e.g. "Glossa Lab " or just an email)',onChange:ae=>I(ae.target.value),style:{...Jn,marginTop:8}}),n.jsxs("label",{style:{display:"flex",alignItems:"center",gap:6,marginTop:8,fontSize:12,color:"#374151"},children:[n.jsx("input",{type:"checkbox",checked:A,onChange:ae=>q(ae.target.checked)}),"Use STARTTLS (recommended)"]}),n.jsxs("div",{style:{display:"flex",gap:6,marginTop:10,flexWrap:"wrap"},children:[n.jsx("button",{onClick:()=>void Le(),disabled:y,style:hc,children:y?"Saving…":"Save SMTP settings"}),n.jsx("button",{onClick:()=>void De(),disabled:y||!Je||yt===0,style:{...ha,cursor:y||!Je||yt===0?"not-allowed":"pointer",opacity:y||!Je||yt===0?.5:1},children:"✉ Send test"})]})]}),n.jsxs("div",{style:{marginTop:14,padding:"12px 14px",borderRadius:7,border:`1px solid ${p!=null&&p.running?"#86efac":"#e5e7eb"}`,background:p!=null&&p.running?"#f0fdf4":"#fafafa",display:"flex",alignItems:"center",gap:10,flexWrap:"wrap"},children:[n.jsx("span",{style:{fontSize:16},children:p!=null&&p.running?"⏱️":"💤"}),n.jsxs("div",{style:{flex:1,minWidth:240},children:[n.jsxs("div",{style:{fontSize:13,fontWeight:600,color:p!=null&&p.running?"#15803d":"#374151"},children:["Auto-start discovery ",p!=null&&p.running?"— RUNNING":"— OFF"]}),n.jsx("div",{style:{fontSize:11,color:"#6b7280",marginTop:2},children:p?`Fetch + mine + digest every ${Math.round(p.interval_seconds/3600)}h. ${p.enabled?"Persisted; resumes on next backend boot.":"Not persisted."}`:"Loading scheduler status…"})]}),n.jsx("div",{onClick:()=>!y&&void lt(!(p!=null&&p.running)),title:p!=null&&p.running?"Stop scheduler + persist OFF":"Start scheduler + persist ON",style:{width:44,height:24,borderRadius:12,cursor:y?"not-allowed":"pointer",flexShrink:0,position:"relative",background:p!=null&&p.running?"#22c55e":"#d1d5db",opacity:y?.5:1,transition:"background 0.2s"},children:n.jsx("div",{style:{position:"absolute",top:3,left:p!=null&&p.running?23:3,width:18,height:18,borderRadius:"50%",background:"#fff",boxShadow:"0 1px 3px rgba(0,0,0,0.25)",transition:"left 0.2s"}})})]}),n.jsxs("div",{style:{marginTop:14},children:[n.jsxs("div",{style:Uf,children:["3 · Recipients (",l.length,")"]}),h?n.jsx("div",{style:{fontSize:12,color:"#6b7280"},children:"Loading…"}):l.length===0?n.jsx("div",{style:{fontSize:12,color:"#9ca3af",fontStyle:"italic"},children:"No recipients yet. Add at least one address below to start receiving emails."}):n.jsx("div",{style:{border:"1px solid #e5e7eb",borderRadius:6,overflow:"hidden"},children:l.map(ae=>n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,padding:"7px 12px",borderBottom:"1px solid #f1f5f9",background:ae.active?"#fff":"#fafafa"},children:[n.jsx("span",{title:ae.active?"Active":"Paused",style:{width:8,height:8,borderRadius:"50%",background:ae.active?"#22c55e":"#cbd5e1",flexShrink:0}}),n.jsxs("div",{style:{flex:1,minWidth:0},children:[n.jsx("div",{style:{fontSize:13,fontWeight:500,color:"#111827",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:ae.email}),ae.label&&n.jsx("div",{style:{fontSize:11,color:"#6b7280",marginTop:1},children:ae.label})]}),n.jsx("button",{onClick:()=>void Ce(ae),title:ae.active?"Pause notifications":"Resume notifications",style:Wf(ae.active?"#f59e0b":"#22c55e"),children:ae.active?"⏸":"▶"}),n.jsx("button",{onClick:()=>void ze(ae),title:"Edit label",style:Wf("#6b7280"),children:"✎"}),n.jsx("button",{onClick:()=>void ve(ae),title:"Remove",style:Wf("#dc2626"),children:"🗑"})]},ae.id))}),n.jsxs("div",{style:{display:"flex",gap:6,marginTop:8,flexWrap:"wrap"},children:[n.jsx("input",{value:w,onChange:ae=>j(ae.target.value),onKeyDown:ae=>{ae.key==="Enter"&&w.trim()&&de()},placeholder:"recipient@example.com",style:{...Jn,flex:2,minWidth:200}}),n.jsx("input",{value:_,onChange:ae=>C(ae.target.value),onKeyDown:ae=>{ae.key==="Enter"&&w.trim()&&de()},placeholder:"Label (optional, e.g. PI, lab)",style:{...Jn,flex:1,minWidth:140}}),n.jsx("button",{onClick:()=>void de(),disabled:y||!w.trim(),style:{...Bk,cursor:y||!w.trim()?"not-allowed":"pointer",opacity:y||!w.trim()?.5:1},children:"+ Add"})]})]}),n.jsxs("details",{style:{marginTop:16},children:[n.jsxs("summary",{style:{cursor:"pointer",fontWeight:600,fontSize:13,color:"#374151"},children:["📜 Recent send log (",d.length,")"]}),n.jsx("div",{style:{marginTop:8,maxHeight:220,overflowY:"auto",border:"1px solid #e5e7eb",borderRadius:6},children:d.length===0?n.jsx("div",{style:{fontSize:12,color:"#9ca3af",padding:"10px 14px",fontStyle:"italic"},children:"No emails sent yet."}):d.map(ae=>{const He=ae.status==="sent"?"#22c55e":ae.status==="failed"?"#dc2626":"#9ca3af";return n.jsxs("div",{style:{display:"flex",gap:8,padding:"6px 12px",borderBottom:"1px solid #f1f5f9",alignItems:"center"},children:[n.jsx("span",{style:{fontSize:9,fontWeight:700,color:He,background:He+"20",padding:"1px 6px",borderRadius:4,textTransform:"uppercase",flexShrink:0},children:ae.status}),n.jsxs("div",{style:{flex:1,minWidth:0},children:[n.jsx("div",{style:{fontSize:12,color:"#111827",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:ae.subject}),n.jsxs("div",{style:{fontSize:10,color:"#6b7280",marginTop:1},children:["to ",ae.recipient," · ",ae.kind," · ",Dk(ae.sent_at),ae.item_count>0&&` · ${ae.item_count} items`]}),ae.error&&n.jsx("div",{style:{fontSize:10,color:"#dc2626",marginTop:1},children:ae.error})]})]},ae.id)})})]})]})}function Wf(t){return{border:"1px solid "+t+"40",borderRadius:4,background:"none",color:t,cursor:"pointer",fontSize:11,padding:"2px 7px"}}function Dk(t){if(!t)return"";const o=new Date(t);return Number.isNaN(o.getTime())?t:o.toLocaleString()}const Lk={marginBottom:"2rem",padding:"1.25rem",border:"1px solid #e5e7eb",borderRadius:8},Nk={margin:"0 0 0.5rem 0",fontSize:15,fontWeight:600,color:"#111827"},ay={margin:0,fontSize:12,color:"#6b7280",lineHeight:1.5},Uf={fontSize:11,fontWeight:700,color:"#7c3aed",textTransform:"uppercase",letterSpacing:.5,marginBottom:6},Jn={padding:"6px 10px",border:"1px solid #d1d5db",borderRadius:5,fontSize:13,width:"100%",boxSizing:"border-box",outline:"none"},hc={padding:"5px 12px",border:"1px solid #2563eb",borderRadius:6,background:"#2563eb",color:"#fff",fontSize:12,fontWeight:600,cursor:"pointer"},Bk={padding:"6px 16px",border:"none",borderRadius:5,background:"#7c3aed",color:"#fff",fontSize:12,fontWeight:600,cursor:"pointer"},ly={padding:"5px 9px",border:"1px solid #d1d5db",borderRadius:5,background:"#fff",cursor:"pointer",fontSize:12},ha={padding:"5px 12px",border:"1px solid #c7d2fe",borderRadius:6,background:"#fff",color:"#4338ca",fontSize:12,fontWeight:600,cursor:"pointer"},Ok=[{id:"news_api_key",label:"NewsAPI",href:"https://newsapi.org/account",hint:"Global news articles. Free tier: 100 req/day."},{id:"serp_api_key",label:"SerpAPI",href:"https://serpapi.com/manage-api-key",hint:"Google search results. Free tier: 100 searches/month."},{id:"brave_search_api_key",label:"Brave Search",href:"https://api-dashboard.search.brave.com/",hint:"Web search. Free tier: 2,000 queries/month."},{id:"uspto_api_key",label:"USPTO (ODP)",href:"https://developer.uspto.gov/",hint:"US patent search via the Open Data Portal. Free key."}],Ik=[{id:"semantic_scholar_api_key",label:"Semantic Scholar",href:"https://www.semanticscholar.org/product/api#api-key-form",hint:"Removes the 100 req/5 min cap. Strongly recommended."},{id:"openalex_email",label:"OpenAlex (email)",href:"https://docs.openalex.org/how-to-use-the-api/rate-limits-and-authentication",hint:"Enter your email for priority access. Not a key — just an email."}];function $k(){const{toast:t}=nt(),[o,r]=x.useState(null),[l,c]=x.useState([]),[d,u]=x.useState([]),[p,g]=x.useState(null),[h,b]=x.useState(null),[y,v]=x.useState({}),[w,j]=x.useState({}),[_,C]=x.useState(!1),[S,E]=x.useState(!1),[k,D]=x.useState(!1),H=x.useCallback(async()=>{try{const[I,A,q,R,J]=await Promise.all([ld(),Tb(),Cb(),Eb().catch(()=>null),zb().catch(()=>null)]);r(I),c(A.sources),u(q.topics),g(R),b(J)}catch(I){t(I instanceof Error?I.message:"Failed to load discovery state","error")}},[t]);x.useEffect(()=>{H()},[H]);const G=async I=>{const A=(y[I]??"").trim();if(!A){t("Paste a value first","warning");return}C(!0);try{await sr({[I]:A}),v(q=>({...q,[I]:""})),t(`${I} saved`,"success"),await H()}catch(q){t(q instanceof Error?q.message:"Save failed","error")}finally{C(!1)}},T=async I=>{j(A=>({...A,[I]:"loading"}));try{const A=await b2(I);j(q=>({...q,[I]:A}))}catch(A){j(q=>({...q,[I]:{valid:!1,provider:I,message:A instanceof Error?A.message:"verify failed"}}))}},P=async I=>{C(!0);try{const A=I?await Rb():await Ab();g(A),t(I?`Auto-start ON · every ${Math.round(A.interval_seconds/3600)}h`:"Auto-start OFF","info")}catch(A){t(A instanceof Error?A.message:"Toggle failed","error")}finally{C(!1)}},F=async()=>{E(!0);try{const I=await Fc({});t(`Fetch started · job ${I.job_id.slice(0,8)}`,"info")}catch(I){t(I instanceof Error?I.message:"Fetch failed to start","error")}finally{E(!1)}},W=async()=>{D(!0);try{const I=await $p({limit:50});t(`Mine started · job ${I.job_id.slice(0,8)} · limit 50`,"info")}catch(I){t(I instanceof Error?I.message:"Mine failed to start","error")}finally{D(!1)}},M=l.filter(I=>I.configured).length,V=l.length;return n.jsxs("section",{style:Hk,children:[n.jsx("h3",{style:Wk,children:"🔭 Auto Discovery"}),n.jsx("p",{style:ga,children:"The continuous-discovery loop fetches new findings from external sources, classifies + de-duplicates them via your AI provider, and surfaces them in the Discovery view + Dashboard. Configure the sources, toggle the schedule, and trigger manual runs from this panel."}),n.jsxs("div",{style:{marginTop:10,padding:"10px 14px",borderRadius:7,border:`1px solid ${p!=null&&p.running?"#86efac":"#fcd34d"}`,background:p!=null&&p.running?"#f0fdf4":"#fffbeb",display:"flex",alignItems:"center",gap:10,flexWrap:"wrap"},children:[n.jsx("span",{style:{fontSize:16},children:p!=null&&p.running?"⏱️":"💤"}),n.jsxs("div",{style:{flex:1,minWidth:220},children:[n.jsx("div",{style:{fontSize:13,fontWeight:600,color:p!=null&&p.running?"#15803d":"#92400e"},children:p!=null&&p.running?"Auto-discovery running":"Auto-discovery off"}),n.jsxs("div",{style:{fontSize:11,color:"#6b7280",marginTop:2},children:[M,"/",V," sources configured",p?` · interval ${Math.round(p.interval_seconds/3600)}h`:"",p!=null&&p.enabled?" · persisted":p?" · not persisted":"",d.length>0?` · ${d.length} topic(s)`:""]})]}),n.jsx("div",{onClick:()=>!_&&void P(!(p!=null&&p.running)),title:p!=null&&p.running?"Stop scheduler":"Start scheduler + persist",style:{width:44,height:24,borderRadius:12,cursor:_?"not-allowed":"pointer",flexShrink:0,position:"relative",background:p!=null&&p.running?"#22c55e":"#d1d5db",opacity:_?.5:1,transition:"background 0.2s"},children:n.jsx("div",{style:{position:"absolute",top:3,left:p!=null&&p.running?23:3,width:18,height:18,borderRadius:"50%",background:"#fff",boxShadow:"0 1px 3px rgba(0,0,0,0.25)",transition:"left 0.2s"}})})]}),n.jsxs("div",{style:{marginTop:14},children:[n.jsx("div",{style:gc,children:"1 · Manual run"}),n.jsx("p",{style:{...ga,marginTop:4},children:"Trigger a fetch (pulls new items from every configured source for every topic) and/or a mine (LLM-classifies un-mined items in the queue). Both run as background jobs you can watch in the Jobs panel."}),n.jsxs("div",{style:{display:"flex",gap:8,flexWrap:"wrap"},children:[n.jsx("button",{onClick:()=>void F(),disabled:S,style:{...Gk,opacity:S?.5:1,cursor:S?"not-allowed":"pointer"},children:S?"⏳ Fetching…":"▶ Fetch now"}),n.jsx("button",{onClick:()=>void W(),disabled:k,style:{...Pk,opacity:k?.5:1,cursor:k?"not-allowed":"pointer"},children:k?"⏳ Mining…":"✨ Mine now (50)"}),n.jsx("span",{style:{flex:1}}),n.jsx("a",{href:"#",onClick:I=>{I.preventDefault(),window.dispatchEvent(new CustomEvent("glossa:navigate",{detail:{view:"discovery"}}))},style:{alignSelf:"center",fontSize:11,color:"#2563eb",textDecoration:"underline"},children:"Open Discovery view →"})]}),n.jsxs("p",{style:{...ga,marginTop:8,fontSize:11},children:["Or from a shell: ",n.jsx("code",{children:"python -m glossa_lab.discovery fetch"})," / ",n.jsx("code",{children:"mine --limit 50"})," / ",n.jsx("code",{children:"daily --notify"})]})]}),n.jsxs("div",{style:{marginTop:14},children:[n.jsx("div",{style:gc,children:"2 · API keys"}),n.jsx("p",{style:{...ga,marginTop:4},children:"Sources that need a key are listed below. Keyless sources (arXiv, Crossref, OpenAlex, PubMed, Europe PMC, DOAJ, GDELT, PPUBS, RSS, Academia) are always on."}),n.jsx("div",{style:{marginTop:10,marginBottom:4},children:n.jsx("span",{style:dy,children:"🔑 Required — source won’t fetch without these"})}),n.jsx("div",{style:{display:"grid",gap:8},children:Ok.map(I=>n.jsx(cy,{k:I,settings:o,pendingKeys:y,setPendingKeys:v,verify:w,onSaveKey:G,onVerifyKey:T,busy:_},I.id))}),n.jsx("div",{style:{marginTop:14,marginBottom:4},children:n.jsx("span",{style:dy,children:"⚡ Optional upgrades — source works without, key removes rate limits"})}),n.jsx("div",{style:{display:"grid",gap:8},children:Ik.map(I=>n.jsx(cy,{k:I,settings:o,pendingKeys:y,setPendingKeys:v,verify:w,onSaveKey:G,onVerifyKey:T,busy:_},I.id))})]}),n.jsxs("div",{style:{marginTop:14},children:[n.jsx("div",{style:gc,children:"3 · Email digest on run"}),n.jsx("p",{style:{...ga,marginTop:4},children:"When notifications are configured (any active recipient + a working transport), every scheduled fetch+mine cycle sends a digest of new findings."}),n.jsxs("div",{style:{padding:10,borderRadius:7,border:`1px solid ${h!=null&&h.configured?"#86efac":"#fcd34d"}`,background:h!=null&&h.configured?"#f0fdf4":"#fffbeb",display:"flex",alignItems:"center",gap:10,flexWrap:"wrap"},children:[n.jsx("span",{style:{fontSize:14},children:h!=null&&h.configured?"✉":"⚠"}),n.jsxs("div",{style:{flex:1,minWidth:220},children:[n.jsx("div",{style:{fontSize:12,fontWeight:600,color:h!=null&&h.configured?"#15803d":"#92400e"},children:h!=null&&h.configured?`Transport: ${h==null?void 0:h.transport} · ${h==null?void 0:h.recipients_active}/${h==null?void 0:h.recipients_total} active recipient(s)`:"Email transport not configured"}),n.jsx("div",{style:{fontSize:10,color:"#6b7280",marginTop:2},children:h!=null&&h.configured?"Manage recipients + send a test in the Email & Notifications section below.":"Configure Resend, Outlook 365 OAuth, or SMTP in the Email & Notifications section below."})]})]})]}),n.jsxs("div",{style:{marginTop:14},children:[n.jsx("div",{style:gc,children:"4 · Sources detected by the backend"}),n.jsx("div",{style:{display:"flex",gap:6,flexWrap:"wrap",marginTop:6},children:l.map(I=>{const A=I,q=A.rate_limit,R=q==null?void 0:q.rate_limited,J=Number((q==null?void 0:q.errors_429)??0),N=Number((q==null?void 0:q.requests)??0),X=A.upgrade_hint,Q=A.upgrade_url,L=R?"#fef2f2":I.configured?"#f0fdf4":"#fafafa",B=R?"#fca5a5":I.configured?"#86efac":"#e5e7eb",$=R?"#b91c1c":I.configured?"#15803d":"#9ca3af";return n.jsxs("span",{title:R?`⚠ Rate limited (${J}/${N} requests returned 429)${X?`. ${X}`:""}`:N>0?`${N} requests, ${J} rate-limited`:I.disabled_reason||`${I.source} ready`,style:{padding:"3px 9px",borderRadius:12,border:"1px solid",background:L,borderColor:B,color:$,fontSize:11,fontWeight:500,cursor:Q?"pointer":"default"},onClick:()=>Q&&window.open(Q,"_blank"),children:[R?"⚠ ":I.configured?"✓ ":"✗ ",I.source,N>0&&n.jsxs("span",{style:{fontSize:9,marginLeft:4,opacity:.7},children:[N,"req",J>0?` · ${J}×429`:""]})]},I.source)})})]})]})}function cy({k:t,settings:o,pendingKeys:r,setPendingKeys:l,verify:c,onSaveKey:d,onVerifyKey:u,busy:p}){var y,v,w,j,_;const g=((y=o==null?void 0:o.keys[t.id])==null?void 0:y.set)??!1,h=((v=o==null?void 0:o.keys[t.id])==null?void 0:v.source)??null,b=c[t.id];return n.jsxs("div",{style:{padding:"8px 10px",border:"1px solid #e5e7eb",borderRadius:7,background:"#fff",display:"flex",flexDirection:"column",gap:5},children:[n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,flexWrap:"wrap"},children:[n.jsx("span",{style:{fontSize:13,fontWeight:600,color:"#111827"},children:t.label}),g?n.jsxs("span",{style:{fontSize:10,padding:"1px 7px",borderRadius:9,background:"#dcfce7",color:"#15803d",fontWeight:700},children:["SET (",h,")"]}):n.jsx("span",{style:{fontSize:10,padding:"1px 7px",borderRadius:9,background:"#fee2e2",color:"#b91c1c",fontWeight:700},children:"MISSING"}),t.hint&&n.jsxs("span",{style:{fontSize:10,color:"#6b7280"},children:["— ",t.hint]}),n.jsx("a",{href:t.href,target:"_blank",rel:"noopener noreferrer",style:{fontSize:11,color:"#2563eb",marginLeft:"auto"},children:"Get key →"})]}),n.jsxs("div",{style:{display:"flex",gap:6},children:[n.jsx("input",{value:r[t.id]??"",onChange:C=>l(S=>({...S,[t.id]:C.target.value})),placeholder:g?"●●●●●●●● (paste new value)":`Paste ${t.label} key`,type:"password",autoComplete:"off",style:Uk}),n.jsx("button",{onClick:()=>void d(t.id),disabled:p||!((w=r[t.id])!=null&&w.trim()),style:{...Fk,opacity:p||!((j=r[t.id])!=null&&j.trim())?.5:1,cursor:p||!((_=r[t.id])!=null&&_.trim())?"not-allowed":"pointer"},children:"Save"}),n.jsx("button",{onClick:()=>void u(t.id),disabled:!g||b==="loading",style:{...qk,opacity:!g||b==="loading"?.5:1,cursor:!g||b==="loading"?"not-allowed":"pointer"},children:b==="loading"?"…":"Verify"})]}),b&&b!=="loading"&&n.jsxs("div",{style:{fontSize:11,color:b.valid?"#15803d":"#b91c1c"},children:[b.valid?"✓":"✗"," ",b.message]})]})}const Hk={marginBottom:"2rem",padding:"1.25rem",border:"1px solid #e5e7eb",borderRadius:8},Wk={margin:"0 0 0.5rem 0",fontSize:15,fontWeight:600,color:"#111827"},ga={margin:0,fontSize:12,color:"#6b7280",lineHeight:1.5},gc={fontSize:11,fontWeight:700,color:"#7c3aed",textTransform:"uppercase",letterSpacing:.5,marginBottom:6},dy={fontSize:11,fontWeight:600,color:"#374151"},Uk={flex:1,padding:"6px 10px",border:"1px solid #d1d5db",borderRadius:5,fontSize:13,boxSizing:"border-box",outline:"none"},Gk={padding:"6px 14px",border:"1px solid #2563eb",borderRadius:6,background:"#2563eb",color:"#fff",fontSize:12,fontWeight:600,cursor:"pointer"},Pk={padding:"6px 14px",border:"1px solid #7c3aed",borderRadius:6,background:"#7c3aed",color:"#fff",fontSize:12,fontWeight:600,cursor:"pointer"},qk={padding:"5px 10px",border:"1px solid #d1d5db",borderRadius:5,background:"#fff",cursor:"pointer",fontSize:12},Fk={padding:"5px 12px",border:"1px solid #c7d2fe",borderRadius:6,background:"#fff",color:"#4338ca",fontSize:12,fontWeight:600,cursor:"pointer"},Yk={cloud:"☁️",ollama:"🦙",byoe:"🔌",huggingface:"🤗"},uy={reachable:"#16a34a",unreachable:"#dc2626",untested:"#9ca3af"};function Vk(){const{toast:t}=nt(),[o,r]=x.useState([]),[l,c]=x.useState([]),[d,u]=x.useState(!0),[p,g]=x.useState({}),[h,b]=x.useState(!1),[y,v]=x.useState(null),[w,j]=x.useState({}),[_,C]=x.useState({}),[S,E]=x.useState("cloud"),[k,D]=x.useState(""),[H,G]=x.useState(""),[T,P]=x.useState(""),[F,W]=x.useState(""),[M,V]=x.useState(!1),I=async()=>{u(!0);try{const B=await Lb();r(B.providers)}catch{}finally{u(!1)}};x.useEffect(()=>{I(),Oj().then(B=>c(B.providers)).catch(()=>{})},[]);const A=async B=>{var Y;const $=((Y=o.find(O=>O.id===B))==null?void 0:Y.name)??"provider";g(O=>({...O,[B]:!0})),t(`Testing '${$}'...`,"info");try{const O=await Nj(B);t(O.message,O.valid?"success":"error"),await I()}catch(O){t(O instanceof Error?O.message:"Test failed","error")}g(O=>({...O,[B]:!1}))},q=async(B,$)=>{if(window.confirm(`Delete provider "${$}"?`))try{await Lj(B),t(`${$} deleted`,"success"),v(null),await I()}catch(Y){t(Y instanceof Error?Y.message:"Delete failed","error")}},R=async(B,$)=>{try{await ty(B,{enabled:$?1:0}),await I()}catch{}},J=async(B,$,Y)=>{if($==="name"&&!Y.trim()){t("Provider name cannot be empty","error");return}C(O=>({...O,[`${B}_${$}`]:!0}));try{await ty(B,{[$]:Y}),t(`${$} updated`,"success"),j(O=>{const K={...O};return delete K[`${B}_${$}`],K}),await I()}catch(O){t(O instanceof Error?O.message:"Save failed","error")}C(O=>({...O,[`${B}_${$}`]:!1}))},N=async()=>{if(!H.trim()){t("Name is required","error");return}V(!0);try{const B=l.find($=>$.id===k);await Dj({name:H,provider_type:S,provider_id:S==="cloud"?k:S,base_url:T||((B==null?void 0:B.base_url)??""),api_key:F}),t(`${H} added`,"success"),b(!1),G(""),P(""),W(""),D(""),await I()}catch(B){t(B instanceof Error?B.message:"Add failed","error")}V(!1)},X=async()=>{t("Scanning for Ollama...","info");try{const B=await Bj();if(B.detected.length===0){t("No Ollama instances found","error");return}const $=B.detected[0];E("ollama"),G("Ollama"),P($.url),b(!0),t(`Found Ollama at ${$.url} with ${$.models.length} model(s)`,"success")}catch{t("Detection failed","error")}},Q=(B,$,Y,O="text",K="")=>{const ne=`${B.id}_${$}`,se=ne in w,pe=w[ne]??"",_e=_[ne],Se=$==="api_key"?"":B[$]||"",ke=se?pe:$==="api_key"?"":Se,te=$==="name"&&se&&!pe.trim();return n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("label",{style:{fontSize:10,fontWeight:600,color:"#6b7280",display:"block",marginBottom:2},children:Y}),n.jsxs("div",{style:{display:"flex",gap:4},children:[n.jsx("input",{type:O,value:ke,onChange:de=>j(Ce=>({...Ce,[ne]:de.target.value})),placeholder:$==="api_key"?B.api_key_set?"•••••••• (paste new to replace)":"Paste API key...":K||Se,style:{flex:1,padding:"4px 8px",fontSize:12,borderRadius:4,border:`1px solid ${te?"#f87171":"#d1d5db"}`,fontFamily:O==="password"?"monospace":void 0}}),se&&n.jsx("button",{onClick:()=>J(B.id,$,pe),disabled:_e||te,style:{padding:"4px 10px",fontSize:11,border:"none",borderRadius:4,background:te?"#9ca3af":"#2563eb",color:"#fff",cursor:te?"not-allowed":"pointer",fontWeight:600},children:_e?"...":"Save"})]}),te&&n.jsx("div",{style:{fontSize:10,color:"#ef4444",marginTop:2},children:"Name cannot be empty"})]})},L={border:"1px solid #e5e7eb",borderRadius:8,padding:16,marginBottom:16,background:"#fff"};return n.jsxs("section",{style:L,children:[n.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:12},children:[n.jsx("h3",{style:{margin:0,fontSize:15,fontWeight:700},children:"🔗 Provider Registry"}),n.jsxs("div",{style:{display:"flex",gap:6},children:[n.jsx("button",{onClick:X,style:{padding:"4px 10px",fontSize:11,border:"1px solid #d1d5db",borderRadius:4,cursor:"pointer",background:"#fff"},children:"🦙 Detect Ollama"}),n.jsx("button",{onClick:()=>b(!0),style:{padding:"4px 10px",fontSize:11,border:"none",borderRadius:4,cursor:"pointer",background:"#2563eb",color:"#fff",fontWeight:600},children:"+ Add Provider"})]})]}),d&&n.jsx("div",{style:{color:"#9ca3af",fontSize:12},children:"Loading..."}),n.jsxs("div",{style:{display:"grid",gap:8},children:[o.map(B=>{const $=y===B.id;return n.jsxs("div",{style:{border:"1px solid #e5e7eb",borderRadius:6,overflow:"hidden",background:B.enabled?"#f0fdf4":"#fafafa"},children:[n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,padding:"8px 12px",cursor:"pointer"},onClick:()=>v($?null:B.id),children:[n.jsx("span",{style:{fontSize:16},children:Yk[B.provider_type]||"🔗"}),n.jsxs("div",{style:{flex:1,minWidth:0},children:[n.jsxs("div",{style:{display:"flex",gap:6,alignItems:"center"},children:[n.jsx("span",{style:{fontWeight:600,fontSize:13},children:B.name}),n.jsx("span",{style:{fontSize:10,padding:"1px 5px",borderRadius:3,background:`${uy[B.status]||"#9ca3af"}20`,color:uy[B.status]||"#9ca3af",fontWeight:700},children:B.status}),B.api_key_set&&n.jsx("span",{style:{fontSize:9,padding:"1px 4px",borderRadius:3,background:"#dcfce7",color:"#166534"},children:"key set"}),B.available_models.length>0&&n.jsxs("span",{style:{fontSize:10,color:"#6b7280"},children:[B.available_models.length," model(s)"]})]}),n.jsxs("div",{style:{fontSize:11,color:"#6b7280",marginTop:1},children:[(()=>{var K;const Y=B.provider_type==="cloud"?((K=l.find(ne=>ne.id===B.provider_id))==null?void 0:K.label)??B.provider_id:B.provider_id,O=Y&&Y!==B.provider_type;return n.jsxs(n.Fragment,{children:[B.provider_type,O?` · ${Y}`:""]})})(),B.base_url&&n.jsxs("span",{children:[" · ",B.base_url.replace(/https?:\/\//,"").slice(0,40)]})]})]}),n.jsx("input",{type:"checkbox",checked:!!B.enabled,onChange:Y=>{Y.stopPropagation(),R(B.id,Y.target.checked)},style:{width:14,height:14,cursor:"pointer"}}),n.jsx("button",{onClick:Y=>{Y.stopPropagation(),A(B.id)},disabled:p[B.id],style:{padding:"3px 8px",fontSize:10,border:"1px solid #d1d5db",borderRadius:3,cursor:"pointer",background:"#fff"},children:p[B.id]?"...":"Test"}),n.jsx("span",{style:{fontSize:10,color:"#9ca3af",transform:$?"rotate(90deg)":"rotate(0deg)",transition:"transform 0.15s"},children:"▶"})]}),$&&n.jsxs("div",{style:{padding:"8px 12px 12px",borderTop:"1px solid #e5e7eb",background:"#f8fafc"},children:[Q(B,"name","Name","text","Provider name"),Q(B,"base_url","Base URL","text","https://api.openai.com/v1"),Q(B,"api_key","API Key","password","sk-..."),B.available_models.length>0&&n.jsxs("div",{style:{marginBottom:8},children:[n.jsx("label",{style:{fontSize:10,fontWeight:600,color:"#6b7280",display:"block",marginBottom:4},children:"Available Models"}),n.jsxs("div",{style:{display:"flex",flexWrap:"wrap",gap:4},children:[B.available_models.slice(0,20).map(Y=>n.jsx("span",{style:{fontSize:10,padding:"2px 6px",background:"#e0f2fe",color:"#0369a1",borderRadius:3,fontFamily:"monospace"},children:Y},Y)),B.available_models.length>20&&n.jsxs("span",{style:{fontSize:10,color:"#9ca3af"},children:["+",B.available_models.length-20," more"]})]})]}),n.jsxs("div",{style:{display:"flex",gap:6,marginTop:8},children:[n.jsx("button",{onClick:()=>A(B.id),disabled:p[B.id],style:{padding:"4px 12px",fontSize:11,border:"1px solid #d1d5db",borderRadius:4,cursor:"pointer",background:"#fff"},children:p[B.id]?"Testing...":"↻ Refresh Models"}),n.jsx("button",{onClick:()=>q(B.id,B.name),style:{padding:"4px 12px",fontSize:11,border:"1px solid #fca5a5",borderRadius:4,cursor:"pointer",background:"#fef2f2",color:"#dc2626",marginLeft:"auto"},children:"Delete Provider"})]})]})]},B.id)}),!d&&o.length===0&&n.jsx("div",{style:{textAlign:"center",padding:20,color:"#9ca3af",fontSize:12},children:'No providers configured. Click "Add Provider" to get started.'})]}),h&&n.jsx("div",{style:{position:"fixed",inset:0,background:"rgba(0,0,0,0.3)",zIndex:1e3,display:"flex",alignItems:"center",justifyContent:"center"},onClick:()=>b(!1),children:n.jsxs("div",{style:{background:"#fff",borderRadius:10,padding:24,width:440,maxHeight:"80vh",overflow:"auto"},onClick:B=>B.stopPropagation(),children:[n.jsx("h4",{style:{margin:"0 0 12px"},children:"Add Provider"}),n.jsx("label",{style:{fontSize:11,fontWeight:600,display:"block",marginBottom:4},children:"Type"}),n.jsxs("select",{value:S,onChange:B=>{E(B.target.value),D(""),P("")},style:{width:"100%",padding:"6px 8px",borderRadius:4,border:"1px solid #d1d5db",marginBottom:10,fontSize:13},children:[n.jsx("option",{value:"cloud",children:"☁️ Cloud (OpenAI, Anthropic, Mistral, ...)"}),n.jsx("option",{value:"ollama",children:"🦙 Ollama (local)"}),n.jsx("option",{value:"byoe",children:"🔌 BYOE (vLLM, LM Studio, custom endpoint)"}),n.jsx("option",{value:"huggingface",children:"🤗 HuggingFace Inference"})]}),S==="cloud"&&n.jsxs(n.Fragment,{children:[n.jsx("label",{style:{fontSize:11,fontWeight:600,display:"block",marginBottom:4},children:"Provider"}),n.jsxs("select",{value:k,onChange:B=>{const $=B.target.value;D($);const Y=l.find(O=>O.id===$);Y&&(G(Y.label),P(Y.base_url))},style:{width:"100%",padding:"6px 8px",borderRadius:4,border:"1px solid #d1d5db",marginBottom:10,fontSize:13},children:[n.jsx("option",{value:"",children:"Select..."}),l.map(B=>n.jsx("option",{value:B.id,children:B.label},B.id))]})]}),n.jsx("label",{style:{fontSize:11,fontWeight:600,display:"block",marginBottom:4},children:"Name"}),n.jsx("input",{value:H,onChange:B=>G(B.target.value),placeholder:"My vLLM server",style:{width:"100%",padding:"6px 8px",borderRadius:4,border:"1px solid #d1d5db",marginBottom:10,fontSize:13}}),n.jsx("label",{style:{fontSize:11,fontWeight:600,display:"block",marginBottom:4},children:"Base URL"}),n.jsx("input",{value:T,onChange:B=>P(B.target.value),placeholder:S==="ollama"?"http://localhost:11434":"http://BitConcepts:8000/v1",style:{width:"100%",padding:"6px 8px",borderRadius:4,border:"1px solid #d1d5db",marginBottom:10,fontSize:13}}),n.jsx("label",{style:{fontSize:11,fontWeight:600,display:"block",marginBottom:4},children:"API Key (optional)"}),n.jsx("input",{value:F,onChange:B=>W(B.target.value),type:"password",placeholder:"sk-...",style:{width:"100%",padding:"6px 8px",borderRadius:4,border:"1px solid #d1d5db",marginBottom:16,fontSize:13}}),n.jsxs("div",{style:{display:"flex",gap:8,justifyContent:"flex-end"},children:[n.jsx("button",{onClick:()=>b(!1),style:{padding:"6px 14px",borderRadius:4,border:"1px solid #d1d5db",cursor:"pointer",background:"#fff",fontSize:12},children:"Cancel"}),n.jsx("button",{onClick:N,disabled:M,style:{padding:"6px 14px",borderRadius:4,border:"none",cursor:"pointer",background:"#2563eb",color:"#fff",fontSize:12,fontWeight:600},children:M?"Saving...":"Add Provider"})]})]})})]})}const fy={ollama:{icon:"🦙",label:"Ollama",bg:"#fef3c7",color:"#92400e"},cloud:{icon:"☁️",label:"Cloud",bg:"#dbeafe",color:"#1e40af"},byoe:{icon:"⚡",label:"vLLM/Custom",bg:"#f3e8ff",color:"#6b21a8"},huggingface:{icon:"🤗",label:"HuggingFace",bg:"#fce7f3",color:"#9d174d"}};function Xk(t,o){return t==="ollama"?"ollama":t==="huggingface"?"huggingface":o!=null&&o.includes(":11434")||o!=null&&o.toLowerCase().includes("ollama")?"ollama":t==="byoe"?"byoe":t}const Jk={reasoning:{label:"Reasoning",icon:"🧠",desc:"Decipher, hypotheses, experiment planning, discovery classification"},conversational:{label:"Conversational",icon:"💬",desc:"Chat, synthesis, general Q&A"},longform:{label:"Long-form",icon:"📝",desc:"Paper drafting, report generation"},global:{label:"Global Default",icon:"🌐",desc:"Used when no bucket-specific assignment exists"}};function Pi(t){return t?`${t.provider_registry_id}|${t.model}`:""}function Kk(){const{toast:t}=nt(),[o,r]=x.useState([]),[l,c]=x.useState([]),[d,u]=x.useState([]),[p,g]=x.useState(!0),[h,b]=x.useState(!1),[y,v]=x.useState(!1),[w,j]=x.useState(!1),[_,C]=x.useState(!1),[S,E]=x.useState(!1),[k,D]=x.useState(()=>localStorage.getItem("glossa_assignment_filter")||"mixed"),H=Y=>{D(Y),localStorage.setItem("glossa_assignment_filter",Y)},[G,T]=x.useState({}),P=[];for(const Y of o)for(const O of Y.available_models||[])P.push({providerId:Y.id,providerName:Y.name,model:O,providerType:Xk(Y.provider_type,Y.base_url),baseUrl:Y.base_url});const F=P.filter(Y=>k==="cloud"?Y.providerType==="cloud":k==="local"?Y.providerType==="ollama"||Y.providerType==="byoe":!0),W=Y=>{const O={};for(const K of Y)O[`${K.bucket}_primary`]=Pi(K.primary),O[`${K.bucket}_fallback`]=Pi(K.fallback);return O},M=async()=>{g(!0);try{const[Y,O,K]=await Promise.all([Lb(!0),Ij(),Nb()]);r(Y.providers),c(O.assignments),u(K.scores),T(W(O.assignments))}catch{}g(!1)};x.useEffect(()=>{M()},[]);const V=(Y,O)=>{const K=l.find(ne=>ne.bucket===Y);return O==="primary"?K==null?void 0:K.primary:K==null?void 0:K.fallback},I=Y=>{const O=[Y];if(Y.includes("/")&&O.push(Y.split("/").slice(1).join("/")),Y.includes(":")){const K=Y.split(":")[0],ne=Y.split(":")[1];O.push(`${K}-${ne}`),O.push(K)}O.push(Y.replace(/\./g,"-").replace(/:/,"-")),O.push(Y.replace(/\./g,"").replace(/:/,"-"));for(const K of O){const ne=d.find(se=>se.model_name===K||K.toLowerCase().includes(se.model_name.toLowerCase())||se.model_name.toLowerCase().includes(K.toLowerCase()));if(ne)return ne}},A=(()=>{for(const Y of l){const O=`${Y.bucket}_primary`,K=`${Y.bucket}_fallback`;if(G[O]!==Pi(Y.primary)||G[K]!==Pi(Y.fallback))return!0}for(const Y of Object.keys(G))if(G[Y]){const[O,K]=Y.split("_"),ne=l.find(pe=>pe.bucket===O),se=Pi(K==="primary"?ne==null?void 0:ne.primary:ne==null?void 0:ne.fallback);if(G[Y]!==se)return!0}return!1})(),q=(Y,O,K)=>{T(ne=>({...ne,[`${Y}_${O}`]:K}))},R=async()=>{b(!0);const Y=["reasoning","conversational","longform","global"];let O=!1;for(const K of Y){const ne=G[`${K}_primary`]??"",se=G[`${K}_fallback`]??"",[pe,..._e]=ne.split("|"),Se=_e.join("|"),[ke,...te]=se.split("|"),de=te.join("|"),Ce=l.find(De=>De.bucket===K),ze=Pi(Ce==null?void 0:Ce.primary),ve=Pi(Ce==null?void 0:Ce.fallback);if(!(ne===ze&&se===ve))try{await $j(K,{primary_provider_id:pe||"",primary_model:Se||"",fallback_provider_id:ke||"",fallback_model:de||""})}catch(De){t(`${K}: ${De instanceof Error?De.message:"Save failed"}`,"error"),O=!0}}await M(),O||t("Model assignments saved","success"),b(!1)},J=()=>{T(W(l)),t("Changes reverted","info")},N=async()=>{C(!0);try{const Y=await Hj(k);Y.configured?(t(`Auto-configured (${k}) model assignments`,"success"),await M()):t(Y.message||"No models available","error")}catch(Y){t(Y instanceof Error?Y.message:"Auto-configure failed","error")}C(!1)},X=Y=>{const O=`${Y}_primary`,K=`${Y}_fallback`,ne=G[O]??"",se=G[K]??"";!ne&&!se||(T(pe=>({...pe,[O]:se,[K]:ne})),t(`${Y} primary ↔ fallback swapped (not saved yet)`,"info"))},Q=async()=>{v(!0),t("🔄 Syncing model scores from HuggingFace...","info");try{const Y=await Bb();t(Y.message,Y.message.includes("unreachable")||Y.message.includes("static")?"info":"success"),await M()}catch(Y){t(Y instanceof Error?Y.message:"Sync failed","error")}v(!1)},L=async()=>{j(!0);try{const Y=await Wj();t(Y.message,Y.valid?"success":"error")}catch(Y){t(Y instanceof Error?Y.message:"HF test failed","error")}j(!1)},B={section:{border:"1px solid #e5e7eb",borderRadius:8,padding:16,marginBottom:16,background:"#fff"}},$=(Y,O)=>{const K=G[`${Y}_${O}`]??"",ne=Pi(V(Y,O)),se=K!==ne,pe=h;return n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6,marginBottom:6},children:[n.jsxs("span",{style:{fontSize:10,fontWeight:600,color:O==="primary"?"#2563eb":"#9ca3af",width:55,flexShrink:0},children:[O==="primary"?"⚡ Primary":"⚠️ Fallback",se&&n.jsx("span",{style:{color:"#f59e0b",marginLeft:2},children:"●"})]}),n.jsxs("select",{value:K,onChange:_e=>q(Y,O,_e.target.value),disabled:pe,style:{flex:1,minWidth:0,fontSize:12,padding:"4px 6px",borderRadius:4,border:"1px solid #d1d5db",background:pe?"#f3f4f6":"#fff",textOverflow:"ellipsis"},children:[n.jsx("option",{value:"",children:"— not set —"}),F.map(_e=>{const Se=I(_e.model),te=Se?Se[Y==="conversational"?"conversational_score":Y==="longform"?"longform_score":"reasoning_score"]??0:0;return{..._e,scoreVal:te,hasScore:!!Se}}).filter(_e=>!S||_e.hasScore).sort((_e,Se)=>Se.scoreVal-_e.scoreVal).map(_e=>{var Se;return n.jsxs("option",{value:`${_e.providerId}|${_e.model}`,children:[((Se=fy[_e.providerType])==null?void 0:Se.icon)??"🔌"," ",_e.scoreVal>0?`★${_e.scoreVal.toFixed(0)} `:_e.hasScore?"☆0 ":"",_e.providerName," · ",_e.model]},`${_e.providerId}|${_e.model}`)})]})]})};return n.jsxs("section",{style:B.section,children:[n.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:12},children:[n.jsx("h3",{style:{margin:0,fontSize:15,fontWeight:700},children:"🎯 Model Assignments"}),n.jsxs("div",{style:{display:"flex",gap:6},children:[n.jsx("button",{onClick:L,disabled:w,style:{padding:"4px 10px",fontSize:11,border:"1px solid #d1d5db",borderRadius:4,cursor:"pointer",background:"#fff"},children:w?"Testing...":"🤗 Test HF"}),n.jsx("button",{onClick:Q,disabled:y,style:{padding:"4px 10px",fontSize:11,border:"1px solid #d1d5db",borderRadius:4,cursor:"pointer",background:"#fff"},children:y?"Syncing...":"🔄 Sync Scores"}),n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:2},children:[n.jsx("span",{style:{fontSize:10,color:"#9ca3af",flexShrink:0},children:"Filter:"}),n.jsxs("select",{value:k,onChange:Y=>H(Y.target.value),style:{fontSize:11,padding:"3px 4px",borderRadius:4,border:"1px solid #d1d5db",background:"#fff"},children:[n.jsx("option",{value:"mixed",children:"🔀 All"}),n.jsx("option",{value:"cloud",children:"☁️ Cloud only"}),n.jsx("option",{value:"local",children:"🖥️ Local only"})]})]}),n.jsx("button",{onClick:N,disabled:_,style:{padding:"4px 10px",fontSize:11,border:"none",borderRadius:4,cursor:"pointer",background:"#7c3aed",color:"#fff",fontWeight:600},children:_?"Configuring...":"✨ Auto-Configure"})]})]}),p&&n.jsx("div",{style:{color:"#9ca3af",fontSize:12},children:"Loading..."}),P.length===0&&!p&&n.jsx("div",{style:{textAlign:"center",padding:16,color:"#9ca3af",fontSize:12,background:"#f9fafb",borderRadius:6},children:'No models available. Add providers above and click "Test" to fetch model lists.'}),n.jsx("div",{style:{display:"grid",gap:10,gridTemplateColumns:"1fr 1fr",minWidth:0},children:["reasoning","conversational","longform","global"].map(Y=>{const O=Jk[Y],K=!!(G[`${Y}_primary`]||V(Y,"primary"))&&!!(G[`${Y}_fallback`]||V(Y,"fallback"));return n.jsxs("div",{style:{border:"1px solid #e5e7eb",borderRadius:6,padding:12,background:"#fafafa",minWidth:0,overflow:"hidden"},children:[n.jsxs("div",{style:{display:"flex",gap:6,alignItems:"center",marginBottom:8},children:[n.jsx("span",{style:{fontSize:16},children:O.icon}),n.jsxs("div",{style:{flex:1,minWidth:0},children:[n.jsx("div",{style:{fontWeight:700,fontSize:13},children:O.label}),n.jsx("div",{style:{fontSize:10,color:"#6b7280"},children:O.desc})]}),K&&n.jsx("button",{onClick:()=>X(Y),disabled:h,title:"Swap primary ↔ fallback (draft)",style:{padding:"2px 6px",fontSize:11,border:"1px solid #d1d5db",borderRadius:3,cursor:"pointer",background:"#fff",color:"#6b7280",flexShrink:0},children:"⇅"})]}),$(Y,"primary"),$(Y,"fallback")]},Y)})}),n.jsxs("div",{style:{marginTop:10,display:"flex",alignItems:"center",gap:8,padding:"8px 12px",borderRadius:6,background:A?"#fffbeb":"#f9fafb",border:`1px solid ${A?"#fcd34d":"#e5e7eb"}`,transition:"background 0.2s, border-color 0.2s"},children:[n.jsx("span",{style:{fontSize:12,color:A?"#92400e":"#9ca3af",flex:1},children:A?"⚠️ Unsaved changes":"✓ All changes saved"}),n.jsx("button",{onClick:J,disabled:!A||h,style:{padding:"4px 12px",fontSize:12,border:"1px solid #d1d5db",borderRadius:4,cursor:A&&!h?"pointer":"not-allowed",background:"#fff",color:A?"#374151":"#9ca3af",opacity:A?1:.5},children:"Revert"}),n.jsx("button",{onClick:R,disabled:!A||h,style:{padding:"4px 16px",fontSize:12,border:"none",borderRadius:4,cursor:A&&!h?"pointer":"not-allowed",background:A?"#2563eb":"#93c5fd",color:"#fff",fontWeight:700,opacity:A?1:.6},children:h?"Saving…":"✓ Apply"})]}),n.jsxs("div",{style:{marginTop:12,display:"flex",alignItems:"center",gap:12,flexWrap:"wrap"},children:[d.length>0&&n.jsxs("span",{style:{fontSize:10,color:"#9ca3af"},children:["📊 ",d.length," model(s) scored · ★ = bucket fitness score (higher = better)"]}),n.jsxs("label",{style:{display:"flex",alignItems:"center",gap:4,fontSize:11,color:"#6b7280",cursor:"pointer"},children:[n.jsx("input",{type:"checkbox",checked:S,onChange:Y=>E(Y.target.checked)}),"Scored models only"]}),n.jsx("div",{style:{display:"flex",gap:4,marginLeft:"auto",flexWrap:"wrap"},children:Object.values(fy).map(Y=>n.jsxs("span",{style:{fontSize:10,padding:"2px 6px",borderRadius:3,background:Y.bg,color:Y.color,fontWeight:600},children:[Y.icon," ",Y.label]},Y.label))})]})]})}const Ko=new Map,Qk=[{label:"All",max:999},{label:"≤ 4 GB",max:4},{label:"≤ 8 GB",max:8},{label:"≤ 12 GB",max:12},{label:"≤ 16 GB",max:16},{label:"≤ 24 GB",max:24}],Zk={excellent:"#16a34a",great:"#2563eb",good:"#ca8a04"};function e5(){const{toast:t}=nt(),[o,r]=x.useState([]),[l,c]=x.useState(null),[d,u]=x.useState([]),[p,g]=x.useState(!0),[h,b]=x.useState(!1),[y,v]=x.useState(-1),[w,j]=x.useState(()=>{const V={};for(const[I,A]of Ko)V[I]={pct:A.pct,status:A.status};return V}),[_,C]=x.useState({set:!1,editing:!1,value:""}),S=async()=>{g(!0);try{const[V,I,A]=await Promise.all([V2(),X2().catch(()=>null),Nb()]);r(V.models),b(V.running),c(I),u(A.scores);try{const q=await ld();C(R=>{var J,N;return{...R,set:((N=(J=q.keys)==null?void 0:J.hf_api_token)==null?void 0:N.set)??!1}})}catch{}I&&I.vram_gb>0&&y===-1?v(-1):y===-1&&v(999)}catch{}g(!1)};x.useEffect(()=>{S()},[]);const E=V=>d.find(I=>I.model_name===V||V.includes(I.model_name)||I.model_name.includes(V)),k=V=>{if(Ko.has(V))return;const I={pct:0,status:"connecting…"},A=new EventSource(`/api/v1/ollama/pull/${encodeURIComponent(V)}`);Ko.set(V,{es:A,...I}),j(q=>({...q,[V]:I})),A.onmessage=q=>{try{const R=JSON.parse(q.data);if(R.error){t(`Pull failed: ${R.error}`,"error"),Ko.delete(V),j(Q=>{const L={...Q};return delete L[V],L}),A.close();return}if(R.status==="success"){t(`${V} downloaded`,"success"),Ko.delete(V),j(Q=>{const L={...Q};return delete L[V],L}),A.close(),S();return}const J=R.total&&R.completed?Math.round(R.completed/R.total*100):0,N=R.status||"downloading…",X=Ko.get(V);X&&(X.pct=J,X.status=N),j(Q=>({...Q,[V]:{pct:J,status:N}}))}catch{}},A.onerror=()=>{Ko.delete(V),j(q=>{const R={...q};return delete R[V],R}),A.close()}},D=async()=>{try{await sr({hf_api_token:_.value}),C({set:!0,editing:!1,value:""}),t("HF token saved — click Sync Scores to fetch leaderboard data","success")}catch(V){t(V instanceof Error?V.message:"Save failed","error")}},H=async()=>{try{const V=await Bb();t(V.message,"success"),S()}catch(V){t(V instanceof Error?V.message:"Sync failed","error")}},G=async V=>{if(confirm(`Delete ${V}?`))try{await J2(V),t(`${V} deleted`,"success"),S()}catch(I){t(I instanceof Error?I.message:"Delete failed","error")}},T=(l==null?void 0:l.vram_gb)??0,P=y===-1?T:y,F=y!==999&&!(y===-1&&T===0),W=o.slice().sort((V,I)=>{if(F){const A=V.min_vram_gb<=P?0:1,q=I.min_vram_gb<=P?0:1;if(A!==q)return A-q}return I.glossa_score-V.glossa_score||V.min_vram_gb-I.min_vram_gb}),M={section:{border:"1px solid #e5e7eb",borderRadius:8,padding:16,marginBottom:16,background:"#fff"}};return n.jsxs("section",{style:M.section,children:[n.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:10},children:[n.jsx("h3",{style:{margin:0,fontSize:15,fontWeight:700},children:"🏪 Model Hub"}),n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6},children:[n.jsx("span",{style:{width:8,height:8,borderRadius:"50%",background:h?"#16a34a":"#ef4444"}}),n.jsx("span",{style:{fontSize:11,color:"#6b7280"},children:h?"Ollama running":"Ollama offline"})]})]}),n.jsxs("div",{style:{display:"flex",gap:6,alignItems:"center",marginBottom:10,fontSize:11},children:[n.jsx("span",{style:{color:"#6b7280"},children:"HuggingFace token:"}),_.editing?n.jsxs(n.Fragment,{children:[n.jsx("input",{value:_.value,onChange:V=>C(I=>({...I,value:V.target.value})),placeholder:"hf_...",type:"password",style:{flex:1,maxWidth:220,padding:"2px 6px",border:"1px solid #d1d5db",borderRadius:4,fontSize:11}}),n.jsx("button",{onClick:D,style:{padding:"2px 8px",fontSize:10,border:"none",borderRadius:4,background:"#2563eb",color:"#fff",cursor:"pointer"},children:"Save"}),n.jsx("button",{onClick:()=>C(V=>({...V,editing:!1,value:""})),style:{padding:"2px 8px",fontSize:10,border:"1px solid #d1d5db",borderRadius:4,background:"#fff",cursor:"pointer"},children:"Cancel"})]}):n.jsxs(n.Fragment,{children:[n.jsx("span",{style:{color:_.set?"#16a34a":"#9ca3af"},children:_.set?"set ✓":"not set"}),n.jsx("button",{onClick:()=>C(V=>({...V,editing:!0})),style:{padding:"2px 8px",fontSize:10,border:"1px solid #d1d5db",borderRadius:4,background:"#fff",cursor:"pointer"},children:_.set?"Change":"Add"}),n.jsx("button",{onClick:H,style:{padding:"2px 8px",fontSize:10,border:"1px solid #d1d5db",borderRadius:4,background:"#fff",cursor:"pointer"},children:"🔄 Sync from HF"}),!_.set&&n.jsx("span",{style:{color:"#9ca3af",fontSize:10},children:"Optional — free at huggingface.co/settings/tokens"})]})]}),l&&l.vram_gb>0&&n.jsxs("div",{style:{background:"#f0fdf4",border:"1px solid #86efac",borderRadius:6,padding:"8px 12px",marginBottom:10,fontSize:11,color:"#166534"},children:["🖥️ ",n.jsx("strong",{children:l.gpu_name})," — ",l.vram_gb," GB VRAM · Recommended: ",n.jsx("strong",{children:l.recommended.display})]}),n.jsxs("div",{style:{display:"flex",gap:4,marginBottom:12,flexWrap:"wrap"},children:[T>0&&n.jsxs("button",{onClick:()=>v(-1),style:{padding:"3px 10px",fontSize:11,border:"1px solid #d1d5db",borderRadius:4,cursor:"pointer",background:y===-1?"#16a34a":"#fff",color:y===-1?"#fff":"#374151",fontWeight:y===-1?700:400},children:["🖥️ My GPU (",T," GB)"]}),Qk.map(V=>n.jsx("button",{onClick:()=>v(V.max),style:{padding:"3px 10px",fontSize:11,border:"1px solid #d1d5db",borderRadius:4,cursor:"pointer",background:y===V.max?"#2563eb":"#fff",color:y===V.max?"#fff":"#374151",fontWeight:y===V.max?700:400},children:V.label},V.max)),n.jsxs("span",{style:{fontSize:10,color:"#9ca3af",alignSelf:"center",marginLeft:4},children:[W.length," model",W.length!==1?"s":""]})]}),p&&n.jsx("div",{style:{color:"#9ca3af",fontSize:12,padding:16,textAlign:"center"},children:"Loading…"}),!p&&!h&&n.jsxs("div",{style:{textAlign:"center",padding:20,color:"#9ca3af",fontSize:12,background:"#fef2f2",border:"1px solid #fca5a5",borderRadius:6},children:["Ollama is not running. Install from ",n.jsx("a",{href:"https://ollama.com",target:"_blank",rel:"noopener noreferrer",children:"ollama.com"})," and start it to download models."]}),!p&&W.map(V=>{const I=E(V.name),A=w[V.name],q=!F||V.min_vram_gb<=P,R=F&&!q;return n.jsxs("div",{style:{display:"flex",gap:10,alignItems:"flex-start",padding:"10px 0",borderBottom:"1px solid #f3f4f6",opacity:R?.45:1},children:[n.jsxs("div",{style:{flex:1,minWidth:0},children:[n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6,flexWrap:"wrap"},children:[n.jsx("span",{style:{fontSize:13,fontWeight:700},children:V.display}),n.jsx("span",{style:{fontSize:9,padding:"1px 5px",borderRadius:8,background:Zk[V.quality]||"#6b7280",color:"#fff",fontWeight:600},children:V.quality}),V.installed&&n.jsx("span",{style:{fontSize:9,padding:"1px 5px",borderRadius:8,background:"#16a34a",color:"#fff",fontWeight:600},children:"installed"}),V.tags.includes("top-pick")&&n.jsx("span",{style:{fontSize:9,padding:"1px 5px",borderRadius:8,background:"#f59e0b",color:"#78350f",fontWeight:700},children:"⭐ TOP PICK"}),V.tags.includes("moe")&&n.jsx("span",{style:{fontSize:9,padding:"1px 5px",borderRadius:8,background:"#8b5cf6",color:"#fff",fontWeight:600},children:"MoE"}),R&&n.jsxs("span",{style:{fontSize:9,padding:"1px 5px",borderRadius:8,background:"#ef4444",color:"#fff",fontWeight:600},children:["needs ≥",V.min_vram_gb," GB"]})]}),n.jsx("div",{style:{fontSize:11,color:"#6b7280",marginTop:2},children:V.desc}),n.jsxs("div",{style:{display:"flex",gap:10,marginTop:3,fontSize:10,color:"#9ca3af"},children:[n.jsxs("span",{children:[V.param_b,"B params"]}),n.jsxs("span",{children:[V.size_gb," GB"]}),n.jsxs("span",{children:["≥",V.min_vram_gb," GB VRAM"]}),I&&n.jsxs(n.Fragment,{children:[n.jsxs("span",{title:"Reasoning",children:["🧠",I.reasoning_score.toFixed(0)]}),n.jsxs("span",{title:"Conversational",children:["💬",I.conversational_score.toFixed(0)]}),n.jsxs("span",{title:"Long-form",children:["📝",I.longform_score.toFixed(0)]})]})]}),A&&n.jsxs("div",{style:{marginTop:4},children:[n.jsx("div",{style:{height:4,background:"#e5e7eb",borderRadius:2,overflow:"hidden"},children:n.jsx("div",{style:{height:"100%",width:`${A.pct}%`,background:"#2563eb",transition:"width 0.3s"}})}),n.jsxs("div",{style:{fontSize:9,color:"#6b7280",marginTop:1},children:[A.status," ",A.pct>0?`${A.pct}%`:""]})]})]}),n.jsx("div",{style:{display:"flex",gap:4,flexShrink:0,alignItems:"center"},children:V.installed?n.jsx("button",{onClick:()=>G(V.name),style:{padding:"3px 8px",fontSize:10,border:"1px solid #fca5a5",borderRadius:4,background:"#fff",color:"#dc2626",cursor:"pointer"},children:"🗑️ Delete"}):n.jsx("button",{onClick:()=>k(V.name),disabled:!h||!!A,style:{padding:"3px 10px",fontSize:10,border:"none",borderRadius:4,cursor:h&&!A?"pointer":"not-allowed",background:h&&!A?"#2563eb":"#e5e7eb",color:h&&!A?"#fff":"#9ca3af",fontWeight:600},children:A?"Pulling…":"⬇ Pull"})})]},V.name)}),h&&n.jsx(t5,{onPull:k,pulling:w})]})}function t5({onPull:t,pulling:o}){const[r,l]=x.useState("");return n.jsxs("div",{style:{marginTop:10,display:"flex",gap:6,alignItems:"center"},children:[n.jsx("input",{value:r,onChange:c=>l(c.target.value),placeholder:"any-model:tag",style:{flex:1,fontSize:11,padding:"4px 8px",border:"1px solid #d1d5db",borderRadius:4},onKeyDown:c=>{c.key==="Enter"&&r.trim()&&(t(r.trim()),l(""))}}),n.jsx("button",{onClick:()=>{r.trim()&&(t(r.trim()),l(""))},disabled:!r.trim()||!!o[r.trim()],style:{padding:"4px 10px",fontSize:10,border:"none",borderRadius:4,background:"#7c3aed",color:"#fff",cursor:"pointer",fontWeight:600},children:"Pull custom"})]})}function n5(){const{toast:t}=nt(),[o,r]=x.useState(null),[l,c]=x.useState(!0),[d,u]=x.useState(!1),[p,g]=x.useState([]),[h,b]=x.useState(null),[y,v]=x.useState(!0),[w,j]=x.useState(!0),_=x.useRef(null),C=async()=>{c(!0);try{r(await _b())}catch{}finally{c(!1)}};x.useEffect(()=>{C()},[]),x.useEffect(()=>{const T=_.current;T&&(T.scrollTop=T.scrollHeight)},[p]);const S=async(T,P)=>{u(!0),g([{text:`Running: ${P}…`,type:"info"}]);try{const F=await T();if(!F.body){g(I=>[...I,{text:"No response body",type:"error"}]);return}const W=F.body.getReader(),M=new TextDecoder;let V="";for(;;){const{done:I,value:A}=await W.read();if(I)break;V+=M.decode(A,{stream:!0});const q=V.split(` -`);Y=G.pop()??"";for(const R of G)for(const X of R.split(` -`))if(X.startsWith("data: "))try{const B=JSON.parse(X.slice(6));if(B.text){const V=B.text.toLowerCase().includes("error")||B.text.startsWith("⚠"),Q=B.text.startsWith("✓");g(N=>[...N,{text:B.text,type:V?"error":Q?"success":"output"}])}}catch{}else X.startsWith("event: done")||X.startsWith("event: error")}await T(),t(`${M} complete`,"success")}catch(q){g(K=>[...K,{text:`Failed: ${q instanceof Error?q.message:String(q)}`,type:"error"}]),t(`${M} failed`,"error")}finally{u(!1)}},C=async()=>{if(h!==null){v(null);return}const z=await ij();v(z.packages),k(!0)},j=o==null?void 0:o.venv_exists,L=l?"#9ca3af":j?"#16a34a":"#ef4444",W=l?"checking…":j?`Active · Python ${(o==null?void 0:o.python_version)??"?"}`:"Not found",P=(z,M)=>({padding:"5px 12px",border:"none",borderRadius:5,background:M?"#e5e7eb":z,color:M?"#9ca3af":"#fff",cursor:M?"not-allowed":"pointer",fontSize:12,fontWeight:600});return n.jsxs("section",{style:n3,children:[n.jsx("h3",{style:{margin:"0 0 10px",fontSize:15,fontWeight:600,color:"#111827"},children:"🐍 Python Environment"}),n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10,marginBottom:12,padding:"10px 14px",background:j?"#f0fdf4":"#fef2f2",border:`1px solid ${j?"#86efac":"#fca5a5"}`,borderRadius:7},children:[n.jsx("span",{style:{width:9,height:9,borderRadius:"50%",background:L,flexShrink:0}}),n.jsxs("div",{style:{flex:1},children:[n.jsx("div",{style:{fontSize:13,fontWeight:600,color:"#111827"},children:W}),(o==null?void 0:o.venv_path)&&n.jsx("div",{style:{fontSize:10,color:"#6b7280",fontFamily:"monospace",marginTop:1},children:o.venv_path}),j&&n.jsxs("div",{style:{fontSize:11,color:"#6b7280",marginTop:2},children:[(o==null?void 0:o.pkg_count)??0," packages installed"]})]}),n.jsx("button",{onClick:T,style:{padding:"3px 8px",border:"1px solid #d1d5db",borderRadius:4,background:"#fff",cursor:"pointer",fontSize:11,color:"#6b7280"},children:"⟳"})]}),!j&&!l&&n.jsxs("div",{style:{padding:"12px 14px",background:"#fef3c7",border:"1px solid #fcd34d",borderRadius:6,marginBottom:12,fontSize:12,color:"#92400e"},children:["No virtual environment found. Click ",n.jsx("strong",{children:"Setup venv"})," to create one and install all dependencies."]}),n.jsxs("div",{style:{display:"flex",gap:8,flexWrap:"wrap",marginBottom:12},children:[n.jsx("button",{onClick:()=>w(oj,"Setup venv"),disabled:d,style:P("#16a34a",d),children:"⬇ Setup venv"}),n.jsx("button",{onClick:()=>w(sj,"Rebuild venv"),disabled:d,style:P("#ea580c",d),children:"↺ Rebuild venv"}),n.jsx("button",{onClick:()=>w(rj,"Upgrade deps"),disabled:d||!j,style:P("#2563eb",d||!j),children:"↑ Upgrade deps"}),n.jsx("button",{onClick:C,disabled:!j,style:P("#7c3aed",!j),title:h!==null?"Hide the package list (does not uninstall anything)":"Fetch and show installed packages",children:h!==null?"📦 Hide packages":"📦 Show packages"})]}),p.length>0&&n.jsxs("div",{style:{marginBottom:10},children:[n.jsxs("button",{onClick:()=>b(z=>!z),style:{display:"flex",alignItems:"center",gap:5,background:"none",border:"none",cursor:"pointer",padding:"2px 0",marginBottom:4,fontSize:11,fontWeight:700,color:"#374151",textTransform:"uppercase",letterSpacing:.5},children:[n.jsx("span",{style:{fontSize:9,transition:"transform .15s",transform:y?"rotate(90deg)":"rotate(0deg)"},children:"▶"}),"Install output"]}),y&&n.jsx("div",{ref:_,style:{background:"#0f172a",borderRadius:5,padding:"8px 10px",maxHeight:200,overflowY:"auto",fontFamily:"monospace",fontSize:11},children:p.map((z,M)=>n.jsx("div",{style:{color:z.type==="error"?"#f87171":z.type==="success"?"#86efac":"#e2e8f0",lineHeight:1.6},children:z.text},M))})]}),h&&n.jsxs("div",{children:[n.jsxs("button",{onClick:()=>k(z=>!z),style:{display:"flex",alignItems:"center",gap:5,background:"none",border:"none",cursor:"pointer",padding:"2px 0",marginBottom:4,fontSize:11,fontWeight:700,color:"#374151",textTransform:"uppercase",letterSpacing:.5},children:[n.jsx("span",{style:{fontSize:9,transition:"transform .15s",transform:S?"rotate(90deg)":"rotate(0deg)"},children:"▶"}),"Installed packages (",h.length,")"]}),S&&n.jsx("div",{style:{display:"flex",flexWrap:"wrap",gap:"2px 8px",maxHeight:140,overflowY:"auto"},children:h.map(z=>n.jsxs("span",{style:{fontSize:10,fontFamily:"monospace",color:"#374151"},children:[z.name," ",n.jsx("span",{style:{color:"#9ca3af"},children:z.version})]},z.name))})]})]})}const hy="glossa_settings_tab",gy=[{id:"ai",label:"AI",icon:"🤖"},{id:"discovery",label:"Discovery",icon:"🔭"},{id:"notifications",label:"Notifications",icon:"✉️"},{id:"system",label:"System",icon:"⚙️"}];function Qk(){const[t,o]=x.useState(()=>{const b=localStorage.getItem(hy);return b&&gy.some(S=>S.id===b)?b:"ai"}),r=b=>{o(b),localStorage.setItem(hy,b)},[l,c]=x.useState(""),[d,u]=x.useState(""),[p,g]=x.useState(""),[h,v]=x.useState(""),y=async()=>{try{const[b,S]=await Promise.all([ad(),Na()]);c(b.data_dir),u(S.version??"");const k=S.uptime_seconds??0,_=Math.floor(k/60),T=Math.floor(_/60);g(T>0?`${T}h ${_%60}m`:_>0?`${_}m`:`${Math.round(k)}s`),v("")}catch{}};return x.useEffect(()=>{y()},[]),n.jsxs("div",{style:{maxWidth:760},children:[n.jsx("h2",{style:{marginTop:0,marginBottom:12},children:"Settings"}),n.jsx("div",{style:{display:"flex",gap:2,borderBottom:"2px solid #e5e7eb",marginBottom:20},children:gy.map(b=>n.jsxs("button",{onClick:()=>r(b.id),style:{padding:"8px 16px",border:"none",cursor:"pointer",fontSize:13,fontWeight:t===b.id?700:500,color:t===b.id?"#2563eb":"#6b7280",background:t===b.id?"#eff6ff":"transparent",borderBottom:t===b.id?"2px solid #2563eb":"2px solid transparent",borderRadius:"6px 6px 0 0",marginBottom:-2},children:[b.icon," ",b.label]},b.id))}),h&&n.jsx("div",{style:{...t3,background:"#fef2f2",borderColor:"#fca5a5",color:"#991b1b"},children:h}),t==="ai"&&n.jsxs(n.Fragment,{children:[n.jsx(qk,{}),n.jsx(Fk,{}),n.jsx(Xk,{}),n.jsxs("section",{style:mp,children:[n.jsx("h3",{style:xp,children:"AI Behavior"}),n.jsx("p",{style:is,children:"Control how Glossa AI handles action proposals during chat."}),n.jsx(e3,{})]})]}),t==="discovery"&&n.jsx(Lk,{}),t==="notifications"&&n.jsx(Tk,{}),t==="system"&&n.jsxs(n.Fragment,{children:[n.jsx(Kk,{}),n.jsx(Zk,{}),n.jsxs("section",{style:mp,children:[n.jsx("h3",{style:xp,children:"System"}),n.jsx("table",{style:{borderCollapse:"collapse"},children:n.jsxs("tbody",{children:[n.jsx(Uf,{label:"Data directory",value:l||"—",mono:!0}),d&&n.jsx(Uf,{label:"Backend version",value:d}),p&&n.jsx(Uf,{label:"Backend uptime",value:p})]})}),n.jsx("p",{style:{...is,marginTop:10,color:"#9ca3af"},children:"Corpus, sign mapping, and pipeline settings are project-specific. Open or create a project to configure them."})]})]})]})}function Zk(){const{toast:t}=et(),[o,r]=x.useState(!1),l=async()=>{r(!0);try{const c=await h2();g2(),window.dispatchEvent(new CustomEvent("glossa:seq_queue_updated")),t(`${c.cleared_jobs} job(s) cleared — cache reset`,"success")}catch(c){t(c instanceof Error?c.message:"Clear failed","error")}finally{r(!1)}};return n.jsxs("section",{style:mp,children:[n.jsx("h3",{style:xp,children:"🗑 Clear Cache"}),n.jsx("p",{style:is,children:"Removes all non-running jobs from the database (completed, failed, paused, queued) and clears all run-related browser state:"}),n.jsxs("ul",{style:{...is,margin:"6px 0 0 16px",padding:0},children:[n.jsx("li",{children:"Experiment run badges (✓/✗) in the Builder"}),n.jsx("li",{children:"Sequential run queue"}),n.jsx("li",{children:"Dashboard AI insight + applied action state"})]}),n.jsxs("p",{style:{...is,marginTop:8,color:"#9ca3af"},children:[n.jsx("strong",{children:"Running jobs are never affected."})," Use this before re-running experiments to start completely clean."]}),n.jsx("button",{onClick:l,disabled:o,style:{marginTop:12,padding:"6px 16px",border:"none",borderRadius:5,background:o?"#e5e7eb":"#b45309",color:o?"#9ca3af":"#fff",cursor:o?"not-allowed":"pointer",fontSize:13,fontWeight:600},children:o?"Clearing…":"🗑 Clear Cache"})]})}const my="glossa_auto_approve";function e3(){const{toast:t}=et(),[o,r]=x.useState(()=>localStorage.getItem(my)==="true"),l=c=>{r(c),localStorage.setItem(my,c?"true":"false"),window.dispatchEvent(new CustomEvent("glossa:auto_approve_changed")),t(c?"Auto-approve enabled — Glossa AI will run all actions automatically":"Auto-approve disabled",c?"success":"info")};return n.jsxs("div",{style:{marginTop:12},children:[n.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"12px 14px",borderRadius:7,border:`1px solid ${o?"#fbbf24":"#e5e7eb"}`,background:o?"#fffbeb":"#fafafa"},children:[n.jsxs("div",{children:[n.jsxs("div",{style:{fontSize:13,fontWeight:600,color:o?"#92400e":"#374151",display:"flex",alignItems:"center",gap:6},children:[n.jsx("span",{style:{fontSize:15},children:o?"⚡":"✋"}),"Auto Approve All AI Actions",o&&n.jsx("span",{style:{fontSize:9,padding:"1px 6px",borderRadius:8,background:"#f59e0b",color:"#78350f",fontWeight:700},children:"ACTIVE"})]}),n.jsx("p",{style:{...is,marginTop:3},children:o?"Glossa AI will execute all proposed actions automatically without asking for approval. Click to disable.":"Glossa AI will ask for approval before executing actions. Toggle on to run all actions automatically."})]}),n.jsx("div",{onClick:()=>l(!o),title:o?"Click to disable auto-approve":"Click to enable auto-approve",style:{width:44,height:24,borderRadius:12,cursor:"pointer",flexShrink:0,background:o?"#f59e0b":"#d1d5db",position:"relative",transition:"background 0.2s"},children:n.jsx("div",{style:{position:"absolute",top:3,left:o?23:3,width:18,height:18,borderRadius:"50%",background:"#fff",boxShadow:"0 1px 3px rgba(0,0,0,0.25)",transition:"left 0.2s"}})})]}),n.jsxs("p",{style:{...is,marginTop:6,color:"#9ca3af"},children:["You can also toggle auto-approve per-session from the ",n.jsx("strong",{children:"⚡ AUTO"})," badge in the Glossa AI chat header, or via the ",n.jsx("strong",{children:"▾"})," dropdown on any Approve button."]})]})}function Uf({label:t,value:o,mono:r}){return n.jsxs("tr",{children:[n.jsx("td",{style:{padding:"3px 16px 3px 0",fontSize:13,color:"#6b7280",whiteSpace:"nowrap"},children:t}),n.jsx("td",{style:{padding:"3px 0",fontSize:13,fontFamily:r?"monospace":void 0},children:o})]})}const mp={marginBottom:"2rem",padding:"1.25rem",border:"1px solid #e5e7eb",borderRadius:8},xp={margin:"0 0 0.75rem 0",fontSize:15,fontWeight:600,color:"#111827"},is={margin:0,fontSize:12,color:"#6b7280",lineHeight:1.5},t3={padding:"10px 14px",borderRadius:6,border:"1px solid",marginBottom:"1rem",fontSize:13},n3={marginBottom:"2rem",padding:"1.25rem",border:"1px solid #d1fae5",borderRadius:8,background:"#fafffe"},ma="glossa_active_project",xy="__global__",qb=x.createContext({activeProject:null,projects:[],setActiveProject:async()=>{},refreshProjects:async()=>{},loading:!0});function i3({children:t}){const[o,r]=x.useState([]),[l,c]=x.useState(null),[d,u]=x.useState(!0),p=x.useCallback(async()=>{try{const h=await Ab();r(h);const v=localStorage.getItem(ma);let y=null;const b=v===xy;if(v&&!b&&(y=h.find(S=>S.id===v)??null),!y)try{const S=await _j();y=h.find(k=>k.id===S.id)??null}catch{}!y&&h.length===1&&!b&&(y=h[0]),c(y),y&&localStorage.setItem(ma,y.id)}catch{}finally{u(!1)}},[]);x.useEffect(()=>{p()},[p]),x.useEffect(()=>{const h=()=>{p()};return window.addEventListener("glossa:project-changed",h),()=>window.removeEventListener("glossa:project-changed",h)},[p]);const g=x.useCallback(async h=>{if(h===null)c(null),localStorage.setItem(ma,xy);else{try{await Mb(h)}catch{}const v=o.find(y=>y.id===h)??null;c(v),v?localStorage.setItem(ma,v.id):localStorage.removeItem(ma)}window.dispatchEvent(new CustomEvent("glossa:project-changed"))},[o]);return n.jsx(qb.Provider,{value:{activeProject:l,projects:o,setActiveProject:g,refreshProjects:p,loading:d},children:t})}function zo(){return x.useContext(qb)}function yy(t){return t.replace(/^### (.+)$/gm,'

$1

').replace(/^## (.+)$/gm,'

$1

').replace(/^# (.+)$/gm,'

$1

').replace(/\*\*(.+?)\*\*/g,"$1").replace(/\*(.+?)\*/g,"$1").replace(/^\| (.+) \|$/gm,o=>""+o.split("|").filter(l=>l.trim()).map(l=>`${l.trim()}`).join("")+"").replace(/(.*?<\/tr>\n?)+/gs,o=>`${o}
`).replace(/^- (.+)$/gm,'
  • $1
  • ').replace(/(\n?)+/gs,'
      $1
    ').replace(/^(?!<[a-z])(.+)$/gm,'

    $1

    ').replace(/```[\s\S]*?```/g,o=>`
    ${o.replace(/```\w*/g,"").trim()}
    `)}const by=new Set(["data","document"]),vy=new Set(["report"]),xa={report:"PDF Report",data:"Data",document:"Document"},Sy={report:"#dc2626",data:"#2563eb",document:"#7c3aed"};function wy({label:t,options:o,selected:r,onChange:l,colorMap:c}){const[d,u]=x.useState(!1),[p,g]=x.useState(""),h=x.useRef(null);x.useEffect(()=>{if(!d)return;const S=k=>{h.current&&!h.current.contains(k.target)&&u(!1)};return document.addEventListener("mousedown",S),()=>document.removeEventListener("mousedown",S)},[d]);const v=S=>{const k=new Set(r);k.has(S)?k.delete(S):k.add(S),l(k)},y=o.filter(S=>!p||S.toLowerCase().includes(p.toLowerCase())),b=r.size;return n.jsxs("div",{ref:h,style:{position:"relative"},children:[n.jsxs("button",{onClick:()=>u(S=>!S),style:{display:"flex",alignItems:"center",gap:5,padding:"4px 10px",border:`1px solid ${b>0?"#2563eb":"#d1d5db"}`,borderRadius:6,background:b>0?"#eff6ff":"#fff",cursor:"pointer",fontSize:12,color:"#374151",whiteSpace:"nowrap"},children:[n.jsxs("span",{style:{fontSize:11,color:"#6b7280"},children:[t,":"]}),b===0?n.jsx("span",{style:{color:"#9ca3af"},children:"All"}):n.jsxs("span",{style:{fontWeight:700,color:"#2563eb"},children:[b," selected"]}),n.jsx("span",{style:{fontSize:9,color:"#9ca3af"},children:d?"▲":"▼"})]}),d&&n.jsxs("div",{style:{position:"absolute",top:"calc(100% + 4px)",left:0,zIndex:200,background:"#fff",border:"1px solid #e5e7eb",borderRadius:8,boxShadow:"0 8px 24px rgba(0,0,0,0.12)",minWidth:200,maxHeight:280,display:"flex",flexDirection:"column"},children:[o.length>6&&n.jsx("div",{style:{padding:"6px 8px",borderBottom:"1px solid #f3f4f6"},children:n.jsx("input",{value:p,onChange:S=>g(S.target.value),placeholder:"Search\\u2026",style:{width:"100%",border:"1px solid #e5e7eb",borderRadius:4,padding:"3px 7px",fontSize:11,outline:"none",boxSizing:"border-box"},autoFocus:!0})}),n.jsxs("button",{onClick:()=>l(new Set),style:{padding:"6px 12px",border:"none",background:"none",textAlign:"left",cursor:"pointer",fontSize:11,color:b===0?"#2563eb":"#374151",fontWeight:b===0?700:400,borderBottom:"1px solid #f3f4f6"},children:[b===0?"✔ ":""," All (",o.length,")"]}),n.jsxs("div",{style:{overflowY:"auto",flex:1},children:[y.map(S=>{const k=(c==null?void 0:c[S])??"#2563eb",_=r.has(S);return n.jsxs("button",{onClick:()=>v(S),style:{display:"flex",alignItems:"center",gap:8,width:"100%",padding:"6px 12px",border:"none",background:_?k+"10":"none",cursor:"pointer",textAlign:"left",fontSize:11,borderBottom:"1px solid #f9fafb"},children:[n.jsx("span",{style:{width:14,height:14,borderRadius:3,border:`2px solid ${_?k:"#d1d5db"}`,background:_?k:"#fff",flexShrink:0,display:"flex",alignItems:"center",justifyContent:"center"},children:_&&n.jsx("span",{style:{color:"#fff",fontSize:9,fontWeight:700},children:"\\u2713"})}),n.jsx("span",{style:{flex:1,color:_?k:"#374151",fontWeight:_?600:400},children:S})]},S)}),y.length===0&&n.jsx("div",{style:{padding:"8px 12px",color:"#9ca3af",fontSize:11},children:"No matches"})]}),b>0&&n.jsx("button",{onClick:()=>{l(new Set),u(!1)},style:{padding:"5px 12px",border:"none",background:"none",borderTop:"1px solid #f3f4f6",cursor:"pointer",fontSize:10,color:"#6b7280",textAlign:"left"},children:"Clear selection"})]}),b>0&&n.jsx("div",{style:{display:"flex",gap:3,flexWrap:"wrap",marginTop:4},children:Array.from(r).map(S=>n.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:3,padding:"1px 6px",borderRadius:10,fontSize:10,fontWeight:600,background:((c==null?void 0:c[S])??"#2563eb")+"18",color:(c==null?void 0:c[S])??"#2563eb",border:`1px solid ${(c==null?void 0:c[S])??"#2563eb"}30`},children:[S,n.jsx("button",{onClick:()=>v(S),style:{border:"none",background:"none",cursor:"pointer",color:"inherit",fontSize:11,padding:0,lineHeight:1},children:"\\u00d7"})]},S))})]})}function o3(){const{activeProject:t}=zo(),o=(t==null?void 0:t.id)??null,[r,l]=x.useState([]),[c,d]=x.useState(!0),[u,p]=x.useState(null),[g,h]=x.useState("reports"),[v,y]=x.useState(""),[b,S]=x.useState(new Set),[k,_]=x.useState(new Set),[T,w]=x.useState("updated_at"),[C,j]=x.useState("desc"),[L,W]=x.useState(!0),[P,z]=x.useState(null),[M,q]=x.useState(!1),[K,D]=x.useState([]),[Y,H]=x.useState(""),[A,G]=x.useState(!1),[R,X]=x.useState(null),B=async()=>{X(null),q(!0);try{const oe=await v2();D(oe),oe.length>0&&H(oe[0].id)}catch{D([])}},V=async()=>{if(Y){G(!0),X(null);try{const oe=await S2(Y);X(oe.message),setTimeout(()=>{q(!1),X(null),de()},3e3)}catch(oe){X(oe instanceof Error?oe.message:"Generation failed")}finally{G(!1)}}},[Q,N]=x.useState(!1),[O,$]=x.useState(new Set),[F,I]=x.useState(!1),[J,ne]=x.useState(null),se=async()=>{const oe=r.filter(Ne=>O.has(Ne.id));if(oe.length){I(!0);try{const Ne=await Promise.all(oe.map(async mt=>{const St=Df(mt.id);try{const Ht=await fetch(St);if(Ht.ok){const Kt=await Ht.json();return{name:mt.name,filename:mt.relative_path,data:Kt}}}catch{}return{name:mt.name,filename:mt.relative_path,data:{}}})),We=await jb({report_contents:Ne,title:oe.length===1?`Analysis: ${oe[0].name}`:`Synthesis of ${oe.length} Reports`});ne(We)}catch(Ne){alert(Ne instanceof Error?Ne.message:"AI report generation failed. Check that a language model is configured in Settings.")}finally{I(!1)}}},pe=oe=>$(Ne=>{const We=new Set(Ne);return We.has(oe)?We.delete(oe):We.add(oe),We}),[_e,we]=x.useState(()=>{try{return new Set(JSON.parse(localStorage.getItem("glossa_starred_reports")??"[]"))}catch{return new Set}}),ke=oe=>{we(Ne=>{const We=new Set(Ne);return We.has(oe)?We.delete(oe):We.add(oe),localStorage.setItem("glossa_starred_reports",JSON.stringify([...We])),We})},te=async()=>{const oe=r.filter(St=>O.has(St.id));if(!oe.length)return;const We=(await Promise.all(oe.map(async St=>{const Ht=Df(St.id);let Kt=`Open source file →`;try{const _i=await fetch(Ht);if(_i.ok&&St.kind==="data"){const bn=await _i.json();if(bn.results&&typeof bn.results=="object"){const di=Object.entries(bn.results).map(([Qi,gn])=>{const Rt=typeof gn=="object"?JSON.stringify(gn,null,2):String(gn);return`${Qi.replace(/_/g," ")}
    ${Rt.slice(0,800)}${Rt.length>800?"…":""}
    `}).join("");Kt=(typeof bn.generated=="string"?`

    ${bn.generated}

    `:"")+(di.length?`${di}
    `:`
    ${JSON.stringify(bn,null,2).slice(0,1200)}
    `)}else Kt=`
    ${JSON.stringify(bn,null,2).slice(0,2e3)}
    `}}catch{}return`

    ${St.name}

    ${St.kind.replace("_"," ")} · ${St.relative_path}

    `+Kt+"
    "}))).join(`
    +`);V=q.pop()??"";for(const R of q)for(const J of R.split(` +`))if(J.startsWith("data: "))try{const N=JSON.parse(J.slice(6));if(N.text){const X=N.text.toLowerCase().includes("error")||N.text.startsWith("⚠"),Q=N.text.startsWith("✓");g(L=>[...L,{text:N.text,type:X?"error":Q?"success":"output"}])}}catch{}else J.startsWith("event: done")||J.startsWith("event: error")}await C(),t(`${P} complete`,"success")}catch(F){g(W=>[...W,{text:`Failed: ${F instanceof Error?F.message:String(F)}`,type:"error"}]),t(`${P} failed`,"error")}finally{u(!1)}},E=async()=>{if(h!==null){b(null);return}const T=await rj();b(T.packages),j(!0)},k=o==null?void 0:o.venv_exists,D=l?"#9ca3af":k?"#16a34a":"#ef4444",H=l?"checking…":k?`Active · Python ${(o==null?void 0:o.python_version)??"?"}`:"Not found",G=(T,P)=>({padding:"5px 12px",border:"none",borderRadius:5,background:P?"#e5e7eb":T,color:P?"#9ca3af":"#fff",cursor:P?"not-allowed":"pointer",fontSize:12,fontWeight:600});return n.jsxs("section",{style:a5,children:[n.jsx("h3",{style:{margin:"0 0 10px",fontSize:15,fontWeight:600,color:"#111827"},children:"🐍 Python Environment"}),n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10,marginBottom:12,padding:"10px 14px",background:k?"#f0fdf4":"#fef2f2",border:`1px solid ${k?"#86efac":"#fca5a5"}`,borderRadius:7},children:[n.jsx("span",{style:{width:9,height:9,borderRadius:"50%",background:D,flexShrink:0}}),n.jsxs("div",{style:{flex:1},children:[n.jsx("div",{style:{fontSize:13,fontWeight:600,color:"#111827"},children:H}),(o==null?void 0:o.venv_path)&&n.jsx("div",{style:{fontSize:10,color:"#6b7280",fontFamily:"monospace",marginTop:1},children:o.venv_path}),k&&n.jsxs("div",{style:{fontSize:11,color:"#6b7280",marginTop:2},children:[(o==null?void 0:o.pkg_count)??0," packages installed"]})]}),n.jsx("button",{onClick:C,style:{padding:"3px 8px",border:"1px solid #d1d5db",borderRadius:4,background:"#fff",cursor:"pointer",fontSize:11,color:"#6b7280"},children:"⟳"})]}),!k&&!l&&n.jsxs("div",{style:{padding:"12px 14px",background:"#fef3c7",border:"1px solid #fcd34d",borderRadius:6,marginBottom:12,fontSize:12,color:"#92400e"},children:["No virtual environment found. Click ",n.jsx("strong",{children:"Setup venv"})," to create one and install all dependencies."]}),n.jsxs("div",{style:{display:"flex",gap:8,flexWrap:"wrap",marginBottom:12},children:[n.jsx("button",{onClick:()=>S(aj,"Setup venv"),disabled:d,style:G("#16a34a",d),children:"⬇ Setup venv"}),n.jsx("button",{onClick:()=>S(lj,"Rebuild venv"),disabled:d,style:G("#ea580c",d),children:"↺ Rebuild venv"}),n.jsx("button",{onClick:()=>S(cj,"Upgrade deps"),disabled:d||!k,style:G("#2563eb",d||!k),children:"↑ Upgrade deps"}),n.jsx("button",{onClick:E,disabled:!k,style:G("#7c3aed",!k),title:h!==null?"Hide the package list (does not uninstall anything)":"Fetch and show installed packages",children:h!==null?"📦 Hide packages":"📦 Show packages"})]}),p.length>0&&n.jsxs("div",{style:{marginBottom:10},children:[n.jsxs("button",{onClick:()=>v(T=>!T),style:{display:"flex",alignItems:"center",gap:5,background:"none",border:"none",cursor:"pointer",padding:"2px 0",marginBottom:4,fontSize:11,fontWeight:700,color:"#374151",textTransform:"uppercase",letterSpacing:.5},children:[n.jsx("span",{style:{fontSize:9,transition:"transform .15s",transform:y?"rotate(90deg)":"rotate(0deg)"},children:"▶"}),"Install output"]}),y&&n.jsx("div",{ref:_,style:{background:"#0f172a",borderRadius:5,padding:"8px 10px",maxHeight:200,overflowY:"auto",fontFamily:"monospace",fontSize:11},children:p.map((T,P)=>n.jsx("div",{style:{color:T.type==="error"?"#f87171":T.type==="success"?"#86efac":"#e2e8f0",lineHeight:1.6},children:T.text},P))})]}),h&&n.jsxs("div",{children:[n.jsxs("button",{onClick:()=>j(T=>!T),style:{display:"flex",alignItems:"center",gap:5,background:"none",border:"none",cursor:"pointer",padding:"2px 0",marginBottom:4,fontSize:11,fontWeight:700,color:"#374151",textTransform:"uppercase",letterSpacing:.5},children:[n.jsx("span",{style:{fontSize:9,transition:"transform .15s",transform:w?"rotate(90deg)":"rotate(0deg)"},children:"▶"}),"Installed packages (",h.length,")"]}),w&&n.jsx("div",{style:{display:"flex",flexWrap:"wrap",gap:"2px 8px",maxHeight:140,overflowY:"auto"},children:h.map(T=>n.jsxs("span",{style:{fontSize:10,fontFamily:"monospace",color:"#374151"},children:[T.name," ",n.jsx("span",{style:{color:"#9ca3af"},children:T.version})]},T.name))})]})]})}const py="glossa_settings_tab",hy=[{id:"ai",label:"AI",icon:"🤖"},{id:"discovery",label:"Discovery",icon:"🔭"},{id:"notifications",label:"Notifications",icon:"✉️"},{id:"system",label:"System",icon:"⚙️"}];function i5(){const[t,o]=x.useState(()=>{const v=localStorage.getItem(py);return v&&hy.some(w=>w.id===v)?v:"ai"}),r=v=>{o(v),localStorage.setItem(py,v)},[l,c]=x.useState(""),[d,u]=x.useState(""),[p,g]=x.useState(""),[h,b]=x.useState(""),y=async()=>{try{const[v,w]=await Promise.all([ld(),Ba()]);c(v.data_dir),u(w.version??"");const j=w.uptime_seconds??0,_=Math.floor(j/60),C=Math.floor(_/60);g(C>0?`${C}h ${_%60}m`:_>0?`${_}m`:`${Math.round(j)}s`),b("")}catch{}};return x.useEffect(()=>{y()},[]),n.jsxs("div",{style:{maxWidth:760},children:[n.jsx("h2",{style:{marginTop:0,marginBottom:12},children:"Settings"}),n.jsx("div",{style:{display:"flex",gap:2,borderBottom:"2px solid #e5e7eb",marginBottom:20},children:hy.map(v=>n.jsxs("button",{onClick:()=>r(v.id),style:{padding:"8px 16px",border:"none",cursor:"pointer",fontSize:13,fontWeight:t===v.id?700:500,color:t===v.id?"#2563eb":"#6b7280",background:t===v.id?"#eff6ff":"transparent",borderBottom:t===v.id?"2px solid #2563eb":"2px solid transparent",borderRadius:"6px 6px 0 0",marginBottom:-2},children:[v.icon," ",v.label]},v.id))}),h&&n.jsx("div",{style:{...r5,background:"#fef2f2",borderColor:"#fca5a5",color:"#991b1b"},children:h}),t==="ai"&&n.jsxs(n.Fragment,{children:[n.jsx(Vk,{}),n.jsx(Kk,{}),n.jsx(e5,{}),n.jsxs("section",{style:gp,children:[n.jsx("h3",{style:mp,children:"AI Behavior"}),n.jsx("p",{style:os,children:"Control how Glossa AI handles action proposals during chat."}),n.jsx(s5,{})]})]}),t==="discovery"&&n.jsx($k,{}),t==="notifications"&&n.jsx(Mk,{}),t==="system"&&n.jsxs(n.Fragment,{children:[n.jsx(n5,{}),n.jsx(o5,{}),n.jsxs("section",{style:gp,children:[n.jsx("h3",{style:mp,children:"System"}),n.jsx("table",{style:{borderCollapse:"collapse"},children:n.jsxs("tbody",{children:[n.jsx(Gf,{label:"Data directory",value:l||"—",mono:!0}),d&&n.jsx(Gf,{label:"Backend version",value:d}),p&&n.jsx(Gf,{label:"Backend uptime",value:p})]})}),n.jsx("p",{style:{...os,marginTop:10,color:"#9ca3af"},children:"Corpus, sign mapping, and pipeline settings are project-specific. Open or create a project to configure them."})]})]})]})}function o5(){const{toast:t}=nt(),[o,r]=x.useState(!1),l=async()=>{r(!0);try{const c=await x2();y2(),window.dispatchEvent(new CustomEvent("glossa:seq_queue_updated")),t(`${c.cleared_jobs} job(s) cleared — cache reset`,"success")}catch(c){t(c instanceof Error?c.message:"Clear failed","error")}finally{r(!1)}};return n.jsxs("section",{style:gp,children:[n.jsx("h3",{style:mp,children:"🗑 Clear Cache"}),n.jsx("p",{style:os,children:"Removes all non-running jobs from the database (completed, failed, paused, queued) and clears all run-related browser state:"}),n.jsxs("ul",{style:{...os,margin:"6px 0 0 16px",padding:0},children:[n.jsx("li",{children:"Experiment run badges (✓/✗) in the Builder"}),n.jsx("li",{children:"Sequential run queue"}),n.jsx("li",{children:"Dashboard AI insight + applied action state"})]}),n.jsxs("p",{style:{...os,marginTop:8,color:"#9ca3af"},children:[n.jsx("strong",{children:"Running jobs are never affected."})," Use this before re-running experiments to start completely clean."]}),n.jsx("button",{onClick:l,disabled:o,style:{marginTop:12,padding:"6px 16px",border:"none",borderRadius:5,background:o?"#e5e7eb":"#b45309",color:o?"#9ca3af":"#fff",cursor:o?"not-allowed":"pointer",fontSize:13,fontWeight:600},children:o?"Clearing…":"🗑 Clear Cache"})]})}const gy="glossa_auto_approve";function s5(){const{toast:t}=nt(),[o,r]=x.useState(()=>localStorage.getItem(gy)==="true"),l=c=>{r(c),localStorage.setItem(gy,c?"true":"false"),window.dispatchEvent(new CustomEvent("glossa:auto_approve_changed")),t(c?"Auto-approve enabled — Glossa AI will run all actions automatically":"Auto-approve disabled",c?"success":"info")};return n.jsxs("div",{style:{marginTop:12},children:[n.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"12px 14px",borderRadius:7,border:`1px solid ${o?"#fbbf24":"#e5e7eb"}`,background:o?"#fffbeb":"#fafafa"},children:[n.jsxs("div",{children:[n.jsxs("div",{style:{fontSize:13,fontWeight:600,color:o?"#92400e":"#374151",display:"flex",alignItems:"center",gap:6},children:[n.jsx("span",{style:{fontSize:15},children:o?"⚡":"✋"}),"Auto Approve All AI Actions",o&&n.jsx("span",{style:{fontSize:9,padding:"1px 6px",borderRadius:8,background:"#f59e0b",color:"#78350f",fontWeight:700},children:"ACTIVE"})]}),n.jsx("p",{style:{...os,marginTop:3},children:o?"Glossa AI will execute all proposed actions automatically without asking for approval. Click to disable.":"Glossa AI will ask for approval before executing actions. Toggle on to run all actions automatically."})]}),n.jsx("div",{onClick:()=>l(!o),title:o?"Click to disable auto-approve":"Click to enable auto-approve",style:{width:44,height:24,borderRadius:12,cursor:"pointer",flexShrink:0,background:o?"#f59e0b":"#d1d5db",position:"relative",transition:"background 0.2s"},children:n.jsx("div",{style:{position:"absolute",top:3,left:o?23:3,width:18,height:18,borderRadius:"50%",background:"#fff",boxShadow:"0 1px 3px rgba(0,0,0,0.25)",transition:"left 0.2s"}})})]}),n.jsxs("p",{style:{...os,marginTop:6,color:"#9ca3af"},children:["You can also toggle auto-approve per-session from the ",n.jsx("strong",{children:"⚡ AUTO"})," badge in the Glossa AI chat header, or via the ",n.jsx("strong",{children:"▾"})," dropdown on any Approve button."]})]})}function Gf({label:t,value:o,mono:r}){return n.jsxs("tr",{children:[n.jsx("td",{style:{padding:"3px 16px 3px 0",fontSize:13,color:"#6b7280",whiteSpace:"nowrap"},children:t}),n.jsx("td",{style:{padding:"3px 0",fontSize:13,fontFamily:r?"monospace":void 0},children:o})]})}const gp={marginBottom:"2rem",padding:"1.25rem",border:"1px solid #e5e7eb",borderRadius:8},mp={margin:"0 0 0.75rem 0",fontSize:15,fontWeight:600,color:"#111827"},os={margin:0,fontSize:12,color:"#6b7280",lineHeight:1.5},r5={padding:"10px 14px",borderRadius:6,border:"1px solid",marginBottom:"1rem",fontSize:13},a5={marginBottom:"2rem",padding:"1.25rem",border:"1px solid #d1fae5",borderRadius:8,background:"#fafffe"},ma="glossa_active_project",my="__global__",Pb=x.createContext({activeProject:null,projects:[],setActiveProject:async()=>{},refreshProjects:async()=>{},loading:!0});function l5({children:t}){const[o,r]=x.useState([]),[l,c]=x.useState(null),[d,u]=x.useState(!0),p=x.useCallback(async()=>{try{const h=await Mb();r(h);const b=localStorage.getItem(ma);let y=null;const v=b===my;if(b&&!v&&(y=h.find(w=>w.id===b)??null),!y)try{const w=await zj();y=h.find(j=>j.id===w.id)??null}catch{}!y&&h.length===1&&!v&&(y=h[0]),c(y),y&&localStorage.setItem(ma,y.id)}catch{}finally{u(!1)}},[]);x.useEffect(()=>{p()},[p]),x.useEffect(()=>{const h=()=>{p()};return window.addEventListener("glossa:project-changed",h),()=>window.removeEventListener("glossa:project-changed",h)},[p]);const g=x.useCallback(async h=>{if(h===null)c(null),localStorage.setItem(ma,my);else{try{await Db(h)}catch{}const b=o.find(y=>y.id===h)??null;c(b),b?localStorage.setItem(ma,b.id):localStorage.removeItem(ma)}window.dispatchEvent(new CustomEvent("glossa:project-changed"))},[o]);return n.jsx(Pb.Provider,{value:{activeProject:l,projects:o,setActiveProject:g,refreshProjects:p,loading:d},children:t})}function zo(){return x.useContext(Pb)}function xy(t){return t.replace(/^### (.+)$/gm,'

    $1

    ').replace(/^## (.+)$/gm,'

    $1

    ').replace(/^# (.+)$/gm,'

    $1

    ').replace(/\*\*(.+?)\*\*/g,"$1").replace(/\*(.+?)\*/g,"$1").replace(/^\| (.+) \|$/gm,o=>""+o.split("|").filter(l=>l.trim()).map(l=>`${l.trim()}`).join("")+"").replace(/(.*?<\/tr>\n?)+/gs,o=>`${o}
    `).replace(/^- (.+)$/gm,'
  • $1
  • ').replace(/(\n?)+/gs,'
      $1
    ').replace(/^(?!<[a-z])(.+)$/gm,'

    $1

    ').replace(/```[\s\S]*?```/g,o=>`
    ${o.replace(/```\w*/g,"").trim()}
    `)}const yy=new Set(["data","document"]),by=new Set(["report"]),xa={report:"PDF Report",data:"Data",document:"Document"},vy={report:"#dc2626",data:"#2563eb",document:"#7c3aed"};function Sy({label:t,options:o,selected:r,onChange:l,colorMap:c}){const[d,u]=x.useState(!1),[p,g]=x.useState(""),h=x.useRef(null);x.useEffect(()=>{if(!d)return;const w=j=>{h.current&&!h.current.contains(j.target)&&u(!1)};return document.addEventListener("mousedown",w),()=>document.removeEventListener("mousedown",w)},[d]);const b=w=>{const j=new Set(r);j.has(w)?j.delete(w):j.add(w),l(j)},y=o.filter(w=>!p||w.toLowerCase().includes(p.toLowerCase())),v=r.size;return n.jsxs("div",{ref:h,style:{position:"relative"},children:[n.jsxs("button",{onClick:()=>u(w=>!w),style:{display:"flex",alignItems:"center",gap:5,padding:"4px 10px",border:`1px solid ${v>0?"#2563eb":"#d1d5db"}`,borderRadius:6,background:v>0?"#eff6ff":"#fff",cursor:"pointer",fontSize:12,color:"#374151",whiteSpace:"nowrap"},children:[n.jsxs("span",{style:{fontSize:11,color:"#6b7280"},children:[t,":"]}),v===0?n.jsx("span",{style:{color:"#9ca3af"},children:"All"}):n.jsxs("span",{style:{fontWeight:700,color:"#2563eb"},children:[v," selected"]}),n.jsx("span",{style:{fontSize:9,color:"#9ca3af"},children:d?"▲":"▼"})]}),d&&n.jsxs("div",{style:{position:"absolute",top:"calc(100% + 4px)",left:0,zIndex:200,background:"#fff",border:"1px solid #e5e7eb",borderRadius:8,boxShadow:"0 8px 24px rgba(0,0,0,0.12)",minWidth:200,maxHeight:280,display:"flex",flexDirection:"column"},children:[o.length>6&&n.jsx("div",{style:{padding:"6px 8px",borderBottom:"1px solid #f3f4f6"},children:n.jsx("input",{value:p,onChange:w=>g(w.target.value),placeholder:"Search\\u2026",style:{width:"100%",border:"1px solid #e5e7eb",borderRadius:4,padding:"3px 7px",fontSize:11,outline:"none",boxSizing:"border-box"},autoFocus:!0})}),n.jsxs("button",{onClick:()=>l(new Set),style:{padding:"6px 12px",border:"none",background:"none",textAlign:"left",cursor:"pointer",fontSize:11,color:v===0?"#2563eb":"#374151",fontWeight:v===0?700:400,borderBottom:"1px solid #f3f4f6"},children:[v===0?"✔ ":""," All (",o.length,")"]}),n.jsxs("div",{style:{overflowY:"auto",flex:1},children:[y.map(w=>{const j=(c==null?void 0:c[w])??"#2563eb",_=r.has(w);return n.jsxs("button",{onClick:()=>b(w),style:{display:"flex",alignItems:"center",gap:8,width:"100%",padding:"6px 12px",border:"none",background:_?j+"10":"none",cursor:"pointer",textAlign:"left",fontSize:11,borderBottom:"1px solid #f9fafb"},children:[n.jsx("span",{style:{width:14,height:14,borderRadius:3,border:`2px solid ${_?j:"#d1d5db"}`,background:_?j:"#fff",flexShrink:0,display:"flex",alignItems:"center",justifyContent:"center"},children:_&&n.jsx("span",{style:{color:"#fff",fontSize:9,fontWeight:700},children:"\\u2713"})}),n.jsx("span",{style:{flex:1,color:_?j:"#374151",fontWeight:_?600:400},children:w})]},w)}),y.length===0&&n.jsx("div",{style:{padding:"8px 12px",color:"#9ca3af",fontSize:11},children:"No matches"})]}),v>0&&n.jsx("button",{onClick:()=>{l(new Set),u(!1)},style:{padding:"5px 12px",border:"none",background:"none",borderTop:"1px solid #f3f4f6",cursor:"pointer",fontSize:10,color:"#6b7280",textAlign:"left"},children:"Clear selection"})]}),v>0&&n.jsx("div",{style:{display:"flex",gap:3,flexWrap:"wrap",marginTop:4},children:Array.from(r).map(w=>n.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:3,padding:"1px 6px",borderRadius:10,fontSize:10,fontWeight:600,background:((c==null?void 0:c[w])??"#2563eb")+"18",color:(c==null?void 0:c[w])??"#2563eb",border:`1px solid ${(c==null?void 0:c[w])??"#2563eb"}30`},children:[w,n.jsx("button",{onClick:()=>b(w),style:{border:"none",background:"none",cursor:"pointer",color:"inherit",fontSize:11,padding:0,lineHeight:1},children:"\\u00d7"})]},w))})]})}function c5(){const{activeProject:t}=zo(),o=(t==null?void 0:t.id)??null,[r,l]=x.useState([]),[c,d]=x.useState(!0),[u,p]=x.useState(null),[g,h]=x.useState("reports"),[b,y]=x.useState(""),[v,w]=x.useState(new Set),[j,_]=x.useState(new Set),[C,S]=x.useState("updated_at"),[E,k]=x.useState("desc"),[D,H]=x.useState(!0),[G,T]=x.useState(null),[P,F]=x.useState(!1),[W,M]=x.useState([]),[V,I]=x.useState(""),[A,q]=x.useState(!1),[R,J]=x.useState(null),N=async()=>{J(null),F(!0);try{const oe=await j2();M(oe),oe.length>0&&I(oe[0].id)}catch{M([])}},X=async()=>{if(V){q(!0),J(null);try{const oe=await k2(V);J(oe.message),setTimeout(()=>{F(!1),J(null),de()},3e3)}catch(oe){J(oe instanceof Error?oe.message:"Generation failed")}finally{q(!1)}}},[Q,L]=x.useState(!1),[B,$]=x.useState(new Set),[Y,O]=x.useState(!1),[K,ne]=x.useState(null),se=async()=>{const oe=r.filter(Ne=>B.has(Ne.id));if(oe.length){O(!0);try{const Ne=await Promise.all(oe.map(async mt=>{const St=Lf(mt.id);try{const Ht=await fetch(St);if(Ht.ok){const Kt=await Ht.json();return{name:mt.name,filename:mt.relative_path,data:Kt}}}catch{}return{name:mt.name,filename:mt.relative_path,data:{}}})),We=await jb({report_contents:Ne,title:oe.length===1?`Analysis: ${oe[0].name}`:`Synthesis of ${oe.length} Reports`});ne(We)}catch(Ne){alert(Ne instanceof Error?Ne.message:"AI report generation failed. Check that a language model is configured in Settings.")}finally{O(!1)}}},pe=oe=>$(Ne=>{const We=new Set(Ne);return We.has(oe)?We.delete(oe):We.add(oe),We}),[_e,Se]=x.useState(()=>{try{return new Set(JSON.parse(localStorage.getItem("glossa_starred_reports")??"[]"))}catch{return new Set}}),ke=oe=>{Se(Ne=>{const We=new Set(Ne);return We.has(oe)?We.delete(oe):We.add(oe),localStorage.setItem("glossa_starred_reports",JSON.stringify([...We])),We})},te=async()=>{const oe=r.filter(St=>B.has(St.id));if(!oe.length)return;const We=(await Promise.all(oe.map(async St=>{const Ht=Lf(St.id);let Kt=`Open source file →`;try{const _i=await fetch(Ht);if(_i.ok&&St.kind==="data"){const bn=await _i.json();if(bn.results&&typeof bn.results=="object"){const di=Object.entries(bn.results).map(([Qi,gn])=>{const Rt=typeof gn=="object"?JSON.stringify(gn,null,2):String(gn);return`${Qi.replace(/_/g," ")}
    ${Rt.slice(0,800)}${Rt.length>800?"…":""}
    `}).join("");Kt=(typeof bn.generated=="string"?`

    ${bn.generated}

    `:"")+(di.length?`${di}
    `:`
    ${JSON.stringify(bn,null,2).slice(0,1200)}
    `)}else Kt=`
    ${JSON.stringify(bn,null,2).slice(0,2e3)}
    `}}catch{}return`

    ${St.name}

    ${St.kind.replace("_"," ")} · ${St.relative_path}

    `+Kt+"
    "}))).join(`
    `),mt=window.open("","_blank","width=920,height=940");if(!mt){alert("Allow popups from localhost in your browser settings, then try again.");return}mt.document.write(`Glossa Lab — Research Report

    Glossa Lab — Research Report

    Generated ${new Date().toLocaleString()} · ${oe.length} report${oe.length!==1?"s":""}


    `+We+" + -
    +
    diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index c643376a..59116219 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -12,7 +12,7 @@ import { HypothesisTracker } from "./components/HypothesisTracker"; import { ResearchNotebook } from "./components/ResearchNotebook"; import { AIToolsView } from "./components/AIToolsView"; import { HelpView } from "./components/HelpView"; -import { SignDictionary } from "./components/SignDictionary"; +import { SignsView } from "./components/SignsView"; import { TimelineView } from "./components/TimelineView"; import { CitationManager } from "./components/CitationManager"; import { DashboardView } from "./components/DashboardView"; @@ -695,7 +695,7 @@ function AppContent() { {tab === "hypotheses" && } {tab === "notebooks" && } {tab === "ai-tools" && } - {tab === "signs" && } + {tab === "signs" && } {tab === "timeline" && setTab(t as Tab)} />} {tab === "citations" && } {tab === "correspondence" && } diff --git a/frontend/src/api.ts b/frontend/src/api.ts index d84a51dc..ac79ead9 100644 --- a/frontend/src/api.ts +++ b/frontend/src/api.ts @@ -2561,3 +2561,76 @@ export const uploadIndusPaper = (file: File): Promise => { fd.append("file", file); return fetch(`${BASE}/indus-evidence/upload`, { method: "POST", body: fd }); }; + +// ── Signs API ──────────────────────────────────────────────────────────── + +export interface SignSource { + experiment: string; + phase: number | null; + job_id: string | null; + report_ref: string; + staging_entry: string | null; + dedr_ref: string; + dedr_source: string; +} + +export interface SignEntry { + sign_id: string; + reading: string; + confidence: "HIGH" | "MEDIUM" | "LOW" | "UNCERTAIN"; + in_corpus: boolean; + corpus_freq: number; + evidence_type: string; + evidence_score: number; + basis: string; + gloss: string; + source: SignSource; + wells_ids: string[]; + mahadevan_ids: string[]; + numbering_system: string; +} + +export interface SignsSummary { + total: number; + deciphered: number; + undeciphered: number; + icit_total: number; + high: number; + medium: number; + low: number; + in_corpus: number; +} + +export interface SignsListResponse { + items: SignEntry[]; + total: number; + limit: number; + offset: number; +} + +export const getSignsSummary = (): Promise => + request("GET", "/signs/summary"); + +export const listSigns = ( + params: { + deciphered?: boolean; + confidence?: string; + in_corpus?: boolean; + search?: string; + limit?: number; + offset?: number; + } = {}, +): Promise => { + const qs = new URLSearchParams(); + if (params.deciphered !== undefined) qs.set("deciphered", String(params.deciphered)); + if (params.confidence) qs.set("confidence", params.confidence); + if (params.in_corpus !== undefined) qs.set("in_corpus", String(params.in_corpus)); + if (params.search) qs.set("search", params.search); + if (params.limit !== undefined) qs.set("limit", String(params.limit)); + if (params.offset !== undefined) qs.set("offset", String(params.offset)); + const q = qs.toString(); + return request("GET", `/signs${q ? `?${q}` : ""}`); +}; + +export const getSign = (signId: string): Promise => + request("GET", `/signs/${encodeURIComponent(signId)}`); diff --git a/frontend/src/components/CorpusAnalyticsPanel.tsx b/frontend/src/components/CorpusAnalyticsPanel.tsx new file mode 100644 index 00000000..aefc7c64 --- /dev/null +++ b/frontend/src/components/CorpusAnalyticsPanel.tsx @@ -0,0 +1,153 @@ +/** + * CorpusAnalyticsPanel — displays the world language corpus catalogue + * with language family, script type, token count, reading direction, + * Indus sign overlap, and a placeholder contact score column. + */ +import { useEffect, useMemo, useState } from "react"; +import { + listCorpusCatalogue, + type CorpusCatalogueEntry, +} from "../api"; + +function OverlapBar({ pct }: { pct: number }) { + const clamp = Math.min(100, Math.max(0, pct)); + const color = clamp > 60 ? "#22c55e" : clamp > 30 ? "#eab308" : "#ef4444"; + return ( +
    +
    +
    +
    + + {clamp.toFixed(0)}% + +
    + ); +} + +export function CorpusAnalyticsPanel() { + const [entries, setEntries] = useState([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + // Filters + const [langFilter, setLangFilter] = useState(""); + const [scriptFilter, setScriptFilter] = useState(""); + + useEffect(() => { + setLoading(true); + listCorpusCatalogue() + .then(setEntries) + .catch(e => setError(e instanceof Error ? e.message : "Failed to load catalogue")) + .finally(() => setLoading(false)); + }, []); + + const langFamilies = useMemo(() => { + const set = new Set(entries.map(e => e.language_family).filter(Boolean)); + return Array.from(set).sort(); + }, [entries]); + + const scriptTypes = useMemo(() => { + const set = new Set(entries.map(e => e.script_type).filter(Boolean)); + return Array.from(set).sort(); + }, [entries]); + + const filtered = useMemo(() => { + return entries.filter(e => { + if (langFilter && e.language_family !== langFilter) return false; + if (scriptFilter && e.script_type !== scriptFilter) return false; + return true; + }); + }, [entries, langFilter, scriptFilter]); + + // Simulate overlap % using a hash of the name for now (placeholder until + // real overlap data is available from experiment results). + function overlapPct(entry: CorpusCatalogueEntry): number { + if (entry.is_undeciphered) return 100; // Indus itself + let h = 0; + for (let i = 0; i < entry.name.length; i++) h = ((h << 5) - h + entry.name.charCodeAt(i)) | 0; + return Math.abs(h) % 40; // 0-39% range for non-Indus corpora + } + + if (loading) return
    Loading corpus catalogue…
    ; + if (error) return
    {error}
    ; + + return ( +
    +

    📊 Corpus Analytics

    +

    + World language corpus catalogue — {entries.length} corpora. Overlap shows percentage of Indus signs appearing in each corpus. +

    + + {/* Filters */} +
    + + + {filtered.length} corpora +
    + + {/* Table */} +
    + + + + {["Name", "Language Family", "Script", "Tokens", "Direction", "Overlap", "Contact Score"].map(h => ( + + ))} + + + + {filtered.map(e => ( + + + + + + + + + + ))} + +
    + {h} +
    + {e.name} + {e.is_undeciphered ? ( + UNDECIPHERED + ) : null} + {e.language_family || "—"}{e.script_type || "—"}{e.tokens_approx > 0 ? e.tokens_approx.toLocaleString() : "—"}{e.reading_direction || "—"} + +
    +
    + + {filtered.length === 0 && ( +
    No corpora match the current filters.
    + )} +
    + ); +} diff --git a/frontend/src/components/DashboardView.tsx b/frontend/src/components/DashboardView.tsx index 9b5bfaee..7f22efd9 100644 --- a/frontend/src/components/DashboardView.tsx +++ b/frontend/src/components/DashboardView.tsx @@ -779,6 +779,20 @@ export function DashboardView() { }, `decipher-${label.slice(0, 30)}`) } /> + {/* Quick link to full Signs view */} +
    + +
    + {/* Integrated Research Loop */} diff --git a/frontend/src/components/SignsView.tsx b/frontend/src/components/SignsView.tsx new file mode 100644 index 00000000..73a0d51c --- /dev/null +++ b/frontend/src/components/SignsView.tsx @@ -0,0 +1,401 @@ +/** + * SignsView — browse all deciphered/undeciphered signs with confidence + * filters, search, glyph placeholders, and full cross-references to + * experiments, DEDR entries, and reports. + */ +import { useCallback, useEffect, useState } from "react"; +import { + getSignsSummary, + listSigns, + type SignEntry, + type SignsSummary, +} from "../api"; +import { CorpusAnalyticsPanel } from "./CorpusAnalyticsPanel"; + +// ── SignGlyph placeholder ─────────────────────────────────────────────── +function hashCode(s: string): number { + let h = 0; + for (let i = 0; i < s.length; i++) h = ((h << 5) - h + s.charCodeAt(i)) | 0; + return Math.abs(h); +} + +const GLYPH_HUES = [210, 30, 150, 340, 60, 270, 190, 20, 300, 120]; + +function SignGlyph({ sign_id, size = 56 }: { sign_id: string; size?: number }) { + const hue = GLYPH_HUES[hashCode(sign_id) % GLYPH_HUES.length]; + const bg = `hsl(${hue}, 25%, 18%)`; + const fg = `hsl(${hue}, 50%, 75%)`; + const border = `hsl(${hue}, 30%, 30%)`; + return ( + + + 4 ? "11" : "14"} + fill={fg} + letterSpacing="0.5" + > + {sign_id} + + + ); +} + +// ── Confidence chip ───────────────────────────────────────────────────── +const CONF_COLORS: Record = { + HIGH: { bg: "#052e16", fg: "#4ade80", border: "#16a34a" }, + MEDIUM: { bg: "#1c1917", fg: "#fbbf24", border: "#d97706" }, + LOW: { bg: "#1c1917", fg: "#f87171", border: "#dc2626" }, + UNCERTAIN: { bg: "#1e293b", fg: "#94a3b8", border: "#475569" }, +}; + +function ConfChip({ level }: { level: string }) { + const c = CONF_COLORS[level] ?? CONF_COLORS.UNCERTAIN; + return ( + + ●{level} + + ); +} + +// ── Filter chips ──────────────────────────────────────────────────────── +type ConfLevel = "HIGH" | "MEDIUM" | "LOW" | "Undeciphered"; + +function FilterChip({ label, active, onClick }: { label: string; active: boolean; onClick: () => void }) { + return ( + + ); +} + +// ── Sign Card ─────────────────────────────────────────────────────────── +function SignCard({ sign, onClick }: { sign: SignEntry; onClick?: () => void }) { + const phase = sign.source?.phase; + const dedr = sign.source?.dedr_ref; + const expName = sign.source?.experiment || ""; + // Truncate long experiment names + const shortExp = expName.length > 30 ? expName.slice(0, 30) + "…" : expName; + + return ( +
    { e.currentTarget.style.borderColor = "#3b82f6"; e.currentTarget.style.boxShadow = "0 0 0 1px #3b82f680"; }} + onMouseLeave={e => { e.currentTarget.style.borderColor = "rgba(255,255,255,0.08)"; e.currentTarget.style.boxShadow = "none"; }} + > + {/* Top row: glyph + id + reading + confidence */} +
    + +
    +
    + + {sign.sign_id} + + +
    + {sign.reading && ( +
    + Reading: {sign.reading} +
    + )} + {sign.corpus_freq > 0 && ( +
    + Corpus freq: {sign.corpus_freq.toLocaleString()} +
    + )} +
    +
    + + {/* Divider */} +
    + + {/* Cross-reference section */} +
    + {phase != null && phase > 0 && ( +
    Source: Phase {phase} Anchored SA
    + )} + {dedr && ( +
    Evidence: {dedr}{sign.gloss ? ` (${sign.gloss})` : ""}
    + )} + {shortExp && ( +
    Experiment: {shortExp}
    + )} + {sign.basis && !dedr && ( +
    + {sign.basis.length > 80 ? sign.basis.slice(0, 80) + "…" : sign.basis} +
    + )} +
    + + {/* Action buttons */} +
    + {sign.source?.report_ref && ( + + )} + {expName && ( + + )} +
    +
    + ); +} + +// ── Detail panel ──────────────────────────────────────────────────────── +function SignDetail({ sign, onClose }: { sign: SignEntry; onClose: () => void }) { + return ( +
    +
    +

    Sign {sign.sign_id}

    + +
    + +
    + +
    + + {sign.reading &&
    {sign.reading}
    } + {sign.gloss &&
    {sign.gloss}
    } +
    +
    + + {/* Fields */} + {[ + ["Corpus Frequency", sign.corpus_freq > 0 ? sign.corpus_freq.toLocaleString() : "—"], + ["In Corpus", sign.in_corpus ? "Yes" : "No"], + ["Evidence Type", sign.evidence_type || "—"], + ["Evidence Score", sign.evidence_score > 0 ? sign.evidence_score.toFixed(3) : "—"], + ["Numbering System", sign.numbering_system || "—"], + ["Phase", sign.source?.phase?.toString() || "—"], + ["Source Experiment", sign.source?.experiment || "—"], + ["DEDR Reference", sign.source?.dedr_ref || "—"], + ["Report", sign.source?.report_ref || "—"], + ].map(([k, v]) => ( +
    + {k} + {v} +
    + ))} + + {sign.basis && ( +
    +
    Basis
    +

    {sign.basis}

    +
    + )} +
    + ); +} + +// ── Main component ────────────────────────────────────────────────────── +export function SignsView() { + const [summary, setSummary] = useState(null); + const [signs, setSigns] = useState([]); + const [total, setTotal] = useState(0); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + // Filters + const [confFilters, setConfFilters] = useState>(new Set()); + const [search, setSearch] = useState(""); + const [inCorpusOnly, setInCorpusOnly] = useState(false); + const [offset, setOffset] = useState(0); + const [selected, setSelected] = useState(null); + const [activeTab, setActiveTab] = useState<"signs" | "corpus">("signs"); + + const limit = 100; + + // Load summary on mount + useEffect(() => { + getSignsSummary().then(setSummary).catch(() => {}); + }, []); + + // Load signs with filters + const loadSigns = useCallback(async () => { + setLoading(true); + setError(null); + try { + const confParam = confFilters.size > 0 + ? Array.from(confFilters).filter(c => c !== "Undeciphered").join(",") + : undefined; + const deciphered = confFilters.has("Undeciphered") && confFilters.size === 1 ? false : undefined; + + const resp = await listSigns({ + confidence: confParam || undefined, + search: search || undefined, + in_corpus: inCorpusOnly ? true : undefined, + deciphered, + limit, + offset, + }); + setSigns(resp.items); + setTotal(resp.total); + } catch (e) { + setError(e instanceof Error ? e.message : "Failed to load signs"); + } finally { + setLoading(false); + } + }, [confFilters, search, inCorpusOnly, offset]); + + useEffect(() => { void loadSigns(); }, [loadSigns]); + + const toggleConf = (level: ConfLevel) => { + setConfFilters(prev => { + const next = new Set(prev); + if (next.has(level)) next.delete(level); else next.add(level); + return next; + }); + setOffset(0); + }; + + const totalPages = Math.ceil(total / limit); + const currentPage = Math.floor(offset / limit) + 1; + + return ( +
    + {/* Header */} +
    +

    + 🔣 Signs +

    + {summary && ( +
    + {summary.deciphered} deciphered + · + {summary.undeciphered} undeciphered + · + {summary.icit_total} known + · + {summary.in_corpus} in corpus +
    + )} +
    + + {/* Tab bar */} +
    + {(["signs", "corpus"] as const).map(t => ( + + ))} +
    + + {activeTab === "corpus" ? ( + + ) : ( + <> + {/* Filter bar */} +
    + {(["HIGH", "MEDIUM", "LOW", "Undeciphered"] as ConfLevel[]).map(level => ( + toggleConf(level)} /> + ))} + { setSearch(e.target.value); setOffset(0); }} + style={{ + padding: "5px 12px", borderRadius: 6, fontSize: 12, width: 220, + border: "1px solid rgba(255,255,255,0.1)", background: "rgba(255,255,255,0.04)", + color: "#e2e8f0", outline: "none", + }} + /> + + {total} signs +
    + + {/* Error / loading */} + {error &&
    {error}
    } + + {/* Sign grid */} + {loading && signs.length === 0 ? ( +
    Loading signs…
    + ) : ( +
    + {signs.map(s => ( + setSelected(s)} /> + ))} +
    + )} + + {/* Pagination */} + {totalPages > 1 && ( +
    + + Page {currentPage} of {totalPages} + +
    + )} + + )} + + {/* Detail slide-over */} + {selected && setSelected(null)} />} +
    + ); +} diff --git a/frontend/tsconfig.tsbuildinfo b/frontend/tsconfig.tsbuildinfo index acff1bd0..6bf722fd 100644 --- a/frontend/tsconfig.tsbuildinfo +++ b/frontend/tsconfig.tsbuildinfo @@ -1 +1 @@ -{"root":["./src/app.tsx","./src/api.ts","./src/dateformat.ts","./src/main.tsx","./src/vite-env.d.ts","./src/components/ag2panel.tsx","./src/components/aichatview.tsx","./src/components/aichatwindow.tsx","./src/components/aitoolsview.tsx","./src/components/bottompanel.tsx","./src/components/citationmanager.tsx","./src/components/collaborationpanel.tsx","./src/components/commandpalette.tsx","./src/components/corporaview.tsx","./src/components/corpusselector.tsx","./src/components/correspondenceview.tsx","./src/components/dashboardview.tsx","./src/components/deciphermentpanel.tsx","./src/components/entropychart.tsx","./src/components/entropydashboard.tsx","./src/components/errorboundary.tsx","./src/components/experimentbuilderview.tsx","./src/components/experimentsview.tsx","./src/components/foundationcheckview.tsx","./src/components/helpview.tsx","./src/components/hypothesistracker.tsx","./src/components/indusevidenceview.tsx","./src/components/jobsview.tsx","./src/components/notificationdrawer.tsx","./src/components/pipelinesview.tsx","./src/components/presetsview.tsx","./src/components/projectsview.tsx","./src/components/reportsview.tsx","./src/components/researchlooppanel.tsx","./src/components/researchnotebook.tsx","./src/components/resultsview.tsx","./src/components/settingsview.tsx","./src/components/signdictionary.tsx","./src/components/statusview.tsx","./src/components/studiesview.tsx","./src/components/studybuilderview.tsx","./src/components/timelineview.tsx","./src/components/discovery/discoveryview.tsx","./src/components/notifications/notificationspanel.tsx","./src/components/settings/aiendpointspanel.tsx","./src/components/settings/aiprofilespanel.tsx","./src/components/settings/autodiscoverypanel.tsx","./src/components/settings/modelassignmentspanel.tsx","./src/components/settings/modelhubpanel.tsx","./src/components/settings/providerspanel.tsx","./src/hooks/useaichat.tsx","./src/hooks/usecontextmenu.tsx","./src/hooks/useproject.tsx","./src/hooks/usetoast.tsx","./src/utils/autoarrange.ts"],"version":"5.7.3"} \ No newline at end of file +{"root":["./src/app.tsx","./src/api.ts","./src/dateformat.ts","./src/main.tsx","./src/vite-env.d.ts","./src/components/ag2panel.tsx","./src/components/aichatview.tsx","./src/components/aichatwindow.tsx","./src/components/aitoolsview.tsx","./src/components/bottompanel.tsx","./src/components/citationmanager.tsx","./src/components/collaborationpanel.tsx","./src/components/commandpalette.tsx","./src/components/corporaview.tsx","./src/components/corpusanalyticspanel.tsx","./src/components/corpusselector.tsx","./src/components/correspondenceview.tsx","./src/components/dashboardview.tsx","./src/components/deciphermentpanel.tsx","./src/components/entropychart.tsx","./src/components/entropydashboard.tsx","./src/components/errorboundary.tsx","./src/components/experimentbuilderview.tsx","./src/components/experimentsview.tsx","./src/components/foundationcheckview.tsx","./src/components/helpview.tsx","./src/components/hypothesistracker.tsx","./src/components/indusevidenceview.tsx","./src/components/jobsview.tsx","./src/components/notificationdrawer.tsx","./src/components/pipelinesview.tsx","./src/components/presetsview.tsx","./src/components/projectsview.tsx","./src/components/reportsview.tsx","./src/components/researchlooppanel.tsx","./src/components/researchnotebook.tsx","./src/components/resultsview.tsx","./src/components/settingsview.tsx","./src/components/signdictionary.tsx","./src/components/signsview.tsx","./src/components/statusview.tsx","./src/components/studiesview.tsx","./src/components/studybuilderview.tsx","./src/components/timelineview.tsx","./src/components/discovery/discoveryview.tsx","./src/components/notifications/notificationspanel.tsx","./src/components/settings/aiendpointspanel.tsx","./src/components/settings/aiprofilespanel.tsx","./src/components/settings/autodiscoverypanel.tsx","./src/components/settings/modelassignmentspanel.tsx","./src/components/settings/modelhubpanel.tsx","./src/components/settings/providerspanel.tsx","./src/hooks/useaichat.tsx","./src/hooks/usecontextmenu.tsx","./src/hooks/useproject.tsx","./src/hooks/usetoast.tsx","./src/utils/autoarrange.ts"],"version":"5.7.3"} \ No newline at end of file