commit b73ff9465c419ff888c380e67a296109242f670b Author: mo Date: Fri Jul 17 04:00:38 2026 +0200 Initial import of Dell OpenManage Cockpit for ATC. Interactive OME fleet UI with topology, KPI popups, in-browser SSH, chat, tickets, and full inventory landscape. diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..a5d0ff6 --- /dev/null +++ b/.env.example @@ -0,0 +1,14 @@ +OME_URL=https://cov-omeprod01.dell-atc.lan +OME_USER=admin +OME_PASSWORD=CHANGE_ME +POLL_INTERVAL=12 +OPENWEBUI_URL=http://atc-portal01.dell-atc.lan:3080 +CORS_ORIGINS=* +GPU_METRICS_URL=http://10.0.10.106:9110 +VLLM_URL=http://10.0.10.106:8000/v1 +VLLM_MODEL=llama3-70b-gptq +COCKPIT_DATA=/data +OPENWEBUI_EMAIL=mohamed.el.kadi@dell.com +OPENWEBUI_PASSWORD=CHANGE_ME +VLLM_MAX_TOKENS=700 +CHAT_SYSTEM_CHARS=5500 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5b43fe7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +.env +data/ +*.db +*.db-journal +__pycache__/ +*.pyc +*.bak* +ui/ome-cockpit-* +.DS_Store diff --git a/DEMO.md b/DEMO.md new file mode 100644 index 0000000..35a5341 --- /dev/null +++ b/DEMO.md @@ -0,0 +1,11 @@ +# OME Cockpit — demo path + +URL: http://atc-portal01.dell-atc.lan:3090 + +1. Watch live pulse lines from OME hub to connected iDRACs/servers +2. Filter a subnet (10.0.40 / 10.0.41) in the left rail +3. Click a glowing node → inspector (IP, model, service tag, power) +4. Click **OpenManage AI** → chat drawer with OME Copilot +5. Use **Connected only** to focus the live fabric + +OpenManage AI standalone remains at :3080 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..6b1194d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,9 @@ +FROM python:3.12-slim +WORKDIR /app +COPY api/requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt +COPY api/main.py /app/main.py +COPY ui /ui +# main.py expects ../ui from api parent — adjust path: STATIC_DIR = /ui +ENV PYTHONUNBUFFERED=1 +CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8090"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..6842158 --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ +# Dell OpenManage Cockpit (ATC) + +Interactive fleet operations UI for Dell OpenManage Enterprise. + +## Features +- Live topology (Orbit / Galaxy / Clusters / Lanes / Helix) +- KPI context popups, triage, ops desk tickets +- In-browser SSH terminal (own username/password) +- Cockpit chat against vLLM / OpenManage AI models +- Full inventory + application/firmware landscape from OME + +## Run +```bash +cp .env.example .env # fill OME + vLLM settings +docker compose up -d --build +``` + +UI: `http://:3090` + +## Layout +- `api/main.py` — FastAPI (OME poll, chat, SSH bridge, tickets) +- `ui/` — static frontend +- `docker-compose.yml` / `Dockerfile` diff --git a/api/Dockerfile b/api/Dockerfile new file mode 100644 index 0000000..1ecbcf9 --- /dev/null +++ b/api/Dockerfile @@ -0,0 +1,9 @@ +FROM python:3.12-slim +WORKDIR /app +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt +COPY main.py . +# UI copied at compose build context level +COPY ../ui /ui +ENV PYTHONUNBUFFERED=1 +CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8090"] diff --git a/api/main.py b/api/main.py new file mode 100644 index 0000000..42e6b2f --- /dev/null +++ b/api/main.py @@ -0,0 +1,1576 @@ + +import asyncio +import json +import os +import sqlite3 +import ipaddress +import logging +import time +from collections import defaultdict +from pathlib import Path +from typing import Any + +import httpx +import asyncssh +from fastapi import FastAPI, WebSocket, WebSocketDisconnect, HTTPException +from fastapi.middleware.cors import CORSMiddleware +from fastapi.responses import FileResponse, Response +from pydantic import BaseModel, Field +from pydantic_settings import BaseSettings + +logging.basicConfig(level=logging.INFO) +log = logging.getLogger("ome-cockpit") + + +class Settings(BaseSettings): + ome_url: str = "https://cov-omeprod01.dell-atc.lan" + ome_user: str = "admin" + ome_password: str = "" + poll_interval: float = 15.0 + openwebui_url: str = "http://atc-portal01.dell-atc.lan:3080" + cors_origins: str = "*" + power_fetch_limit: int = 40 + gpu_metrics_url: str = "http://10.0.10.106:9110" + vllm_url: str = "http://10.0.10.106:8000/v1" + vllm_model: str = "llama3-70b-gptq" + vllm_max_model_len: int = 4096 + vllm_max_tokens: int = 700 + chat_system_chars: int = 5500 + openwebui_email: str = "" + openwebui_password: str = "" + cockpit_data: str = "/data" + + class Config: + env_file = ".env" + + +settings = Settings() +app = FastAPI(title="OME Cockpit API", version="1.2.0") +app.add_middleware( + CORSMiddleware, + allow_origins=[o.strip() for o in settings.cors_origins.split(",")], + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + +STATE: dict[str, Any] = { + "updated_at": 0, + "ome": {}, + "summary": {}, + "subnets": [], + "devices": [], + "groups": [], + "models": [], + "alerts": [], + "events": [], + "context": {}, + "gpu": {}, + "pulse": 0, + "openwebui_url": settings.openwebui_url, +} +CLIENTS: set[WebSocket] = set() +SSH_SESSIONS: dict[str, dict] = {} +SSH_MAX_SESSIONS = 25 +SSH_MAX_PER_CLIENT = 3 +_ssh_sem: asyncio.Semaphore | None = None +_lock = asyncio.Lock() +DETAIL_CACHE: dict[int, dict] = {} +PREV_DEVICES: dict[int, dict] = {} +EVENT_FEED: list[dict] = [] + + +def subnet_of(ip: str | None) -> str: + if not ip or ip.count(".") != 3: + return "unknown" + try: + return str(ipaddress.ip_network(f"{ip}/24", strict=False)) + except Exception: + parts = ip.split(".") + return f"{parts[0]}.{parts[1]}.{parts[2]}.0/24" + + +def pick_ip(device: dict) -> str | None: + for m in device.get("DeviceManagement") or []: + addr = m.get("NetworkAddress") + if addr and addr.count(".") == 3: + return addr + return None + + +async def fetch_power(client: httpx.AsyncClient, base: str, headers: dict, device_id: int) -> dict: + try: + r = await client.get(f"{base}/api/DeviceService/Devices({device_id})/Power", headers=headers) + if r.status_code != 200: + return {} + p = r.json() + def num(key): + v = p.get(key) + try: + return float(v) if v not in (None, "") else None + except Exception: + return None + return { + "watts": num("power"), + "avg_watts": num("avgPower"), + "peak_watts": num("peakPower"), + "min_watts": num("minimumPower"), + "energy_kwh": num("systemEnergyConsumption"), + "power_unit": p.get("powerUnit") or "watt", + } + except Exception: + return {} + + +async def ome_fetch() -> dict: + base = settings.ome_url.rstrip("/") + async with httpx.AsyncClient(verify=False, timeout=60.0) as client: + r = await client.post( + f"{base}/api/SessionService/Sessions", + json={ + "UserName": settings.ome_user, + "Password": settings.ome_password, + "SessionType": "API", + }, + ) + r.raise_for_status() + token = r.headers.get("X-Auth-Token") + sid = r.json().get("Id") + headers = {"X-Auth-Token": token, "Accept": "application/json"} + try: + info = (await client.get(f"{base}/api/ApplicationService/Info", headers=headers)).json() + devices_resp = ( + await client.get(f"{base}/api/DeviceService/Devices?$top=5000", headers=headers) + ).json() + groups_resp = ( + await client.get(f"{base}/api/GroupService/Groups?$top=200", headers=headers) + ).json() + alerts_raw = [] + alerts_total = None + try: + alerts_resp = ( + await client.get( + f"{base}/api/AlertService/Alerts?$top=200", + headers=headers, + ) + ).json() + alerts_raw = alerts_resp.get("value") or [] + alerts_total = alerts_resp.get("@odata.count") + except Exception as e: + log.warning("OME alerts fetch failed: %s", e) + + devices_raw = devices_resp.get("value") or [] + # power for connected servers first + power_targets = [ + d.get("Id") + for d in devices_raw + if d.get("Type") == 1000 and d.get("ConnectionState") and d.get("Id") + ][: settings.power_fetch_limit] + # also a few offline servers for comparison + offline_ids = [ + d.get("Id") + for d in devices_raw + if d.get("Type") == 1000 and not d.get("ConnectionState") and d.get("Id") + ][:5] + power_targets = list(dict.fromkeys(power_targets + offline_ids)) + + sem = asyncio.Semaphore(8) + + async def limited(did): + async with sem: + return did, await fetch_power(client, base, headers, did) + + power_map = {} + if power_targets: + results = await asyncio.gather(*[limited(i) for i in power_targets]) + power_map = {i: p for i, p in results if p} + finally: + if sid: + try: + await client.delete( + f"{base}/api/SessionService/Sessions('{sid}')", + headers=headers, + ) + except Exception: + pass + + devices = [] + subnet_map: dict[str, list] = defaultdict(list) + model_counts: dict[str, int] = defaultdict(int) + idrac_count = server_count = connected = powered = 0 + total_watts = 0.0 + watts_samples = 0 + status_counts: dict[str, int] = defaultdict(int) + + for d in devices_raw: + ip = pick_ip(d) + subnet = subnet_of(ip) + dtype = d.get("Type") + sub = d.get("SubDeviceType") or "" + is_server = dtype == 1000 + is_idrac = sub == "iDRAC" + conn = bool(d.get("ConnectionState")) + power_state = d.get("PowerState") + status = str(d.get("Status") or "") + status_counts[status] += 1 + model = d.get("Model") or "Unknown" + if is_server: + model_counts[model] += 1 + if is_idrac: + idrac_count += 1 + if is_server: + server_count += 1 + if conn: + connected += 1 + if power_state == 17: + powered += 1 + + pwr = power_map.get(d.get("Id")) or {} + watts = pwr.get("watts") + if watts is not None: + total_watts += watts + watts_samples += 1 + + node = { + "id": d.get("Id"), + "name": d.get("DeviceName") or f"device-{d.get('Id')}", + "model": model, + "service_tag": d.get("DeviceServiceTag"), + "type": dtype, + "sub_type": sub, + "connected": conn, + "power_state": power_state, + "powered_on": power_state == 17, + "status": status, + "ip": ip, + "subnet": subnet, + "is_server": is_server, + "is_idrac": is_idrac, + "idrac_url": f"https://{ip}" if ip else None, + "watts": watts, + "avg_watts": pwr.get("avg_watts"), + "peak_watts": pwr.get("peak_watts"), + "energy_kwh": pwr.get("energy_kwh"), + "last_status_time": d.get("LastStatusTime"), + "last_inventory_time": d.get("LastInventoryTime"), + } + devices.append(node) + subnet_map[subnet].append(node["id"]) + + subnets = [] + for cidr, ids in sorted(subnet_map.items(), key=lambda x: -len(x[1])): + members = [n for n in devices if n["id"] in ids] + sub_watts = sum(n["watts"] or 0 for n in members if n.get("watts") is not None) + subnets.append({ + "cidr": cidr, + "count": len(members), + "connected": sum(1 for n in members if n["connected"]), + "watts": round(sub_watts, 1) if sub_watts else None, + "device_ids": ids, + }) + + groups = [ + {"id": g.get("Id"), "name": g.get("Name")} + for g in (groups_resp.get("value") or []) + if g.get("Name") + ][:60] + + models = [ + {"name": m, "count": c} + for m, c in sorted(model_counts.items(), key=lambda x: -x[1]) + ] + + # --- realtime context: fleet deltas + alerts --- + global PREV_DEVICES, EVENT_FEED + now = time.time() + new_events: list[dict] = [] + first_poll = not PREV_DEVICES + current_ids: set[int] = set() + + def _role(n: dict) -> str: + if n.get("is_idrac"): + return "iDRAC" + if n.get("is_server"): + return "server" + return "device" + + for n in devices: + did = n.get("id") + if did is None: + continue + current_ids.add(did) + prev = PREV_DEVICES.get(did) + if not prev: + # First poll only seeds baseline; later polls raise new-node alerts + if not first_poll and (n.get("is_server") or n.get("is_idrac")): + role = _role(n) + new_events.append({ + "ts": now, + "kind": "device_new", + "severity": "critical", + "device_id": did, + "title": f"New {role} discovered", + "text": ( + f"{n.get('name')} · {n.get('ip') or 'no IP'} · " + f"{n.get('model') or 'unknown model'} · {n.get('subnet') or 'unknown subnet'}" + ), + "notify": True, + "role": role, + "ip": n.get("ip"), + "model": n.get("model"), + "subnet": n.get("subnet"), + "name": n.get("name"), + }) + continue + if bool(prev.get("connected")) != bool(n.get("connected")): + new_events.append({ + "ts": now, + "kind": "connection", + "severity": "info" if n.get("connected") else "warning", + "device_id": did, + "title": n.get("name"), + "text": "Connected" if n.get("connected") else "Went offline", + }) + if bool(prev.get("powered_on")) != bool(n.get("powered_on")): + new_events.append({ + "ts": now, + "kind": "power_state", + "severity": "info" if n.get("powered_on") else "warning", + "device_id": did, + "title": n.get("name"), + "text": "Powered on" if n.get("powered_on") else "Powered off", + }) + pw, pp = n.get("watts"), prev.get("watts") + if pw is not None and pp is not None and abs(pw - pp) >= 40: + new_events.append({ + "ts": now, + "kind": "power_watt", + "severity": "info", + "device_id": did, + "title": n.get("name"), + "text": f"Power {round(pp)}W → {round(pw)}W", + }) + if str(prev.get("status")) != str(n.get("status")): + new_events.append({ + "ts": now, + "kind": "status", + "severity": "warning", + "device_id": did, + "title": n.get("name"), + "text": f"Status {prev.get('status')} → {n.get('status')}", + }) + + if not first_poll: + for did, prev in PREV_DEVICES.items(): + if did in current_ids: + continue + if not (prev.get("is_server") or prev.get("is_idrac")): + continue + role = _role(prev) + new_events.append({ + "ts": now, + "kind": "device_removed", + "severity": "warning", + "device_id": did, + "title": f"{role} left inventory", + "text": ( + f"{prev.get('name')} · {prev.get('ip') or 'no IP'} · " + f"{prev.get('model') or 'unknown model'}" + ), + "notify": True, + "role": role, + "name": prev.get("name"), + "ip": prev.get("ip"), + "model": prev.get("model"), + }) + + PREV_DEVICES = {n["id"]: n for n in devices if n.get("id") is not None} + if new_events: + EVENT_FEED = (new_events + EVENT_FEED)[:120] + + sev_map = {"Critical": 0, "Warning": 0, "Normal": 0, "Info": 0, "Unknown": 0} + alerts = [] + for a in alerts_raw: + sev = a.get("SeverityName") or "Unknown" + if sev not in sev_map: + sev_map[sev] = 0 + sev_map[sev] = sev_map.get(sev, 0) + 1 + alerts.append({ + "id": a.get("Id"), + "severity": sev, + "device_id": a.get("AlertDeviceId") or a.get("AlertEntityId"), + "device": a.get("AlertDeviceName") or a.get("AlertEntityName"), + "ip": a.get("AlertDeviceIpAddress"), + "category": a.get("CategoryName"), + "subcategory": a.get("SubCategoryName"), + "message": a.get("Message"), + "message_id": a.get("AlertMessageId"), + "status": a.get("StatusName"), + "time": a.get("TimeStamp"), + "action": a.get("RecommendedAction"), + }) + + hottest = sorted( + [n for n in devices if n.get("watts") is not None], + key=lambda x: x.get("watts") or 0, + reverse=True, + )[:5] + recent_status = sorted( + [n for n in devices if n.get("last_status_time")], + key=lambda x: str(x.get("last_status_time")), + reverse=True, + )[:5] + + context = { + "refreshed_at": now, + "poll_seconds": settings.poll_interval, + "alerts_total": alerts_total, + "alert_severity": sev_map, + "events_new": len(new_events), + "notifications": [e for e in new_events if e.get("notify")], + "hottest": [ + {"id": n["id"], "name": n["name"], "watts": n["watts"], "subnet": n["subnet"]} + for n in hottest + ], + "recent_status": [ + { + "id": n["id"], + "name": n["name"], + "time": n.get("last_status_time"), + "connected": n.get("connected"), + "status": n.get("status"), + } + for n in recent_status + ], + "focus_hint": ( + f"{connected} connected · {round(total_watts)} W sampled · " + f"{sev_map.get('Critical', 0)} critical / {sev_map.get('Warning', 0)} warning alerts in feed" + ), + } + + return { + "ome": { + "name": info.get("Name") or "OpenManage Enterprise", + "version": info.get("Version"), + "build": info.get("BuildNumber"), + "url": base, + "fqdn": "cov-omeprod01.dell-atc.lan", + "console_url": f"{base}/management-console/ome/", + }, + "summary": { + "total": len(devices), + "idracs": idrac_count, + "servers": server_count, + "connected": connected, + "powered_on": powered, + "offline": max(0, server_count - connected), + "status_counts": dict(status_counts), + "total_watts": round(total_watts, 1), + "avg_node_watts": round(total_watts / watts_samples, 1) if watts_samples else None, + "power_samples": watts_samples, + "alerts_critical": sev_map.get("Critical", 0), + "alerts_warning": sev_map.get("Warning", 0), + "alerts_total": alerts_total, + }, + "subnets": subnets, + "devices": devices, + "groups": groups, + "models": models, + "alerts": alerts, + "events": EVENT_FEED[:40], + "context": context, + "openwebui_url": settings.openwebui_url, + "updated_at": now, + } + + +async def broadcast(payload: dict): + dead = [] + for ws in list(CLIENTS): + try: + await ws.send_json(payload) + except Exception: + dead.append(ws) + for ws in dead: + CLIENTS.discard(ws) + + +ADMINS = [ + {"id": "jody", "name": "Jody van Dongen", "role": "ATC Datacenter Admin", "email": "jody.van.dongen@dell.com"}, + {"id": "laurens", "name": "Laurens Rammers", "role": "ATC Datacenter Admin", "email": "laurens.rammers@dell.com"}, +] + +DATA_DIR = Path(settings.cockpit_data) +DB_PATH = DATA_DIR / "ops.db" + + +def _db(): + DATA_DIR.mkdir(parents=True, exist_ok=True) + conn = sqlite3.connect(DB_PATH) + conn.row_factory = sqlite3.Row + conn.execute("PRAGMA foreign_keys=ON") + return conn + + +def init_db(): + with _db() as conn: + conn.executescript( + """ + CREATE TABLE IF NOT EXISTS tickets ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + title TEXT NOT NULL, + body TEXT NOT NULL, + status TEXT NOT NULL DEFAULT 'open', + priority TEXT NOT NULL DEFAULT 'normal', + created_by TEXT NOT NULL, + assignee TEXT, + accepted_by TEXT, + created_at REAL NOT NULL, + updated_at REAL NOT NULL + ); + CREATE TABLE IF NOT EXISTS ticket_messages ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + ticket_id INTEGER NOT NULL REFERENCES tickets(id) ON DELETE CASCADE, + author TEXT NOT NULL, + body TEXT NOT NULL, + created_at REAL NOT NULL + ); + """ + ) + cols = {r[1] for r in conn.execute("PRAGMA table_info(tickets)").fetchall()} + if "accepted_by" not in cols: + conn.execute("ALTER TABLE tickets ADD COLUMN accepted_by TEXT") + + +async def fetch_gpu() -> dict: + url = settings.gpu_metrics_url.rstrip("/") + "/api/gpu" + try: + async with httpx.AsyncClient(timeout=4.0) as client: + r = await client.get(url) + if r.status_code == 200: + return r.json() + except Exception as e: + log.warning("GPU metrics fetch failed: %s", e) + return { + "host": "atc-gpu-prod", + "gpus": [], + "error": "unreachable", + "updated_at": time.time(), + "model": settings.vllm_model, + } + + +async def poll_loop(): + while True: + try: + data = await ome_fetch() + gpu = await fetch_gpu() + data["gpu"] = gpu + async with _lock: + STATE.update(data) + STATE["pulse"] = int(STATE.get("pulse") or 0) + 1 + await broadcast({"type": "snapshot", "data": {**STATE}}) + log.info( + "OME refresh: %s devices, %s connected, %s W sampled, GPU util avg %s", + STATE["summary"].get("total"), + STATE["summary"].get("connected"), + STATE["summary"].get("total_watts"), + (gpu.get("summary") or {}).get("avg_util"), + ) + except Exception as e: + log.exception("OME poll failed: %s", e) + await broadcast({"type": "error", "message": str(e)}) + await asyncio.sleep(settings.poll_interval) + + +async def gpu_loop(): + """Faster GPU pulse so matrix feels live during inference.""" + while True: + try: + gpu = await fetch_gpu() + async with _lock: + STATE["gpu"] = gpu + await broadcast({"type": "gpu", "data": gpu}) + except Exception as e: + log.warning("gpu loop: %s", e) + await asyncio.sleep(2.0) + + +@app.on_event("startup") +async def startup(): + init_db() + asyncio.create_task(poll_loop()) + asyncio.create_task(gpu_loop()) + + +@app.get("/api/health") +async def health(): + return { + "status": "ok", + "updated_at": STATE.get("updated_at"), + "pulse": STATE.get("pulse"), + } + + +@app.get("/api/fleet") +async def fleet(): + return {**STATE} + + +@app.get("/api/devices/{device_id}") +async def device_detail(device_id: int): + # lightweight detail: return fleet node + optional inventory slices + node = next((d for d in STATE.get("devices") or [] if d.get("id") == device_id), None) + if not node: + raise HTTPException(404, "Device not found in current fleet snapshot") + + if device_id in DETAIL_CACHE and time.time() - DETAIL_CACHE[device_id].get("_ts", 0) < 300: + return DETAIL_CACHE[device_id] + + base = settings.ome_url.rstrip("/") + detail = {"device": node, "inventory": {}, "power": {}} + async with httpx.AsyncClient(verify=False, timeout=60.0) as client: + r = await client.post( + f"{base}/api/SessionService/Sessions", + json={ + "UserName": settings.ome_user, + "Password": settings.ome_password, + "SessionType": "API", + }, + ) + r.raise_for_status() + token = r.headers.get("X-Auth-Token") + sid = r.json().get("Id") + headers = {"X-Auth-Token": token, "Accept": "application/json"} + try: + detail["power"] = await fetch_power(client, base, headers, device_id) + + # Discover all inventory types OME has for this device (app/firmware landscape) + inv_types: list[str] = [] + try: + tr = await client.get( + f"{base}/api/DeviceService/Devices({device_id})/InventoryTypes", + headers=headers, + ) + if tr.status_code == 200: + inv_types = list((tr.json() or {}).get("InventoryTypes") or []) + except Exception: + inv_types = [] + # Ensure core + software landscape types are always attempted + for required in ( + "serverProcessors", + "serverMemoryDevices", + "serverArrayDisks", + "serverPowerSupplies", + "serverNetworkInterfaces", + "deviceLocation", + "deviceManagement", + "subsystemRollupStatus", + "serverOperatingSystems", + "deviceSoftware", + "deviceLicense", + "deviceFru", + "deviceCapabilities", + "serverRaidControllers", + "serverDeviceCards", + "deviceBaseboards", + "serverDellVideos", + "serverFcCards", + "serverVirtualFlashes", + "serverStorageEnclosures", + "serverSupportedPowerStates", + "serverBiosSystemProfileSettings", + "deviceInventory", + ): + if required not in inv_types: + inv_types.append(required) + + detail["inventory_types"] = inv_types + for inv_type in inv_types: + try: + ir = await client.get( + f"{base}/api/DeviceService/Devices({device_id})/InventoryDetails('{inv_type}')", + headers=headers, + ) + if ir.status_code == 200: + info = ir.json().get("InventoryInfo") or [] + if info: + detail["inventory"][inv_type] = info + except Exception: + pass + + # Normalized application / firmware landscape view + software = detail["inventory"].get("deviceSoftware") or [] + os_info = detail["inventory"].get("serverOperatingSystems") or [] + mgmt = detail["inventory"].get("deviceManagement") or [] + licenses = detail["inventory"].get("deviceLicense") or [] + def _stype(s: dict) -> str: + return str(s.get("SoftwareType") or "").strip().upper() + + fw_types = {"BIOS", "FRMW", "FIRMWARE", "IDRAC", "USC", "BMC", "CPLD", "DCSM"} + drv_types = {"DRVR", "DRIVER", "DRV"} + firmware = [s for s in software if _stype(s) in fw_types or "FW" in _stype(s)] + drivers = [s for s in software if _stype(s) in drv_types or "DRIVER" in _stype(s)] + fw_ids = {id(s) for s in firmware} + drv_ids = {id(s) for s in drivers} + applications = [s for s in software if id(s) not in fw_ids and id(s) not in drv_ids] + detail["landscape"] = { + "os": os_info, + "software": software, + "management": mgmt, + "licenses": licenses, + "firmware": firmware, + "drivers": drivers, + "applications": applications, + } + finally: + if sid: + try: + await client.delete( + f"{base}/api/SessionService/Sessions('{sid}')", + headers=headers, + ) + except Exception: + pass + detail["_ts"] = time.time() + DETAIL_CACHE[device_id] = detail + return detail + + +@app.websocket("/ws/fleet") +async def ws_fleet(ws: WebSocket): + await ws.accept() + CLIENTS.add(ws) + try: + await ws.send_json({"type": "snapshot", "data": {**STATE}}) + while True: + await ws.receive_text() + except WebSocketDisconnect: + pass + finally: + CLIENTS.discard(ws) + + +class ChatIn(BaseModel): + message: str + history: list[dict] = Field(default_factory=list) + focus_device_id: int | None = None + model: str | None = None + + +class TicketIn(BaseModel): + title: str + body: str + created_by: str + assignee: str | None = None + priority: str = "normal" + + +class TicketMsgIn(BaseModel): + author: str + body: str + + +class TicketPatch(BaseModel): + status: str | None = None + assignee: str | None = None + priority: str | None = None + accepted_by: str | None = None + + +def build_fleet_context(focus_device_id: int | None = None, max_chars: int | None = None) -> str: + summary = STATE.get("summary") or {} + gpu = STATE.get("gpu") or {} + gsum = gpu.get("summary") or {} + devices = STATE.get("devices") or [] + alerts = STATE.get("alerts") or [] + events = STATE.get("events") or [] + subnets = STATE.get("subnets") or [] + ctx = STATE.get("context") or {} + limit = max_chars if max_chars is not None else settings.chat_system_chars + + connected = [d for d in devices if d.get("connected")] + critical = [a for a in alerts if a.get("severity") == "Critical"][:8] + warnings = [a for a in alerts if a.get("severity") == "Warning"][:5] + hottest = (ctx.get("hottest") or [])[:5] + + lines = [ + "You are OpenManage Cockpit Copilot for Dell ATC. Be concise and operational.", + "Admins: Jody van Dongen, Laurens Rammers, Mohamed El Kadi.", + "Use ONLY this live snapshot. Unknown => say unknown.", + "", + "FLEET: total={t} connected={c} offline={o} watts={w} alerts_total={a}".format( + t=summary.get("total"), + c=summary.get("connected"), + o=summary.get("offline"), + w=summary.get("total_watts"), + a=summary.get("alerts_total"), + ), + "CONNECTED:", + ] + for d in connected[:18]: + lines.append( + "- {name} ip={ip} model={model} W={watts} st={status}".format( + name=(d.get("name") or "")[:36], + ip=d.get("ip"), + model=(d.get("model") or "")[:28], + watts=d.get("watts"), + status=d.get("status"), + ) + ) + + lines.append("SUBNETS:") + for s in subnets[:8]: + lines.append( + "- {cidr}: {conn}/{cnt} W={watts}".format( + cidr=s.get("cidr"), + conn=s.get("connected"), + cnt=s.get("count"), + watts=s.get("watts"), + ) + ) + + lines.append("CRITICAL:") + if not critical: + lines.append("(none)") + for a in critical: + lines.append( + "- {dev} ({ip}): {msg}".format( + dev=(a.get("device") or "")[:32], + ip=a.get("ip"), + msg=(a.get("message") or "")[:110], + ) + ) + + lines.append("WARNINGS:") + for a in warnings: + lines.append( + "- {dev} ({ip}): {msg}".format( + dev=(a.get("device") or "")[:32], + ip=a.get("ip"), + msg=(a.get("message") or "")[:90], + ) + ) + + lines.append("DELTAS:") + if not events: + lines.append("(none)") + for e in events[:8]: + lines.append("- {title}: {text}".format(title=e.get("title"), text=(e.get("text") or "")[:100])) + + lines.append("HOT POWER:") + for h in hottest: + lines.append("- {name}: {watts}W".format(name=(h.get("name") or "")[:28], watts=h.get("watts"))) + + lines.append( + "GPU atc-gpu-prod: avg_util={u}% power={p}W mem={mu}/{mt}MB".format( + u=gsum.get("avg_util"), + p=gsum.get("total_power_w"), + mu=gsum.get("total_mem_used_mb"), + mt=gsum.get("total_mem_mb"), + ) + ) + for g in (gpu.get("gpus") or [])[:8]: + lines.append( + "- GPU{i}: {util}% {temp}C {pw}W".format( + i=g.get("index"), + util=g.get("util_gpu"), + temp=g.get("temp_c"), + pw=g.get("power_w"), + ) + ) + + if focus_device_id is not None: + node = next((d for d in devices if d.get("id") == focus_device_id), None) + lines.append("FOCUS:") + if node: + lines.append( + "{name} id={id} ip={ip} model={model} W={watts} connected={conn} status={st}".format( + name=node.get("name"), + id=node.get("id"), + ip=node.get("ip"), + model=node.get("model"), + watts=node.get("watts"), + conn=node.get("connected"), + st=node.get("status"), + ) + ) + related = [a for a in alerts if a.get("device_id") == focus_device_id][:5] + for a in related: + lines.append("alert {sev}: {msg}".format(sev=a.get("severity"), msg=(a.get("message") or "")[:100])) + else: + lines.append("device_id=%s missing" % focus_device_id) + + lines.append("Reply with concrete names, IPs, and next actions.") + out = "\n".join(lines) + if len(out) > limit: + out = out[: limit - 20] + "\n…[truncated]" + return out + + + +@app.get("/api/gpu") +async def api_gpu(): + if not STATE.get("gpu"): + STATE["gpu"] = await fetch_gpu() + return STATE.get("gpu") or {} + + +@app.get("/api/admins") +async def api_admins(): + return {"admins": ADMINS} + + + +_OWUI_TOKEN: dict[str, Any] = {"token": None, "expires": 0.0} + + +async def _owui_token() -> str | None: + email = (settings.openwebui_email or "").strip() + password = settings.openwebui_password or "" + if not email or not password: + return None + now = time.time() + if _OWUI_TOKEN.get("token") and float(_OWUI_TOKEN.get("expires") or 0) > now: + return str(_OWUI_TOKEN["token"]) + url = settings.openwebui_url.rstrip("/") + "/api/v1/auths/signin" + try: + async with httpx.AsyncClient(timeout=20.0) as client: + r = await client.post(url, json={"email": email, "password": password}) + if r.status_code >= 400: + log.warning("Open WebUI signin failed: %s %s", r.status_code, r.text[:200]) + return None + token = (r.json() or {}).get("token") + if token: + _OWUI_TOKEN["token"] = token + _OWUI_TOKEN["expires"] = now + 3500 + return token + except Exception as e: + log.warning("Open WebUI signin error: %s", e) + return None + + +async def list_chat_models() -> list[dict]: + models: list[dict] = [] + seen: set[str] = set() + + token = await _owui_token() + if token: + try: + async with httpx.AsyncClient(timeout=15.0) as client: + r = await client.get( + settings.openwebui_url.rstrip("/") + "/api/models", + headers={"Authorization": f"Bearer {token}"}, + ) + if r.status_code == 200: + for m in (r.json() or {}).get("data") or []: + mid = m.get("id") + if not mid or mid in seen: + continue + seen.add(mid) + models.append( + { + "id": mid, + "name": m.get("name") or mid, + "source": "openwebui", + "owned_by": m.get("owned_by"), + } + ) + except Exception as e: + log.warning("Open WebUI models failed: %s", e) + + try: + async with httpx.AsyncClient(timeout=10.0) as client: + r = await client.get(settings.vllm_url.rstrip("/") + "/models") + if r.status_code == 200: + for m in (r.json() or {}).get("data") or []: + mid = m.get("id") + if not mid or mid in seen: + continue + seen.add(mid) + models.append( + { + "id": mid, + "name": mid, + "source": "vllm", + "owned_by": m.get("owned_by") or "vllm", + } + ) + except Exception as e: + log.warning("vLLM models failed: %s", e) + + if not models: + models.append( + { + "id": settings.vllm_model, + "name": settings.vllm_model, + "source": "vllm", + "owned_by": "vllm", + } + ) + return models + + +@app.get("/api/models") +async def api_models(): + models = await list_chat_models() + return {"models": models, "default": settings.vllm_model} + + +@app.post("/api/chat") +async def api_chat(payload: ChatIn): + gpu = STATE.get("gpu") or {} + gsum = gpu.get("summary") or {} + model = (payload.model or settings.vllm_model or "").strip() or settings.vllm_model + + system = build_fleet_context(payload.focus_device_id, max_chars=settings.chat_system_chars) + messages = [{"role": "system", "content": system}] + for h in (payload.history or [])[-4:]: + role = h.get("role") + content = h.get("content") + if role in ("user", "assistant") and content: + messages.append({"role": role, "content": str(content)[:1200]}) + messages.append({"role": "user", "content": payload.message[:2500]}) + + owui_models = {"ome-copilot", "arena-model"} + use_owui = model in owui_models + + try: + if use_owui: + token = await _owui_token() + if not token: + raise HTTPException( + 502, + "Open WebUI auth not configured (set OPENWEBUI_EMAIL / OPENWEBUI_PASSWORD)", + ) + url = settings.openwebui_url.rstrip("/") + "/api/chat/completions" + async with httpx.AsyncClient(timeout=180.0) as client: + r = await client.post( + url, + headers={"Authorization": f"Bearer {token}"}, + json={ + "model": model, + "messages": messages, + "temperature": 0.2, + "max_tokens": settings.vllm_max_tokens, + "stream": False, + }, + ) + if r.status_code >= 400: + raise HTTPException(502, f"Open WebUI error {r.status_code}: {r.text[:500]}") + data = r.json() + backend = "openwebui" + else: + url = settings.vllm_url.rstrip("/") + "/chat/completions" + async with httpx.AsyncClient(timeout=180.0) as client: + r = await client.post( + url, + json={ + "model": model, + "messages": messages, + "temperature": 0.2, + "max_tokens": settings.vllm_max_tokens, + }, + ) + if r.status_code >= 400: + detail = r.text + if r.status_code == 400 and "context length" in detail.lower(): + tight = build_fleet_context(payload.focus_device_id, max_chars=3200) + messages = [{"role": "system", "content": tight}, messages[-1]] + r = await client.post( + url, + json={ + "model": model, + "messages": messages, + "temperature": 0.2, + "max_tokens": 500, + }, + ) + detail = r.text + if r.status_code >= 400: + raise HTTPException(502, f"vLLM error {r.status_code}: {detail[:600]}") + data = r.json() + backend = "vllm" + + text_out = ( + ((data.get("choices") or [{}])[0].get("message") or {}).get("content") + or "" + ) + return { + "reply": text_out, + "model": model, + "backend": backend, + "gpu": gsum, + "context_bytes": len(system), + } + except HTTPException: + raise + except Exception as e: + raise HTTPException(502, f"Chat backend error: {e}") from e + + + + +def _admin_name(aid: str) -> str: + for a in ADMINS: + if a["id"] == aid: + return a["name"] + return aid + + +@app.get("/api/tickets") +async def list_tickets(): + with _db() as conn: + rows = conn.execute( + "SELECT * FROM tickets ORDER BY updated_at DESC LIMIT 200" + ).fetchall() + return {"tickets": [dict(r) for r in rows], "admins": ADMINS} + + +@app.post("/api/tickets") +async def create_ticket(payload: TicketIn): + now = time.time() + assignee = payload.assignee + if not assignee: + assignee = "laurens" if payload.created_by == "jody" else "jody" + with _db() as conn: + cur = conn.execute( + """ + INSERT INTO tickets(title, body, status, priority, created_by, assignee, created_at, updated_at) + VALUES (?, ?, 'open', ?, ?, ?, ?, ?) + """, + ( + payload.title.strip()[:200], + payload.body.strip()[:5000], + payload.priority, + payload.created_by, + assignee, + now, + now, + ), + ) + tid = cur.lastrowid + conn.execute( + "INSERT INTO ticket_messages(ticket_id, author, body, created_at) VALUES (?, ?, ?, ?)", + (tid, payload.created_by, payload.body.strip()[:5000], now), + ) + row = conn.execute("SELECT * FROM tickets WHERE id=?", (tid,)).fetchone() + return dict(row) + + +@app.get("/api/tickets/{ticket_id}") +async def get_ticket(ticket_id: int): + with _db() as conn: + row = conn.execute("SELECT * FROM tickets WHERE id=?", (ticket_id,)).fetchone() + if not row: + raise HTTPException(404, "Ticket not found") + msgs = conn.execute( + "SELECT * FROM ticket_messages WHERE ticket_id=? ORDER BY created_at ASC", + (ticket_id,), + ).fetchall() + return {"ticket": dict(row), "messages": [dict(m) for m in msgs], "admins": ADMINS} + + +@app.post("/api/tickets/{ticket_id}/messages") +async def add_ticket_message(ticket_id: int, payload: TicketMsgIn): + now = time.time() + with _db() as conn: + row = conn.execute("SELECT id FROM tickets WHERE id=?", (ticket_id,)).fetchone() + if not row: + raise HTTPException(404, "Ticket not found") + conn.execute( + "INSERT INTO ticket_messages(ticket_id, author, body, created_at) VALUES (?, ?, ?, ?)", + (ticket_id, payload.author, payload.body.strip()[:5000], now), + ) + conn.execute("UPDATE tickets SET updated_at=? WHERE id=?", (now, ticket_id)) + msgs = conn.execute( + "SELECT * FROM ticket_messages WHERE ticket_id=? ORDER BY created_at ASC", + (ticket_id,), + ).fetchall() + return {"messages": [dict(m) for m in msgs]} + + +@app.patch("/api/tickets/{ticket_id}") +async def patch_ticket(ticket_id: int, payload: TicketPatch): + now = time.time() + with _db() as conn: + row = conn.execute("SELECT * FROM tickets WHERE id=?", (ticket_id,)).fetchone() + if not row: + raise HTTPException(404, "Ticket not found") + status = payload.status or row["status"] + assignee = payload.assignee if payload.assignee is not None else row["assignee"] + priority = payload.priority or row["priority"] + # accepted_by: keep existing unless explicitly set; accepting sets status accepted + accepted_by = row["accepted_by"] if "accepted_by" in row.keys() else None + if payload.accepted_by is not None: + accepted_by = payload.accepted_by + if status == "open": + status = "accepted" + conn.execute( + "UPDATE tickets SET status=?, assignee=?, priority=?, accepted_by=?, updated_at=? WHERE id=?", + (status, assignee, priority, accepted_by, now, ticket_id), + ) + if payload.accepted_by: + conn.execute( + "INSERT INTO ticket_messages(ticket_id, author, body, created_at) VALUES (?, ?, ?, ?)", + ( + ticket_id, + payload.accepted_by, + f"Ticket accepted by {_admin_name(payload.accepted_by)}", + now, + ), + ) + row = conn.execute("SELECT * FROM tickets WHERE id=?", (ticket_id,)).fetchone() + return dict(row) + + +@app.delete("/api/tickets/{ticket_id}") +async def delete_ticket(ticket_id: int): + with _db() as conn: + row = conn.execute("SELECT id FROM tickets WHERE id=?", (ticket_id,)).fetchone() + if not row: + raise HTTPException(404, "Ticket not found") + conn.execute("DELETE FROM ticket_messages WHERE ticket_id=?", (ticket_id,)) + conn.execute("DELETE FROM tickets WHERE id=?", (ticket_id,)) + return {"ok": True, "deleted": ticket_id} + + + +def _get_ssh_sem() -> asyncio.Semaphore: + global _ssh_sem + if _ssh_sem is None: + _ssh_sem = asyncio.Semaphore(SSH_MAX_SESSIONS) + return _ssh_sem + + +def _fleet_ssh_targets() -> set[str]: + """Allow SSH only to IPs currently known in the OME fleet snapshot.""" + allowed: set[str] = set() + for d in STATE.get("devices") or []: + ip = d.get("ip") + if ip and ip.count(".") == 3: + allowed.add(ip) + return allowed + + +@app.websocket("/ws/ssh") +async def ws_ssh(ws: WebSocket): + """Browser terminal <-> SSH bridge. Isolated per connection; concurrency-limited.""" + await ws.accept() + conn = None + process = None + reader_task = None + session_id = f"{id(ws)}-{time.time()}" + client_host = "" + acquired = False + + async def send_json(payload: dict): + try: + await ws.send_text(json.dumps(payload)) + except Exception: + pass + + def _client_key() -> str: + try: + return ws.client.host if ws.client else "unknown" + except Exception: + return "unknown" + + try: + # Limit concurrent sessions globally and per browser IP + ck = _client_key() + active_for_client = sum(1 for s in SSH_SESSIONS.values() if s.get("client") == ck) + if active_for_client >= SSH_MAX_PER_CLIENT: + await send_json({ + "type": "error", + "message": f"Too many SSH sessions from this client (max {SSH_MAX_PER_CLIENT})", + }) + await ws.close() + return + + try: + await asyncio.wait_for(_get_ssh_sem().acquire(), timeout=8.0) + acquired = True + except asyncio.TimeoutError: + await send_json({ + "type": "error", + "message": "SSH gateway busy — try again in a moment", + }) + await ws.close() + return + + SSH_SESSIONS[session_id] = { + "client": ck, + "started": time.time(), + "host": None, + "user": None, + } + + raw = await asyncio.wait_for(ws.receive_text(), timeout=60.0) + try: + msg = json.loads(raw) + except Exception: + await send_json({"type": "error", "message": "Invalid auth payload"}) + await ws.close() + return + + if msg.get("type") != "auth": + await send_json({"type": "error", "message": "Expected auth message"}) + await ws.close() + return + + host = str(msg.get("host") or "").strip() + username = str(msg.get("username") or "").strip() + password = str(msg.get("password") or "") + try: + port = int(msg.get("port") or 22) + except Exception: + port = 22 + + if not host or not username: + await send_json({"type": "error", "message": "Host and username are required"}) + await ws.close() + return + if port < 1 or port > 65535: + await send_json({"type": "error", "message": "Invalid port"}) + await ws.close() + return + + async with _lock: + allowed = set(_fleet_ssh_targets()) + if host not in allowed: + await send_json({ + "type": "error", + "message": f"Host {host} is not in the current OME fleet — SSH blocked", + }) + await ws.close() + return + + client_host = host + SSH_SESSIONS[session_id]["host"] = host + SSH_SESSIONS[session_id]["user"] = username + await send_json({"type": "status", "message": f"Connecting to {username}@{host}:{port}…"}) + + try: + conn = await asyncio.wait_for( + asyncssh.connect( + host, + port=port, + username=username, + password=password, + known_hosts=None, + client_keys=None, + preferred_auth=["password", "keyboard-interactive"], + keepalive_interval=30, + keepalive_count_max=3, + ), + timeout=25.0, + ) + except Exception as e: + await send_json({"type": "error", "message": f"SSH connect failed: {e}"}) + await ws.close() + return + + term = str(msg.get("term") or "xterm-256color") + cols = int(msg.get("cols") or 120) + rows = int(msg.get("rows") or 36) + process = await conn.create_process( + term_type=term, + term_size=(max(cols, 40), max(rows, 10)), + encoding="utf-8", + errors="replace", + ) + await send_json({"type": "ready", "message": f"Connected as {username}@{host}"}) + log.info("SSH session start id=%s client=%s target=%s@%s active=%s", + session_id, ck, username, host, len(SSH_SESSIONS)) + + async def pump_ssh_to_ws(): + try: + while True: + data = await process.stdout.read(8192) + if not data: + try: + err = await asyncio.wait_for(process.stderr.read(1024), timeout=0.2) + except Exception: + err = "" + if err: + await ws.send_text(err if isinstance(err, str) else err.decode("utf-8", "replace")) + break + await ws.send_text(data if isinstance(data, str) else data.decode("utf-8", "replace")) + except Exception: + pass + try: + await send_json({"type": "status", "message": "SSH session ended"}) + except Exception: + pass + + reader_task = asyncio.create_task(pump_ssh_to_ws()) + + # Idle watchdog: close after 30 min without client input + last_input = time.time() + IDLE_LIMIT = 1800 + + while True: + try: + packet = await asyncio.wait_for(ws.receive(), timeout=30.0) + except asyncio.TimeoutError: + if time.time() - last_input > IDLE_LIMIT: + await send_json({"type": "status", "message": "SSH idle timeout"}) + break + # keepalive ping to browser + await send_json({"type": "pong"}) + continue + + if packet.get("type") == "websocket.disconnect": + break + text = packet.get("text") + if text is None: + continue + last_input = time.time() + if text.startswith("{") and '"type"' in text[:48]: + try: + ctrl = json.loads(text) + except Exception: + process.stdin.write(text) + await process.stdin.drain() + continue + ctype = ctrl.get("type") + if ctype == "resize": + try: + process.change_terminal_size(int(ctrl.get("cols") or 80), int(ctrl.get("rows") or 24)) + except Exception: + pass + elif ctype == "data": + process.stdin.write(str(ctrl.get("data") or "")) + await process.stdin.drain() + elif ctype == "ping": + await send_json({"type": "pong"}) + continue + process.stdin.write(text) + await process.stdin.drain() + + except WebSocketDisconnect: + pass + except Exception as e: + log.warning("SSH websocket error: %s", e) + try: + await send_json({"type": "error", "message": str(e)}) + except Exception: + pass + finally: + SSH_SESSIONS.pop(session_id, None) + if reader_task: + reader_task.cancel() + try: + await reader_task + except Exception: + pass + try: + if process: + process.close() + await asyncio.wait_for(process.wait_closed(), timeout=3.0) + except Exception: + pass + try: + if conn: + conn.close() + await asyncio.wait_for(conn.wait_closed(), timeout=3.0) + except Exception: + pass + if acquired: + try: + _get_ssh_sem().release() + except Exception: + pass + try: + await ws.close() + except Exception: + pass + log.info("SSH session end id=%s target=%s active=%s", session_id, client_host, len(SSH_SESSIONS)) + + +@app.get("/api/ssh/sessions") +async def api_ssh_sessions(): + """Ops visibility: active SSH bridges (no secrets).""" + now = time.time() + sessions = [ + { + "id": sid, + "client": meta.get("client"), + "host": meta.get("host"), + "user": meta.get("user"), + "age_sec": int(now - float(meta.get("started") or now)), + } + for sid, meta in list(SSH_SESSIONS.items()) + ] + return {"active": len(sessions), "max": SSH_MAX_SESSIONS, "sessions": sessions} + + + + + +STATIC_DIR = Path("/ui") + + +@app.get("/") +async def index(): + resp = FileResponse(STATIC_DIR / "index.html") + resp.headers["Cache-Control"] = "no-store, no-cache, must-revalidate" + resp.headers["Pragma"] = "no-cache" + return resp + + +@app.get("/styles.css") +async def styles(): + return FileResponse(STATIC_DIR / "styles.css", media_type="text/css") + + +@app.get("/app.js") +async def app_js(): + return FileResponse(STATIC_DIR / "app.js", media_type="application/javascript") + + +@app.get("/ops.js") +async def ops_js(): + return FileResponse(STATIC_DIR / "ops.js", media_type="application/javascript") + + +@app.get("/ssh.js") +async def ssh_js(): + return FileResponse(STATIC_DIR / "ssh.js", media_type="application/javascript") + + +@app.get("/vendor/xterm/xterm.css") +async def vendor_xterm_css(): + return FileResponse(STATIC_DIR / "vendor/xterm/xterm.css", media_type="text/css") + + +@app.get("/vendor/xterm/xterm.min.js") +async def vendor_xterm_js(): + return FileResponse( + STATIC_DIR / "vendor/xterm/xterm.min.js", + media_type="application/javascript", + ) + + +@app.get("/vendor/xterm/xterm-addon-fit.min.js") +async def vendor_xterm_fit_js(): + return FileResponse( + STATIC_DIR / "vendor/xterm/xterm-addon-fit.min.js", + media_type="application/javascript", + ) + + +@app.get("/dell.png") +async def dell_png(): + return FileResponse(STATIC_DIR / "dell.png", media_type="image/png") + + +@app.get("/dell-mark.png") +async def dell_mark(): + return FileResponse(STATIC_DIR / "dell-mark.png", media_type="image/png") + + +@app.get("/dell.svg") +async def dell_svg(): + return FileResponse(STATIC_DIR / "dell.png", media_type="image/png") diff --git a/api/requirements.txt b/api/requirements.txt new file mode 100644 index 0000000..6de65ef --- /dev/null +++ b/api/requirements.txt @@ -0,0 +1,6 @@ +fastapi==0.115.6 +uvicorn[standard]==0.34.0 +httpx==0.28.1 +pydantic==2.10.4 +pydantic-settings==2.7.0 +asyncssh==2.18.0 diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..7fb5e54 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,19 @@ +services: + ome-cockpit: + build: . + container_name: ome-cockpit + restart: unless-stopped + ports: + - "3090:8090" + env_file: + - .env + volumes: + - ./ui:/ui:ro + - ./api/main.py:/app/main.py:ro + - ./data:/data + healthcheck: + test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen(\"http://127.0.0.1:8090/api/health\")"] + interval: 20s + timeout: 5s + retries: 5 + start_period: 25s diff --git a/ui/app.js b/ui/app.js new file mode 100644 index 0000000..18d0aaa --- /dev/null +++ b/ui/app.js @@ -0,0 +1,2253 @@ +(() => { + const $ = (sel) => document.querySelector(sel); + const canvas = $("#topo"); + const ctx = canvas.getContext("2d"); + + const state = { + data: null, + viewMode: "status", + layoutMode: "orbit", + clusterHubs: [], + laneGuides: [], + subnet: "all", + model: null, + groupHint: null, + kpiFocus: null, + selectedId: null, + inventoryCache: {}, + inventoryLoadingId: null, + notifiedEventKeys: new Set(), + lastPulse: 0, + filters: { + connected: false, + powered: false, + servers: true, + idrac: false, + hasPower: false, + ghostLinks: false, + pulseLinks: true, + minWatts: 0, + search: "", + }, + cam: { x: 0, y: 0, scale: 1 }, + nodes: [], + hub: null, + dragging: false, + last: null, + hoverId: null, + connectNode: null, + pulseT: 0, + modelColors: new Map(), + subnetColors: new Map(), + }; + + const PALETTE = [ + "#00a8e8", "#3dffe0", "#ffb020", "#7ec8ff", "#3dffa0", + "#ff7a59", "#c4a7ff", "#f0e68c", "#5eead4", "#f472b6", + ]; + + function colorFor(map, key) { + if (!map.has(key)) map.set(key, PALETTE[map.size % PALETTE.length]); + return map.get(key); + } + + function statusColor(status) { + const s = String(status || ""); + if (s === "1000" || s === "0") return "#3dffa0"; + if (s === "2000" || s === "2") return "#ffb020"; + if (s === "3000" || s === "3" || s === "4000") return "#ff5c5c"; + return "#7a93a8"; + } + + function powerColor(watts) { + if (watts == null) return "#3a4a5a"; + if (watts < 200) return "#3dffa0"; + if (watts < 450) return "#00a8e8"; + if (watts < 650) return "#ffb020"; + return "#ff5c5c"; + } + + function nodeColor(n) { + switch (state.viewMode) { + case "power": + return powerColor(n.watts); + case "connection": + return n.connected ? "#3dffe0" : "#ff5c5c"; + case "model": + return colorFor(state.modelColors, n.model || "?"); + case "subnet": + return colorFor(state.subnetColors, n.subnet || "?"); + default: + if (!n.connected) return "#5a6a7a"; + return statusColor(n.status); + } + } + + function visibleDevices() { + const d = state.data; + if (!d) return []; + const f = state.filters; + const q = (f.search || "").trim().toLowerCase(); + + // Type filters are INCLUDE toggles: + // - Servers on => include servers + // - iDRACs on => include iDRACs + // - both off => show nothing (do not silently show all) + const includeServers = !!f.servers; + const includeIdrac = !!f.idrac; + if (!includeServers && !includeIdrac) return []; + + return (d.devices || []).filter((n) => { + if (state.subnet !== "all" && n.subnet !== state.subnet) return false; + if (state.model && n.model !== state.model) return false; + + const isServer = !!n.is_server; + const isIdrac = !!n.is_idrac; + const typeOk = + (includeServers && isServer) || + (includeIdrac && isIdrac); + if (!typeOk) return false; + + if (f.connected && !n.connected) return false; + if (f.powered && !n.powered_on) return false; + if (f.hasPower && n.watts == null) return false; + if (f.minWatts > 0 && (n.watts == null || n.watts < f.minWatts)) return false; + + if (state.kpiFocus === "offline" && (n.connected || !n.is_server)) return false; + if (state.kpiFocus === "connected" && !n.connected) return false; + if (state.kpiFocus === "powered" && !n.powered_on) return false; + if (state.kpiFocus === "idracs" && !n.is_idrac) return false; + if (state.kpiFocus === "power" && n.watts == null) return false; + + if (q) { + const hay = [n.name, n.model, n.service_tag, n.ip, n.subnet] + .filter(Boolean) + .join(" ") + .toLowerCase(); + if (!hay.includes(q)) return false; + } + return true; + }); + } + + function groupBySubnet(devices) { + const bySubnet = new Map(); + for (const n of devices) { + const k = n.subnet || "unknown"; + if (!bySubnet.has(k)) bySubnet.set(k, []); + bySubnet.get(k).push(n); + } + return [...bySubnet.keys()].sort().map((k) => ({ cidr: k, members: bySubnet.get(k) })); + } + + function nodeRadius(n) { + return n.connected ? 8 : 5.5; + } + + function setTargets(nodes) { + // preserve current x/y for lerp; first time seed from target + const prev = new Map(state.nodes.map((n) => [n.id, n])); + for (const n of nodes) { + const p = prev.get(n.id); + if (p && Number.isFinite(p.x)) { + n.x = p.x; + n.y = p.y; + } else { + n.x = n.tx; + n.y = n.ty; + } + } + state.nodes = nodes; + } + + function layoutOrbit(devices, cx, cy, w, h) { + const groups = groupBySubnet(devices); + const ringBase = Math.min(w, h) * 0.18; + const nodes = []; + groups.forEach((g, si) => { + const ring = ringBase + si * Math.min(70, Math.max(42, 360 / Math.max(groups.length, 1))); + g.members.forEach((n, i) => { + const a = (i / Math.max(g.members.length, 1)) * Math.PI * 2 - Math.PI / 2 + si * 0.15; + const jitter = (n.id % 7) * 2.2; + nodes.push({ + ...n, + tx: cx + Math.cos(a) * (ring + jitter), + ty: cy + Math.sin(a) * (ring + jitter), + r: nodeRadius(n), + depth: 1, + }); + }); + }); + state.clusterHubs = []; + state.laneGuides = []; + setTargets(nodes); + } + + function layoutGalaxy(devices, cx, cy, w, h) { + const groups = groupBySubnet(devices); + const nodes = []; + const arms = Math.max(groups.length, 1); + const maxR = Math.min(w, h) * 0.42; + groups.forEach((g, si) => { + const armAngle = (si / arms) * Math.PI * 2; + g.members.forEach((n, i) => { + const t = (i + 1) / (g.members.length + 1); + const r = 70 + t * maxR; + const twist = t * 3.2 + armAngle; + const wobble = Math.sin(i * 1.7 + si) * 12; + nodes.push({ + ...n, + tx: cx + Math.cos(twist) * r + Math.cos(twist + Math.PI / 2) * wobble * 0.35, + ty: cy + Math.sin(twist) * r + Math.sin(twist + Math.PI / 2) * wobble * 0.35, + r: nodeRadius(n), + depth: 0.6 + t * 0.8, + arm: si, + }); + }); + }); + state.clusterHubs = []; + state.laneGuides = []; + setTargets(nodes); + } + + function layoutClusters(devices, cx, cy, w, h) { + const groups = groupBySubnet(devices); + const nodes = []; + const hubs = []; + const R = Math.min(w, h) * 0.32; + groups.forEach((g, si) => { + const a = (si / Math.max(groups.length, 1)) * Math.PI * 2 - Math.PI / 2; + const hx = cx + Math.cos(a) * R; + const hy = cy + Math.sin(a) * R; + hubs.push({ x: hx, y: hy, label: g.cidr, color: colorFor(state.subnetColors, g.cidr) }); + const localR = 28 + Math.min(90, g.members.length * 4.5); + g.members.forEach((n, i) => { + const la = (i / Math.max(g.members.length, 1)) * Math.PI * 2; + nodes.push({ + ...n, + tx: hx + Math.cos(la) * localR, + ty: hy + Math.sin(la) * localR, + r: nodeRadius(n), + depth: 1, + cluster: si, + }); + }); + }); + state.clusterHubs = hubs; + state.laneGuides = []; + setTargets(nodes); + } + + function layoutLanes(devices, cx, cy, w, h) { + const groups = groupBySubnet(devices); + const nodes = []; + const guides = []; + const top = 70; + const bottom = h - 50; + const span = Math.max(bottom - top, 120); + groups.forEach((g, si) => { + const y = top + (groups.length <= 1 ? span / 2 : (si / (groups.length - 1 || 1)) * span); + guides.push({ y, label: g.cidr, color: colorFor(state.subnetColors, g.cidr) }); + g.members.forEach((n, i) => { + const t = g.members.length <= 1 ? 0.5 : i / (g.members.length - 1); + const x = 90 + t * (w - 160); + const bob = Math.sin(i * 0.9 + si) * 10; + nodes.push({ + ...n, + tx: x, + ty: y + bob, + r: nodeRadius(n), + depth: 1, + lane: si, + }); + }); + }); + state.clusterHubs = []; + state.laneGuides = guides; + // hub left side + state.hub = { x: 48, y: cy, r: 26 }; + setTargets(nodes); + } + + function layoutHelix(devices, cx, cy, w, h) { + const list = [...devices].sort((a, b) => Number(b.connected) - Number(a.connected) || (b.watts || 0) - (a.watts || 0)); + const nodes = []; + const turns = 2.4; + list.forEach((n, i) => { + const t = list.length <= 1 ? 0.5 : i / (list.length - 1); + const angle = t * Math.PI * 2 * turns; + const y = 60 + t * (h - 120); + const amp = Math.min(w, h) * 0.28; + // perspective: scale by "depth" + const depth = 0.45 + 0.55 * (0.5 + 0.5 * Math.sin(angle)); + const x = cx + Math.cos(angle) * amp * depth; + nodes.push({ + ...n, + tx: x, + ty: y + Math.sin(angle * 2) * 8, + r: (n.connected ? 7 : 4.5) * (0.75 + depth * 0.55), + depth, + helixT: t, + }); + }); + state.clusterHubs = []; + state.laneGuides = []; + setTargets(nodes); + } + + function layout() { + const devices = visibleDevices(); + const w = canvas.clientWidth; + const h = canvas.clientHeight; + const cx = w / 2; + const cy = h / 2; + if (state.layoutMode !== "lanes") { + state.hub = { x: cx, y: cy, r: 28 }; + } + switch (state.layoutMode) { + case "galaxy": + layoutGalaxy(devices, cx, cy, w, h); + break; + case "clusters": + layoutClusters(devices, cx, cy, w, h); + break; + case "lanes": + layoutLanes(devices, cx, cy, w, h); + break; + case "helix": + layoutHelix(devices, cx, cy, w, h); + break; + default: + layoutOrbit(devices, cx, cy, w, h); + } + } + + function resize() { + const dpr = Math.min(window.devicePixelRatio || 1, 2); + const w = canvas.clientWidth; + const h = canvas.clientHeight; + canvas.width = Math.floor(w * dpr); + canvas.height = Math.floor(h * dpr); + ctx.setTransform(dpr, 0, 0, dpr, 0, 0); + layout(); + } + + function drawHub(hub, t) { + const hubGlow = 16 + 6 * Math.sin(t * 0.05); + const g = ctx.createRadialGradient(hub.x, hub.y, 4, hub.x, hub.y, hubGlow + 20); + g.addColorStop(0, "rgba(0,118,206,0.55)"); + g.addColorStop(1, "rgba(0,118,206,0)"); + ctx.fillStyle = g; + ctx.beginPath(); + ctx.arc(hub.x, hub.y, hubGlow + 20, 0, Math.PI * 2); + ctx.fill(); + ctx.beginPath(); + ctx.arc(hub.x, hub.y, hub.r, 0, Math.PI * 2); + ctx.fillStyle = "#0076ce"; + ctx.fill(); + ctx.strokeStyle = "#3dffe0"; + ctx.lineWidth = 2; + ctx.stroke(); + ctx.fillStyle = "#fff"; + ctx.font = "700 11px IBM Plex Sans, sans-serif"; + ctx.textAlign = "center"; + ctx.textBaseline = "middle"; + ctx.fillText("OME", hub.x, hub.y); + } + + function drawPulseLink(x0, y0, x1, y1, connected, t, id, alphaScale) { + if (!connected && !state.filters.ghostLinks) return; + const animate = state.filters.pulseLinks !== false; + const alpha = connected + ? (animate ? (0.55 + 0.35 * Math.sin(t * 0.05 + id)) : 0.72) * alphaScale + : 0.06 * alphaScale; + // glow underlay for live OME links + if (connected) { + ctx.beginPath(); + ctx.moveTo(x0, y0); + ctx.lineTo(x1, y1); + ctx.strokeStyle = `rgba(0,168,232,${(animate ? 0.22 : 0.14) * alphaScale})`; + ctx.lineWidth = animate ? 4.5 : 3.2; + ctx.stroke(); + } + ctx.beginPath(); + ctx.moveTo(x0, y0); + ctx.lineTo(x1, y1); + ctx.strokeStyle = connected ? `rgba(61,255,224,${alpha})` : `rgba(90,106,122,${0.14 * alphaScale})`; + ctx.lineWidth = connected ? 2.4 : 0.8; + ctx.stroke(); + if (connected && animate) { + // dual packets along the link + for (const off of [0, 0.5]) { + const u = ((t * 0.018 + (id % 50) * 0.02 + off) % 1); + const px = x0 + (x1 - x0) * u; + const py = y0 + (y1 - y0) * u; + ctx.beginPath(); + ctx.arc(px, py, 3.2, 0, Math.PI * 2); + ctx.fillStyle = "rgba(255,255,255,0.95)"; + ctx.fill(); + ctx.beginPath(); + ctx.arc(px, py, 5.5, 0, Math.PI * 2); + ctx.strokeStyle = "rgba(61,255,224,0.55)"; + ctx.lineWidth = 1.5; + ctx.stroke(); + } + } + } + + function drawDecor(w, h, hub, t) { + const mode = state.layoutMode; + if (mode === "orbit" || mode === "galaxy") { + for (let i = 1; i <= 5; i++) { + ctx.beginPath(); + ctx.arc(hub.x, hub.y, 70 * i * 0.5, 0, Math.PI * 2); + ctx.strokeStyle = `rgba(0,168,232,${0.035 + i * 0.012})`; + ctx.lineWidth = 1; + ctx.stroke(); + } + if (mode === "galaxy") { + // faint spiral guide + ctx.beginPath(); + for (let i = 0; i <= 120; i++) { + const u = i / 120; + const ang = u * Math.PI * 4; + const r = 40 + u * Math.min(w, h) * 0.4; + const x = hub.x + Math.cos(ang) * r; + const y = hub.y + Math.sin(ang) * r; + if (i === 0) ctx.moveTo(x, y); + else ctx.lineTo(x, y); + } + ctx.strokeStyle = "rgba(0,168,232,0.08)"; + ctx.lineWidth = 1.2; + ctx.stroke(); + } + } else if (mode === "clusters") { + for (const ch of state.clusterHubs || []) { + ctx.beginPath(); + ctx.arc(ch.x, ch.y, 52, 0, Math.PI * 2); + ctx.strokeStyle = (ch.color || "#00a8e8") + "33"; + ctx.lineWidth = 1.2; + ctx.stroke(); + ctx.beginPath(); + ctx.arc(ch.x, ch.y, 10, 0, Math.PI * 2); + ctx.fillStyle = ch.color || "#00a8e8"; + ctx.globalAlpha = 0.55; + ctx.fill(); + ctx.globalAlpha = 1; + ctx.fillStyle = "rgba(232,244,255,0.7)"; + ctx.font = "500 9px IBM Plex Mono, monospace"; + ctx.textAlign = "center"; + ctx.fillText((ch.label || "").slice(0, 18), ch.x, ch.y - 18); + drawPulseLink(hub.x, hub.y, ch.x, ch.y, true, t, (ch.label || "").length * 17, 0.55); + } + } else if (mode === "lanes") { + for (const g of state.laneGuides || []) { + ctx.beginPath(); + ctx.moveTo(70, g.y); + ctx.lineTo(w - 30, g.y); + ctx.strokeStyle = (g.color || "#00a8e8") + "44"; + ctx.lineWidth = 2; + ctx.stroke(); + // moving dashes + const dashX = ((t * 1.8) % (w - 100)) + 70; + ctx.beginPath(); + ctx.arc(dashX, g.y, 2.5, 0, Math.PI * 2); + ctx.fillStyle = g.color || "#3dffe0"; + ctx.fill(); + ctx.fillStyle = "rgba(232,244,255,0.55)"; + ctx.font = "500 9px IBM Plex Mono, monospace"; + ctx.textAlign = "left"; + ctx.fillText((g.label || "").slice(0, 16), 74, g.y - 8); + } + } else if (mode === "helix") { + // depth rails + for (let i = 0; i < 3; i++) { + ctx.beginPath(); + for (let s = 0; s <= 80; s++) { + const u = s / 80; + const ang = u * Math.PI * 2 * 2.4 + i * 0.9; + const y = 60 + u * (h - 120); + const amp = Math.min(w, h) * 0.28; + const depth = 0.45 + 0.55 * (0.5 + 0.5 * Math.sin(ang)); + const x = hub.x + Math.cos(ang) * amp * depth; + if (s === 0) ctx.moveTo(x, y); + else ctx.lineTo(x, y); + } + ctx.strokeStyle = `rgba(0,168,232,${0.06 + i * 0.03})`; + ctx.lineWidth = 1; + ctx.stroke(); + } + } + } + + function drawLinks(hub, t) { + const mode = state.layoutMode; + if (mode === "clusters") { + // node to nearest cluster hub + for (const n of state.nodes) { + let best = null; + let bestD = Infinity; + for (const ch of state.clusterHubs || []) { + const dx = n.x - ch.x; + const dy = n.y - ch.y; + const d = dx * dx + dy * dy; + if (d < bestD) { + bestD = d; + best = ch; + } + } + if (best) drawPulseLink(best.x, best.y, n.x, n.y, n.connected, t, n.id, 0.85); + } + return; + } + if (mode === "lanes") { + for (const n of state.nodes) { + drawPulseLink(hub.x, hub.y, n.x, n.y, n.connected, t, n.id, 0.55); + } + return; + } + if (mode === "helix") { + // chain neighbors + faint hub links for connected + const sorted = [...state.nodes].sort((a, b) => (a.helixT || 0) - (b.helixT || 0)); + for (let i = 0; i < sorted.length - 1; i++) { + const a = sorted[i]; + const b = sorted[i + 1]; + drawPulseLink(a.x, a.y, b.x, b.y, a.connected || b.connected, t, a.id, 0.7); + } + for (const n of state.nodes) { + if (n.connected) drawPulseLink(hub.x, hub.y, n.x, n.y, true, t, n.id, 0.25); + } + return; + } + // orbit / galaxy + for (const n of state.nodes) { + drawPulseLink(hub.x, hub.y, n.x, n.y, n.connected, t, n.id, 1); + } + } + + function drawNodes(t) { + // draw far (small depth) first for helix + const list = [...state.nodes].sort((a, b) => (a.depth || 1) - (b.depth || 1)); + for (const n of list) { + // lerp toward target + if (Number.isFinite(n.tx)) { + n.x += (n.tx - n.x) * 0.14; + n.y += (n.ty - n.y) * 0.14; + } + const col = nodeColor(n); + const selected = n.id === state.selectedId; + const depth = n.depth || 1; + if (selected) { + ctx.beginPath(); + ctx.arc(n.x, n.y, n.r + 6, 0, Math.PI * 2); + ctx.strokeStyle = "#fff"; + ctx.lineWidth = 2; + ctx.stroke(); + } + if (n.watts != null && state.viewMode === "power") { + ctx.beginPath(); + ctx.arc(n.x, n.y, n.r + 3 + Math.min(10, n.watts / 80), 0, Math.PI * 2); + ctx.strokeStyle = col + "55"; + ctx.lineWidth = 2; + ctx.stroke(); + } + ctx.beginPath(); + ctx.arc(n.x, n.y, n.r, 0, Math.PI * 2); + ctx.fillStyle = col; + ctx.globalAlpha = 0.55 + 0.45 * Math.min(depth, 1); + ctx.fill(); + ctx.globalAlpha = 1; + if (state.cam.scale > 0.85) { + ctx.fillStyle = "rgba(232,244,255,0.85)"; + ctx.font = "500 9px IBM Plex Mono, monospace"; + ctx.textAlign = "center"; + ctx.textBaseline = "top"; + const label = + state.viewMode === "power" && n.watts != null + ? `${Math.round(n.watts)}W` + : (n.name || "").slice(0, 18); + ctx.fillText(label, n.x, n.y + n.r + 3); + } + } + } + + function draw() { + const w = canvas.clientWidth; + const h = canvas.clientHeight; + // hard clear in device pixels (avoids trail artifacts with DPR transform) + ctx.save(); + ctx.setTransform(1, 0, 0, 1, 0, 0); + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.restore(); + + ctx.save(); + ctx.translate(state.cam.x, state.cam.y); + ctx.scale(state.cam.scale, state.cam.scale); + + const hub = state.hub; + if (!hub) { + ctx.restore(); + requestAnimationFrame(draw); + return; + } + + const t = state.pulseT; + drawDecor(w, h, hub, t); + drawLinks(hub, t); + drawHub(hub, t); + drawNodes(t); + + ctx.restore(); + + if (!state.nodes.length) { + ctx.fillStyle = "rgba(232,244,255,0.82)"; + ctx.font = "600 15px IBM Plex Sans, sans-serif"; + ctx.textAlign = "center"; + ctx.textBaseline = "middle"; + const f = state.filters; + const tip = (!f.servers && !f.idrac) + ? "No types selected — enable Servers and/or iDRACs in Filters" + : "No devices match the current filters"; + ctx.fillText(tip, w / 2, h / 2); + ctx.font = "500 12px IBM Plex Mono, monospace"; + ctx.fillStyle = "rgba(122,147,168,0.95)"; + ctx.fillText("Adjust Filters or click Reset filters", w / 2, h / 2 + 28); + } + + if (state.filters.pulseLinks !== false) state.pulseT += 1; + requestAnimationFrame(draw); + } + + function screenToWorld(sx, sy) { + return { + x: (sx - state.cam.x) / state.cam.scale, + y: (sy - state.cam.y) / state.cam.scale, + }; + } + + function hitTest(sx, sy) { + const p = screenToWorld(sx, sy); + if (state.hub) { + const dx = p.x - state.hub.x; + const dy = p.y - state.hub.y; + if (dx * dx + dy * dy <= (state.hub.r + 6) ** 2) return { type: "hub" }; + } + let best = null; + let bestD = Infinity; + for (const n of state.nodes) { + const dx = p.x - n.x; + const dy = p.y - n.y; + const d = dx * dx + dy * dy; + if (d <= (n.r + 8) ** 2 && d < bestD) { + bestD = d; + best = n; + } + } + return best ? { type: "node", node: best } : null; + } + + + const KPI_META = { + total: { title: "All nodes", blurb: "Full OME inventory currently in cockpit." }, + servers: { title: "Servers", blurb: "Server-class devices (OME type 1000)." }, + idracs: { title: "iDRACs", blurb: "iDRAC / BMC endpoints discovered in OME." }, + connected: { title: "Connected", blurb: "Devices with live OME connection state." }, + offline: { title: "Offline", blurb: "Devices currently not connected to OME." }, + powered: { title: "Powered on", blurb: "Devices reporting powered-on state." }, + power: { title: "Live power", blurb: "Nodes with a live watt reading — hottest first." }, + avgw: { title: "Average watts / node", blurb: "Power samples contributing to fleet average." }, + samples: { title: "Power samples", blurb: "Devices included in the live power sample set." }, + }; + + let kpiPopup = { key: null, selectedId: null, q: "", sort: "name" }; + + function devicesForKpi(key) { + const all = state.data?.devices || []; + switch (key) { + case "servers": + return all.filter((d) => d.is_server); + case "idracs": + return all.filter((d) => d.is_idrac); + case "connected": + return all.filter((d) => d.connected); + case "offline": + return all.filter((d) => !d.connected); + case "powered": + return all.filter((d) => d.powered_on); + case "power": + case "avgw": + case "samples": + return all.filter((d) => d.watts != null); + case "total": + default: + return all.slice(); + } + } + + function sortKpiDevices(list) { + const sort = kpiPopup.sort || "name"; + const arr = list.slice(); + if (sort === "watts") arr.sort((a, b) => (b.watts || 0) - (a.watts || 0)); + else if (sort === "status") arr.sort((a, b) => String(a.status || "").localeCompare(String(b.status || ""))); + else if (sort === "subnet") arr.sort((a, b) => String(a.subnet || "").localeCompare(String(b.subnet || ""))); + else arr.sort((a, b) => String(a.name || "").localeCompare(String(b.name || ""))); + return arr; + } + + function filterKpiDevices(list) { + const q = (kpiPopup.q || "").trim().toLowerCase(); + if (!q) return list; + return list.filter((d) => + [d.name, d.ip, d.model, d.service_tag, d.subnet, d.status] + .filter(Boolean) + .join(" ") + .toLowerCase() + .includes(q) + ); + } + + function kpiSummaryHtml(key, list) { + const connected = list.filter((d) => d.connected).length; + const offline = list.length - connected; + const powered = list.filter((d) => d.powered_on).length; + const withW = list.filter((d) => d.watts != null); + const watts = withW.reduce((a, d) => a + (d.watts || 0), 0); + const subnets = new Set(list.map((d) => d.subnet).filter(Boolean)).size; + const pills = [ + `${list.length} in view`, + `${connected} connected`, + `${offline} offline`, + `${powered} powered`, + withW.length ? `${Math.round(watts)} W sampled` : "no power samples", + `${subnets} subnets`, + ]; + if (key === "power" || key === "avgw" || key === "samples") { + const top = sortKpiDevices(withW).slice(0, 1)[0]; + if (top) pills.push(`hottest ${top.name?.slice(0, 22)} ${Math.round(top.watts)}W`); + } + return pills.map((p) => `${escapeHtml(p)}`).join(""); + } + + function renderKpiDetail(node) { + const el = $("#kpi-detail"); + if (!el) return; + if (!node) { + el.innerHTML = `

Select a system on the left for live context and actions.

`; + return; + } + const alerts = (state.data?.alerts || []).filter((a) => a.device_id === node.id).slice(0, 5); + el.innerHTML = ` +

${escapeHtml(node.name || "device")}

+

${escapeHtml(node.model || "—")} · ${escapeHtml(node.service_tag || "no tag")} · id ${node.id}

+
+ ${node.connected ? "CONNECTED" : "OFFLINE"} + ${node.powered_on ? "POWERED ON" : "POWER N/A"} + ${node.watts != null ? `${Math.round(node.watts)} W` : ""} + ${node.is_idrac ? `iDRAC` : ""} + ${node.is_server ? `SERVER` : ""} +
+
+
IP${escapeHtml(node.ip || "—")}
+
Subnet${escapeHtml(node.subnet || "—")}
+
Status${escapeHtml(node.status || "—")}
+
Avg / peak${node.avg_watts != null ? Math.round(node.avg_watts) + " W" : "—"} / ${node.peak_watts != null ? Math.round(node.peak_watts) + " W" : "—"}
+
Last status${escapeHtml(node.last_status_time || "—")}
+
+
+ + + + + + ${node.idrac_url ? `iDRAC Web` : ""} +
+
+

Related alerts

+ ${ + alerts.length + ? alerts + .map( + (a) => + `
${escapeHtml(a.severity)} · ${escapeHtml((a.message || "").slice(0, 120))}
` + ) + .join("") + : `

No alerts for this node in the current feed.

` + } +
`; + } + + function renderKpiPopup() { + const key = kpiPopup.key; + if (!key) return; + const meta = KPI_META[key] || { title: key, blurb: "" }; + const raw = devicesForKpi(key); + const list = sortKpiDevices(filterKpiDevices(raw)); + $("#kpi-title").textContent = meta.title; + $("#kpi-sub").textContent = `${meta.blurb} · ${list.length} shown of ${raw.length}`; + $("#kpi-summary").innerHTML = kpiSummaryHtml(key, raw); + + const listEl = $("#kpi-list"); + if (!list.length) { + listEl.innerHTML = `

No systems match this KPI / search.

`; + renderKpiDetail(null); + return; + } + if (kpiPopup.selectedId == null || !list.some((d) => d.id === kpiPopup.selectedId)) { + kpiPopup.selectedId = list[0].id; + } + listEl.innerHTML = list + .slice(0, 200) + .map((d) => { + const bits = [ + d.ip || "no IP", + d.connected ? "up" : "down", + d.watts != null ? Math.round(d.watts) + "W" : null, + d.subnet, + ] + .filter(Boolean) + .join(" · "); + return ``; + }) + .join(""); + const selected = list.find((d) => d.id === kpiPopup.selectedId) || null; + renderKpiDetail(selected); + } + + function openKpiPopup(key) { + kpiPopup.key = key; + kpiPopup.selectedId = null; + kpiPopup.q = ""; + const search = $("#kpi-search"); + if (search) search.value = ""; + const modal = $("#kpi-modal"); + const scrim = $("#scrim"); + modal?.classList.remove("hidden"); + modal?.setAttribute("aria-hidden", "false"); + scrim?.classList.add("open"); + if (scrim) scrim.dataset.mode = "kpi"; + renderKpiPopup(); + } + + function closeKpiPopup() { + const modal = $("#kpi-modal"); + modal?.classList.add("hidden"); + modal?.setAttribute("aria-hidden", "true"); + const scrim = $("#scrim"); + if (scrim?.dataset.mode === "kpi") { + scrim.classList.remove("open"); + delete scrim.dataset.mode; + } + } + + function applyKpiAsFilter(key) { + state.kpiFocus = key; + // Align type filters so the map can show the KPI set + if (key === "idracs") { + state.filters.idrac = true; + state.filters.servers = false; + } else if (key === "servers" || key === "offline" || key === "powered" || key === "connected" || key === "total") { + state.filters.servers = true; + // keep idrac optional for total/connected/offline breadth + if (key === "total" || key === "connected" || key === "offline") { + state.filters.idrac = true; + } + } + if (key === "connected") state.filters.connected = true; + if (key === "powered") state.filters.powered = true; + if (key === "power" || key === "avgw" || key === "samples") { + state.filters.hasPower = true; + state.viewMode = "power"; + $("#view-modes")?.querySelectorAll(".chip").forEach((c) => + c.classList.toggle("active", c.dataset.mode === "power") + ); + } + syncFilterInputs(); + refreshLists(); + layout(); + snapNodes(); + fitCameraToNodes(); + updateFocusContext(); + showToast(`Map filter: ${KPI_META[key]?.title || key}`); + } + + + function renderKpis() { + const s = state.data?.summary || {}; + const items = [ + { key: "total", label: "Nodes", v: s.total ?? "—", cls: "" }, + { key: "servers", label: "Servers", v: s.servers ?? "—", cls: "" }, + { key: "idracs", label: "iDRACs", v: s.idracs ?? "—", cls: "" }, + { key: "connected", label: "Connected", v: s.connected ?? "—", cls: "" }, + { key: "offline", label: "Offline", v: s.offline ?? "—", cls: "warn" }, + { key: "powered", label: "Powered on", v: s.powered_on ?? "—", cls: "" }, + { + key: "power", + label: "Live power", + v: s.total_watts != null ? `${Math.round(s.total_watts)} W` : "—", + cls: "power", + }, + { + key: "avgw", + label: "Avg / node", + v: s.avg_node_watts != null ? `${Math.round(s.avg_node_watts)} W` : "—", + cls: "power", + }, + { + key: "samples", + label: "Power samples", + v: s.power_samples ?? "—", + cls: "", + }, + ]; + $("#kpi-strip").innerHTML = items + .map( + (it) => ` + ` + ) + .join(""); + } + + function renderSubnets() { + const subs = state.data?.subnets || []; + const html = [ + ``, + ...subs.map( + (s) => `` + ), + ]; + $("#subnet-list").innerHTML = html.join(""); + } + + function renderModels() { + const models = state.data?.models || []; + $("#model-list").innerHTML = [ + ``, + ...models.map( + (m) => `` + ), + ].join(""); + } + + function renderGroups() { + const groups = state.data?.groups || []; + $("#group-list").innerHTML = groups.length + ? groups + .map( + (g) => `` + ) + .join("") + : `

No groups loaded

`; + } + + function renderLegend() { + const el = $("#legend"); + if (state.viewMode === "power") { + el.innerHTML = ` + <200W + 200–450W + 450–650W + >650W + geen reading`; + } else if (state.viewMode === "connection") { + el.innerHTML = `connectedoffline`; + } else if (state.viewMode === "model") { + el.innerHTML = [...state.modelColors.entries()] + .slice(0, 6) + .map(([k, c]) => `${escapeHtml(k.slice(0, 22))}`) + .join(""); + } else if (state.viewMode === "subnet") { + el.innerHTML = [...state.subnetColors.entries()] + .slice(0, 6) + .map(([k, c]) => `${escapeHtml(k)}`) + .join(""); + } else { + el.innerHTML = ` + healthy + warning + critical + offline`; + } + } + + function renderTicker() { + const d = state.data; + if (!d) return; + const ome = d.ome || {}; + const s = d.summary || {}; + const ctx = d.context || {}; + const sev = ctx.alert_severity || {}; + $("#ticker").innerHTML = ` + + · + + · + + · + + · + + · + + · + updated ${d.updated_at ? new Date(d.updated_at * 1000).toLocaleTimeString() : "—"} + `; + } + + function escapeHtml(s) { + return String(s ?? "") + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/"/g, """); + } + function escapeAttr(s) { + return escapeHtml(s).replace(/'/g, "'"); + } + + function sevClass(sev) { + const s = String(sev || "").toLowerCase(); + if (s.includes("crit")) return "critical"; + if (s.includes("warn")) return "warning"; + return "info"; + } + + function relTime(ts) { + if (!ts) return "—"; + let t; + if (typeof ts === "number") t = ts * (ts > 1e12 ? 1 : 1000); + else { + // OME: "2026-07-16 23:36:33.858" + const d = Date.parse(String(ts).replace(" ", "T") + "Z"); + t = Number.isFinite(d) ? d : Date.parse(String(ts)); + } + if (!Number.isFinite(t)) return String(ts).slice(0, 19); + const sec = Math.max(0, Math.round((Date.now() - t) / 1000)); + if (sec < 60) return sec + "s ago"; + if (sec < 3600) return Math.floor(sec / 60) + "m ago"; + if (sec < 86400) return Math.floor(sec / 3600) + "h ago"; + return Math.floor(sec / 86400) + "d ago"; + } + + function updateFocusContext() { + const el = $("#ctx-focus"); + if (!el) return; + const bits = []; + bits.push("layout " + (state.layoutMode || "orbit")); + bits.push("color " + (state.viewMode || "status")); + bits.push(state.subnet === "all" ? "all networks" : state.subnet); + if (state.model) bits.push(state.model); + const types = []; + if (state.filters.servers) types.push("servers"); + if (state.filters.idrac) types.push("iDRACs"); + bits.push(types.length ? types.join("+") : "no types"); + if (state.filters.connected) bits.push("connected"); + if (state.filters.powered) bits.push("powered"); + if (state.filters.hasPower) bits.push("has W"); + if (state.filters.minWatts > 0) bits.push("≥" + state.filters.minWatts + "W"); + if (state.filters.pulseLinks === false) bits.push("pulse off"); + if (state.filters.search) bits.push("“" + state.filters.search.slice(0, 18) + "”"); + if (state.selectedId) { + const n = (state.data?.devices || []).find((d) => d.id === state.selectedId); + if (n) bits.push("node " + (n.name || "").slice(0, 22)); + } + bits.push(state.nodes.length + " visible"); + el.textContent = "Focus: " + bits.join(" · "); + } + + function renderContext() { + const d = state.data; + const ctx = d?.context || {}; + const s = d?.summary || {}; + const live = $("#ctx-live-text"); + if (live) { + const age = d?.updated_at ? relTime(d.updated_at) : "—"; + live.textContent = + (ctx.focus_hint || "Realtime context") + + " · pulse #" + + (d?.pulse ?? 0) + + " · " + + age; + } + const stats = $("#ctx-stats"); + if (stats) { + const sev = ctx.alert_severity || {}; + stats.innerHTML = ` + + + + `; + } + + // alerts in left rail + const al = $("#alert-list"); + if (al) { + const alerts = (d?.alerts || []).slice(0, 12); + if (!alerts.length) { + al.innerHTML = `

No alerts in this snapshot

`; + } else { + al.innerHTML = alerts + .map( + (a) => `` + ) + .join(""); + } + } + + // live feed overlay: merge events + alerts + const body = $("#ctx-feed-body"); + const meta = $("#ctx-feed-meta"); + if (meta) { + meta.textContent = + (ctx.alerts_total != null ? ctx.alerts_total + " alerts total" : "alerts…") + + (ctx.events_new ? ` · +${ctx.events_new} delta` : ""); + } + if (body) { + if ($("#ctx-feed")?.classList.contains("collapsed")) { + body.innerHTML = ""; + updateFocusContext(); + return; + } + const items = []; + for (const e of d?.events || []) { + items.push({ + cls: sevClass(e.severity), + title: e.title || e.kind, + msg: e.text, + sub: (e.kind || "delta") + " · " + relTime(e.ts), + deviceId: e.device_id, + sort: e.ts || 0, + }); + } + for (const a of (d?.alerts || []).slice(0, 15)) { + let sort = 0; + const parsed = Date.parse(String(a.time || "").replace(" ", "T") + "Z"); + sort = Number.isFinite(parsed) ? parsed / 1000 : 0; + items.push({ + cls: sevClass(a.severity), + title: (a.device || "OME") + " · " + (a.severity || ""), + msg: a.message || "", + sub: (a.category || "alert") + " · " + relTime(a.time), + deviceId: a.device_id, + sort, + }); + } + // hottest quick context + for (const h of ctx.hottest || []) { + items.push({ + cls: "info", + title: "Hot · " + (h.name || "").slice(0, 24), + msg: Math.round(h.watts) + " W · " + (h.subnet || ""), + sub: "power ranking", + deviceId: h.id, + sort: (d?.updated_at || 0) + (h.watts || 0) / 1e6, + }); + } + items.sort((x, y) => (y.sort || 0) - (x.sort || 0)); + body.innerHTML = items + .slice(0, 24) + .map( + (it) => `` + ) + .join(""); + } + updateFocusContext(); + } + + function focusDeviceId(id) { + if (id == null || id === "") return; + const nid = Number(id); + const n = (state.data?.devices || []).find((d) => d.id === nid || d.id === id); + if (!n) return; + state.selectedId = n.id; + // ensure visible: clear blocking filters lightly + showInspector(n); + // pan toward node if laid out + const laid = state.nodes.find((x) => x.id === n.id); + if (laid) { + const w = canvas.clientWidth; + const h = canvas.clientHeight; + state.cam.x = w / 2 - laid.x * state.cam.scale; + state.cam.y = h / 2 - laid.y * state.cam.scale; + } + updateFocusContext(); + } + + function snapNodes() { + for (const n of state.nodes) { + if (Number.isFinite(n.tx)) { + n.x = n.tx; + n.y = n.ty; + } + } + } + + function fitCameraToNodes(opts = {}) { + const nodes = state.nodes; + const w = canvas.clientWidth; + const h = canvas.clientHeight; + if (!w || !h) { + state.cam = { x: 0, y: 0, scale: 1 }; + return; + } + if (!nodes.length) { + state.cam = { x: 0, y: 0, scale: 1 }; + return; + } + + let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity; + const expand = (x, y, r = 0) => { + minX = Math.min(minX, x - r); + maxX = Math.max(maxX, x + r); + minY = Math.min(minY, y - r); + maxY = Math.max(maxY, y + r); + }; + for (const n of nodes) { + const x = Number.isFinite(n.tx) ? n.tx : n.x; + const y = Number.isFinite(n.ty) ? n.ty : n.y; + expand(x, y, (n.r || 6) + 14); + } + if (state.hub) expand(state.hub.x, state.hub.y, (state.hub.r || 28) + 16); + for (const ch of state.clusterHubs || []) expand(ch.x, ch.y, 56); + + const bw = Math.max(80, maxX - minX); + const bh = Math.max(80, maxY - minY); + // Leave room for ctx-bar (top) + legend/feed (bottom) + const padX = opts.padX ?? 70; + const padY = opts.padY ?? 110; + const availW = Math.max(120, w - padX * 2); + const availH = Math.max(120, h - padY * 2); + const minScale = opts.minScale ?? 0.28; + const maxScale = opts.maxScale ?? 1.35; + let scale = Math.min(availW / bw, availH / bh); + scale = Math.min(maxScale, Math.max(minScale, scale)); + const cx = (minX + maxX) / 2; + const cy = (minY + maxY) / 2; + // Bias slightly downward so top ctx-bar does not cover the hub + const yBias = 18; + state.cam.scale = scale; + state.cam.x = w / 2 - cx * scale; + state.cam.y = h / 2 - cy * scale + yBias; + } + + function resetView() { + // Ensure canvas metrics are current, then rebuild layout in screen space + const dpr = Math.min(window.devicePixelRatio || 1, 2); + const w = canvas.clientWidth; + const h = canvas.clientHeight; + if (w && h) { + canvas.width = Math.floor(w * dpr); + canvas.height = Math.floor(h * dpr); + ctx.setTransform(dpr, 0, 0, dpr, 0, 0); + } + layout(); + snapNodes(); + // Designed layouts assume identity camera; then nudge to fit with padding + state.cam = { x: 0, y: 0, scale: 1 }; + fitCameraToNodes(); + updateFocusContext(); + showToast("View reset · fit to fleet"); + } + + function syncFilterInputs() { + const f = state.filters; + const set = (id, val) => { + const el = document.getElementById(id); + if (!el) return; + if (el.type === "checkbox") el.checked = !!val; + else el.value = val; + }; + set("f-connected", f.connected); + set("f-powered", f.powered); + set("f-servers", f.servers); + set("f-idrac", f.idrac); + set("f-has-power", f.hasPower); + set("f-ghost-links", f.ghostLinks); + set("f-pulse-links", f.pulseLinks !== false); + set("f-min-watts", f.minWatts || 0); + const lab = $("#min-w-label"); + if (lab) lab.textContent = String(f.minWatts || 0); + const search = $("#search"); + if (search) search.value = f.search || ""; + } + + function readFiltersFromDom() { + const on = (id) => !!document.getElementById(id)?.checked; + state.filters.connected = on("f-connected"); + state.filters.powered = on("f-powered"); + state.filters.servers = on("f-servers"); + state.filters.idrac = on("f-idrac"); + state.filters.hasPower = on("f-has-power"); + state.filters.ghostLinks = on("f-ghost-links"); + state.filters.pulseLinks = on("f-pulse-links"); + const mw = document.getElementById("f-min-watts"); + state.filters.minWatts = mw ? Number(mw.value) || 0 : 0; + state.filters.search = $("#search")?.value || ""; + } + + function clearFilters() { + state.filters = { + connected: false, + powered: false, + servers: true, + idrac: false, + hasPower: false, + ghostLinks: false, + pulseLinks: true, + minWatts: 0, + search: "", + }; + state.subnet = "all"; + state.model = null; + state.kpiFocus = null; + state.groupHint = null; + syncFilterInputs(); + refreshLists(); + layout(); + snapNodes(); + state.cam = { x: 0, y: 0, scale: 1 }; + fitCameraToNodes(); + updateFocusContext(); + showToast("Filters reset · Servers on"); + } + + function showToast(msg, opts = {}) { + let el = $("#toast"); + if (!el) { + el = document.createElement("div"); + el.id = "toast"; + el.className = "toast"; + document.body.appendChild(el); + } + el.textContent = msg; + el.classList.toggle("toast-alert", !!opts.alert); + el.classList.add("show"); + clearTimeout(showToast._t); + const ms = opts.ms != null ? opts.ms : opts.alert ? 8000 : 2200; + showToast._t = setTimeout(() => el.classList.remove("show"), ms); + } + + function pushNotifyCard(ev) { + const host = $("#notify-stack"); + if (!host) return; + const card = document.createElement("button"); + card.type = "button"; + card.className = `notify-card ${ev.severity || "info"}`; + card.dataset.deviceId = ev.device_id ?? ""; + card.innerHTML = ` + ${escapeHtml(ev.kind === "device_removed" ? "Removed" : "New on network")} + ${escapeHtml(ev.title || "Fleet change")} + ${escapeHtml(ev.text || "")} + ${escapeHtml(relTime(ev.ts))}`; + card.addEventListener("click", () => { + if (ev.device_id != null) focusDeviceId(ev.device_id); + card.remove(); + }); + host.prepend(card); + while (host.children.length > 6) host.lastElementChild.remove(); + setTimeout(() => card.classList.add("show"), 20); + setTimeout(() => { + card.classList.remove("show"); + setTimeout(() => card.remove(), 400); + }, 14000); + } + + function handleFleetNotifications(data) { + const notes = data?.context?.notifications || []; + const events = data?.events || []; + const candidates = [ + ...notes, + ...events.filter((e) => e.kind === "device_new" || e.kind === "device_removed"), + ]; + for (const ev of candidates) { + const key = `${ev.kind}:${ev.device_id}:${Math.floor(ev.ts || 0)}`; + if (state.notifiedEventKeys.has(key)) continue; + state.notifiedEventKeys.add(key); + if (state.notifiedEventKeys.size > 200) { + state.notifiedEventKeys = new Set([...state.notifiedEventKeys].slice(-100)); + } + const role = ev.role || (String(ev.title || "").toLowerCase().includes("idrac") ? "iDRAC" : "server"); + const msg = + ev.kind === "device_removed" + ? `${role} removed: ${ev.name || ev.title || "device"}` + : `New ${role} on network: ${ev.name || ev.title || "device"} · ${ev.ip || ""}`.trim(); + showToast(msg, { alert: true, ms: 9000 }); + pushNotifyCard(ev); + } + } + + function hideTip() { + state.hoverId = null; + const tip = $("#node-tip"); + if (tip) tip.classList.add("hidden"); + } + + function showTip(node, clientX, clientY) { + const tip = $("#node-tip"); + if (!tip || !node) return; + state.hoverId = node.id; + const watts = node.watts != null ? `${Math.round(node.watts)} W` : "no power sample"; + tip.innerHTML = ` +

${escapeHtml(node.name || "node")}

+

${escapeHtml(node.model || "—")}
+ ${node.connected ? "connected" : "offline"} · ${node.powered_on ? "powered on" : "power n/a"} · ${escapeHtml(watts)}
+ ${escapeHtml(node.ip || "no IP")} · ${escapeHtml(node.subnet || "")}

+

Double-click · Quick Connect

`; + tip.classList.remove("hidden"); + const pad = 14; + let x = clientX + pad; + let y = clientY + pad; + const tw = tip.offsetWidth || 220; + const th = tip.offsetHeight || 100; + if (x + tw > window.innerWidth - 8) x = clientX - tw - pad; + if (y + th > window.innerHeight - 8) y = clientY - th - pad; + tip.style.left = `${Math.max(8, x)}px`; + tip.style.top = `${Math.max(8, y)}px`; + } + + function relatedAlerts(node) { + const id = node?.id; + return (state.data?.alerts || []).filter((a) => a.device_id === id).slice(0, 3); + } + + function openConnect(node) { + if (!node || node.id == null) return; + state.connectNode = node; + const modal = $("#connect-modal"); + const scrim = $("#scrim"); + if (!modal) return; + $("#connect-title").textContent = node.name || "Device"; + $("#connect-sub").textContent = `${node.model || "—"} · ${node.service_tag || "no tag"} · OME #${node.id}`; + $("#connect-badges").innerHTML = ` + ${node.connected ? "CONNECTED" : "OFFLINE"} + ${node.powered_on ? "POWERED ON" : "POWER N/A"} + ${node.watts != null ? `${Math.round(node.watts)} W` : ""} + ${node.is_idrac ? `iDRAC` : ""} + ${node.is_server ? `SERVER` : ""}`; + const alerts = relatedAlerts(node); + $("#connect-context").innerHTML = ` + + + + `; + + const ip = node.ip; + const idrac = node.idrac_url || (ip ? `https://${ip}` : null); + $("#connect-grid").innerHTML = ` + ${idrac ? ` + + iDRAC Web + BMC console · ${escapeHtml(ip)} + ` : `
iDRAC WebNo management IP
`} + ${ip ? `` : ""} + + `; + + modal.classList.remove("hidden"); + modal.setAttribute("aria-hidden", "false"); + scrim?.classList.add("open"); + scrim.dataset.mode = "connect"; + + $("#connect-grid").onclick = async (e) => { + const copyBtn = e.target.closest("[data-copy]"); + if (copyBtn) { + try { + await navigator.clipboard.writeText(copyBtn.dataset.copy); + showToast("SSH command copied"); + } catch (_) { + showToast("Copy failed"); + } + return; + } + if (e.target.closest("#btn-modal-ssh")) { + closeConnect(); + window.cockpitSsh?.open(node); + return; + } + if (e.target.closest("#btn-modal-ai")) { + closeConnect(); + openAi(node); + return; + } + if (e.target.closest("#btn-modal-inventory")) { + closeConnect(); + showInspector(node); + setTimeout(() => $("#btn-detail")?.click(), 50); + } + }; + } + + function closeConnect() { + const modal = $("#connect-modal"); + modal?.classList.add("hidden"); + modal?.setAttribute("aria-hidden", "true"); + state.connectNode = null; + const scrim = $("#scrim"); + if (scrim?.dataset.mode === "connect") { + scrim.classList.remove("open"); + delete scrim.dataset.mode; + } + } + + function softRefreshInspector(node) { + if (!node) return; + const body = $("#inspector-body"); + if (!body || body.classList.contains("hidden")) { + showInspector(node); + return; + } + // Same node already open: update live fields only — keep inventory panel. + if (state.selectedId !== node.id) { + showInspector(node); + return; + } + const head = body.querySelector(".insp-head h2"); + if (head && head.textContent !== (node.name || "")) { + showInspector(node); + return; + } + const badges = body.querySelector(".badge-row"); + if (badges) { + badges.innerHTML = ` + ${node.connected ? "CONNECTED" : "OFFLINE"} + ${node.powered_on ? "POWERED ON" : "POWER OFF / N/A"} + ${node.watts != null ? `${Math.round(node.watts)} W` : ""} + ${node.is_idrac ? `iDRAC` : ""} + ${node.is_server ? `SERVER` : ""}`; + } + const setKv = (label, value) => { + for (const row of body.querySelectorAll(".kv-row")) { + const k = row.querySelector(".k"); + const v = row.querySelector(".v"); + if (k && v && k.textContent === label) { + if (label === "Subnet") return; // keep jump button + v.textContent = value; + } + } + }; + setKv("IP", node.ip || "—"); + setKv("Status", node.status || "—"); + setKv("Avg W", node.avg_watts != null ? Math.round(node.avg_watts) + " W" : "—"); + setKv("Peak W", node.peak_watts != null ? Math.round(node.peak_watts) + " W" : "—"); + setKv("Energy", node.energy_kwh != null ? node.energy_kwh + " kWh" : "—"); + setKv("Last status", node.last_status_time || "—"); + setKv("Inventory", node.last_inventory_time || "—"); + updateFocusContext(); + } + + async function showInspector(node) { + state.selectedId = node?.id ?? null; + const empty = $("#inspector-empty"); + const body = $("#inspector-body"); + if (!node) { + empty.classList.remove("hidden"); + body.classList.add("hidden"); + return; + } + empty.classList.add("hidden"); + body.classList.remove("hidden"); + body.innerHTML = ` +
+

${escapeHtml(node.name)}

+

${escapeHtml(node.model || "—")} · ${escapeHtml(node.service_tag || "no tag")}

+
+
+ ${node.connected ? "CONNECTED" : "OFFLINE"} + ${node.powered_on ? "POWERED ON" : "POWER OFF / N/A"} + ${node.watts != null ? `${Math.round(node.watts)} W` : ""} + ${node.is_idrac ? `iDRAC` : ""} + ${node.is_server ? `SERVER` : ""} +
+
+
IP${escapeHtml(node.ip || "—")}
+
Subnet
+
Status${escapeHtml(node.status)}
+
Avg W${node.avg_watts != null ? Math.round(node.avg_watts) + " W" : "—"}
+
Peak W${node.peak_watts != null ? Math.round(node.peak_watts) + " W" : "—"}
+
Energy${node.energy_kwh != null ? node.energy_kwh + " kWh" : "—"}
+
OME id${node.id}
+
Last status${escapeHtml(node.last_status_time || "—")}
+
Inventory${escapeHtml(node.last_inventory_time || "—")}
+
+
+ + ${node.idrac_url ? `iDRAC Web` : ""} + ${node.ip ? `` : ""} + + + +
+
+ `; + + body.querySelector("[data-jump-subnet]")?.addEventListener("click", (e) => { + state.subnet = e.currentTarget.dataset.jumpSubnet; + refreshLists(); + layout(); + }); + $("#btn-focus-model")?.addEventListener("click", () => { + state.model = node.model; + refreshLists(); + layout(); + }); + updateFocusContext(); + $("#btn-quick-connect")?.addEventListener("click", () => openConnect(node)); + $("#btn-ssh-term")?.addEventListener("click", () => window.cockpitSsh?.open(node)); + $("#btn-ask-ai")?.addEventListener("click", () => openAi(node)); + const cachedInv = state.inventoryCache[node.id]; + if (cachedInv) { + const mount = $("#inv-mount"); + if (mount) mount.innerHTML = cachedInv; + } + + $("#btn-detail")?.addEventListener("click", async () => { + const mount = $("#inv-mount"); + const deviceId = node.id; + state.inventoryLoadingId = deviceId; + mount.innerHTML = `

Loading full inventory + application landscape…

`; + try { + const r = await fetch(`/api/devices/${deviceId}`); + const detail = await r.json(); + const inv = detail.inventory || {}; + const land = detail.landscape || {}; + const p = detail.power || {}; + + const line = (s) => `
${escapeHtml(s)}
`; + const section = (title, rows) => { + if (!rows || !rows.length) return ""; + return `

${escapeHtml(title)} (${rows.length})

${rows.join("")}
`; + }; + + let html = `

Power (live)

+
Instant ${p.watts ?? "—"} W · avg ${p.avg_watts ?? "—"} · peak ${p.peak_watts ?? "—"}
+
Energy ${p.energy_kwh ?? "—"} kWh
`; + + // Application / firmware landscape first + const osRows = (land.os || []).map((x) => + line(`${x.OsName || x.OperatingSystemName || "OS"} · ${x.OsVersion || ""} · host ${x.Hostname || "—"}`) + ); + html += section("Operating system", osRows); + + const soft = (items, title) => { + const rows = (items || []).slice(0, 40).map((x) => + line( + `${x.DeviceDescription || x.SoftwareType || x.Name || "component"} · v${x.Version || "?"} · ${x.Status || ""} · ${x.InstallationDate || ""}`.trim() + ) + ); + return section(title, rows); + }; + html += soft(land.firmware, "Firmware landscape"); + html += soft(land.drivers, "Drivers"); + html += soft(land.applications, "Software / apps"); + if (!(land.firmware || []).length && (land.software || []).length) { + html += soft(land.software, "Software inventory"); + } + + const mgmtRows = (land.management || []).map((x) => { + const agents = (x.EndPointAgents || []) + .map((a) => a.AgentName || a.ManagementProfile || a.AgentType || "") + .filter(Boolean) + .join(", "); + return line( + `${x.DnsName || x.InstrumentationName || "mgmt"} · ${x.IpAddress || ""} · MAC ${x.MacAddress || "—"}` + + (agents ? ` · agents: ${agents}` : "") + ); + }); + html += section("Management / agents", mgmtRows); + + const licRows = (land.licenses || []).slice(0, 20).map((x) => + line(`${x.LicenseDescription || x.EntitlementId || x.LicenseType || "license"} · ${x.LicenseStatus || x.Status || ""}`) + ); + html += section("Licenses", licRows); + + const sections = [ + ["serverProcessors", "CPUs", (x) => `${x.ModelName || x.BrandName || x.Manufacturer || "CPU"} · ${x.CurrentSpeed || ""} MHz · ${x.NumberOfCores || "?"} cores · ${x.Status || ""}`], + ["serverMemoryDevices", "Memory", (x) => `${x.Name || "DIMM"} · ${x.Size || "?"} · ${x.Speed || x.CurrentOperatingSpeed || ""} · ${x.Manufacturer || ""} · ${x.SerialNumber || ""}`], + ["serverArrayDisks", "Disks", (x) => `${x.ModelNumber || x.SerialNumber || "disk"} · ${x.MediaType || ""} · ${x.Size || x.Capacity || "?"} · ${x.StatusString || x.Status || ""}`], + ["serverRaidControllers", "RAID", (x) => `${x.Name || "RAID"} · FW ${x.FirmwareVersion || "?"} · cache ${x.CacheSizeInMb || "?"} MB · ${x.Status || ""}`], + ["serverPowerSupplies", "PSUs", (x) => `${x.Name || x.Model || "PSU"} · ${x.OutputWatts || "?"} W · ${x.FirmwareVersion || ""} · ${x.Status || ""}`], + ["serverNetworkInterfaces", "NICs", (x) => { + const ports = (x.Ports || []).map((p) => p.ProductName || p.PermanentMACAddress || p.MacAddress || "").filter(Boolean).slice(0, 4).join(" | "); + return `${x.ProductName || x.VendorName || "NIC"} · ${ports || x.PermanentMACAddress || ""}`; + }], + ["serverFcCards", "FC HBAs", (x) => `${x.ProductName || x.VendorName || "FC"} · ${x.WWN || x.PortName || ""}`], + ["serverDellVideos", "GPUs / video", (x) => `${x.ProductName || x.Description || "video"} · ${x.Manufacturer || ""}`], + ["serverDeviceCards", "Device cards", (x) => `${x.ProductName || x.Description || x.SlotName || "card"} · ${x.Manufacturer || ""}`], + ["deviceBaseboards", "Baseboard", (x) => `${x.Manufacturer || ""} · ${x.ProductName || x.Model || ""} · SN ${x.SerialNumber || "—"}`], + ["deviceFru", "FRU", (x) => `${x.Name || "FRU"} · ${x.Manufacturer || ""} · PN ${x.PartNumber || ""} · SN ${x.SerialNumber || ""}`], + ["deviceLocation", "Location", (x) => `${x.Datacenter || ""} ${x.Room || ""} ${x.Aisle || ""} ${x.Rack || ""} U${x.Rackslot || x.RackSlot || ""}`.trim() || JSON.stringify(x).slice(0, 80)], + ["subsystemRollupStatus", "Health rollup", (x) => `${x.SubsystemName || x.Type || "sub"} · ${x.Status || ""}`], + ["serverStorageEnclosures", "Storage enclosures", (x) => `${x.Name || x.ProductName || "enclosure"} · ${x.Status || ""}`], + ["serverVirtualFlashes", "Virtual flash", (x) => `${x.Name || "vFlash"} · ${x.Capacity || x.Size || ""} · ${x.Status || ""}`], + ["serverBiosSystemProfileSettings", "BIOS profile", (x) => Object.entries(x).slice(0, 6).map(([k, v]) => `${k}=${v}`).join(" · ")], + ["deviceCapabilities", "Capabilities", (x) => `CapabilityType ${x.CapabilityType ?? x.Id ?? "?"}`], + ["serverSupportedPowerStates", "Power states", (x) => `PowerState ${x.PowerState ?? x.Id ?? "?"}`], + ]; + for (const [key, title, fmt] of sections) { + const rows = inv[key] || []; + if (!rows.length) continue; + html += section( + title, + rows.slice(0, 24).map((row) => line(fmt(row))) + ); + } + + // Any remaining inventory keys not already shown + const shown = new Set(sections.map((s) => s[0]).concat([ + "deviceSoftware", "serverOperatingSystems", "deviceManagement", "deviceLicense", + ])); + for (const [key, rows] of Object.entries(inv)) { + if (shown.has(key) || !Array.isArray(rows) || !rows.length) continue; + html += section( + key, + rows.slice(0, 12).map((row) => + line( + typeof row === "object" + ? Object.entries(row).slice(0, 6).map(([k, v]) => `${k}=${v}`).join(" · ") + : String(row) + ) + ) + ); + } + + html = html || `

No inventory available

`; + state.inventoryCache[deviceId] = html; + if (state.selectedId === deviceId) { + const live = $("#inv-mount"); + if (live) live.innerHTML = html; + } + } catch (e) { + const errHtml = `

Inventory failed: ${escapeHtml(e.message)}

`; + if (state.selectedId === deviceId) { + const live = $("#inv-mount"); + if (live) live.innerHTML = errHtml; + } + } finally { + if (state.inventoryLoadingId === deviceId) state.inventoryLoadingId = null; + } + }); + } + + function showHubInspector() { + const ome = state.data?.ome || {}; + const s = state.data?.summary || {}; + state.selectedId = null; + $("#inspector-empty").classList.add("hidden"); + const body = $("#inspector-body"); + body.classList.remove("hidden"); + body.innerHTML = ` +
+

${escapeHtml(ome.name || "OpenManage Enterprise")}

+

v${escapeHtml(ome.version || "?")} · build ${escapeHtml(String(ome.build || "?"))}

+
+
+ HUB + ${s.total_watts != null ? Math.round(s.total_watts) + " W fleet" : "power…"} +
+
+
FQDN${escapeHtml(ome.fqdn || "—")}
+
API${escapeHtml(ome.url || "—")}
+
Servers${s.servers ?? "—"}
+
Connected${s.connected ?? "—"}
+
Power samples${s.power_samples ?? "—"}
+
+
+ Open OME console + +
`; + $("#btn-ai-hub")?.addEventListener("click", () => openAi(null)); + } + + function openAi(node) { + const url = state.data?.openwebui_url || "http://atc-portal01.dell-atc.lan:3080"; + $("#ai-frame").src = url; + $("#ai-drawer").classList.add("open"); + $("#ai-drawer").setAttribute("aria-hidden", "false"); + const scrim = $("#scrim"); + scrim?.classList.add("open"); + if (scrim) scrim.dataset.mode = "ai"; + if (node) { + console.info("Ask AI about", node.name, node.service_tag, node.watts); + } + } + + function closeAi() { + $("#ai-drawer").classList.remove("open"); + $("#ai-drawer").setAttribute("aria-hidden", "true"); + const scrim = $("#scrim"); + if (scrim?.dataset.mode === "ai" || !scrim?.dataset.mode) { + scrim?.classList.remove("open"); + if (scrim) delete scrim.dataset.mode; + } + } + + function refreshLists() { + renderKpis(); + renderSubnets(); + renderModels(); + renderGroups(); + renderLegend(); + renderTicker(); + renderContext(); + const ome = state.data?.ome; + if (ome) { + $("#ome-meta").textContent = `OM Enterprise ${ome.version || "?"} · build ${ome.build || "?"} · live`; + } + } + + function applySnapshot(data) { + state.data = data; + handleFleetNotifications(data); + try { + window.dispatchEvent(new CustomEvent("cockpit-snapshot", { detail: data })); + if (data.gpu) window.dispatchEvent(new CustomEvent("cockpit-gpu", { detail: data.gpu })); + } catch (_) {} + // warm color maps + for (const d of data.devices || []) { + colorFor(state.modelColors, d.model || "?"); + colorFor(state.subnetColors, d.subnet || "?"); + } + refreshLists(); + layout(); + if (state.selectedId) { + const n = (data.devices || []).find((x) => x.id === state.selectedId); + if (n) softRefreshInspector(n); + } + } + + // events + $("#layout-modes")?.addEventListener("click", (e) => { + const btn = e.target.closest("[data-layout]"); + if (!btn) return; + state.layoutMode = btn.dataset.layout; + $("#layout-modes").querySelectorAll(".viz-card").forEach((c) => c.classList.toggle("active", c === btn)); + layout(); + snapNodes(); + state.cam = { x: 0, y: 0, scale: 1 }; + fitCameraToNodes(); + updateFocusContext(); + }); + + $("#view-modes").addEventListener("click", (e) => { + const btn = e.target.closest("[data-mode]"); + if (!btn) return; + state.viewMode = btn.dataset.mode; + $("#view-modes").querySelectorAll(".chip").forEach((c) => c.classList.toggle("active", c === btn)); + renderLegend(); + layout(); + }); + + $("#subnet-list").addEventListener("click", (e) => { + const btn = e.target.closest("[data-subnet]"); + if (!btn) return; + state.subnet = btn.dataset.subnet; + state.kpiFocus = null; + refreshLists(); + layout(); + }); + + $("#model-list").addEventListener("click", (e) => { + const btn = e.target.closest("[data-model]"); + if (!btn) return; + state.model = btn.dataset.model || null; + refreshLists(); + layout(); + }); + + $("#group-list").addEventListener("click", (e) => { + const btn = e.target.closest("[data-group]"); + if (!btn) return; + state.filters.search = btn.dataset.group || ""; + $("#search").value = state.filters.search; + state.groupHint = btn.dataset.group; + showInspector({ + id: null, + name: `Group: ${btn.dataset.group}`, + model: "OME Group", + service_tag: "—", + connected: true, + powered_on: false, + watts: null, + avg_watts: null, + peak_watts: null, + energy_kwh: null, + ip: null, + subnet: "—", + status: "group", + is_idrac: false, + is_server: false, + idrac_url: null, + }); + // note: OME groups aren't device-membership expanded here — search/filter by name hint + layout(); + }); + + $("#kpi-strip").addEventListener("click", (e) => { + const btn = e.target.closest("[data-kpi]"); + if (!btn) return; + const key = btn.dataset.kpi; + openKpiPopup(key); + // Keep strip highlight in sync with open context + state.kpiFocus = key; + renderKpis(); + }); + + $("#btn-kpi-close")?.addEventListener("click", closeKpiPopup); + $("#kpi-search")?.addEventListener("input", (e) => { + kpiPopup.q = e.target.value || ""; + renderKpiPopup(); + }); + $("#kpi-sort")?.addEventListener("change", (e) => { + kpiPopup.sort = e.target.value || "name"; + renderKpiPopup(); + }); + $("#btn-kpi-apply")?.addEventListener("click", () => { + if (kpiPopup.key) applyKpiAsFilter(kpiPopup.key); + }); + $("#btn-kpi-clear")?.addEventListener("click", () => { + state.kpiFocus = null; + state.filters.connected = false; + state.filters.powered = false; + state.filters.hasPower = false; + state.filters.servers = true; + state.filters.idrac = false; + syncFilterInputs(); + refreshLists(); + layout(); + snapNodes(); + fitCameraToNodes(); + updateFocusContext(); + renderKpis(); + showToast("Map KPI filter cleared"); + }); + $("#kpi-list")?.addEventListener("click", (e) => { + const btn = e.target.closest("[data-kpi-device]"); + if (!btn) return; + kpiPopup.selectedId = Number(btn.dataset.kpiDevice); + renderKpiPopup(); + }); + $("#kpi-detail")?.addEventListener("click", (e) => { + const act = e.target.closest("[data-kpi-act]"); + if (!act) return; + const node = (state.data?.devices || []).find((d) => d.id === kpiPopup.selectedId); + if (!node) return; + const a = act.dataset.kpiAct; + if (a === "focus") { + closeKpiPopup(); + focusDeviceId(node.id); + showToast("Focused " + (node.name || "")); + } else if (a === "ssh") { + window.cockpitSsh?.open(node); + } else if (a === "connect") { + closeKpiPopup(); + openConnect(node); + } else if (a === "inventory") { + closeKpiPopup(); + showInspector(node); + setTimeout(() => $("#btn-detail")?.click(), 60); + } else if (a === "chat") { + closeKpiPopup(); + document.getElementById("btn-chat")?.click(); + setTimeout(() => { + const input = document.getElementById("chat-input"); + if (input) { + input.value = `Give operational context for ${node.name} (${node.ip || "no IP"}). Status ${node.status}, connected=${node.connected}, watts=${node.watts ?? "n/a"}. Suggest next actions for ATC admins.`; + input.focus(); + } + }, 150); + } + }); + + $("#filters").addEventListener("change", (e) => { + const t = e.target; + readFiltersFromDom(); + if (t.id === "f-min-watts") { + $("#min-w-label").textContent = String(state.filters.minWatts); + } + // Pulse-only toggle: no need to relayout + if (t.id === "f-pulse-links") { + updateFocusContext(); + showToast(state.filters.pulseLinks ? "Link pulse on" : "Link pulse off"); + return; + } + layout(); + snapNodes(); + fitCameraToNodes(); + renderTicker(); + updateFocusContext(); + if (!state.filters.servers && !state.filters.idrac) { + showToast("Enable Servers and/or iDRACs to show nodes"); + } + }); + + $("#search").addEventListener("input", (e) => { + state.filters.search = e.target.value; + layout(); + renderTicker(); + }); + + $("#ticker").addEventListener("click", (e) => { + const btn = e.target.closest("[data-tick]"); + if (!btn) return; + const k = btn.dataset.tick; + if (k === "ome") showHubInspector(); + if (k === "power") { + state.viewMode = "power"; + state.kpiFocus = "power"; + state.filters.hasPower = true; + $("#f-has-power").checked = true; + refreshLists(); + layout(); + } + if (k === "connected") { + state.kpiFocus = "connected"; + state.filters.connected = true; + $("#f-connected").checked = true; + refreshLists(); + layout(); + } + if (k === "alerts") { + if (window.cockpit?.openTriage) window.cockpit.openTriage("critical"); + else updateFocusContext(); + } + }); + + canvas.addEventListener("mousedown", (e) => { + state.dragging = true; + state.last = { x: e.clientX, y: e.clientY }; + }); + window.addEventListener("mouseup", () => { + state.dragging = false; + }); + canvas.addEventListener("mousemove", (e) => { + if (state.dragging) { + state.cam.x += e.clientX - state.last.x; + state.cam.y += e.clientY - state.last.y; + state.last = { x: e.clientX, y: e.clientY }; + hideTip(); + return; + } + const rect = canvas.getBoundingClientRect(); + const hit = hitTest(e.clientX - rect.left, e.clientY - rect.top); + if (hit?.type === "node") showTip(hit.node, e.clientX, e.clientY); + else hideTip(); + }); + canvas.addEventListener("mouseleave", hideTip); + canvas.addEventListener("wheel", (e) => { + e.preventDefault(); + const rect = canvas.getBoundingClientRect(); + const mx = e.clientX - rect.left; + const my = e.clientY - rect.top; + const before = screenToWorld(mx, my); + const factor = e.deltaY > 0 ? 0.9 : 1.1; + state.cam.scale = Math.min(3.5, Math.max(0.35, state.cam.scale * factor)); + const after = screenToWorld(mx, my); + state.cam.x += (after.x - before.x) * state.cam.scale; + state.cam.y += (after.y - before.y) * state.cam.scale; + }, { passive: false }); + + canvas.addEventListener("click", (e) => { + const rect = canvas.getBoundingClientRect(); + const hit = hitTest(e.clientX - rect.left, e.clientY - rect.top); + if (!hit) { + showInspector(null); + hideTip(); + return; + } + if (hit.type === "hub") { + showHubInspector(); + return; + } + showInspector(hit.node); + }); + canvas.addEventListener("dblclick", (e) => { + e.preventDefault(); + const rect = canvas.getBoundingClientRect(); + const hit = hitTest(e.clientX - rect.left, e.clientY - rect.top); + if (hit?.type === "node") { + showInspector(hit.node); + openConnect(hit.node); + } else if (hit?.type === "hub") { + showHubInspector(); + } + }); + + + // Shared API for Ops desk / triage popup + window.cockpit = { + getState: () => state, + focusDeviceId, + openConnect, + showInspector, + openAi, + relTime, + escapeHtml, + openTriage: null, + openKpiPopup, + closeKpiPopup, + }; + + // Realtime context interactivity + $("#ctx-stats")?.addEventListener("click", (e) => { + const btn = e.target.closest("[data-ctx]"); + if (!btn) return; + if (window.cockpit.openTriage) window.cockpit.openTriage(btn.dataset.ctx); + }); + $("#alert-list")?.addEventListener("click", (e) => { + const btn = e.target.closest("[data-alert-device]"); + if (!btn) return; + if (window.cockpit.openTriage) { + window.cockpit.openTriage("all", { + alertId: btn.dataset.alertId, + deviceId: btn.dataset.alertDevice, + }); + } else { + focusDeviceId(btn.dataset.alertDevice); + } + }); + $("#ctx-feed-body")?.addEventListener("click", (e) => { + const btn = e.target.closest("[data-feed-device]"); + if (!btn) return; + if (window.cockpit.openTriage) { + window.cockpit.openTriage("all", { deviceId: btn.dataset.feedDevice }); + } else { + focusDeviceId(btn.dataset.feedDevice); + } + }); + + $("#btn-reset-view").addEventListener("click", (e) => { + e.preventDefault(); + e.stopPropagation(); + resetView(); + }); + $("#btn-clear-filters")?.addEventListener("click", (e) => { + e.preventDefault(); + e.stopPropagation(); + clearFilters(); + }); + $("#btn-ai")?.addEventListener("click", () => openAi(null)); + $("#btn-ai-close").addEventListener("click", closeAi); + $("#btn-connect-close")?.addEventListener("click", closeConnect); + $("#scrim").addEventListener("click", () => { + const mode = $("#scrim")?.dataset.mode; + if (mode === "triage") document.getElementById("btn-triage-close")?.click(); + else if (mode === "kpi") closeKpiPopup(); + else if (mode === "connect") closeConnect(); + else if (mode === "chat-drawer" || mode === "ops-drawer" || mode === "ai-drawer") { + /* ops.js also listens */ + } else closeAi(); + }); + $("#btn-ome-console").addEventListener("click", () => { + const url = state.data?.ome?.console_url || state.data?.ome?.url; + if (url) window.open(url, "_blank", "noopener"); + }); + + // collapsible left-rail modules + $("#left-rail")?.addEventListener("click", (e) => { + const btn = e.target.closest(".rail-toggle"); + if (!btn) return; + const block = btn.closest(".rail-block"); + if (!block) return; + const open = block.classList.toggle("open"); + btn.setAttribute("aria-expanded", open ? "true" : "false"); + }); + + window.addEventListener("keydown", (e) => { + if (e.key === "Escape") { + closeConnect(); + closeAi(); + closeKpiPopup(); + hideTip(); + document.getElementById("btn-triage-close")?.click(); + } + }); + window.addEventListener("resize", resize); + window.addEventListener("cockpit-feed-expand", () => { + try { renderContext(); } catch (_) {} + }); + + async function boot() { + try { + const r = await fetch("/api/fleet"); + applySnapshot(await r.json()); + } catch (e) { + console.error(e); + } + connectWs(); + } + + function connectWs() { + const proto = location.protocol === "https:" ? "wss" : "ws"; + const ws = new WebSocket(`${proto}://${location.host}/ws/fleet`); + ws.onmessage = (ev) => { + try { + const msg = JSON.parse(ev.data); + if (msg.type === "snapshot" && msg.data) applySnapshot(msg.data); + if (msg.type === "gpu" && msg.data) { + if (state.data) state.data.gpu = msg.data; + window.dispatchEvent(new CustomEvent("cockpit-gpu", { detail: msg.data })); + } + } catch (_) {} + }; + ws.onclose = () => setTimeout(connectWs, 2500); + } + + // Keep JS filter state in sync with checkbox defaults in HTML + readFiltersFromDom(); + syncFilterInputs(); + resize(); + requestAnimationFrame(draw); + boot(); + + // style for inline link buttons in inspector + const style = document.createElement("style"); + style.textContent = `.linkish{appearance:none;border:none;background:none;color:var(--dell-bright);font:inherit;font-family:var(--mono);padding:0;cursor:pointer;text-align:left}.linkish:hover{text-decoration:underline;color:#fff}`; + document.head.appendChild(style); +})(); diff --git a/ui/dell-mark.png b/ui/dell-mark.png new file mode 100644 index 0000000..bc45f4a Binary files /dev/null and b/ui/dell-mark.png differ diff --git a/ui/dell.png b/ui/dell.png new file mode 100644 index 0000000..10376c9 Binary files /dev/null and b/ui/dell.png differ diff --git a/ui/dell.svg b/ui/dell.svg new file mode 100644 index 0000000..551bca8 --- /dev/null +++ b/ui/dell.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/ui/index.html b/ui/index.html new file mode 100644 index 0000000..1e8f5ef --- /dev/null +++ b/ui/index.html @@ -0,0 +1,450 @@ + + + + + + Dell OpenManage Cockpit — ATC + + + + + + + + +
+
+
+ + +
+

OpenManage Cockpit

+

OME · connecting…

+
+
+ +
+ +
+ + + + +
+
+ + + +
+
+
+ + Realtime context · waiting for OME… +
+
Focus: all networks
+
+ +
+
+
Scroll = zoom · drag = pan · hover tip · double-click = Quick Connect
+
+ +
+ + + +
+
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + diff --git a/ui/ops.js b/ui/ops.js new file mode 100644 index 0000000..9c7e803 --- /dev/null +++ b/ui/ops.js @@ -0,0 +1,866 @@ +(() => { + const $ = (sel) => document.querySelector(sel); + const state = window.__cockpitState || null; + + // Hook into app.js state if exposed; else work via DOM + fetch + function ensureApi() { + return { + async get(url) { + const r = await fetch(url); + if (!r.ok) throw new Error(await r.text()); + return r.json(); + }, + async post(url, body) { + const r = await fetch(url, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(body), + }); + if (!r.ok) throw new Error(await r.text()); + return r.json(); + }, + async patch(url, body) { + const r = await fetch(url, { + method: "PATCH", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(body), + }); + if (!r.ok) throw new Error(await r.text()); + return r.json(); + }, + async del(url) { + const r = await fetch(url, { method: "DELETE" }); + if (!r.ok) throw new Error(await r.text()); + return r.json(); + }, + }; + } + + const api = ensureApi(); + const chatHistory = []; + let tickets = []; + let activeTicketId = null; + let gpuData = null; + let chatModelsLoaded = false; + + function selectedChatModel() { + const sel = $("#chat-model"); + const saved = localStorage.getItem("cockpit_chat_model"); + return (sel?.value || saved || "llama3-70b-gptq").trim(); + } + + async function loadChatModels() { + const sel = $("#chat-model"); + if (!sel) return; + try { + const data = await api.get("/api/models"); + const models = data.models || []; + const preferred = localStorage.getItem("cockpit_chat_model") || data.default || "llama3-70b-gptq"; + if (models.length) { + sel.innerHTML = models + .map((m) => { + const id = m.id || m.name; + const label = m.name && m.name !== id ? `${m.name} (${id})` : id; + return ``; + }) + .join(""); + const ids = models.map((m) => m.id); + sel.value = ids.includes(preferred) ? preferred : ids[0]; + } + chatModelsLoaded = true; + } catch (e) { + console.warn("model list failed", e); + } + } + + function actor() { + return $("#ops-actor")?.value || localStorage.getItem("atc_actor") || "jody"; + } + + function adminName(id) { + return id === "laurens" ? "Laurens Rammers" : "Jody van Dongen"; + } + + function openDrawer(id) { + closeDrawers(); + const el = $(id); + el?.classList.add("open"); + el?.setAttribute("aria-hidden", "false"); + const scrim = $("#scrim"); + scrim?.classList.add("open"); + if (scrim) scrim.dataset.mode = id.replace("#", ""); + } + + function closeDrawers() { + ["#chat-drawer", "#ops-drawer", "#ai-drawer"].forEach((id) => { + const el = $(id); + el?.classList.remove("open"); + el?.setAttribute("aria-hidden", "true"); + }); + const scrim = $("#scrim"); + if (scrim && ["chat-drawer", "ops-drawer", "ai-drawer"].includes(scrim.dataset.mode)) { + scrim.classList.remove("open"); + delete scrim.dataset.mode; + } + } + + function renderGpu(data) { + gpuData = data; + const box = $("#gpu-matrix"); + const sum = $("#gpu-summary"); + if (!box) return; + if (!data || data.error) { + if (sum) sum.textContent = "GPU telemetry unreachable"; + box.innerHTML = ""; + return; + } + const s = data.summary || {}; + if (sum) { + sum.innerHTML = `${s.avg_util ?? 0}% avg util · ${Math.round(s.total_power_w || 0)} W · mem ${Math.round((s.total_mem_used_mb || 0) / 1024)} / ${Math.round((s.total_mem_mb || 0) / 1024)} GB`; + } + box.innerHTML = (data.gpus || []) + .map((g) => { + const busy = g.util_gpu >= 5; + const pct = Math.max(0, Math.min(100, g.util_gpu || 0)); + return `
+
GPU ${g.index}${pct.toFixed(0)}%
+
+
${Math.round(g.mem_used_mb)} / ${Math.round(g.mem_total_mb)} MB · ${Math.round(g.temp_c)}°C · ${Math.round(g.power_w)} W
+
${g.name || "V100"}
+
`; + }) + .join(""); + } + + function appendChat(role, text) { + const body = $("#chat-body"); + if (!body) return; + const div = document.createElement("div"); + div.className = `chat-bubble ${role}`; + div.textContent = text; + body.appendChild(div); + body.scrollTop = body.scrollHeight; + } + + function refreshChatContext() { + const d = window.cockpit?.getState?.()?.data || {}; + const s = d.summary || {}; + const fleet = $("#chat-ctx-fleet"); + if (fleet) { + fleet.textContent = `${s.connected ?? "—"} connected · ${s.total_watts != null ? Math.round(s.total_watts) + "W" : "—"} · ${(d.alerts || []).filter((a) => a.severity === "Critical").length} crit`; + } + const focus = $("#chat-ctx-focus"); + const sel = window.cockpit?.getState?.()?.selectedId; + const node = (d.devices || []).find((x) => x.id === sel); + if (focus) focus.textContent = node ? `focus: ${(node.name || "").slice(0, 28)}` : "focus: none"; + } + + async function sendChat(msg) { + refreshChatContext(); + appendChat("user", msg); + chatHistory.push({ role: "user", content: msg }); + const model = selectedChatModel(); + appendChat("assistant", `Thinking with ${model}…`); + const thinking = $("#chat-body")?.lastElementChild; + try { + const focusId = window.cockpit?.getState?.()?.selectedId || null; + const res = await api.post("/api/chat", { + message: msg, + history: chatHistory.slice(0, -1), + focus_device_id: focusId, + model, + }); + if (thinking) thinking.textContent = res.reply || "(empty reply)"; + chatHistory.push({ role: "assistant", content: res.reply || "" }); + const g = await api.get("/api/gpu"); + renderGpu(g); + refreshChatContext(); + } catch (e) { + if (thinking) thinking.textContent = "Chat error: " + e.message; + } + } + + function ticketFilterValue() { + return $("#ops-filter")?.value || "openish"; + } + + async function loadTickets() { + const data = await api.get("/api/tickets"); + tickets = data.tickets || []; + const list = $("#ticket-list"); + if (!list) return; + const f = ticketFilterValue(); + const me = actor(); + const filtered = tickets.filter((t) => { + if (f === "all") return true; + if (f === "mine") return t.assignee === me; + if (f === "openish") return ["open", "accepted", "in_progress"].includes(t.status); + return t.status === f; + }); + if (!filtered.length) { + list.innerHTML = `

No tickets in this filter.

`; + return; + } + list.innerHTML = filtered + .map((tkt) => { + const active = tkt.id === activeTicketId ? " active" : ""; + return ``; + }) + .join(""); + } + + function escape(s) { + return String(s ?? "") + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/"/g, """); + } + + async function openTicket(id) { + activeTicketId = id; + await loadTickets(); + const data = await api.get(`/api/tickets/${id}`); + const tkt = data.ticket; + const msgs = data.messages || []; + $("#ops-empty")?.classList.add("hidden"); + const thread = $("#ops-thread"); + thread?.classList.remove("hidden"); + if (!thread) return; + const me = actor(); + const canAccept = tkt.assignee === me && !tkt.accepted_by && tkt.status === "open"; + thread.innerHTML = ` +
+

#${tkt.id} · ${escape(tkt.title)}

+
+
Status${escape(tkt.status)}
+
Priority${escape(tkt.priority)}
+
Created by${escape(adminName(tkt.created_by))}
+
Assignee${escape(adminName(tkt.assignee))}
+
Accepted by${tkt.accepted_by ? escape(adminName(tkt.accepted_by)) : "—"}
+
Updated${new Date(tkt.updated_at * 1000).toLocaleString()}
+
+
+ + + + + ${canAccept ? `` : ""} + + +
+
+
+ ${msgs + .map( + (m) => `
${escape(adminName(m.author))} + ${new Date(m.created_at * 1000).toLocaleString()} +

${escape(m.body)}

` + ) + .join("")} +
+
+ + +
`; + + $("#ops-status").value = tkt.status || "open"; + $("#ops-assign").value = tkt.assignee || "jody"; + $("#ops-priority").value = tkt.priority || "normal"; + + $("#ops-save-meta")?.addEventListener("click", async () => { + await api.patch(`/api/tickets/${id}`, { + status: $("#ops-status").value, + assignee: $("#ops-assign").value, + priority: $("#ops-priority").value, + }); + openTicket(id); + }); + $("#ops-accept")?.addEventListener("click", async () => { + await api.patch(`/api/tickets/${id}`, { accepted_by: me, status: "accepted" }); + openTicket(id); + }); + $("#ops-close-ticket")?.addEventListener("click", async () => { + await api.patch(`/api/tickets/${id}`, { status: "closed" }); + openTicket(id); + }); + $("#ops-delete-ticket")?.addEventListener("click", async () => { + if (!confirm(`Delete ticket #${id}? This cannot be undone.`)) return; + await api.del(`/api/tickets/${id}`); + activeTicketId = null; + $("#ops-thread")?.classList.add("hidden"); + $("#ops-empty")?.classList.remove("hidden"); + await loadTickets(); + }); + $("#ops-reply")?.addEventListener("submit", async (e) => { + e.preventDefault(); + const body = $("#ops-reply-body")?.value?.trim(); + if (!body) return; + await api.post(`/api/tickets/${id}/messages`, { author: actor(), body }); + openTicket(id); + }); + } + + let ticketDraft = null; + + function openTicketModal(draft = null) { + ticketDraft = draft; + const me = actor(); + const other = me === "jody" ? "laurens" : "jody"; + $("#ticket-title").value = draft?.title || ""; + $("#ticket-body").value = draft?.body || ""; + $("#ticket-priority").value = draft?.priority || "normal"; + $("#ticket-assignee").value = draft?.assignee || other; + const modal = $("#ticket-modal"); + const scrim = $("#scrim"); + modal?.classList.remove("hidden"); + modal?.setAttribute("aria-hidden", "false"); + scrim?.classList.add("open"); + if (scrim) scrim.dataset.mode = "ticket"; + setTimeout(() => $("#ticket-title")?.focus(), 50); + } + + function closeTicketModal() { + const modal = $("#ticket-modal"); + modal?.classList.add("hidden"); + modal?.setAttribute("aria-hidden", "true"); + const scrim = $("#scrim"); + if (scrim?.dataset.mode === "ticket") { + scrim.classList.remove("open"); + delete scrim.dataset.mode; + } + ticketDraft = null; + } + + async function newTicket() { + openTicketModal(null); + } + + // Collapsible + lightly draggable live feed + function initFeedDrag() { + const feed = $("#ctx-feed"); + const handle = $("#ctx-feed-drag"); + if (!feed || !handle) return; + + const applyCollapsed = (collapsed) => { + feed.classList.toggle("collapsed", collapsed); + document.querySelector(".stage")?.classList.toggle("feed-collapsed", collapsed); + $("#btn-feed-collapse")?.classList.toggle("hidden", collapsed); + $("#btn-feed-expand")?.classList.toggle("hidden", !collapsed); + localStorage.setItem("feed_collapsed", collapsed ? "1" : "0"); + const body = $("#ctx-feed-body"); + if (collapsed) { + // park as compact bar near bottom-right; purge DOM to avoid Chromium ghost text + feed.style.bottom = "0.55rem"; + feed.style.left = ""; + feed.style.right = "0.75rem"; + feed.style.top = ""; + feed.style.width = ""; + feed.style.height = ""; + if (body) body.innerHTML = ""; + } else { + const saved = localStorage.getItem("feed_bottom"); + feed.style.bottom = saved && !saved.includes("rem") ? saved : "2.4rem"; + // ask app to refill feed on next snapshot + window.dispatchEvent(new CustomEvent("cockpit-feed-expand")); + } + }; + + // migrate: clear broken bottom values that pinned feed mid-screen + const savedBottom = localStorage.getItem("feed_bottom"); + if (savedBottom) { + const n = parseFloat(savedBottom); + if (!Number.isFinite(n) || n > 200) localStorage.removeItem("feed_bottom"); + } + applyCollapsed(localStorage.getItem("feed_collapsed") === "1"); + + $("#btn-feed-collapse")?.addEventListener("click", (e) => { + e.preventDefault(); + e.stopPropagation(); + applyCollapsed(true); + }); + $("#btn-feed-expand")?.addEventListener("click", (e) => { + e.preventDefault(); + e.stopPropagation(); + applyCollapsed(false); + }); + // click header when collapsed = expand + handle.addEventListener("click", (e) => { + if (e.target.closest("button")) return; + if (feed.classList.contains("collapsed")) applyCollapsed(false); + }); + + const feedBottomPx = () => { + const raw = feed.style.bottom || getComputedStyle(feed).bottom || "38px"; + const n = parseFloat(raw); + return Number.isFinite(n) ? n : 38; + }; + const setFeedBottom = (px) => { + if (feed.classList.contains("collapsed")) return; + const next = Math.max(8, Math.min(160, px)); + feed.style.bottom = next + "px"; + localStorage.setItem("feed_bottom", feed.style.bottom); + }; + + let dragging = false; + let startY = 0; + let startBottom = 0; + handle.addEventListener("mousedown", (e) => { + if (e.target.closest("button")) return; + if (feed.classList.contains("collapsed")) return; + dragging = true; + startY = e.clientY; + startBottom = feedBottomPx(); + e.preventDefault(); + }); + window.addEventListener("mousemove", (e) => { + if (!dragging) return; + const dy = e.clientY - startY; + setFeedBottom(startBottom - dy); + }); + window.addEventListener("mouseup", () => { + dragging = false; + }); + } + + // GPU via fleet snapshot + dedicated WS messages: monkey-patch WebSocket if needed + function hookGpuFromFleet() { + const orig = window.__applyGpu; + // poll GPU every 2s as backup + async function tick() { + try { + renderGpu(await api.get("/api/gpu")); + } catch (_) {} + } + tick(); + setInterval(tick, 2500); + + // listen custom event from app.js if dispatched + window.addEventListener("cockpit-gpu", (e) => renderGpu(e.detail)); + window.addEventListener("cockpit-snapshot", (e) => { + if (e.detail?.gpu) renderGpu(e.detail.gpu); + }); + } + + + // ===== Realtime triage popup ===== + let triageMode = "critical"; + let triageSelected = null; + let triageFilter = ""; + + function closeTriage() { + const modal = $("#triage-modal"); + modal?.classList.add("hidden"); + modal?.setAttribute("aria-hidden", "true"); + const scrim = $("#scrim"); + if (scrim?.dataset.mode === "triage") { + scrim.classList.remove("open"); + delete scrim.dataset.mode; + } + } + + function openTriage(mode = "critical", opts = {}) { + triageMode = mode || "critical"; + triageFilter = ""; + const search = $("#triage-search"); + if (search) search.value = ""; + const modal = $("#triage-modal"); + const scrim = $("#scrim"); + if (!modal) return; + // close other overlays lightly + modal.classList.remove("hidden"); + modal.setAttribute("aria-hidden", "false"); + scrim?.classList.add("open"); + if (scrim) scrim.dataset.mode = "triage"; + + $("#triage-tabs")?.querySelectorAll("[data-triage]").forEach((c) => { + c.classList.toggle("active", c.dataset.triage === triageMode); + }); + const titles = { + critical: "Critical alerts", + warning: "Warning alerts", + events: "Fleet deltas", + hottest: "Live power ranking", + all: "Realtime alert feed", + }; + const elTitle = $("#triage-title"); + if (elTitle) elTitle.textContent = titles[triageMode] || "Realtime triage"; + renderTriageList(opts); + } + + function cockpitData() { + return window.cockpit?.getState?.()?.data || {}; + } + + function deviceById(id) { + if (id == null || id === "") return null; + return (cockpitData().devices || []).find((d) => String(d.id) === String(id)) || null; + } + + function triageItems(mode) { + const d = cockpitData(); + const items = []; + if (mode === "critical" || mode === "warning" || mode === "all") { + const want = mode === "all" ? null : mode === "critical" ? "Critical" : "Warning"; + for (const a of d.alerts || []) { + if (want && String(a.severity) !== want) continue; + items.push({ + kind: "alert", + id: "alert-" + a.id, + alertId: a.id, + deviceId: a.device_id, + severity: a.severity, + title: a.device || "Unknown system", + message: a.message || "", + meta: [a.ip || "no-ip", a.category, a.subcategory, a.message_id, a.time].filter(Boolean).join(" · "), + raw: a, + sort: Date.parse(String(a.time || "").replace(" ", "T") + "Z") || 0, + }); + } + } + if (mode === "events" || mode === "all") { + for (const e of d.events || []) { + items.push({ + kind: "event", + id: "event-" + e.ts + "-" + e.device_id + "-" + e.kind, + deviceId: e.device_id, + severity: e.severity || "info", + title: e.title || e.kind, + message: e.text || "", + meta: (e.kind || "delta") + " · " + new Date((e.ts || 0) * 1000).toLocaleString(), + raw: e, + sort: (e.ts || 0) * 1000, + }); + } + } + if (mode === "hottest" || mode === "all") { + for (const h of (d.context || {}).hottest || []) { + items.push({ + kind: "power", + id: "hot-" + h.id, + deviceId: h.id, + severity: "info", + title: h.name || "node", + message: Math.round(h.watts || 0) + " W live sample", + meta: (h.subnet || "") + " · power ranking", + raw: h, + sort: (h.watts || 0) * 1e6, + }); + } + } + items.sort((x, y) => (y.sort || 0) - (x.sort || 0)); + return items; + } + + function renderTriageList(opts = {}) { + const list = $("#triage-list"); + if (!list) return; + let items = triageItems(triageMode); + const q = (triageFilter || "").trim().toLowerCase(); + if (q) { + items = items.filter((it) => + [it.title, it.message, it.meta, it.severity].join(" ").toLowerCase().includes(q) + ); + } + const sub = $("#triage-sub"); + if (sub) { + const systems = new Set(items.map((i) => i.title)); + sub.textContent = items.length + " items · " + systems.size + " systems · inspect & create ATC ticket"; + } + if (!items.length) { + list.innerHTML = '

No matching items in the current live snapshot.

'; + $("#triage-detail").innerHTML = '

Nothing selected.

'; + triageSelected = null; + return; + } + const groups = new Map(); + for (const it of items) { + const g = it.title || "Unknown"; + if (!groups.has(g)) groups.set(g, []); + groups.get(g).push(it); + } + let html = ""; + for (const [sys, rows] of groups) { + html += '
' + escape(sys) + " · " + rows.length + "
"; + for (const it of rows) { + const sev = String(it.severity || "").toLowerCase(); + const cls = sev.includes("crit") ? "critical" : sev.includes("warn") ? "warning" : "info"; + const active = triageSelected && triageSelected.id === it.id ? " active" : ""; + html += + '"; + } + } + list.innerHTML = html; + let pick = items[0]; + if (opts.alertId) pick = items.find((i) => String(i.alertId) === String(opts.alertId)) || pick; + else if (opts.deviceId) pick = items.find((i) => String(i.deviceId) === String(opts.deviceId)) || pick; + selectTriageItem(pick); + } + + function selectTriageItem(it) { + triageSelected = it; + $("#triage-list")?.querySelectorAll(".triage-item").forEach((el) => { + el.classList.toggle("active", el.dataset.triageId === (it && it.id)); + }); + const detail = $("#triage-detail"); + if (!detail || !it) return; + const node = deviceById(it.deviceId); + const a = it.kind === "alert" ? it.raw : null; + const connected = node && node.connected ? "CONNECTED" : "OFFLINE / unknown"; + const watts = node && node.watts != null ? Math.round(node.watts) + " W" : "n/a"; + detail.innerHTML = + "

" + + escape(it.title) + + '

' + + escape(it.severity || it.kind) + + '' + + connected + + "" + + (node && node.watts != null ? '' + watts + "" : "") + + '
' + + '
System' + + escape(it.title) + + "
" + + '
IP' + + escape((node && node.ip) || (a && a.ip) || "—") + + "
" + + '
Model' + + escape((node && node.model) || "—") + + "
" + + '
Service tag' + + escape((node && node.service_tag) || "—") + + "
" + + '
Subnet' + + escape((node && node.subnet) || "—") + + "
" + + '
Message' + + escape(it.message || "—") + + "
" + + (a && a.action + ? '
Recommended' + escape(a.action) + "
" + : "") + + '
Meta' + + escape(it.meta) + + "
" + + '
' + + '' + + '' + + '" + + '' + + '' + + '
'; + + $("#triage-ticket")?.addEventListener("click", () => createTicketFromTriage(it, node)); + $("#triage-focus")?.addEventListener("click", () => { + if (it.deviceId != null) window.cockpit?.focusDeviceId?.(it.deviceId); + closeTriage(); + }); + $("#triage-connect")?.addEventListener("click", () => { + if (!node) return; + closeTriage(); + window.cockpit?.openConnect?.(node); + }); + $("#triage-ops")?.addEventListener("click", async () => { + closeTriage(); + openDrawer("#ops-drawer"); + await loadTickets(); + }); + $("#triage-ai")?.addEventListener("click", () => { + closeTriage(); + openDrawer("#chat-drawer"); + sendChat( + "Triage this " + + (it.severity || it.kind) + + " on " + + it.title + + " (" + + ((node && node.ip) || (a && a.ip) || "no-ip") + + "): " + + it.message + + ". Suggest next steps for ATC admins Jody and Laurens." + ); + }); + $("#triage-inspect")?.addEventListener("click", () => { + if (node) window.cockpit?.showInspector?.(node); + closeTriage(); + }); + } + + async function createTicketFromTriage(it, node) { + const me = actor(); + const other = me === "jody" ? "laurens" : "jody"; + const sev = it.severity || it.kind || "alert"; + const title = ("[" + sev + "] " + it.title).slice(0, 180); + const body = [ + "Auto-triage from OpenManage Cockpit", + "Reporter: " + adminName(me), + "Assignee: " + adminName(other), + "System: " + it.title, + "IP: " + ((node && node.ip) || (it.raw && it.raw.ip) || "—"), + "Model: " + ((node && node.model) || "—"), + "Service tag: " + ((node && node.service_tag) || "—"), + "Subnet: " + ((node && node.subnet) || "—"), + "Severity: " + sev, + "Message: " + it.message, + it.meta ? "Meta: " + it.meta : "", + it.raw && it.raw.action ? "Recommended: " + it.raw.action : "", + ] + .filter(Boolean) + .join("\n"); + closeTriage(); + openTicketModal({ + title, + body, + assignee: other, + priority: String(sev).toLowerCase().includes("crit") ? "critical" : "high", + }); + } + + + + function wire() { + $("#ops-actor")?.addEventListener("change", (e) => { + localStorage.setItem("atc_actor", e.target.value); + }); + const saved = localStorage.getItem("atc_actor"); + if (saved && $("#ops-actor")) $("#ops-actor").value = saved; + + + if (window.cockpit) window.cockpit.openTriage = openTriage; + else window.cockpit = { openTriage }; + $("#btn-triage-close")?.addEventListener("click", closeTriage); + $("#triage-tabs")?.addEventListener("click", (e) => { + const btn = e.target.closest("[data-triage]"); + if (!btn) return; + openTriage(btn.dataset.triage); + }); + $("#triage-search")?.addEventListener("input", (e) => { + triageFilter = e.target.value || ""; + renderTriageList(); + }); + $("#triage-list")?.addEventListener("click", (e) => { + const btn = e.target.closest("[data-triage-id]"); + if (!btn) return; + const it = triageItems(triageMode).find((x) => x.id === btn.dataset.triageId); + if (it) selectTriageItem(it); + }); + + $("#btn-chat")?.addEventListener("click", () => { + openDrawer("#chat-drawer"); + loadChatModels(); + if (!$("#chat-body")?.children.length) { + appendChat( + "assistant", + "Cockpit Copilot online. Pick a model above (same catalog as OpenManage AI), then ask about fleet health, alerts, power, or GPUs." + ); + } + }); + $("#chat-model")?.addEventListener("change", (e) => { + localStorage.setItem("cockpit_chat_model", e.target.value); + chatHistory.length = 0; + const body = $("#chat-body"); + if (body) body.innerHTML = ""; + appendChat("assistant", `Model switched to ${e.target.value}. Context cleared.`); + }); + $("#btn-chat-close")?.addEventListener("click", closeDrawers); + $("#btn-ops")?.addEventListener("click", async () => { + openDrawer("#ops-drawer"); + await loadTickets(); + }); + $("#btn-ops-close")?.addEventListener("click", closeDrawers); + + $("#ops-filter")?.addEventListener("change", () => loadTickets()); + $("#btn-ticket-modal-close")?.addEventListener("click", closeTicketModal); + $("#btn-ticket-cancel")?.addEventListener("click", closeTicketModal); + $("#ticket-form")?.addEventListener("submit", async (e) => { + e.preventDefault(); + const title = $("#ticket-title")?.value?.trim(); + const body = $("#ticket-body")?.value?.trim(); + if (!title || !body) return; + try { + const created = await api.post("/api/tickets", { + title, + body, + created_by: actor(), + assignee: $("#ticket-assignee").value, + priority: $("#ticket-priority").value, + }); + closeTicketModal(); + openDrawer("#ops-drawer"); + await loadTickets(); + await openTicket(created.id); + } catch (err) { + alert("Ticket create failed: " + err.message); + } + }); + $("#chat-quick")?.addEventListener("click", (e) => { + const btn = e.target.closest("[data-q]"); + if (!btn) return; + sendChat(btn.dataset.q); + }); + window.addEventListener("cockpit-snapshot", () => refreshChatContext()); + + $("#btn-new-ticket")?.addEventListener("click", () => newTicket().catch((e) => alert(e.message))); + $("#ticket-list")?.addEventListener("click", (e) => { + const btn = e.target.closest("[data-ticket]"); + if (!btn) return; + openTicket(Number(btn.dataset.ticket)).catch((err) => alert(err.message)); + }); + + $("#chat-form")?.addEventListener("submit", (e) => { + e.preventDefault(); + const input = $("#chat-input"); + const msg = input?.value?.trim(); + if (!msg) return; + input.value = ""; + sendChat(msg); + }); + + // Extend scrim close + const scrim = $("#scrim"); + scrim?.addEventListener("click", () => { + const mode = scrim.dataset.mode; + if (mode === "chat-drawer" || mode === "ops-drawer" || mode === "ai-drawer") closeDrawers(); + }); + + initFeedDrag(); + hookGpuFromFleet(); + } + + if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", wire); + else wire(); +})(); diff --git a/ui/ssh.js b/ui/ssh.js new file mode 100644 index 0000000..3081af8 --- /dev/null +++ b/ui/ssh.js @@ -0,0 +1,287 @@ +(() => { + const $ = (sel) => document.querySelector(sel); + + let term = null; + let fitAddon = null; + let socket = null; + let connected = false; + let connectInFlight = false; + let currentHost = ""; + + function protoWs() { + return location.protocol === "https:" ? "wss" : "ws"; + } + + function rememberUser(user) { + if (user) localStorage.setItem("cockpit_ssh_user", user); + } + + function rememberedUser() { + return localStorage.getItem("cockpit_ssh_user") || ""; + } + + function openSshModal(opts = {}) { + const modal = $("#ssh-modal"); + const scrim = $("#scrim"); + if (!modal) return; + + currentHost = opts.host || ""; + $("#ssh-host").value = currentHost; + $("#ssh-port").value = opts.port || 22; + $("#ssh-user").value = opts.username || rememberedUser(); + $("#ssh-pass").value = ""; + $("#ssh-device").textContent = opts.name || currentHost || "SSH session"; + $("#ssh-sub").textContent = opts.model + ? `${opts.model}${opts.ip ? " · " + opts.ip : ""}` + : opts.ip || currentHost || "—"; + $("#ssh-status").textContent = "Enter username and password, then Connect."; + $("#ssh-status").className = "ssh-status"; + $("#ssh-connect-btn").disabled = false; + $("#ssh-term-wrap").classList.add("hidden"); + $("#ssh-login").classList.remove("hidden"); + + modal.classList.remove("hidden"); + modal.setAttribute("aria-hidden", "false"); + scrim?.classList.add("open"); + if (scrim) scrim.dataset.mode = "ssh"; + + setTimeout(() => { + const u = $("#ssh-user"); + if (u && !u.value) u.focus(); + else $("#ssh-pass")?.focus(); + }, 50); + } + + function closeSshModal() { + disconnectSsh(); + const modal = $("#ssh-modal"); + modal?.classList.add("hidden"); + modal?.setAttribute("aria-hidden", "true"); + const scrim = $("#scrim"); + if (scrim?.dataset.mode === "ssh") { + scrim.classList.remove("open"); + delete scrim.dataset.mode; + } + } + + function setStatus(msg, kind) { + const el = $("#ssh-status"); + if (!el) return; + el.textContent = msg; + el.className = "ssh-status" + (kind ? " " + kind : ""); + } + + function ensureTerminal() { + if (term) return term; + if (!window.Terminal) { + setStatus("Terminal library missing — hard refresh (Ctrl+Shift+R) or check /vendor/xterm/", "error"); + $("#ssh-login")?.classList.remove("hidden"); + return null; + } + term = new window.Terminal({ + cursorBlink: true, + fontFamily: "IBM Plex Mono, ui-monospace, Menlo, monospace", + fontSize: 13, + lineHeight: 1.2, + theme: { + background: "#071018", + foreground: "#e8f4ff", + cursor: "#3dffe0", + selectionBackground: "rgba(0,168,232,0.35)", + }, + allowProposedApi: true, + }); + const FitCtor = window.FitAddon?.FitAddon || window.FitAddon; + fitAddon = FitCtor ? new FitCtor() : null; + if (fitAddon) term.loadAddon(fitAddon); + term.open($("#ssh-term")); + term.onData((data) => { + if (!socket || socket.readyState !== WebSocket.OPEN || !connected) return; + socket.send(data); + }); + window.addEventListener("resize", () => { + try { + fitAddon?.fit(); + sendResize(); + } catch (_) {} + }); + return term; + } + + function sendResize() { + if (!socket || socket.readyState !== WebSocket.OPEN || !term) return; + socket.send( + JSON.stringify({ + type: "resize", + cols: term.cols, + rows: term.rows, + }) + ); + } + + function disconnectSsh() { + connected = false; + try { + socket?.close(); + } catch (_) {} + socket = null; + try { + term?.reset(); + } catch (_) {} + } + + async function connectSsh() { + if (connectInFlight) return; + const host = ($("#ssh-host")?.value || "").trim(); + const username = ($("#ssh-user")?.value || "").trim(); + const password = $("#ssh-pass")?.value || ""; + const port = Number($("#ssh-port")?.value || 22); + + if (!host || !username) { + setStatus("Host and username are required", "error"); + return; + } + if (!password) { + setStatus("Password is required", "error"); + $("#ssh-pass")?.focus(); + return; + } + + rememberUser(username); + connectInFlight = true; + disconnectSsh(); + $("#ssh-login").classList.add("hidden"); + $("#ssh-term-wrap").classList.remove("hidden"); + const t = ensureTerminal(); + if (!t) return; + t.reset(); + t.focus(); + try { + fitAddon?.fit(); + } catch (_) {} + + setStatus(`Connecting as ${username}@${host}:${port}…`, "info"); + $("#ssh-connect-btn").disabled = true; + + const ws = new WebSocket(`${protoWs()}://${location.host}/ws/ssh`); + socket = ws; + + ws.onopen = () => { + ws.send( + JSON.stringify({ + type: "auth", + host, + port, + username, + password, + cols: t.cols || 120, + rows: t.rows || 36, + term: "xterm-256color", + }) + ); + // clear password from DOM after send + if ($("#ssh-pass")) $("#ssh-pass").value = ""; + }; + + ws.onmessage = (ev) => { + const data = String(ev.data || ""); + if (data.startsWith("{") && data.includes('"type"')) { + try { + const msg = JSON.parse(data); + if (msg.type === "ready") { + connected = true; + connectInFlight = false; + setStatus(msg.message || "Connected", "ok"); + $("#ssh-connect-btn").disabled = false; + $("#ssh-connect-btn").textContent = "Reconnect"; + try { + fitAddon?.fit(); + sendResize(); + t.focus(); + } catch (_) {} + return; + } + if (msg.type === "status") { + setStatus(msg.message || "", "info"); + return; + } + if (msg.type === "error") { + connected = false; + connectInFlight = false; + setStatus(msg.message || "SSH error", "error"); + $("#ssh-connect-btn").disabled = false; + $("#ssh-login").classList.remove("hidden"); + return; + } + if (msg.type === "pong") return; + } catch (_) { + // fall through as terminal output + } + } + t.write(data); + }; + + ws.onerror = () => { + setStatus("WebSocket error", "error"); + $("#ssh-connect-btn").disabled = false; + $("#ssh-login").classList.remove("hidden"); + }; + + ws.onclose = () => { + connected = false; + connectInFlight = false; + setStatus("Disconnected", "info"); + $("#ssh-connect-btn").disabled = false; + $("#ssh-connect-btn").textContent = "Connect"; + }; + } + + function openSshForNode(node) { + if (!node?.ip) { + alert("No management IP for this device"); + return; + } + openSshModal({ + host: node.ip, + ip: node.ip, + name: node.name, + model: node.model, + username: rememberedUser(), + }); + } + + function bind() { + $("#btn-ssh-close")?.addEventListener("click", closeSshModal); + $("#btn-ssh-disconnect")?.addEventListener("click", () => { + disconnectSsh(); + $("#ssh-login").classList.remove("hidden"); + setStatus("Disconnected. Enter credentials to reconnect.", "info"); + }); + $("#ssh-form")?.addEventListener("submit", (e) => { + e.preventDefault(); + connectSsh(); + }); + $("#ssh-connect-btn")?.addEventListener("click", (e) => { + e.preventDefault(); + connectSsh(); + }); + + // Scrim close for SSH + $("#scrim")?.addEventListener("click", () => { + if ($("#scrim")?.dataset.mode === "ssh") closeSshModal(); + }); + window.addEventListener("keydown", (e) => { + if (e.key === "Escape" && !$("#ssh-modal")?.classList.contains("hidden")) { + closeSshModal(); + } + }); + } + + bind(); + + window.cockpitSsh = { + open: openSshForNode, + openModal: openSshModal, + close: closeSshModal, + }; +})(); diff --git a/ui/styles.css b/ui/styles.css new file mode 100644 index 0000000..067d05b --- /dev/null +++ b/ui/styles.css @@ -0,0 +1,1707 @@ +:root { + --bg: #050b14; + --bg-deep: #02060c; + --panel: rgba(8, 18, 32, 0.92); + --panel-border: rgba(0, 168, 232, 0.22); + --dell: #0076ce; + --dell-bright: #00a8e8; + --cyan: #3dffe0; + --amber: #ffb020; + --red: #ff5c5c; + --green: #3dffa0; + --text: #e8f4ff; + --muted: #7a93a8; + --mono: "IBM Plex Mono", ui-monospace, monospace; + --sans: "IBM Plex Sans", system-ui, sans-serif; + --rail-w: 280px; + --top-h: auto; + --tick-h: 36px; +} + +* { box-sizing: border-box; } +html, body { height: 100%; margin: 0; background: var(--bg-deep); color: var(--text); font-family: var(--sans); } +button, input { font: inherit; color: inherit; } +button { cursor: pointer; } +.hidden { display: none !important; } + +#app { + display: grid; + grid-template-columns: var(--rail-w) 1fr var(--rail-w); + grid-template-rows: auto 1fr auto; + height: 100vh; + background: + radial-gradient(ellipse 80% 60% at 50% 40%, rgba(0, 118, 206, 0.12), transparent 60%), + var(--bg); +} + +.topbar { + grid-column: 1 / -1; + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 0.65rem 1rem; + padding: 0.55rem 1rem; + min-height: 64px; + border-bottom: 1px solid var(--panel-border); + background: linear-gradient(180deg, rgba(0, 40, 70, 0.55), rgba(5, 11, 20, 0.9)); + z-index: 5; + overflow: visible; +} + +.brand { + display: flex; + align-items: center; + gap: 0.75rem; + text-decoration: none; + color: inherit; + min-width: 260px; +} +.brand:hover .dell-logo { filter: brightness(1.15); } +.dell-logo { + display: block; + height: 44px; + width: 44px; + object-fit: contain; + border-radius: 50%; +} +.drawer-brand img { + height: 28px !important; + width: 28px !important; + border-radius: 50%; + object-fit: contain; +} +.inspector-empty .ghost-logo { + width: 64px !important; + height: 64px !important; + border-radius: 50%; + object-fit: contain; + opacity: 0.35; +} +.brand-text h1 { + margin: 0; + font-size: 1.05rem; + font-weight: 600; + letter-spacing: 0.02em; +} +.brand-text h1 span { color: var(--dell-bright); font-weight: 700; } +.brand-text p { + margin: 0.1rem 0 0; + font-family: var(--mono); + font-size: 0.68rem; + color: var(--muted); +} + +.kpi-strip { + flex: 1; + display: flex; + flex-wrap: wrap; + gap: 0.3rem; + overflow: visible; + padding: 0.35rem 0; + min-width: 0; + justify-content: flex-start; + align-content: center; +} +.kpi { + appearance: none; + border: 1px solid transparent; + background: rgba(0, 118, 206, 0.12); + border-radius: 6px; + padding: 0.28rem 0.55rem; + min-width: 0; + flex: 0 1 auto; + text-align: left; + transition: border-color 0.15s, background 0.15s, transform 0.15s; +} +.kpi:hover { border-color: var(--dell-bright); background: rgba(0, 168, 232, 0.18); transform: translateY(-1px); } +.kpi.active { border-color: var(--cyan); box-shadow: 0 0 0 1px rgba(61, 255, 224, 0.25); } +.kpi .v { + display: block; + font-family: var(--mono); + font-size: 0.88rem; + font-weight: 600; + color: var(--cyan); + line-height: 1.1; + white-space: nowrap; +} +.kpi .l { + display: block; + font-size: 0.58rem; + text-transform: uppercase; + letter-spacing: 0.05em; + color: var(--muted); + margin-top: 0.08rem; + white-space: nowrap; +} +.kpi.warn .v { color: var(--amber); } +.kpi.danger .v { color: var(--red); } +.kpi.power .v { color: #7ec8ff; } + +.top-actions { display: flex; gap: 0.4rem; flex-shrink: 0; } +.btn { + border: 1px solid var(--panel-border); + background: rgba(8, 22, 40, 0.8); + border-radius: 6px; + padding: 0.45rem 0.8rem; + font-size: 0.8rem; + font-weight: 500; +} +.btn:hover { border-color: var(--dell-bright); color: #fff; } +.btn.primary { + background: linear-gradient(135deg, var(--dell), #005a9e); + border-color: #0a8ad8; + color: #fff; +} +.btn.primary:hover { filter: brightness(1.08); } +.btn.ghost { background: transparent; } + +.rail { + background: var(--panel); + border-right: 1px solid var(--panel-border); + overflow-x: hidden; + overflow-y: auto; + padding: 0.75rem; + z-index: 3; + scrollbar-width: thin; + scrollbar-color: rgba(0,168,232,0.35) transparent; +} +.rail .list { + max-height: none; + overflow: visible; +} +.rail.right { + border-right: none; + border-left: 1px solid var(--panel-border); +} +.rail-block { + margin-bottom: 0.45rem; + border: 1px solid rgba(0, 168, 232, 0.12); + border-radius: 8px; + background: rgba(0, 24, 44, 0.35); + overflow: hidden; +} +.rail-toggle { + width: 100%; + display: flex; + align-items: center; + justify-content: space-between; + gap: 0.5rem; + appearance: none; + border: none; + background: transparent; + color: var(--dell-bright); + padding: 0.55rem 0.65rem; + font-size: 0.68rem; + letter-spacing: 0.12em; + text-transform: uppercase; + font-weight: 600; + cursor: pointer; + text-align: left; +} +.rail-toggle:hover { background: rgba(0, 118, 206, 0.12); color: #fff; } +.rail-toggle .chev { + width: 0.45rem; + height: 0.45rem; + border-right: 2px solid currentColor; + border-bottom: 2px solid currentColor; + transform: rotate(-45deg); + transition: transform 0.18s ease; + flex-shrink: 0; + opacity: 0.85; +} +.rail-block.open .rail-toggle .chev { + transform: rotate(45deg); +} +.rail-panel { + display: none; + padding: 0 0.65rem 0.7rem; +} +.rail-block.open .rail-panel { display: block; } +.rail-block h2 { + margin: 0 0 0.2rem; + font-size: 0.68rem; + letter-spacing: 0.12em; + text-transform: uppercase; + color: var(--dell-bright); + font-weight: 600; +} +.hint { margin: 0 0 0.55rem; font-size: 0.72rem; color: var(--muted); line-height: 1.35; } + +.chip-grid { display: flex; flex-wrap: wrap; gap: 0.35rem; } +.chip { + border: 1px solid var(--panel-border); + background: rgba(0, 40, 70, 0.4); + border-radius: 999px; + padding: 0.28rem 0.65rem; + font-size: 0.72rem; + color: var(--muted); +} +.chip:hover { color: var(--text); border-color: var(--dell-bright); } +.chip.active { + color: #041018; + background: var(--cyan); + border-color: var(--cyan); + font-weight: 600; +} + +.list { display: flex; flex-direction: column; gap: 0.35rem; } +.card { + appearance: none; + text-align: left; + width: 100%; + border: 1px solid rgba(0, 168, 232, 0.15); + background: rgba(0, 30, 55, 0.45); + border-radius: 8px; + padding: 0.55rem 0.65rem; + transition: border-color 0.15s, background 0.15s; +} +.card:hover { border-color: var(--dell-bright); background: rgba(0, 80, 130, 0.25); } +.card.active { + border-color: var(--cyan); + background: rgba(61, 255, 224, 0.08); + box-shadow: inset 0 0 0 1px rgba(61, 255, 224, 0.15); +} +.card .t { display: block; font-size: 0.84rem; font-weight: 600; } +.card .s { + display: block; + margin-top: 0.15rem; + font-family: var(--mono); + font-size: 0.68rem; + color: var(--muted); +} + +.filters { display: flex; flex-direction: column; gap: 0.4rem; margin-bottom: 0.6rem; } +.toggle { + display: flex; + align-items: center; + gap: 0.5rem; + font-size: 0.78rem; + color: var(--text); + cursor: pointer; +} +.toggle input { accent-color: var(--dell-bright); } +.range { + display: flex; + flex-direction: column; + gap: 0.25rem; + font-size: 0.72rem; + color: var(--muted); + margin-top: 0.25rem; +} +.range input { width: 100%; accent-color: var(--dell-bright); } +.range em { color: var(--cyan); font-style: normal; font-family: var(--mono); } +.search { + width: 100%; + border: 1px solid var(--panel-border); + background: rgba(0, 20, 40, 0.6); + border-radius: 6px; + padding: 0.45rem 0.6rem; + font-size: 0.78rem; + outline: none; +} +.search:focus { border-color: var(--dell-bright); } + +.stage { + position: relative; + overflow: hidden; + background: + radial-gradient(circle at 50% 48%, rgba(0, 118, 206, 0.08), transparent 45%), + repeating-radial-gradient(circle at 50% 48%, transparent 0, transparent 38px, rgba(0, 168, 232, 0.04) 39px, transparent 40px); +} +#topo { + display: block; + width: 100%; + height: 100%; + cursor: grab; +} +#topo:active { cursor: grabbing; } + +.stage-hud { + position: absolute; + left: 0.75rem; + right: 0.75rem; + bottom: 0.6rem; + display: flex; + justify-content: space-between; + align-items: flex-end; + pointer-events: none; + gap: 1rem; +} +.legend { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + font-family: var(--mono); + font-size: 0.65rem; + color: var(--muted); + background: rgba(2, 8, 16, 0.65); + padding: 0.35rem 0.55rem; + border-radius: 6px; + border: 1px solid rgba(0, 168, 232, 0.15); +} +.legend span::before { + content: ""; + display: inline-block; + width: 8px; + height: 8px; + border-radius: 50%; + margin-right: 0.35rem; + background: var(--c, var(--muted)); + vertical-align: middle; +} +.hint-bar { + font-size: 0.65rem; + color: rgba(122, 147, 168, 0.85); + font-family: var(--mono); +} + +.inspector-empty, .inspector-body { padding: 0.25rem; } +.inspector-empty { + text-align: center; + padding-top: 2.5rem; + color: var(--muted); +} +.inspector-empty .ghost-logo { + width: 72px; + opacity: 0.25; + margin-bottom: 0.75rem; +} +.inspector-empty h2 { + color: var(--dell-bright); + font-size: 0.9rem; + letter-spacing: 0.08em; + text-transform: uppercase; +} +.inspector-empty p { font-size: 0.8rem; line-height: 1.45; } + +.insp-head { margin-bottom: 0.85rem; } +.insp-head h2 { + margin: 0; + font-size: 1rem; + word-break: break-word; +} +.insp-head .meta { + margin: 0.25rem 0 0; + font-family: var(--mono); + font-size: 0.7rem; + color: var(--muted); +} +.badge-row { display: flex; flex-wrap: wrap; gap: 0.3rem; margin: 0.55rem 0; } +.badge { + font-size: 0.65rem; + font-family: var(--mono); + padding: 0.2rem 0.45rem; + border-radius: 4px; + border: 1px solid var(--panel-border); + color: var(--muted); +} +.badge.on { color: var(--green); border-color: rgba(61, 255, 160, 0.4); } +.badge.off { color: var(--red); border-color: rgba(255, 92, 92, 0.4); } +.badge.power { color: #7ec8ff; border-color: rgba(126, 200, 255, 0.4); } + +.kv { display: grid; gap: 0.35rem; margin: 0.6rem 0; } +.kv-row { + display: grid; + grid-template-columns: 96px 1fr; + gap: 0.4rem; + font-size: 0.75rem; + padding: 0.3rem 0; + border-bottom: 1px solid rgba(0, 168, 232, 0.08); +} +.kv-row .k { color: var(--muted); } +.kv-row .v { font-family: var(--mono); word-break: break-all; } +.kv-row a { color: var(--dell-bright); } + +.action-stack { display: flex; flex-direction: column; gap: 0.35rem; margin-top: 0.75rem; } +.action-stack .btn { width: 100%; text-align: center; } + +.inv-section { margin-top: 0.9rem; } +.inv-section h3 { + margin: 0 0 0.35rem; + font-size: 0.68rem; + letter-spacing: 0.1em; + text-transform: uppercase; + color: var(--dell-bright); +} +.inv-line { + font-family: var(--mono); + font-size: 0.68rem; + color: var(--muted); + padding: 0.2rem 0; + border-bottom: 1px solid rgba(255, 255, 255, 0.04); +} + +.ticker { + grid-column: 1 / -1; + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 0.35rem 1rem; + padding: 0.35rem 1rem; + border-top: 1px solid var(--panel-border); + background: rgba(2, 8, 16, 0.95); + font-family: var(--mono); + font-size: 0.7rem; + color: var(--muted); + overflow: hidden; +} +.ticker button { + appearance: none; + border: none; + background: none; + color: var(--cyan); + padding: 0; + font: inherit; +} +.ticker button:hover { text-decoration: underline; color: #fff; } +.ticker .sep { opacity: 0.35; } + +.drawer { + position: fixed; + top: 0; + right: 0; + width: min(520px, 100vw); + height: 100vh; + background: #0a121c; + border-left: 1px solid var(--panel-border); + z-index: 40; + transform: translateX(105%); + transition: transform 0.28s ease; + display: flex; + flex-direction: column; +} +.drawer.open { transform: translateX(0); } +.drawer-head { + display: flex; + align-items: center; + justify-content: space-between; + padding: 0.65rem 0.85rem; + border-bottom: 1px solid var(--panel-border); +} +.drawer-brand { display: flex; align-items: center; gap: 0.55rem; font-weight: 600; } +.drawer-brand img { height: 22px; width: auto; } +#ai-frame { flex: 1; border: 0; width: 100%; background: #111; } +.scrim { + position: fixed; + inset: 0; + background: rgba(0, 0, 0, 0.45); + z-index: 30; + opacity: 0; + pointer-events: none; + transition: opacity 0.25s; +} +.scrim.open { opacity: 1; pointer-events: auto; } + +@media (max-width: 1100px) { + #app { + grid-template-columns: 240px 1fr; + grid-template-rows: auto 1fr auto; + } + .rail.right { + grid-column: 1 / -1; + grid-row: 3; + max-height: 220px; + border-left: none; + border-top: 1px solid var(--panel-border); + } + .ticker { grid-row: 4; } +} + + +/* Visualization layout picker */ +.viz-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 0.4rem; +} +.viz-card { + appearance: none; + border: 1px solid rgba(0, 168, 232, 0.18); + background: rgba(0, 30, 55, 0.55); + border-radius: 8px; + padding: 0.5rem 0.45rem; + text-align: left; + color: var(--muted); + transition: border-color 0.15s, background 0.15s, transform 0.15s; + display: flex; + flex-direction: column; + gap: 0.08rem; + min-height: 64px; +} +.viz-card:nth-child(5) { + grid-column: 1 / -1; +} +.viz-card:hover { + border-color: var(--dell-bright); + color: var(--text); + transform: translateY(-1px); +} +.viz-card.active { + border-color: var(--cyan); + background: rgba(61, 255, 224, 0.1); + color: var(--text); + box-shadow: inset 0 0 0 1px rgba(61, 255, 224, 0.2); +} +.viz-ico { + font-size: 0.95rem; + color: var(--dell-bright); + line-height: 1; +} +.viz-card.active .viz-ico { color: var(--cyan); } +.viz-t { + font-size: 0.78rem; + font-weight: 600; + color: inherit; +} +.viz-s { + font-family: var(--mono); + font-size: 0.58rem; + color: var(--muted); + letter-spacing: 0.02em; +} + +/* Realtime context */ +.ctx-bar { + position: absolute; + top: 0.6rem; + left: 0.75rem; + right: 0.75rem; + z-index: 4; + display: flex; + flex-wrap: wrap; + gap: 0.45rem 0.85rem; + align-items: center; + justify-content: space-between; + pointer-events: none; + font-family: var(--mono); + font-size: 0.68rem; +} +.ctx-live, .ctx-focus { + pointer-events: none; + background: rgba(2, 10, 20, 0.72); + border: 1px solid rgba(0, 168, 232, 0.22); + border-radius: 6px; + padding: 0.35rem 0.6rem; + color: var(--muted); + max-width: 100%; +} +.ctx-live { + display: flex; + align-items: center; + gap: 0.45rem; + color: var(--text); +} +.pulse-dot { + width: 7px; + height: 7px; + border-radius: 50%; + background: var(--cyan); + box-shadow: 0 0 0 0 rgba(61, 255, 224, 0.55); + animation: pulse-ring 1.6s ease-out infinite; + flex-shrink: 0; +} +@keyframes pulse-ring { + 0% { box-shadow: 0 0 0 0 rgba(61, 255, 224, 0.45); } + 70% { box-shadow: 0 0 0 8px rgba(61, 255, 224, 0); } + 100% { box-shadow: 0 0 0 0 rgba(61, 255, 224, 0); } +} +.ctx-focus { color: var(--dell-bright); } + +.ctx-feed { + position: absolute; + right: 0.75rem; + bottom: 2.4rem; + width: min(340px, calc(100% - 1.5rem)); + max-height: 42%; + z-index: 4; + background: rgba(2, 10, 20, 0.82); + border: 1px solid rgba(0, 168, 232, 0.22); + border-radius: 8px; + backdrop-filter: blur(6px); + display: flex; + flex-direction: column; + overflow: hidden; + pointer-events: auto; +} +.ctx-feed-head { + display: flex; + justify-content: space-between; + align-items: center; + padding: 0.45rem 0.65rem; + border-bottom: 1px solid rgba(0, 168, 232, 0.15); + font-size: 0.68rem; + letter-spacing: 0.08em; + text-transform: uppercase; + color: var(--dell-bright); +} +.ctx-feed-head span { + text-transform: none; + letter-spacing: 0; + color: var(--muted); + font-family: var(--mono); + font-size: 0.62rem; +} +.ctx-feed-body { + overflow-y: auto; + max-height: 220px; + padding: 0.25rem; + scrollbar-width: thin; +} +.feed-item { + appearance: none; + width: 100%; + text-align: left; + border: none; + background: transparent; + border-radius: 6px; + padding: 0.4rem 0.5rem; + color: var(--text); + cursor: pointer; + border-left: 2px solid transparent; +} +.feed-item:hover { background: rgba(0, 118, 206, 0.15); } +.feed-item.critical { border-left-color: var(--red); } +.feed-item.warning { border-left-color: var(--amber); } +.feed-item.info { border-left-color: var(--cyan); } +.feed-item .ft { + display: block; + font-size: 0.72rem; + font-weight: 600; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +.feed-item .fm { + display: block; + margin-top: 0.12rem; + font-family: var(--mono); + font-size: 0.62rem; + color: var(--muted); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +.feed-item .fs { + display: block; + margin-top: 0.1rem; + font-size: 0.58rem; + color: rgba(122, 147, 168, 0.9); + font-family: var(--mono); +} + +.ctx-stats { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 0.35rem; + margin-bottom: 0.55rem; +} +.ctx-stat { + appearance: none; + border: 1px solid rgba(0, 168, 232, 0.18); + background: rgba(0, 30, 55, 0.45); + border-radius: 6px; + padding: 0.4rem 0.45rem; + text-align: left; + color: inherit; +} +.ctx-stat:hover { border-color: var(--dell-bright); } +.ctx-stat .v { + display: block; + font-family: var(--mono); + font-size: 0.9rem; + font-weight: 600; + color: var(--cyan); +} +.ctx-stat.warn .v { color: var(--amber); } +.ctx-stat.danger .v { color: var(--red); } +.ctx-stat .l { + display: block; + font-size: 0.58rem; + text-transform: uppercase; + letter-spacing: 0.05em; + color: var(--muted); + margin-top: 0.1rem; +} +.alert-card .t { font-size: 0.78rem; } +.alert-card .s { white-space: normal; line-height: 1.3; } + + +/* Hover context tip */ +.node-tip { + position: fixed; + z-index: 50; + min-width: 200px; + max-width: 280px; + padding: 0.65rem 0.75rem; + border-radius: 10px; + background: rgba(4, 14, 28, 0.94); + border: 1px solid rgba(0, 168, 232, 0.35); + box-shadow: 0 12px 40px rgba(0, 0, 0, 0.45), 0 0 0 1px rgba(61, 255, 224, 0.08); + pointer-events: none; + backdrop-filter: blur(8px); + transform: translate(12px, 12px); +} +.node-tip .nt-name { + font-size: 0.82rem; + font-weight: 600; + margin: 0 0 0.2rem; + word-break: break-word; +} +.node-tip .nt-meta { + font-family: var(--mono); + font-size: 0.62rem; + color: var(--muted); + margin: 0; + line-height: 1.45; +} +.node-tip .nt-hint { + margin: 0.45rem 0 0; + font-size: 0.6rem; + color: var(--dell-bright); + letter-spacing: 0.04em; + text-transform: uppercase; +} + +/* Connect / context modal */ +.modal { + position: fixed; + inset: 0; + z-index: 60; + display: grid; + place-items: center; + padding: 1rem; +} +.modal.hidden { display: none !important; } +.modal-card { + position: relative; + width: min(520px, 100%); + background: + radial-gradient(ellipse 80% 60% at 10% 0%, rgba(0, 118, 206, 0.28), transparent 55%), + rgba(6, 14, 26, 0.97); + border: 1px solid rgba(0, 168, 232, 0.35); + border-radius: 16px; + padding: 1.15rem 1.2rem 1rem; + box-shadow: 0 24px 80px rgba(0, 0, 0, 0.55); + animation: modal-in 0.22s ease-out; +} +@keyframes modal-in { + from { opacity: 0; transform: translateY(12px) scale(0.98); } + to { opacity: 1; transform: none; } +} +.modal-close { + position: absolute; + top: 0.55rem; + right: 0.65rem; + appearance: none; + border: none; + background: transparent; + color: var(--muted); + font-size: 1.4rem; + line-height: 1; + padding: 0.2rem 0.45rem; + border-radius: 6px; +} +.modal-close:hover { color: #fff; background: rgba(255,255,255,0.06); } +.modal-brand { + display: flex; + gap: 0.75rem; + align-items: center; + margin-bottom: 0.75rem; + padding-right: 1.5rem; +} +.modal-brand img { + width: 40px; + height: 40px; + border-radius: 50%; +} +.modal-kicker { + margin: 0; + font-size: 0.62rem; + letter-spacing: 0.14em; + text-transform: uppercase; + color: var(--dell-bright); +} +.modal-brand h2 { + margin: 0.1rem 0 0; + font-size: 1.05rem; + word-break: break-word; +} +.modal-sub { + margin: 0.15rem 0 0; + font-family: var(--mono); + font-size: 0.7rem; + color: var(--muted); +} +.modal-badges { + display: flex; + flex-wrap: wrap; + gap: 0.3rem; + margin-bottom: 0.75rem; +} +.modal-context { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 0.4rem; + margin-bottom: 0.9rem; +} +.modal-ctx-item { + border: 1px solid rgba(0, 168, 232, 0.15); + background: rgba(0, 30, 55, 0.4); + border-radius: 8px; + padding: 0.45rem 0.55rem; +} +.modal-ctx-item .k { + display: block; + font-size: 0.58rem; + text-transform: uppercase; + letter-spacing: 0.06em; + color: var(--muted); +} +.modal-ctx-item .v { + display: block; + margin-top: 0.15rem; + font-family: var(--mono); + font-size: 0.75rem; + color: var(--text); + word-break: break-all; +} +.connect-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 0.5rem; +} +.connect-tile { + appearance: none; + text-align: left; + border: 1px solid rgba(0, 168, 232, 0.22); + background: rgba(0, 40, 70, 0.45); + border-radius: 12px; + padding: 0.75rem 0.8rem; + color: var(--text); + transition: border-color 0.15s, transform 0.15s, background 0.15s; + min-height: 88px; + display: flex; + flex-direction: column; + gap: 0.2rem; + text-decoration: none; + cursor: pointer; +} +.connect-tile:hover { + border-color: var(--cyan); + background: rgba(0, 118, 206, 0.22); + transform: translateY(-2px); +} +.connect-tile.primary { + border-color: rgba(0, 168, 232, 0.55); + background: linear-gradient(145deg, rgba(0, 118, 206, 0.45), rgba(0, 40, 70, 0.55)); +} +.connect-tile .ct-ico { + font-size: 1.1rem; + color: var(--cyan); + line-height: 1; +} +.connect-tile .ct-t { + font-size: 0.88rem; + font-weight: 600; +} +.connect-tile .ct-s { + font-family: var(--mono); + font-size: 0.62rem; + color: var(--muted); + line-height: 1.35; +} +.modal-foot { + margin: 0.75rem 0 0; + font-size: 0.62rem; + color: var(--muted); + line-height: 1.4; +} +.toast { + position: fixed; + bottom: 3.2rem; + left: 50%; + transform: translateX(-50%); + z-index: 70; + background: rgba(0, 40, 70, 0.95); + border: 1px solid var(--cyan); + color: var(--text); + padding: 0.55rem 0.9rem; + border-radius: 8px; + font-family: var(--mono); + font-size: 0.72rem; + pointer-events: none; + opacity: 0; + transition: opacity 0.2s; +} +.toast.show { opacity: 1; } + +/* SSH / iDRAC action text only — high-visibility orange */ +.conn-link, +a.conn-link, +.action-stack a.conn-link { + color: #ff9a3c !important; +} +.conn-link:hover, +a.conn-link:hover { + color: #ffc078 !important; + text-decoration: underline; +} +.connect-tile.conn-link .ct-t, +.connect-tile.conn-link .ct-s, +.connect-tile.conn-link .ct-ico { + color: #ff9a3c; +} +.connect-tile.conn-link:hover .ct-t, +.connect-tile.conn-link:hover .ct-ico { + color: #ffc078; +} + +/* Feed dock control */ +.ctx-feed-head { + cursor: grab; + gap: 0.5rem; +} +.ctx-feed-head .feed-dock { + margin-left: auto; + appearance: none; + border: 1px solid rgba(0,168,232,0.25); + background: rgba(0,40,70,0.5); + color: var(--text); + border-radius: 4px; + width: 24px; + height: 22px; + line-height: 1; + cursor: pointer; +} +.ctx-feed-head .feed-dock:hover { border-color: var(--cyan); color: var(--cyan); } + +/* V100 GPU matrix */ +.gpu-summary { + font-family: var(--mono); + font-size: 0.68rem; + color: var(--muted); + margin-bottom: 0.45rem; + line-height: 1.4; +} +.gpu-summary strong { color: var(--cyan); } +.gpu-matrix { display: flex; flex-direction: column; gap: 0.4rem; } +.gpu-card { + border: 1px solid rgba(0,168,232,0.18); + background: rgba(0,30,55,0.45); + border-radius: 8px; + padding: 0.45rem 0.5rem; +} +.gpu-card.busy { + border-color: rgba(255,154,60,0.55); + box-shadow: 0 0 0 1px rgba(255,154,60,0.15); +} +.gpu-top { + display: flex; + justify-content: space-between; + font-family: var(--mono); + font-size: 0.7rem; + color: var(--text); +} +.gpu-bar { + margin-top: 0.3rem; + height: 6px; + border-radius: 99px; + background: rgba(255,255,255,0.06); + overflow: hidden; +} +.gpu-bar i { + display: block; + height: 100%; + background: linear-gradient(90deg, #00a8e8, #3dffe0 55%, #ff9a3c); + border-radius: 99px; + transition: width 0.35s ease; +} +.gpu-card.busy .gpu-bar i { + background: linear-gradient(90deg, #ff9a3c, #ff5c5c); +} +.gpu-meta, .gpu-name { + margin-top: 0.25rem; + font-family: var(--mono); + font-size: 0.58rem; + color: var(--muted); +} + +/* Chat drawer */ +.chat-body { + flex: 1; + overflow-y: auto; + padding: 0.85rem; + display: flex; + flex-direction: column; + gap: 0.55rem; + background: rgba(2,8,16,0.85); +} +.chat-bubble { + max-width: 92%; + padding: 0.55rem 0.7rem; + border-radius: 10px; + font-size: 0.8rem; + line-height: 1.4; + white-space: pre-wrap; +} +.chat-bubble.user { + align-self: flex-end; + background: rgba(0,118,206,0.35); + border: 1px solid rgba(0,168,232,0.35); +} +.chat-bubble.assistant { + align-self: flex-start; + background: rgba(0,40,70,0.55); + border: 1px solid rgba(61,255,224,0.2); +} +.chat-form { + display: flex; + gap: 0.4rem; + padding: 0.65rem; + border-top: 1px solid var(--panel-border); +} +.chat-form input { + flex: 1; + border: 1px solid var(--panel-border); + background: rgba(0,20,40,0.7); + border-radius: 6px; + padding: 0.5rem 0.65rem; + outline: none; +} +.chat-form input:focus { border-color: var(--dell-bright); } + +/* Ops desk */ +.drawer.wide { width: min(780px, 100vw); } +.ops-layout { + flex: 1; + display: grid; + grid-template-columns: 240px 1fr; + min-height: 0; +} +.ops-side { + border-right: 1px solid var(--panel-border); + padding: 0.75rem; + overflow-y: auto; + display: flex; + flex-direction: column; + gap: 0.55rem; +} +.ops-identity { + display: flex; + flex-direction: column; + gap: 0.3rem; + font-size: 0.72rem; + color: var(--muted); +} +.ops-identity select { + border: 1px solid var(--panel-border); + background: rgba(0,20,40,0.7); + border-radius: 6px; + padding: 0.4rem; + color: var(--text); +} +.ops-main { + overflow-y: auto; + padding: 0.85rem; +} +.ops-empty h3 { margin: 0 0 0.35rem; color: var(--dell-bright); } +.ops-ticket-head h3 { margin: 0 0 0.25rem; font-size: 1rem; } +.ops-actions { display: flex; flex-wrap: wrap; gap: 0.3rem; margin: 0.5rem 0 0.75rem; } +.ops-msgs { display: flex; flex-direction: column; gap: 0.55rem; margin-bottom: 0.75rem; } +.ops-msg { + border: 1px solid rgba(0,168,232,0.15); + background: rgba(0,30,55,0.35); + border-radius: 8px; + padding: 0.55rem 0.65rem; +} +.ops-msg p { margin: 0.35rem 0 0; font-size: 0.8rem; line-height: 1.4; } +.ops-time { margin-left: 0.45rem; font-family: var(--mono); font-size: 0.62rem; color: var(--muted); } +.ops-reply textarea { + width: 100%; + border: 1px solid var(--panel-border); + background: rgba(0,20,40,0.7); + border-radius: 6px; + padding: 0.5rem; + color: var(--text); + resize: vertical; + margin-bottom: 0.4rem; +} +.drawer { + display: flex; + flex-direction: column; +} + +.feed-docks { margin-left: auto; display: inline-flex; gap: 0.25rem; } +.ctx-feed-head .feed-dock { margin-left: 0; } + +/* Collapsible live feed */ +.ctx-feed.collapsed { + max-height: none; + height: auto; + bottom: 0.55rem !important; + width: auto; + min-width: 0; + right: 0.75rem; + overflow: hidden; + /* backdrop-filter ghosts collapsed body text in Chromium */ + backdrop-filter: none; + -webkit-backdrop-filter: none; + background: rgba(2, 14, 28, 0.92); +} +.ctx-feed.collapsed .ctx-feed-body { + display: none !important; + visibility: hidden !important; + height: 0 !important; + max-height: 0 !important; + overflow: hidden !important; + padding: 0 !important; + margin: 0 !important; + opacity: 0 !important; + pointer-events: none !important; + position: absolute !important; + left: -9999px !important; + width: 0 !important; +} +.ctx-feed.collapsed .ctx-feed-head { + border-bottom: none; + padding: 0.4rem 0.55rem; + cursor: pointer; +} +.ctx-feed.collapsed .ctx-feed-head strong { + letter-spacing: 0.06em; +} +.ctx-feed.collapsed #ctx-feed-meta { + display: none !important; +} +.feed-dock.hidden { display: none !important; } + +/* Keep legend/hint clear of collapsed feed chip */ +.stage.feed-collapsed .stage-hud { + right: 12rem; +} + +/* Alert triage popup */ +.triage-card { + width: min(920px, 96vw); + max-height: min(86vh, 820px); + display: flex; + flex-direction: column; + padding-bottom: 0.85rem; +} +.triage-toolbar { + display: flex; + flex-direction: column; + gap: 0.45rem; + margin-bottom: 0.65rem; +} +.triage-layout { + display: grid; + grid-template-columns: 1.1fr 1fr; + gap: 0.65rem; + min-height: 0; + flex: 1; + overflow: hidden; +} +.triage-list { + overflow-y: auto; + max-height: min(54vh, 480px); + display: flex; + flex-direction: column; + gap: 0.35rem; + padding-right: 0.15rem; +} +.triage-detail { + overflow-y: auto; + max-height: min(54vh, 480px); + border: 1px solid rgba(0,168,232,0.2); + border-radius: 10px; + background: rgba(0, 24, 44, 0.55); + padding: 0.75rem; +} +.triage-item { + appearance: none; + text-align: left; + width: 100%; + border: 1px solid rgba(0,168,232,0.16); + background: rgba(0,30,55,0.45); + border-radius: 8px; + padding: 0.55rem 0.65rem; + color: var(--text); + border-left: 3px solid transparent; + cursor: pointer; +} +.triage-item:hover { border-color: var(--dell-bright); } +.triage-item.active { border-color: var(--cyan); background: rgba(61,255,224,0.08); } +.triage-item.critical { border-left-color: var(--red); } +.triage-item.warning { border-left-color: var(--amber); } +.triage-item.info { border-left-color: var(--cyan); } +.triage-item .ti-top { + display: flex; + justify-content: space-between; + gap: 0.4rem; + font-size: 0.78rem; + font-weight: 600; +} +.triage-item .ti-msg { + margin-top: 0.2rem; + font-size: 0.68rem; + color: var(--muted); + line-height: 1.35; +} +.triage-item .ti-meta { + margin-top: 0.25rem; + font-family: var(--mono); + font-size: 0.58rem; + color: rgba(122,147,168,0.95); +} +.triage-detail h3 { + margin: 0 0 0.35rem; + font-size: 0.95rem; + word-break: break-word; +} +.triage-actions { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 0.4rem; + margin-top: 0.75rem; +} +.triage-actions .btn { width: 100%; text-align: center; font-size: 0.75rem; } +.triage-group-label { + font-size: 0.62rem; + letter-spacing: 0.08em; + text-transform: uppercase; + color: var(--dell-bright); + margin: 0.35rem 0 0.2rem; + font-weight: 600; +} +@media (max-width: 800px) { + .triage-layout { grid-template-columns: 1fr; } +} + +/* Chat context integration */ +.chat-context { + display: flex; + flex-wrap: wrap; + gap: 0.35rem; + padding: 0.55rem 0.75rem 0.2rem; + border-bottom: 1px solid rgba(0,168,232,0.12); +} +.chat-ctx-pill { + font-family: var(--mono); + font-size: 0.62rem; + color: var(--cyan); + border: 1px solid rgba(0,168,232,0.28); + background: rgba(0,40,70,0.45); + border-radius: 999px; + padding: 0.2rem 0.55rem; +} +.chat-model-wrap { + display: inline-flex; + align-items: center; + gap: 0.35rem; + font-size: 0.62rem; + color: var(--muted); +} +.chat-model-label { + text-transform: uppercase; + letter-spacing: 0.06em; +} +.chat-model-select { + appearance: none; + border: 1px solid rgba(0,168,232,0.35); + background: rgba(0,40,70,0.65); + color: var(--cyan); + border-radius: 999px; + padding: 0.22rem 1.6rem 0.22rem 0.65rem; + font-family: var(--mono); + font-size: 0.68rem; + cursor: pointer; + background-image: linear-gradient(45deg, transparent 50%, var(--cyan) 50%), + linear-gradient(135deg, var(--cyan) 50%, transparent 50%); + background-position: calc(100% - 14px) 55%, calc(100% - 9px) 55%; + background-size: 5px 5px, 5px 5px; + background-repeat: no-repeat; + max-width: 220px; +} +.chat-model-select:hover, +.chat-model-select:focus { + border-color: var(--cyan); + outline: none; + color: #fff; +} +.chat-quick { + display: flex; + flex-wrap: wrap; + gap: 0.3rem; + padding: 0.45rem 0.75rem; +} +.chat-quick button { + appearance: none; + border: 1px solid rgba(0,168,232,0.22); + background: rgba(0,30,55,0.5); + color: var(--muted); + border-radius: 999px; + padding: 0.25rem 0.6rem; + font-size: 0.68rem; + cursor: pointer; +} +.chat-quick button:hover { color: #fff; border-color: var(--cyan); } + +/* Ticket create modal */ +.ticket-card { width: min(560px, 96vw); } +.ticket-form { display: flex; flex-direction: column; gap: 0.7rem; } +.ticket-form label { + display: flex; + flex-direction: column; + gap: 0.3rem; + font-size: 0.72rem; + color: var(--muted); + letter-spacing: 0.04em; + text-transform: uppercase; +} +.ticket-form input, +.ticket-form select, +.ticket-form textarea { + border: 1px solid rgba(0,168,232,0.25); + background: rgba(0, 18, 36, 0.85); + border-radius: 8px; + padding: 0.55rem 0.65rem; + color: var(--text); + font: inherit; + text-transform: none; + letter-spacing: 0; + font-size: 0.85rem; +} +.ticket-form textarea { resize: vertical; line-height: 1.4; } +.ticket-form input:focus, +.ticket-form select:focus, +.ticket-form textarea:focus { + outline: none; + border-color: var(--cyan); + box-shadow: 0 0 0 2px rgba(61,255,224,0.12); +} +.ticket-form-row { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 0.55rem; +} +.ticket-form-actions { + display: flex; + justify-content: flex-end; + gap: 0.45rem; + margin-top: 0.25rem; +} + +/* Richer ops desk */ +.ops-filters select { + width: 100%; + border: 1px solid var(--panel-border); + background: rgba(0,20,40,0.7); + border-radius: 6px; + padding: 0.4rem; + color: var(--text); + font-size: 0.75rem; +} +.ops-ticket-head { + border: 1px solid rgba(0,168,232,0.18); + background: rgba(0,30,55,0.4); + border-radius: 10px; + padding: 0.75rem; + margin-bottom: 0.75rem; +} +.ops-meta-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 0.4rem; + margin: 0.55rem 0; +} +.ops-meta-grid div { + border: 1px solid rgba(0,168,232,0.12); + border-radius: 6px; + padding: 0.35rem 0.45rem; + font-size: 0.72rem; +} +.ops-meta-grid span { display:block; color: var(--muted); font-size: 0.58rem; text-transform: uppercase; letter-spacing: 0.05em; } +.ops-toolbar { + display: flex; + flex-wrap: wrap; + gap: 0.35rem; + margin-top: 0.55rem; +} +.ops-toolbar .btn { font-size: 0.72rem; padding: 0.35rem 0.55rem; } +.ops-toolbar select { + border: 1px solid var(--panel-border); + background: rgba(0,20,40,0.7); + border-radius: 6px; + color: var(--text); + padding: 0.3rem 0.4rem; + font-size: 0.72rem; +} +.card .s .st-open { color: var(--amber); } +.card .s .st-accepted, .card .s .st-in_progress { color: var(--cyan); } +.card .s .st-resolved, .card .s .st-closed { color: var(--muted); } +.btn.danger { + border-color: rgba(255,92,92,0.45); + color: #ff8f8f; +} +.btn.danger:hover { background: rgba(255,92,92,0.15); color: #fff; } + + +.filter-actions { + display: flex; + justify-content: flex-end; + margin: 0.35rem 0 0.45rem; +} +.btn.compact { + padding: 0.25rem 0.55rem; + font-size: 0.68rem; +} + + +#notify-stack { + position: fixed; + top: 4.6rem; + right: 1rem; + z-index: 80; + display: flex; + flex-direction: column; + gap: 0.45rem; + width: min(360px, calc(100vw - 2rem)); + pointer-events: none; +} +.notify-card { + pointer-events: auto; + appearance: none; + text-align: left; + border: 1px solid rgba(0,168,232,0.35); + background: rgba(4, 18, 34, 0.94); + color: var(--text); + border-radius: 10px; + padding: 0.65rem 0.75rem; + box-shadow: 0 10px 28px rgba(0,0,0,0.35); + opacity: 0; + transform: translateX(18px); + transition: opacity 0.25s ease, transform 0.25s ease; + cursor: pointer; +} +.notify-card.show { + opacity: 1; + transform: translateX(0); +} +.notify-card.critical { border-color: rgba(61,255,224,0.55); } +.notify-card.warning { border-color: rgba(255,176,32,0.55); } +.notify-card .nc-kicker { + display: block; + font-size: 0.62rem; + letter-spacing: 0.08em; + text-transform: uppercase; + color: var(--cyan); + margin-bottom: 0.2rem; +} +.notify-card .nc-title { + display: block; + font-size: 0.86rem; + margin-bottom: 0.2rem; +} +.notify-card .nc-text { + display: block; + font-family: var(--mono); + font-size: 0.68rem; + color: var(--muted); + line-height: 1.35; +} +.notify-card .nc-meta { + display: block; + margin-top: 0.3rem; + font-size: 0.6rem; + color: rgba(122,147,168,0.85); + font-family: var(--mono); +} +.toast.toast-alert { + border-color: rgba(61,255,224,0.55); + background: rgba(0, 60, 90, 0.95); + color: #fff; + font-weight: 600; +} +.inv-section h3 { + color: var(--dell-bright); +} + + +.ssh-card { + width: min(920px, 96vw); + max-height: min(90vh, 860px); + display: flex; + flex-direction: column; +} +.ssh-status { + margin: 0.35rem 0 0.75rem; + font-family: var(--mono); + font-size: 0.72rem; + color: var(--muted); +} +.ssh-status.ok { color: var(--cyan); } +.ssh-status.error { color: #ff7a7a; } +.ssh-status.info { color: var(--dell-bright); } +.ssh-login { margin-bottom: 0.5rem; } +.ssh-grid { + display: grid; + grid-template-columns: 1.4fr 0.6fr; + gap: 0.55rem 0.65rem; + margin-bottom: 0.7rem; +} +.ssh-grid label { + display: flex; + flex-direction: column; + gap: 0.25rem; + font-size: 0.68rem; + letter-spacing: 0.04em; + text-transform: uppercase; + color: var(--muted); +} +.ssh-grid label:nth-child(3), +.ssh-grid label:nth-child(4) { + grid-column: 1 / -1; +} +.ssh-grid input { + appearance: none; + border: 1px solid var(--panel-border); + background: rgba(0, 20, 40, 0.7); + border-radius: 6px; + padding: 0.5rem 0.6rem; + color: var(--text); + font-family: var(--mono); + font-size: 0.84rem; + text-transform: none; + letter-spacing: 0; +} +.ssh-grid input:focus { + outline: none; + border-color: var(--cyan); +} +.ssh-actions { + display: flex; + gap: 0.45rem; + flex-wrap: wrap; +} +.ssh-term-wrap { + flex: 1; + min-height: 360px; + border: 1px solid rgba(0,168,232,0.22); + border-radius: 8px; + overflow: hidden; + background: #071018; +} +.ssh-term { + height: min(52vh, 520px); + padding: 0.35rem; +} +.ssh-term .xterm { height: 100%; } +.ssh-term .xterm-viewport { overflow-y: auto !important; } +@media (max-width: 700px) { + .ssh-grid { grid-template-columns: 1fr; } + .ssh-grid label:nth-child(3), + .ssh-grid label:nth-child(4) { grid-column: auto; } +} + + +.kpi-card { + width: min(1100px, 96vw); + max-height: min(88vh, 860px); + display: flex; + flex-direction: column; +} +.kpi-summary { + display: flex; + flex-wrap: wrap; + gap: 0.4rem; + margin: 0.25rem 0 0.7rem; +} +.kpi-summary .pill { + font-family: var(--mono); + font-size: 0.68rem; + color: var(--cyan); + border: 1px solid rgba(0,168,232,0.28); + background: rgba(0,40,70,0.45); + border-radius: 999px; + padding: 0.22rem 0.6rem; +} +.kpi-toolbar { + display: grid; + grid-template-columns: 1fr auto auto auto; + gap: 0.4rem; + margin-bottom: 0.65rem; + align-items: center; +} +.kpi-toolbar select { + appearance: none; + border: 1px solid var(--panel-border); + background: rgba(0,20,40,0.7); + color: var(--text); + border-radius: 6px; + padding: 0.45rem 0.55rem; + font-family: var(--mono); + font-size: 0.72rem; +} +.kpi-layout { + display: grid; + grid-template-columns: 1.15fr 1fr; + gap: 0.65rem; + min-height: 0; + flex: 1; + overflow: hidden; +} +.kpi-list, .kpi-detail { + border: 1px solid rgba(0,168,232,0.15); + background: rgba(0,20,40,0.35); + border-radius: 8px; + overflow: auto; + max-height: min(56vh, 520px); +} +.kpi-list { padding: 0.35rem; } +.kpi-detail { padding: 0.75rem; } +.kpi-item { + appearance: none; + width: 100%; + text-align: left; + border: 1px solid transparent; + background: transparent; + color: inherit; + border-radius: 8px; + padding: 0.5rem 0.55rem; + cursor: pointer; + margin-bottom: 0.25rem; +} +.kpi-item:hover { background: rgba(0,118,206,0.15); } +.kpi-item.active { + border-color: rgba(61,255,224,0.35); + background: rgba(61,255,224,0.08); +} +.kpi-item .t { + display: block; + font-weight: 600; + font-size: 0.82rem; +} +.kpi-item .s { + display: block; + margin-top: 0.15rem; + font-family: var(--mono); + font-size: 0.66rem; + color: var(--muted); +} +.kpi-detail h3 { margin: 0 0 0.35rem; color: var(--dell-bright); font-size: 1rem; } +.kpi-detail .meta { margin: 0 0 0.65rem; color: var(--muted); font-family: var(--mono); font-size: 0.72rem; } +.kpi-actions { display: flex; flex-wrap: wrap; gap: 0.35rem; margin: 0.65rem 0; } +.kpi-kv { display: grid; gap: 0.3rem; margin-top: 0.5rem; } +.kpi-kv .row { + display: grid; + grid-template-columns: 110px 1fr; + gap: 0.4rem; + font-size: 0.78rem; +} +.kpi-kv .k { color: var(--muted); } +.kpi-kv .v { font-family: var(--mono); color: var(--text); word-break: break-all; } +@media (max-width: 900px) { + .kpi-layout { grid-template-columns: 1fr; } + .kpi-toolbar { grid-template-columns: 1fr 1fr; } +} diff --git a/ui/vendor/xterm/xterm-addon-fit.min.js b/ui/vendor/xterm/xterm-addon-fit.min.js new file mode 100644 index 0000000..7384f10 --- /dev/null +++ b/ui/vendor/xterm/xterm-addon-fit.min.js @@ -0,0 +1,8 @@ +/** + * Skipped minification because the original files appears to be already minified. + * Original file: /npm/xterm-addon-fit@0.8.0/lib/xterm-addon-fit.js + * + * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files + */ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.FitAddon=t():e.FitAddon=t()}(self,(()=>(()=>{"use strict";var e={};return(()=>{var t=e;Object.defineProperty(t,"__esModule",{value:!0}),t.FitAddon=void 0,t.FitAddon=class{activate(e){this._terminal=e}dispose(){}fit(){const e=this.proposeDimensions();if(!e||!this._terminal||isNaN(e.cols)||isNaN(e.rows))return;const t=this._terminal._core;this._terminal.rows===e.rows&&this._terminal.cols===e.cols||(t._renderService.clear(),this._terminal.resize(e.cols,e.rows))}proposeDimensions(){if(!this._terminal)return;if(!this._terminal.element||!this._terminal.element.parentElement)return;const e=this._terminal._core,t=e._renderService.dimensions;if(0===t.css.cell.width||0===t.css.cell.height)return;const r=0===this._terminal.options.scrollback?0:e.viewport.scrollBarWidth,i=window.getComputedStyle(this._terminal.element.parentElement),o=parseInt(i.getPropertyValue("height")),s=Math.max(0,parseInt(i.getPropertyValue("width"))),n=window.getComputedStyle(this._terminal.element),l=o-(parseInt(n.getPropertyValue("padding-top"))+parseInt(n.getPropertyValue("padding-bottom"))),a=s-(parseInt(n.getPropertyValue("padding-right"))+parseInt(n.getPropertyValue("padding-left")))-r;return{cols:Math.max(2,Math.floor(a/t.css.cell.width)),rows:Math.max(1,Math.floor(l/t.css.cell.height))}}}})(),e})())); +//# sourceMappingURL=xterm-addon-fit.js.map \ No newline at end of file diff --git a/ui/vendor/xterm/xterm.css b/ui/vendor/xterm/xterm.css new file mode 100644 index 0000000..74acc26 --- /dev/null +++ b/ui/vendor/xterm/xterm.css @@ -0,0 +1,209 @@ +/** + * Copyright (c) 2014 The xterm.js authors. All rights reserved. + * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License) + * https://github.com/chjj/term.js + * @license MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Originally forked from (with the author's permission): + * Fabrice Bellard's javascript vt100 for jslinux: + * http://bellard.org/jslinux/ + * Copyright (c) 2011 Fabrice Bellard + * The original design remains. The terminal itself + * has been extended to include xterm CSI codes, among + * other features. + */ + +/** + * Default styles for xterm.js + */ + +.xterm { + cursor: text; + position: relative; + user-select: none; + -ms-user-select: none; + -webkit-user-select: none; +} + +.xterm.focus, +.xterm:focus { + outline: none; +} + +.xterm .xterm-helpers { + position: absolute; + top: 0; + /** + * The z-index of the helpers must be higher than the canvases in order for + * IMEs to appear on top. + */ + z-index: 5; +} + +.xterm .xterm-helper-textarea { + padding: 0; + border: 0; + margin: 0; + /* Move textarea out of the screen to the far left, so that the cursor is not visible */ + position: absolute; + opacity: 0; + left: -9999em; + top: 0; + width: 0; + height: 0; + z-index: -5; + /** Prevent wrapping so the IME appears against the textarea at the correct position */ + white-space: nowrap; + overflow: hidden; + resize: none; +} + +.xterm .composition-view { + /* TODO: Composition position got messed up somewhere */ + background: #000; + color: #FFF; + display: none; + position: absolute; + white-space: nowrap; + z-index: 1; +} + +.xterm .composition-view.active { + display: block; +} + +.xterm .xterm-viewport { + /* On OS X this is required in order for the scroll bar to appear fully opaque */ + background-color: #000; + overflow-y: scroll; + cursor: default; + position: absolute; + right: 0; + left: 0; + top: 0; + bottom: 0; +} + +.xterm .xterm-screen { + position: relative; +} + +.xterm .xterm-screen canvas { + position: absolute; + left: 0; + top: 0; +} + +.xterm .xterm-scroll-area { + visibility: hidden; +} + +.xterm-char-measure-element { + display: inline-block; + visibility: hidden; + position: absolute; + top: 0; + left: -9999em; + line-height: normal; +} + +.xterm.enable-mouse-events { + /* When mouse events are enabled (eg. tmux), revert to the standard pointer cursor */ + cursor: default; +} + +.xterm.xterm-cursor-pointer, +.xterm .xterm-cursor-pointer { + cursor: pointer; +} + +.xterm.column-select.focus { + /* Column selection mode */ + cursor: crosshair; +} + +.xterm .xterm-accessibility, +.xterm .xterm-message { + position: absolute; + left: 0; + top: 0; + bottom: 0; + right: 0; + z-index: 10; + color: transparent; + pointer-events: none; +} + +.xterm .live-region { + position: absolute; + left: -9999px; + width: 1px; + height: 1px; + overflow: hidden; +} + +.xterm-dim { + /* Dim should not apply to background, so the opacity of the foreground color is applied + * explicitly in the generated class and reset to 1 here */ + opacity: 1 !important; +} + +.xterm-underline-1 { text-decoration: underline; } +.xterm-underline-2 { text-decoration: double underline; } +.xterm-underline-3 { text-decoration: wavy underline; } +.xterm-underline-4 { text-decoration: dotted underline; } +.xterm-underline-5 { text-decoration: dashed underline; } + +.xterm-overline { + text-decoration: overline; +} + +.xterm-overline.xterm-underline-1 { text-decoration: overline underline; } +.xterm-overline.xterm-underline-2 { text-decoration: overline double underline; } +.xterm-overline.xterm-underline-3 { text-decoration: overline wavy underline; } +.xterm-overline.xterm-underline-4 { text-decoration: overline dotted underline; } +.xterm-overline.xterm-underline-5 { text-decoration: overline dashed underline; } + +.xterm-strikethrough { + text-decoration: line-through; +} + +.xterm-screen .xterm-decoration-container .xterm-decoration { + z-index: 6; + position: absolute; +} + +.xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer { + z-index: 7; +} + +.xterm-decoration-overview-ruler { + z-index: 8; + position: absolute; + top: 0; + right: 0; + pointer-events: none; +} + +.xterm-decoration-top { + z-index: 2; + position: relative; +} diff --git a/ui/vendor/xterm/xterm.min.js b/ui/vendor/xterm/xterm.min.js new file mode 100644 index 0000000..d7bd63f --- /dev/null +++ b/ui/vendor/xterm/xterm.min.js @@ -0,0 +1,8 @@ +/** + * Skipped minification because the original files appears to be already minified. + * Original file: /npm/xterm@5.3.0/lib/xterm.js + * + * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files + */ +!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var i=t();for(var s in i)("object"==typeof exports?exports:e)[s]=i[s]}}(self,(()=>(()=>{"use strict";var e={4567:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.AccessibilityManager=void 0;const n=i(9042),o=i(6114),a=i(9924),h=i(844),c=i(5596),l=i(4725),d=i(3656);let _=t.AccessibilityManager=class extends h.Disposable{constructor(e,t){super(),this._terminal=e,this._renderService=t,this._liveRegionLineCount=0,this._charsToConsume=[],this._charsToAnnounce="",this._accessibilityContainer=document.createElement("div"),this._accessibilityContainer.classList.add("xterm-accessibility"),this._rowContainer=document.createElement("div"),this._rowContainer.setAttribute("role","list"),this._rowContainer.classList.add("xterm-accessibility-tree"),this._rowElements=[];for(let e=0;ethis._handleBoundaryFocus(e,0),this._bottomBoundaryFocusListener=e=>this._handleBoundaryFocus(e,1),this._rowElements[0].addEventListener("focus",this._topBoundaryFocusListener),this._rowElements[this._rowElements.length-1].addEventListener("focus",this._bottomBoundaryFocusListener),this._refreshRowsDimensions(),this._accessibilityContainer.appendChild(this._rowContainer),this._liveRegion=document.createElement("div"),this._liveRegion.classList.add("live-region"),this._liveRegion.setAttribute("aria-live","assertive"),this._accessibilityContainer.appendChild(this._liveRegion),this._liveRegionDebouncer=this.register(new a.TimeBasedDebouncer(this._renderRows.bind(this))),!this._terminal.element)throw new Error("Cannot enable accessibility before Terminal.open");this._terminal.element.insertAdjacentElement("afterbegin",this._accessibilityContainer),this.register(this._terminal.onResize((e=>this._handleResize(e.rows)))),this.register(this._terminal.onRender((e=>this._refreshRows(e.start,e.end)))),this.register(this._terminal.onScroll((()=>this._refreshRows()))),this.register(this._terminal.onA11yChar((e=>this._handleChar(e)))),this.register(this._terminal.onLineFeed((()=>this._handleChar("\n")))),this.register(this._terminal.onA11yTab((e=>this._handleTab(e)))),this.register(this._terminal.onKey((e=>this._handleKey(e.key)))),this.register(this._terminal.onBlur((()=>this._clearLiveRegion()))),this.register(this._renderService.onDimensionsChange((()=>this._refreshRowsDimensions()))),this._screenDprMonitor=new c.ScreenDprMonitor(window),this.register(this._screenDprMonitor),this._screenDprMonitor.setListener((()=>this._refreshRowsDimensions())),this.register((0,d.addDisposableDomListener)(window,"resize",(()=>this._refreshRowsDimensions()))),this._refreshRows(),this.register((0,h.toDisposable)((()=>{this._accessibilityContainer.remove(),this._rowElements.length=0})))}_handleTab(e){for(let t=0;t0?this._charsToConsume.shift()!==e&&(this._charsToAnnounce+=e):this._charsToAnnounce+=e,"\n"===e&&(this._liveRegionLineCount++,21===this._liveRegionLineCount&&(this._liveRegion.textContent+=n.tooMuchOutput)),o.isMac&&this._liveRegion.textContent&&this._liveRegion.textContent.length>0&&!this._liveRegion.parentNode&&setTimeout((()=>{this._accessibilityContainer.appendChild(this._liveRegion)}),0))}_clearLiveRegion(){this._liveRegion.textContent="",this._liveRegionLineCount=0,o.isMac&&this._liveRegion.remove()}_handleKey(e){this._clearLiveRegion(),/\p{Control}/u.test(e)||this._charsToConsume.push(e)}_refreshRows(e,t){this._liveRegionDebouncer.refresh(e,t,this._terminal.rows)}_renderRows(e,t){const i=this._terminal.buffer,s=i.lines.length.toString();for(let r=e;r<=t;r++){const e=i.translateBufferLineToString(i.ydisp+r,!0),t=(i.ydisp+r+1).toString(),n=this._rowElements[r];n&&(0===e.length?n.innerText=" ":n.textContent=e,n.setAttribute("aria-posinset",t),n.setAttribute("aria-setsize",s))}this._announceCharacters()}_announceCharacters(){0!==this._charsToAnnounce.length&&(this._liveRegion.textContent+=this._charsToAnnounce,this._charsToAnnounce="")}_handleBoundaryFocus(e,t){const i=e.target,s=this._rowElements[0===t?1:this._rowElements.length-2];if(i.getAttribute("aria-posinset")===(0===t?"1":`${this._terminal.buffer.lines.length}`))return;if(e.relatedTarget!==s)return;let r,n;if(0===t?(r=i,n=this._rowElements.pop(),this._rowContainer.removeChild(n)):(r=this._rowElements.shift(),n=i,this._rowContainer.removeChild(r)),r.removeEventListener("focus",this._topBoundaryFocusListener),n.removeEventListener("focus",this._bottomBoundaryFocusListener),0===t){const e=this._createAccessibilityTreeNode();this._rowElements.unshift(e),this._rowContainer.insertAdjacentElement("afterbegin",e)}else{const e=this._createAccessibilityTreeNode();this._rowElements.push(e),this._rowContainer.appendChild(e)}this._rowElements[0].addEventListener("focus",this._topBoundaryFocusListener),this._rowElements[this._rowElements.length-1].addEventListener("focus",this._bottomBoundaryFocusListener),this._terminal.scrollLines(0===t?-1:1),this._rowElements[0===t?1:this._rowElements.length-2].focus(),e.preventDefault(),e.stopImmediatePropagation()}_handleResize(e){this._rowElements[this._rowElements.length-1].removeEventListener("focus",this._bottomBoundaryFocusListener);for(let e=this._rowContainer.children.length;ee;)this._rowContainer.removeChild(this._rowElements.pop());this._rowElements[this._rowElements.length-1].addEventListener("focus",this._bottomBoundaryFocusListener),this._refreshRowsDimensions()}_createAccessibilityTreeNode(){const e=document.createElement("div");return e.setAttribute("role","listitem"),e.tabIndex=-1,this._refreshRowDimensions(e),e}_refreshRowsDimensions(){if(this._renderService.dimensions.css.cell.height){this._accessibilityContainer.style.width=`${this._renderService.dimensions.css.canvas.width}px`,this._rowElements.length!==this._terminal.rows&&this._handleResize(this._terminal.rows);for(let e=0;e{function i(e){return e.replace(/\r?\n/g,"\r")}function s(e,t){return t?"[200~"+e+"[201~":e}function r(e,t,r,n){e=s(e=i(e),r.decPrivateModes.bracketedPasteMode&&!0!==n.rawOptions.ignoreBracketedPasteMode),r.triggerDataEvent(e,!0),t.value=""}function n(e,t,i){const s=i.getBoundingClientRect(),r=e.clientX-s.left-10,n=e.clientY-s.top-10;t.style.width="20px",t.style.height="20px",t.style.left=`${r}px`,t.style.top=`${n}px`,t.style.zIndex="1000",t.focus()}Object.defineProperty(t,"__esModule",{value:!0}),t.rightClickHandler=t.moveTextAreaUnderMouseCursor=t.paste=t.handlePasteEvent=t.copyHandler=t.bracketTextForPaste=t.prepareTextForTerminal=void 0,t.prepareTextForTerminal=i,t.bracketTextForPaste=s,t.copyHandler=function(e,t){e.clipboardData&&e.clipboardData.setData("text/plain",t.selectionText),e.preventDefault()},t.handlePasteEvent=function(e,t,i,s){e.stopPropagation(),e.clipboardData&&r(e.clipboardData.getData("text/plain"),t,i,s)},t.paste=r,t.moveTextAreaUnderMouseCursor=n,t.rightClickHandler=function(e,t,i,s,r){n(e,t,i),r&&s.rightClickSelect(e),t.value=s.selectionText,t.select()}},7239:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.ColorContrastCache=void 0;const s=i(1505);t.ColorContrastCache=class{constructor(){this._color=new s.TwoKeyMap,this._css=new s.TwoKeyMap}setCss(e,t,i){this._css.set(e,t,i)}getCss(e,t){return this._css.get(e,t)}setColor(e,t,i){this._color.set(e,t,i)}getColor(e,t){return this._color.get(e,t)}clear(){this._color.clear(),this._css.clear()}}},3656:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.addDisposableDomListener=void 0,t.addDisposableDomListener=function(e,t,i,s){e.addEventListener(t,i,s);let r=!1;return{dispose:()=>{r||(r=!0,e.removeEventListener(t,i,s))}}}},6465:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.Linkifier2=void 0;const n=i(3656),o=i(8460),a=i(844),h=i(2585);let c=t.Linkifier2=class extends a.Disposable{get currentLink(){return this._currentLink}constructor(e){super(),this._bufferService=e,this._linkProviders=[],this._linkCacheDisposables=[],this._isMouseOut=!0,this._wasResized=!1,this._activeLine=-1,this._onShowLinkUnderline=this.register(new o.EventEmitter),this.onShowLinkUnderline=this._onShowLinkUnderline.event,this._onHideLinkUnderline=this.register(new o.EventEmitter),this.onHideLinkUnderline=this._onHideLinkUnderline.event,this.register((0,a.getDisposeArrayDisposable)(this._linkCacheDisposables)),this.register((0,a.toDisposable)((()=>{this._lastMouseEvent=void 0}))),this.register(this._bufferService.onResize((()=>{this._clearCurrentLink(),this._wasResized=!0})))}registerLinkProvider(e){return this._linkProviders.push(e),{dispose:()=>{const t=this._linkProviders.indexOf(e);-1!==t&&this._linkProviders.splice(t,1)}}}attachToDom(e,t,i){this._element=e,this._mouseService=t,this._renderService=i,this.register((0,n.addDisposableDomListener)(this._element,"mouseleave",(()=>{this._isMouseOut=!0,this._clearCurrentLink()}))),this.register((0,n.addDisposableDomListener)(this._element,"mousemove",this._handleMouseMove.bind(this))),this.register((0,n.addDisposableDomListener)(this._element,"mousedown",this._handleMouseDown.bind(this))),this.register((0,n.addDisposableDomListener)(this._element,"mouseup",this._handleMouseUp.bind(this)))}_handleMouseMove(e){if(this._lastMouseEvent=e,!this._element||!this._mouseService)return;const t=this._positionFromMouseEvent(e,this._element,this._mouseService);if(!t)return;this._isMouseOut=!1;const i=e.composedPath();for(let e=0;e{null==e||e.forEach((e=>{e.link.dispose&&e.link.dispose()}))})),this._activeProviderReplies=new Map,this._activeLine=e.y);let r=!1;for(const[i,n]of this._linkProviders.entries())t?(null===(s=this._activeProviderReplies)||void 0===s?void 0:s.get(i))&&(r=this._checkLinkProviderResult(i,e,r)):n.provideLinks(e.y,(t=>{var s,n;if(this._isMouseOut)return;const o=null==t?void 0:t.map((e=>({link:e})));null===(s=this._activeProviderReplies)||void 0===s||s.set(i,o),r=this._checkLinkProviderResult(i,e,r),(null===(n=this._activeProviderReplies)||void 0===n?void 0:n.size)===this._linkProviders.length&&this._removeIntersectingLinks(e.y,this._activeProviderReplies)}))}_removeIntersectingLinks(e,t){const i=new Set;for(let s=0;se?this._bufferService.cols:s.link.range.end.x;for(let e=n;e<=o;e++){if(i.has(e)){r.splice(t--,1);break}i.add(e)}}}}_checkLinkProviderResult(e,t,i){var s;if(!this._activeProviderReplies)return i;const r=this._activeProviderReplies.get(e);let n=!1;for(let t=0;tthis._linkAtPosition(e.link,t)));e&&(i=!0,this._handleNewLink(e))}if(this._activeProviderReplies.size===this._linkProviders.length&&!i)for(let e=0;ethis._linkAtPosition(e.link,t)));if(r){i=!0,this._handleNewLink(r);break}}return i}_handleMouseDown(){this._mouseDownLink=this._currentLink}_handleMouseUp(e){if(!this._element||!this._mouseService||!this._currentLink)return;const t=this._positionFromMouseEvent(e,this._element,this._mouseService);t&&this._mouseDownLink===this._currentLink&&this._linkAtPosition(this._currentLink.link,t)&&this._currentLink.link.activate(e,this._currentLink.link.text)}_clearCurrentLink(e,t){this._element&&this._currentLink&&this._lastMouseEvent&&(!e||!t||this._currentLink.link.range.start.y>=e&&this._currentLink.link.range.end.y<=t)&&(this._linkLeave(this._element,this._currentLink.link,this._lastMouseEvent),this._currentLink=void 0,(0,a.disposeArray)(this._linkCacheDisposables))}_handleNewLink(e){if(!this._element||!this._lastMouseEvent||!this._mouseService)return;const t=this._positionFromMouseEvent(this._lastMouseEvent,this._element,this._mouseService);t&&this._linkAtPosition(e.link,t)&&(this._currentLink=e,this._currentLink.state={decorations:{underline:void 0===e.link.decorations||e.link.decorations.underline,pointerCursor:void 0===e.link.decorations||e.link.decorations.pointerCursor},isHovered:!0},this._linkHover(this._element,e.link,this._lastMouseEvent),e.link.decorations={},Object.defineProperties(e.link.decorations,{pointerCursor:{get:()=>{var e,t;return null===(t=null===(e=this._currentLink)||void 0===e?void 0:e.state)||void 0===t?void 0:t.decorations.pointerCursor},set:e=>{var t,i;(null===(t=this._currentLink)||void 0===t?void 0:t.state)&&this._currentLink.state.decorations.pointerCursor!==e&&(this._currentLink.state.decorations.pointerCursor=e,this._currentLink.state.isHovered&&(null===(i=this._element)||void 0===i||i.classList.toggle("xterm-cursor-pointer",e)))}},underline:{get:()=>{var e,t;return null===(t=null===(e=this._currentLink)||void 0===e?void 0:e.state)||void 0===t?void 0:t.decorations.underline},set:t=>{var i,s,r;(null===(i=this._currentLink)||void 0===i?void 0:i.state)&&(null===(r=null===(s=this._currentLink)||void 0===s?void 0:s.state)||void 0===r?void 0:r.decorations.underline)!==t&&(this._currentLink.state.decorations.underline=t,this._currentLink.state.isHovered&&this._fireUnderlineEvent(e.link,t))}}}),this._renderService&&this._linkCacheDisposables.push(this._renderService.onRenderedViewportChange((e=>{if(!this._currentLink)return;const t=0===e.start?0:e.start+1+this._bufferService.buffer.ydisp,i=this._bufferService.buffer.ydisp+1+e.end;if(this._currentLink.link.range.start.y>=t&&this._currentLink.link.range.end.y<=i&&(this._clearCurrentLink(t,i),this._lastMouseEvent&&this._element)){const e=this._positionFromMouseEvent(this._lastMouseEvent,this._element,this._mouseService);e&&this._askForLink(e,!1)}}))))}_linkHover(e,t,i){var s;(null===(s=this._currentLink)||void 0===s?void 0:s.state)&&(this._currentLink.state.isHovered=!0,this._currentLink.state.decorations.underline&&this._fireUnderlineEvent(t,!0),this._currentLink.state.decorations.pointerCursor&&e.classList.add("xterm-cursor-pointer")),t.hover&&t.hover(i,t.text)}_fireUnderlineEvent(e,t){const i=e.range,s=this._bufferService.buffer.ydisp,r=this._createLinkUnderlineEvent(i.start.x-1,i.start.y-s-1,i.end.x,i.end.y-s-1,void 0);(t?this._onShowLinkUnderline:this._onHideLinkUnderline).fire(r)}_linkLeave(e,t,i){var s;(null===(s=this._currentLink)||void 0===s?void 0:s.state)&&(this._currentLink.state.isHovered=!1,this._currentLink.state.decorations.underline&&this._fireUnderlineEvent(t,!1),this._currentLink.state.decorations.pointerCursor&&e.classList.remove("xterm-cursor-pointer")),t.leave&&t.leave(i,t.text)}_linkAtPosition(e,t){const i=e.range.start.y*this._bufferService.cols+e.range.start.x,s=e.range.end.y*this._bufferService.cols+e.range.end.x,r=t.y*this._bufferService.cols+t.x;return i<=r&&r<=s}_positionFromMouseEvent(e,t,i){const s=i.getCoords(e,t,this._bufferService.cols,this._bufferService.rows);if(s)return{x:s[0],y:s[1]+this._bufferService.buffer.ydisp}}_createLinkUnderlineEvent(e,t,i,s,r){return{x1:e,y1:t,x2:i,y2:s,cols:this._bufferService.cols,fg:r}}};t.Linkifier2=c=s([r(0,h.IBufferService)],c)},9042:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.tooMuchOutput=t.promptLabel=void 0,t.promptLabel="Terminal input",t.tooMuchOutput="Too much output to announce, navigate to rows manually to read"},3730:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.OscLinkProvider=void 0;const n=i(511),o=i(2585);let a=t.OscLinkProvider=class{constructor(e,t,i){this._bufferService=e,this._optionsService=t,this._oscLinkService=i}provideLinks(e,t){var i;const s=this._bufferService.buffer.lines.get(e-1);if(!s)return void t(void 0);const r=[],o=this._optionsService.rawOptions.linkHandler,a=new n.CellData,c=s.getTrimmedLength();let l=-1,d=-1,_=!1;for(let t=0;to?o.activate(e,t,i):h(0,t),hover:(e,t)=>{var s;return null===(s=null==o?void 0:o.hover)||void 0===s?void 0:s.call(o,e,t,i)},leave:(e,t)=>{var s;return null===(s=null==o?void 0:o.leave)||void 0===s?void 0:s.call(o,e,t,i)}})}_=!1,a.hasExtendedAttrs()&&a.extended.urlId?(d=t,l=a.extended.urlId):(d=-1,l=-1)}}t(r)}};function h(e,t){if(confirm(`Do you want to navigate to ${t}?\n\nWARNING: This link could potentially be dangerous`)){const e=window.open();if(e){try{e.opener=null}catch(e){}e.location.href=t}else console.warn("Opening link blocked as opener could not be cleared")}}t.OscLinkProvider=a=s([r(0,o.IBufferService),r(1,o.IOptionsService),r(2,o.IOscLinkService)],a)},6193:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.RenderDebouncer=void 0,t.RenderDebouncer=class{constructor(e,t){this._parentWindow=e,this._renderCallback=t,this._refreshCallbacks=[]}dispose(){this._animationFrame&&(this._parentWindow.cancelAnimationFrame(this._animationFrame),this._animationFrame=void 0)}addRefreshCallback(e){return this._refreshCallbacks.push(e),this._animationFrame||(this._animationFrame=this._parentWindow.requestAnimationFrame((()=>this._innerRefresh()))),this._animationFrame}refresh(e,t,i){this._rowCount=i,e=void 0!==e?e:0,t=void 0!==t?t:this._rowCount-1,this._rowStart=void 0!==this._rowStart?Math.min(this._rowStart,e):e,this._rowEnd=void 0!==this._rowEnd?Math.max(this._rowEnd,t):t,this._animationFrame||(this._animationFrame=this._parentWindow.requestAnimationFrame((()=>this._innerRefresh())))}_innerRefresh(){if(this._animationFrame=void 0,void 0===this._rowStart||void 0===this._rowEnd||void 0===this._rowCount)return void this._runRefreshCallbacks();const e=Math.max(this._rowStart,0),t=Math.min(this._rowEnd,this._rowCount-1);this._rowStart=void 0,this._rowEnd=void 0,this._renderCallback(e,t),this._runRefreshCallbacks()}_runRefreshCallbacks(){for(const e of this._refreshCallbacks)e(0);this._refreshCallbacks=[]}}},5596:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.ScreenDprMonitor=void 0;const s=i(844);class r extends s.Disposable{constructor(e){super(),this._parentWindow=e,this._currentDevicePixelRatio=this._parentWindow.devicePixelRatio,this.register((0,s.toDisposable)((()=>{this.clearListener()})))}setListener(e){this._listener&&this.clearListener(),this._listener=e,this._outerListener=()=>{this._listener&&(this._listener(this._parentWindow.devicePixelRatio,this._currentDevicePixelRatio),this._updateDpr())},this._updateDpr()}_updateDpr(){var e;this._outerListener&&(null===(e=this._resolutionMediaMatchList)||void 0===e||e.removeListener(this._outerListener),this._currentDevicePixelRatio=this._parentWindow.devicePixelRatio,this._resolutionMediaMatchList=this._parentWindow.matchMedia(`screen and (resolution: ${this._parentWindow.devicePixelRatio}dppx)`),this._resolutionMediaMatchList.addListener(this._outerListener))}clearListener(){this._resolutionMediaMatchList&&this._listener&&this._outerListener&&(this._resolutionMediaMatchList.removeListener(this._outerListener),this._resolutionMediaMatchList=void 0,this._listener=void 0,this._outerListener=void 0)}}t.ScreenDprMonitor=r},3236:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.Terminal=void 0;const s=i(3614),r=i(3656),n=i(6465),o=i(9042),a=i(3730),h=i(1680),c=i(3107),l=i(5744),d=i(2950),_=i(1296),u=i(428),f=i(4269),v=i(5114),p=i(8934),g=i(3230),m=i(9312),S=i(4725),C=i(6731),b=i(8055),y=i(8969),w=i(8460),E=i(844),k=i(6114),L=i(8437),D=i(2584),R=i(7399),x=i(5941),A=i(9074),B=i(2585),T=i(5435),M=i(4567),O="undefined"!=typeof window?window.document:null;class P extends y.CoreTerminal{get onFocus(){return this._onFocus.event}get onBlur(){return this._onBlur.event}get onA11yChar(){return this._onA11yCharEmitter.event}get onA11yTab(){return this._onA11yTabEmitter.event}get onWillOpen(){return this._onWillOpen.event}constructor(e={}){super(e),this.browser=k,this._keyDownHandled=!1,this._keyDownSeen=!1,this._keyPressHandled=!1,this._unprocessedDeadKey=!1,this._accessibilityManager=this.register(new E.MutableDisposable),this._onCursorMove=this.register(new w.EventEmitter),this.onCursorMove=this._onCursorMove.event,this._onKey=this.register(new w.EventEmitter),this.onKey=this._onKey.event,this._onRender=this.register(new w.EventEmitter),this.onRender=this._onRender.event,this._onSelectionChange=this.register(new w.EventEmitter),this.onSelectionChange=this._onSelectionChange.event,this._onTitleChange=this.register(new w.EventEmitter),this.onTitleChange=this._onTitleChange.event,this._onBell=this.register(new w.EventEmitter),this.onBell=this._onBell.event,this._onFocus=this.register(new w.EventEmitter),this._onBlur=this.register(new w.EventEmitter),this._onA11yCharEmitter=this.register(new w.EventEmitter),this._onA11yTabEmitter=this.register(new w.EventEmitter),this._onWillOpen=this.register(new w.EventEmitter),this._setup(),this.linkifier2=this.register(this._instantiationService.createInstance(n.Linkifier2)),this.linkifier2.registerLinkProvider(this._instantiationService.createInstance(a.OscLinkProvider)),this._decorationService=this._instantiationService.createInstance(A.DecorationService),this._instantiationService.setService(B.IDecorationService,this._decorationService),this.register(this._inputHandler.onRequestBell((()=>this._onBell.fire()))),this.register(this._inputHandler.onRequestRefreshRows(((e,t)=>this.refresh(e,t)))),this.register(this._inputHandler.onRequestSendFocus((()=>this._reportFocus()))),this.register(this._inputHandler.onRequestReset((()=>this.reset()))),this.register(this._inputHandler.onRequestWindowsOptionsReport((e=>this._reportWindowsOptions(e)))),this.register(this._inputHandler.onColor((e=>this._handleColorEvent(e)))),this.register((0,w.forwardEvent)(this._inputHandler.onCursorMove,this._onCursorMove)),this.register((0,w.forwardEvent)(this._inputHandler.onTitleChange,this._onTitleChange)),this.register((0,w.forwardEvent)(this._inputHandler.onA11yChar,this._onA11yCharEmitter)),this.register((0,w.forwardEvent)(this._inputHandler.onA11yTab,this._onA11yTabEmitter)),this.register(this._bufferService.onResize((e=>this._afterResize(e.cols,e.rows)))),this.register((0,E.toDisposable)((()=>{var e,t;this._customKeyEventHandler=void 0,null===(t=null===(e=this.element)||void 0===e?void 0:e.parentNode)||void 0===t||t.removeChild(this.element)})))}_handleColorEvent(e){if(this._themeService)for(const t of e){let e,i="";switch(t.index){case 256:e="foreground",i="10";break;case 257:e="background",i="11";break;case 258:e="cursor",i="12";break;default:e="ansi",i="4;"+t.index}switch(t.type){case 0:const s=b.color.toColorRGB("ansi"===e?this._themeService.colors.ansi[t.index]:this._themeService.colors[e]);this.coreService.triggerDataEvent(`${D.C0.ESC}]${i};${(0,x.toRgbString)(s)}${D.C1_ESCAPED.ST}`);break;case 1:if("ansi"===e)this._themeService.modifyColors((e=>e.ansi[t.index]=b.rgba.toColor(...t.color)));else{const i=e;this._themeService.modifyColors((e=>e[i]=b.rgba.toColor(...t.color)))}break;case 2:this._themeService.restoreColor(t.index)}}}_setup(){super._setup(),this._customKeyEventHandler=void 0}get buffer(){return this.buffers.active}focus(){this.textarea&&this.textarea.focus({preventScroll:!0})}_handleScreenReaderModeOptionChange(e){e?!this._accessibilityManager.value&&this._renderService&&(this._accessibilityManager.value=this._instantiationService.createInstance(M.AccessibilityManager,this)):this._accessibilityManager.clear()}_handleTextAreaFocus(e){this.coreService.decPrivateModes.sendFocus&&this.coreService.triggerDataEvent(D.C0.ESC+"[I"),this.updateCursorStyle(e),this.element.classList.add("focus"),this._showCursor(),this._onFocus.fire()}blur(){var e;return null===(e=this.textarea)||void 0===e?void 0:e.blur()}_handleTextAreaBlur(){this.textarea.value="",this.refresh(this.buffer.y,this.buffer.y),this.coreService.decPrivateModes.sendFocus&&this.coreService.triggerDataEvent(D.C0.ESC+"[O"),this.element.classList.remove("focus"),this._onBlur.fire()}_syncTextArea(){if(!this.textarea||!this.buffer.isCursorInViewport||this._compositionHelper.isComposing||!this._renderService)return;const e=this.buffer.ybase+this.buffer.y,t=this.buffer.lines.get(e);if(!t)return;const i=Math.min(this.buffer.x,this.cols-1),s=this._renderService.dimensions.css.cell.height,r=t.getWidth(i),n=this._renderService.dimensions.css.cell.width*r,o=this.buffer.y*this._renderService.dimensions.css.cell.height,a=i*this._renderService.dimensions.css.cell.width;this.textarea.style.left=a+"px",this.textarea.style.top=o+"px",this.textarea.style.width=n+"px",this.textarea.style.height=s+"px",this.textarea.style.lineHeight=s+"px",this.textarea.style.zIndex="-5"}_initGlobal(){this._bindKeys(),this.register((0,r.addDisposableDomListener)(this.element,"copy",(e=>{this.hasSelection()&&(0,s.copyHandler)(e,this._selectionService)})));const e=e=>(0,s.handlePasteEvent)(e,this.textarea,this.coreService,this.optionsService);this.register((0,r.addDisposableDomListener)(this.textarea,"paste",e)),this.register((0,r.addDisposableDomListener)(this.element,"paste",e)),k.isFirefox?this.register((0,r.addDisposableDomListener)(this.element,"mousedown",(e=>{2===e.button&&(0,s.rightClickHandler)(e,this.textarea,this.screenElement,this._selectionService,this.options.rightClickSelectsWord)}))):this.register((0,r.addDisposableDomListener)(this.element,"contextmenu",(e=>{(0,s.rightClickHandler)(e,this.textarea,this.screenElement,this._selectionService,this.options.rightClickSelectsWord)}))),k.isLinux&&this.register((0,r.addDisposableDomListener)(this.element,"auxclick",(e=>{1===e.button&&(0,s.moveTextAreaUnderMouseCursor)(e,this.textarea,this.screenElement)})))}_bindKeys(){this.register((0,r.addDisposableDomListener)(this.textarea,"keyup",(e=>this._keyUp(e)),!0)),this.register((0,r.addDisposableDomListener)(this.textarea,"keydown",(e=>this._keyDown(e)),!0)),this.register((0,r.addDisposableDomListener)(this.textarea,"keypress",(e=>this._keyPress(e)),!0)),this.register((0,r.addDisposableDomListener)(this.textarea,"compositionstart",(()=>this._compositionHelper.compositionstart()))),this.register((0,r.addDisposableDomListener)(this.textarea,"compositionupdate",(e=>this._compositionHelper.compositionupdate(e)))),this.register((0,r.addDisposableDomListener)(this.textarea,"compositionend",(()=>this._compositionHelper.compositionend()))),this.register((0,r.addDisposableDomListener)(this.textarea,"input",(e=>this._inputEvent(e)),!0)),this.register(this.onRender((()=>this._compositionHelper.updateCompositionElements())))}open(e){var t;if(!e)throw new Error("Terminal requires a parent element.");e.isConnected||this._logService.debug("Terminal.open was called on an element that was not attached to the DOM"),this._document=e.ownerDocument,this.element=this._document.createElement("div"),this.element.dir="ltr",this.element.classList.add("terminal"),this.element.classList.add("xterm"),e.appendChild(this.element);const i=O.createDocumentFragment();this._viewportElement=O.createElement("div"),this._viewportElement.classList.add("xterm-viewport"),i.appendChild(this._viewportElement),this._viewportScrollArea=O.createElement("div"),this._viewportScrollArea.classList.add("xterm-scroll-area"),this._viewportElement.appendChild(this._viewportScrollArea),this.screenElement=O.createElement("div"),this.screenElement.classList.add("xterm-screen"),this._helperContainer=O.createElement("div"),this._helperContainer.classList.add("xterm-helpers"),this.screenElement.appendChild(this._helperContainer),i.appendChild(this.screenElement),this.textarea=O.createElement("textarea"),this.textarea.classList.add("xterm-helper-textarea"),this.textarea.setAttribute("aria-label",o.promptLabel),k.isChromeOS||this.textarea.setAttribute("aria-multiline","false"),this.textarea.setAttribute("autocorrect","off"),this.textarea.setAttribute("autocapitalize","off"),this.textarea.setAttribute("spellcheck","false"),this.textarea.tabIndex=0,this._coreBrowserService=this._instantiationService.createInstance(v.CoreBrowserService,this.textarea,null!==(t=this._document.defaultView)&&void 0!==t?t:window),this._instantiationService.setService(S.ICoreBrowserService,this._coreBrowserService),this.register((0,r.addDisposableDomListener)(this.textarea,"focus",(e=>this._handleTextAreaFocus(e)))),this.register((0,r.addDisposableDomListener)(this.textarea,"blur",(()=>this._handleTextAreaBlur()))),this._helperContainer.appendChild(this.textarea),this._charSizeService=this._instantiationService.createInstance(u.CharSizeService,this._document,this._helperContainer),this._instantiationService.setService(S.ICharSizeService,this._charSizeService),this._themeService=this._instantiationService.createInstance(C.ThemeService),this._instantiationService.setService(S.IThemeService,this._themeService),this._characterJoinerService=this._instantiationService.createInstance(f.CharacterJoinerService),this._instantiationService.setService(S.ICharacterJoinerService,this._characterJoinerService),this._renderService=this.register(this._instantiationService.createInstance(g.RenderService,this.rows,this.screenElement)),this._instantiationService.setService(S.IRenderService,this._renderService),this.register(this._renderService.onRenderedViewportChange((e=>this._onRender.fire(e)))),this.onResize((e=>this._renderService.resize(e.cols,e.rows))),this._compositionView=O.createElement("div"),this._compositionView.classList.add("composition-view"),this._compositionHelper=this._instantiationService.createInstance(d.CompositionHelper,this.textarea,this._compositionView),this._helperContainer.appendChild(this._compositionView),this.element.appendChild(i);try{this._onWillOpen.fire(this.element)}catch(e){}this._renderService.hasRenderer()||this._renderService.setRenderer(this._createRenderer()),this._mouseService=this._instantiationService.createInstance(p.MouseService),this._instantiationService.setService(S.IMouseService,this._mouseService),this.viewport=this._instantiationService.createInstance(h.Viewport,this._viewportElement,this._viewportScrollArea),this.viewport.onRequestScrollLines((e=>this.scrollLines(e.amount,e.suppressScrollEvent,1))),this.register(this._inputHandler.onRequestSyncScrollBar((()=>this.viewport.syncScrollArea()))),this.register(this.viewport),this.register(this.onCursorMove((()=>{this._renderService.handleCursorMove(),this._syncTextArea()}))),this.register(this.onResize((()=>this._renderService.handleResize(this.cols,this.rows)))),this.register(this.onBlur((()=>this._renderService.handleBlur()))),this.register(this.onFocus((()=>this._renderService.handleFocus()))),this.register(this._renderService.onDimensionsChange((()=>this.viewport.syncScrollArea()))),this._selectionService=this.register(this._instantiationService.createInstance(m.SelectionService,this.element,this.screenElement,this.linkifier2)),this._instantiationService.setService(S.ISelectionService,this._selectionService),this.register(this._selectionService.onRequestScrollLines((e=>this.scrollLines(e.amount,e.suppressScrollEvent)))),this.register(this._selectionService.onSelectionChange((()=>this._onSelectionChange.fire()))),this.register(this._selectionService.onRequestRedraw((e=>this._renderService.handleSelectionChanged(e.start,e.end,e.columnSelectMode)))),this.register(this._selectionService.onLinuxMouseSelection((e=>{this.textarea.value=e,this.textarea.focus(),this.textarea.select()}))),this.register(this._onScroll.event((e=>{this.viewport.syncScrollArea(),this._selectionService.refresh()}))),this.register((0,r.addDisposableDomListener)(this._viewportElement,"scroll",(()=>this._selectionService.refresh()))),this.linkifier2.attachToDom(this.screenElement,this._mouseService,this._renderService),this.register(this._instantiationService.createInstance(c.BufferDecorationRenderer,this.screenElement)),this.register((0,r.addDisposableDomListener)(this.element,"mousedown",(e=>this._selectionService.handleMouseDown(e)))),this.coreMouseService.areMouseEventsActive?(this._selectionService.disable(),this.element.classList.add("enable-mouse-events")):this._selectionService.enable(),this.options.screenReaderMode&&(this._accessibilityManager.value=this._instantiationService.createInstance(M.AccessibilityManager,this)),this.register(this.optionsService.onSpecificOptionChange("screenReaderMode",(e=>this._handleScreenReaderModeOptionChange(e)))),this.options.overviewRulerWidth&&(this._overviewRulerRenderer=this.register(this._instantiationService.createInstance(l.OverviewRulerRenderer,this._viewportElement,this.screenElement))),this.optionsService.onSpecificOptionChange("overviewRulerWidth",(e=>{!this._overviewRulerRenderer&&e&&this._viewportElement&&this.screenElement&&(this._overviewRulerRenderer=this.register(this._instantiationService.createInstance(l.OverviewRulerRenderer,this._viewportElement,this.screenElement)))})),this._charSizeService.measure(),this.refresh(0,this.rows-1),this._initGlobal(),this.bindMouse()}_createRenderer(){return this._instantiationService.createInstance(_.DomRenderer,this.element,this.screenElement,this._viewportElement,this.linkifier2)}bindMouse(){const e=this,t=this.element;function i(t){const i=e._mouseService.getMouseReportCoords(t,e.screenElement);if(!i)return!1;let s,r;switch(t.overrideType||t.type){case"mousemove":r=32,void 0===t.buttons?(s=3,void 0!==t.button&&(s=t.button<3?t.button:3)):s=1&t.buttons?0:4&t.buttons?1:2&t.buttons?2:3;break;case"mouseup":r=0,s=t.button<3?t.button:3;break;case"mousedown":r=1,s=t.button<3?t.button:3;break;case"wheel":if(0===e.viewport.getLinesScrolled(t))return!1;r=t.deltaY<0?0:1,s=4;break;default:return!1}return!(void 0===r||void 0===s||s>4)&&e.coreMouseService.triggerMouseEvent({col:i.col,row:i.row,x:i.x,y:i.y,button:s,action:r,ctrl:t.ctrlKey,alt:t.altKey,shift:t.shiftKey})}const s={mouseup:null,wheel:null,mousedrag:null,mousemove:null},n={mouseup:e=>(i(e),e.buttons||(this._document.removeEventListener("mouseup",s.mouseup),s.mousedrag&&this._document.removeEventListener("mousemove",s.mousedrag)),this.cancel(e)),wheel:e=>(i(e),this.cancel(e,!0)),mousedrag:e=>{e.buttons&&i(e)},mousemove:e=>{e.buttons||i(e)}};this.register(this.coreMouseService.onProtocolChange((e=>{e?("debug"===this.optionsService.rawOptions.logLevel&&this._logService.debug("Binding to mouse events:",this.coreMouseService.explainEvents(e)),this.element.classList.add("enable-mouse-events"),this._selectionService.disable()):(this._logService.debug("Unbinding from mouse events."),this.element.classList.remove("enable-mouse-events"),this._selectionService.enable()),8&e?s.mousemove||(t.addEventListener("mousemove",n.mousemove),s.mousemove=n.mousemove):(t.removeEventListener("mousemove",s.mousemove),s.mousemove=null),16&e?s.wheel||(t.addEventListener("wheel",n.wheel,{passive:!1}),s.wheel=n.wheel):(t.removeEventListener("wheel",s.wheel),s.wheel=null),2&e?s.mouseup||(t.addEventListener("mouseup",n.mouseup),s.mouseup=n.mouseup):(this._document.removeEventListener("mouseup",s.mouseup),t.removeEventListener("mouseup",s.mouseup),s.mouseup=null),4&e?s.mousedrag||(s.mousedrag=n.mousedrag):(this._document.removeEventListener("mousemove",s.mousedrag),s.mousedrag=null)}))),this.coreMouseService.activeProtocol=this.coreMouseService.activeProtocol,this.register((0,r.addDisposableDomListener)(t,"mousedown",(e=>{if(e.preventDefault(),this.focus(),this.coreMouseService.areMouseEventsActive&&!this._selectionService.shouldForceSelection(e))return i(e),s.mouseup&&this._document.addEventListener("mouseup",s.mouseup),s.mousedrag&&this._document.addEventListener("mousemove",s.mousedrag),this.cancel(e)}))),this.register((0,r.addDisposableDomListener)(t,"wheel",(e=>{if(!s.wheel){if(!this.buffer.hasScrollback){const t=this.viewport.getLinesScrolled(e);if(0===t)return;const i=D.C0.ESC+(this.coreService.decPrivateModes.applicationCursorKeys?"O":"[")+(e.deltaY<0?"A":"B");let s="";for(let e=0;e{if(!this.coreMouseService.areMouseEventsActive)return this.viewport.handleTouchStart(e),this.cancel(e)}),{passive:!0})),this.register((0,r.addDisposableDomListener)(t,"touchmove",(e=>{if(!this.coreMouseService.areMouseEventsActive)return this.viewport.handleTouchMove(e)?void 0:this.cancel(e)}),{passive:!1}))}refresh(e,t){var i;null===(i=this._renderService)||void 0===i||i.refreshRows(e,t)}updateCursorStyle(e){var t;(null===(t=this._selectionService)||void 0===t?void 0:t.shouldColumnSelect(e))?this.element.classList.add("column-select"):this.element.classList.remove("column-select")}_showCursor(){this.coreService.isCursorInitialized||(this.coreService.isCursorInitialized=!0,this.refresh(this.buffer.y,this.buffer.y))}scrollLines(e,t,i=0){var s;1===i?(super.scrollLines(e,t,i),this.refresh(0,this.rows-1)):null===(s=this.viewport)||void 0===s||s.scrollLines(e)}paste(e){(0,s.paste)(e,this.textarea,this.coreService,this.optionsService)}attachCustomKeyEventHandler(e){this._customKeyEventHandler=e}registerLinkProvider(e){return this.linkifier2.registerLinkProvider(e)}registerCharacterJoiner(e){if(!this._characterJoinerService)throw new Error("Terminal must be opened first");const t=this._characterJoinerService.register(e);return this.refresh(0,this.rows-1),t}deregisterCharacterJoiner(e){if(!this._characterJoinerService)throw new Error("Terminal must be opened first");this._characterJoinerService.deregister(e)&&this.refresh(0,this.rows-1)}get markers(){return this.buffer.markers}registerMarker(e){return this.buffer.addMarker(this.buffer.ybase+this.buffer.y+e)}registerDecoration(e){return this._decorationService.registerDecoration(e)}hasSelection(){return!!this._selectionService&&this._selectionService.hasSelection}select(e,t,i){this._selectionService.setSelection(e,t,i)}getSelection(){return this._selectionService?this._selectionService.selectionText:""}getSelectionPosition(){if(this._selectionService&&this._selectionService.hasSelection)return{start:{x:this._selectionService.selectionStart[0],y:this._selectionService.selectionStart[1]},end:{x:this._selectionService.selectionEnd[0],y:this._selectionService.selectionEnd[1]}}}clearSelection(){var e;null===(e=this._selectionService)||void 0===e||e.clearSelection()}selectAll(){var e;null===(e=this._selectionService)||void 0===e||e.selectAll()}selectLines(e,t){var i;null===(i=this._selectionService)||void 0===i||i.selectLines(e,t)}_keyDown(e){if(this._keyDownHandled=!1,this._keyDownSeen=!0,this._customKeyEventHandler&&!1===this._customKeyEventHandler(e))return!1;const t=this.browser.isMac&&this.options.macOptionIsMeta&&e.altKey;if(!t&&!this._compositionHelper.keydown(e))return this.options.scrollOnUserInput&&this.buffer.ybase!==this.buffer.ydisp&&this.scrollToBottom(),!1;t||"Dead"!==e.key&&"AltGraph"!==e.key||(this._unprocessedDeadKey=!0);const i=(0,R.evaluateKeyboardEvent)(e,this.coreService.decPrivateModes.applicationCursorKeys,this.browser.isMac,this.options.macOptionIsMeta);if(this.updateCursorStyle(e),3===i.type||2===i.type){const t=this.rows-1;return this.scrollLines(2===i.type?-t:t),this.cancel(e,!0)}return 1===i.type&&this.selectAll(),!!this._isThirdLevelShift(this.browser,e)||(i.cancel&&this.cancel(e,!0),!i.key||!!(e.key&&!e.ctrlKey&&!e.altKey&&!e.metaKey&&1===e.key.length&&e.key.charCodeAt(0)>=65&&e.key.charCodeAt(0)<=90)||(this._unprocessedDeadKey?(this._unprocessedDeadKey=!1,!0):(i.key!==D.C0.ETX&&i.key!==D.C0.CR||(this.textarea.value=""),this._onKey.fire({key:i.key,domEvent:e}),this._showCursor(),this.coreService.triggerDataEvent(i.key,!0),!this.optionsService.rawOptions.screenReaderMode||e.altKey||e.ctrlKey?this.cancel(e,!0):void(this._keyDownHandled=!0))))}_isThirdLevelShift(e,t){const i=e.isMac&&!this.options.macOptionIsMeta&&t.altKey&&!t.ctrlKey&&!t.metaKey||e.isWindows&&t.altKey&&t.ctrlKey&&!t.metaKey||e.isWindows&&t.getModifierState("AltGraph");return"keypress"===t.type?i:i&&(!t.keyCode||t.keyCode>47)}_keyUp(e){this._keyDownSeen=!1,this._customKeyEventHandler&&!1===this._customKeyEventHandler(e)||(function(e){return 16===e.keyCode||17===e.keyCode||18===e.keyCode}(e)||this.focus(),this.updateCursorStyle(e),this._keyPressHandled=!1)}_keyPress(e){let t;if(this._keyPressHandled=!1,this._keyDownHandled)return!1;if(this._customKeyEventHandler&&!1===this._customKeyEventHandler(e))return!1;if(this.cancel(e),e.charCode)t=e.charCode;else if(null===e.which||void 0===e.which)t=e.keyCode;else{if(0===e.which||0===e.charCode)return!1;t=e.which}return!(!t||(e.altKey||e.ctrlKey||e.metaKey)&&!this._isThirdLevelShift(this.browser,e)||(t=String.fromCharCode(t),this._onKey.fire({key:t,domEvent:e}),this._showCursor(),this.coreService.triggerDataEvent(t,!0),this._keyPressHandled=!0,this._unprocessedDeadKey=!1,0))}_inputEvent(e){if(e.data&&"insertText"===e.inputType&&(!e.composed||!this._keyDownSeen)&&!this.optionsService.rawOptions.screenReaderMode){if(this._keyPressHandled)return!1;this._unprocessedDeadKey=!1;const t=e.data;return this.coreService.triggerDataEvent(t,!0),this.cancel(e),!0}return!1}resize(e,t){e!==this.cols||t!==this.rows?super.resize(e,t):this._charSizeService&&!this._charSizeService.hasValidSize&&this._charSizeService.measure()}_afterResize(e,t){var i,s;null===(i=this._charSizeService)||void 0===i||i.measure(),null===(s=this.viewport)||void 0===s||s.syncScrollArea(!0)}clear(){var e;if(0!==this.buffer.ybase||0!==this.buffer.y){this.buffer.clearAllMarkers(),this.buffer.lines.set(0,this.buffer.lines.get(this.buffer.ybase+this.buffer.y)),this.buffer.lines.length=1,this.buffer.ydisp=0,this.buffer.ybase=0,this.buffer.y=0;for(let e=1;e{Object.defineProperty(t,"__esModule",{value:!0}),t.TimeBasedDebouncer=void 0,t.TimeBasedDebouncer=class{constructor(e,t=1e3){this._renderCallback=e,this._debounceThresholdMS=t,this._lastRefreshMs=0,this._additionalRefreshRequested=!1}dispose(){this._refreshTimeoutID&&clearTimeout(this._refreshTimeoutID)}refresh(e,t,i){this._rowCount=i,e=void 0!==e?e:0,t=void 0!==t?t:this._rowCount-1,this._rowStart=void 0!==this._rowStart?Math.min(this._rowStart,e):e,this._rowEnd=void 0!==this._rowEnd?Math.max(this._rowEnd,t):t;const s=Date.now();if(s-this._lastRefreshMs>=this._debounceThresholdMS)this._lastRefreshMs=s,this._innerRefresh();else if(!this._additionalRefreshRequested){const e=s-this._lastRefreshMs,t=this._debounceThresholdMS-e;this._additionalRefreshRequested=!0,this._refreshTimeoutID=window.setTimeout((()=>{this._lastRefreshMs=Date.now(),this._innerRefresh(),this._additionalRefreshRequested=!1,this._refreshTimeoutID=void 0}),t)}}_innerRefresh(){if(void 0===this._rowStart||void 0===this._rowEnd||void 0===this._rowCount)return;const e=Math.max(this._rowStart,0),t=Math.min(this._rowEnd,this._rowCount-1);this._rowStart=void 0,this._rowEnd=void 0,this._renderCallback(e,t)}}},1680:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.Viewport=void 0;const n=i(3656),o=i(4725),a=i(8460),h=i(844),c=i(2585);let l=t.Viewport=class extends h.Disposable{constructor(e,t,i,s,r,o,h,c){super(),this._viewportElement=e,this._scrollArea=t,this._bufferService=i,this._optionsService=s,this._charSizeService=r,this._renderService=o,this._coreBrowserService=h,this.scrollBarWidth=0,this._currentRowHeight=0,this._currentDeviceCellHeight=0,this._lastRecordedBufferLength=0,this._lastRecordedViewportHeight=0,this._lastRecordedBufferHeight=0,this._lastTouchY=0,this._lastScrollTop=0,this._wheelPartialScroll=0,this._refreshAnimationFrame=null,this._ignoreNextScrollEvent=!1,this._smoothScrollState={startTime:0,origin:-1,target:-1},this._onRequestScrollLines=this.register(new a.EventEmitter),this.onRequestScrollLines=this._onRequestScrollLines.event,this.scrollBarWidth=this._viewportElement.offsetWidth-this._scrollArea.offsetWidth||15,this.register((0,n.addDisposableDomListener)(this._viewportElement,"scroll",this._handleScroll.bind(this))),this._activeBuffer=this._bufferService.buffer,this.register(this._bufferService.buffers.onBufferActivate((e=>this._activeBuffer=e.activeBuffer))),this._renderDimensions=this._renderService.dimensions,this.register(this._renderService.onDimensionsChange((e=>this._renderDimensions=e))),this._handleThemeChange(c.colors),this.register(c.onChangeColors((e=>this._handleThemeChange(e)))),this.register(this._optionsService.onSpecificOptionChange("scrollback",(()=>this.syncScrollArea()))),setTimeout((()=>this.syncScrollArea()))}_handleThemeChange(e){this._viewportElement.style.backgroundColor=e.background.css}reset(){this._currentRowHeight=0,this._currentDeviceCellHeight=0,this._lastRecordedBufferLength=0,this._lastRecordedViewportHeight=0,this._lastRecordedBufferHeight=0,this._lastTouchY=0,this._lastScrollTop=0,this._coreBrowserService.window.requestAnimationFrame((()=>this.syncScrollArea()))}_refresh(e){if(e)return this._innerRefresh(),void(null!==this._refreshAnimationFrame&&this._coreBrowserService.window.cancelAnimationFrame(this._refreshAnimationFrame));null===this._refreshAnimationFrame&&(this._refreshAnimationFrame=this._coreBrowserService.window.requestAnimationFrame((()=>this._innerRefresh())))}_innerRefresh(){if(this._charSizeService.height>0){this._currentRowHeight=this._renderService.dimensions.device.cell.height/this._coreBrowserService.dpr,this._currentDeviceCellHeight=this._renderService.dimensions.device.cell.height,this._lastRecordedViewportHeight=this._viewportElement.offsetHeight;const e=Math.round(this._currentRowHeight*this._lastRecordedBufferLength)+(this._lastRecordedViewportHeight-this._renderService.dimensions.css.canvas.height);this._lastRecordedBufferHeight!==e&&(this._lastRecordedBufferHeight=e,this._scrollArea.style.height=this._lastRecordedBufferHeight+"px")}const e=this._bufferService.buffer.ydisp*this._currentRowHeight;this._viewportElement.scrollTop!==e&&(this._ignoreNextScrollEvent=!0,this._viewportElement.scrollTop=e),this._refreshAnimationFrame=null}syncScrollArea(e=!1){if(this._lastRecordedBufferLength!==this._bufferService.buffer.lines.length)return this._lastRecordedBufferLength=this._bufferService.buffer.lines.length,void this._refresh(e);this._lastRecordedViewportHeight===this._renderService.dimensions.css.canvas.height&&this._lastScrollTop===this._activeBuffer.ydisp*this._currentRowHeight&&this._renderDimensions.device.cell.height===this._currentDeviceCellHeight||this._refresh(e)}_handleScroll(e){if(this._lastScrollTop=this._viewportElement.scrollTop,!this._viewportElement.offsetParent)return;if(this._ignoreNextScrollEvent)return this._ignoreNextScrollEvent=!1,void this._onRequestScrollLines.fire({amount:0,suppressScrollEvent:!0});const t=Math.round(this._lastScrollTop/this._currentRowHeight)-this._bufferService.buffer.ydisp;this._onRequestScrollLines.fire({amount:t,suppressScrollEvent:!0})}_smoothScroll(){if(this._isDisposed||-1===this._smoothScrollState.origin||-1===this._smoothScrollState.target)return;const e=this._smoothScrollPercent();this._viewportElement.scrollTop=this._smoothScrollState.origin+Math.round(e*(this._smoothScrollState.target-this._smoothScrollState.origin)),e<1?this._coreBrowserService.window.requestAnimationFrame((()=>this._smoothScroll())):this._clearSmoothScrollState()}_smoothScrollPercent(){return this._optionsService.rawOptions.smoothScrollDuration&&this._smoothScrollState.startTime?Math.max(Math.min((Date.now()-this._smoothScrollState.startTime)/this._optionsService.rawOptions.smoothScrollDuration,1),0):1}_clearSmoothScrollState(){this._smoothScrollState.startTime=0,this._smoothScrollState.origin=-1,this._smoothScrollState.target=-1}_bubbleScroll(e,t){const i=this._viewportElement.scrollTop+this._lastRecordedViewportHeight;return!(t<0&&0!==this._viewportElement.scrollTop||t>0&&i0&&(s=e),r=""}}return{bufferElements:n,cursorElement:s}}getLinesScrolled(e){if(0===e.deltaY||e.shiftKey)return 0;let t=this._applyScrollModifier(e.deltaY,e);return e.deltaMode===WheelEvent.DOM_DELTA_PIXEL?(t/=this._currentRowHeight+0,this._wheelPartialScroll+=t,t=Math.floor(Math.abs(this._wheelPartialScroll))*(this._wheelPartialScroll>0?1:-1),this._wheelPartialScroll%=1):e.deltaMode===WheelEvent.DOM_DELTA_PAGE&&(t*=this._bufferService.rows),t}_applyScrollModifier(e,t){const i=this._optionsService.rawOptions.fastScrollModifier;return"alt"===i&&t.altKey||"ctrl"===i&&t.ctrlKey||"shift"===i&&t.shiftKey?e*this._optionsService.rawOptions.fastScrollSensitivity*this._optionsService.rawOptions.scrollSensitivity:e*this._optionsService.rawOptions.scrollSensitivity}handleTouchStart(e){this._lastTouchY=e.touches[0].pageY}handleTouchMove(e){const t=this._lastTouchY-e.touches[0].pageY;return this._lastTouchY=e.touches[0].pageY,0!==t&&(this._viewportElement.scrollTop+=t,this._bubbleScroll(e,t))}};t.Viewport=l=s([r(2,c.IBufferService),r(3,c.IOptionsService),r(4,o.ICharSizeService),r(5,o.IRenderService),r(6,o.ICoreBrowserService),r(7,o.IThemeService)],l)},3107:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.BufferDecorationRenderer=void 0;const n=i(3656),o=i(4725),a=i(844),h=i(2585);let c=t.BufferDecorationRenderer=class extends a.Disposable{constructor(e,t,i,s){super(),this._screenElement=e,this._bufferService=t,this._decorationService=i,this._renderService=s,this._decorationElements=new Map,this._altBufferIsActive=!1,this._dimensionsChanged=!1,this._container=document.createElement("div"),this._container.classList.add("xterm-decoration-container"),this._screenElement.appendChild(this._container),this.register(this._renderService.onRenderedViewportChange((()=>this._doRefreshDecorations()))),this.register(this._renderService.onDimensionsChange((()=>{this._dimensionsChanged=!0,this._queueRefresh()}))),this.register((0,n.addDisposableDomListener)(window,"resize",(()=>this._queueRefresh()))),this.register(this._bufferService.buffers.onBufferActivate((()=>{this._altBufferIsActive=this._bufferService.buffer===this._bufferService.buffers.alt}))),this.register(this._decorationService.onDecorationRegistered((()=>this._queueRefresh()))),this.register(this._decorationService.onDecorationRemoved((e=>this._removeDecoration(e)))),this.register((0,a.toDisposable)((()=>{this._container.remove(),this._decorationElements.clear()})))}_queueRefresh(){void 0===this._animationFrame&&(this._animationFrame=this._renderService.addRefreshCallback((()=>{this._doRefreshDecorations(),this._animationFrame=void 0})))}_doRefreshDecorations(){for(const e of this._decorationService.decorations)this._renderDecoration(e);this._dimensionsChanged=!1}_renderDecoration(e){this._refreshStyle(e),this._dimensionsChanged&&this._refreshXPosition(e)}_createElement(e){var t,i;const s=document.createElement("div");s.classList.add("xterm-decoration"),s.classList.toggle("xterm-decoration-top-layer","top"===(null===(t=null==e?void 0:e.options)||void 0===t?void 0:t.layer)),s.style.width=`${Math.round((e.options.width||1)*this._renderService.dimensions.css.cell.width)}px`,s.style.height=(e.options.height||1)*this._renderService.dimensions.css.cell.height+"px",s.style.top=(e.marker.line-this._bufferService.buffers.active.ydisp)*this._renderService.dimensions.css.cell.height+"px",s.style.lineHeight=`${this._renderService.dimensions.css.cell.height}px`;const r=null!==(i=e.options.x)&&void 0!==i?i:0;return r&&r>this._bufferService.cols&&(s.style.display="none"),this._refreshXPosition(e,s),s}_refreshStyle(e){const t=e.marker.line-this._bufferService.buffers.active.ydisp;if(t<0||t>=this._bufferService.rows)e.element&&(e.element.style.display="none",e.onRenderEmitter.fire(e.element));else{let i=this._decorationElements.get(e);i||(i=this._createElement(e),e.element=i,this._decorationElements.set(e,i),this._container.appendChild(i),e.onDispose((()=>{this._decorationElements.delete(e),i.remove()}))),i.style.top=t*this._renderService.dimensions.css.cell.height+"px",i.style.display=this._altBufferIsActive?"none":"block",e.onRenderEmitter.fire(i)}}_refreshXPosition(e,t=e.element){var i;if(!t)return;const s=null!==(i=e.options.x)&&void 0!==i?i:0;"right"===(e.options.anchor||"left")?t.style.right=s?s*this._renderService.dimensions.css.cell.width+"px":"":t.style.left=s?s*this._renderService.dimensions.css.cell.width+"px":""}_removeDecoration(e){var t;null===(t=this._decorationElements.get(e))||void 0===t||t.remove(),this._decorationElements.delete(e),e.dispose()}};t.BufferDecorationRenderer=c=s([r(1,h.IBufferService),r(2,h.IDecorationService),r(3,o.IRenderService)],c)},5871:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.ColorZoneStore=void 0,t.ColorZoneStore=class{constructor(){this._zones=[],this._zonePool=[],this._zonePoolIndex=0,this._linePadding={full:0,left:0,center:0,right:0}}get zones(){return this._zonePool.length=Math.min(this._zonePool.length,this._zones.length),this._zones}clear(){this._zones.length=0,this._zonePoolIndex=0}addDecoration(e){if(e.options.overviewRulerOptions){for(const t of this._zones)if(t.color===e.options.overviewRulerOptions.color&&t.position===e.options.overviewRulerOptions.position){if(this._lineIntersectsZone(t,e.marker.line))return;if(this._lineAdjacentToZone(t,e.marker.line,e.options.overviewRulerOptions.position))return void this._addLineToZone(t,e.marker.line)}if(this._zonePoolIndex=e.startBufferLine&&t<=e.endBufferLine}_lineAdjacentToZone(e,t,i){return t>=e.startBufferLine-this._linePadding[i||"full"]&&t<=e.endBufferLine+this._linePadding[i||"full"]}_addLineToZone(e,t){e.startBufferLine=Math.min(e.startBufferLine,t),e.endBufferLine=Math.max(e.endBufferLine,t)}}},5744:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.OverviewRulerRenderer=void 0;const n=i(5871),o=i(3656),a=i(4725),h=i(844),c=i(2585),l={full:0,left:0,center:0,right:0},d={full:0,left:0,center:0,right:0},_={full:0,left:0,center:0,right:0};let u=t.OverviewRulerRenderer=class extends h.Disposable{get _width(){return this._optionsService.options.overviewRulerWidth||0}constructor(e,t,i,s,r,o,a){var c;super(),this._viewportElement=e,this._screenElement=t,this._bufferService=i,this._decorationService=s,this._renderService=r,this._optionsService=o,this._coreBrowseService=a,this._colorZoneStore=new n.ColorZoneStore,this._shouldUpdateDimensions=!0,this._shouldUpdateAnchor=!0,this._lastKnownBufferLength=0,this._canvas=document.createElement("canvas"),this._canvas.classList.add("xterm-decoration-overview-ruler"),this._refreshCanvasDimensions(),null===(c=this._viewportElement.parentElement)||void 0===c||c.insertBefore(this._canvas,this._viewportElement);const l=this._canvas.getContext("2d");if(!l)throw new Error("Ctx cannot be null");this._ctx=l,this._registerDecorationListeners(),this._registerBufferChangeListeners(),this._registerDimensionChangeListeners(),this.register((0,h.toDisposable)((()=>{var e;null===(e=this._canvas)||void 0===e||e.remove()})))}_registerDecorationListeners(){this.register(this._decorationService.onDecorationRegistered((()=>this._queueRefresh(void 0,!0)))),this.register(this._decorationService.onDecorationRemoved((()=>this._queueRefresh(void 0,!0))))}_registerBufferChangeListeners(){this.register(this._renderService.onRenderedViewportChange((()=>this._queueRefresh()))),this.register(this._bufferService.buffers.onBufferActivate((()=>{this._canvas.style.display=this._bufferService.buffer===this._bufferService.buffers.alt?"none":"block"}))),this.register(this._bufferService.onScroll((()=>{this._lastKnownBufferLength!==this._bufferService.buffers.normal.lines.length&&(this._refreshDrawHeightConstants(),this._refreshColorZonePadding())})))}_registerDimensionChangeListeners(){this.register(this._renderService.onRender((()=>{this._containerHeight&&this._containerHeight===this._screenElement.clientHeight||(this._queueRefresh(!0),this._containerHeight=this._screenElement.clientHeight)}))),this.register(this._optionsService.onSpecificOptionChange("overviewRulerWidth",(()=>this._queueRefresh(!0)))),this.register((0,o.addDisposableDomListener)(this._coreBrowseService.window,"resize",(()=>this._queueRefresh(!0)))),this._queueRefresh(!0)}_refreshDrawConstants(){const e=Math.floor(this._canvas.width/3),t=Math.ceil(this._canvas.width/3);d.full=this._canvas.width,d.left=e,d.center=t,d.right=e,this._refreshDrawHeightConstants(),_.full=0,_.left=0,_.center=d.left,_.right=d.left+d.center}_refreshDrawHeightConstants(){l.full=Math.round(2*this._coreBrowseService.dpr);const e=this._canvas.height/this._bufferService.buffer.lines.length,t=Math.round(Math.max(Math.min(e,12),6)*this._coreBrowseService.dpr);l.left=t,l.center=t,l.right=t}_refreshColorZonePadding(){this._colorZoneStore.setPadding({full:Math.floor(this._bufferService.buffers.active.lines.length/(this._canvas.height-1)*l.full),left:Math.floor(this._bufferService.buffers.active.lines.length/(this._canvas.height-1)*l.left),center:Math.floor(this._bufferService.buffers.active.lines.length/(this._canvas.height-1)*l.center),right:Math.floor(this._bufferService.buffers.active.lines.length/(this._canvas.height-1)*l.right)}),this._lastKnownBufferLength=this._bufferService.buffers.normal.lines.length}_refreshCanvasDimensions(){this._canvas.style.width=`${this._width}px`,this._canvas.width=Math.round(this._width*this._coreBrowseService.dpr),this._canvas.style.height=`${this._screenElement.clientHeight}px`,this._canvas.height=Math.round(this._screenElement.clientHeight*this._coreBrowseService.dpr),this._refreshDrawConstants(),this._refreshColorZonePadding()}_refreshDecorations(){this._shouldUpdateDimensions&&this._refreshCanvasDimensions(),this._ctx.clearRect(0,0,this._canvas.width,this._canvas.height),this._colorZoneStore.clear();for(const e of this._decorationService.decorations)this._colorZoneStore.addDecoration(e);this._ctx.lineWidth=1;const e=this._colorZoneStore.zones;for(const t of e)"full"!==t.position&&this._renderColorZone(t);for(const t of e)"full"===t.position&&this._renderColorZone(t);this._shouldUpdateDimensions=!1,this._shouldUpdateAnchor=!1}_renderColorZone(e){this._ctx.fillStyle=e.color,this._ctx.fillRect(_[e.position||"full"],Math.round((this._canvas.height-1)*(e.startBufferLine/this._bufferService.buffers.active.lines.length)-l[e.position||"full"]/2),d[e.position||"full"],Math.round((this._canvas.height-1)*((e.endBufferLine-e.startBufferLine)/this._bufferService.buffers.active.lines.length)+l[e.position||"full"]))}_queueRefresh(e,t){this._shouldUpdateDimensions=e||this._shouldUpdateDimensions,this._shouldUpdateAnchor=t||this._shouldUpdateAnchor,void 0===this._animationFrame&&(this._animationFrame=this._coreBrowseService.window.requestAnimationFrame((()=>{this._refreshDecorations(),this._animationFrame=void 0})))}};t.OverviewRulerRenderer=u=s([r(2,c.IBufferService),r(3,c.IDecorationService),r(4,a.IRenderService),r(5,c.IOptionsService),r(6,a.ICoreBrowserService)],u)},2950:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.CompositionHelper=void 0;const n=i(4725),o=i(2585),a=i(2584);let h=t.CompositionHelper=class{get isComposing(){return this._isComposing}constructor(e,t,i,s,r,n){this._textarea=e,this._compositionView=t,this._bufferService=i,this._optionsService=s,this._coreService=r,this._renderService=n,this._isComposing=!1,this._isSendingComposition=!1,this._compositionPosition={start:0,end:0},this._dataAlreadySent=""}compositionstart(){this._isComposing=!0,this._compositionPosition.start=this._textarea.value.length,this._compositionView.textContent="",this._dataAlreadySent="",this._compositionView.classList.add("active")}compositionupdate(e){this._compositionView.textContent=e.data,this.updateCompositionElements(),setTimeout((()=>{this._compositionPosition.end=this._textarea.value.length}),0)}compositionend(){this._finalizeComposition(!0)}keydown(e){if(this._isComposing||this._isSendingComposition){if(229===e.keyCode)return!1;if(16===e.keyCode||17===e.keyCode||18===e.keyCode)return!1;this._finalizeComposition(!1)}return 229!==e.keyCode||(this._handleAnyTextareaChanges(),!1)}_finalizeComposition(e){if(this._compositionView.classList.remove("active"),this._isComposing=!1,e){const e={start:this._compositionPosition.start,end:this._compositionPosition.end};this._isSendingComposition=!0,setTimeout((()=>{if(this._isSendingComposition){let t;this._isSendingComposition=!1,e.start+=this._dataAlreadySent.length,t=this._isComposing?this._textarea.value.substring(e.start,e.end):this._textarea.value.substring(e.start),t.length>0&&this._coreService.triggerDataEvent(t,!0)}}),0)}else{this._isSendingComposition=!1;const e=this._textarea.value.substring(this._compositionPosition.start,this._compositionPosition.end);this._coreService.triggerDataEvent(e,!0)}}_handleAnyTextareaChanges(){const e=this._textarea.value;setTimeout((()=>{if(!this._isComposing){const t=this._textarea.value,i=t.replace(e,"");this._dataAlreadySent=i,t.length>e.length?this._coreService.triggerDataEvent(i,!0):t.lengththis.updateCompositionElements(!0)),0)}}};t.CompositionHelper=h=s([r(2,o.IBufferService),r(3,o.IOptionsService),r(4,o.ICoreService),r(5,n.IRenderService)],h)},9806:(e,t)=>{function i(e,t,i){const s=i.getBoundingClientRect(),r=e.getComputedStyle(i),n=parseInt(r.getPropertyValue("padding-left")),o=parseInt(r.getPropertyValue("padding-top"));return[t.clientX-s.left-n,t.clientY-s.top-o]}Object.defineProperty(t,"__esModule",{value:!0}),t.getCoords=t.getCoordsRelativeToElement=void 0,t.getCoordsRelativeToElement=i,t.getCoords=function(e,t,s,r,n,o,a,h,c){if(!o)return;const l=i(e,t,s);return l?(l[0]=Math.ceil((l[0]+(c?a/2:0))/a),l[1]=Math.ceil(l[1]/h),l[0]=Math.min(Math.max(l[0],1),r+(c?1:0)),l[1]=Math.min(Math.max(l[1],1),n),l):void 0}},9504:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.moveToCellSequence=void 0;const s=i(2584);function r(e,t,i,s){const r=e-n(e,i),a=t-n(t,i),l=Math.abs(r-a)-function(e,t,i){let s=0;const r=e-n(e,i),a=t-n(t,i);for(let n=0;n=0&&et?"A":"B"}function a(e,t,i,s,r,n){let o=e,a=t,h="";for(;o!==i||a!==s;)o+=r?1:-1,r&&o>n.cols-1?(h+=n.buffer.translateBufferLineToString(a,!1,e,o),o=0,e=0,a++):!r&&o<0&&(h+=n.buffer.translateBufferLineToString(a,!1,0,e+1),o=n.cols-1,e=o,a--);return h+n.buffer.translateBufferLineToString(a,!1,e,o)}function h(e,t){const i=t?"O":"[";return s.C0.ESC+i+e}function c(e,t){e=Math.floor(e);let i="";for(let s=0;s0?s-n(s,o):t;const _=s,u=function(e,t,i,s,o,a){let h;return h=r(i,s,o,a).length>0?s-n(s,o):t,e=i&&he?"D":"C",c(Math.abs(o-e),h(d,s));d=l>t?"D":"C";const _=Math.abs(l-t);return c(function(e,t){return t.cols-e}(l>t?e:o,i)+(_-1)*i.cols+1+((l>t?o:e)-1),h(d,s))}},1296:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.DomRenderer=void 0;const n=i(3787),o=i(2550),a=i(2223),h=i(6171),c=i(4725),l=i(8055),d=i(8460),_=i(844),u=i(2585),f="xterm-dom-renderer-owner-",v="xterm-rows",p="xterm-fg-",g="xterm-bg-",m="xterm-focus",S="xterm-selection";let C=1,b=t.DomRenderer=class extends _.Disposable{constructor(e,t,i,s,r,a,c,l,u,p){super(),this._element=e,this._screenElement=t,this._viewportElement=i,this._linkifier2=s,this._charSizeService=a,this._optionsService=c,this._bufferService=l,this._coreBrowserService=u,this._themeService=p,this._terminalClass=C++,this._rowElements=[],this.onRequestRedraw=this.register(new d.EventEmitter).event,this._rowContainer=document.createElement("div"),this._rowContainer.classList.add(v),this._rowContainer.style.lineHeight="normal",this._rowContainer.setAttribute("aria-hidden","true"),this._refreshRowElements(this._bufferService.cols,this._bufferService.rows),this._selectionContainer=document.createElement("div"),this._selectionContainer.classList.add(S),this._selectionContainer.setAttribute("aria-hidden","true"),this.dimensions=(0,h.createRenderDimensions)(),this._updateDimensions(),this.register(this._optionsService.onOptionChange((()=>this._handleOptionsChanged()))),this.register(this._themeService.onChangeColors((e=>this._injectCss(e)))),this._injectCss(this._themeService.colors),this._rowFactory=r.createInstance(n.DomRendererRowFactory,document),this._element.classList.add(f+this._terminalClass),this._screenElement.appendChild(this._rowContainer),this._screenElement.appendChild(this._selectionContainer),this.register(this._linkifier2.onShowLinkUnderline((e=>this._handleLinkHover(e)))),this.register(this._linkifier2.onHideLinkUnderline((e=>this._handleLinkLeave(e)))),this.register((0,_.toDisposable)((()=>{this._element.classList.remove(f+this._terminalClass),this._rowContainer.remove(),this._selectionContainer.remove(),this._widthCache.dispose(),this._themeStyleElement.remove(),this._dimensionsStyleElement.remove()}))),this._widthCache=new o.WidthCache(document),this._widthCache.setFont(this._optionsService.rawOptions.fontFamily,this._optionsService.rawOptions.fontSize,this._optionsService.rawOptions.fontWeight,this._optionsService.rawOptions.fontWeightBold),this._setDefaultSpacing()}_updateDimensions(){const e=this._coreBrowserService.dpr;this.dimensions.device.char.width=this._charSizeService.width*e,this.dimensions.device.char.height=Math.ceil(this._charSizeService.height*e),this.dimensions.device.cell.width=this.dimensions.device.char.width+Math.round(this._optionsService.rawOptions.letterSpacing),this.dimensions.device.cell.height=Math.floor(this.dimensions.device.char.height*this._optionsService.rawOptions.lineHeight),this.dimensions.device.char.left=0,this.dimensions.device.char.top=0,this.dimensions.device.canvas.width=this.dimensions.device.cell.width*this._bufferService.cols,this.dimensions.device.canvas.height=this.dimensions.device.cell.height*this._bufferService.rows,this.dimensions.css.canvas.width=Math.round(this.dimensions.device.canvas.width/e),this.dimensions.css.canvas.height=Math.round(this.dimensions.device.canvas.height/e),this.dimensions.css.cell.width=this.dimensions.css.canvas.width/this._bufferService.cols,this.dimensions.css.cell.height=this.dimensions.css.canvas.height/this._bufferService.rows;for(const e of this._rowElements)e.style.width=`${this.dimensions.css.canvas.width}px`,e.style.height=`${this.dimensions.css.cell.height}px`,e.style.lineHeight=`${this.dimensions.css.cell.height}px`,e.style.overflow="hidden";this._dimensionsStyleElement||(this._dimensionsStyleElement=document.createElement("style"),this._screenElement.appendChild(this._dimensionsStyleElement));const t=`${this._terminalSelector} .${v} span { display: inline-block; height: 100%; vertical-align: top;}`;this._dimensionsStyleElement.textContent=t,this._selectionContainer.style.height=this._viewportElement.style.height,this._screenElement.style.width=`${this.dimensions.css.canvas.width}px`,this._screenElement.style.height=`${this.dimensions.css.canvas.height}px`}_injectCss(e){this._themeStyleElement||(this._themeStyleElement=document.createElement("style"),this._screenElement.appendChild(this._themeStyleElement));let t=`${this._terminalSelector} .${v} { color: ${e.foreground.css}; font-family: ${this._optionsService.rawOptions.fontFamily}; font-size: ${this._optionsService.rawOptions.fontSize}px; font-kerning: none; white-space: pre}`;t+=`${this._terminalSelector} .${v} .xterm-dim { color: ${l.color.multiplyOpacity(e.foreground,.5).css};}`,t+=`${this._terminalSelector} span:not(.xterm-bold) { font-weight: ${this._optionsService.rawOptions.fontWeight};}${this._terminalSelector} span.xterm-bold { font-weight: ${this._optionsService.rawOptions.fontWeightBold};}${this._terminalSelector} span.xterm-italic { font-style: italic;}`,t+="@keyframes blink_box_shadow_"+this._terminalClass+" { 50% { border-bottom-style: hidden; }}",t+="@keyframes blink_block_"+this._terminalClass+" { 0% {"+` background-color: ${e.cursor.css};`+` color: ${e.cursorAccent.css}; } 50% { background-color: inherit;`+` color: ${e.cursor.css}; }}`,t+=`${this._terminalSelector} .${v}.${m} .xterm-cursor.xterm-cursor-blink:not(.xterm-cursor-block) { animation: blink_box_shadow_`+this._terminalClass+" 1s step-end infinite;}"+`${this._terminalSelector} .${v}.${m} .xterm-cursor.xterm-cursor-blink.xterm-cursor-block { animation: blink_block_`+this._terminalClass+" 1s step-end infinite;}"+`${this._terminalSelector} .${v} .xterm-cursor.xterm-cursor-block {`+` background-color: ${e.cursor.css};`+` color: ${e.cursorAccent.css};}`+`${this._terminalSelector} .${v} .xterm-cursor.xterm-cursor-outline {`+` outline: 1px solid ${e.cursor.css}; outline-offset: -1px;}`+`${this._terminalSelector} .${v} .xterm-cursor.xterm-cursor-bar {`+` box-shadow: ${this._optionsService.rawOptions.cursorWidth}px 0 0 ${e.cursor.css} inset;}`+`${this._terminalSelector} .${v} .xterm-cursor.xterm-cursor-underline {`+` border-bottom: 1px ${e.cursor.css}; border-bottom-style: solid; height: calc(100% - 1px);}`,t+=`${this._terminalSelector} .${S} { position: absolute; top: 0; left: 0; z-index: 1; pointer-events: none;}${this._terminalSelector}.focus .${S} div { position: absolute; background-color: ${e.selectionBackgroundOpaque.css};}${this._terminalSelector} .${S} div { position: absolute; background-color: ${e.selectionInactiveBackgroundOpaque.css};}`;for(const[i,s]of e.ansi.entries())t+=`${this._terminalSelector} .${p}${i} { color: ${s.css}; }${this._terminalSelector} .${p}${i}.xterm-dim { color: ${l.color.multiplyOpacity(s,.5).css}; }${this._terminalSelector} .${g}${i} { background-color: ${s.css}; }`;t+=`${this._terminalSelector} .${p}${a.INVERTED_DEFAULT_COLOR} { color: ${l.color.opaque(e.background).css}; }${this._terminalSelector} .${p}${a.INVERTED_DEFAULT_COLOR}.xterm-dim { color: ${l.color.multiplyOpacity(l.color.opaque(e.background),.5).css}; }${this._terminalSelector} .${g}${a.INVERTED_DEFAULT_COLOR} { background-color: ${e.foreground.css}; }`,this._themeStyleElement.textContent=t}_setDefaultSpacing(){const e=this.dimensions.css.cell.width-this._widthCache.get("W",!1,!1);this._rowContainer.style.letterSpacing=`${e}px`,this._rowFactory.defaultSpacing=e}handleDevicePixelRatioChange(){this._updateDimensions(),this._widthCache.clear(),this._setDefaultSpacing()}_refreshRowElements(e,t){for(let e=this._rowElements.length;e<=t;e++){const e=document.createElement("div");this._rowContainer.appendChild(e),this._rowElements.push(e)}for(;this._rowElements.length>t;)this._rowContainer.removeChild(this._rowElements.pop())}handleResize(e,t){this._refreshRowElements(e,t),this._updateDimensions()}handleCharSizeChanged(){this._updateDimensions(),this._widthCache.clear(),this._setDefaultSpacing()}handleBlur(){this._rowContainer.classList.remove(m)}handleFocus(){this._rowContainer.classList.add(m),this.renderRows(this._bufferService.buffer.y,this._bufferService.buffer.y)}handleSelectionChanged(e,t,i){if(this._selectionContainer.replaceChildren(),this._rowFactory.handleSelectionChanged(e,t,i),this.renderRows(0,this._bufferService.rows-1),!e||!t)return;const s=e[1]-this._bufferService.buffer.ydisp,r=t[1]-this._bufferService.buffer.ydisp,n=Math.max(s,0),o=Math.min(r,this._bufferService.rows-1);if(n>=this._bufferService.rows||o<0)return;const a=document.createDocumentFragment();if(i){const i=e[0]>t[0];a.appendChild(this._createSelectionElement(n,i?t[0]:e[0],i?e[0]:t[0],o-n+1))}else{const i=s===n?e[0]:0,h=n===r?t[0]:this._bufferService.cols;a.appendChild(this._createSelectionElement(n,i,h));const c=o-n-1;if(a.appendChild(this._createSelectionElement(n+1,0,this._bufferService.cols,c)),n!==o){const e=r===o?t[0]:this._bufferService.cols;a.appendChild(this._createSelectionElement(o,0,e))}}this._selectionContainer.appendChild(a)}_createSelectionElement(e,t,i,s=1){const r=document.createElement("div");return r.style.height=s*this.dimensions.css.cell.height+"px",r.style.top=e*this.dimensions.css.cell.height+"px",r.style.left=t*this.dimensions.css.cell.width+"px",r.style.width=this.dimensions.css.cell.width*(i-t)+"px",r}handleCursorMove(){}_handleOptionsChanged(){this._updateDimensions(),this._injectCss(this._themeService.colors),this._widthCache.setFont(this._optionsService.rawOptions.fontFamily,this._optionsService.rawOptions.fontSize,this._optionsService.rawOptions.fontWeight,this._optionsService.rawOptions.fontWeightBold),this._setDefaultSpacing()}clear(){for(const e of this._rowElements)e.replaceChildren()}renderRows(e,t){const i=this._bufferService.buffer,s=i.ybase+i.y,r=Math.min(i.x,this._bufferService.cols-1),n=this._optionsService.rawOptions.cursorBlink,o=this._optionsService.rawOptions.cursorStyle,a=this._optionsService.rawOptions.cursorInactiveStyle;for(let h=e;h<=t;h++){const e=h+i.ydisp,t=this._rowElements[h],c=i.lines.get(e);if(!t||!c)break;t.replaceChildren(...this._rowFactory.createRow(c,e,e===s,o,a,r,n,this.dimensions.css.cell.width,this._widthCache,-1,-1))}}get _terminalSelector(){return`.${f}${this._terminalClass}`}_handleLinkHover(e){this._setCellUnderline(e.x1,e.x2,e.y1,e.y2,e.cols,!0)}_handleLinkLeave(e){this._setCellUnderline(e.x1,e.x2,e.y1,e.y2,e.cols,!1)}_setCellUnderline(e,t,i,s,r,n){i<0&&(e=0),s<0&&(t=0);const o=this._bufferService.rows-1;i=Math.max(Math.min(i,o),0),s=Math.max(Math.min(s,o),0),r=Math.min(r,this._bufferService.cols);const a=this._bufferService.buffer,h=a.ybase+a.y,c=Math.min(a.x,r-1),l=this._optionsService.rawOptions.cursorBlink,d=this._optionsService.rawOptions.cursorStyle,_=this._optionsService.rawOptions.cursorInactiveStyle;for(let o=i;o<=s;++o){const u=o+a.ydisp,f=this._rowElements[o],v=a.lines.get(u);if(!f||!v)break;f.replaceChildren(...this._rowFactory.createRow(v,u,u===h,d,_,c,l,this.dimensions.css.cell.width,this._widthCache,n?o===i?e:0:-1,n?(o===s?t:r)-1:-1))}}};t.DomRenderer=b=s([r(4,u.IInstantiationService),r(5,c.ICharSizeService),r(6,u.IOptionsService),r(7,u.IBufferService),r(8,c.ICoreBrowserService),r(9,c.IThemeService)],b)},3787:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.DomRendererRowFactory=void 0;const n=i(2223),o=i(643),a=i(511),h=i(2585),c=i(8055),l=i(4725),d=i(4269),_=i(6171),u=i(3734);let f=t.DomRendererRowFactory=class{constructor(e,t,i,s,r,n,o){this._document=e,this._characterJoinerService=t,this._optionsService=i,this._coreBrowserService=s,this._coreService=r,this._decorationService=n,this._themeService=o,this._workCell=new a.CellData,this._columnSelectMode=!1,this.defaultSpacing=0}handleSelectionChanged(e,t,i){this._selectionStart=e,this._selectionEnd=t,this._columnSelectMode=i}createRow(e,t,i,s,r,a,h,l,_,f,p){const g=[],m=this._characterJoinerService.getJoinedCharacters(t),S=this._themeService.colors;let C,b=e.getNoBgTrimmedLength();i&&b0&&M===m[0][0]){O=!0;const t=m.shift();I=new d.JoinedCellData(this._workCell,e.translateToString(!0,t[0],t[1]),t[1]-t[0]),P=t[1]-1,b=I.getWidth()}const H=this._isCellInSelection(M,t),F=i&&M===a,W=T&&M>=f&&M<=p;let U=!1;this._decorationService.forEachDecorationAtCell(M,t,void 0,(e=>{U=!0}));let N=I.getChars()||o.WHITESPACE_CELL_CHAR;if(" "===N&&(I.isUnderline()||I.isOverline())&&(N=" "),A=b*l-_.get(N,I.isBold(),I.isItalic()),C){if(y&&(H&&x||!H&&!x&&I.bg===E)&&(H&&x&&S.selectionForeground||I.fg===k)&&I.extended.ext===L&&W===D&&A===R&&!F&&!O&&!U){w+=N,y++;continue}y&&(C.textContent=w),C=this._document.createElement("span"),y=0,w=""}else C=this._document.createElement("span");if(E=I.bg,k=I.fg,L=I.extended.ext,D=W,R=A,x=H,O&&a>=M&&a<=P&&(a=M),!this._coreService.isCursorHidden&&F)if(B.push("xterm-cursor"),this._coreBrowserService.isFocused)h&&B.push("xterm-cursor-blink"),B.push("bar"===s?"xterm-cursor-bar":"underline"===s?"xterm-cursor-underline":"xterm-cursor-block");else if(r)switch(r){case"outline":B.push("xterm-cursor-outline");break;case"block":B.push("xterm-cursor-block");break;case"bar":B.push("xterm-cursor-bar");break;case"underline":B.push("xterm-cursor-underline")}if(I.isBold()&&B.push("xterm-bold"),I.isItalic()&&B.push("xterm-italic"),I.isDim()&&B.push("xterm-dim"),w=I.isInvisible()?o.WHITESPACE_CELL_CHAR:I.getChars()||o.WHITESPACE_CELL_CHAR,I.isUnderline()&&(B.push(`xterm-underline-${I.extended.underlineStyle}`)," "===w&&(w=" "),!I.isUnderlineColorDefault()))if(I.isUnderlineColorRGB())C.style.textDecorationColor=`rgb(${u.AttributeData.toColorRGB(I.getUnderlineColor()).join(",")})`;else{let e=I.getUnderlineColor();this._optionsService.rawOptions.drawBoldTextInBrightColors&&I.isBold()&&e<8&&(e+=8),C.style.textDecorationColor=S.ansi[e].css}I.isOverline()&&(B.push("xterm-overline")," "===w&&(w=" ")),I.isStrikethrough()&&B.push("xterm-strikethrough"),W&&(C.style.textDecoration="underline");let $=I.getFgColor(),j=I.getFgColorMode(),z=I.getBgColor(),K=I.getBgColorMode();const q=!!I.isInverse();if(q){const e=$;$=z,z=e;const t=j;j=K,K=t}let V,G,X,J=!1;switch(this._decorationService.forEachDecorationAtCell(M,t,void 0,(e=>{"top"!==e.options.layer&&J||(e.backgroundColorRGB&&(K=50331648,z=e.backgroundColorRGB.rgba>>8&16777215,V=e.backgroundColorRGB),e.foregroundColorRGB&&(j=50331648,$=e.foregroundColorRGB.rgba>>8&16777215,G=e.foregroundColorRGB),J="top"===e.options.layer)})),!J&&H&&(V=this._coreBrowserService.isFocused?S.selectionBackgroundOpaque:S.selectionInactiveBackgroundOpaque,z=V.rgba>>8&16777215,K=50331648,J=!0,S.selectionForeground&&(j=50331648,$=S.selectionForeground.rgba>>8&16777215,G=S.selectionForeground)),J&&B.push("xterm-decoration-top"),K){case 16777216:case 33554432:X=S.ansi[z],B.push(`xterm-bg-${z}`);break;case 50331648:X=c.rgba.toColor(z>>16,z>>8&255,255&z),this._addStyle(C,`background-color:#${v((z>>>0).toString(16),"0",6)}`);break;default:q?(X=S.foreground,B.push(`xterm-bg-${n.INVERTED_DEFAULT_COLOR}`)):X=S.background}switch(V||I.isDim()&&(V=c.color.multiplyOpacity(X,.5)),j){case 16777216:case 33554432:I.isBold()&&$<8&&this._optionsService.rawOptions.drawBoldTextInBrightColors&&($+=8),this._applyMinimumContrast(C,X,S.ansi[$],I,V,void 0)||B.push(`xterm-fg-${$}`);break;case 50331648:const e=c.rgba.toColor($>>16&255,$>>8&255,255&$);this._applyMinimumContrast(C,X,e,I,V,G)||this._addStyle(C,`color:#${v($.toString(16),"0",6)}`);break;default:this._applyMinimumContrast(C,X,S.foreground,I,V,void 0)||q&&B.push(`xterm-fg-${n.INVERTED_DEFAULT_COLOR}`)}B.length&&(C.className=B.join(" "),B.length=0),F||O||U?C.textContent=w:y++,A!==this.defaultSpacing&&(C.style.letterSpacing=`${A}px`),g.push(C),M=P}return C&&y&&(C.textContent=w),g}_applyMinimumContrast(e,t,i,s,r,n){if(1===this._optionsService.rawOptions.minimumContrastRatio||(0,_.excludeFromContrastRatioDemands)(s.getCode()))return!1;const o=this._getContrastCache(s);let a;if(r||n||(a=o.getColor(t.rgba,i.rgba)),void 0===a){const e=this._optionsService.rawOptions.minimumContrastRatio/(s.isDim()?2:1);a=c.color.ensureContrastRatio(r||t,n||i,e),o.setColor((r||t).rgba,(n||i).rgba,null!=a?a:null)}return!!a&&(this._addStyle(e,`color:${a.css}`),!0)}_getContrastCache(e){return e.isDim()?this._themeService.colors.halfContrastCache:this._themeService.colors.contrastCache}_addStyle(e,t){e.setAttribute("style",`${e.getAttribute("style")||""}${t};`)}_isCellInSelection(e,t){const i=this._selectionStart,s=this._selectionEnd;return!(!i||!s)&&(this._columnSelectMode?i[0]<=s[0]?e>=i[0]&&t>=i[1]&&e=i[1]&&e>=s[0]&&t<=s[1]:t>i[1]&&t=i[0]&&e=i[0])}};function v(e,t,i){for(;e.length{Object.defineProperty(t,"__esModule",{value:!0}),t.WidthCache=void 0,t.WidthCache=class{constructor(e){this._flat=new Float32Array(256),this._font="",this._fontSize=0,this._weight="normal",this._weightBold="bold",this._measureElements=[],this._container=e.createElement("div"),this._container.style.position="absolute",this._container.style.top="-50000px",this._container.style.width="50000px",this._container.style.whiteSpace="pre",this._container.style.fontKerning="none";const t=e.createElement("span"),i=e.createElement("span");i.style.fontWeight="bold";const s=e.createElement("span");s.style.fontStyle="italic";const r=e.createElement("span");r.style.fontWeight="bold",r.style.fontStyle="italic",this._measureElements=[t,i,s,r],this._container.appendChild(t),this._container.appendChild(i),this._container.appendChild(s),this._container.appendChild(r),e.body.appendChild(this._container),this.clear()}dispose(){this._container.remove(),this._measureElements.length=0,this._holey=void 0}clear(){this._flat.fill(-9999),this._holey=new Map}setFont(e,t,i,s){e===this._font&&t===this._fontSize&&i===this._weight&&s===this._weightBold||(this._font=e,this._fontSize=t,this._weight=i,this._weightBold=s,this._container.style.fontFamily=this._font,this._container.style.fontSize=`${this._fontSize}px`,this._measureElements[0].style.fontWeight=`${i}`,this._measureElements[1].style.fontWeight=`${s}`,this._measureElements[2].style.fontWeight=`${i}`,this._measureElements[3].style.fontWeight=`${s}`,this.clear())}get(e,t,i){let s=0;if(!t&&!i&&1===e.length&&(s=e.charCodeAt(0))<256)return-9999!==this._flat[s]?this._flat[s]:this._flat[s]=this._measure(e,0);let r=e;t&&(r+="B"),i&&(r+="I");let n=this._holey.get(r);if(void 0===n){let s=0;t&&(s|=1),i&&(s|=2),n=this._measure(e,s),this._holey.set(r,n)}return n}_measure(e,t){const i=this._measureElements[t];return i.textContent=e.repeat(32),i.offsetWidth/32}}},2223:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.TEXT_BASELINE=t.DIM_OPACITY=t.INVERTED_DEFAULT_COLOR=void 0;const s=i(6114);t.INVERTED_DEFAULT_COLOR=257,t.DIM_OPACITY=.5,t.TEXT_BASELINE=s.isFirefox||s.isLegacyEdge?"bottom":"ideographic"},6171:(e,t)=>{function i(e){return 57508<=e&&e<=57558}Object.defineProperty(t,"__esModule",{value:!0}),t.createRenderDimensions=t.excludeFromContrastRatioDemands=t.isRestrictedPowerlineGlyph=t.isPowerlineGlyph=t.throwIfFalsy=void 0,t.throwIfFalsy=function(e){if(!e)throw new Error("value must not be falsy");return e},t.isPowerlineGlyph=i,t.isRestrictedPowerlineGlyph=function(e){return 57520<=e&&e<=57527},t.excludeFromContrastRatioDemands=function(e){return i(e)||function(e){return 9472<=e&&e<=9631}(e)},t.createRenderDimensions=function(){return{css:{canvas:{width:0,height:0},cell:{width:0,height:0}},device:{canvas:{width:0,height:0},cell:{width:0,height:0},char:{width:0,height:0,left:0,top:0}}}}},456:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.SelectionModel=void 0,t.SelectionModel=class{constructor(e){this._bufferService=e,this.isSelectAllActive=!1,this.selectionStartLength=0}clearSelection(){this.selectionStart=void 0,this.selectionEnd=void 0,this.isSelectAllActive=!1,this.selectionStartLength=0}get finalSelectionStart(){return this.isSelectAllActive?[0,0]:this.selectionEnd&&this.selectionStart&&this.areSelectionValuesReversed()?this.selectionEnd:this.selectionStart}get finalSelectionEnd(){if(this.isSelectAllActive)return[this._bufferService.cols,this._bufferService.buffer.ybase+this._bufferService.rows-1];if(this.selectionStart){if(!this.selectionEnd||this.areSelectionValuesReversed()){const e=this.selectionStart[0]+this.selectionStartLength;return e>this._bufferService.cols?e%this._bufferService.cols==0?[this._bufferService.cols,this.selectionStart[1]+Math.floor(e/this._bufferService.cols)-1]:[e%this._bufferService.cols,this.selectionStart[1]+Math.floor(e/this._bufferService.cols)]:[e,this.selectionStart[1]]}if(this.selectionStartLength&&this.selectionEnd[1]===this.selectionStart[1]){const e=this.selectionStart[0]+this.selectionStartLength;return e>this._bufferService.cols?[e%this._bufferService.cols,this.selectionStart[1]+Math.floor(e/this._bufferService.cols)]:[Math.max(e,this.selectionEnd[0]),this.selectionEnd[1]]}return this.selectionEnd}}areSelectionValuesReversed(){const e=this.selectionStart,t=this.selectionEnd;return!(!e||!t)&&(e[1]>t[1]||e[1]===t[1]&&e[0]>t[0])}handleTrim(e){return this.selectionStart&&(this.selectionStart[1]-=e),this.selectionEnd&&(this.selectionEnd[1]-=e),this.selectionEnd&&this.selectionEnd[1]<0?(this.clearSelection(),!0):(this.selectionStart&&this.selectionStart[1]<0&&(this.selectionStart[1]=0),!1)}}},428:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.CharSizeService=void 0;const n=i(2585),o=i(8460),a=i(844);let h=t.CharSizeService=class extends a.Disposable{get hasValidSize(){return this.width>0&&this.height>0}constructor(e,t,i){super(),this._optionsService=i,this.width=0,this.height=0,this._onCharSizeChange=this.register(new o.EventEmitter),this.onCharSizeChange=this._onCharSizeChange.event,this._measureStrategy=new c(e,t,this._optionsService),this.register(this._optionsService.onMultipleOptionChange(["fontFamily","fontSize"],(()=>this.measure())))}measure(){const e=this._measureStrategy.measure();e.width===this.width&&e.height===this.height||(this.width=e.width,this.height=e.height,this._onCharSizeChange.fire())}};t.CharSizeService=h=s([r(2,n.IOptionsService)],h);class c{constructor(e,t,i){this._document=e,this._parentElement=t,this._optionsService=i,this._result={width:0,height:0},this._measureElement=this._document.createElement("span"),this._measureElement.classList.add("xterm-char-measure-element"),this._measureElement.textContent="W".repeat(32),this._measureElement.setAttribute("aria-hidden","true"),this._measureElement.style.whiteSpace="pre",this._measureElement.style.fontKerning="none",this._parentElement.appendChild(this._measureElement)}measure(){this._measureElement.style.fontFamily=this._optionsService.rawOptions.fontFamily,this._measureElement.style.fontSize=`${this._optionsService.rawOptions.fontSize}px`;const e={height:Number(this._measureElement.offsetHeight),width:Number(this._measureElement.offsetWidth)};return 0!==e.width&&0!==e.height&&(this._result.width=e.width/32,this._result.height=Math.ceil(e.height)),this._result}}},4269:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.CharacterJoinerService=t.JoinedCellData=void 0;const n=i(3734),o=i(643),a=i(511),h=i(2585);class c extends n.AttributeData{constructor(e,t,i){super(),this.content=0,this.combinedData="",this.fg=e.fg,this.bg=e.bg,this.combinedData=t,this._width=i}isCombined(){return 2097152}getWidth(){return this._width}getChars(){return this.combinedData}getCode(){return 2097151}setFromCharData(e){throw new Error("not implemented")}getAsCharData(){return[this.fg,this.getChars(),this.getWidth(),this.getCode()]}}t.JoinedCellData=c;let l=t.CharacterJoinerService=class e{constructor(e){this._bufferService=e,this._characterJoiners=[],this._nextCharacterJoinerId=0,this._workCell=new a.CellData}register(e){const t={id:this._nextCharacterJoinerId++,handler:e};return this._characterJoiners.push(t),t.id}deregister(e){for(let t=0;t1){const e=this._getJoinedRanges(s,a,n,t,r);for(let t=0;t1){const e=this._getJoinedRanges(s,a,n,t,r);for(let t=0;t{Object.defineProperty(t,"__esModule",{value:!0}),t.CoreBrowserService=void 0,t.CoreBrowserService=class{constructor(e,t){this._textarea=e,this.window=t,this._isFocused=!1,this._cachedIsFocused=void 0,this._textarea.addEventListener("focus",(()=>this._isFocused=!0)),this._textarea.addEventListener("blur",(()=>this._isFocused=!1))}get dpr(){return this.window.devicePixelRatio}get isFocused(){return void 0===this._cachedIsFocused&&(this._cachedIsFocused=this._isFocused&&this._textarea.ownerDocument.hasFocus(),queueMicrotask((()=>this._cachedIsFocused=void 0))),this._cachedIsFocused}}},8934:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.MouseService=void 0;const n=i(4725),o=i(9806);let a=t.MouseService=class{constructor(e,t){this._renderService=e,this._charSizeService=t}getCoords(e,t,i,s,r){return(0,o.getCoords)(window,e,t,i,s,this._charSizeService.hasValidSize,this._renderService.dimensions.css.cell.width,this._renderService.dimensions.css.cell.height,r)}getMouseReportCoords(e,t){const i=(0,o.getCoordsRelativeToElement)(window,e,t);if(this._charSizeService.hasValidSize)return i[0]=Math.min(Math.max(i[0],0),this._renderService.dimensions.css.canvas.width-1),i[1]=Math.min(Math.max(i[1],0),this._renderService.dimensions.css.canvas.height-1),{col:Math.floor(i[0]/this._renderService.dimensions.css.cell.width),row:Math.floor(i[1]/this._renderService.dimensions.css.cell.height),x:Math.floor(i[0]),y:Math.floor(i[1])}}};t.MouseService=a=s([r(0,n.IRenderService),r(1,n.ICharSizeService)],a)},3230:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.RenderService=void 0;const n=i(3656),o=i(6193),a=i(5596),h=i(4725),c=i(8460),l=i(844),d=i(7226),_=i(2585);let u=t.RenderService=class extends l.Disposable{get dimensions(){return this._renderer.value.dimensions}constructor(e,t,i,s,r,h,_,u){if(super(),this._rowCount=e,this._charSizeService=s,this._renderer=this.register(new l.MutableDisposable),this._pausedResizeTask=new d.DebouncedIdleTask,this._isPaused=!1,this._needsFullRefresh=!1,this._isNextRenderRedrawOnly=!0,this._needsSelectionRefresh=!1,this._canvasWidth=0,this._canvasHeight=0,this._selectionState={start:void 0,end:void 0,columnSelectMode:!1},this._onDimensionsChange=this.register(new c.EventEmitter),this.onDimensionsChange=this._onDimensionsChange.event,this._onRenderedViewportChange=this.register(new c.EventEmitter),this.onRenderedViewportChange=this._onRenderedViewportChange.event,this._onRender=this.register(new c.EventEmitter),this.onRender=this._onRender.event,this._onRefreshRequest=this.register(new c.EventEmitter),this.onRefreshRequest=this._onRefreshRequest.event,this._renderDebouncer=new o.RenderDebouncer(_.window,((e,t)=>this._renderRows(e,t))),this.register(this._renderDebouncer),this._screenDprMonitor=new a.ScreenDprMonitor(_.window),this._screenDprMonitor.setListener((()=>this.handleDevicePixelRatioChange())),this.register(this._screenDprMonitor),this.register(h.onResize((()=>this._fullRefresh()))),this.register(h.buffers.onBufferActivate((()=>{var e;return null===(e=this._renderer.value)||void 0===e?void 0:e.clear()}))),this.register(i.onOptionChange((()=>this._handleOptionsChanged()))),this.register(this._charSizeService.onCharSizeChange((()=>this.handleCharSizeChanged()))),this.register(r.onDecorationRegistered((()=>this._fullRefresh()))),this.register(r.onDecorationRemoved((()=>this._fullRefresh()))),this.register(i.onMultipleOptionChange(["customGlyphs","drawBoldTextInBrightColors","letterSpacing","lineHeight","fontFamily","fontSize","fontWeight","fontWeightBold","minimumContrastRatio"],(()=>{this.clear(),this.handleResize(h.cols,h.rows),this._fullRefresh()}))),this.register(i.onMultipleOptionChange(["cursorBlink","cursorStyle"],(()=>this.refreshRows(h.buffer.y,h.buffer.y,!0)))),this.register((0,n.addDisposableDomListener)(_.window,"resize",(()=>this.handleDevicePixelRatioChange()))),this.register(u.onChangeColors((()=>this._fullRefresh()))),"IntersectionObserver"in _.window){const e=new _.window.IntersectionObserver((e=>this._handleIntersectionChange(e[e.length-1])),{threshold:0});e.observe(t),this.register({dispose:()=>e.disconnect()})}}_handleIntersectionChange(e){this._isPaused=void 0===e.isIntersecting?0===e.intersectionRatio:!e.isIntersecting,this._isPaused||this._charSizeService.hasValidSize||this._charSizeService.measure(),!this._isPaused&&this._needsFullRefresh&&(this._pausedResizeTask.flush(),this.refreshRows(0,this._rowCount-1),this._needsFullRefresh=!1)}refreshRows(e,t,i=!1){this._isPaused?this._needsFullRefresh=!0:(i||(this._isNextRenderRedrawOnly=!1),this._renderDebouncer.refresh(e,t,this._rowCount))}_renderRows(e,t){this._renderer.value&&(e=Math.min(e,this._rowCount-1),t=Math.min(t,this._rowCount-1),this._renderer.value.renderRows(e,t),this._needsSelectionRefresh&&(this._renderer.value.handleSelectionChanged(this._selectionState.start,this._selectionState.end,this._selectionState.columnSelectMode),this._needsSelectionRefresh=!1),this._isNextRenderRedrawOnly||this._onRenderedViewportChange.fire({start:e,end:t}),this._onRender.fire({start:e,end:t}),this._isNextRenderRedrawOnly=!0)}resize(e,t){this._rowCount=t,this._fireOnCanvasResize()}_handleOptionsChanged(){this._renderer.value&&(this.refreshRows(0,this._rowCount-1),this._fireOnCanvasResize())}_fireOnCanvasResize(){this._renderer.value&&(this._renderer.value.dimensions.css.canvas.width===this._canvasWidth&&this._renderer.value.dimensions.css.canvas.height===this._canvasHeight||this._onDimensionsChange.fire(this._renderer.value.dimensions))}hasRenderer(){return!!this._renderer.value}setRenderer(e){this._renderer.value=e,this._renderer.value.onRequestRedraw((e=>this.refreshRows(e.start,e.end,!0))),this._needsSelectionRefresh=!0,this._fullRefresh()}addRefreshCallback(e){return this._renderDebouncer.addRefreshCallback(e)}_fullRefresh(){this._isPaused?this._needsFullRefresh=!0:this.refreshRows(0,this._rowCount-1)}clearTextureAtlas(){var e,t;this._renderer.value&&(null===(t=(e=this._renderer.value).clearTextureAtlas)||void 0===t||t.call(e),this._fullRefresh())}handleDevicePixelRatioChange(){this._charSizeService.measure(),this._renderer.value&&(this._renderer.value.handleDevicePixelRatioChange(),this.refreshRows(0,this._rowCount-1))}handleResize(e,t){this._renderer.value&&(this._isPaused?this._pausedResizeTask.set((()=>this._renderer.value.handleResize(e,t))):this._renderer.value.handleResize(e,t),this._fullRefresh())}handleCharSizeChanged(){var e;null===(e=this._renderer.value)||void 0===e||e.handleCharSizeChanged()}handleBlur(){var e;null===(e=this._renderer.value)||void 0===e||e.handleBlur()}handleFocus(){var e;null===(e=this._renderer.value)||void 0===e||e.handleFocus()}handleSelectionChanged(e,t,i){var s;this._selectionState.start=e,this._selectionState.end=t,this._selectionState.columnSelectMode=i,null===(s=this._renderer.value)||void 0===s||s.handleSelectionChanged(e,t,i)}handleCursorMove(){var e;null===(e=this._renderer.value)||void 0===e||e.handleCursorMove()}clear(){var e;null===(e=this._renderer.value)||void 0===e||e.clear()}};t.RenderService=u=s([r(2,_.IOptionsService),r(3,h.ICharSizeService),r(4,_.IDecorationService),r(5,_.IBufferService),r(6,h.ICoreBrowserService),r(7,h.IThemeService)],u)},9312:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.SelectionService=void 0;const n=i(9806),o=i(9504),a=i(456),h=i(4725),c=i(8460),l=i(844),d=i(6114),_=i(4841),u=i(511),f=i(2585),v=String.fromCharCode(160),p=new RegExp(v,"g");let g=t.SelectionService=class extends l.Disposable{constructor(e,t,i,s,r,n,o,h,d){super(),this._element=e,this._screenElement=t,this._linkifier=i,this._bufferService=s,this._coreService=r,this._mouseService=n,this._optionsService=o,this._renderService=h,this._coreBrowserService=d,this._dragScrollAmount=0,this._enabled=!0,this._workCell=new u.CellData,this._mouseDownTimeStamp=0,this._oldHasSelection=!1,this._oldSelectionStart=void 0,this._oldSelectionEnd=void 0,this._onLinuxMouseSelection=this.register(new c.EventEmitter),this.onLinuxMouseSelection=this._onLinuxMouseSelection.event,this._onRedrawRequest=this.register(new c.EventEmitter),this.onRequestRedraw=this._onRedrawRequest.event,this._onSelectionChange=this.register(new c.EventEmitter),this.onSelectionChange=this._onSelectionChange.event,this._onRequestScrollLines=this.register(new c.EventEmitter),this.onRequestScrollLines=this._onRequestScrollLines.event,this._mouseMoveListener=e=>this._handleMouseMove(e),this._mouseUpListener=e=>this._handleMouseUp(e),this._coreService.onUserInput((()=>{this.hasSelection&&this.clearSelection()})),this._trimListener=this._bufferService.buffer.lines.onTrim((e=>this._handleTrim(e))),this.register(this._bufferService.buffers.onBufferActivate((e=>this._handleBufferActivate(e)))),this.enable(),this._model=new a.SelectionModel(this._bufferService),this._activeSelectionMode=0,this.register((0,l.toDisposable)((()=>{this._removeMouseDownListeners()})))}reset(){this.clearSelection()}disable(){this.clearSelection(),this._enabled=!1}enable(){this._enabled=!0}get selectionStart(){return this._model.finalSelectionStart}get selectionEnd(){return this._model.finalSelectionEnd}get hasSelection(){const e=this._model.finalSelectionStart,t=this._model.finalSelectionEnd;return!(!e||!t||e[0]===t[0]&&e[1]===t[1])}get selectionText(){const e=this._model.finalSelectionStart,t=this._model.finalSelectionEnd;if(!e||!t)return"";const i=this._bufferService.buffer,s=[];if(3===this._activeSelectionMode){if(e[0]===t[0])return"";const r=e[0]e.replace(p," "))).join(d.isWindows?"\r\n":"\n")}clearSelection(){this._model.clearSelection(),this._removeMouseDownListeners(),this.refresh(),this._onSelectionChange.fire()}refresh(e){this._refreshAnimationFrame||(this._refreshAnimationFrame=this._coreBrowserService.window.requestAnimationFrame((()=>this._refresh()))),d.isLinux&&e&&this.selectionText.length&&this._onLinuxMouseSelection.fire(this.selectionText)}_refresh(){this._refreshAnimationFrame=void 0,this._onRedrawRequest.fire({start:this._model.finalSelectionStart,end:this._model.finalSelectionEnd,columnSelectMode:3===this._activeSelectionMode})}_isClickInSelection(e){const t=this._getMouseBufferCoords(e),i=this._model.finalSelectionStart,s=this._model.finalSelectionEnd;return!!(i&&s&&t)&&this._areCoordsInSelection(t,i,s)}isCellInSelection(e,t){const i=this._model.finalSelectionStart,s=this._model.finalSelectionEnd;return!(!i||!s)&&this._areCoordsInSelection([e,t],i,s)}_areCoordsInSelection(e,t,i){return e[1]>t[1]&&e[1]=t[0]&&e[0]=t[0]}_selectWordAtCursor(e,t){var i,s;const r=null===(s=null===(i=this._linkifier.currentLink)||void 0===i?void 0:i.link)||void 0===s?void 0:s.range;if(r)return this._model.selectionStart=[r.start.x-1,r.start.y-1],this._model.selectionStartLength=(0,_.getRangeLength)(r,this._bufferService.cols),this._model.selectionEnd=void 0,!0;const n=this._getMouseBufferCoords(e);return!!n&&(this._selectWordAt(n,t),this._model.selectionEnd=void 0,!0)}selectAll(){this._model.isSelectAllActive=!0,this.refresh(),this._onSelectionChange.fire()}selectLines(e,t){this._model.clearSelection(),e=Math.max(e,0),t=Math.min(t,this._bufferService.buffer.lines.length-1),this._model.selectionStart=[0,e],this._model.selectionEnd=[this._bufferService.cols,t],this.refresh(),this._onSelectionChange.fire()}_handleTrim(e){this._model.handleTrim(e)&&this.refresh()}_getMouseBufferCoords(e){const t=this._mouseService.getCoords(e,this._screenElement,this._bufferService.cols,this._bufferService.rows,!0);if(t)return t[0]--,t[1]--,t[1]+=this._bufferService.buffer.ydisp,t}_getMouseEventScrollAmount(e){let t=(0,n.getCoordsRelativeToElement)(this._coreBrowserService.window,e,this._screenElement)[1];const i=this._renderService.dimensions.css.canvas.height;return t>=0&&t<=i?0:(t>i&&(t-=i),t=Math.min(Math.max(t,-50),50),t/=50,t/Math.abs(t)+Math.round(14*t))}shouldForceSelection(e){return d.isMac?e.altKey&&this._optionsService.rawOptions.macOptionClickForcesSelection:e.shiftKey}handleMouseDown(e){if(this._mouseDownTimeStamp=e.timeStamp,(2!==e.button||!this.hasSelection)&&0===e.button){if(!this._enabled){if(!this.shouldForceSelection(e))return;e.stopPropagation()}e.preventDefault(),this._dragScrollAmount=0,this._enabled&&e.shiftKey?this._handleIncrementalClick(e):1===e.detail?this._handleSingleClick(e):2===e.detail?this._handleDoubleClick(e):3===e.detail&&this._handleTripleClick(e),this._addMouseDownListeners(),this.refresh(!0)}}_addMouseDownListeners(){this._screenElement.ownerDocument&&(this._screenElement.ownerDocument.addEventListener("mousemove",this._mouseMoveListener),this._screenElement.ownerDocument.addEventListener("mouseup",this._mouseUpListener)),this._dragScrollIntervalTimer=this._coreBrowserService.window.setInterval((()=>this._dragScroll()),50)}_removeMouseDownListeners(){this._screenElement.ownerDocument&&(this._screenElement.ownerDocument.removeEventListener("mousemove",this._mouseMoveListener),this._screenElement.ownerDocument.removeEventListener("mouseup",this._mouseUpListener)),this._coreBrowserService.window.clearInterval(this._dragScrollIntervalTimer),this._dragScrollIntervalTimer=void 0}_handleIncrementalClick(e){this._model.selectionStart&&(this._model.selectionEnd=this._getMouseBufferCoords(e))}_handleSingleClick(e){if(this._model.selectionStartLength=0,this._model.isSelectAllActive=!1,this._activeSelectionMode=this.shouldColumnSelect(e)?3:0,this._model.selectionStart=this._getMouseBufferCoords(e),!this._model.selectionStart)return;this._model.selectionEnd=void 0;const t=this._bufferService.buffer.lines.get(this._model.selectionStart[1]);t&&t.length!==this._model.selectionStart[0]&&0===t.hasWidth(this._model.selectionStart[0])&&this._model.selectionStart[0]++}_handleDoubleClick(e){this._selectWordAtCursor(e,!0)&&(this._activeSelectionMode=1)}_handleTripleClick(e){const t=this._getMouseBufferCoords(e);t&&(this._activeSelectionMode=2,this._selectLineAt(t[1]))}shouldColumnSelect(e){return e.altKey&&!(d.isMac&&this._optionsService.rawOptions.macOptionClickForcesSelection)}_handleMouseMove(e){if(e.stopImmediatePropagation(),!this._model.selectionStart)return;const t=this._model.selectionEnd?[this._model.selectionEnd[0],this._model.selectionEnd[1]]:null;if(this._model.selectionEnd=this._getMouseBufferCoords(e),!this._model.selectionEnd)return void this.refresh(!0);2===this._activeSelectionMode?this._model.selectionEnd[1]0?this._model.selectionEnd[0]=this._bufferService.cols:this._dragScrollAmount<0&&(this._model.selectionEnd[0]=0));const i=this._bufferService.buffer;if(this._model.selectionEnd[1]0?(3!==this._activeSelectionMode&&(this._model.selectionEnd[0]=this._bufferService.cols),this._model.selectionEnd[1]=Math.min(e.ydisp+this._bufferService.rows,e.lines.length-1)):(3!==this._activeSelectionMode&&(this._model.selectionEnd[0]=0),this._model.selectionEnd[1]=e.ydisp),this.refresh()}}_handleMouseUp(e){const t=e.timeStamp-this._mouseDownTimeStamp;if(this._removeMouseDownListeners(),this.selectionText.length<=1&&t<500&&e.altKey&&this._optionsService.rawOptions.altClickMovesCursor){if(this._bufferService.buffer.ybase===this._bufferService.buffer.ydisp){const t=this._mouseService.getCoords(e,this._element,this._bufferService.cols,this._bufferService.rows,!1);if(t&&void 0!==t[0]&&void 0!==t[1]){const e=(0,o.moveToCellSequence)(t[0]-1,t[1]-1,this._bufferService,this._coreService.decPrivateModes.applicationCursorKeys);this._coreService.triggerDataEvent(e,!0)}}}else this._fireEventIfSelectionChanged()}_fireEventIfSelectionChanged(){const e=this._model.finalSelectionStart,t=this._model.finalSelectionEnd,i=!(!e||!t||e[0]===t[0]&&e[1]===t[1]);i?e&&t&&(this._oldSelectionStart&&this._oldSelectionEnd&&e[0]===this._oldSelectionStart[0]&&e[1]===this._oldSelectionStart[1]&&t[0]===this._oldSelectionEnd[0]&&t[1]===this._oldSelectionEnd[1]||this._fireOnSelectionChange(e,t,i)):this._oldHasSelection&&this._fireOnSelectionChange(e,t,i)}_fireOnSelectionChange(e,t,i){this._oldSelectionStart=e,this._oldSelectionEnd=t,this._oldHasSelection=i,this._onSelectionChange.fire()}_handleBufferActivate(e){this.clearSelection(),this._trimListener.dispose(),this._trimListener=e.activeBuffer.lines.onTrim((e=>this._handleTrim(e)))}_convertViewportColToCharacterIndex(e,t){let i=t;for(let s=0;t>=s;s++){const r=e.loadCell(s,this._workCell).getChars().length;0===this._workCell.getWidth()?i--:r>1&&t!==s&&(i+=r-1)}return i}setSelection(e,t,i){this._model.clearSelection(),this._removeMouseDownListeners(),this._model.selectionStart=[e,t],this._model.selectionStartLength=i,this.refresh(),this._fireEventIfSelectionChanged()}rightClickSelect(e){this._isClickInSelection(e)||(this._selectWordAtCursor(e,!1)&&this.refresh(!0),this._fireEventIfSelectionChanged())}_getWordAt(e,t,i=!0,s=!0){if(e[0]>=this._bufferService.cols)return;const r=this._bufferService.buffer,n=r.lines.get(e[1]);if(!n)return;const o=r.translateBufferLineToString(e[1],!1);let a=this._convertViewportColToCharacterIndex(n,e[0]),h=a;const c=e[0]-a;let l=0,d=0,_=0,u=0;if(" "===o.charAt(a)){for(;a>0&&" "===o.charAt(a-1);)a--;for(;h1&&(u+=s-1,h+=s-1);t>0&&a>0&&!this._isCharWordSeparator(n.loadCell(t-1,this._workCell));){n.loadCell(t-1,this._workCell);const e=this._workCell.getChars().length;0===this._workCell.getWidth()?(l++,t--):e>1&&(_+=e-1,a-=e-1),a--,t--}for(;i1&&(u+=e-1,h+=e-1),h++,i++}}h++;let f=a+c-l+_,v=Math.min(this._bufferService.cols,h-a+l+d-_-u);if(t||""!==o.slice(a,h).trim()){if(i&&0===f&&32!==n.getCodePoint(0)){const t=r.lines.get(e[1]-1);if(t&&n.isWrapped&&32!==t.getCodePoint(this._bufferService.cols-1)){const t=this._getWordAt([this._bufferService.cols-1,e[1]-1],!1,!0,!1);if(t){const e=this._bufferService.cols-t.start;f-=e,v+=e}}}if(s&&f+v===this._bufferService.cols&&32!==n.getCodePoint(this._bufferService.cols-1)){const t=r.lines.get(e[1]+1);if((null==t?void 0:t.isWrapped)&&32!==t.getCodePoint(0)){const t=this._getWordAt([0,e[1]+1],!1,!1,!0);t&&(v+=t.length)}}return{start:f,length:v}}}_selectWordAt(e,t){const i=this._getWordAt(e,t);if(i){for(;i.start<0;)i.start+=this._bufferService.cols,e[1]--;this._model.selectionStart=[i.start,e[1]],this._model.selectionStartLength=i.length}}_selectToWordAt(e){const t=this._getWordAt(e,!0);if(t){let i=e[1];for(;t.start<0;)t.start+=this._bufferService.cols,i--;if(!this._model.areSelectionValuesReversed())for(;t.start+t.length>this._bufferService.cols;)t.length-=this._bufferService.cols,i++;this._model.selectionEnd=[this._model.areSelectionValuesReversed()?t.start:t.start+t.length,i]}}_isCharWordSeparator(e){return 0!==e.getWidth()&&this._optionsService.rawOptions.wordSeparator.indexOf(e.getChars())>=0}_selectLineAt(e){const t=this._bufferService.buffer.getWrappedRangeForLine(e),i={start:{x:0,y:t.first},end:{x:this._bufferService.cols-1,y:t.last}};this._model.selectionStart=[0,t.first],this._model.selectionEnd=void 0,this._model.selectionStartLength=(0,_.getRangeLength)(i,this._bufferService.cols)}};t.SelectionService=g=s([r(3,f.IBufferService),r(4,f.ICoreService),r(5,h.IMouseService),r(6,f.IOptionsService),r(7,h.IRenderService),r(8,h.ICoreBrowserService)],g)},4725:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.IThemeService=t.ICharacterJoinerService=t.ISelectionService=t.IRenderService=t.IMouseService=t.ICoreBrowserService=t.ICharSizeService=void 0;const s=i(8343);t.ICharSizeService=(0,s.createDecorator)("CharSizeService"),t.ICoreBrowserService=(0,s.createDecorator)("CoreBrowserService"),t.IMouseService=(0,s.createDecorator)("MouseService"),t.IRenderService=(0,s.createDecorator)("RenderService"),t.ISelectionService=(0,s.createDecorator)("SelectionService"),t.ICharacterJoinerService=(0,s.createDecorator)("CharacterJoinerService"),t.IThemeService=(0,s.createDecorator)("ThemeService")},6731:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.ThemeService=t.DEFAULT_ANSI_COLORS=void 0;const n=i(7239),o=i(8055),a=i(8460),h=i(844),c=i(2585),l=o.css.toColor("#ffffff"),d=o.css.toColor("#000000"),_=o.css.toColor("#ffffff"),u=o.css.toColor("#000000"),f={css:"rgba(255, 255, 255, 0.3)",rgba:4294967117};t.DEFAULT_ANSI_COLORS=Object.freeze((()=>{const e=[o.css.toColor("#2e3436"),o.css.toColor("#cc0000"),o.css.toColor("#4e9a06"),o.css.toColor("#c4a000"),o.css.toColor("#3465a4"),o.css.toColor("#75507b"),o.css.toColor("#06989a"),o.css.toColor("#d3d7cf"),o.css.toColor("#555753"),o.css.toColor("#ef2929"),o.css.toColor("#8ae234"),o.css.toColor("#fce94f"),o.css.toColor("#729fcf"),o.css.toColor("#ad7fa8"),o.css.toColor("#34e2e2"),o.css.toColor("#eeeeec")],t=[0,95,135,175,215,255];for(let i=0;i<216;i++){const s=t[i/36%6|0],r=t[i/6%6|0],n=t[i%6];e.push({css:o.channels.toCss(s,r,n),rgba:o.channels.toRgba(s,r,n)})}for(let t=0;t<24;t++){const i=8+10*t;e.push({css:o.channels.toCss(i,i,i),rgba:o.channels.toRgba(i,i,i)})}return e})());let v=t.ThemeService=class extends h.Disposable{get colors(){return this._colors}constructor(e){super(),this._optionsService=e,this._contrastCache=new n.ColorContrastCache,this._halfContrastCache=new n.ColorContrastCache,this._onChangeColors=this.register(new a.EventEmitter),this.onChangeColors=this._onChangeColors.event,this._colors={foreground:l,background:d,cursor:_,cursorAccent:u,selectionForeground:void 0,selectionBackgroundTransparent:f,selectionBackgroundOpaque:o.color.blend(d,f),selectionInactiveBackgroundTransparent:f,selectionInactiveBackgroundOpaque:o.color.blend(d,f),ansi:t.DEFAULT_ANSI_COLORS.slice(),contrastCache:this._contrastCache,halfContrastCache:this._halfContrastCache},this._updateRestoreColors(),this._setTheme(this._optionsService.rawOptions.theme),this.register(this._optionsService.onSpecificOptionChange("minimumContrastRatio",(()=>this._contrastCache.clear()))),this.register(this._optionsService.onSpecificOptionChange("theme",(()=>this._setTheme(this._optionsService.rawOptions.theme))))}_setTheme(e={}){const i=this._colors;if(i.foreground=p(e.foreground,l),i.background=p(e.background,d),i.cursor=p(e.cursor,_),i.cursorAccent=p(e.cursorAccent,u),i.selectionBackgroundTransparent=p(e.selectionBackground,f),i.selectionBackgroundOpaque=o.color.blend(i.background,i.selectionBackgroundTransparent),i.selectionInactiveBackgroundTransparent=p(e.selectionInactiveBackground,i.selectionBackgroundTransparent),i.selectionInactiveBackgroundOpaque=o.color.blend(i.background,i.selectionInactiveBackgroundTransparent),i.selectionForeground=e.selectionForeground?p(e.selectionForeground,o.NULL_COLOR):void 0,i.selectionForeground===o.NULL_COLOR&&(i.selectionForeground=void 0),o.color.isOpaque(i.selectionBackgroundTransparent)){const e=.3;i.selectionBackgroundTransparent=o.color.opacity(i.selectionBackgroundTransparent,e)}if(o.color.isOpaque(i.selectionInactiveBackgroundTransparent)){const e=.3;i.selectionInactiveBackgroundTransparent=o.color.opacity(i.selectionInactiveBackgroundTransparent,e)}if(i.ansi=t.DEFAULT_ANSI_COLORS.slice(),i.ansi[0]=p(e.black,t.DEFAULT_ANSI_COLORS[0]),i.ansi[1]=p(e.red,t.DEFAULT_ANSI_COLORS[1]),i.ansi[2]=p(e.green,t.DEFAULT_ANSI_COLORS[2]),i.ansi[3]=p(e.yellow,t.DEFAULT_ANSI_COLORS[3]),i.ansi[4]=p(e.blue,t.DEFAULT_ANSI_COLORS[4]),i.ansi[5]=p(e.magenta,t.DEFAULT_ANSI_COLORS[5]),i.ansi[6]=p(e.cyan,t.DEFAULT_ANSI_COLORS[6]),i.ansi[7]=p(e.white,t.DEFAULT_ANSI_COLORS[7]),i.ansi[8]=p(e.brightBlack,t.DEFAULT_ANSI_COLORS[8]),i.ansi[9]=p(e.brightRed,t.DEFAULT_ANSI_COLORS[9]),i.ansi[10]=p(e.brightGreen,t.DEFAULT_ANSI_COLORS[10]),i.ansi[11]=p(e.brightYellow,t.DEFAULT_ANSI_COLORS[11]),i.ansi[12]=p(e.brightBlue,t.DEFAULT_ANSI_COLORS[12]),i.ansi[13]=p(e.brightMagenta,t.DEFAULT_ANSI_COLORS[13]),i.ansi[14]=p(e.brightCyan,t.DEFAULT_ANSI_COLORS[14]),i.ansi[15]=p(e.brightWhite,t.DEFAULT_ANSI_COLORS[15]),e.extendedAnsi){const s=Math.min(i.ansi.length-16,e.extendedAnsi.length);for(let r=0;r{Object.defineProperty(t,"__esModule",{value:!0}),t.CircularList=void 0;const s=i(8460),r=i(844);class n extends r.Disposable{constructor(e){super(),this._maxLength=e,this.onDeleteEmitter=this.register(new s.EventEmitter),this.onDelete=this.onDeleteEmitter.event,this.onInsertEmitter=this.register(new s.EventEmitter),this.onInsert=this.onInsertEmitter.event,this.onTrimEmitter=this.register(new s.EventEmitter),this.onTrim=this.onTrimEmitter.event,this._array=new Array(this._maxLength),this._startIndex=0,this._length=0}get maxLength(){return this._maxLength}set maxLength(e){if(this._maxLength===e)return;const t=new Array(e);for(let i=0;ithis._length)for(let t=this._length;t=e;t--)this._array[this._getCyclicIndex(t+i.length)]=this._array[this._getCyclicIndex(t)];for(let t=0;tthis._maxLength){const e=this._length+i.length-this._maxLength;this._startIndex+=e,this._length=this._maxLength,this.onTrimEmitter.fire(e)}else this._length+=i.length}trimStart(e){e>this._length&&(e=this._length),this._startIndex+=e,this._length-=e,this.onTrimEmitter.fire(e)}shiftElements(e,t,i){if(!(t<=0)){if(e<0||e>=this._length)throw new Error("start argument out of range");if(e+i<0)throw new Error("Cannot shift elements in list beyond index 0");if(i>0){for(let s=t-1;s>=0;s--)this.set(e+s+i,this.get(e+s));const s=e+t+i-this._length;if(s>0)for(this._length+=s;this._length>this._maxLength;)this._length--,this._startIndex++,this.onTrimEmitter.fire(1)}else for(let s=0;s{Object.defineProperty(t,"__esModule",{value:!0}),t.clone=void 0,t.clone=function e(t,i=5){if("object"!=typeof t)return t;const s=Array.isArray(t)?[]:{};for(const r in t)s[r]=i<=1?t[r]:t[r]&&e(t[r],i-1);return s}},8055:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.contrastRatio=t.toPaddedHex=t.rgba=t.rgb=t.css=t.color=t.channels=t.NULL_COLOR=void 0;const s=i(6114);let r=0,n=0,o=0,a=0;var h,c,l,d,_;function u(e){const t=e.toString(16);return t.length<2?"0"+t:t}function f(e,t){return e>>0}}(h||(t.channels=h={})),function(e){function t(e,t){return a=Math.round(255*t),[r,n,o]=_.toChannels(e.rgba),{css:h.toCss(r,n,o,a),rgba:h.toRgba(r,n,o,a)}}e.blend=function(e,t){if(a=(255&t.rgba)/255,1===a)return{css:t.css,rgba:t.rgba};const i=t.rgba>>24&255,s=t.rgba>>16&255,c=t.rgba>>8&255,l=e.rgba>>24&255,d=e.rgba>>16&255,_=e.rgba>>8&255;return r=l+Math.round((i-l)*a),n=d+Math.round((s-d)*a),o=_+Math.round((c-_)*a),{css:h.toCss(r,n,o),rgba:h.toRgba(r,n,o)}},e.isOpaque=function(e){return 255==(255&e.rgba)},e.ensureContrastRatio=function(e,t,i){const s=_.ensureContrastRatio(e.rgba,t.rgba,i);if(s)return _.toColor(s>>24&255,s>>16&255,s>>8&255)},e.opaque=function(e){const t=(255|e.rgba)>>>0;return[r,n,o]=_.toChannels(t),{css:h.toCss(r,n,o),rgba:t}},e.opacity=t,e.multiplyOpacity=function(e,i){return a=255&e.rgba,t(e,a*i/255)},e.toColorRGB=function(e){return[e.rgba>>24&255,e.rgba>>16&255,e.rgba>>8&255]}}(c||(t.color=c={})),function(e){let t,i;if(!s.isNode){const e=document.createElement("canvas");e.width=1,e.height=1;const s=e.getContext("2d",{willReadFrequently:!0});s&&(t=s,t.globalCompositeOperation="copy",i=t.createLinearGradient(0,0,1,1))}e.toColor=function(e){if(e.match(/#[\da-f]{3,8}/i))switch(e.length){case 4:return r=parseInt(e.slice(1,2).repeat(2),16),n=parseInt(e.slice(2,3).repeat(2),16),o=parseInt(e.slice(3,4).repeat(2),16),_.toColor(r,n,o);case 5:return r=parseInt(e.slice(1,2).repeat(2),16),n=parseInt(e.slice(2,3).repeat(2),16),o=parseInt(e.slice(3,4).repeat(2),16),a=parseInt(e.slice(4,5).repeat(2),16),_.toColor(r,n,o,a);case 7:return{css:e,rgba:(parseInt(e.slice(1),16)<<8|255)>>>0};case 9:return{css:e,rgba:parseInt(e.slice(1),16)>>>0}}const s=e.match(/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(,\s*(0|1|\d?\.(\d+))\s*)?\)/);if(s)return r=parseInt(s[1]),n=parseInt(s[2]),o=parseInt(s[3]),a=Math.round(255*(void 0===s[5]?1:parseFloat(s[5]))),_.toColor(r,n,o,a);if(!t||!i)throw new Error("css.toColor: Unsupported css format");if(t.fillStyle=i,t.fillStyle=e,"string"!=typeof t.fillStyle)throw new Error("css.toColor: Unsupported css format");if(t.fillRect(0,0,1,1),[r,n,o,a]=t.getImageData(0,0,1,1).data,255!==a)throw new Error("css.toColor: Unsupported css format");return{rgba:h.toRgba(r,n,o,a),css:e}}}(l||(t.css=l={})),function(e){function t(e,t,i){const s=e/255,r=t/255,n=i/255;return.2126*(s<=.03928?s/12.92:Math.pow((s+.055)/1.055,2.4))+.7152*(r<=.03928?r/12.92:Math.pow((r+.055)/1.055,2.4))+.0722*(n<=.03928?n/12.92:Math.pow((n+.055)/1.055,2.4))}e.relativeLuminance=function(e){return t(e>>16&255,e>>8&255,255&e)},e.relativeLuminance2=t}(d||(t.rgb=d={})),function(e){function t(e,t,i){const s=e>>24&255,r=e>>16&255,n=e>>8&255;let o=t>>24&255,a=t>>16&255,h=t>>8&255,c=f(d.relativeLuminance2(o,a,h),d.relativeLuminance2(s,r,n));for(;c0||a>0||h>0);)o-=Math.max(0,Math.ceil(.1*o)),a-=Math.max(0,Math.ceil(.1*a)),h-=Math.max(0,Math.ceil(.1*h)),c=f(d.relativeLuminance2(o,a,h),d.relativeLuminance2(s,r,n));return(o<<24|a<<16|h<<8|255)>>>0}function i(e,t,i){const s=e>>24&255,r=e>>16&255,n=e>>8&255;let o=t>>24&255,a=t>>16&255,h=t>>8&255,c=f(d.relativeLuminance2(o,a,h),d.relativeLuminance2(s,r,n));for(;c>>0}e.ensureContrastRatio=function(e,s,r){const n=d.relativeLuminance(e>>8),o=d.relativeLuminance(s>>8);if(f(n,o)>8));if(af(n,d.relativeLuminance(t>>8))?o:t}return o}const a=i(e,s,r),h=f(n,d.relativeLuminance(a>>8));if(hf(n,d.relativeLuminance(i>>8))?a:i}return a}},e.reduceLuminance=t,e.increaseLuminance=i,e.toChannels=function(e){return[e>>24&255,e>>16&255,e>>8&255,255&e]},e.toColor=function(e,t,i,s){return{css:h.toCss(e,t,i,s),rgba:h.toRgba(e,t,i,s)}}}(_||(t.rgba=_={})),t.toPaddedHex=u,t.contrastRatio=f},8969:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.CoreTerminal=void 0;const s=i(844),r=i(2585),n=i(4348),o=i(7866),a=i(744),h=i(7302),c=i(6975),l=i(8460),d=i(1753),_=i(1480),u=i(7994),f=i(9282),v=i(5435),p=i(5981),g=i(2660);let m=!1;class S extends s.Disposable{get onScroll(){return this._onScrollApi||(this._onScrollApi=this.register(new l.EventEmitter),this._onScroll.event((e=>{var t;null===(t=this._onScrollApi)||void 0===t||t.fire(e.position)}))),this._onScrollApi.event}get cols(){return this._bufferService.cols}get rows(){return this._bufferService.rows}get buffers(){return this._bufferService.buffers}get options(){return this.optionsService.options}set options(e){for(const t in e)this.optionsService.options[t]=e[t]}constructor(e){super(),this._windowsWrappingHeuristics=this.register(new s.MutableDisposable),this._onBinary=this.register(new l.EventEmitter),this.onBinary=this._onBinary.event,this._onData=this.register(new l.EventEmitter),this.onData=this._onData.event,this._onLineFeed=this.register(new l.EventEmitter),this.onLineFeed=this._onLineFeed.event,this._onResize=this.register(new l.EventEmitter),this.onResize=this._onResize.event,this._onWriteParsed=this.register(new l.EventEmitter),this.onWriteParsed=this._onWriteParsed.event,this._onScroll=this.register(new l.EventEmitter),this._instantiationService=new n.InstantiationService,this.optionsService=this.register(new h.OptionsService(e)),this._instantiationService.setService(r.IOptionsService,this.optionsService),this._bufferService=this.register(this._instantiationService.createInstance(a.BufferService)),this._instantiationService.setService(r.IBufferService,this._bufferService),this._logService=this.register(this._instantiationService.createInstance(o.LogService)),this._instantiationService.setService(r.ILogService,this._logService),this.coreService=this.register(this._instantiationService.createInstance(c.CoreService)),this._instantiationService.setService(r.ICoreService,this.coreService),this.coreMouseService=this.register(this._instantiationService.createInstance(d.CoreMouseService)),this._instantiationService.setService(r.ICoreMouseService,this.coreMouseService),this.unicodeService=this.register(this._instantiationService.createInstance(_.UnicodeService)),this._instantiationService.setService(r.IUnicodeService,this.unicodeService),this._charsetService=this._instantiationService.createInstance(u.CharsetService),this._instantiationService.setService(r.ICharsetService,this._charsetService),this._oscLinkService=this._instantiationService.createInstance(g.OscLinkService),this._instantiationService.setService(r.IOscLinkService,this._oscLinkService),this._inputHandler=this.register(new v.InputHandler(this._bufferService,this._charsetService,this.coreService,this._logService,this.optionsService,this._oscLinkService,this.coreMouseService,this.unicodeService)),this.register((0,l.forwardEvent)(this._inputHandler.onLineFeed,this._onLineFeed)),this.register(this._inputHandler),this.register((0,l.forwardEvent)(this._bufferService.onResize,this._onResize)),this.register((0,l.forwardEvent)(this.coreService.onData,this._onData)),this.register((0,l.forwardEvent)(this.coreService.onBinary,this._onBinary)),this.register(this.coreService.onRequestScrollToBottom((()=>this.scrollToBottom()))),this.register(this.coreService.onUserInput((()=>this._writeBuffer.handleUserInput()))),this.register(this.optionsService.onMultipleOptionChange(["windowsMode","windowsPty"],(()=>this._handleWindowsPtyOptionChange()))),this.register(this._bufferService.onScroll((e=>{this._onScroll.fire({position:this._bufferService.buffer.ydisp,source:0}),this._inputHandler.markRangeDirty(this._bufferService.buffer.scrollTop,this._bufferService.buffer.scrollBottom)}))),this.register(this._inputHandler.onScroll((e=>{this._onScroll.fire({position:this._bufferService.buffer.ydisp,source:0}),this._inputHandler.markRangeDirty(this._bufferService.buffer.scrollTop,this._bufferService.buffer.scrollBottom)}))),this._writeBuffer=this.register(new p.WriteBuffer(((e,t)=>this._inputHandler.parse(e,t)))),this.register((0,l.forwardEvent)(this._writeBuffer.onWriteParsed,this._onWriteParsed))}write(e,t){this._writeBuffer.write(e,t)}writeSync(e,t){this._logService.logLevel<=r.LogLevelEnum.WARN&&!m&&(this._logService.warn("writeSync is unreliable and will be removed soon."),m=!0),this._writeBuffer.writeSync(e,t)}resize(e,t){isNaN(e)||isNaN(t)||(e=Math.max(e,a.MINIMUM_COLS),t=Math.max(t,a.MINIMUM_ROWS),this._bufferService.resize(e,t))}scroll(e,t=!1){this._bufferService.scroll(e,t)}scrollLines(e,t,i){this._bufferService.scrollLines(e,t,i)}scrollPages(e){this.scrollLines(e*(this.rows-1))}scrollToTop(){this.scrollLines(-this._bufferService.buffer.ydisp)}scrollToBottom(){this.scrollLines(this._bufferService.buffer.ybase-this._bufferService.buffer.ydisp)}scrollToLine(e){const t=e-this._bufferService.buffer.ydisp;0!==t&&this.scrollLines(t)}registerEscHandler(e,t){return this._inputHandler.registerEscHandler(e,t)}registerDcsHandler(e,t){return this._inputHandler.registerDcsHandler(e,t)}registerCsiHandler(e,t){return this._inputHandler.registerCsiHandler(e,t)}registerOscHandler(e,t){return this._inputHandler.registerOscHandler(e,t)}_setup(){this._handleWindowsPtyOptionChange()}reset(){this._inputHandler.reset(),this._bufferService.reset(),this._charsetService.reset(),this.coreService.reset(),this.coreMouseService.reset()}_handleWindowsPtyOptionChange(){let e=!1;const t=this.optionsService.rawOptions.windowsPty;t&&void 0!==t.buildNumber&&void 0!==t.buildNumber?e=!!("conpty"===t.backend&&t.buildNumber<21376):this.optionsService.rawOptions.windowsMode&&(e=!0),e?this._enableWindowsWrappingHeuristics():this._windowsWrappingHeuristics.clear()}_enableWindowsWrappingHeuristics(){if(!this._windowsWrappingHeuristics.value){const e=[];e.push(this.onLineFeed(f.updateWindowsModeWrappedState.bind(null,this._bufferService))),e.push(this.registerCsiHandler({final:"H"},(()=>((0,f.updateWindowsModeWrappedState)(this._bufferService),!1)))),this._windowsWrappingHeuristics.value=(0,s.toDisposable)((()=>{for(const t of e)t.dispose()}))}}}t.CoreTerminal=S},8460:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.forwardEvent=t.EventEmitter=void 0,t.EventEmitter=class{constructor(){this._listeners=[],this._disposed=!1}get event(){return this._event||(this._event=e=>(this._listeners.push(e),{dispose:()=>{if(!this._disposed)for(let t=0;tt.fire(e)))}},5435:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.InputHandler=t.WindowsOptionsReportType=void 0;const n=i(2584),o=i(7116),a=i(2015),h=i(844),c=i(482),l=i(8437),d=i(8460),_=i(643),u=i(511),f=i(3734),v=i(2585),p=i(6242),g=i(6351),m=i(5941),S={"(":0,")":1,"*":2,"+":3,"-":1,".":2},C=131072;function b(e,t){if(e>24)return t.setWinLines||!1;switch(e){case 1:return!!t.restoreWin;case 2:return!!t.minimizeWin;case 3:return!!t.setWinPosition;case 4:return!!t.setWinSizePixels;case 5:return!!t.raiseWin;case 6:return!!t.lowerWin;case 7:return!!t.refreshWin;case 8:return!!t.setWinSizeChars;case 9:return!!t.maximizeWin;case 10:return!!t.fullscreenWin;case 11:return!!t.getWinState;case 13:return!!t.getWinPosition;case 14:return!!t.getWinSizePixels;case 15:return!!t.getScreenSizePixels;case 16:return!!t.getCellSizePixels;case 18:return!!t.getWinSizeChars;case 19:return!!t.getScreenSizeChars;case 20:return!!t.getIconTitle;case 21:return!!t.getWinTitle;case 22:return!!t.pushTitle;case 23:return!!t.popTitle;case 24:return!!t.setWinLines}return!1}var y;!function(e){e[e.GET_WIN_SIZE_PIXELS=0]="GET_WIN_SIZE_PIXELS",e[e.GET_CELL_SIZE_PIXELS=1]="GET_CELL_SIZE_PIXELS"}(y||(t.WindowsOptionsReportType=y={}));let w=0;class E extends h.Disposable{getAttrData(){return this._curAttrData}constructor(e,t,i,s,r,h,_,f,v=new a.EscapeSequenceParser){super(),this._bufferService=e,this._charsetService=t,this._coreService=i,this._logService=s,this._optionsService=r,this._oscLinkService=h,this._coreMouseService=_,this._unicodeService=f,this._parser=v,this._parseBuffer=new Uint32Array(4096),this._stringDecoder=new c.StringToUtf32,this._utf8Decoder=new c.Utf8ToUtf32,this._workCell=new u.CellData,this._windowTitle="",this._iconName="",this._windowTitleStack=[],this._iconNameStack=[],this._curAttrData=l.DEFAULT_ATTR_DATA.clone(),this._eraseAttrDataInternal=l.DEFAULT_ATTR_DATA.clone(),this._onRequestBell=this.register(new d.EventEmitter),this.onRequestBell=this._onRequestBell.event,this._onRequestRefreshRows=this.register(new d.EventEmitter),this.onRequestRefreshRows=this._onRequestRefreshRows.event,this._onRequestReset=this.register(new d.EventEmitter),this.onRequestReset=this._onRequestReset.event,this._onRequestSendFocus=this.register(new d.EventEmitter),this.onRequestSendFocus=this._onRequestSendFocus.event,this._onRequestSyncScrollBar=this.register(new d.EventEmitter),this.onRequestSyncScrollBar=this._onRequestSyncScrollBar.event,this._onRequestWindowsOptionsReport=this.register(new d.EventEmitter),this.onRequestWindowsOptionsReport=this._onRequestWindowsOptionsReport.event,this._onA11yChar=this.register(new d.EventEmitter),this.onA11yChar=this._onA11yChar.event,this._onA11yTab=this.register(new d.EventEmitter),this.onA11yTab=this._onA11yTab.event,this._onCursorMove=this.register(new d.EventEmitter),this.onCursorMove=this._onCursorMove.event,this._onLineFeed=this.register(new d.EventEmitter),this.onLineFeed=this._onLineFeed.event,this._onScroll=this.register(new d.EventEmitter),this.onScroll=this._onScroll.event,this._onTitleChange=this.register(new d.EventEmitter),this.onTitleChange=this._onTitleChange.event,this._onColor=this.register(new d.EventEmitter),this.onColor=this._onColor.event,this._parseStack={paused:!1,cursorStartX:0,cursorStartY:0,decodedLength:0,position:0},this._specialColors=[256,257,258],this.register(this._parser),this._dirtyRowTracker=new k(this._bufferService),this._activeBuffer=this._bufferService.buffer,this.register(this._bufferService.buffers.onBufferActivate((e=>this._activeBuffer=e.activeBuffer))),this._parser.setCsiHandlerFallback(((e,t)=>{this._logService.debug("Unknown CSI code: ",{identifier:this._parser.identToString(e),params:t.toArray()})})),this._parser.setEscHandlerFallback((e=>{this._logService.debug("Unknown ESC code: ",{identifier:this._parser.identToString(e)})})),this._parser.setExecuteHandlerFallback((e=>{this._logService.debug("Unknown EXECUTE code: ",{code:e})})),this._parser.setOscHandlerFallback(((e,t,i)=>{this._logService.debug("Unknown OSC code: ",{identifier:e,action:t,data:i})})),this._parser.setDcsHandlerFallback(((e,t,i)=>{"HOOK"===t&&(i=i.toArray()),this._logService.debug("Unknown DCS code: ",{identifier:this._parser.identToString(e),action:t,payload:i})})),this._parser.setPrintHandler(((e,t,i)=>this.print(e,t,i))),this._parser.registerCsiHandler({final:"@"},(e=>this.insertChars(e))),this._parser.registerCsiHandler({intermediates:" ",final:"@"},(e=>this.scrollLeft(e))),this._parser.registerCsiHandler({final:"A"},(e=>this.cursorUp(e))),this._parser.registerCsiHandler({intermediates:" ",final:"A"},(e=>this.scrollRight(e))),this._parser.registerCsiHandler({final:"B"},(e=>this.cursorDown(e))),this._parser.registerCsiHandler({final:"C"},(e=>this.cursorForward(e))),this._parser.registerCsiHandler({final:"D"},(e=>this.cursorBackward(e))),this._parser.registerCsiHandler({final:"E"},(e=>this.cursorNextLine(e))),this._parser.registerCsiHandler({final:"F"},(e=>this.cursorPrecedingLine(e))),this._parser.registerCsiHandler({final:"G"},(e=>this.cursorCharAbsolute(e))),this._parser.registerCsiHandler({final:"H"},(e=>this.cursorPosition(e))),this._parser.registerCsiHandler({final:"I"},(e=>this.cursorForwardTab(e))),this._parser.registerCsiHandler({final:"J"},(e=>this.eraseInDisplay(e,!1))),this._parser.registerCsiHandler({prefix:"?",final:"J"},(e=>this.eraseInDisplay(e,!0))),this._parser.registerCsiHandler({final:"K"},(e=>this.eraseInLine(e,!1))),this._parser.registerCsiHandler({prefix:"?",final:"K"},(e=>this.eraseInLine(e,!0))),this._parser.registerCsiHandler({final:"L"},(e=>this.insertLines(e))),this._parser.registerCsiHandler({final:"M"},(e=>this.deleteLines(e))),this._parser.registerCsiHandler({final:"P"},(e=>this.deleteChars(e))),this._parser.registerCsiHandler({final:"S"},(e=>this.scrollUp(e))),this._parser.registerCsiHandler({final:"T"},(e=>this.scrollDown(e))),this._parser.registerCsiHandler({final:"X"},(e=>this.eraseChars(e))),this._parser.registerCsiHandler({final:"Z"},(e=>this.cursorBackwardTab(e))),this._parser.registerCsiHandler({final:"`"},(e=>this.charPosAbsolute(e))),this._parser.registerCsiHandler({final:"a"},(e=>this.hPositionRelative(e))),this._parser.registerCsiHandler({final:"b"},(e=>this.repeatPrecedingCharacter(e))),this._parser.registerCsiHandler({final:"c"},(e=>this.sendDeviceAttributesPrimary(e))),this._parser.registerCsiHandler({prefix:">",final:"c"},(e=>this.sendDeviceAttributesSecondary(e))),this._parser.registerCsiHandler({final:"d"},(e=>this.linePosAbsolute(e))),this._parser.registerCsiHandler({final:"e"},(e=>this.vPositionRelative(e))),this._parser.registerCsiHandler({final:"f"},(e=>this.hVPosition(e))),this._parser.registerCsiHandler({final:"g"},(e=>this.tabClear(e))),this._parser.registerCsiHandler({final:"h"},(e=>this.setMode(e))),this._parser.registerCsiHandler({prefix:"?",final:"h"},(e=>this.setModePrivate(e))),this._parser.registerCsiHandler({final:"l"},(e=>this.resetMode(e))),this._parser.registerCsiHandler({prefix:"?",final:"l"},(e=>this.resetModePrivate(e))),this._parser.registerCsiHandler({final:"m"},(e=>this.charAttributes(e))),this._parser.registerCsiHandler({final:"n"},(e=>this.deviceStatus(e))),this._parser.registerCsiHandler({prefix:"?",final:"n"},(e=>this.deviceStatusPrivate(e))),this._parser.registerCsiHandler({intermediates:"!",final:"p"},(e=>this.softReset(e))),this._parser.registerCsiHandler({intermediates:" ",final:"q"},(e=>this.setCursorStyle(e))),this._parser.registerCsiHandler({final:"r"},(e=>this.setScrollRegion(e))),this._parser.registerCsiHandler({final:"s"},(e=>this.saveCursor(e))),this._parser.registerCsiHandler({final:"t"},(e=>this.windowOptions(e))),this._parser.registerCsiHandler({final:"u"},(e=>this.restoreCursor(e))),this._parser.registerCsiHandler({intermediates:"'",final:"}"},(e=>this.insertColumns(e))),this._parser.registerCsiHandler({intermediates:"'",final:"~"},(e=>this.deleteColumns(e))),this._parser.registerCsiHandler({intermediates:'"',final:"q"},(e=>this.selectProtected(e))),this._parser.registerCsiHandler({intermediates:"$",final:"p"},(e=>this.requestMode(e,!0))),this._parser.registerCsiHandler({prefix:"?",intermediates:"$",final:"p"},(e=>this.requestMode(e,!1))),this._parser.setExecuteHandler(n.C0.BEL,(()=>this.bell())),this._parser.setExecuteHandler(n.C0.LF,(()=>this.lineFeed())),this._parser.setExecuteHandler(n.C0.VT,(()=>this.lineFeed())),this._parser.setExecuteHandler(n.C0.FF,(()=>this.lineFeed())),this._parser.setExecuteHandler(n.C0.CR,(()=>this.carriageReturn())),this._parser.setExecuteHandler(n.C0.BS,(()=>this.backspace())),this._parser.setExecuteHandler(n.C0.HT,(()=>this.tab())),this._parser.setExecuteHandler(n.C0.SO,(()=>this.shiftOut())),this._parser.setExecuteHandler(n.C0.SI,(()=>this.shiftIn())),this._parser.setExecuteHandler(n.C1.IND,(()=>this.index())),this._parser.setExecuteHandler(n.C1.NEL,(()=>this.nextLine())),this._parser.setExecuteHandler(n.C1.HTS,(()=>this.tabSet())),this._parser.registerOscHandler(0,new p.OscHandler((e=>(this.setTitle(e),this.setIconName(e),!0)))),this._parser.registerOscHandler(1,new p.OscHandler((e=>this.setIconName(e)))),this._parser.registerOscHandler(2,new p.OscHandler((e=>this.setTitle(e)))),this._parser.registerOscHandler(4,new p.OscHandler((e=>this.setOrReportIndexedColor(e)))),this._parser.registerOscHandler(8,new p.OscHandler((e=>this.setHyperlink(e)))),this._parser.registerOscHandler(10,new p.OscHandler((e=>this.setOrReportFgColor(e)))),this._parser.registerOscHandler(11,new p.OscHandler((e=>this.setOrReportBgColor(e)))),this._parser.registerOscHandler(12,new p.OscHandler((e=>this.setOrReportCursorColor(e)))),this._parser.registerOscHandler(104,new p.OscHandler((e=>this.restoreIndexedColor(e)))),this._parser.registerOscHandler(110,new p.OscHandler((e=>this.restoreFgColor(e)))),this._parser.registerOscHandler(111,new p.OscHandler((e=>this.restoreBgColor(e)))),this._parser.registerOscHandler(112,new p.OscHandler((e=>this.restoreCursorColor(e)))),this._parser.registerEscHandler({final:"7"},(()=>this.saveCursor())),this._parser.registerEscHandler({final:"8"},(()=>this.restoreCursor())),this._parser.registerEscHandler({final:"D"},(()=>this.index())),this._parser.registerEscHandler({final:"E"},(()=>this.nextLine())),this._parser.registerEscHandler({final:"H"},(()=>this.tabSet())),this._parser.registerEscHandler({final:"M"},(()=>this.reverseIndex())),this._parser.registerEscHandler({final:"="},(()=>this.keypadApplicationMode())),this._parser.registerEscHandler({final:">"},(()=>this.keypadNumericMode())),this._parser.registerEscHandler({final:"c"},(()=>this.fullReset())),this._parser.registerEscHandler({final:"n"},(()=>this.setgLevel(2))),this._parser.registerEscHandler({final:"o"},(()=>this.setgLevel(3))),this._parser.registerEscHandler({final:"|"},(()=>this.setgLevel(3))),this._parser.registerEscHandler({final:"}"},(()=>this.setgLevel(2))),this._parser.registerEscHandler({final:"~"},(()=>this.setgLevel(1))),this._parser.registerEscHandler({intermediates:"%",final:"@"},(()=>this.selectDefaultCharset())),this._parser.registerEscHandler({intermediates:"%",final:"G"},(()=>this.selectDefaultCharset()));for(const e in o.CHARSETS)this._parser.registerEscHandler({intermediates:"(",final:e},(()=>this.selectCharset("("+e))),this._parser.registerEscHandler({intermediates:")",final:e},(()=>this.selectCharset(")"+e))),this._parser.registerEscHandler({intermediates:"*",final:e},(()=>this.selectCharset("*"+e))),this._parser.registerEscHandler({intermediates:"+",final:e},(()=>this.selectCharset("+"+e))),this._parser.registerEscHandler({intermediates:"-",final:e},(()=>this.selectCharset("-"+e))),this._parser.registerEscHandler({intermediates:".",final:e},(()=>this.selectCharset("."+e))),this._parser.registerEscHandler({intermediates:"/",final:e},(()=>this.selectCharset("/"+e)));this._parser.registerEscHandler({intermediates:"#",final:"8"},(()=>this.screenAlignmentPattern())),this._parser.setErrorHandler((e=>(this._logService.error("Parsing error: ",e),e))),this._parser.registerDcsHandler({intermediates:"$",final:"q"},new g.DcsHandler(((e,t)=>this.requestStatusString(e,t))))}_preserveStack(e,t,i,s){this._parseStack.paused=!0,this._parseStack.cursorStartX=e,this._parseStack.cursorStartY=t,this._parseStack.decodedLength=i,this._parseStack.position=s}_logSlowResolvingAsync(e){this._logService.logLevel<=v.LogLevelEnum.WARN&&Promise.race([e,new Promise(((e,t)=>setTimeout((()=>t("#SLOW_TIMEOUT")),5e3)))]).catch((e=>{if("#SLOW_TIMEOUT"!==e)throw e;console.warn("async parser handler taking longer than 5000 ms")}))}_getCurrentLinkId(){return this._curAttrData.extended.urlId}parse(e,t){let i,s=this._activeBuffer.x,r=this._activeBuffer.y,n=0;const o=this._parseStack.paused;if(o){if(i=this._parser.parse(this._parseBuffer,this._parseStack.decodedLength,t))return this._logSlowResolvingAsync(i),i;s=this._parseStack.cursorStartX,r=this._parseStack.cursorStartY,this._parseStack.paused=!1,e.length>C&&(n=this._parseStack.position+C)}if(this._logService.logLevel<=v.LogLevelEnum.DEBUG&&this._logService.debug("parsing data"+("string"==typeof e?` "${e}"`:` "${Array.prototype.map.call(e,(e=>String.fromCharCode(e))).join("")}"`),"string"==typeof e?e.split("").map((e=>e.charCodeAt(0))):e),this._parseBuffer.lengthC)for(let t=n;t0&&2===u.getWidth(this._activeBuffer.x-1)&&u.setCellFromCodePoint(this._activeBuffer.x-1,0,1,d.fg,d.bg,d.extended);for(let f=t;f=a)if(h){for(;this._activeBuffer.x=this._bufferService.rows&&(this._activeBuffer.y=this._bufferService.rows-1),this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y).isWrapped=!0),u=this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y)}else if(this._activeBuffer.x=a-1,2===r)continue;if(l&&(u.insertCells(this._activeBuffer.x,r,this._activeBuffer.getNullCell(d),d),2===u.getWidth(a-1)&&u.setCellFromCodePoint(a-1,_.NULL_CELL_CODE,_.NULL_CELL_WIDTH,d.fg,d.bg,d.extended)),u.setCellFromCodePoint(this._activeBuffer.x++,s,r,d.fg,d.bg,d.extended),r>0)for(;--r;)u.setCellFromCodePoint(this._activeBuffer.x++,0,0,d.fg,d.bg,d.extended)}else u.getWidth(this._activeBuffer.x-1)?u.addCodepointToCell(this._activeBuffer.x-1,s):u.addCodepointToCell(this._activeBuffer.x-2,s)}i-t>0&&(u.loadCell(this._activeBuffer.x-1,this._workCell),2===this._workCell.getWidth()||this._workCell.getCode()>65535?this._parser.precedingCodepoint=0:this._workCell.isCombined()?this._parser.precedingCodepoint=this._workCell.getChars().charCodeAt(0):this._parser.precedingCodepoint=this._workCell.content),this._activeBuffer.x0&&0===u.getWidth(this._activeBuffer.x)&&!u.hasContent(this._activeBuffer.x)&&u.setCellFromCodePoint(this._activeBuffer.x,0,1,d.fg,d.bg,d.extended),this._dirtyRowTracker.markDirty(this._activeBuffer.y)}registerCsiHandler(e,t){return"t"!==e.final||e.prefix||e.intermediates?this._parser.registerCsiHandler(e,t):this._parser.registerCsiHandler(e,(e=>!b(e.params[0],this._optionsService.rawOptions.windowOptions)||t(e)))}registerDcsHandler(e,t){return this._parser.registerDcsHandler(e,new g.DcsHandler(t))}registerEscHandler(e,t){return this._parser.registerEscHandler(e,t)}registerOscHandler(e,t){return this._parser.registerOscHandler(e,new p.OscHandler(t))}bell(){return this._onRequestBell.fire(),!0}lineFeed(){return this._dirtyRowTracker.markDirty(this._activeBuffer.y),this._optionsService.rawOptions.convertEol&&(this._activeBuffer.x=0),this._activeBuffer.y++,this._activeBuffer.y===this._activeBuffer.scrollBottom+1?(this._activeBuffer.y--,this._bufferService.scroll(this._eraseAttrData())):this._activeBuffer.y>=this._bufferService.rows?this._activeBuffer.y=this._bufferService.rows-1:this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y).isWrapped=!1,this._activeBuffer.x>=this._bufferService.cols&&this._activeBuffer.x--,this._dirtyRowTracker.markDirty(this._activeBuffer.y),this._onLineFeed.fire(),!0}carriageReturn(){return this._activeBuffer.x=0,!0}backspace(){var e;if(!this._coreService.decPrivateModes.reverseWraparound)return this._restrictCursor(),this._activeBuffer.x>0&&this._activeBuffer.x--,!0;if(this._restrictCursor(this._bufferService.cols),this._activeBuffer.x>0)this._activeBuffer.x--;else if(0===this._activeBuffer.x&&this._activeBuffer.y>this._activeBuffer.scrollTop&&this._activeBuffer.y<=this._activeBuffer.scrollBottom&&(null===(e=this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y))||void 0===e?void 0:e.isWrapped)){this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y).isWrapped=!1,this._activeBuffer.y--,this._activeBuffer.x=this._bufferService.cols-1;const e=this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y);e.hasWidth(this._activeBuffer.x)&&!e.hasContent(this._activeBuffer.x)&&this._activeBuffer.x--}return this._restrictCursor(),!0}tab(){if(this._activeBuffer.x>=this._bufferService.cols)return!0;const e=this._activeBuffer.x;return this._activeBuffer.x=this._activeBuffer.nextStop(),this._optionsService.rawOptions.screenReaderMode&&this._onA11yTab.fire(this._activeBuffer.x-e),!0}shiftOut(){return this._charsetService.setgLevel(1),!0}shiftIn(){return this._charsetService.setgLevel(0),!0}_restrictCursor(e=this._bufferService.cols-1){this._activeBuffer.x=Math.min(e,Math.max(0,this._activeBuffer.x)),this._activeBuffer.y=this._coreService.decPrivateModes.origin?Math.min(this._activeBuffer.scrollBottom,Math.max(this._activeBuffer.scrollTop,this._activeBuffer.y)):Math.min(this._bufferService.rows-1,Math.max(0,this._activeBuffer.y)),this._dirtyRowTracker.markDirty(this._activeBuffer.y)}_setCursor(e,t){this._dirtyRowTracker.markDirty(this._activeBuffer.y),this._coreService.decPrivateModes.origin?(this._activeBuffer.x=e,this._activeBuffer.y=this._activeBuffer.scrollTop+t):(this._activeBuffer.x=e,this._activeBuffer.y=t),this._restrictCursor(),this._dirtyRowTracker.markDirty(this._activeBuffer.y)}_moveCursor(e,t){this._restrictCursor(),this._setCursor(this._activeBuffer.x+e,this._activeBuffer.y+t)}cursorUp(e){const t=this._activeBuffer.y-this._activeBuffer.scrollTop;return t>=0?this._moveCursor(0,-Math.min(t,e.params[0]||1)):this._moveCursor(0,-(e.params[0]||1)),!0}cursorDown(e){const t=this._activeBuffer.scrollBottom-this._activeBuffer.y;return t>=0?this._moveCursor(0,Math.min(t,e.params[0]||1)):this._moveCursor(0,e.params[0]||1),!0}cursorForward(e){return this._moveCursor(e.params[0]||1,0),!0}cursorBackward(e){return this._moveCursor(-(e.params[0]||1),0),!0}cursorNextLine(e){return this.cursorDown(e),this._activeBuffer.x=0,!0}cursorPrecedingLine(e){return this.cursorUp(e),this._activeBuffer.x=0,!0}cursorCharAbsolute(e){return this._setCursor((e.params[0]||1)-1,this._activeBuffer.y),!0}cursorPosition(e){return this._setCursor(e.length>=2?(e.params[1]||1)-1:0,(e.params[0]||1)-1),!0}charPosAbsolute(e){return this._setCursor((e.params[0]||1)-1,this._activeBuffer.y),!0}hPositionRelative(e){return this._moveCursor(e.params[0]||1,0),!0}linePosAbsolute(e){return this._setCursor(this._activeBuffer.x,(e.params[0]||1)-1),!0}vPositionRelative(e){return this._moveCursor(0,e.params[0]||1),!0}hVPosition(e){return this.cursorPosition(e),!0}tabClear(e){const t=e.params[0];return 0===t?delete this._activeBuffer.tabs[this._activeBuffer.x]:3===t&&(this._activeBuffer.tabs={}),!0}cursorForwardTab(e){if(this._activeBuffer.x>=this._bufferService.cols)return!0;let t=e.params[0]||1;for(;t--;)this._activeBuffer.x=this._activeBuffer.nextStop();return!0}cursorBackwardTab(e){if(this._activeBuffer.x>=this._bufferService.cols)return!0;let t=e.params[0]||1;for(;t--;)this._activeBuffer.x=this._activeBuffer.prevStop();return!0}selectProtected(e){const t=e.params[0];return 1===t&&(this._curAttrData.bg|=536870912),2!==t&&0!==t||(this._curAttrData.bg&=-536870913),!0}_eraseInBufferLine(e,t,i,s=!1,r=!1){const n=this._activeBuffer.lines.get(this._activeBuffer.ybase+e);n.replaceCells(t,i,this._activeBuffer.getNullCell(this._eraseAttrData()),this._eraseAttrData(),r),s&&(n.isWrapped=!1)}_resetBufferLine(e,t=!1){const i=this._activeBuffer.lines.get(this._activeBuffer.ybase+e);i&&(i.fill(this._activeBuffer.getNullCell(this._eraseAttrData()),t),this._bufferService.buffer.clearMarkers(this._activeBuffer.ybase+e),i.isWrapped=!1)}eraseInDisplay(e,t=!1){let i;switch(this._restrictCursor(this._bufferService.cols),e.params[0]){case 0:for(i=this._activeBuffer.y,this._dirtyRowTracker.markDirty(i),this._eraseInBufferLine(i++,this._activeBuffer.x,this._bufferService.cols,0===this._activeBuffer.x,t);i=this._bufferService.cols&&(this._activeBuffer.lines.get(i+1).isWrapped=!1);i--;)this._resetBufferLine(i,t);this._dirtyRowTracker.markDirty(0);break;case 2:for(i=this._bufferService.rows,this._dirtyRowTracker.markDirty(i-1);i--;)this._resetBufferLine(i,t);this._dirtyRowTracker.markDirty(0);break;case 3:const e=this._activeBuffer.lines.length-this._bufferService.rows;e>0&&(this._activeBuffer.lines.trimStart(e),this._activeBuffer.ybase=Math.max(this._activeBuffer.ybase-e,0),this._activeBuffer.ydisp=Math.max(this._activeBuffer.ydisp-e,0),this._onScroll.fire(0))}return!0}eraseInLine(e,t=!1){switch(this._restrictCursor(this._bufferService.cols),e.params[0]){case 0:this._eraseInBufferLine(this._activeBuffer.y,this._activeBuffer.x,this._bufferService.cols,0===this._activeBuffer.x,t);break;case 1:this._eraseInBufferLine(this._activeBuffer.y,0,this._activeBuffer.x+1,!1,t);break;case 2:this._eraseInBufferLine(this._activeBuffer.y,0,this._bufferService.cols,!0,t)}return this._dirtyRowTracker.markDirty(this._activeBuffer.y),!0}insertLines(e){this._restrictCursor();let t=e.params[0]||1;if(this._activeBuffer.y>this._activeBuffer.scrollBottom||this._activeBuffer.ythis._activeBuffer.scrollBottom||this._activeBuffer.ythis._activeBuffer.scrollBottom||this._activeBuffer.ythis._activeBuffer.scrollBottom||this._activeBuffer.ythis._activeBuffer.scrollBottom||this._activeBuffer.ythis._activeBuffer.scrollBottom||this._activeBuffer.y0||(this._is("xterm")||this._is("rxvt-unicode")||this._is("screen")?this._coreService.triggerDataEvent(n.C0.ESC+"[?1;2c"):this._is("linux")&&this._coreService.triggerDataEvent(n.C0.ESC+"[?6c")),!0}sendDeviceAttributesSecondary(e){return e.params[0]>0||(this._is("xterm")?this._coreService.triggerDataEvent(n.C0.ESC+"[>0;276;0c"):this._is("rxvt-unicode")?this._coreService.triggerDataEvent(n.C0.ESC+"[>85;95;0c"):this._is("linux")?this._coreService.triggerDataEvent(e.params[0]+"c"):this._is("screen")&&this._coreService.triggerDataEvent(n.C0.ESC+"[>83;40003;0c")),!0}_is(e){return 0===(this._optionsService.rawOptions.termName+"").indexOf(e)}setMode(e){for(let t=0;te?1:2,u=e.params[0];return f=u,v=t?2===u?4:4===u?_(o.modes.insertMode):12===u?3:20===u?_(d.convertEol):0:1===u?_(i.applicationCursorKeys):3===u?d.windowOptions.setWinLines?80===h?2:132===h?1:0:0:6===u?_(i.origin):7===u?_(i.wraparound):8===u?3:9===u?_("X10"===s):12===u?_(d.cursorBlink):25===u?_(!o.isCursorHidden):45===u?_(i.reverseWraparound):66===u?_(i.applicationKeypad):67===u?4:1e3===u?_("VT200"===s):1002===u?_("DRAG"===s):1003===u?_("ANY"===s):1004===u?_(i.sendFocus):1005===u?4:1006===u?_("SGR"===r):1015===u?4:1016===u?_("SGR_PIXELS"===r):1048===u?1:47===u||1047===u||1049===u?_(c===l):2004===u?_(i.bracketedPasteMode):0,o.triggerDataEvent(`${n.C0.ESC}[${t?"":"?"}${f};${v}$y`),!0;var f,v}_updateAttrColor(e,t,i,s,r){return 2===t?(e|=50331648,e&=-16777216,e|=f.AttributeData.fromColorRGB([i,s,r])):5===t&&(e&=-50331904,e|=33554432|255&i),e}_extractColor(e,t,i){const s=[0,0,-1,0,0,0];let r=0,n=0;do{if(s[n+r]=e.params[t+n],e.hasSubParams(t+n)){const i=e.getSubParams(t+n);let o=0;do{5===s[1]&&(r=1),s[n+o+1+r]=i[o]}while(++o=2||2===s[1]&&n+r>=5)break;s[1]&&(r=1)}while(++n+t5)&&(e=1),t.extended.underlineStyle=e,t.fg|=268435456,0===e&&(t.fg&=-268435457),t.updateExtended()}_processSGR0(e){e.fg=l.DEFAULT_ATTR_DATA.fg,e.bg=l.DEFAULT_ATTR_DATA.bg,e.extended=e.extended.clone(),e.extended.underlineStyle=0,e.extended.underlineColor&=-67108864,e.updateExtended()}charAttributes(e){if(1===e.length&&0===e.params[0])return this._processSGR0(this._curAttrData),!0;const t=e.length;let i;const s=this._curAttrData;for(let r=0;r=30&&i<=37?(s.fg&=-50331904,s.fg|=16777216|i-30):i>=40&&i<=47?(s.bg&=-50331904,s.bg|=16777216|i-40):i>=90&&i<=97?(s.fg&=-50331904,s.fg|=16777224|i-90):i>=100&&i<=107?(s.bg&=-50331904,s.bg|=16777224|i-100):0===i?this._processSGR0(s):1===i?s.fg|=134217728:3===i?s.bg|=67108864:4===i?(s.fg|=268435456,this._processUnderline(e.hasSubParams(r)?e.getSubParams(r)[0]:1,s)):5===i?s.fg|=536870912:7===i?s.fg|=67108864:8===i?s.fg|=1073741824:9===i?s.fg|=2147483648:2===i?s.bg|=134217728:21===i?this._processUnderline(2,s):22===i?(s.fg&=-134217729,s.bg&=-134217729):23===i?s.bg&=-67108865:24===i?(s.fg&=-268435457,this._processUnderline(0,s)):25===i?s.fg&=-536870913:27===i?s.fg&=-67108865:28===i?s.fg&=-1073741825:29===i?s.fg&=2147483647:39===i?(s.fg&=-67108864,s.fg|=16777215&l.DEFAULT_ATTR_DATA.fg):49===i?(s.bg&=-67108864,s.bg|=16777215&l.DEFAULT_ATTR_DATA.bg):38===i||48===i||58===i?r+=this._extractColor(e,r,s):53===i?s.bg|=1073741824:55===i?s.bg&=-1073741825:59===i?(s.extended=s.extended.clone(),s.extended.underlineColor=-1,s.updateExtended()):100===i?(s.fg&=-67108864,s.fg|=16777215&l.DEFAULT_ATTR_DATA.fg,s.bg&=-67108864,s.bg|=16777215&l.DEFAULT_ATTR_DATA.bg):this._logService.debug("Unknown SGR attribute: %d.",i);return!0}deviceStatus(e){switch(e.params[0]){case 5:this._coreService.triggerDataEvent(`${n.C0.ESC}[0n`);break;case 6:const e=this._activeBuffer.y+1,t=this._activeBuffer.x+1;this._coreService.triggerDataEvent(`${n.C0.ESC}[${e};${t}R`)}return!0}deviceStatusPrivate(e){if(6===e.params[0]){const e=this._activeBuffer.y+1,t=this._activeBuffer.x+1;this._coreService.triggerDataEvent(`${n.C0.ESC}[?${e};${t}R`)}return!0}softReset(e){return this._coreService.isCursorHidden=!1,this._onRequestSyncScrollBar.fire(),this._activeBuffer.scrollTop=0,this._activeBuffer.scrollBottom=this._bufferService.rows-1,this._curAttrData=l.DEFAULT_ATTR_DATA.clone(),this._coreService.reset(),this._charsetService.reset(),this._activeBuffer.savedX=0,this._activeBuffer.savedY=this._activeBuffer.ybase,this._activeBuffer.savedCurAttrData.fg=this._curAttrData.fg,this._activeBuffer.savedCurAttrData.bg=this._curAttrData.bg,this._activeBuffer.savedCharset=this._charsetService.charset,this._coreService.decPrivateModes.origin=!1,!0}setCursorStyle(e){const t=e.params[0]||1;switch(t){case 1:case 2:this._optionsService.options.cursorStyle="block";break;case 3:case 4:this._optionsService.options.cursorStyle="underline";break;case 5:case 6:this._optionsService.options.cursorStyle="bar"}const i=t%2==1;return this._optionsService.options.cursorBlink=i,!0}setScrollRegion(e){const t=e.params[0]||1;let i;return(e.length<2||(i=e.params[1])>this._bufferService.rows||0===i)&&(i=this._bufferService.rows),i>t&&(this._activeBuffer.scrollTop=t-1,this._activeBuffer.scrollBottom=i-1,this._setCursor(0,0)),!0}windowOptions(e){if(!b(e.params[0],this._optionsService.rawOptions.windowOptions))return!0;const t=e.length>1?e.params[1]:0;switch(e.params[0]){case 14:2!==t&&this._onRequestWindowsOptionsReport.fire(y.GET_WIN_SIZE_PIXELS);break;case 16:this._onRequestWindowsOptionsReport.fire(y.GET_CELL_SIZE_PIXELS);break;case 18:this._bufferService&&this._coreService.triggerDataEvent(`${n.C0.ESC}[8;${this._bufferService.rows};${this._bufferService.cols}t`);break;case 22:0!==t&&2!==t||(this._windowTitleStack.push(this._windowTitle),this._windowTitleStack.length>10&&this._windowTitleStack.shift()),0!==t&&1!==t||(this._iconNameStack.push(this._iconName),this._iconNameStack.length>10&&this._iconNameStack.shift());break;case 23:0!==t&&2!==t||this._windowTitleStack.length&&this.setTitle(this._windowTitleStack.pop()),0!==t&&1!==t||this._iconNameStack.length&&this.setIconName(this._iconNameStack.pop())}return!0}saveCursor(e){return this._activeBuffer.savedX=this._activeBuffer.x,this._activeBuffer.savedY=this._activeBuffer.ybase+this._activeBuffer.y,this._activeBuffer.savedCurAttrData.fg=this._curAttrData.fg,this._activeBuffer.savedCurAttrData.bg=this._curAttrData.bg,this._activeBuffer.savedCharset=this._charsetService.charset,!0}restoreCursor(e){return this._activeBuffer.x=this._activeBuffer.savedX||0,this._activeBuffer.y=Math.max(this._activeBuffer.savedY-this._activeBuffer.ybase,0),this._curAttrData.fg=this._activeBuffer.savedCurAttrData.fg,this._curAttrData.bg=this._activeBuffer.savedCurAttrData.bg,this._charsetService.charset=this._savedCharset,this._activeBuffer.savedCharset&&(this._charsetService.charset=this._activeBuffer.savedCharset),this._restrictCursor(),!0}setTitle(e){return this._windowTitle=e,this._onTitleChange.fire(e),!0}setIconName(e){return this._iconName=e,!0}setOrReportIndexedColor(e){const t=[],i=e.split(";");for(;i.length>1;){const e=i.shift(),s=i.shift();if(/^\d+$/.exec(e)){const i=parseInt(e);if(L(i))if("?"===s)t.push({type:0,index:i});else{const e=(0,m.parseColor)(s);e&&t.push({type:1,index:i,color:e})}}}return t.length&&this._onColor.fire(t),!0}setHyperlink(e){const t=e.split(";");return!(t.length<2)&&(t[1]?this._createHyperlink(t[0],t[1]):!t[0]&&this._finishHyperlink())}_createHyperlink(e,t){this._getCurrentLinkId()&&this._finishHyperlink();const i=e.split(":");let s;const r=i.findIndex((e=>e.startsWith("id=")));return-1!==r&&(s=i[r].slice(3)||void 0),this._curAttrData.extended=this._curAttrData.extended.clone(),this._curAttrData.extended.urlId=this._oscLinkService.registerLink({id:s,uri:t}),this._curAttrData.updateExtended(),!0}_finishHyperlink(){return this._curAttrData.extended=this._curAttrData.extended.clone(),this._curAttrData.extended.urlId=0,this._curAttrData.updateExtended(),!0}_setOrReportSpecialColor(e,t){const i=e.split(";");for(let e=0;e=this._specialColors.length);++e,++t)if("?"===i[e])this._onColor.fire([{type:0,index:this._specialColors[t]}]);else{const s=(0,m.parseColor)(i[e]);s&&this._onColor.fire([{type:1,index:this._specialColors[t],color:s}])}return!0}setOrReportFgColor(e){return this._setOrReportSpecialColor(e,0)}setOrReportBgColor(e){return this._setOrReportSpecialColor(e,1)}setOrReportCursorColor(e){return this._setOrReportSpecialColor(e,2)}restoreIndexedColor(e){if(!e)return this._onColor.fire([{type:2}]),!0;const t=[],i=e.split(";");for(let e=0;e=this._bufferService.rows&&(this._activeBuffer.y=this._bufferService.rows-1),this._restrictCursor(),!0}tabSet(){return this._activeBuffer.tabs[this._activeBuffer.x]=!0,!0}reverseIndex(){if(this._restrictCursor(),this._activeBuffer.y===this._activeBuffer.scrollTop){const e=this._activeBuffer.scrollBottom-this._activeBuffer.scrollTop;this._activeBuffer.lines.shiftElements(this._activeBuffer.ybase+this._activeBuffer.y,e,1),this._activeBuffer.lines.set(this._activeBuffer.ybase+this._activeBuffer.y,this._activeBuffer.getBlankLine(this._eraseAttrData())),this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop,this._activeBuffer.scrollBottom)}else this._activeBuffer.y--,this._restrictCursor();return!0}fullReset(){return this._parser.reset(),this._onRequestReset.fire(),!0}reset(){this._curAttrData=l.DEFAULT_ATTR_DATA.clone(),this._eraseAttrDataInternal=l.DEFAULT_ATTR_DATA.clone()}_eraseAttrData(){return this._eraseAttrDataInternal.bg&=-67108864,this._eraseAttrDataInternal.bg|=67108863&this._curAttrData.bg,this._eraseAttrDataInternal}setgLevel(e){return this._charsetService.setgLevel(e),!0}screenAlignmentPattern(){const e=new u.CellData;e.content=1<<22|"E".charCodeAt(0),e.fg=this._curAttrData.fg,e.bg=this._curAttrData.bg,this._setCursor(0,0);for(let t=0;t(this._coreService.triggerDataEvent(`${n.C0.ESC}${e}${n.C0.ESC}\\`),!0))('"q'===e?`P1$r${this._curAttrData.isProtected()?1:0}"q`:'"p'===e?'P1$r61;1"p':"r"===e?`P1$r${i.scrollTop+1};${i.scrollBottom+1}r`:"m"===e?"P1$r0m":" q"===e?`P1$r${{block:2,underline:4,bar:6}[s.cursorStyle]-(s.cursorBlink?1:0)} q`:"P0$r")}markRangeDirty(e,t){this._dirtyRowTracker.markRangeDirty(e,t)}}t.InputHandler=E;let k=class{constructor(e){this._bufferService=e,this.clearRange()}clearRange(){this.start=this._bufferService.buffer.y,this.end=this._bufferService.buffer.y}markDirty(e){ethis.end&&(this.end=e)}markRangeDirty(e,t){e>t&&(w=e,e=t,t=w),ethis.end&&(this.end=t)}markAllDirty(){this.markRangeDirty(0,this._bufferService.rows-1)}};function L(e){return 0<=e&&e<256}k=s([r(0,v.IBufferService)],k)},844:(e,t)=>{function i(e){for(const t of e)t.dispose();e.length=0}Object.defineProperty(t,"__esModule",{value:!0}),t.getDisposeArrayDisposable=t.disposeArray=t.toDisposable=t.MutableDisposable=t.Disposable=void 0,t.Disposable=class{constructor(){this._disposables=[],this._isDisposed=!1}dispose(){this._isDisposed=!0;for(const e of this._disposables)e.dispose();this._disposables.length=0}register(e){return this._disposables.push(e),e}unregister(e){const t=this._disposables.indexOf(e);-1!==t&&this._disposables.splice(t,1)}},t.MutableDisposable=class{constructor(){this._isDisposed=!1}get value(){return this._isDisposed?void 0:this._value}set value(e){var t;this._isDisposed||e===this._value||(null===(t=this._value)||void 0===t||t.dispose(),this._value=e)}clear(){this.value=void 0}dispose(){var e;this._isDisposed=!0,null===(e=this._value)||void 0===e||e.dispose(),this._value=void 0}},t.toDisposable=function(e){return{dispose:e}},t.disposeArray=i,t.getDisposeArrayDisposable=function(e){return{dispose:()=>i(e)}}},1505:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.FourKeyMap=t.TwoKeyMap=void 0;class i{constructor(){this._data={}}set(e,t,i){this._data[e]||(this._data[e]={}),this._data[e][t]=i}get(e,t){return this._data[e]?this._data[e][t]:void 0}clear(){this._data={}}}t.TwoKeyMap=i,t.FourKeyMap=class{constructor(){this._data=new i}set(e,t,s,r,n){this._data.get(e,t)||this._data.set(e,t,new i),this._data.get(e,t).set(s,r,n)}get(e,t,i,s){var r;return null===(r=this._data.get(e,t))||void 0===r?void 0:r.get(i,s)}clear(){this._data.clear()}}},6114:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.isChromeOS=t.isLinux=t.isWindows=t.isIphone=t.isIpad=t.isMac=t.getSafariVersion=t.isSafari=t.isLegacyEdge=t.isFirefox=t.isNode=void 0,t.isNode="undefined"==typeof navigator;const i=t.isNode?"node":navigator.userAgent,s=t.isNode?"node":navigator.platform;t.isFirefox=i.includes("Firefox"),t.isLegacyEdge=i.includes("Edge"),t.isSafari=/^((?!chrome|android).)*safari/i.test(i),t.getSafariVersion=function(){if(!t.isSafari)return 0;const e=i.match(/Version\/(\d+)/);return null===e||e.length<2?0:parseInt(e[1])},t.isMac=["Macintosh","MacIntel","MacPPC","Mac68K"].includes(s),t.isIpad="iPad"===s,t.isIphone="iPhone"===s,t.isWindows=["Windows","Win16","Win32","WinCE"].includes(s),t.isLinux=s.indexOf("Linux")>=0,t.isChromeOS=/\bCrOS\b/.test(i)},6106:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.SortedList=void 0;let i=0;t.SortedList=class{constructor(e){this._getKey=e,this._array=[]}clear(){this._array.length=0}insert(e){0!==this._array.length?(i=this._search(this._getKey(e)),this._array.splice(i,0,e)):this._array.push(e)}delete(e){if(0===this._array.length)return!1;const t=this._getKey(e);if(void 0===t)return!1;if(i=this._search(t),-1===i)return!1;if(this._getKey(this._array[i])!==t)return!1;do{if(this._array[i]===e)return this._array.splice(i,1),!0}while(++i=this._array.length)&&this._getKey(this._array[i])===e))do{yield this._array[i]}while(++i=this._array.length)&&this._getKey(this._array[i])===e))do{t(this._array[i])}while(++i=t;){let s=t+i>>1;const r=this._getKey(this._array[s]);if(r>e)i=s-1;else{if(!(r0&&this._getKey(this._array[s-1])===e;)s--;return s}t=s+1}}return t}}},7226:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.DebouncedIdleTask=t.IdleTaskQueue=t.PriorityTaskQueue=void 0;const s=i(6114);class r{constructor(){this._tasks=[],this._i=0}enqueue(e){this._tasks.push(e),this._start()}flush(){for(;this._ir)return s-t<-20&&console.warn(`task queue exceeded allotted deadline by ${Math.abs(Math.round(s-t))}ms`),void this._start();s=r}this.clear()}}class n extends r{_requestCallback(e){return setTimeout((()=>e(this._createDeadline(16))))}_cancelCallback(e){clearTimeout(e)}_createDeadline(e){const t=Date.now()+e;return{timeRemaining:()=>Math.max(0,t-Date.now())}}}t.PriorityTaskQueue=n,t.IdleTaskQueue=!s.isNode&&"requestIdleCallback"in window?class extends r{_requestCallback(e){return requestIdleCallback(e)}_cancelCallback(e){cancelIdleCallback(e)}}:n,t.DebouncedIdleTask=class{constructor(){this._queue=new t.IdleTaskQueue}set(e){this._queue.clear(),this._queue.enqueue(e)}flush(){this._queue.flush()}}},9282:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.updateWindowsModeWrappedState=void 0;const s=i(643);t.updateWindowsModeWrappedState=function(e){const t=e.buffer.lines.get(e.buffer.ybase+e.buffer.y-1),i=null==t?void 0:t.get(e.cols-1),r=e.buffer.lines.get(e.buffer.ybase+e.buffer.y);r&&i&&(r.isWrapped=i[s.CHAR_DATA_CODE_INDEX]!==s.NULL_CELL_CODE&&i[s.CHAR_DATA_CODE_INDEX]!==s.WHITESPACE_CELL_CODE)}},3734:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.ExtendedAttrs=t.AttributeData=void 0;class i{constructor(){this.fg=0,this.bg=0,this.extended=new s}static toColorRGB(e){return[e>>>16&255,e>>>8&255,255&e]}static fromColorRGB(e){return(255&e[0])<<16|(255&e[1])<<8|255&e[2]}clone(){const e=new i;return e.fg=this.fg,e.bg=this.bg,e.extended=this.extended.clone(),e}isInverse(){return 67108864&this.fg}isBold(){return 134217728&this.fg}isUnderline(){return this.hasExtendedAttrs()&&0!==this.extended.underlineStyle?1:268435456&this.fg}isBlink(){return 536870912&this.fg}isInvisible(){return 1073741824&this.fg}isItalic(){return 67108864&this.bg}isDim(){return 134217728&this.bg}isStrikethrough(){return 2147483648&this.fg}isProtected(){return 536870912&this.bg}isOverline(){return 1073741824&this.bg}getFgColorMode(){return 50331648&this.fg}getBgColorMode(){return 50331648&this.bg}isFgRGB(){return 50331648==(50331648&this.fg)}isBgRGB(){return 50331648==(50331648&this.bg)}isFgPalette(){return 16777216==(50331648&this.fg)||33554432==(50331648&this.fg)}isBgPalette(){return 16777216==(50331648&this.bg)||33554432==(50331648&this.bg)}isFgDefault(){return 0==(50331648&this.fg)}isBgDefault(){return 0==(50331648&this.bg)}isAttributeDefault(){return 0===this.fg&&0===this.bg}getFgColor(){switch(50331648&this.fg){case 16777216:case 33554432:return 255&this.fg;case 50331648:return 16777215&this.fg;default:return-1}}getBgColor(){switch(50331648&this.bg){case 16777216:case 33554432:return 255&this.bg;case 50331648:return 16777215&this.bg;default:return-1}}hasExtendedAttrs(){return 268435456&this.bg}updateExtended(){this.extended.isEmpty()?this.bg&=-268435457:this.bg|=268435456}getUnderlineColor(){if(268435456&this.bg&&~this.extended.underlineColor)switch(50331648&this.extended.underlineColor){case 16777216:case 33554432:return 255&this.extended.underlineColor;case 50331648:return 16777215&this.extended.underlineColor;default:return this.getFgColor()}return this.getFgColor()}getUnderlineColorMode(){return 268435456&this.bg&&~this.extended.underlineColor?50331648&this.extended.underlineColor:this.getFgColorMode()}isUnderlineColorRGB(){return 268435456&this.bg&&~this.extended.underlineColor?50331648==(50331648&this.extended.underlineColor):this.isFgRGB()}isUnderlineColorPalette(){return 268435456&this.bg&&~this.extended.underlineColor?16777216==(50331648&this.extended.underlineColor)||33554432==(50331648&this.extended.underlineColor):this.isFgPalette()}isUnderlineColorDefault(){return 268435456&this.bg&&~this.extended.underlineColor?0==(50331648&this.extended.underlineColor):this.isFgDefault()}getUnderlineStyle(){return 268435456&this.fg?268435456&this.bg?this.extended.underlineStyle:1:0}}t.AttributeData=i;class s{get ext(){return this._urlId?-469762049&this._ext|this.underlineStyle<<26:this._ext}set ext(e){this._ext=e}get underlineStyle(){return this._urlId?5:(469762048&this._ext)>>26}set underlineStyle(e){this._ext&=-469762049,this._ext|=e<<26&469762048}get underlineColor(){return 67108863&this._ext}set underlineColor(e){this._ext&=-67108864,this._ext|=67108863&e}get urlId(){return this._urlId}set urlId(e){this._urlId=e}constructor(e=0,t=0){this._ext=0,this._urlId=0,this._ext=e,this._urlId=t}clone(){return new s(this._ext,this._urlId)}isEmpty(){return 0===this.underlineStyle&&0===this._urlId}}t.ExtendedAttrs=s},9092:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.Buffer=t.MAX_BUFFER_SIZE=void 0;const s=i(6349),r=i(7226),n=i(3734),o=i(8437),a=i(4634),h=i(511),c=i(643),l=i(4863),d=i(7116);t.MAX_BUFFER_SIZE=4294967295,t.Buffer=class{constructor(e,t,i){this._hasScrollback=e,this._optionsService=t,this._bufferService=i,this.ydisp=0,this.ybase=0,this.y=0,this.x=0,this.tabs={},this.savedY=0,this.savedX=0,this.savedCurAttrData=o.DEFAULT_ATTR_DATA.clone(),this.savedCharset=d.DEFAULT_CHARSET,this.markers=[],this._nullCell=h.CellData.fromCharData([0,c.NULL_CELL_CHAR,c.NULL_CELL_WIDTH,c.NULL_CELL_CODE]),this._whitespaceCell=h.CellData.fromCharData([0,c.WHITESPACE_CELL_CHAR,c.WHITESPACE_CELL_WIDTH,c.WHITESPACE_CELL_CODE]),this._isClearing=!1,this._memoryCleanupQueue=new r.IdleTaskQueue,this._memoryCleanupPosition=0,this._cols=this._bufferService.cols,this._rows=this._bufferService.rows,this.lines=new s.CircularList(this._getCorrectBufferLength(this._rows)),this.scrollTop=0,this.scrollBottom=this._rows-1,this.setupTabStops()}getNullCell(e){return e?(this._nullCell.fg=e.fg,this._nullCell.bg=e.bg,this._nullCell.extended=e.extended):(this._nullCell.fg=0,this._nullCell.bg=0,this._nullCell.extended=new n.ExtendedAttrs),this._nullCell}getWhitespaceCell(e){return e?(this._whitespaceCell.fg=e.fg,this._whitespaceCell.bg=e.bg,this._whitespaceCell.extended=e.extended):(this._whitespaceCell.fg=0,this._whitespaceCell.bg=0,this._whitespaceCell.extended=new n.ExtendedAttrs),this._whitespaceCell}getBlankLine(e,t){return new o.BufferLine(this._bufferService.cols,this.getNullCell(e),t)}get hasScrollback(){return this._hasScrollback&&this.lines.maxLength>this._rows}get isCursorInViewport(){const e=this.ybase+this.y-this.ydisp;return e>=0&&et.MAX_BUFFER_SIZE?t.MAX_BUFFER_SIZE:i}fillViewportRows(e){if(0===this.lines.length){void 0===e&&(e=o.DEFAULT_ATTR_DATA);let t=this._rows;for(;t--;)this.lines.push(this.getBlankLine(e))}}clear(){this.ydisp=0,this.ybase=0,this.y=0,this.x=0,this.lines=new s.CircularList(this._getCorrectBufferLength(this._rows)),this.scrollTop=0,this.scrollBottom=this._rows-1,this.setupTabStops()}resize(e,t){const i=this.getNullCell(o.DEFAULT_ATTR_DATA);let s=0;const r=this._getCorrectBufferLength(t);if(r>this.lines.maxLength&&(this.lines.maxLength=r),this.lines.length>0){if(this._cols0&&this.lines.length<=this.ybase+this.y+n+1?(this.ybase--,n++,this.ydisp>0&&this.ydisp--):this.lines.push(new o.BufferLine(e,i)));else for(let e=this._rows;e>t;e--)this.lines.length>t+this.ybase&&(this.lines.length>this.ybase+this.y+1?this.lines.pop():(this.ybase++,this.ydisp++));if(r0&&(this.lines.trimStart(e),this.ybase=Math.max(this.ybase-e,0),this.ydisp=Math.max(this.ydisp-e,0),this.savedY=Math.max(this.savedY-e,0)),this.lines.maxLength=r}this.x=Math.min(this.x,e-1),this.y=Math.min(this.y,t-1),n&&(this.y+=n),this.savedX=Math.min(this.savedX,e-1),this.scrollTop=0}if(this.scrollBottom=t-1,this._isReflowEnabled&&(this._reflow(e,t),this._cols>e))for(let t=0;t.1*this.lines.length&&(this._memoryCleanupPosition=0,this._memoryCleanupQueue.enqueue((()=>this._batchedMemoryCleanup())))}_batchedMemoryCleanup(){let e=!0;this._memoryCleanupPosition>=this.lines.length&&(this._memoryCleanupPosition=0,e=!1);let t=0;for(;this._memoryCleanupPosition100)return!0;return e}get _isReflowEnabled(){const e=this._optionsService.rawOptions.windowsPty;return e&&e.buildNumber?this._hasScrollback&&"conpty"===e.backend&&e.buildNumber>=21376:this._hasScrollback&&!this._optionsService.rawOptions.windowsMode}_reflow(e,t){this._cols!==e&&(e>this._cols?this._reflowLarger(e,t):this._reflowSmaller(e,t))}_reflowLarger(e,t){const i=(0,a.reflowLargerGetLinesToRemove)(this.lines,this._cols,e,this.ybase+this.y,this.getNullCell(o.DEFAULT_ATTR_DATA));if(i.length>0){const s=(0,a.reflowLargerCreateNewLayout)(this.lines,i);(0,a.reflowLargerApplyNewLayout)(this.lines,s.layout),this._reflowLargerAdjustViewport(e,t,s.countRemoved)}}_reflowLargerAdjustViewport(e,t,i){const s=this.getNullCell(o.DEFAULT_ATTR_DATA);let r=i;for(;r-- >0;)0===this.ybase?(this.y>0&&this.y--,this.lines.length=0;n--){let h=this.lines.get(n);if(!h||!h.isWrapped&&h.getTrimmedLength()<=e)continue;const c=[h];for(;h.isWrapped&&n>0;)h=this.lines.get(--n),c.unshift(h);const l=this.ybase+this.y;if(l>=n&&l0&&(s.push({start:n+c.length+r,newLines:v}),r+=v.length),c.push(...v);let p=_.length-1,g=_[p];0===g&&(p--,g=_[p]);let m=c.length-u-1,S=d;for(;m>=0;){const e=Math.min(S,g);if(void 0===c[p])break;if(c[p].copyCellsFrom(c[m],S-e,g-e,e,!0),g-=e,0===g&&(p--,g=_[p]),S-=e,0===S){m--;const e=Math.max(m,0);S=(0,a.getWrappedLineTrimmedLength)(c,e,this._cols)}}for(let t=0;t0;)0===this.ybase?this.y0){const e=[],t=[];for(let e=0;e=0;c--)if(a&&a.start>n+h){for(let e=a.newLines.length-1;e>=0;e--)this.lines.set(c--,a.newLines[e]);c++,e.push({index:n+1,amount:a.newLines.length}),h+=a.newLines.length,a=s[++o]}else this.lines.set(c,t[n--]);let c=0;for(let t=e.length-1;t>=0;t--)e[t].index+=c,this.lines.onInsertEmitter.fire(e[t]),c+=e[t].amount;const l=Math.max(0,i+r-this.lines.maxLength);l>0&&this.lines.onTrimEmitter.fire(l)}}translateBufferLineToString(e,t,i=0,s){const r=this.lines.get(e);return r?r.translateToString(t,i,s):""}getWrappedRangeForLine(e){let t=e,i=e;for(;t>0&&this.lines.get(t).isWrapped;)t--;for(;i+10;);return e>=this._cols?this._cols-1:e<0?0:e}nextStop(e){for(null==e&&(e=this.x);!this.tabs[++e]&&e=this._cols?this._cols-1:e<0?0:e}clearMarkers(e){this._isClearing=!0;for(let t=0;t{t.line-=e,t.line<0&&t.dispose()}))),t.register(this.lines.onInsert((e=>{t.line>=e.index&&(t.line+=e.amount)}))),t.register(this.lines.onDelete((e=>{t.line>=e.index&&t.linee.index&&(t.line-=e.amount)}))),t.register(t.onDispose((()=>this._removeMarker(t)))),t}_removeMarker(e){this._isClearing||this.markers.splice(this.markers.indexOf(e),1)}}},8437:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.BufferLine=t.DEFAULT_ATTR_DATA=void 0;const s=i(3734),r=i(511),n=i(643),o=i(482);t.DEFAULT_ATTR_DATA=Object.freeze(new s.AttributeData);let a=0;class h{constructor(e,t,i=!1){this.isWrapped=i,this._combined={},this._extendedAttrs={},this._data=new Uint32Array(3*e);const s=t||r.CellData.fromCharData([0,n.NULL_CELL_CHAR,n.NULL_CELL_WIDTH,n.NULL_CELL_CODE]);for(let t=0;t>22,2097152&t?this._combined[e].charCodeAt(this._combined[e].length-1):i]}set(e,t){this._data[3*e+1]=t[n.CHAR_DATA_ATTR_INDEX],t[n.CHAR_DATA_CHAR_INDEX].length>1?(this._combined[e]=t[1],this._data[3*e+0]=2097152|e|t[n.CHAR_DATA_WIDTH_INDEX]<<22):this._data[3*e+0]=t[n.CHAR_DATA_CHAR_INDEX].charCodeAt(0)|t[n.CHAR_DATA_WIDTH_INDEX]<<22}getWidth(e){return this._data[3*e+0]>>22}hasWidth(e){return 12582912&this._data[3*e+0]}getFg(e){return this._data[3*e+1]}getBg(e){return this._data[3*e+2]}hasContent(e){return 4194303&this._data[3*e+0]}getCodePoint(e){const t=this._data[3*e+0];return 2097152&t?this._combined[e].charCodeAt(this._combined[e].length-1):2097151&t}isCombined(e){return 2097152&this._data[3*e+0]}getString(e){const t=this._data[3*e+0];return 2097152&t?this._combined[e]:2097151&t?(0,o.stringFromCodePoint)(2097151&t):""}isProtected(e){return 536870912&this._data[3*e+2]}loadCell(e,t){return a=3*e,t.content=this._data[a+0],t.fg=this._data[a+1],t.bg=this._data[a+2],2097152&t.content&&(t.combinedData=this._combined[e]),268435456&t.bg&&(t.extended=this._extendedAttrs[e]),t}setCell(e,t){2097152&t.content&&(this._combined[e]=t.combinedData),268435456&t.bg&&(this._extendedAttrs[e]=t.extended),this._data[3*e+0]=t.content,this._data[3*e+1]=t.fg,this._data[3*e+2]=t.bg}setCellFromCodePoint(e,t,i,s,r,n){268435456&r&&(this._extendedAttrs[e]=n),this._data[3*e+0]=t|i<<22,this._data[3*e+1]=s,this._data[3*e+2]=r}addCodepointToCell(e,t){let i=this._data[3*e+0];2097152&i?this._combined[e]+=(0,o.stringFromCodePoint)(t):(2097151&i?(this._combined[e]=(0,o.stringFromCodePoint)(2097151&i)+(0,o.stringFromCodePoint)(t),i&=-2097152,i|=2097152):i=t|1<<22,this._data[3*e+0]=i)}insertCells(e,t,i,n){if((e%=this.length)&&2===this.getWidth(e-1)&&this.setCellFromCodePoint(e-1,0,1,(null==n?void 0:n.fg)||0,(null==n?void 0:n.bg)||0,(null==n?void 0:n.extended)||new s.ExtendedAttrs),t=0;--i)this.setCell(e+t+i,this.loadCell(e+i,s));for(let s=0;sthis.length){if(this._data.buffer.byteLength>=4*i)this._data=new Uint32Array(this._data.buffer,0,i);else{const e=new Uint32Array(i);e.set(this._data),this._data=e}for(let i=this.length;i=e&&delete this._combined[s]}const s=Object.keys(this._extendedAttrs);for(let t=0;t=e&&delete this._extendedAttrs[i]}}return this.length=e,4*i*2=0;--e)if(4194303&this._data[3*e+0])return e+(this._data[3*e+0]>>22);return 0}getNoBgTrimmedLength(){for(let e=this.length-1;e>=0;--e)if(4194303&this._data[3*e+0]||50331648&this._data[3*e+2])return e+(this._data[3*e+0]>>22);return 0}copyCellsFrom(e,t,i,s,r){const n=e._data;if(r)for(let r=s-1;r>=0;r--){for(let e=0;e<3;e++)this._data[3*(i+r)+e]=n[3*(t+r)+e];268435456&n[3*(t+r)+2]&&(this._extendedAttrs[i+r]=e._extendedAttrs[t+r])}else for(let r=0;r=t&&(this._combined[r-t+i]=e._combined[r])}}translateToString(e=!1,t=0,i=this.length){e&&(i=Math.min(i,this.getTrimmedLength()));let s="";for(;t>22||1}return s}}t.BufferLine=h},4841:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.getRangeLength=void 0,t.getRangeLength=function(e,t){if(e.start.y>e.end.y)throw new Error(`Buffer range end (${e.end.x}, ${e.end.y}) cannot be before start (${e.start.x}, ${e.start.y})`);return t*(e.end.y-e.start.y)+(e.end.x-e.start.x+1)}},4634:(e,t)=>{function i(e,t,i){if(t===e.length-1)return e[t].getTrimmedLength();const s=!e[t].hasContent(i-1)&&1===e[t].getWidth(i-1),r=2===e[t+1].getWidth(0);return s&&r?i-1:i}Object.defineProperty(t,"__esModule",{value:!0}),t.getWrappedLineTrimmedLength=t.reflowSmallerGetNewLineLengths=t.reflowLargerApplyNewLayout=t.reflowLargerCreateNewLayout=t.reflowLargerGetLinesToRemove=void 0,t.reflowLargerGetLinesToRemove=function(e,t,s,r,n){const o=[];for(let a=0;a=a&&r0&&(e>d||0===l[e].getTrimmedLength());e--)v++;v>0&&(o.push(a+l.length-v),o.push(v)),a+=l.length-1}return o},t.reflowLargerCreateNewLayout=function(e,t){const i=[];let s=0,r=t[s],n=0;for(let o=0;oi(e,r,t))).reduce(((e,t)=>e+t));let o=0,a=0,h=0;for(;hc&&(o-=c,a++);const l=2===e[a].getWidth(o-1);l&&o--;const d=l?s-1:s;r.push(d),h+=d}return r},t.getWrappedLineTrimmedLength=i},5295:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.BufferSet=void 0;const s=i(8460),r=i(844),n=i(9092);class o extends r.Disposable{constructor(e,t){super(),this._optionsService=e,this._bufferService=t,this._onBufferActivate=this.register(new s.EventEmitter),this.onBufferActivate=this._onBufferActivate.event,this.reset(),this.register(this._optionsService.onSpecificOptionChange("scrollback",(()=>this.resize(this._bufferService.cols,this._bufferService.rows)))),this.register(this._optionsService.onSpecificOptionChange("tabStopWidth",(()=>this.setupTabStops())))}reset(){this._normal=new n.Buffer(!0,this._optionsService,this._bufferService),this._normal.fillViewportRows(),this._alt=new n.Buffer(!1,this._optionsService,this._bufferService),this._activeBuffer=this._normal,this._onBufferActivate.fire({activeBuffer:this._normal,inactiveBuffer:this._alt}),this.setupTabStops()}get alt(){return this._alt}get active(){return this._activeBuffer}get normal(){return this._normal}activateNormalBuffer(){this._activeBuffer!==this._normal&&(this._normal.x=this._alt.x,this._normal.y=this._alt.y,this._alt.clearAllMarkers(),this._alt.clear(),this._activeBuffer=this._normal,this._onBufferActivate.fire({activeBuffer:this._normal,inactiveBuffer:this._alt}))}activateAltBuffer(e){this._activeBuffer!==this._alt&&(this._alt.fillViewportRows(e),this._alt.x=this._normal.x,this._alt.y=this._normal.y,this._activeBuffer=this._alt,this._onBufferActivate.fire({activeBuffer:this._alt,inactiveBuffer:this._normal}))}resize(e,t){this._normal.resize(e,t),this._alt.resize(e,t),this.setupTabStops(e)}setupTabStops(e){this._normal.setupTabStops(e),this._alt.setupTabStops(e)}}t.BufferSet=o},511:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.CellData=void 0;const s=i(482),r=i(643),n=i(3734);class o extends n.AttributeData{constructor(){super(...arguments),this.content=0,this.fg=0,this.bg=0,this.extended=new n.ExtendedAttrs,this.combinedData=""}static fromCharData(e){const t=new o;return t.setFromCharData(e),t}isCombined(){return 2097152&this.content}getWidth(){return this.content>>22}getChars(){return 2097152&this.content?this.combinedData:2097151&this.content?(0,s.stringFromCodePoint)(2097151&this.content):""}getCode(){return this.isCombined()?this.combinedData.charCodeAt(this.combinedData.length-1):2097151&this.content}setFromCharData(e){this.fg=e[r.CHAR_DATA_ATTR_INDEX],this.bg=0;let t=!1;if(e[r.CHAR_DATA_CHAR_INDEX].length>2)t=!0;else if(2===e[r.CHAR_DATA_CHAR_INDEX].length){const i=e[r.CHAR_DATA_CHAR_INDEX].charCodeAt(0);if(55296<=i&&i<=56319){const s=e[r.CHAR_DATA_CHAR_INDEX].charCodeAt(1);56320<=s&&s<=57343?this.content=1024*(i-55296)+s-56320+65536|e[r.CHAR_DATA_WIDTH_INDEX]<<22:t=!0}else t=!0}else this.content=e[r.CHAR_DATA_CHAR_INDEX].charCodeAt(0)|e[r.CHAR_DATA_WIDTH_INDEX]<<22;t&&(this.combinedData=e[r.CHAR_DATA_CHAR_INDEX],this.content=2097152|e[r.CHAR_DATA_WIDTH_INDEX]<<22)}getAsCharData(){return[this.fg,this.getChars(),this.getWidth(),this.getCode()]}}t.CellData=o},643:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.WHITESPACE_CELL_CODE=t.WHITESPACE_CELL_WIDTH=t.WHITESPACE_CELL_CHAR=t.NULL_CELL_CODE=t.NULL_CELL_WIDTH=t.NULL_CELL_CHAR=t.CHAR_DATA_CODE_INDEX=t.CHAR_DATA_WIDTH_INDEX=t.CHAR_DATA_CHAR_INDEX=t.CHAR_DATA_ATTR_INDEX=t.DEFAULT_EXT=t.DEFAULT_ATTR=t.DEFAULT_COLOR=void 0,t.DEFAULT_COLOR=0,t.DEFAULT_ATTR=256|t.DEFAULT_COLOR<<9,t.DEFAULT_EXT=0,t.CHAR_DATA_ATTR_INDEX=0,t.CHAR_DATA_CHAR_INDEX=1,t.CHAR_DATA_WIDTH_INDEX=2,t.CHAR_DATA_CODE_INDEX=3,t.NULL_CELL_CHAR="",t.NULL_CELL_WIDTH=1,t.NULL_CELL_CODE=0,t.WHITESPACE_CELL_CHAR=" ",t.WHITESPACE_CELL_WIDTH=1,t.WHITESPACE_CELL_CODE=32},4863:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.Marker=void 0;const s=i(8460),r=i(844);class n{get id(){return this._id}constructor(e){this.line=e,this.isDisposed=!1,this._disposables=[],this._id=n._nextId++,this._onDispose=this.register(new s.EventEmitter),this.onDispose=this._onDispose.event}dispose(){this.isDisposed||(this.isDisposed=!0,this.line=-1,this._onDispose.fire(),(0,r.disposeArray)(this._disposables),this._disposables.length=0)}register(e){return this._disposables.push(e),e}}t.Marker=n,n._nextId=1},7116:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.DEFAULT_CHARSET=t.CHARSETS=void 0,t.CHARSETS={},t.DEFAULT_CHARSET=t.CHARSETS.B,t.CHARSETS[0]={"`":"◆",a:"▒",b:"␉",c:"␌",d:"␍",e:"␊",f:"°",g:"±",h:"␤",i:"␋",j:"┘",k:"┐",l:"┌",m:"└",n:"┼",o:"⎺",p:"⎻",q:"─",r:"⎼",s:"⎽",t:"├",u:"┤",v:"┴",w:"┬",x:"│",y:"≤",z:"≥","{":"π","|":"≠","}":"£","~":"·"},t.CHARSETS.A={"#":"£"},t.CHARSETS.B=void 0,t.CHARSETS[4]={"#":"£","@":"¾","[":"ij","\\":"½","]":"|","{":"¨","|":"f","}":"¼","~":"´"},t.CHARSETS.C=t.CHARSETS[5]={"[":"Ä","\\":"Ö","]":"Å","^":"Ü","`":"é","{":"ä","|":"ö","}":"å","~":"ü"},t.CHARSETS.R={"#":"£","@":"à","[":"°","\\":"ç","]":"§","{":"é","|":"ù","}":"è","~":"¨"},t.CHARSETS.Q={"@":"à","[":"â","\\":"ç","]":"ê","^":"î","`":"ô","{":"é","|":"ù","}":"è","~":"û"},t.CHARSETS.K={"@":"§","[":"Ä","\\":"Ö","]":"Ü","{":"ä","|":"ö","}":"ü","~":"ß"},t.CHARSETS.Y={"#":"£","@":"§","[":"°","\\":"ç","]":"é","`":"ù","{":"à","|":"ò","}":"è","~":"ì"},t.CHARSETS.E=t.CHARSETS[6]={"@":"Ä","[":"Æ","\\":"Ø","]":"Å","^":"Ü","`":"ä","{":"æ","|":"ø","}":"å","~":"ü"},t.CHARSETS.Z={"#":"£","@":"§","[":"¡","\\":"Ñ","]":"¿","{":"°","|":"ñ","}":"ç"},t.CHARSETS.H=t.CHARSETS[7]={"@":"É","[":"Ä","\\":"Ö","]":"Å","^":"Ü","`":"é","{":"ä","|":"ö","}":"å","~":"ü"},t.CHARSETS["="]={"#":"ù","@":"à","[":"é","\\":"ç","]":"ê","^":"î",_:"è","`":"ô","{":"ä","|":"ö","}":"ü","~":"û"}},2584:(e,t)=>{var i,s,r;Object.defineProperty(t,"__esModule",{value:!0}),t.C1_ESCAPED=t.C1=t.C0=void 0,function(e){e.NUL="\0",e.SOH="",e.STX="",e.ETX="",e.EOT="",e.ENQ="",e.ACK="",e.BEL="",e.BS="\b",e.HT="\t",e.LF="\n",e.VT="\v",e.FF="\f",e.CR="\r",e.SO="",e.SI="",e.DLE="",e.DC1="",e.DC2="",e.DC3="",e.DC4="",e.NAK="",e.SYN="",e.ETB="",e.CAN="",e.EM="",e.SUB="",e.ESC="",e.FS="",e.GS="",e.RS="",e.US="",e.SP=" ",e.DEL=""}(i||(t.C0=i={})),function(e){e.PAD="€",e.HOP="",e.BPH="‚",e.NBH="ƒ",e.IND="„",e.NEL="…",e.SSA="†",e.ESA="‡",e.HTS="ˆ",e.HTJ="‰",e.VTS="Š",e.PLD="‹",e.PLU="Œ",e.RI="",e.SS2="Ž",e.SS3="",e.DCS="",e.PU1="‘",e.PU2="’",e.STS="“",e.CCH="”",e.MW="•",e.SPA="–",e.EPA="—",e.SOS="˜",e.SGCI="™",e.SCI="š",e.CSI="›",e.ST="œ",e.OSC="",e.PM="ž",e.APC="Ÿ"}(s||(t.C1=s={})),function(e){e.ST=`${i.ESC}\\`}(r||(t.C1_ESCAPED=r={}))},7399:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.evaluateKeyboardEvent=void 0;const s=i(2584),r={48:["0",")"],49:["1","!"],50:["2","@"],51:["3","#"],52:["4","$"],53:["5","%"],54:["6","^"],55:["7","&"],56:["8","*"],57:["9","("],186:[";",":"],187:["=","+"],188:[",","<"],189:["-","_"],190:[".",">"],191:["/","?"],192:["`","~"],219:["[","{"],220:["\\","|"],221:["]","}"],222:["'",'"']};t.evaluateKeyboardEvent=function(e,t,i,n){const o={type:0,cancel:!1,key:void 0},a=(e.shiftKey?1:0)|(e.altKey?2:0)|(e.ctrlKey?4:0)|(e.metaKey?8:0);switch(e.keyCode){case 0:"UIKeyInputUpArrow"===e.key?o.key=t?s.C0.ESC+"OA":s.C0.ESC+"[A":"UIKeyInputLeftArrow"===e.key?o.key=t?s.C0.ESC+"OD":s.C0.ESC+"[D":"UIKeyInputRightArrow"===e.key?o.key=t?s.C0.ESC+"OC":s.C0.ESC+"[C":"UIKeyInputDownArrow"===e.key&&(o.key=t?s.C0.ESC+"OB":s.C0.ESC+"[B");break;case 8:if(e.altKey){o.key=s.C0.ESC+s.C0.DEL;break}o.key=s.C0.DEL;break;case 9:if(e.shiftKey){o.key=s.C0.ESC+"[Z";break}o.key=s.C0.HT,o.cancel=!0;break;case 13:o.key=e.altKey?s.C0.ESC+s.C0.CR:s.C0.CR,o.cancel=!0;break;case 27:o.key=s.C0.ESC,e.altKey&&(o.key=s.C0.ESC+s.C0.ESC),o.cancel=!0;break;case 37:if(e.metaKey)break;a?(o.key=s.C0.ESC+"[1;"+(a+1)+"D",o.key===s.C0.ESC+"[1;3D"&&(o.key=s.C0.ESC+(i?"b":"[1;5D"))):o.key=t?s.C0.ESC+"OD":s.C0.ESC+"[D";break;case 39:if(e.metaKey)break;a?(o.key=s.C0.ESC+"[1;"+(a+1)+"C",o.key===s.C0.ESC+"[1;3C"&&(o.key=s.C0.ESC+(i?"f":"[1;5C"))):o.key=t?s.C0.ESC+"OC":s.C0.ESC+"[C";break;case 38:if(e.metaKey)break;a?(o.key=s.C0.ESC+"[1;"+(a+1)+"A",i||o.key!==s.C0.ESC+"[1;3A"||(o.key=s.C0.ESC+"[1;5A")):o.key=t?s.C0.ESC+"OA":s.C0.ESC+"[A";break;case 40:if(e.metaKey)break;a?(o.key=s.C0.ESC+"[1;"+(a+1)+"B",i||o.key!==s.C0.ESC+"[1;3B"||(o.key=s.C0.ESC+"[1;5B")):o.key=t?s.C0.ESC+"OB":s.C0.ESC+"[B";break;case 45:e.shiftKey||e.ctrlKey||(o.key=s.C0.ESC+"[2~");break;case 46:o.key=a?s.C0.ESC+"[3;"+(a+1)+"~":s.C0.ESC+"[3~";break;case 36:o.key=a?s.C0.ESC+"[1;"+(a+1)+"H":t?s.C0.ESC+"OH":s.C0.ESC+"[H";break;case 35:o.key=a?s.C0.ESC+"[1;"+(a+1)+"F":t?s.C0.ESC+"OF":s.C0.ESC+"[F";break;case 33:e.shiftKey?o.type=2:e.ctrlKey?o.key=s.C0.ESC+"[5;"+(a+1)+"~":o.key=s.C0.ESC+"[5~";break;case 34:e.shiftKey?o.type=3:e.ctrlKey?o.key=s.C0.ESC+"[6;"+(a+1)+"~":o.key=s.C0.ESC+"[6~";break;case 112:o.key=a?s.C0.ESC+"[1;"+(a+1)+"P":s.C0.ESC+"OP";break;case 113:o.key=a?s.C0.ESC+"[1;"+(a+1)+"Q":s.C0.ESC+"OQ";break;case 114:o.key=a?s.C0.ESC+"[1;"+(a+1)+"R":s.C0.ESC+"OR";break;case 115:o.key=a?s.C0.ESC+"[1;"+(a+1)+"S":s.C0.ESC+"OS";break;case 116:o.key=a?s.C0.ESC+"[15;"+(a+1)+"~":s.C0.ESC+"[15~";break;case 117:o.key=a?s.C0.ESC+"[17;"+(a+1)+"~":s.C0.ESC+"[17~";break;case 118:o.key=a?s.C0.ESC+"[18;"+(a+1)+"~":s.C0.ESC+"[18~";break;case 119:o.key=a?s.C0.ESC+"[19;"+(a+1)+"~":s.C0.ESC+"[19~";break;case 120:o.key=a?s.C0.ESC+"[20;"+(a+1)+"~":s.C0.ESC+"[20~";break;case 121:o.key=a?s.C0.ESC+"[21;"+(a+1)+"~":s.C0.ESC+"[21~";break;case 122:o.key=a?s.C0.ESC+"[23;"+(a+1)+"~":s.C0.ESC+"[23~";break;case 123:o.key=a?s.C0.ESC+"[24;"+(a+1)+"~":s.C0.ESC+"[24~";break;default:if(!e.ctrlKey||e.shiftKey||e.altKey||e.metaKey)if(i&&!n||!e.altKey||e.metaKey)!i||e.altKey||e.ctrlKey||e.shiftKey||!e.metaKey?e.key&&!e.ctrlKey&&!e.altKey&&!e.metaKey&&e.keyCode>=48&&1===e.key.length?o.key=e.key:e.key&&e.ctrlKey&&("_"===e.key&&(o.key=s.C0.US),"@"===e.key&&(o.key=s.C0.NUL)):65===e.keyCode&&(o.type=1);else{const t=r[e.keyCode],i=null==t?void 0:t[e.shiftKey?1:0];if(i)o.key=s.C0.ESC+i;else if(e.keyCode>=65&&e.keyCode<=90){const t=e.ctrlKey?e.keyCode-64:e.keyCode+32;let i=String.fromCharCode(t);e.shiftKey&&(i=i.toUpperCase()),o.key=s.C0.ESC+i}else if(32===e.keyCode)o.key=s.C0.ESC+(e.ctrlKey?s.C0.NUL:" ");else if("Dead"===e.key&&e.code.startsWith("Key")){let t=e.code.slice(3,4);e.shiftKey||(t=t.toLowerCase()),o.key=s.C0.ESC+t,o.cancel=!0}}else e.keyCode>=65&&e.keyCode<=90?o.key=String.fromCharCode(e.keyCode-64):32===e.keyCode?o.key=s.C0.NUL:e.keyCode>=51&&e.keyCode<=55?o.key=String.fromCharCode(e.keyCode-51+27):56===e.keyCode?o.key=s.C0.DEL:219===e.keyCode?o.key=s.C0.ESC:220===e.keyCode?o.key=s.C0.FS:221===e.keyCode&&(o.key=s.C0.GS)}return o}},482:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.Utf8ToUtf32=t.StringToUtf32=t.utf32ToString=t.stringFromCodePoint=void 0,t.stringFromCodePoint=function(e){return e>65535?(e-=65536,String.fromCharCode(55296+(e>>10))+String.fromCharCode(e%1024+56320)):String.fromCharCode(e)},t.utf32ToString=function(e,t=0,i=e.length){let s="";for(let r=t;r65535?(t-=65536,s+=String.fromCharCode(55296+(t>>10))+String.fromCharCode(t%1024+56320)):s+=String.fromCharCode(t)}return s},t.StringToUtf32=class{constructor(){this._interim=0}clear(){this._interim=0}decode(e,t){const i=e.length;if(!i)return 0;let s=0,r=0;if(this._interim){const i=e.charCodeAt(r++);56320<=i&&i<=57343?t[s++]=1024*(this._interim-55296)+i-56320+65536:(t[s++]=this._interim,t[s++]=i),this._interim=0}for(let n=r;n=i)return this._interim=r,s;const o=e.charCodeAt(n);56320<=o&&o<=57343?t[s++]=1024*(r-55296)+o-56320+65536:(t[s++]=r,t[s++]=o)}else 65279!==r&&(t[s++]=r)}return s}},t.Utf8ToUtf32=class{constructor(){this.interim=new Uint8Array(3)}clear(){this.interim.fill(0)}decode(e,t){const i=e.length;if(!i)return 0;let s,r,n,o,a=0,h=0,c=0;if(this.interim[0]){let s=!1,r=this.interim[0];r&=192==(224&r)?31:224==(240&r)?15:7;let n,o=0;for(;(n=63&this.interim[++o])&&o<4;)r<<=6,r|=n;const h=192==(224&this.interim[0])?2:224==(240&this.interim[0])?3:4,l=h-o;for(;c=i)return 0;if(n=e[c++],128!=(192&n)){c--,s=!0;break}this.interim[o++]=n,r<<=6,r|=63&n}s||(2===h?r<128?c--:t[a++]=r:3===h?r<2048||r>=55296&&r<=57343||65279===r||(t[a++]=r):r<65536||r>1114111||(t[a++]=r)),this.interim.fill(0)}const l=i-4;let d=c;for(;d=i)return this.interim[0]=s,a;if(r=e[d++],128!=(192&r)){d--;continue}if(h=(31&s)<<6|63&r,h<128){d--;continue}t[a++]=h}else if(224==(240&s)){if(d>=i)return this.interim[0]=s,a;if(r=e[d++],128!=(192&r)){d--;continue}if(d>=i)return this.interim[0]=s,this.interim[1]=r,a;if(n=e[d++],128!=(192&n)){d--;continue}if(h=(15&s)<<12|(63&r)<<6|63&n,h<2048||h>=55296&&h<=57343||65279===h)continue;t[a++]=h}else if(240==(248&s)){if(d>=i)return this.interim[0]=s,a;if(r=e[d++],128!=(192&r)){d--;continue}if(d>=i)return this.interim[0]=s,this.interim[1]=r,a;if(n=e[d++],128!=(192&n)){d--;continue}if(d>=i)return this.interim[0]=s,this.interim[1]=r,this.interim[2]=n,a;if(o=e[d++],128!=(192&o)){d--;continue}if(h=(7&s)<<18|(63&r)<<12|(63&n)<<6|63&o,h<65536||h>1114111)continue;t[a++]=h}}return a}}},225:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.UnicodeV6=void 0;const i=[[768,879],[1155,1158],[1160,1161],[1425,1469],[1471,1471],[1473,1474],[1476,1477],[1479,1479],[1536,1539],[1552,1557],[1611,1630],[1648,1648],[1750,1764],[1767,1768],[1770,1773],[1807,1807],[1809,1809],[1840,1866],[1958,1968],[2027,2035],[2305,2306],[2364,2364],[2369,2376],[2381,2381],[2385,2388],[2402,2403],[2433,2433],[2492,2492],[2497,2500],[2509,2509],[2530,2531],[2561,2562],[2620,2620],[2625,2626],[2631,2632],[2635,2637],[2672,2673],[2689,2690],[2748,2748],[2753,2757],[2759,2760],[2765,2765],[2786,2787],[2817,2817],[2876,2876],[2879,2879],[2881,2883],[2893,2893],[2902,2902],[2946,2946],[3008,3008],[3021,3021],[3134,3136],[3142,3144],[3146,3149],[3157,3158],[3260,3260],[3263,3263],[3270,3270],[3276,3277],[3298,3299],[3393,3395],[3405,3405],[3530,3530],[3538,3540],[3542,3542],[3633,3633],[3636,3642],[3655,3662],[3761,3761],[3764,3769],[3771,3772],[3784,3789],[3864,3865],[3893,3893],[3895,3895],[3897,3897],[3953,3966],[3968,3972],[3974,3975],[3984,3991],[3993,4028],[4038,4038],[4141,4144],[4146,4146],[4150,4151],[4153,4153],[4184,4185],[4448,4607],[4959,4959],[5906,5908],[5938,5940],[5970,5971],[6002,6003],[6068,6069],[6071,6077],[6086,6086],[6089,6099],[6109,6109],[6155,6157],[6313,6313],[6432,6434],[6439,6440],[6450,6450],[6457,6459],[6679,6680],[6912,6915],[6964,6964],[6966,6970],[6972,6972],[6978,6978],[7019,7027],[7616,7626],[7678,7679],[8203,8207],[8234,8238],[8288,8291],[8298,8303],[8400,8431],[12330,12335],[12441,12442],[43014,43014],[43019,43019],[43045,43046],[64286,64286],[65024,65039],[65056,65059],[65279,65279],[65529,65531]],s=[[68097,68099],[68101,68102],[68108,68111],[68152,68154],[68159,68159],[119143,119145],[119155,119170],[119173,119179],[119210,119213],[119362,119364],[917505,917505],[917536,917631],[917760,917999]];let r;t.UnicodeV6=class{constructor(){if(this.version="6",!r){r=new Uint8Array(65536),r.fill(1),r[0]=0,r.fill(0,1,32),r.fill(0,127,160),r.fill(2,4352,4448),r[9001]=2,r[9002]=2,r.fill(2,11904,42192),r[12351]=1,r.fill(2,44032,55204),r.fill(2,63744,64256),r.fill(2,65040,65050),r.fill(2,65072,65136),r.fill(2,65280,65377),r.fill(2,65504,65511);for(let e=0;et[r][1])return!1;for(;r>=s;)if(i=s+r>>1,e>t[i][1])s=i+1;else{if(!(e=131072&&e<=196605||e>=196608&&e<=262141?2:1}}},5981:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.WriteBuffer=void 0;const s=i(8460),r=i(844);class n extends r.Disposable{constructor(e){super(),this._action=e,this._writeBuffer=[],this._callbacks=[],this._pendingData=0,this._bufferOffset=0,this._isSyncWriting=!1,this._syncCalls=0,this._didUserInput=!1,this._onWriteParsed=this.register(new s.EventEmitter),this.onWriteParsed=this._onWriteParsed.event}handleUserInput(){this._didUserInput=!0}writeSync(e,t){if(void 0!==t&&this._syncCalls>t)return void(this._syncCalls=0);if(this._pendingData+=e.length,this._writeBuffer.push(e),this._callbacks.push(void 0),this._syncCalls++,this._isSyncWriting)return;let i;for(this._isSyncWriting=!0;i=this._writeBuffer.shift();){this._action(i);const e=this._callbacks.shift();e&&e()}this._pendingData=0,this._bufferOffset=2147483647,this._isSyncWriting=!1,this._syncCalls=0}write(e,t){if(this._pendingData>5e7)throw new Error("write data discarded, use flow control to avoid losing data");if(!this._writeBuffer.length){if(this._bufferOffset=0,this._didUserInput)return this._didUserInput=!1,this._pendingData+=e.length,this._writeBuffer.push(e),this._callbacks.push(t),void this._innerWrite();setTimeout((()=>this._innerWrite()))}this._pendingData+=e.length,this._writeBuffer.push(e),this._callbacks.push(t)}_innerWrite(e=0,t=!0){const i=e||Date.now();for(;this._writeBuffer.length>this._bufferOffset;){const e=this._writeBuffer[this._bufferOffset],s=this._action(e,t);if(s){const e=e=>Date.now()-i>=12?setTimeout((()=>this._innerWrite(0,e))):this._innerWrite(i,e);return void s.catch((e=>(queueMicrotask((()=>{throw e})),Promise.resolve(!1)))).then(e)}const r=this._callbacks[this._bufferOffset];if(r&&r(),this._bufferOffset++,this._pendingData-=e.length,Date.now()-i>=12)break}this._writeBuffer.length>this._bufferOffset?(this._bufferOffset>50&&(this._writeBuffer=this._writeBuffer.slice(this._bufferOffset),this._callbacks=this._callbacks.slice(this._bufferOffset),this._bufferOffset=0),setTimeout((()=>this._innerWrite()))):(this._writeBuffer.length=0,this._callbacks.length=0,this._pendingData=0,this._bufferOffset=0),this._onWriteParsed.fire()}}t.WriteBuffer=n},5941:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.toRgbString=t.parseColor=void 0;const i=/^([\da-f])\/([\da-f])\/([\da-f])$|^([\da-f]{2})\/([\da-f]{2})\/([\da-f]{2})$|^([\da-f]{3})\/([\da-f]{3})\/([\da-f]{3})$|^([\da-f]{4})\/([\da-f]{4})\/([\da-f]{4})$/,s=/^[\da-f]+$/;function r(e,t){const i=e.toString(16),s=i.length<2?"0"+i:i;switch(t){case 4:return i[0];case 8:return s;case 12:return(s+s).slice(0,3);default:return s+s}}t.parseColor=function(e){if(!e)return;let t=e.toLowerCase();if(0===t.indexOf("rgb:")){t=t.slice(4);const e=i.exec(t);if(e){const t=e[1]?15:e[4]?255:e[7]?4095:65535;return[Math.round(parseInt(e[1]||e[4]||e[7]||e[10],16)/t*255),Math.round(parseInt(e[2]||e[5]||e[8]||e[11],16)/t*255),Math.round(parseInt(e[3]||e[6]||e[9]||e[12],16)/t*255)]}}else if(0===t.indexOf("#")&&(t=t.slice(1),s.exec(t)&&[3,6,9,12].includes(t.length))){const e=t.length/3,i=[0,0,0];for(let s=0;s<3;++s){const r=parseInt(t.slice(e*s,e*s+e),16);i[s]=1===e?r<<4:2===e?r:3===e?r>>4:r>>8}return i}},t.toRgbString=function(e,t=16){const[i,s,n]=e;return`rgb:${r(i,t)}/${r(s,t)}/${r(n,t)}`}},5770:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.PAYLOAD_LIMIT=void 0,t.PAYLOAD_LIMIT=1e7},6351:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.DcsHandler=t.DcsParser=void 0;const s=i(482),r=i(8742),n=i(5770),o=[];t.DcsParser=class{constructor(){this._handlers=Object.create(null),this._active=o,this._ident=0,this._handlerFb=()=>{},this._stack={paused:!1,loopPosition:0,fallThrough:!1}}dispose(){this._handlers=Object.create(null),this._handlerFb=()=>{},this._active=o}registerHandler(e,t){void 0===this._handlers[e]&&(this._handlers[e]=[]);const i=this._handlers[e];return i.push(t),{dispose:()=>{const e=i.indexOf(t);-1!==e&&i.splice(e,1)}}}clearHandler(e){this._handlers[e]&&delete this._handlers[e]}setHandlerFallback(e){this._handlerFb=e}reset(){if(this._active.length)for(let e=this._stack.paused?this._stack.loopPosition-1:this._active.length-1;e>=0;--e)this._active[e].unhook(!1);this._stack.paused=!1,this._active=o,this._ident=0}hook(e,t){if(this.reset(),this._ident=e,this._active=this._handlers[e]||o,this._active.length)for(let e=this._active.length-1;e>=0;e--)this._active[e].hook(t);else this._handlerFb(this._ident,"HOOK",t)}put(e,t,i){if(this._active.length)for(let s=this._active.length-1;s>=0;s--)this._active[s].put(e,t,i);else this._handlerFb(this._ident,"PUT",(0,s.utf32ToString)(e,t,i))}unhook(e,t=!0){if(this._active.length){let i=!1,s=this._active.length-1,r=!1;if(this._stack.paused&&(s=this._stack.loopPosition-1,i=t,r=this._stack.fallThrough,this._stack.paused=!1),!r&&!1===i){for(;s>=0&&(i=this._active[s].unhook(e),!0!==i);s--)if(i instanceof Promise)return this._stack.paused=!0,this._stack.loopPosition=s,this._stack.fallThrough=!1,i;s--}for(;s>=0;s--)if(i=this._active[s].unhook(!1),i instanceof Promise)return this._stack.paused=!0,this._stack.loopPosition=s,this._stack.fallThrough=!0,i}else this._handlerFb(this._ident,"UNHOOK",e);this._active=o,this._ident=0}};const a=new r.Params;a.addParam(0),t.DcsHandler=class{constructor(e){this._handler=e,this._data="",this._params=a,this._hitLimit=!1}hook(e){this._params=e.length>1||e.params[0]?e.clone():a,this._data="",this._hitLimit=!1}put(e,t,i){this._hitLimit||(this._data+=(0,s.utf32ToString)(e,t,i),this._data.length>n.PAYLOAD_LIMIT&&(this._data="",this._hitLimit=!0))}unhook(e){let t=!1;if(this._hitLimit)t=!1;else if(e&&(t=this._handler(this._data,this._params),t instanceof Promise))return t.then((e=>(this._params=a,this._data="",this._hitLimit=!1,e)));return this._params=a,this._data="",this._hitLimit=!1,t}}},2015:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.EscapeSequenceParser=t.VT500_TRANSITION_TABLE=t.TransitionTable=void 0;const s=i(844),r=i(8742),n=i(6242),o=i(6351);class a{constructor(e){this.table=new Uint8Array(e)}setDefault(e,t){this.table.fill(e<<4|t)}add(e,t,i,s){this.table[t<<8|e]=i<<4|s}addMany(e,t,i,s){for(let r=0;rt)),i=(e,i)=>t.slice(e,i),s=i(32,127),r=i(0,24);r.push(25),r.push.apply(r,i(28,32));const n=i(0,14);let o;for(o in e.setDefault(1,0),e.addMany(s,0,2,0),n)e.addMany([24,26,153,154],o,3,0),e.addMany(i(128,144),o,3,0),e.addMany(i(144,152),o,3,0),e.add(156,o,0,0),e.add(27,o,11,1),e.add(157,o,4,8),e.addMany([152,158,159],o,0,7),e.add(155,o,11,3),e.add(144,o,11,9);return e.addMany(r,0,3,0),e.addMany(r,1,3,1),e.add(127,1,0,1),e.addMany(r,8,0,8),e.addMany(r,3,3,3),e.add(127,3,0,3),e.addMany(r,4,3,4),e.add(127,4,0,4),e.addMany(r,6,3,6),e.addMany(r,5,3,5),e.add(127,5,0,5),e.addMany(r,2,3,2),e.add(127,2,0,2),e.add(93,1,4,8),e.addMany(s,8,5,8),e.add(127,8,5,8),e.addMany([156,27,24,26,7],8,6,0),e.addMany(i(28,32),8,0,8),e.addMany([88,94,95],1,0,7),e.addMany(s,7,0,7),e.addMany(r,7,0,7),e.add(156,7,0,0),e.add(127,7,0,7),e.add(91,1,11,3),e.addMany(i(64,127),3,7,0),e.addMany(i(48,60),3,8,4),e.addMany([60,61,62,63],3,9,4),e.addMany(i(48,60),4,8,4),e.addMany(i(64,127),4,7,0),e.addMany([60,61,62,63],4,0,6),e.addMany(i(32,64),6,0,6),e.add(127,6,0,6),e.addMany(i(64,127),6,0,0),e.addMany(i(32,48),3,9,5),e.addMany(i(32,48),5,9,5),e.addMany(i(48,64),5,0,6),e.addMany(i(64,127),5,7,0),e.addMany(i(32,48),4,9,5),e.addMany(i(32,48),1,9,2),e.addMany(i(32,48),2,9,2),e.addMany(i(48,127),2,10,0),e.addMany(i(48,80),1,10,0),e.addMany(i(81,88),1,10,0),e.addMany([89,90,92],1,10,0),e.addMany(i(96,127),1,10,0),e.add(80,1,11,9),e.addMany(r,9,0,9),e.add(127,9,0,9),e.addMany(i(28,32),9,0,9),e.addMany(i(32,48),9,9,12),e.addMany(i(48,60),9,8,10),e.addMany([60,61,62,63],9,9,10),e.addMany(r,11,0,11),e.addMany(i(32,128),11,0,11),e.addMany(i(28,32),11,0,11),e.addMany(r,10,0,10),e.add(127,10,0,10),e.addMany(i(28,32),10,0,10),e.addMany(i(48,60),10,8,10),e.addMany([60,61,62,63],10,0,11),e.addMany(i(32,48),10,9,12),e.addMany(r,12,0,12),e.add(127,12,0,12),e.addMany(i(28,32),12,0,12),e.addMany(i(32,48),12,9,12),e.addMany(i(48,64),12,0,11),e.addMany(i(64,127),12,12,13),e.addMany(i(64,127),10,12,13),e.addMany(i(64,127),9,12,13),e.addMany(r,13,13,13),e.addMany(s,13,13,13),e.add(127,13,0,13),e.addMany([27,156,24,26],13,14,0),e.add(h,0,2,0),e.add(h,8,5,8),e.add(h,6,0,6),e.add(h,11,0,11),e.add(h,13,13,13),e}();class c extends s.Disposable{constructor(e=t.VT500_TRANSITION_TABLE){super(),this._transitions=e,this._parseStack={state:0,handlers:[],handlerPos:0,transition:0,chunkPos:0},this.initialState=0,this.currentState=this.initialState,this._params=new r.Params,this._params.addParam(0),this._collect=0,this.precedingCodepoint=0,this._printHandlerFb=(e,t,i)=>{},this._executeHandlerFb=e=>{},this._csiHandlerFb=(e,t)=>{},this._escHandlerFb=e=>{},this._errorHandlerFb=e=>e,this._printHandler=this._printHandlerFb,this._executeHandlers=Object.create(null),this._csiHandlers=Object.create(null),this._escHandlers=Object.create(null),this.register((0,s.toDisposable)((()=>{this._csiHandlers=Object.create(null),this._executeHandlers=Object.create(null),this._escHandlers=Object.create(null)}))),this._oscParser=this.register(new n.OscParser),this._dcsParser=this.register(new o.DcsParser),this._errorHandler=this._errorHandlerFb,this.registerEscHandler({final:"\\"},(()=>!0))}_identifier(e,t=[64,126]){let i=0;if(e.prefix){if(e.prefix.length>1)throw new Error("only one byte as prefix supported");if(i=e.prefix.charCodeAt(0),i&&60>i||i>63)throw new Error("prefix must be in range 0x3c .. 0x3f")}if(e.intermediates){if(e.intermediates.length>2)throw new Error("only two bytes as intermediates are supported");for(let t=0;ts||s>47)throw new Error("intermediate must be in range 0x20 .. 0x2f");i<<=8,i|=s}}if(1!==e.final.length)throw new Error("final must be a single byte");const s=e.final.charCodeAt(0);if(t[0]>s||s>t[1])throw new Error(`final must be in range ${t[0]} .. ${t[1]}`);return i<<=8,i|=s,i}identToString(e){const t=[];for(;e;)t.push(String.fromCharCode(255&e)),e>>=8;return t.reverse().join("")}setPrintHandler(e){this._printHandler=e}clearPrintHandler(){this._printHandler=this._printHandlerFb}registerEscHandler(e,t){const i=this._identifier(e,[48,126]);void 0===this._escHandlers[i]&&(this._escHandlers[i]=[]);const s=this._escHandlers[i];return s.push(t),{dispose:()=>{const e=s.indexOf(t);-1!==e&&s.splice(e,1)}}}clearEscHandler(e){this._escHandlers[this._identifier(e,[48,126])]&&delete this._escHandlers[this._identifier(e,[48,126])]}setEscHandlerFallback(e){this._escHandlerFb=e}setExecuteHandler(e,t){this._executeHandlers[e.charCodeAt(0)]=t}clearExecuteHandler(e){this._executeHandlers[e.charCodeAt(0)]&&delete this._executeHandlers[e.charCodeAt(0)]}setExecuteHandlerFallback(e){this._executeHandlerFb=e}registerCsiHandler(e,t){const i=this._identifier(e);void 0===this._csiHandlers[i]&&(this._csiHandlers[i]=[]);const s=this._csiHandlers[i];return s.push(t),{dispose:()=>{const e=s.indexOf(t);-1!==e&&s.splice(e,1)}}}clearCsiHandler(e){this._csiHandlers[this._identifier(e)]&&delete this._csiHandlers[this._identifier(e)]}setCsiHandlerFallback(e){this._csiHandlerFb=e}registerDcsHandler(e,t){return this._dcsParser.registerHandler(this._identifier(e),t)}clearDcsHandler(e){this._dcsParser.clearHandler(this._identifier(e))}setDcsHandlerFallback(e){this._dcsParser.setHandlerFallback(e)}registerOscHandler(e,t){return this._oscParser.registerHandler(e,t)}clearOscHandler(e){this._oscParser.clearHandler(e)}setOscHandlerFallback(e){this._oscParser.setHandlerFallback(e)}setErrorHandler(e){this._errorHandler=e}clearErrorHandler(){this._errorHandler=this._errorHandlerFb}reset(){this.currentState=this.initialState,this._oscParser.reset(),this._dcsParser.reset(),this._params.reset(),this._params.addParam(0),this._collect=0,this.precedingCodepoint=0,0!==this._parseStack.state&&(this._parseStack.state=2,this._parseStack.handlers=[])}_preserveStack(e,t,i,s,r){this._parseStack.state=e,this._parseStack.handlers=t,this._parseStack.handlerPos=i,this._parseStack.transition=s,this._parseStack.chunkPos=r}parse(e,t,i){let s,r=0,n=0,o=0;if(this._parseStack.state)if(2===this._parseStack.state)this._parseStack.state=0,o=this._parseStack.chunkPos+1;else{if(void 0===i||1===this._parseStack.state)throw this._parseStack.state=1,new Error("improper continuation due to previous async handler, giving up parsing");const t=this._parseStack.handlers;let n=this._parseStack.handlerPos-1;switch(this._parseStack.state){case 3:if(!1===i&&n>-1)for(;n>=0&&(s=t[n](this._params),!0!==s);n--)if(s instanceof Promise)return this._parseStack.handlerPos=n,s;this._parseStack.handlers=[];break;case 4:if(!1===i&&n>-1)for(;n>=0&&(s=t[n](),!0!==s);n--)if(s instanceof Promise)return this._parseStack.handlerPos=n,s;this._parseStack.handlers=[];break;case 6:if(r=e[this._parseStack.chunkPos],s=this._dcsParser.unhook(24!==r&&26!==r,i),s)return s;27===r&&(this._parseStack.transition|=1),this._params.reset(),this._params.addParam(0),this._collect=0;break;case 5:if(r=e[this._parseStack.chunkPos],s=this._oscParser.end(24!==r&&26!==r,i),s)return s;27===r&&(this._parseStack.transition|=1),this._params.reset(),this._params.addParam(0),this._collect=0}this._parseStack.state=0,o=this._parseStack.chunkPos+1,this.precedingCodepoint=0,this.currentState=15&this._parseStack.transition}for(let i=o;i>4){case 2:for(let s=i+1;;++s){if(s>=t||(r=e[s])<32||r>126&&r=t||(r=e[s])<32||r>126&&r=t||(r=e[s])<32||r>126&&r=t||(r=e[s])<32||r>126&&r=0&&(s=o[a](this._params),!0!==s);a--)if(s instanceof Promise)return this._preserveStack(3,o,a,n,i),s;a<0&&this._csiHandlerFb(this._collect<<8|r,this._params),this.precedingCodepoint=0;break;case 8:do{switch(r){case 59:this._params.addParam(0);break;case 58:this._params.addSubParam(-1);break;default:this._params.addDigit(r-48)}}while(++i47&&r<60);i--;break;case 9:this._collect<<=8,this._collect|=r;break;case 10:const c=this._escHandlers[this._collect<<8|r];let l=c?c.length-1:-1;for(;l>=0&&(s=c[l](),!0!==s);l--)if(s instanceof Promise)return this._preserveStack(4,c,l,n,i),s;l<0&&this._escHandlerFb(this._collect<<8|r),this.precedingCodepoint=0;break;case 11:this._params.reset(),this._params.addParam(0),this._collect=0;break;case 12:this._dcsParser.hook(this._collect<<8|r,this._params);break;case 13:for(let s=i+1;;++s)if(s>=t||24===(r=e[s])||26===r||27===r||r>127&&r=t||(r=e[s])<32||r>127&&r{Object.defineProperty(t,"__esModule",{value:!0}),t.OscHandler=t.OscParser=void 0;const s=i(5770),r=i(482),n=[];t.OscParser=class{constructor(){this._state=0,this._active=n,this._id=-1,this._handlers=Object.create(null),this._handlerFb=()=>{},this._stack={paused:!1,loopPosition:0,fallThrough:!1}}registerHandler(e,t){void 0===this._handlers[e]&&(this._handlers[e]=[]);const i=this._handlers[e];return i.push(t),{dispose:()=>{const e=i.indexOf(t);-1!==e&&i.splice(e,1)}}}clearHandler(e){this._handlers[e]&&delete this._handlers[e]}setHandlerFallback(e){this._handlerFb=e}dispose(){this._handlers=Object.create(null),this._handlerFb=()=>{},this._active=n}reset(){if(2===this._state)for(let e=this._stack.paused?this._stack.loopPosition-1:this._active.length-1;e>=0;--e)this._active[e].end(!1);this._stack.paused=!1,this._active=n,this._id=-1,this._state=0}_start(){if(this._active=this._handlers[this._id]||n,this._active.length)for(let e=this._active.length-1;e>=0;e--)this._active[e].start();else this._handlerFb(this._id,"START")}_put(e,t,i){if(this._active.length)for(let s=this._active.length-1;s>=0;s--)this._active[s].put(e,t,i);else this._handlerFb(this._id,"PUT",(0,r.utf32ToString)(e,t,i))}start(){this.reset(),this._state=1}put(e,t,i){if(3!==this._state){if(1===this._state)for(;t0&&this._put(e,t,i)}}end(e,t=!0){if(0!==this._state){if(3!==this._state)if(1===this._state&&this._start(),this._active.length){let i=!1,s=this._active.length-1,r=!1;if(this._stack.paused&&(s=this._stack.loopPosition-1,i=t,r=this._stack.fallThrough,this._stack.paused=!1),!r&&!1===i){for(;s>=0&&(i=this._active[s].end(e),!0!==i);s--)if(i instanceof Promise)return this._stack.paused=!0,this._stack.loopPosition=s,this._stack.fallThrough=!1,i;s--}for(;s>=0;s--)if(i=this._active[s].end(!1),i instanceof Promise)return this._stack.paused=!0,this._stack.loopPosition=s,this._stack.fallThrough=!0,i}else this._handlerFb(this._id,"END",e);this._active=n,this._id=-1,this._state=0}}},t.OscHandler=class{constructor(e){this._handler=e,this._data="",this._hitLimit=!1}start(){this._data="",this._hitLimit=!1}put(e,t,i){this._hitLimit||(this._data+=(0,r.utf32ToString)(e,t,i),this._data.length>s.PAYLOAD_LIMIT&&(this._data="",this._hitLimit=!0))}end(e){let t=!1;if(this._hitLimit)t=!1;else if(e&&(t=this._handler(this._data),t instanceof Promise))return t.then((e=>(this._data="",this._hitLimit=!1,e)));return this._data="",this._hitLimit=!1,t}}},8742:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.Params=void 0;const i=2147483647;class s{static fromArray(e){const t=new s;if(!e.length)return t;for(let i=Array.isArray(e[0])?1:0;i256)throw new Error("maxSubParamsLength must not be greater than 256");this.params=new Int32Array(e),this.length=0,this._subParams=new Int32Array(t),this._subParamsLength=0,this._subParamsIdx=new Uint16Array(e),this._rejectDigits=!1,this._rejectSubDigits=!1,this._digitIsSub=!1}clone(){const e=new s(this.maxLength,this.maxSubParamsLength);return e.params.set(this.params),e.length=this.length,e._subParams.set(this._subParams),e._subParamsLength=this._subParamsLength,e._subParamsIdx.set(this._subParamsIdx),e._rejectDigits=this._rejectDigits,e._rejectSubDigits=this._rejectSubDigits,e._digitIsSub=this._digitIsSub,e}toArray(){const e=[];for(let t=0;t>8,s=255&this._subParamsIdx[t];s-i>0&&e.push(Array.prototype.slice.call(this._subParams,i,s))}return e}reset(){this.length=0,this._subParamsLength=0,this._rejectDigits=!1,this._rejectSubDigits=!1,this._digitIsSub=!1}addParam(e){if(this._digitIsSub=!1,this.length>=this.maxLength)this._rejectDigits=!0;else{if(e<-1)throw new Error("values lesser than -1 are not allowed");this._subParamsIdx[this.length]=this._subParamsLength<<8|this._subParamsLength,this.params[this.length++]=e>i?i:e}}addSubParam(e){if(this._digitIsSub=!0,this.length)if(this._rejectDigits||this._subParamsLength>=this.maxSubParamsLength)this._rejectSubDigits=!0;else{if(e<-1)throw new Error("values lesser than -1 are not allowed");this._subParams[this._subParamsLength++]=e>i?i:e,this._subParamsIdx[this.length-1]++}}hasSubParams(e){return(255&this._subParamsIdx[e])-(this._subParamsIdx[e]>>8)>0}getSubParams(e){const t=this._subParamsIdx[e]>>8,i=255&this._subParamsIdx[e];return i-t>0?this._subParams.subarray(t,i):null}getSubParamsAll(){const e={};for(let t=0;t>8,s=255&this._subParamsIdx[t];s-i>0&&(e[t]=this._subParams.slice(i,s))}return e}addDigit(e){let t;if(this._rejectDigits||!(t=this._digitIsSub?this._subParamsLength:this.length)||this._digitIsSub&&this._rejectSubDigits)return;const s=this._digitIsSub?this._subParams:this.params,r=s[t-1];s[t-1]=~r?Math.min(10*r+e,i):e}}t.Params=s},5741:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.AddonManager=void 0,t.AddonManager=class{constructor(){this._addons=[]}dispose(){for(let e=this._addons.length-1;e>=0;e--)this._addons[e].instance.dispose()}loadAddon(e,t){const i={instance:t,dispose:t.dispose,isDisposed:!1};this._addons.push(i),t.dispose=()=>this._wrappedAddonDispose(i),t.activate(e)}_wrappedAddonDispose(e){if(e.isDisposed)return;let t=-1;for(let i=0;i{Object.defineProperty(t,"__esModule",{value:!0}),t.BufferApiView=void 0;const s=i(3785),r=i(511);t.BufferApiView=class{constructor(e,t){this._buffer=e,this.type=t}init(e){return this._buffer=e,this}get cursorY(){return this._buffer.y}get cursorX(){return this._buffer.x}get viewportY(){return this._buffer.ydisp}get baseY(){return this._buffer.ybase}get length(){return this._buffer.lines.length}getLine(e){const t=this._buffer.lines.get(e);if(t)return new s.BufferLineApiView(t)}getNullCell(){return new r.CellData}}},3785:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.BufferLineApiView=void 0;const s=i(511);t.BufferLineApiView=class{constructor(e){this._line=e}get isWrapped(){return this._line.isWrapped}get length(){return this._line.length}getCell(e,t){if(!(e<0||e>=this._line.length))return t?(this._line.loadCell(e,t),t):this._line.loadCell(e,new s.CellData)}translateToString(e,t,i){return this._line.translateToString(e,t,i)}}},8285:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.BufferNamespaceApi=void 0;const s=i(8771),r=i(8460),n=i(844);class o extends n.Disposable{constructor(e){super(),this._core=e,this._onBufferChange=this.register(new r.EventEmitter),this.onBufferChange=this._onBufferChange.event,this._normal=new s.BufferApiView(this._core.buffers.normal,"normal"),this._alternate=new s.BufferApiView(this._core.buffers.alt,"alternate"),this._core.buffers.onBufferActivate((()=>this._onBufferChange.fire(this.active)))}get active(){if(this._core.buffers.active===this._core.buffers.normal)return this.normal;if(this._core.buffers.active===this._core.buffers.alt)return this.alternate;throw new Error("Active buffer is neither normal nor alternate")}get normal(){return this._normal.init(this._core.buffers.normal)}get alternate(){return this._alternate.init(this._core.buffers.alt)}}t.BufferNamespaceApi=o},7975:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.ParserApi=void 0,t.ParserApi=class{constructor(e){this._core=e}registerCsiHandler(e,t){return this._core.registerCsiHandler(e,(e=>t(e.toArray())))}addCsiHandler(e,t){return this.registerCsiHandler(e,t)}registerDcsHandler(e,t){return this._core.registerDcsHandler(e,((e,i)=>t(e,i.toArray())))}addDcsHandler(e,t){return this.registerDcsHandler(e,t)}registerEscHandler(e,t){return this._core.registerEscHandler(e,t)}addEscHandler(e,t){return this.registerEscHandler(e,t)}registerOscHandler(e,t){return this._core.registerOscHandler(e,t)}addOscHandler(e,t){return this.registerOscHandler(e,t)}}},7090:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.UnicodeApi=void 0,t.UnicodeApi=class{constructor(e){this._core=e}register(e){this._core.unicodeService.register(e)}get versions(){return this._core.unicodeService.versions}get activeVersion(){return this._core.unicodeService.activeVersion}set activeVersion(e){this._core.unicodeService.activeVersion=e}}},744:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.BufferService=t.MINIMUM_ROWS=t.MINIMUM_COLS=void 0;const n=i(8460),o=i(844),a=i(5295),h=i(2585);t.MINIMUM_COLS=2,t.MINIMUM_ROWS=1;let c=t.BufferService=class extends o.Disposable{get buffer(){return this.buffers.active}constructor(e){super(),this.isUserScrolling=!1,this._onResize=this.register(new n.EventEmitter),this.onResize=this._onResize.event,this._onScroll=this.register(new n.EventEmitter),this.onScroll=this._onScroll.event,this.cols=Math.max(e.rawOptions.cols||0,t.MINIMUM_COLS),this.rows=Math.max(e.rawOptions.rows||0,t.MINIMUM_ROWS),this.buffers=this.register(new a.BufferSet(e,this))}resize(e,t){this.cols=e,this.rows=t,this.buffers.resize(e,t),this._onResize.fire({cols:e,rows:t})}reset(){this.buffers.reset(),this.isUserScrolling=!1}scroll(e,t=!1){const i=this.buffer;let s;s=this._cachedBlankLine,s&&s.length===this.cols&&s.getFg(0)===e.fg&&s.getBg(0)===e.bg||(s=i.getBlankLine(e,t),this._cachedBlankLine=s),s.isWrapped=t;const r=i.ybase+i.scrollTop,n=i.ybase+i.scrollBottom;if(0===i.scrollTop){const e=i.lines.isFull;n===i.lines.length-1?e?i.lines.recycle().copyFrom(s):i.lines.push(s.clone()):i.lines.splice(n+1,0,s.clone()),e?this.isUserScrolling&&(i.ydisp=Math.max(i.ydisp-1,0)):(i.ybase++,this.isUserScrolling||i.ydisp++)}else{const e=n-r+1;i.lines.shiftElements(r+1,e-1,-1),i.lines.set(n,s.clone())}this.isUserScrolling||(i.ydisp=i.ybase),this._onScroll.fire(i.ydisp)}scrollLines(e,t,i){const s=this.buffer;if(e<0){if(0===s.ydisp)return;this.isUserScrolling=!0}else e+s.ydisp>=s.ybase&&(this.isUserScrolling=!1);const r=s.ydisp;s.ydisp=Math.max(Math.min(s.ydisp+e,s.ybase),0),r!==s.ydisp&&(t||this._onScroll.fire(s.ydisp))}};t.BufferService=c=s([r(0,h.IOptionsService)],c)},7994:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.CharsetService=void 0,t.CharsetService=class{constructor(){this.glevel=0,this._charsets=[]}reset(){this.charset=void 0,this._charsets=[],this.glevel=0}setgLevel(e){this.glevel=e,this.charset=this._charsets[e]}setgCharset(e,t){this._charsets[e]=t,this.glevel===e&&(this.charset=t)}}},1753:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.CoreMouseService=void 0;const n=i(2585),o=i(8460),a=i(844),h={NONE:{events:0,restrict:()=>!1},X10:{events:1,restrict:e=>4!==e.button&&1===e.action&&(e.ctrl=!1,e.alt=!1,e.shift=!1,!0)},VT200:{events:19,restrict:e=>32!==e.action},DRAG:{events:23,restrict:e=>32!==e.action||3!==e.button},ANY:{events:31,restrict:e=>!0}};function c(e,t){let i=(e.ctrl?16:0)|(e.shift?4:0)|(e.alt?8:0);return 4===e.button?(i|=64,i|=e.action):(i|=3&e.button,4&e.button&&(i|=64),8&e.button&&(i|=128),32===e.action?i|=32:0!==e.action||t||(i|=3)),i}const l=String.fromCharCode,d={DEFAULT:e=>{const t=[c(e,!1)+32,e.col+32,e.row+32];return t[0]>255||t[1]>255||t[2]>255?"":`${l(t[0])}${l(t[1])}${l(t[2])}`},SGR:e=>{const t=0===e.action&&4!==e.button?"m":"M";return`[<${c(e,!0)};${e.col};${e.row}${t}`},SGR_PIXELS:e=>{const t=0===e.action&&4!==e.button?"m":"M";return`[<${c(e,!0)};${e.x};${e.y}${t}`}};let _=t.CoreMouseService=class extends a.Disposable{constructor(e,t){super(),this._bufferService=e,this._coreService=t,this._protocols={},this._encodings={},this._activeProtocol="",this._activeEncoding="",this._lastEvent=null,this._onProtocolChange=this.register(new o.EventEmitter),this.onProtocolChange=this._onProtocolChange.event;for(const e of Object.keys(h))this.addProtocol(e,h[e]);for(const e of Object.keys(d))this.addEncoding(e,d[e]);this.reset()}addProtocol(e,t){this._protocols[e]=t}addEncoding(e,t){this._encodings[e]=t}get activeProtocol(){return this._activeProtocol}get areMouseEventsActive(){return 0!==this._protocols[this._activeProtocol].events}set activeProtocol(e){if(!this._protocols[e])throw new Error(`unknown protocol "${e}"`);this._activeProtocol=e,this._onProtocolChange.fire(this._protocols[e].events)}get activeEncoding(){return this._activeEncoding}set activeEncoding(e){if(!this._encodings[e])throw new Error(`unknown encoding "${e}"`);this._activeEncoding=e}reset(){this.activeProtocol="NONE",this.activeEncoding="DEFAULT",this._lastEvent=null}triggerMouseEvent(e){if(e.col<0||e.col>=this._bufferService.cols||e.row<0||e.row>=this._bufferService.rows)return!1;if(4===e.button&&32===e.action)return!1;if(3===e.button&&32!==e.action)return!1;if(4!==e.button&&(2===e.action||3===e.action))return!1;if(e.col++,e.row++,32===e.action&&this._lastEvent&&this._equalEvents(this._lastEvent,e,"SGR_PIXELS"===this._activeEncoding))return!1;if(!this._protocols[this._activeProtocol].restrict(e))return!1;const t=this._encodings[this._activeEncoding](e);return t&&("DEFAULT"===this._activeEncoding?this._coreService.triggerBinaryEvent(t):this._coreService.triggerDataEvent(t,!0)),this._lastEvent=e,!0}explainEvents(e){return{down:!!(1&e),up:!!(2&e),drag:!!(4&e),move:!!(8&e),wheel:!!(16&e)}}_equalEvents(e,t,i){if(i){if(e.x!==t.x)return!1;if(e.y!==t.y)return!1}else{if(e.col!==t.col)return!1;if(e.row!==t.row)return!1}return e.button===t.button&&e.action===t.action&&e.ctrl===t.ctrl&&e.alt===t.alt&&e.shift===t.shift}};t.CoreMouseService=_=s([r(0,n.IBufferService),r(1,n.ICoreService)],_)},6975:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.CoreService=void 0;const n=i(1439),o=i(8460),a=i(844),h=i(2585),c=Object.freeze({insertMode:!1}),l=Object.freeze({applicationCursorKeys:!1,applicationKeypad:!1,bracketedPasteMode:!1,origin:!1,reverseWraparound:!1,sendFocus:!1,wraparound:!0});let d=t.CoreService=class extends a.Disposable{constructor(e,t,i){super(),this._bufferService=e,this._logService=t,this._optionsService=i,this.isCursorInitialized=!1,this.isCursorHidden=!1,this._onData=this.register(new o.EventEmitter),this.onData=this._onData.event,this._onUserInput=this.register(new o.EventEmitter),this.onUserInput=this._onUserInput.event,this._onBinary=this.register(new o.EventEmitter),this.onBinary=this._onBinary.event,this._onRequestScrollToBottom=this.register(new o.EventEmitter),this.onRequestScrollToBottom=this._onRequestScrollToBottom.event,this.modes=(0,n.clone)(c),this.decPrivateModes=(0,n.clone)(l)}reset(){this.modes=(0,n.clone)(c),this.decPrivateModes=(0,n.clone)(l)}triggerDataEvent(e,t=!1){if(this._optionsService.rawOptions.disableStdin)return;const i=this._bufferService.buffer;t&&this._optionsService.rawOptions.scrollOnUserInput&&i.ybase!==i.ydisp&&this._onRequestScrollToBottom.fire(),t&&this._onUserInput.fire(),this._logService.debug(`sending data "${e}"`,(()=>e.split("").map((e=>e.charCodeAt(0))))),this._onData.fire(e)}triggerBinaryEvent(e){this._optionsService.rawOptions.disableStdin||(this._logService.debug(`sending binary "${e}"`,(()=>e.split("").map((e=>e.charCodeAt(0))))),this._onBinary.fire(e))}};t.CoreService=d=s([r(0,h.IBufferService),r(1,h.ILogService),r(2,h.IOptionsService)],d)},9074:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.DecorationService=void 0;const s=i(8055),r=i(8460),n=i(844),o=i(6106);let a=0,h=0;class c extends n.Disposable{get decorations(){return this._decorations.values()}constructor(){super(),this._decorations=new o.SortedList((e=>null==e?void 0:e.marker.line)),this._onDecorationRegistered=this.register(new r.EventEmitter),this.onDecorationRegistered=this._onDecorationRegistered.event,this._onDecorationRemoved=this.register(new r.EventEmitter),this.onDecorationRemoved=this._onDecorationRemoved.event,this.register((0,n.toDisposable)((()=>this.reset())))}registerDecoration(e){if(e.marker.isDisposed)return;const t=new l(e);if(t){const e=t.marker.onDispose((()=>t.dispose()));t.onDispose((()=>{t&&(this._decorations.delete(t)&&this._onDecorationRemoved.fire(t),e.dispose())})),this._decorations.insert(t),this._onDecorationRegistered.fire(t)}return t}reset(){for(const e of this._decorations.values())e.dispose();this._decorations.clear()}*getDecorationsAtCell(e,t,i){var s,r,n;let o=0,a=0;for(const h of this._decorations.getKeyIterator(t))o=null!==(s=h.options.x)&&void 0!==s?s:0,a=o+(null!==(r=h.options.width)&&void 0!==r?r:1),e>=o&&e{var r,n,o;a=null!==(r=t.options.x)&&void 0!==r?r:0,h=a+(null!==(n=t.options.width)&&void 0!==n?n:1),e>=a&&e{Object.defineProperty(t,"__esModule",{value:!0}),t.InstantiationService=t.ServiceCollection=void 0;const s=i(2585),r=i(8343);class n{constructor(...e){this._entries=new Map;for(const[t,i]of e)this.set(t,i)}set(e,t){const i=this._entries.get(e);return this._entries.set(e,t),i}forEach(e){for(const[t,i]of this._entries.entries())e(t,i)}has(e){return this._entries.has(e)}get(e){return this._entries.get(e)}}t.ServiceCollection=n,t.InstantiationService=class{constructor(){this._services=new n,this._services.set(s.IInstantiationService,this)}setService(e,t){this._services.set(e,t)}getService(e){return this._services.get(e)}createInstance(e,...t){const i=(0,r.getServiceDependencies)(e).sort(((e,t)=>e.index-t.index)),s=[];for(const t of i){const i=this._services.get(t.id);if(!i)throw new Error(`[createInstance] ${e.name} depends on UNKNOWN service ${t.id}.`);s.push(i)}const n=i.length>0?i[0].index:t.length;if(t.length!==n)throw new Error(`[createInstance] First service dependency of ${e.name} at position ${n+1} conflicts with ${t.length} static arguments`);return new e(...[...t,...s])}}},7866:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.traceCall=t.setTraceLogger=t.LogService=void 0;const n=i(844),o=i(2585),a={trace:o.LogLevelEnum.TRACE,debug:o.LogLevelEnum.DEBUG,info:o.LogLevelEnum.INFO,warn:o.LogLevelEnum.WARN,error:o.LogLevelEnum.ERROR,off:o.LogLevelEnum.OFF};let h,c=t.LogService=class extends n.Disposable{get logLevel(){return this._logLevel}constructor(e){super(),this._optionsService=e,this._logLevel=o.LogLevelEnum.OFF,this._updateLogLevel(),this.register(this._optionsService.onSpecificOptionChange("logLevel",(()=>this._updateLogLevel()))),h=this}_updateLogLevel(){this._logLevel=a[this._optionsService.rawOptions.logLevel]}_evalLazyOptionalParams(e){for(let t=0;tJSON.stringify(e))).join(", ")})`);const t=s.apply(this,e);return h.trace(`GlyphRenderer#${s.name} return`,t),t}}},7302:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.OptionsService=t.DEFAULT_OPTIONS=void 0;const s=i(8460),r=i(844),n=i(6114);t.DEFAULT_OPTIONS={cols:80,rows:24,cursorBlink:!1,cursorStyle:"block",cursorWidth:1,cursorInactiveStyle:"outline",customGlyphs:!0,drawBoldTextInBrightColors:!0,fastScrollModifier:"alt",fastScrollSensitivity:5,fontFamily:"courier-new, courier, monospace",fontSize:15,fontWeight:"normal",fontWeightBold:"bold",ignoreBracketedPasteMode:!1,lineHeight:1,letterSpacing:0,linkHandler:null,logLevel:"info",logger:null,scrollback:1e3,scrollOnUserInput:!0,scrollSensitivity:1,screenReaderMode:!1,smoothScrollDuration:0,macOptionIsMeta:!1,macOptionClickForcesSelection:!1,minimumContrastRatio:1,disableStdin:!1,allowProposedApi:!1,allowTransparency:!1,tabStopWidth:8,theme:{},rightClickSelectsWord:n.isMac,windowOptions:{},windowsMode:!1,windowsPty:{},wordSeparator:" ()[]{}',\"`",altClickMovesCursor:!0,convertEol:!1,termName:"xterm",cancelEvents:!1,overviewRulerWidth:0};const o=["normal","bold","100","200","300","400","500","600","700","800","900"];class a extends r.Disposable{constructor(e){super(),this._onOptionChange=this.register(new s.EventEmitter),this.onOptionChange=this._onOptionChange.event;const i=Object.assign({},t.DEFAULT_OPTIONS);for(const t in e)if(t in i)try{const s=e[t];i[t]=this._sanitizeAndValidateOption(t,s)}catch(e){console.error(e)}this.rawOptions=i,this.options=Object.assign({},i),this._setupOptions()}onSpecificOptionChange(e,t){return this.onOptionChange((i=>{i===e&&t(this.rawOptions[e])}))}onMultipleOptionChange(e,t){return this.onOptionChange((i=>{-1!==e.indexOf(i)&&t()}))}_setupOptions(){const e=e=>{if(!(e in t.DEFAULT_OPTIONS))throw new Error(`No option with key "${e}"`);return this.rawOptions[e]},i=(e,i)=>{if(!(e in t.DEFAULT_OPTIONS))throw new Error(`No option with key "${e}"`);i=this._sanitizeAndValidateOption(e,i),this.rawOptions[e]!==i&&(this.rawOptions[e]=i,this._onOptionChange.fire(e))};for(const t in this.rawOptions){const s={get:e.bind(this,t),set:i.bind(this,t)};Object.defineProperty(this.options,t,s)}}_sanitizeAndValidateOption(e,i){switch(e){case"cursorStyle":if(i||(i=t.DEFAULT_OPTIONS[e]),!function(e){return"block"===e||"underline"===e||"bar"===e}(i))throw new Error(`"${i}" is not a valid value for ${e}`);break;case"wordSeparator":i||(i=t.DEFAULT_OPTIONS[e]);break;case"fontWeight":case"fontWeightBold":if("number"==typeof i&&1<=i&&i<=1e3)break;i=o.includes(i)?i:t.DEFAULT_OPTIONS[e];break;case"cursorWidth":i=Math.floor(i);case"lineHeight":case"tabStopWidth":if(i<1)throw new Error(`${e} cannot be less than 1, value: ${i}`);break;case"minimumContrastRatio":i=Math.max(1,Math.min(21,Math.round(10*i)/10));break;case"scrollback":if((i=Math.min(i,4294967295))<0)throw new Error(`${e} cannot be less than 0, value: ${i}`);break;case"fastScrollSensitivity":case"scrollSensitivity":if(i<=0)throw new Error(`${e} cannot be less than or equal to 0, value: ${i}`);break;case"rows":case"cols":if(!i&&0!==i)throw new Error(`${e} must be numeric, value: ${i}`);break;case"windowsPty":i=null!=i?i:{}}return i}}t.OptionsService=a},2660:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.OscLinkService=void 0;const n=i(2585);let o=t.OscLinkService=class{constructor(e){this._bufferService=e,this._nextId=1,this._entriesWithId=new Map,this._dataByLinkId=new Map}registerLink(e){const t=this._bufferService.buffer;if(void 0===e.id){const i=t.addMarker(t.ybase+t.y),s={data:e,id:this._nextId++,lines:[i]};return i.onDispose((()=>this._removeMarkerFromLink(s,i))),this._dataByLinkId.set(s.id,s),s.id}const i=e,s=this._getEntryIdKey(i),r=this._entriesWithId.get(s);if(r)return this.addLineToLink(r.id,t.ybase+t.y),r.id;const n=t.addMarker(t.ybase+t.y),o={id:this._nextId++,key:this._getEntryIdKey(i),data:i,lines:[n]};return n.onDispose((()=>this._removeMarkerFromLink(o,n))),this._entriesWithId.set(o.key,o),this._dataByLinkId.set(o.id,o),o.id}addLineToLink(e,t){const i=this._dataByLinkId.get(e);if(i&&i.lines.every((e=>e.line!==t))){const e=this._bufferService.buffer.addMarker(t);i.lines.push(e),e.onDispose((()=>this._removeMarkerFromLink(i,e)))}}getLinkData(e){var t;return null===(t=this._dataByLinkId.get(e))||void 0===t?void 0:t.data}_getEntryIdKey(e){return`${e.id};;${e.uri}`}_removeMarkerFromLink(e,t){const i=e.lines.indexOf(t);-1!==i&&(e.lines.splice(i,1),0===e.lines.length&&(void 0!==e.data.id&&this._entriesWithId.delete(e.key),this._dataByLinkId.delete(e.id)))}};t.OscLinkService=o=s([r(0,n.IBufferService)],o)},8343:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.createDecorator=t.getServiceDependencies=t.serviceRegistry=void 0;const i="di$target",s="di$dependencies";t.serviceRegistry=new Map,t.getServiceDependencies=function(e){return e[s]||[]},t.createDecorator=function(e){if(t.serviceRegistry.has(e))return t.serviceRegistry.get(e);const r=function(e,t,n){if(3!==arguments.length)throw new Error("@IServiceName-decorator can only be used to decorate a parameter");!function(e,t,r){t[i]===t?t[s].push({id:e,index:r}):(t[s]=[{id:e,index:r}],t[i]=t)}(r,e,n)};return r.toString=()=>e,t.serviceRegistry.set(e,r),r}},2585:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.IDecorationService=t.IUnicodeService=t.IOscLinkService=t.IOptionsService=t.ILogService=t.LogLevelEnum=t.IInstantiationService=t.ICharsetService=t.ICoreService=t.ICoreMouseService=t.IBufferService=void 0;const s=i(8343);var r;t.IBufferService=(0,s.createDecorator)("BufferService"),t.ICoreMouseService=(0,s.createDecorator)("CoreMouseService"),t.ICoreService=(0,s.createDecorator)("CoreService"),t.ICharsetService=(0,s.createDecorator)("CharsetService"),t.IInstantiationService=(0,s.createDecorator)("InstantiationService"),function(e){e[e.TRACE=0]="TRACE",e[e.DEBUG=1]="DEBUG",e[e.INFO=2]="INFO",e[e.WARN=3]="WARN",e[e.ERROR=4]="ERROR",e[e.OFF=5]="OFF"}(r||(t.LogLevelEnum=r={})),t.ILogService=(0,s.createDecorator)("LogService"),t.IOptionsService=(0,s.createDecorator)("OptionsService"),t.IOscLinkService=(0,s.createDecorator)("OscLinkService"),t.IUnicodeService=(0,s.createDecorator)("UnicodeService"),t.IDecorationService=(0,s.createDecorator)("DecorationService")},1480:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.UnicodeService=void 0;const s=i(8460),r=i(225);t.UnicodeService=class{constructor(){this._providers=Object.create(null),this._active="",this._onChange=new s.EventEmitter,this.onChange=this._onChange.event;const e=new r.UnicodeV6;this.register(e),this._active=e.version,this._activeProvider=e}dispose(){this._onChange.dispose()}get versions(){return Object.keys(this._providers)}get activeVersion(){return this._active}set activeVersion(e){if(!this._providers[e])throw new Error(`unknown Unicode version "${e}"`);this._active=e,this._activeProvider=this._providers[e],this._onChange.fire(e)}register(e){this._providers[e.version]=e}wcwidth(e){return this._activeProvider.wcwidth(e)}getStringCellWidth(e){let t=0;const i=e.length;for(let s=0;s=i)return t+this.wcwidth(r);const n=e.charCodeAt(s);56320<=n&&n<=57343?r=1024*(r-55296)+n-56320+65536:t+=this.wcwidth(n)}t+=this.wcwidth(r)}return t}}}},t={};function i(s){var r=t[s];if(void 0!==r)return r.exports;var n=t[s]={exports:{}};return e[s].call(n.exports,n,n.exports,i),n.exports}var s={};return(()=>{var e=s;Object.defineProperty(e,"__esModule",{value:!0}),e.Terminal=void 0;const t=i(9042),r=i(3236),n=i(844),o=i(5741),a=i(8285),h=i(7975),c=i(7090),l=["cols","rows"];class d extends n.Disposable{constructor(e){super(),this._core=this.register(new r.Terminal(e)),this._addonManager=this.register(new o.AddonManager),this._publicOptions=Object.assign({},this._core.options);const t=e=>this._core.options[e],i=(e,t)=>{this._checkReadonlyOptions(e),this._core.options[e]=t};for(const e in this._core.options){const s={get:t.bind(this,e),set:i.bind(this,e)};Object.defineProperty(this._publicOptions,e,s)}}_checkReadonlyOptions(e){if(l.includes(e))throw new Error(`Option "${e}" can only be set in the constructor`)}_checkProposedApi(){if(!this._core.optionsService.rawOptions.allowProposedApi)throw new Error("You must set the allowProposedApi option to true to use proposed API")}get onBell(){return this._core.onBell}get onBinary(){return this._core.onBinary}get onCursorMove(){return this._core.onCursorMove}get onData(){return this._core.onData}get onKey(){return this._core.onKey}get onLineFeed(){return this._core.onLineFeed}get onRender(){return this._core.onRender}get onResize(){return this._core.onResize}get onScroll(){return this._core.onScroll}get onSelectionChange(){return this._core.onSelectionChange}get onTitleChange(){return this._core.onTitleChange}get onWriteParsed(){return this._core.onWriteParsed}get element(){return this._core.element}get parser(){return this._parser||(this._parser=new h.ParserApi(this._core)),this._parser}get unicode(){return this._checkProposedApi(),new c.UnicodeApi(this._core)}get textarea(){return this._core.textarea}get rows(){return this._core.rows}get cols(){return this._core.cols}get buffer(){return this._buffer||(this._buffer=this.register(new a.BufferNamespaceApi(this._core))),this._buffer}get markers(){return this._checkProposedApi(),this._core.markers}get modes(){const e=this._core.coreService.decPrivateModes;let t="none";switch(this._core.coreMouseService.activeProtocol){case"X10":t="x10";break;case"VT200":t="vt200";break;case"DRAG":t="drag";break;case"ANY":t="any"}return{applicationCursorKeysMode:e.applicationCursorKeys,applicationKeypadMode:e.applicationKeypad,bracketedPasteMode:e.bracketedPasteMode,insertMode:this._core.coreService.modes.insertMode,mouseTrackingMode:t,originMode:e.origin,reverseWraparoundMode:e.reverseWraparound,sendFocusMode:e.sendFocus,wraparoundMode:e.wraparound}}get options(){return this._publicOptions}set options(e){for(const t in e)this._publicOptions[t]=e[t]}blur(){this._core.blur()}focus(){this._core.focus()}resize(e,t){this._verifyIntegers(e,t),this._core.resize(e,t)}open(e){this._core.open(e)}attachCustomKeyEventHandler(e){this._core.attachCustomKeyEventHandler(e)}registerLinkProvider(e){return this._core.registerLinkProvider(e)}registerCharacterJoiner(e){return this._checkProposedApi(),this._core.registerCharacterJoiner(e)}deregisterCharacterJoiner(e){this._checkProposedApi(),this._core.deregisterCharacterJoiner(e)}registerMarker(e=0){return this._verifyIntegers(e),this._core.registerMarker(e)}registerDecoration(e){var t,i,s;return this._checkProposedApi(),this._verifyPositiveIntegers(null!==(t=e.x)&&void 0!==t?t:0,null!==(i=e.width)&&void 0!==i?i:0,null!==(s=e.height)&&void 0!==s?s:0),this._core.registerDecoration(e)}hasSelection(){return this._core.hasSelection()}select(e,t,i){this._verifyIntegers(e,t,i),this._core.select(e,t,i)}getSelection(){return this._core.getSelection()}getSelectionPosition(){return this._core.getSelectionPosition()}clearSelection(){this._core.clearSelection()}selectAll(){this._core.selectAll()}selectLines(e,t){this._verifyIntegers(e,t),this._core.selectLines(e,t)}dispose(){super.dispose()}scrollLines(e){this._verifyIntegers(e),this._core.scrollLines(e)}scrollPages(e){this._verifyIntegers(e),this._core.scrollPages(e)}scrollToTop(){this._core.scrollToTop()}scrollToBottom(){this._core.scrollToBottom()}scrollToLine(e){this._verifyIntegers(e),this._core.scrollToLine(e)}clear(){this._core.clear()}write(e,t){this._core.write(e,t)}writeln(e,t){this._core.write(e),this._core.write("\r\n",t)}paste(e){this._core.paste(e)}refresh(e,t){this._verifyIntegers(e,t),this._core.refresh(e,t)}reset(){this._core.reset()}clearTextureAtlas(){this._core.clearTextureAtlas()}loadAddon(e){this._addonManager.loadAddon(this,e)}static get strings(){return t}_verifyIntegers(...e){for(const t of e)if(t===1/0||isNaN(t)||t%1!=0)throw new Error("This API only accepts integers")}_verifyPositiveIntegers(...e){for(const t of e)if(t&&(t===1/0||isNaN(t)||t%1!=0||t<0))throw new Error("This API only accepts positive integers")}}e.Terminal=d})(),s})())); +//# sourceMappingURL=xterm.js.map \ No newline at end of file