diff --git a/README.md b/README.md index 877a2e3..8655c3a 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ uv run pytest tests/ -q | Folder | Purpose | | --- | --- | -| `apps/` | Runnable applications: `ui` (Streamlit), `api_server` (FastAPI), `worker` (background jobs) | +| `apps/` | Runnable applications: `ui` (Material 3 web app), `api_server` (FastAPI), `worker` (background jobs) | | `core/` | Shared primitives: `Action`, `Point3D`, `GardenWorld`, config, logging, events | | `services/` | One service per concern, e.g. hardware gateway, watering, vision, planning, spatial, safety | | `projects/` | Isolated student / research projects | @@ -141,7 +141,7 @@ See [`docs/architecture.md`](docs/architecture.md) for the full system design, a | Folder | Distribution | Purpose | | --- | --- | --- | | `core/` | `twfarmbot-core` | Shared domain, config, logging, events | -| `apps/ui/` | `twfarmbot-ui` | Streamlit dashboard | +| `apps/ui/` | `twfarmbot-ui` | Material 3 web dashboard (FastAPI + Material Web Components) | | `apps/api_server/` | `twfarmbot-api-server` | FastAPI HTTP API | | `apps/worker/` | `twfarmbot-worker` | Background jobs / experiments | diff --git a/apps/api_server/src/twfarmbot_api_server/app.py b/apps/api_server/src/twfarmbot_api_server/app.py index 0731583..7b95dc3 100644 --- a/apps/api_server/src/twfarmbot_api_server/app.py +++ b/apps/api_server/src/twfarmbot_api_server/app.py @@ -429,11 +429,11 @@ def connect_to_farmbot(required: bool = True) -> str: so ``GET /health`` can report it. Set ``FARMBOT_REQUIRED=0`` to allow boot without a live bot (useful - for UI-only or offline dev). When ``required=True`` (the default), - a failed connection raises ``SystemExit`` so uvicorn never starts - with a dead upstream. + for UI-only or offline dev). When ``required=True`` (the default) and + the bot is required, a failed connection raises ``SystemExit`` so + uvicorn never starts with a dead upstream. """ - if not required and os.getenv("FARMBOT_REQUIRED", "1") == "0": + if os.getenv("FARMBOT_REQUIRED", "1") == "0": log.warning("FarmBot connection skipped (FARMBOT_REQUIRED=0)") app.state.farmbot_status = "skipped" return "skipped" diff --git a/apps/ui/pyproject.toml b/apps/ui/pyproject.toml index 7aa954e..ee1060c 100644 --- a/apps/ui/pyproject.toml +++ b/apps/ui/pyproject.toml @@ -6,14 +6,14 @@ readme = "README.md" requires-python = ">=3.10" dependencies = [ "twfarmbot-core", - "twfarmbot-ml-utils", - "altair>=5", + "fastapi>=0.110", + "uvicorn>=0.29", "httpx>=0.27", - "streamlit>=1.30", + "ruamel-yaml>=0.18", ] [project.scripts] -twfarmbot-ui = "twfarmbot_ui.__main__:main" +twfarmbot-ui = "twfarmbot_ui.server:main" [build-system] requires = ["hatchling"] diff --git a/apps/ui/scripts/vendor_js.py b/apps/ui/scripts/vendor_js.py new file mode 100644 index 0000000..5e6d659 --- /dev/null +++ b/apps/ui/scripts/vendor_js.py @@ -0,0 +1,202 @@ +"""Vendor the UI's external JS dependencies into ``static/vendor/``. + +The Material 3 frontend currently loads three third-party libraries from +``esm.run`` (Material Web, Chart.js, marked, DOMPurify) and Google Fonts via +``fonts.googleapis.com``. Both fail completely when the on-farm controller +loses internet connectivity — and the ESTOP button is part of the same +SPA, so every load fails along with them. + +This script fetches the exact-pinned files once and writes them into +``apps/ui/src/twfarmbot_ui/static/vendor/`` so the FastAPI server can serve +them as ordinary static assets. Subsequent runs verify the SHA256 of each +file against the manifest below; a hash mismatch triggers a re-download. +Commit the resulting ``vendor/`` tree to make the UI fully offline-capable. + +Usage:: + + # Initial setup (also re-runs after a manifest change): + python apps/ui/scripts/vendor_js.py + + # Force re-download even if the local file already matches the hash: + python apps/ui/scripts/vendor_js.py --force + +The script intentionally uses only the Python stdlib (``urllib`` + +``hashlib``) so it can run in any environment — including a fresh +``uv`` checkout, a CI runner, or a hardened image without network +access to PyPI. + +At runtime the UI is unaffected: the FastAPI server serves the vendored +files from ``static/vendor/`` just like any other static asset. +""" + +from __future__ import annotations + +import argparse +import hashlib +import json +import logging +import sys +import urllib.error +import urllib.request +from dataclasses import dataclass +from pathlib import Path +from typing import Iterable + +_USER_AGENT = "twfarmbot-vendor-js/1.0" +_TIMEOUT = 60.0 + +# Resolved relative to the repo root (apps/ui/...). Keep the script +# importable from both the repo root and apps/ui/. +HERE = Path(__file__).resolve().parent +DEFAULT_STATIC = HERE.parent / "src" / "twfarmbot_ui" / "static" + +log = logging.getLogger("vendor_js") + + +@dataclass(frozen=True) +class Asset: + """One file to vendor: a remote URL, the local path under ``vendor/``, + and the expected SHA256 (hex) of the bytes we want on disk.""" + + url: str + relpath: str + sha256: str + + +# Pinned versions + SHA256 hashes. Update both fields together; a mismatch +# is treated as tampering/bit-rot and triggers a re-download. +MANIFEST: tuple[Asset, ...] = ( + Asset( + url="https://esm.run/@material/web@2.4.0/all.js", + relpath="@material/web/all.js", + sha256="07023ec48b3b495f34b485a625cc470ed07692594ccfc74d6b800f225d1a80fb", + ), + Asset( + url="https://esm.run/@material/web@2.4.0/typography/md-typescale-styles.js", + relpath="@material/web/typography/md-typescale-styles.js", + sha256="07546a71476de34433a067774d3192900d28e88169fb7aec8831f95b0c97bc07", + ), + Asset( + url="https://esm.run/chart.js@4.4.9/auto", + relpath="chart.js/auto.js", + sha256="e38916283b32321696a17c0acb4123f3889b4331e1859d471b195eecd4a9e497", + ), + Asset( + url="https://esm.run/marked@15.0.12", + relpath="marked.js", + sha256="5b2f8940c0c4fd3f568aa4e08e169cbbcef8496a094eb02b579d342e5e9377e4", + ), + Asset( + url="https://esm.run/dompurify@3.2.6", + relpath="dompurify.js", + sha256="c7cf8c441c3a0be7597d0b15c45df444e624b23a72101b68b5a96dfad8c5f2b5", + ), +) + + +def _hash(data: bytes) -> str: + return hashlib.sha256(data).hexdigest() + + +def _needs_fetch(target: Path, asset: Asset) -> bool: + if not target.exists(): + return True + if _hash(target.read_bytes()) != asset.sha256: + log.warning("hash mismatch for %s — file is stale or corrupted", asset.relpath) + return True + return False + + +def _download(asset: Asset, target: Path) -> None: + log.info("GET %s", asset.url) + req = urllib.request.Request(asset.url, headers={"User-Agent": _USER_AGENT}) + try: + with urllib.request.urlopen(req, timeout=_TIMEOUT) as resp: + data = resp.read() + except urllib.error.HTTPError as err: + raise SystemExit(f"HTTP {err.code} fetching {asset.url}") from err + except urllib.error.URLError as err: + raise SystemExit(f"failed to fetch {asset.url}: {err.reason}") from err + digest = _hash(data) + if digest != asset.sha256: + raise SystemExit( + f"SHA256 mismatch for {asset.url}\n" + f" expected: {asset.sha256}\n" + f" got: {digest}\n" + "Update MANIFEST deliberately, or pin a different upstream." + ) + target.parent.mkdir(parents=True, exist_ok=True) + target.write_bytes(data) + log.info("wrote %s (%d bytes)", target, len(data)) + + +def vendor(static_dir: Path, *, force: bool = False) -> list[Path]: + vendor_dir = static_dir / "vendor" + written: list[Path] = [] + for asset in MANIFEST: + target = vendor_dir / asset.relpath + if not force and not _needs_fetch(target, asset): + log.info("up to date: %s", asset.relpath) + continue + _download(asset, target) + written.append(target) + manifest_path = vendor_dir / "manifest.json" + manifest_path.write_text( + json.dumps( + [ + { + "url": a.url, + "path": a.relpath, + "sha256": a.sha256, + "size": (vendor_dir / a.relpath).stat().st_size, + } + for a in MANIFEST + ], + indent=2, + ) + + "\n" + ) + return written + + +def _parse_args(argv: Iterable[str]) -> argparse.Namespace: + p = argparse.ArgumentParser(description=__doc__.splitlines()[0]) + p.add_argument( + "--static-dir", + type=Path, + default=DEFAULT_STATIC, + help="path to the UI's static/ directory (default: %(default)s)", + ) + p.add_argument( + "--force", + action="store_true", + help="re-download every asset even if the local file is current", + ) + p.add_argument( + "--verbose", + "-v", + action="store_true", + help="enable debug logging", + ) + return p.parse_args(list(argv)) + + +def main(argv: Iterable[str] | None = None) -> int: + args = _parse_args(argv if argv is not None else sys.argv[1:]) + logging.basicConfig( + level=logging.DEBUG if args.verbose else logging.INFO, + format="%(asctime)s %(levelname)s %(message)s", + ) + if not args.static_dir.is_dir(): + raise SystemExit(f"static dir not found: {args.static_dir}") + written = vendor(args.static_dir, force=args.force) + target = args.static_dir / "vendor" + if written: + log.info("updated %d file(s) under %s", len(written), target) + else: + log.info("vendor tree is up to date at %s", target) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/apps/ui/src/twfarmbot_ui/__main__.py b/apps/ui/src/twfarmbot_ui/__main__.py index 99ea192..49a7aff 100644 --- a/apps/ui/src/twfarmbot_ui/__main__.py +++ b/apps/ui/src/twfarmbot_ui/__main__.py @@ -1,25 +1,8 @@ -"""Entry point: ``twfarmbot-ui`` runs the Streamlit dashboard.""" +"""Entry point: ``twfarmbot-ui`` runs the Material 3 web dashboard.""" from __future__ import annotations -import os -import sys -from pathlib import Path - - -def main() -> None: - from twfarmbot_core.logging import configure_logging - - configure_logging() - - app_path = Path(__file__).parent / "app.py" - # Streamlit expects the form: streamlit run path/to/app.py [args] - sys.argv = ["streamlit", "run", str(app_path), *sys.argv[1:]] - port = os.getenv("TWFB_UI_PORT", "8501") - if "--server.port" not in sys.argv: - sys.argv += ["--server.port", port] - os.execvp("streamlit", sys.argv) - +from twfarmbot_ui.server import main if __name__ == "__main__": main() diff --git a/apps/ui/src/twfarmbot_ui/app.py b/apps/ui/src/twfarmbot_ui/app.py deleted file mode 100644 index 73295f1..0000000 --- a/apps/ui/src/twfarmbot_ui/app.py +++ /dev/null @@ -1,2685 +0,0 @@ -"""TWFarmBot Research UI. - -Sidebar navigation with a clean main canvas. Each tab renders a focused, -compact card-based view. Zero business logic — every read and write is -proxied through the api_server. -""" - -from __future__ import annotations - -import json -import os -import re -import time -from datetime import datetime -from pathlib import Path -from typing import Any - -import altair as alt -import streamlit as st -from ruamel.yaml import YAML -from twfarmbot_ml_utils import ( - VisionProcessor, - parse_segmentation_labels, -) - -from twfarmbot_core.actions import summarize_action - -from twfarmbot_ui.client import ApiClient, ApiResult -from twfarmbot_ui import history - -# ── config ──────────────────────────────────────────────────────────────────── - -API_URL = os.getenv("TWFB_API_URL", "http://127.0.0.1:8000") -RESIREG_URL = os.getenv("TWFB_RESIREG_URL", "http://127.0.0.1:8080") -PLAN_TIMEOUT = 60.0 # LLM planning can take longer than the default 2s API timeout - - -@st.cache_resource -def _client(base_url: str) -> ApiClient: - return ApiClient(base_url) - - -@st.cache_resource -def _image_processor(base_url: str) -> VisionProcessor: - return VisionProcessor(base_url) - - -# ── helpers ─────────────────────────────────────────────────────────────────── - - -def _num(value: Any) -> str: - try: - return f"{float(value):.1f}" - except (TypeError, ValueError): - return "—" - - -def _float(value: Any, default: float = 0.0) -> float: - try: - return float(value) - except (TypeError, ValueError): - return default - - -_NUMBER_RE = re.compile(r"^\s*-?\d+(?:[.,]\d+)?\s*$") - - -def _parse_number(value: Any) -> float | None: - """Parse a user-typed number, accepting both '.' and ',' as decimals. - - Returns ``None`` on invalid input rather than silently defaulting — a - silent fallback here would let a mistyped "1.234,5" (German thousands - style) drive the FarmBot to (0, 0, 0). Callers should treat ``None`` - as a user-visible error. - """ - if isinstance(value, (int, float)): - return float(value) - text = str(value).strip() - if not _NUMBER_RE.match(text): - return None - try: - return float(text.replace(",", ".")) - except (TypeError, ValueError): - return None - - -def _action_summary(action: dict[str, Any]) -> str: - """Return a compact, human-readable summary of an action.""" - return summarize_action(action) - - -def _format_metrics_footer(metrics: dict[str, Any] | None) -> str: - """Return a small grey markdown string with backend timing/usage stats.""" - if not metrics: - return "" - parts: list[str] = [] - total = metrics.get("total_latency_s") - if total is not None: - parts.append(f"total {total:.2f}s") - ttft = metrics.get("ttft_s") - if ttft: - parts.append(f"ttft {ttft:.2f}s") - tps = metrics.get("tokens_per_s") - if tps: - parts.append(f"{tps:.1f} tok/s") - prompt = metrics.get("prompt_tokens") - completion = metrics.get("completion_tokens") - total_tokens = metrics.get("total_tokens") - if total_tokens: - parts.append(f"tokens {prompt or 0}+{completion or 0}={total_tokens}") - resi = metrics.get("resireg_latency_s") - if resi: - parts.append(f"resireg {resi:.2f}s") - if not parts: - return "" - return " · ".join(parts) - - -def _render_assistant_metrics() -> None: - """Show the latest turn's backend timing/usage stats above the chat input.""" - metrics = st.session_state.get("assistant_metrics") or {} - if not metrics: - return - footer = _format_metrics_footer(metrics) - if not footer: - return - st.markdown( - f'
{footer}
', - unsafe_allow_html=True, - ) - - -def _render_tool_call( - name: str, args: Any, result: Any, *, show_image: bool = True -) -> None: - """Render a compact tool call; shows AI-analysis images inline if present.""" - label = f"🔧 {name}" - if name == "analyze_image" and isinstance(args, dict) and args.get("prompt"): - label += f" · '{args['prompt']}'" - elif name == "segment_image" and isinstance(args, dict) and args.get("classes"): - label += f" · '{args['classes']}'" - elif name == "visualize_image_features" and isinstance(args, dict): - label += f" · clusters={args.get('n_clusters', 6)}" - elif ( - name == "estimate_traversability" - and isinstance(args, dict) - and args.get("prompt") - ): - label += f" · '{args['prompt']}'" - elif name == "get_images" and isinstance(args, dict) and args.get("limit"): - label += f" · limit={args['limit']}" - - with st.expander(label, expanded=False): - st.json({"args": args, "result": result}) - - if not show_image or not isinstance(result, dict): - return - - if name == "analyze_image" and result.get("image_url"): - st.image(result["image_url"], use_container_width=True) - elif name == "estimate_traversability" and result.get("image_url"): - st.image(result["image_url"], use_container_width=True) - elif name in {"segment_image", "visualize_image_features"} and result.get( - "image_urls" - ): - cols = st.columns(min(len(result["image_urls"]), 3)) - for idx, url in enumerate(result["image_urls"]): - cols[idx % len(cols)].image(url, use_container_width=True) - for label_text in result.get("labels", []): - st.caption(label_text) - elif result.get("image_url"): - # Fallback for any other tool that returns a single image (e.g. take_photo). - st.image(result["image_url"], use_container_width=True) - - -def _render_proposed_actions_inline( - message: dict[str, Any], actions: list[dict[str, Any]], idx: int -) -> None: - """Render proposed actions as compact inline chat-style approval.""" - with st.container(key=f"proposal_{idx}"): - st.markdown("*I can do this:*") - for action in actions: - st.markdown(f"• {_action_summary(action)}") - approve_col, reject_col = st.columns([1, 1]) - if approve_col.button( - "✓ Approve", key=f"approve_{idx}", use_container_width=True - ): - with st.spinner("Executing actions…"): - results = _execute_proposed_actions(actions, message, wait=True) - message["approved"] = True - message["content"] += "\n\n" + _format_execution_results(results) - _persist_session() - st.rerun() - if reject_col.button("✕ Reject", key=f"reject_{idx}", use_container_width=True): - message["rejected"] = True - message["content"] += "\n\n❌ Cancelled." - _persist_session() - st.rerun() - - -_APPROVAL_WORDS = { - "yes", - "y", - "approve", - "approved", - "ok", - "okay", - "sure", - "go ahead", - "do it", - "confirm", - "confirmed", - "execute", - "run it", -} -_REJECTION_WORDS = { - "no", - "n", - "reject", - "rejected", - "cancel", - "cancelled", - "don't", - "dont", - "stop", - "abort", -} - - -def _is_approval(text: str) -> bool: - return text.strip("!.? ").lower() in _APPROVAL_WORDS - - -def _is_rejection(text: str) -> bool: - return text.strip("!.? ").lower() in _REJECTION_WORDS - - -_CONFIG_PATH = Path(os.getenv("TWFB_CONFIG", "configs/dev.yaml")) - - -def _load_config_yaml() -> tuple[YAML, Any, Path]: - """Load the project YAML while preserving comments and formatting.""" - yaml = YAML() - yaml.preserve_quotes = True - yaml.default_flow_style = False - path = Path(_CONFIG_PATH) - with path.open(encoding="utf-8") as fh: - data = yaml.load(fh) - return yaml, data, path - - -def _entity_id(name: str) -> str: - base = re.sub(r"[^a-z0-9_]+", "_", name.lower()).strip("_") - return base or "entity" - - -def _add_garden_entity(x: float, y: float, kind: str, name: str) -> None: - """Append a new entity to ``configs/dev.yaml`` and reload the world model.""" - yaml, data, path = _load_config_yaml() - spatial = data.setdefault("spatial", {}) - entities = spatial.setdefault("entities", []) - entity = { - "id": _entity_id(name), - "kind": kind, - "name": name, - "x": float(x), - "y": float(y), - "z": 0.0, - "radius_mm": 50, - "metadata": {}, - } - entities.append(entity) - with path.open("w", encoding="utf-8") as fh: - yaml.dump(data, fh) - - -def _selected_garden_points(event: Any) -> list[tuple[float, float]]: - """Extract all selected grid coordinates from an Altair on_select event.""" - if not event: - return [] - selection = event.get("selection") if isinstance(event, dict) else None - if not isinstance(selection, dict): - selection = event if isinstance(event, dict) else {} - points: list[tuple[float, float]] = [] - for value in selection.values(): - if isinstance(value, list): - for item in value: - if isinstance(item, dict): - points.append((float(item.get("x", 0)), float(item.get("y", 0)))) - return points - - -def _garden_grid( - bounds: dict[str, float], step: float = 100.0 -) -> list[dict[str, float]]: - x0 = bounds.get("x", 0) - y0 = bounds.get("y", 0) - width = bounds.get("width", 0) - height = bounds.get("height", 0) - rows: list[dict[str, float]] = [] - xi = x0 - while xi <= x0 + width: - yi = y0 - while yi <= y0 + height: - rows.append({"x": round(xi, 1), "y": round(yi, 1)}) - yi += step - xi += step - return rows - - -def _refresh_position(client: ApiClient) -> None: - xyz = client.get_position() or {} - st.session_state["pos_x"] = _num(xyz.get("x")) - st.session_state["pos_y"] = _num(xyz.get("y")) - st.session_state["pos_z"] = _num(xyz.get("z")) - - -def _refresh_health(client: ApiClient) -> None: - health = client.get_health() - if health is not None: - st.session_state["farmbot_status"] = health.get("farmbot", "?") - st.session_state["actions"] = health.get("actions", []) - - -def _refresh_messages(client: ApiClient) -> None: - st.session_state["messages"] = client.get_messages() - - -def _refresh_telemetry(client: ApiClient) -> None: - _refresh_position(client) - _refresh_health(client) - _refresh_messages(client) - - -def _time_ago(ts: float) -> str: - """Return a human-readable 'X s/min/h ago' string.""" - if not ts: - return "never" - delta = time.time() - ts - if delta < 1: - return "just now" - if delta < 60: - return f"{int(delta)} s ago" - if delta < 3600: - return f"{int(delta / 60)} min ago" - return f"{int(delta / 3600)} h ago" - - -@st.fragment(run_every=1) -def _sidebar_auto_refresh(client: ApiClient) -> None: - """Refresh position and stats in the background without interrupting analysis.""" - position_s = max(1, int(st.session_state.get("refresh_position_s", 2))) - stats_s = max(1, int(st.session_state.get("refresh_stats_s", 300))) - - now = time.time() - if now - st.session_state.get("last_position_refresh", 0) >= position_s: - _refresh_position(client) - st.session_state["last_position_refresh"] = now - if now - st.session_state.get("last_stats_refresh", 0) >= stats_s: - _refresh_health(client) - d = client.request("GET", "/status") - st.session_state["diag"] = ( - d.body.get("state", {}) if d.ok and isinstance(d.body, dict) else {} - ) - info_for_history = (st.session_state.get("diag") or {}).get( - "informational_settings", {} - ) or {} - st.session_state["history"].append( - { - "time": datetime.now().strftime("%H:%M:%S"), - "cpu": _float(info_for_history.get("cpu_usage")), - "memory": _float(info_for_history.get("memory_usage")), - "disk": _float(info_for_history.get("disk_usage")), - "wifi": _float(info_for_history.get("wifi_level_percent")), - "soc": _float(info_for_history.get("soc_temp")), - "uptime": _float(info_for_history.get("uptime")), - } - ) - st.session_state["history"] = st.session_state["history"][-60:] - st.session_state["last_stats_refresh"] = now - - fb = st.session_state.get("farmbot_status", "?") - pill_css = "ok" if fb == "connected" else ("warn" if fb == "skipped" else "bad") - st.markdown(f'● {fb}', unsafe_allow_html=True) - st.caption( - f"X {st.session_state.get('pos_x', '—')} · " - f"Y {st.session_state.get('pos_y', '—')} · " - f"Z {st.session_state.get('pos_z', '—')} mm " - f"· updated {_time_ago(st.session_state.get('last_position_refresh', 0))}" - ) - if st.button("↻ Refresh", use_container_width=True): - _refresh_telemetry(client) - st.rerun(scope="fragment") - - -@st.fragment(run_every=1) -def _camera_auto_refresh(client: ApiClient) -> None: - """Refresh the camera gallery in the background without interrupting analysis.""" - camera_s = int(st.session_state.get("refresh_camera_s", 0)) - if camera_s > 0: - now = time.time() - if now - st.session_state.get("last_camera_refresh", 0) >= camera_s: - r = client.request("GET", "/images", timeout=10.0) - if r.ok and isinstance(r.body, dict): - st.session_state["camera_images"] = r.body.get("images", []) - _persist_session() - st.session_state["last_camera_refresh"] = now - - -@st.fragment(run_every=1) -def _garden_live_pose(client: ApiClient) -> None: - """Update the robot/camera pose on the garden map in the background.""" - position_s = max(1, int(st.session_state.get("refresh_position_s", 2))) - now = time.time() - if now - st.session_state.get("last_garden_pose_refresh", 0) >= position_s: - pos = client.get_position() or {} - world = st.session_state.get("garden_world") - if world: - world["robot"] = { - "x": pos.get("x", 0), - "y": pos.get("y", 0), - "z": pos.get("z", 0), - } - cam_offset = world.get("camera", {}).get("position") or {} - world["camera"] = world.get("camera", {}) - world["camera"]["position"] = { - "x": pos.get("x", 0) + cam_offset.get("x", 0), - "y": pos.get("y", 0) + cam_offset.get("y", 0), - "z": pos.get("z", 0) + cam_offset.get("z", 0), - } - st.session_state["garden_world"] = world - st.session_state["last_garden_pose_refresh"] = now - - -TABS = [ - "Overview", - "Garden", - "Motion", - "Camera", - "I/O", - "Assistant", - "History", - "Diagnostics", - "Settings", -] - - -def _qp_tab() -> str: - """Return the tab key currently set in the URL query string.""" - raw = st.query_params.get("tab") - if isinstance(raw, list): - raw = raw[0] if raw else "" - return (raw or "").lower() - - -def _tab_from_key(key: str) -> str: - """Map a URL-safe tab key back to the display name.""" - low = key.lower() - # Legacy routes from the old Sensors / Operations tabs now live under I/O. - if low in {"sensors", "operations"}: - return "I/O" - for tab in TABS: - if tab.lower() == low: - return tab - return TABS[0] - - -def _sync_tab_url() -> None: - """Callback that updates the URL when the user switches tabs.""" - selected = st.session_state.get("nav_tab") - if selected: - st.query_params["tab"] = selected.lower() - - -def _do_move(client: ApiClient, x: float, y: float, z: float, label: str = "") -> None: - r = client.request( - "POST", "/actions", json={"kind": "move", "params": {"x": x, "y": y, "z": z}} - ) - if r.ok: - msg = f"→ {label}" if label else f"→ ({x:.0f}, {y:.0f}, {z:.0f})" - st.toast(msg, icon="➡️") - _refresh_position(client) - else: - st.error(r.error_message()) - - -def _do_pin_write( - client: ApiClient, pin: int, value: int, mode: str = "digital" -) -> None: - r = client.request( - "POST", - "/actions", - json={ - "kind": "write_pin", - "params": {"pin": pin, "value": value, "mode": mode}, - }, - ) - if r.ok: - st.toast(f"pin {pin} = {value}", icon="✏️") - else: - st.error(r.error_message()) - - -def _do_pin_pulse( - client: ApiClient, pin: int, seconds: float, mode: str = "digital" -) -> None: - r = client.request( - "POST", - "/actions", - json={ - "kind": "write_pin", - "params": {"pin": pin, "value": 1, "mode": mode, "seconds": seconds}, - }, - ) - if r.ok: - st.toast(f"pin {pin} HIGH for {seconds}s", icon="✏️") - else: - st.error(r.error_message()) - - -# ── page shell ──────────────────────────────────────────────────────────────── - -st.set_page_config( - page_title="TWFarmBot Research", - page_icon="🌾", - layout="wide", - initial_sidebar_state="expanded", -) - -st.markdown( - """ - -""", - unsafe_allow_html=True, -) - -api_url = st.session_state.setdefault("api_url", API_URL) -client = _client(api_url) -if "farmbot_status" not in st.session_state: - _refresh_health(client) - _refresh_position(client) - st.session_state.setdefault("messages", []) - -# Auto-refresh settings (persisted via the normal session save). -st.session_state.setdefault("refresh_position_s", 45) -st.session_state.setdefault("refresh_stats_s", 300) -st.session_state.setdefault("refresh_camera_s", 0) -st.session_state.setdefault("last_position_refresh", 0.0) -st.session_state.setdefault("last_stats_refresh", 0.0) -st.session_state.setdefault("last_camera_refresh", 0.0) -st.session_state.setdefault("last_garden_pose_refresh", 0.0) -st.session_state.setdefault("history", []) -st.session_state.setdefault("camera_images", []) -st.session_state.setdefault("garden_world", None) - -# ── sidebar ────────────────────────────────────────────────────────────────── - -with st.sidebar: - st.markdown( - '' - '', - unsafe_allow_html=True, - ) - # Sync the navigation radio with the URL ?tab=... query parameter so - # refreshing the browser returns to the same tab. - url_tab = _tab_from_key(_qp_tab()) - if st.session_state.get("nav_tab") != url_tab: - st.session_state["nav_tab"] = url_tab - tab = st.radio( - "Navigation", - TABS, - key="nav_tab", - on_change=_sync_tab_url, - label_visibility="collapsed", - ) - - st.divider() - _sidebar_auto_refresh(client) - - st.divider() - if st.button("🛑 ESTOP", type="primary", use_container_width=True): - r = client.request("POST", "/actions", json={"kind": "e_stop", "params": {}}) - if r.ok: - st.toast("ESTOP sent", icon="🛑") - else: - st.error(r.error_message()) - -# ── tab content ─────────────────────────────────────────────────────────────── - - -def _render_overview() -> None: - st.markdown( - '
TWFarmBot · UAS Technikum Wien
', - unsafe_allow_html=True, - ) - st.markdown("# Research overview") - - # ── Live position ────────────────────────────────────────────────────────── - row = st.columns(3) - row[0].metric("X · mm", st.session_state.get("pos_x", "—")) - row[1].metric("Y · mm", st.session_state.get("pos_y", "—")) - row[2].metric("Z · mm", st.session_state.get("pos_z", "—")) - st.caption( - f"Position updated {_time_ago(st.session_state.get('last_position_refresh', 0))}" - ) - - # ── System status ────────────────────────────────────────────────────────── - st.markdown("### System status") - st.session_state.setdefault("history", []) - - refresh_col, clear_col = st.columns([3, 1]) - with refresh_col: - refresh_clicked = st.button("🔄 Refresh status", use_container_width=True) - with clear_col: - if st.button("Clear history", use_container_width=True): - st.session_state["history"] = [] - st.rerun() - - if refresh_clicked: - _refresh_health(client) - _refresh_position(client) - d = client.request("GET", "/status") - st.session_state["diag"] = ( - d.body.get("state", {}) if d.ok and isinstance(d.body, dict) else {} - ) - info_for_history = (st.session_state.get("diag") or {}).get( - "informational_settings", {} - ) or {} - st.session_state["history"].append( - { - "time": datetime.now().strftime("%H:%M:%S"), - "cpu": _float(info_for_history.get("cpu_usage")), - "memory": _float(info_for_history.get("memory_usage")), - "disk": _float(info_for_history.get("disk_usage")), - "wifi": _float(info_for_history.get("wifi_level_percent")), - "soc": _float(info_for_history.get("soc_temp")), - "uptime": _float(info_for_history.get("uptime")), - } - ) - # Keep the last 60 samples so the chart stays readable. - st.session_state["history"] = st.session_state["history"][-60:] - st.rerun() - - payload = st.session_state.get("diag", {}) or {} - info = payload.get("informational_settings", {}) or {} - loc = payload.get("location_data", {}) or {} - - status_cols = st.columns(5) - status_cols[0].metric("FarmBot", st.session_state.get("farmbot_status", "—")) - status_cols[1].metric("Uptime", f"{_num(info.get('uptime'))} s") - status_cols[2].metric("Wi-Fi", f"{_num(info.get('wifi_level_percent'))}%") - status_cols[3].metric("Sync", info.get("sync_status", "—")) - status_cols[4].metric("Busy", "Yes" if info.get("busy") else "No") - st.caption( - f"Stats updated {_time_ago(st.session_state.get('last_stats_refresh', 0))}" - ) - - # ── Resources over time ──────────────────────────────────────────────────── - st.markdown("### Resources over time") - cpu = info.get("cpu_usage") - mem = info.get("memory_usage") - disk = info.get("disk_usage") - soc = info.get("soc_temp") - - res_cols = st.columns(4) - res_cols[0].metric("CPU", f"{cpu}%" if cpu is not None else "—") - res_cols[1].metric("Memory", f"{mem}%" if mem is not None else "—") - res_cols[2].metric("Disk", f"{disk}%" if disk is not None else "—") - res_cols[3].metric("SoC temp", f"{soc}°C" if soc is not None else "—") - - hist = st.session_state["history"] - if hist: - base = alt.Chart(alt.Data(values=hist)) - usage_lines = ( - base.transform_fold( - fold=["cpu", "memory", "disk"], - as_=["metric", "value"], - ) - .mark_line(point=True, strokeWidth=2) - .encode( - x=alt.X("time:N", title=None), - y=alt.Y("value:Q", title="Usage %", scale=alt.Scale(domain=[0, 100])), - color=alt.Color( - "metric:N", - scale=alt.Scale( - domain=["cpu", "memory", "disk"], - range=["#3f8f64", "#5b8fc7", "#c7a15b"], - ), - legend=alt.Legend(title="Metric"), - ), - ) - .properties(height=240) - ) - st.altair_chart(usage_lines, use_container_width=True) - - extra_cols = st.columns(2) - with extra_cols[0]: - wifi_chart = ( - base.mark_line(point=True, color="#5b8fc7", strokeWidth=2) - .encode( - x=alt.X("time:N", title=None), - y=alt.Y( - "wifi:Q", title="Wi-Fi %", scale=alt.Scale(domain=[0, 100]) - ), - ) - .properties(height=180) - ) - st.altair_chart(wifi_chart, use_container_width=True) - with extra_cols[1]: - soc_chart = ( - base.mark_line(point=True, color="#c75b5b", strokeWidth=2) - .encode( - x=alt.X("time:N", title=None), - y=alt.Y("soc:Q", title="SoC temp °C"), - ) - .properties(height=180) - ) - st.altair_chart(soc_chart, use_container_width=True) - else: - st.info("Click **Refresh status** to start collecting data for the charts.") - - # ── Network & details ────────────────────────────────────────────────────── - c1, c2 = st.columns(2) - with c1: - st.markdown("**Network & hardware**") - st.caption(f"Private IP: `{info.get('private_ip', '—')}`") - st.caption(f"Wi-Fi signal: {_num(info.get('wifi_level'))} dBm") - st.caption(f"Controller: {info.get('controller_version', '—')}") - st.caption(f"Firmware: {info.get('firmware_version', '—')}") - axes = loc.get("axis_states", {}) or {} - st.caption( - f"Axis states · X {axes.get('x', '—')} · Y {axes.get('y', '—')} · Z {axes.get('z', '—')}" - ) - - with c2: - st.markdown("**Recent events**") - msgs = st.session_state.get("messages", []) - if msgs: - st.code("\n".join(msgs[-10:]), language="text") - else: - st.caption("No events recorded.") - - # ── Experiment notes ─────────────────────────────────────────────────────── - st.markdown("### Experiment") - c1, c2, c3 = st.columns(3) - with c1: - st.text_input( - "Run", - key="run", - placeholder="e.g. soil-map-07", - label_visibility="collapsed", - ) - with c2: - st.text_input( - "Operator", key="op", placeholder="initials", label_visibility="collapsed" - ) - with c3: - st.text_area( - "Notes", - key="notes", - placeholder="Conditions, observations…", - height=90, - label_visibility="collapsed", - ) - - -def _render_garden() -> None: - st.markdown( - '
Spatial model · configured world state
', - unsafe_allow_html=True, - ) - st.markdown("# Garden map") - - refresh_col, _ = st.columns([1, 4]) - if refresh_col.button("↻ Refresh map", use_container_width=True): - st.session_state["garden_world"] = None - - world = st.session_state.get("garden_world") - if world is None: - result = client.request("GET", "/garden") - if not result.ok or not isinstance(result.body, dict): - st.error(f"Garden model unavailable: {result.error_message()}") - return - world = result.body - st.session_state["garden_world"] = world - _persist_session() - - _garden_live_pose(client) - - bounds = world.get("bounds", {}) - camera = world.get("camera", {}) - robot = world.get("robot", {}) - entities = world.get("entities", []) - zones = world.get("zones", []) - - metrics = st.columns(4) - metrics[0].metric("Garden X", f"{_num(bounds.get('width'))} mm") - metrics[1].metric("Garden Y", f"{_num(bounds.get('height'))} mm") - metrics[2].metric("Known objects", len(entities)) - metrics[3].metric("Mapped zones", len(zones)) - - zone_rows = [ - { - **zone["bounds"], - "x2": zone["bounds"]["x"] + zone["bounds"]["width"], - "y2": zone["bounds"]["y"] + zone["bounds"]["height"], - "kind": zone["kind"], - "name": zone["name"], - } - for zone in zones - ] - point_rows = [ - { - "x": entity["position"]["x"], - "y": entity["position"]["y"], - "kind": entity["kind"], - "name": entity["name"], - "radius_mm": entity["radius_mm"], - } - for entity in entities - ] - point_rows.extend( - [ - { - "x": robot.get("x", 0), - "y": robot.get("y", 0), - "kind": "robot", - "name": "FarmBot", - "radius_mm": 35, - }, - { - "x": camera.get("position", {}).get("x", 0), - "y": camera.get("position", {}).get("y", 0), - "kind": "camera", - "name": "Camera", - "radius_mm": 25, - }, - ] - ) - - x_min = bounds.get("x", 0) - x_max = x_min + bounds.get("width", 1) - y_min = bounds.get("y", 0) - y_max = y_min + bounds.get("height", 1) - - def _map_scale(lo: float, hi: float) -> alt.Scale: - # Clamp pan/zoom so the user cannot scroll far outside the garden. - return alt.Scale( - domain=[lo, hi], - domainMin=lo, - domainMax=hi, - clamp=True, - nice=False, - ) - - x_scale = _map_scale(x_min, x_max) - y_scale = _map_scale(y_min, y_max) - - bounds_chart = ( - alt.Chart( - alt.Data( - values=[ - { - "x": x_min, - "y": y_min, - "x2": x_max, - "y2": y_max, - } - ] - ) - ) - .mark_rect(filled=False, stroke="#888888", strokeWidth=2) - .encode( - x=alt.X("x:Q", scale=x_scale, title="X · mm"), - x2="x2:Q", - y=alt.Y("y:Q", scale=y_scale, title="Y · mm"), - y2="y2:Q", - ) - ) - zones_chart = ( - alt.Chart(alt.Data(values=zone_rows)) - .mark_rect(opacity=0.18, strokeWidth=2) - .encode( - x=alt.X("x:Q", scale=x_scale, title="X · mm"), - x2="x2:Q", - y=alt.Y("y:Q", scale=y_scale, title="Y · mm"), - y2="y2:Q", - color=alt.Color("kind:N", title="Layer"), - stroke=alt.Stroke("kind:N", legend=None), - tooltip=["name:N", "kind:N", "x:Q", "y:Q", "width:Q", "height:Q"], - ) - ) - points_chart = ( - alt.Chart(alt.Data(values=point_rows)) - .mark_point(filled=True, stroke="white", strokeWidth=1) - .encode( - x=alt.X("x:Q", scale=x_scale), - y=alt.Y("y:Q", scale=y_scale), - color=alt.Color("kind:N", title="Object"), - shape=alt.value("circle"), - size=alt.Size("radius_mm:Q", scale=alt.Scale(range=[90, 500]), legend=None), - tooltip=["name:N", "kind:N", "x:Q", "y:Q"], - ) - ) - - grid_rows = _garden_grid(bounds, step=25) - click_selection = alt.selection_point( - name="garden_click", - fields=["x", "y"], - on="click", - toggle=True, - nearest=True, - empty=False, - ) - click_layer = ( - alt.Chart(alt.Data(values=grid_rows)) - .mark_point(size=120) - .encode( - x=alt.X("x:Q", scale=x_scale), - y=alt.Y("y:Q", scale=y_scale), - opacity=alt.condition(click_selection, alt.value(0.7), alt.value(0)), - color=alt.value("#ff4b4b"), - ) - .add_params(click_selection) - ) - - map_col, details = st.columns([2.3, 1]) - with map_col: - st.altair_chart( - (bounds_chart + zones_chart + points_chart + click_layer) - .properties(height=520) - .interactive(), - width="stretch", - on_select="rerun", - key="garden_map", - ) - selected_points = _selected_garden_points(st.session_state.get("garden_map")) - with details: - if selected_points: - with st.container(border=True): - st.markdown(f"**🌱 {len(selected_points)} selected**") - kind = st.pills( - "Kind", - [ - "plant", - "obstacle", - "tool", - "marker", - "sensor", - "valve", - "custom", - ], - default="plant", - selection_mode="single", - label_visibility="collapsed", - key="garden_assign_kind", - ) - custom_kind = "" - if kind == "custom": - custom_kind = st.text_input( - "Custom kind", - placeholder="e.g. watering", - key="garden_assign_custom_kind", - ) - name = st.text_input( - "Name prefix", - placeholder="e.g. Tomato", - key="garden_assign_name", - ) - c1, c2 = st.columns(2) - if c1.button( - f"Assign {len(selected_points)}", - key="garden_assign_save", - use_container_width=True, - ): - final_kind = ( - custom_kind - if kind == "custom" and custom_kind - else (kind or "plant") - ) - if name: - for i, (px, py) in enumerate(selected_points, start=1): - _add_garden_entity(px, py, final_kind, f"{name}-{i}") - st.success(f"Added {len(selected_points)} {final_kind}(s)") - st.session_state.pop("garden_map", None) - st.rerun() - else: - st.warning("Please enter a name prefix.") - if c2.button( - "Clear", key="garden_assign_cancel", use_container_width=True - ): - st.session_state.pop("garden_map", None) - st.rerun() - st.markdown("**Live pose**") - pose = st.columns(3) - pose[0].metric("X", _num(robot.get("x"))) - pose[1].metric("Y", _num(robot.get("y"))) - pose[2].metric("Z", _num(robot.get("z"))) - st.markdown("**Camera pose**") - st.caption( - f"X {_num(camera.get('position', {}).get('x'))} · " - f"Y {_num(camera.get('position', {}).get('y'))} · " - f"Z {_num(camera.get('position', {}).get('z'))} mm" - ) - st.caption( - f"Yaw {_num(camera.get('yaw_deg'))}° · " - f"Pitch {_num(camera.get('pitch_deg'))}° · " - f"Roll {_num(camera.get('roll_deg'))}°" - ) - camera_offset = world.get("camera_offset") or {} - if camera_offset: - st.caption( - f"Offset from FarmBot: " - f"X {_num(camera_offset.get('x'))} · " - f"Y {_num(camera_offset.get('y'))} · " - f"Z {_num(camera_offset.get('z'))} mm" - ) - st.markdown("**Mapped objects**") - st.dataframe( - [{"name": item["name"], "kind": item["kind"]} for item in entities], - hide_index=True, - width="stretch", - ) - - -def _render_motion() -> None: - cur_x = _float(st.session_state.get("pos_x")) - cur_y = _float(st.session_state.get("pos_y")) - cur_z = _float(st.session_state.get("pos_z")) - - st.markdown( - '
TWFarmBot · UAS Technikum Wien
', - unsafe_allow_html=True, - ) - st.markdown("# Motion workspace") - - row = st.columns(3) - row[0].metric("X · mm", st.session_state.get("pos_x", "—")) - row[1].metric("Y · mm", st.session_state.get("pos_y", "—")) - row[2].metric("Z · mm", st.session_state.get("pos_z", "—")) - - step = float(st.segmented_control("Jog step · mm", [1, 10, 50, 100], default=10)) - - # D-pad - _, u, _ = st.columns(3) - if u.button("▲ Y+", use_container_width=True): - _do_move( - client, float(cur_x), float(cur_y + step), float(cur_z), f"Y+{step:.0f}" - ) - left, m, right = st.columns(3) - if left.button("◀ X−", use_container_width=True): - _do_move( - client, float(cur_x - step), float(cur_y), float(cur_z), f"X-{step:.0f}" - ) - if m.button("🏠 Home", use_container_width=True): - _do_move(client, 0.0, 0.0, 0.0, "Home") - if right.button("X+ ▶", use_container_width=True): - _do_move( - client, float(cur_x + step), float(cur_y), float(cur_z), f"X+{step:.0f}" - ) - _, d, _ = st.columns(3) - if d.button("▼ Y−", use_container_width=True): - _do_move( - client, float(cur_x), float(cur_y - step), float(cur_z), f"Y-{step:.0f}" - ) - - zl, zr = st.columns(2) - if zl.button("⬆ Z+", use_container_width=True): - _do_move( - client, float(cur_x), float(cur_y), float(cur_z + step), f"Z+{step:.0f}" - ) - if zr.button("⬇ Z−", use_container_width=True): - _do_move( - client, float(cur_x), float(cur_y), float(cur_z - step), f"Z-{step:.0f}" - ) - - st.divider() - with st.form("absolute"): - tx, ty, tz = st.columns(3) - gx = tx.text_input("X", value=f"{cur_x:.2f}") - gy = ty.text_input("Y", value=f"{cur_y:.2f}") - gz = tz.text_input("Z", value=f"{cur_z:.2f}") - if st.form_submit_button("Go to", use_container_width=True): - x = _parse_number(gx) - y = _parse_number(gy) - z = _parse_number(gz) - if None in (x, y, z): - st.error( - f"Invalid coordinates: X={gx!r}, Y={gy!r}, Z={gz!r}. " - "Use a plain number like '123' or '123.4' (comma also accepted)." - ) - else: - _do_move(client, float(x), float(y), float(z)) - - if st.button("Find home"): - resp = client.request( - "POST", "/actions", json={"kind": "find_home", "params": {}} - ) - if resp.ok: - st.toast("Homing queued") - else: - st.error(resp.error_message()) - - # Presets - if "presets" not in st.session_state: - resp = client.request("GET", "/positions") - st.session_state["presets"] = resp.body.get("positions", []) if resp.ok else [] - presets = st.session_state["presets"] - if presets: - st.markdown("**Locations**") - cols = st.columns(min(5, len(presets))) - for i, p in enumerate(presets): - if cols[i].button( - p.get("label", "?"), key=f"preset_{i}", use_container_width=True - ): - _do_move( - client, float(p["x"]), float(p["y"]), float(p["z"]), p["label"] - ) - - -def _render_io() -> None: - st.markdown( - '
TWFarmBot · UAS Technikum Wien
', - unsafe_allow_html=True, - ) - st.markdown("# I/O workspace") - - if "named_pins" not in st.session_state: - r = client.request("GET", "/pins") - st.session_state["named_pins"] = r.body.get("pins", []) if r.ok else [] - named = st.session_state["named_pins"] - - # ── Sensors ─────────────────────────────────────────────────────────────── - sensors = [p for p in named if p.get("kind") == "sensor"] - if sensors: - st.markdown("### 🔍 Sensors") - cols = st.columns(min(3, len(sensors))) - for i, s in enumerate(sensors): - with cols[i]: - with st.container(border=True): - mode = s.get("mode", "analog") - st.markdown( - f"**{s['label']}** {mode}", - unsafe_allow_html=True, - ) - st.caption(f"pin {s['pin']}") - if st.button("Read", key=f"sensor_{i}", use_container_width=True): - r = client.request( - "GET", - f"/pin/{s['pin']}", - params={"mode": mode}, - ) - st.session_state[f"sv_{s['pin']}"] = ( - r.body.get("value") if r.ok else "—" - ) - sensor_value = st.session_state.get(f"sv_{s['pin']}", "—") - st.markdown( - f"
{sensor_value}
", - unsafe_allow_html=True, - ) - elif named: - st.info("No sensor pins configured.") - - st.divider() - - # ── Actuators ───────────────────────────────────────────────────────────── - st.markdown("### ⚡ Actuators") - a, b = st.columns(2) - with a: - with st.container(border=True): - st.markdown("**💧 Irrigation**") - secs = st.number_input("Seconds", 0.1, 300.0, 2.0, 0.5, key="water_secs") - if st.button("Water", use_container_width=True, type="primary"): - r = client.request( - "POST", - "/actions", - json={"kind": "water", "params": {"seconds": secs}}, - ) - if r.ok: - st.success("Queued") - else: - st.error(r.error_message()) - st.caption("Runs the pump for the selected duration.") - - with b: - with st.container(border=True): - st.markdown("**🔌 Peripheral control**") - outputs = [p for p in named if p.get("kind") != "sensor"] - if not outputs: - st.info("No output pins configured.") - else: - sel = st.selectbox( - "Output", - outputs, - format_func=lambda p: f"{p['label']} · pin {p['pin']}", - label_visibility="collapsed", - ) - if sel: - mode = sel.get("mode", "digital") - st.markdown( - f"{mode}", - unsafe_allow_html=True, - ) - - if mode == "analog": - presets = sel.get("presets") or {} - if presets: - st.caption("Presets") - preset_cols = st.columns(len(presets)) - for idx, (pval, plabel) in enumerate( - sorted(presets.items(), key=lambda x: int(x[0])) - ): - if preset_cols[idx].button( - f"{plabel} ({pval})", - use_container_width=True, - key=f"preset_{sel['pin']}_{pval}", - ): - _do_pin_write(client, sel["pin"], int(pval), mode) - - val_col, btn_col = st.columns([4, 1]) - with val_col: - analog_value = st.slider( - "PWM value", - min_value=0, - max_value=255, - value=0, - key=f"analog_value_{sel['pin']}", - ) - with btn_col: - st.markdown( - "
", - unsafe_allow_html=True, - ) - if st.button("Apply", use_container_width=True): - _do_pin_write(client, sel["pin"], analog_value, mode) - else: - pulse = st.toggle("Timed pulse", value=True) - pulse_secs: float | None = None - if pulse: - pulse_secs = st.number_input( - "Seconds", - 0.1, - 300.0, - 2.0, - 0.5, - key=f"pulse_secs_{sel['pin']}", - ) - - off, on = st.columns(2) - if off.button("⏻ OFF", use_container_width=True): - _do_pin_write(client, sel["pin"], 0, mode) - if on.button("⏻ ON", use_container_width=True, type="primary"): - if pulse and pulse_secs is not None: - _do_pin_pulse(client, sel["pin"], pulse_secs, mode) - else: - _do_pin_write(client, sel["pin"], 1, mode) - - -def _render_camera() -> None: - st.markdown( - '
TWFarmBot · UAS Technikum Wien
', - unsafe_allow_html=True, - ) - st.markdown("# Camera") - - _camera_auto_refresh(client) - - capture, refresh, _ = st.columns([1, 1, 4]) - if capture.button("📷 Take photo", type="primary", use_container_width=True): - r = client.request( - "POST", "/actions", json={"kind": "take_photo", "params": {}} - ) - if r.ok: - st.toast("Capture queued", icon="📷") - # Fetch the gallery so the new capture appears as soon as it is ready. - rg = client.request("GET", "/images", timeout=10.0) - if rg.ok and isinstance(rg.body, dict): - st.session_state["camera_images"] = rg.body.get("images", []) - _persist_session() - else: - st.error(r.error_message()) - if refresh.button("↻ Refresh gallery", use_container_width=True): - r = client.request("GET", "/images", params={"refresh": "true"}, timeout=10.0) - if r.ok and isinstance(r.body, dict): - st.session_state["camera_images"] = r.body.get("images", []) - _persist_session() - else: - st.error(r.error_message()) - - images = st.session_state.get("camera_images", []) - if not images: - st.info("Refresh the gallery to load FarmBot photos.") - return - - selected = st.selectbox( - "Research image", - images, - format_func=lambda image: ( - f"{image.get('created_at', 'Unknown time')} · image {image.get('id', '—')}" - ), - ) - - # Show the source image and analysis controls side-by-side so both fit - # above the fold without scrolling. The analysis results still appear below. - img_col, ctrl_col = st.columns([1.6, 1]) - - with img_col: - st.image(selected.get("attachment_url"), use_container_width=True) - - with ctrl_col: - st.markdown("**AI analysis**") - mode = st.selectbox( - "Mode", - [ - "Open Language Similarity", - "Zero-Shot Segmentation", - "PCA Feature Visualization", - "Traversability Estimation", - ], - key=f"ai_mode_{selected.get('id', 'unknown')}", - label_visibility="collapsed", - ) - - processor = _image_processor(RESIREG_URL) - inputs: dict[str, Any] = {} - button_disabled = False - - if mode == "Open Language Similarity": - inputs["prompt"] = st.text_input( - "Target prompt", - placeholder="e.g. green leaves, dry soil, red marker", - key=f"ai_prompt_{selected.get('id', 'unknown')}", - label_visibility="collapsed", - ) - button_disabled = not inputs["prompt"].strip() - elif mode == "Zero-Shot Segmentation": - inputs["classes"] = st.text_input( - "Classes (comma-separated)", - value="plant, weed, soil, path", - key=f"ai_classes_{selected.get('id', 'unknown')}", - ) - inputs["negative"] = st.text_input( - "Background prompt (optional)", - placeholder="e.g. thing, object, stuff", - key=f"ai_negative_{selected.get('id', 'unknown')}", - ) - button_disabled = not inputs["classes"].strip() - elif mode == "PCA Feature Visualization": - inputs["n_clusters"] = st.slider( - "K-means clusters", - min_value=2, - max_value=20, - value=6, - key=f"ai_clusters_{selected.get('id', 'unknown')}", - ) - elif mode == "Traversability Estimation": - inputs["prompt"] = st.text_input( - "Traversable prompt", - placeholder="e.g. path, road, flat ground", - key=f"ai_trav_prompt_{selected.get('id', 'unknown')}", - label_visibility="collapsed", - ) - inputs["negatives"] = st.text_input( - "Background prompts (optional, comma-separated)", - placeholder="e.g. thing, object, stuff, scenery", - key=f"ai_trav_negatives_{selected.get('id', 'unknown')}", - ) - button_disabled = not inputs["prompt"].strip() - - if st.button( - "Analyze selected image", - type="primary", - use_container_width=True, - disabled=button_disabled, - ): - try: - with st.spinner("Processing image…"): - if mode == "Open Language Similarity": - result_path = processor.process( - selected["attachment_url"], - inputs["prompt"].strip(), - negatives="", - ) - st.session_state["ai_result"] = { - "image_id": selected.get("id"), - "source_url": selected.get("attachment_url"), - "paths": [str(result_path)], - "captions": [f"Similarity map · {inputs['prompt']}"], - "labels": [], - "mode": mode, - } - elif mode == "Zero-Shot Segmentation": - raw = processor.predict( - selected["attachment_url"], - api_name="/run_seg", - classes=inputs["classes"].strip(), - negative=inputs["negative"].strip(), - ) - labels = [str(raw[2]), str(raw[3])] - class_scores = parse_segmentation_labels(labels) - st.session_state["ai_result"] = { - "image_id": selected.get("id"), - "source_url": selected.get("attachment_url"), - "paths": [str(raw[0]), str(raw[1])], - "captions": ["Segmentation overlay", "Segmentation map"], - "labels": labels, - "class_scores": class_scores, - "dominant_class": ( - max(class_scores, key=class_scores.get) - if class_scores - else None - ), - "classes": inputs["classes"].strip(), - "mode": mode, - } - elif mode == "PCA Feature Visualization": - raw = processor.predict( - selected["attachment_url"], - api_name="/run_pca", - n_clusters=int(inputs["n_clusters"]), - ) - st.session_state["ai_result"] = { - "image_id": selected.get("id"), - "source_url": selected.get("attachment_url"), - "paths": [str(raw[0]), str(raw[1]), str(raw[2])], - "captions": [ - "PCA visualization 1", - "PCA visualization 2", - "PCA visualization 3", - ], - "labels": [], - "n_clusters": int(inputs["n_clusters"]), - "mode": mode, - } - elif mode == "Traversability Estimation": - result_path = processor.predict( - selected["attachment_url"], - api_name="/run_trav", - prompt=inputs["prompt"].strip(), - negatives=inputs["negatives"].strip(), - ) - st.session_state["ai_result"] = { - "image_id": selected.get("id"), - "source_url": selected.get("attachment_url"), - "paths": [str(result_path)], - "captions": [f"Traversability map · {inputs['prompt']}"], - "labels": [], - "mode": mode, - } - except Exception as exc: - st.error(f"AI processing failed: {exc}") - - result = st.session_state.get("ai_result") - if result: - st.markdown("### Analysis result") - result_cols = st.columns(len(result["paths"])) - for idx, (path, caption) in enumerate(zip(result["paths"], result["captions"])): - with result_cols[idx]: - st.image(path, caption=caption, use_container_width=True) - - st.markdown("**Raw output**") - if result.get("class_scores"): - score_cols = st.columns(len(result["class_scores"])) - for idx, (cls, score) in enumerate(result["class_scores"].items()): - score_cols[idx].metric(cls, f"{score * 100:.1f}%") - if result.get("dominant_class"): - st.caption(f"Dominant class: **{result['dominant_class']}**") - elif result.get("n_clusters"): - st.caption(f"PCA with **{result['n_clusters']}** K-means clusters") - - for label in result.get("labels", []): - st.caption(label) - - if len(images) > 1: - st.markdown("**Recent captures**") - gallery = st.columns(3) - for index, image in enumerate(images[1:7]): - image_meta = image.get("meta") or {} - gallery[index % 3].image( - image.get("attachment_url"), - caption=f"X {image_meta.get('x', '—')} · Y {image_meta.get('y', '—')}", - width=240, - ) - - -def _render_model_picker() -> str | None: - """Render provider + model selectors and return the selected model id.""" - if "assistant_providers" not in st.session_state: - r = client.request("GET", "/providers") - if r.ok and isinstance(r.body, dict): - st.session_state["assistant_providers"] = r.body.get("providers", []) - st.session_state["assistant_provider"] = r.body.get("current", "openrouter") - else: - st.session_state["assistant_providers"] = ["openrouter", "local"] - st.session_state["assistant_provider"] = "openrouter" - - providers = st.session_state["assistant_providers"] - provider_col, model_col = st.columns([1, 2]) - with provider_col: - provider = st.selectbox( - "Provider", - providers, - key="assistant_provider", - ) - - cache = st.session_state.setdefault("assistant_models_cache", {}) - if provider not in cache: - r = client.request("GET", "/models", params={"provider": provider}) - if r.ok and isinstance(r.body, dict): - cache[provider] = r.body.get("models", []) - if not st.session_state.get("assistant_model"): - st.session_state["assistant_model"] = r.body.get("current") - else: - cache[provider] = [] - - models = cache.get(provider, []) - selected_model: str | None = None - with model_col: - if models: - current = st.session_state.get("assistant_model") - # Avoid defaulting to the first option from a raw provider list, - # which may be a meta/safeguard model that cannot chat. - if current not in models: - preferred = [ - "openai/gpt-4o-mini", - "openai/gpt-4o", - "anthropic/claude-3.5-sonnet", - "anthropic/claude-3.5-haiku", - "deepseek/deepseek-v4-flash", - ] - current = next((m for m in preferred if m in models), models[0]) - st.session_state["assistant_model"] = current - index = models.index(current) - selected_model = st.selectbox( - "Model", - models, - index=index, - key="assistant_model", - ) - else: - selected_model = ( - st.text_input( - "Model", - value=st.session_state.get("assistant_model", ""), - key="assistant_model", - ) - or None - ) - return selected_model - - -def _render_assistant() -> None: - st.markdown( - '
TWFarmBot · UAS Technikum Wien
', - unsafe_allow_html=True, - ) - title_col, clear_col = st.columns([5, 1]) - with title_col: - st.markdown("# Assistant") - with clear_col: - if st.button("Clear chat", use_container_width=True): - st.session_state["assistant_messages"] = [] - _persist_session() - st.rerun() - _render_session_controls() - selected_model = _render_model_picker() - st.session_state["assistant_selected_model"] = selected_model - _render_chat() - _persist_session() - - -def _render_chat() -> None: - if "assistant_messages" not in st.session_state: - st.session_state["assistant_messages"] = [] - - for idx, msg in enumerate(st.session_state["assistant_messages"]): - if msg.get("role") == "tool": - with st.chat_message("assistant"): - _render_tool_call( - msg.get("name", "tool"), - msg.get("args"), - msg.get("result"), - show_image=True, - ) - continue - - if msg.get("role") == "user": - with st.container(key=f"user_msg_{idx}"): - with st.chat_message("user"): - st.markdown(msg["content"]) - continue - - # Render the model's reasoning as its own collapsible assistant pill, - # similar to how tool calls are shown, so the conversation flow is clear. - if msg.get("thinking"): - with st.chat_message("assistant"): - with st.expander("🧠 Thinking", expanded=False): - st.markdown(msg["thinking"]) - - with st.chat_message(msg["role"]): - st.markdown(msg["content"]) - images = msg.get("images", []) - if images: - cols = st.columns(min(len(images), 3)) - for i, image in enumerate(images): - cols[i % len(cols)].image(image.get("attachment_url"), width=220) - - proposed_actions = msg.get("proposed_actions", []) - if proposed_actions and not msg.get("approved") and not msg.get("rejected"): - _render_proposed_actions_inline(msg, proposed_actions, idx) - elif msg.get("approved"): - st.caption("Approved") - elif msg.get("rejected"): - st.caption("Rejected") - - _render_assistant_metrics() - - if prompt := st.chat_input("Ask the FarmBot assistant…"): - messages = st.session_state["assistant_messages"] - - # Natural-language approval/rejection: if the user replies "yes", - # "approve", "no", "cancel", etc. to a proposal, handle it immediately - # instead of sending it back to the model and getting a confused answer. - if messages and messages[-1].get("role") == "assistant": - last_assistant = messages[-1] - proposed = last_assistant.get("proposed_actions", []) - pending = ( - proposed - and not last_assistant.get("approved") - and not last_assistant.get("rejected") - ) - approval = _is_approval(prompt) - rejection = _is_rejection(prompt) - if approval or rejection: - if pending: - st.session_state["assistant_messages"].append( - {"role": "user", "content": prompt} - ) - with st.container(key="user_msg_current"): - with st.chat_message("user"): - st.markdown(prompt) - if approval: - with st.spinner("Executing actions…"): - results = _execute_proposed_actions( - proposed, last_assistant, wait=True - ) - last_assistant["approved"] = True - last_assistant["content"] += "\n\n" + _format_execution_results( - results - ) - else: - last_assistant["rejected"] = True - last_assistant["content"] += "\n\n❌ Cancelled." - _persist_session() - st.rerun() - else: - st.toast("No pending proposal to approve or reject.", icon="⚠️") - _persist_session() - st.rerun() - - st.session_state["assistant_messages"].append( - {"role": "user", "content": prompt} - ) - with st.container(key="user_msg_current"): - with st.chat_message("user"): - st.markdown(prompt) - - thinking = st.empty() - thinking.caption("🤖 Assistant is thinking…") - with st.chat_message("assistant"): - stream_meta: dict[str, Any] = { - "tool_calls": [], - "proposed_actions": [], - } - stream_thinking: list[str] = [] - stream_error = None - accumulated = "" - # Preserve the order of streamed text relative to tools/thinking. - # Each open segment is a placeholder that gets updated in place. - # When a tool or thinking block starts, the current text segment is - # closed so subsequent text appears *after* that block. - text_segments: list[list[Any] | None] = [] - - def _current_text_segment() -> list[Any]: - if not text_segments or text_segments[-1] is None: - ph = st.empty() - text_segments.append([ph, ""]) - seg = text_segments[-1] - assert seg is not None - return seg - - def _close_text_segment() -> None: - if text_segments and text_segments[-1] is not None: - text_segments.append(None) - - try: - for event in client.stream( - "POST", - "/chat/stream", - json={ - "messages": st.session_state["assistant_messages"], - "model": st.session_state.get("assistant_selected_model"), - }, - timeout=PLAN_TIMEOUT, - ): - etype = event.get("type") - if etype == "delta": - accumulated += event.get("content", "") - seg = _current_text_segment() - seg[1] = accumulated - seg[0].markdown(accumulated) - elif etype == "thinking": - _close_text_segment() - think_text = str(event.get("content", "")) - with st.expander("🧠 Thinking", expanded=False): - st.markdown(think_text) - stream_thinking.append(think_text) - elif etype == "tool_call": - _close_text_segment() - thinking.caption("🤖 Assistant is using tools…") - name = event.get("name") - args = event.get("args") - result = event.get("result") - st.session_state["assistant_messages"].append( - { - "role": "tool", - "name": name, - "args": args, - "result": result, - } - ) - if ( - name == "take_photo" - and isinstance(result, dict) - and result.get("status") == "ok" - ): - image = _capture_photo_image() - if image: - result["image_url"] = image.get("attachment_url") - _render_tool_call(name, args, result) - elif etype == "meta": - stream_meta["tool_calls"] = event.get("tool_calls", []) - stream_meta["proposed_actions"] = event.get( - "proposed_actions", [] - ) - stream_meta["metrics"] = event.get("metrics", {}) - if stream_meta["metrics"]: - st.session_state["assistant_metrics"] = stream_meta[ - "metrics" - ] - elif etype == "error": - stream_error = event.get("error", "stream error") - except Exception as exc: # noqa: BLE001 - stream_error = f"{type(exc).__name__}: {exc}" - - # If the stream produced nothing useful, fall back to the - # non-streaming endpoint so the chat still works even when the - # SSE path is blocked or misbehaving. - if ( - not accumulated - and not stream_meta["tool_calls"] - and not stream_meta["proposed_actions"] - ): - try: - r = client.request( - "POST", - "/chat", - json={ - "messages": st.session_state["assistant_messages"], - "model": st.session_state.get("assistant_selected_model"), - }, - timeout=PLAN_TIMEOUT, - ) - if r.ok and isinstance(r.body, dict): - accumulated = str(r.body.get("response", "")) - stream_meta["tool_calls"] = r.body.get("tool_calls", []) or [] - stream_meta["metrics"] = r.body.get("metrics", {}) or {} - if stream_meta["metrics"]: - st.session_state["assistant_metrics"] = stream_meta[ - "metrics" - ] - for tc in stream_meta["tool_calls"]: - st.session_state["assistant_messages"].append( - { - "role": "tool", - "name": tc.get("name"), - "args": tc.get("args"), - "result": tc.get("result"), - } - ) - stream_meta["proposed_actions"] = [ - { - "kind": tc["result"].get("kind", tc["name"]), - "params": tc["result"].get( - "params", tc.get("args", {}) - ), - } - for tc in stream_meta["tool_calls"] - if isinstance(tc.get("result"), dict) - and tc["result"].get("status") == "proposed" - ] - stream_thinking = [str(r.body.get("thinking", ""))] - stream_error = None - if accumulated: - seg = _current_text_segment() - seg[1] = accumulated - seg[0].markdown(accumulated) - else: - stream_error = f"Fallback failed: {r.error_message()}" - except Exception as exc: # noqa: BLE001 - stream_error = f"Fallback failed: {type(exc).__name__}: {exc}" - - thinking.empty() - if stream_error: - st.error(f"Assistant error: {stream_error}") - - if ( - accumulated - or stream_meta["tool_calls"] - or stream_meta["proposed_actions"] - ): - # Analysis images are shown inline with their tool calls above, - # so we only keep plain photo attachments on the assistant message. - photo_images = [ - {"attachment_url": img.get("attachment_url")} - for img in stream_meta.get("images", []) - if isinstance(img, dict) and img.get("attachment_url") - ] - st.session_state["assistant_messages"].append( - { - "role": "assistant", - "content": accumulated, - "thinking": "".join(stream_thinking), - "tool_calls": stream_meta["tool_calls"], - "proposed_actions": stream_meta["proposed_actions"], - "images": photo_images, - "metrics": stream_meta.get("metrics", {}), - } - ) - _persist_session() - st.rerun() - - -def _fetch_latest_image() -> dict[str, Any] | None: - """Return the most recent FarmBot image via the existing /images endpoint.""" - result = client.request( - "GET", "/images", params={"limit": "1", "refresh": "true"}, timeout=10.0 - ) - if result.ok and isinstance(result.body, dict): - images = result.body.get("images", []) - if images: - return images[0] - return None - - -def _image_is_newer(image: dict[str, Any], previous: dict[str, Any]) -> bool: - """Return True if image is strictly newer/different than previous.""" - if image.get("id") is not None and previous.get("id") is not None: - return image["id"] != previous["id"] - new_ts = image.get("created_at", "") - old_ts = previous.get("created_at", "") - if new_ts and old_ts: - return new_ts > old_ts - return True - - -def _wait_for_new_image( - previous: dict[str, Any] | None, - max_attempts: int = 15, - delay: float = 2.0, -) -> dict[str, Any] | None: - """Poll /images until an image newer than ``previous`` appears.""" - for _ in range(max_attempts): - image = _fetch_latest_image() - if image and (previous is None or _image_is_newer(image, previous)): - return image - time.sleep(delay) - return None - - -def _capture_photo_image() -> dict[str, Any] | None: - """Fetch the latest image after take_photo, polling for a fresh upload.""" - baseline = _fetch_latest_image() - for _ in range(8): - image = _fetch_latest_image() - if image: - if baseline is None or _image_is_newer(image, baseline): - return image - # If baseline is already the newest, wait briefly in case the - # just-triggered photo is still uploading. - time.sleep(1.5) - return baseline - - -def _execute_proposed_actions( - actions: list[dict[str, Any]], - message: dict[str, Any] | None = None, - *, - wait: bool = True, -) -> list[dict[str, Any]]: - """Dispatch proposed actions and return per-action results. - - By default this waits for each action to finish so the UI can give - immediate feedback. For fire-and-forget dispatch, pass ``wait=False``. - """ - will_capture = message is not None and any( - action.get("kind") == "take_photo" for action in actions - ) - previous_image = _fetch_latest_image() if will_capture else None - - results: list[dict[str, Any]] = [] - for action in actions: - r = client.request( - "POST", - "/actions", - json={"kind": action["kind"], "params": action.get("params", {})}, - params={"wait": "true" if wait else "false"}, - ) - results.append( - { - "kind": action["kind"], - "ok": r.ok, - "status": "ok" if r.ok else "error", - "detail": r.body - if isinstance(r.body, str) - else r.body.get("detail") - if isinstance(r.body, dict) - else str(r.body), - } - ) - - if will_capture: - new_image = _wait_for_new_image(previous_image) - if new_image: - message.setdefault("images", []).append(new_image) - - return results - - -def _format_execution_results(results: list[dict[str, Any]]) -> str: - """Turn per-action results into a short, human-readable summary.""" - if not results: - return "✅ Approved (no actions)." - lines: list[str] = [] - for res in results: - summary = _action_summary({"kind": res["kind"], "params": {}}) - if res.get("ok"): - lines.append(f"✅ {summary}") - else: - lines.append(f"❌ {summary} — {res.get('detail', 'unknown error')}") - return "\n".join(lines) - - -# ── session persistence ─────────────────────────────────────────────────────── - - -def _has_session_state() -> bool: - """Return True if any chat/plan state has been initialised.""" - return ( - "assistant_messages" in st.session_state - or "assistant_plan_response" in st.session_state - or "executed_plans" in st.session_state - ) - - -def _is_session_empty() -> bool: - """Return True if the current session has nothing worth saving.""" - messages = st.session_state.get("assistant_messages") or [] - plan_response = st.session_state.get("assistant_plan_response") - executed = st.session_state.get("executed_plans") or [] - return not messages and not plan_response and not executed - - -def _restore_session() -> None: - """Load the latest or URL-specified session on first app load.""" - if _has_session_state(): - return - - session_id = st.query_params.get("session") - if isinstance(session_id, list): - session_id = session_id[0] if session_id else None - - snapshot: dict[str, Any] | None = None - if session_id: - snapshot = history.load_session(session_id) - if snapshot is None: - sessions = history.list_sessions(limit=1) - if sessions: - snapshot = history.load_session(sessions[0]["session_id"]) - - if snapshot is None: - snapshot = history.empty_snapshot() - - st.session_state["assistant_session_id"] = snapshot["session_id"] - st.session_state["assistant_session_label"] = snapshot.get("label") - st.session_state["assistant_messages"] = snapshot.get("assistant_messages", []) - st.session_state["assistant_plan_request"] = snapshot.get( - "assistant_plan_request", "" - ) - st.session_state["assistant_plan_response"] = snapshot.get( - "assistant_plan_response" - ) - st.session_state["assistant_plan_status"] = snapshot.get("assistant_plan_status") - st.session_state["assistant_selected_model"] = snapshot.get( - "assistant_selected_model" - ) - st.session_state["assistant_metrics"] = snapshot.get("assistant_metrics", {}) - st.session_state["executed_plans"] = snapshot.get("executed_plans", []) - st.session_state["refresh_position_s"] = snapshot.get("refresh_position_s", 2) - st.session_state["refresh_stats_s"] = snapshot.get("refresh_stats_s", 300) - st.session_state["refresh_camera_s"] = snapshot.get("refresh_camera_s", 0) - st.session_state["camera_images"] = snapshot.get("camera_images", []) - st.session_state["garden_world"] = snapshot.get("garden_world") - - -def _persist_session() -> None: - """Save the current chat/plan state to disk.""" - if _is_session_empty(): - return - snapshot = history.empty_snapshot( - session_id=st.session_state.get("assistant_session_id") - ) - snapshot["label"] = st.session_state.get("assistant_session_label") - snapshot["created_at"] = st.session_state.get( - "assistant_session_created_at", snapshot["created_at"] - ) - snapshot["assistant_messages"] = st.session_state.get("assistant_messages", []) - snapshot["assistant_plan_request"] = st.session_state.get( - "assistant_plan_request", "" - ) - snapshot["assistant_plan_response"] = st.session_state.get( - "assistant_plan_response" - ) - snapshot["assistant_plan_status"] = st.session_state.get("assistant_plan_status") - snapshot["assistant_selected_model"] = st.session_state.get( - "assistant_selected_model" - ) - snapshot["assistant_metrics"] = st.session_state.get("assistant_metrics", {}) - snapshot["refresh_position_s"] = st.session_state.get("refresh_position_s", 2) - snapshot["refresh_stats_s"] = st.session_state.get("refresh_stats_s", 300) - snapshot["refresh_camera_s"] = st.session_state.get("refresh_camera_s", 0) - snapshot["camera_images"] = st.session_state.get("camera_images", []) - snapshot["garden_world"] = st.session_state.get("garden_world") - snapshot["executed_plans"] = st.session_state.get("executed_plans", []) - history.save_session(snapshot) - - -def _render_session_controls() -> None: - """Render session management widgets inside the Assistant tab.""" - with st.expander("🗂️ Session", expanded=False): - current_label = st.text_input( - "Session label", - value=st.session_state.get("assistant_session_label") or "", - key="assistant_session_label_input", - placeholder="e.g. watering experiment", - ) - st.session_state["assistant_session_label"] = current_label.strip() or None - - new_col, save_col = st.columns([1, 1]) - if new_col.button("New session", use_container_width=True): - _persist_session() - new_id = history.new_session_id() - st.session_state["assistant_session_id"] = new_id - st.session_state["assistant_session_label"] = None - st.session_state["assistant_messages"] = [] - st.session_state["assistant_plan_request"] = "" - st.session_state["assistant_plan_response"] = None - st.session_state["assistant_plan_status"] = None - st.session_state["executed_plans"] = [] - st.query_params.pop("session", None) - st.rerun() - if save_col.button("Save now", use_container_width=True): - _persist_session() - st.toast("Session saved", icon="💾") - - sessions = history.list_sessions(limit=20) - if sessions: - st.divider() - st.markdown("**Previous sessions**") - for sess in sessions: - if sess["session_id"] == st.session_state.get("assistant_session_id"): - continue - label = sess["label"] or sess["session_id"] - preview = sess["preview"] - c1, c2, c3 = st.columns([3, 1, 1]) - c1.caption(f"{label}" + (f" · {preview}" if preview else "")) - if c2.button( - "Load", key=f"load_sess_{sess['session_id']}", use_container_width=True - ): - snapshot = history.load_session(sess["session_id"]) - if snapshot is None: - st.error("Session not found") - continue - st.session_state["assistant_session_id"] = snapshot["session_id"] - st.session_state["assistant_session_label"] = snapshot.get("label") - st.session_state["assistant_messages"] = snapshot.get( - "assistant_messages", [] - ) - st.session_state["assistant_plan_request"] = snapshot.get( - "assistant_plan_request", "" - ) - st.session_state["assistant_plan_response"] = snapshot.get( - "assistant_plan_response" - ) - st.session_state["assistant_plan_status"] = snapshot.get( - "assistant_plan_status" - ) - st.session_state["assistant_selected_model"] = snapshot.get( - "assistant_selected_model" - ) - st.session_state["executed_plans"] = snapshot.get("executed_plans", []) - st.query_params["session"] = snapshot["session_id"] - st.rerun() - if c3.button( - "🗑", key=f"del_sess_{sess['session_id']}", use_container_width=True - ): - history.delete_session(sess["session_id"]) - st.rerun() - - -def _render_plan() -> None: - st.caption( - "Describe a task. The LLM builds a step-by-step plan; review it before running." - ) - - selected_model = _render_model_picker() - st.session_state["assistant_selected_model"] = selected_model - - if "assistant_plan_response" not in st.session_state: - st.session_state["assistant_plan_response"] = None - if "assistant_plan_status" not in st.session_state: - st.session_state["assistant_plan_status"] = None - if "assistant_plan_request" not in st.session_state: - st.session_state["assistant_plan_request"] = "" - - examples = [ - "Water the tomato zone for 90 seconds, then go home", - "Take a photo and send me the result", - "Move to x=500 y=200 z=0", - ] - cols = st.columns(len(examples)) - for col, example in zip(cols, examples): - if col.button(example, use_container_width=True, key=f"plan_ex_{example[:20]}"): - st.session_state["assistant_plan_request"] = example - st.session_state["assistant_plan_response"] = None - st.session_state["assistant_plan_status"] = None - st.rerun() - - request = st.text_area( - "Task", - value=st.session_state["assistant_plan_request"], - placeholder="e.g. water bed for 60 seconds, then home", - height=80, - label_visibility="collapsed", - ) - st.session_state["assistant_plan_request"] = request - - plan_col, _ = st.columns([1, 3]) - preview_clicked = plan_col.button( - "Preview plan", - type="primary", - use_container_width=True, - disabled=not request.strip(), - ) - - if preview_clicked and request.strip(): - with st.spinner("Asking the planner…"): - r = client.request( - "POST", - "/plan", - json={ - "request": request, - "debug": True, - "model": st.session_state.get("assistant_selected_model"), - }, - timeout=PLAN_TIMEOUT, - ) - st.session_state["assistant_plan_response"] = ( - r.body if r.ok else {"error": r.body} - ) - st.session_state["assistant_plan_status"] = r.code - _persist_session() - - response = st.session_state.get("assistant_plan_response") - status = st.session_state.get("assistant_plan_status") - - if not response: - st.info("No plan yet. Type a task above and click **Preview plan**.") - return - - with st.expander("Debug · raw response", expanded=False): - st.json(response) - - if status and status >= 400: - err_body = response.get("error", response) - st.error( - f"Planner error (HTTP {status}): " - f"{ApiResult(ok=False, code=status, body=err_body).error_message()}" - ) - return - - actions = response.get("actions", []) or [] - rationale = response.get("rationale") if isinstance(response, dict) else None - st.success(f"Plan ready · {len(actions)} action(s)") - if rationale: - st.caption(f"Model rationale: {rationale}") - - if not actions: - st.warning("The planner returned an empty plan.") - return - - st.markdown("**Proposed actions**") - for idx, action in enumerate(actions, start=1): - with st.container(border=True): - st.markdown(f"{idx}. {_action_summary(action)}") - with st.expander("Details"): - st.json(action.get("params", {})) - - run_col, clear_col = st.columns([1, 1]) - if clear_col.button("Clear", use_container_width=True): - st.session_state["assistant_plan_response"] = None - st.session_state["assistant_plan_status"] = None - _persist_session() - st.rerun() - - if run_col.button("Run plan", type="primary", use_container_width=True): - queued = 0 - failed = 0 - action_results: list[dict[str, Any]] = [] - for action in actions: - r = client.request( - "POST", - "/actions", - json={"kind": action["kind"], "params": action.get("params", {})}, - ) - action_results.append( - { - "kind": action["kind"], - "ok": r.ok, - "detail": r.error_message() if not r.ok else None, - } - ) - if r.ok: - queued += 1 - st.toast(f"Queued {action['kind']}", icon="➡️") - else: - failed += 1 - st.error(f"Failed to queue {action['kind']}: {r.error_message()}") - if failed == 0: - st.success(f"Plan queued · {queued} action(s)") - else: - st.warning(f"Plan partially queued · {queued} ok, {failed} failed") - executed = st.session_state.get("executed_plans") or [] - executed.append( - { - "request": response.get("request", ""), - "actions": actions, - "results": action_results, - "queued_at": datetime.now().isoformat(), - "status": "ok" - if failed == 0 - else ("partial" if queued > 0 else "failed"), - } - ) - st.session_state["executed_plans"] = executed - st.session_state["assistant_plan_response"] = None - st.session_state["assistant_plan_status"] = None - _persist_session() - st.rerun() - - -def _render_history() -> None: - st.markdown( - '
TWFarmBot · UAS Technikum Wien
', - unsafe_allow_html=True, - ) - st.markdown("# History") - - sessions = history.list_sessions(limit=50) - if not sessions: - st.info("No saved sessions yet. Chat and plans are saved automatically.") - return - - st.markdown("## Chat sessions") - for sess in sessions: - label = sess["label"] or sess["session_id"] - updated = ( - sess["updated_at"][:19].replace("T", " ") if sess["updated_at"] else "" - ) - c1, c2 = st.columns([4, 1]) - with c1: - st.markdown(f"**{label}**") - st.caption( - f"Updated {updated}" - + (f" · {sess['preview']}" if sess["preview"] else "") - ) - if c2.button( - "Load", key=f"hist_load_{sess['session_id']}", use_container_width=True - ): - snapshot = history.load_session(sess["session_id"]) - if snapshot is None: - st.error("Session not found") - else: - st.session_state["assistant_session_id"] = snapshot["session_id"] - st.session_state["assistant_session_label"] = snapshot.get("label") - st.session_state["assistant_messages"] = snapshot.get( - "assistant_messages", [] - ) - st.session_state["assistant_plan_request"] = snapshot.get( - "assistant_plan_request", "" - ) - st.session_state["assistant_plan_response"] = snapshot.get( - "assistant_plan_response" - ) - st.session_state["assistant_plan_status"] = snapshot.get( - "assistant_plan_status" - ) - st.session_state["assistant_selected_model"] = snapshot.get( - "assistant_selected_model" - ) - st.session_state["executed_plans"] = snapshot.get("executed_plans", []) - st.query_params["session"] = snapshot["session_id"] - st.rerun() - - executed = st.session_state.get("executed_plans") or [] - if executed: - st.markdown("## Executed plans") - for idx, plan in enumerate(reversed(executed), start=1): - with st.container(border=True): - queued_at = plan.get("queued_at", "") - ts = queued_at[:19].replace("T", " ") if queued_at else "" - status = plan.get("status", "unknown") - status_emoji = {"ok": "✅", "partial": "⚠️", "failed": "❌"}.get( - status, "❓" - ) - st.markdown( - f"{status_emoji} **Plan {idx}** · {plan.get('request', '')}" - ) - st.caption( - f"{ts} · {len(plan.get('actions', []))} action(s) · {status}" - ) - with st.expander("Actions"): - for action in plan.get("actions", []): - st.markdown(f"• {_action_summary(action)}") - results = plan.get("results", []) - if results: - with st.expander("Results"): - for res in results: - icon = "✅" if res.get("ok") else "❌" - detail = res.get("detail") - line = f"{icon} {_action_summary({'kind': res['kind'], 'params': {}})}" - if detail: - line += f" — {detail}" - st.markdown(line) - - -def _render_diagnostics() -> None: - st.markdown( - '
TWFarmBot · UAS Technikum Wien
', - unsafe_allow_html=True, - ) - st.markdown("# Diagnostics") - - if st.button("Load /status"): - d = client.request("GET", "/status") - if d.ok and isinstance(d.body, dict): - st.session_state["diag"] = d.body.get("state", {}) - else: - st.error(f"Read failed: {d.error_message()}") - - payload = st.session_state.get("diag", {}) or {} - info = payload.get("informational_settings", {}) or {} - loc = payload.get("location_data", {}) or {} - axes = loc.get("axis_states", {}) or {} - pins = payload.get("pins", {}) or {} - jobs = payload.get("jobs", {}) or {} - - if not info and not axes and not pins and not jobs: - st.info("Click 'Load /status' to fetch diagnostic state.") - return - - top = st.columns(4) - top[0].metric("Controller", info.get("controller_version", "—")) - top[1].metric("Firmware", info.get("firmware_version", "—")) - top[2].metric("Wi-Fi", f"{info.get('wifi_level_percent', '—')}%") - top[3].metric("Uptime", f"{info.get('uptime', '—')} s") - - res = st.columns(3) - with res[0]: - st.markdown( - f'
Resources
' - f'
CPU {info.get("cpu_usage", "—")}%
' - f"
Memory {info.get('memory_usage', '—')}% · Disk {info.get('disk_usage', '—')}%
" - f"
SoC {info.get('soc_temp', '—')} °C
", - unsafe_allow_html=True, - ) - with res[1]: - st.markdown( - f'
Axis state
' - f'
X {axes.get("x", "—")}
' - f"
Y {axes.get('y', '—')} · Z {axes.get('z', '—')}
" - f"
Busy: {info.get('busy', '—')}
", - unsafe_allow_html=True, - ) - with res[2]: - st.markdown( - f'
Network
' - f'
{info.get("wifi_level", "—")} dBm
' - f"
{info.get('private_ip', '—')}
" - f"
Sync: {info.get('sync_status', '—')}
", - unsafe_allow_html=True, - ) - - if pins: - st.markdown("**Pin snapshot**") - st.dataframe( - [ - {"pin": pn, "value": pd.get("value"), "mode": pd.get("mode")} - for pn, pd in pins.items() - ], - use_container_width=True, - hide_index=True, - ) - - -def _render_settings() -> None: - st.markdown( - '
TWFarmBot · UAS Technikum Wien
', - unsafe_allow_html=True, - ) - st.markdown("# Settings") - - st.markdown("**Connection**") - url = st.text_input("API URL", value=api_url) - if url != st.session_state["api_url"]: - st.session_state["api_url"] = url - st.cache_resource.clear() - st.rerun() - - st.markdown("**Auto-refresh intervals**") - pos_col, stats_col, cam_col = st.columns(3) - with pos_col: - pos_interval = st.number_input( - "Position refresh (s)", - min_value=1, - max_value=300, - value=int(st.session_state["refresh_position_s"]), - step=1, - ) - with stats_col: - stats_interval = st.number_input( - "Stats refresh (s)", - min_value=10, - max_value=3600, - value=int(st.session_state["refresh_stats_s"]), - step=10, - ) - with cam_col: - cam_interval = st.number_input( - "Camera refresh (s, 0 = off)", - min_value=0, - max_value=3600, - value=int(st.session_state.get("refresh_camera_s", 0)), - step=10, - ) - if ( - pos_interval != st.session_state["refresh_position_s"] - or stats_interval != st.session_state["refresh_stats_s"] - or cam_interval != st.session_state.get("refresh_camera_s", 0) - ): - st.session_state["refresh_position_s"] = int(pos_interval) - st.session_state["refresh_stats_s"] = int(stats_interval) - st.session_state["refresh_camera_s"] = int(cam_interval) - _persist_session() - st.rerun() - - if st.button("Health check"): - _refresh_health(client) - st.rerun() - - st.json( - { - "farmbot": st.session_state.get("farmbot_status", "?"), - "api": st.session_state["api_url"], - "actions": st.session_state.get("actions", []), - } - ) - - with st.expander("Raw action"): - with st.form("raw"): - kind = st.text_input("Kind", "move") - raw = st.text_area("Params (JSON)", '{"message":"hello"}', height=100) - if st.form_submit_button("Fire"): - try: - p = json.loads(raw) - except json.JSONDecodeError as e: - st.error(f"Bad JSON: {e}") - else: - r = client.request( - "POST", "/actions", json={"kind": kind, "params": p} - ) - st.json(r.body) - - -# ── dispatch ────────────────────────────────────────────────────────────────── - -renderers = { - "Overview": _render_overview, - "Garden": _render_garden, - "Motion": _render_motion, - "Camera": _render_camera, - "I/O": _render_io, - "Assistant": _render_assistant, - "History": _render_history, - "Diagnostics": _render_diagnostics, - "Settings": _render_settings, -} - -# Restore the latest or URL-specified chat/plan session on first load. -_restore_session() -renderers[tab]() diff --git a/apps/ui/src/twfarmbot_ui/client.py b/apps/ui/src/twfarmbot_ui/client.py index 31fbc99..341dc62 100644 --- a/apps/ui/src/twfarmbot_ui/client.py +++ b/apps/ui/src/twfarmbot_ui/client.py @@ -1,7 +1,9 @@ -"""API client used by the Streamlit app. +"""Python client for the twfarmbot api_server. -Kept separate from ``app.py`` so tests can import it without dragging in -Streamlit. +The web frontend talks to the API through the server-side proxy in +``server.py``; this client is kept for scripts and tests that need +programmatic access with the same semantics (``wait=false`` action +dispatch, SSE streaming). """ from __future__ import annotations diff --git a/apps/ui/src/twfarmbot_ui/history.py b/apps/ui/src/twfarmbot_ui/history.py index 82b4406..ee689c7 100644 --- a/apps/ui/src/twfarmbot_ui/history.py +++ b/apps/ui/src/twfarmbot_ui/history.py @@ -1,4 +1,4 @@ -"""Persistence for Streamlit UI session state. +"""Persistence for UI session state. Chat history, plan previews, and executed plans are saved as JSON files so they survive page reloads. Storage is local and intended for a single-user diff --git a/apps/ui/src/twfarmbot_ui/server.py b/apps/ui/src/twfarmbot_ui/server.py new file mode 100644 index 0000000..435d1b6 --- /dev/null +++ b/apps/ui/src/twfarmbot_ui/server.py @@ -0,0 +1,241 @@ +"""FastAPI server for the Material 3 web UI. + +Serves the static single-page frontend and reverse-proxies every API call: + +* ``/api/*`` → the twfarmbot api_server (``TWFB_API_URL``) +* ``/resireg/*`` → the ReSiReg vision server (``TWFB_RESIREG_URL``) +* ``/ui/*`` → small UI-local endpoints (session persistence and + garden-entity YAML writes) that used to live inside the + Streamlit process. + +Proxying keeps the frontend same-origin (no CORS on the api_server) and +keeps the upstream URLs server-side, exactly like the old Streamlit app. +""" + +from __future__ import annotations + +import os +import re +from contextlib import asynccontextmanager +from pathlib import Path +from typing import Any + +import httpx +from fastapi import FastAPI, HTTPException, Request +from fastapi.responses import FileResponse, StreamingResponse +from fastapi.staticfiles import StaticFiles +from pydantic import BaseModel, Field +from starlette.background import BackgroundTask + +from twfarmbot_ui import history + +STATIC_DIR = Path(__file__).parent / "static" + +# Hop-by-hop headers must not be forwarded by a proxy (RFC 9110 §7.6.1). +_HOP_BY_HOP = { + "connection", + "keep-alive", + "proxy-authenticate", + "proxy-authorization", + "te", + "trailers", + "transfer-encoding", + "upgrade", + "host", + "content-length", +} + +# Generous read timeout: /chat and /plan can block on the LLM for minutes. +_PROXY_TIMEOUT = httpx.Timeout(300.0, connect=5.0) + + +class GardenEntityPayload(BaseModel): + x: float + y: float + kind: str = Field(..., min_length=1) + name: str = Field(..., min_length=1) + + +class ConfigPayload(BaseModel): + api_url: str | None = None + resireg_url: str | None = None + + +def _entity_id(name: str) -> str: + base = re.sub(r"[^a-z0-9_]+", "_", name.lower()).strip("_") + return base or "entity" + + +def add_garden_entity(x: float, y: float, kind: str, name: str) -> dict[str, Any]: + """Append a new entity to the ``TWFB_CONFIG`` YAML, preserving comments.""" + from ruamel.yaml import YAML + + yaml = YAML() + yaml.preserve_quotes = True + yaml.default_flow_style = False + path = Path(os.getenv("TWFB_CONFIG", "configs/dev.yaml")) + with path.open(encoding="utf-8") as fh: + data = yaml.load(fh) + spatial = data.setdefault("spatial", {}) + entities = spatial.setdefault("entities", []) + entity = { + "id": _entity_id(name), + "kind": kind, + "name": name, + "x": float(x), + "y": float(y), + "z": 0.0, + "radius_mm": 50, + "metadata": {}, + } + entities.append(entity) + with path.open("w", encoding="utf-8") as fh: + yaml.dump(data, fh) + return entity + + +def create_app(http_client: httpx.AsyncClient | None = None) -> FastAPI: + @asynccontextmanager + async def lifespan(application: FastAPI): + yield + await application.state.http.aclose() + + app = FastAPI(title="TWFarmBot UI", version="0.2.0", lifespan=lifespan) + app.state.api_base = os.getenv("TWFB_API_URL", "http://127.0.0.1:8000").rstrip("/") + app.state.resireg_base = os.getenv( + "TWFB_RESIREG_URL", "http://127.0.0.1:8080" + ).rstrip("/") + app.state.http = http_client or httpx.AsyncClient(timeout=_PROXY_TIMEOUT) + + async def _proxy(request: Request, base: str, path: str) -> StreamingResponse: + client: httpx.AsyncClient = app.state.http + headers = { + k: v for k, v in request.headers.items() if k.lower() not in _HOP_BY_HOP + } + upstream = client.build_request( + request.method, + f"{base}/{path}", + params=request.query_params, + headers=headers, + content=await request.body(), + ) + try: + resp = await client.send(upstream, stream=True) + except httpx.HTTPError as err: + raise HTTPException( + status_code=502, detail=f"{type(err).__name__}: {err}" + ) from err + return StreamingResponse( + resp.aiter_raw(), + status_code=resp.status_code, + headers={ + k: v + for k, v in resp.headers.items() + if k.lower() not in _HOP_BY_HOP and k.lower() != "content-encoding" + }, + background=BackgroundTask(resp.aclose), + ) + + @app.api_route( + "/api/{path:path}", methods=["GET", "POST", "PUT", "PATCH", "DELETE"] + ) + async def api_proxy(request: Request, path: str) -> StreamingResponse: + return await _proxy(request, app.state.api_base, path) + + @app.api_route("/resireg/{path:path}", methods=["GET", "POST"]) + async def resireg_proxy(request: Request, path: str) -> StreamingResponse: + return await _proxy(request, app.state.resireg_base, path) + + # ---- UI-local endpoints --------------------------------------------- + + @app.get("/ui/config") + def get_config() -> dict[str, Any]: + return { + "api_url": app.state.api_base, + "resireg_url": app.state.resireg_base, + } + + @app.put("/ui/config") + def put_config(payload: ConfigPayload) -> dict[str, Any]: + if payload.api_url: + app.state.api_base = payload.api_url.rstrip("/") + if payload.resireg_url: + app.state.resireg_base = payload.resireg_url.rstrip("/") + return get_config() + + @app.get("/ui/sessions") + def list_sessions() -> dict[str, Any]: + return {"sessions": history.list_sessions()} + + @app.post("/ui/sessions") + def new_session() -> dict[str, Any]: + return history.empty_snapshot() + + @app.get("/ui/sessions/{session_id}") + def get_session(session_id: str) -> dict[str, Any]: + snapshot = history.load_session(session_id) + if snapshot is None: + raise HTTPException(status_code=404, detail=f"no session: {session_id}") + return snapshot + + @app.put("/ui/sessions/{session_id}") + async def put_session(session_id: str, request: Request) -> dict[str, Any]: + snapshot = await request.json() + if not isinstance(snapshot, dict): + raise HTTPException(status_code=400, detail="snapshot must be an object") + snapshot["session_id"] = session_id + history.save_session(snapshot) + return {"status": "ok", "session_id": session_id} + + @app.delete("/ui/sessions/{session_id}") + def delete_session(session_id: str) -> dict[str, Any]: + return {"deleted": history.delete_session(session_id)} + + @app.post("/ui/garden/entities") + def post_garden_entity(payload: GardenEntityPayload) -> dict[str, Any]: + try: + entity = add_garden_entity(payload.x, payload.y, payload.kind, payload.name) + except (OSError, KeyError, TypeError) as err: + raise HTTPException( + status_code=500, detail=f"config write failed: {err}" + ) from err + return {"status": "ok", "entity": entity} + + # ---- Static frontend ------------------------------------------------- + + @app.get("/", include_in_schema=False) + def index() -> FileResponse: + return FileResponse( + STATIC_DIR / "index.html", + headers={"Cache-Control": "no-cache"}, + ) + + @app.middleware("http") + async def cache_static_assets(request: Request, call_next): + response = await call_next(request) + path = request.url.path + if path == "/app.css" or path.startswith("/js/") or path.startswith("/vendor/"): + # /vendor/ files are SHA256-pinned, so a long cache is safe. + response.headers["Cache-Control"] = "public, max-age=3600" + return response + + app.mount("/", StaticFiles(directory=STATIC_DIR), name="static") + + return app + + +app = create_app() + + +def main() -> None: + from twfarmbot_core.logging import configure_logging + + configure_logging() + import uvicorn + + port = int(os.getenv("TWFB_UI_PORT", "8501")) + uvicorn.run("twfarmbot_ui.server:app", host="0.0.0.0", port=port, reload=False) + + +if __name__ == "__main__": + main() diff --git a/apps/ui/src/twfarmbot_ui/static/app.css b/apps/ui/src/twfarmbot_ui/static/app.css new file mode 100644 index 0000000..940687c --- /dev/null +++ b/apps/ui/src/twfarmbot_ui/static/app.css @@ -0,0 +1,837 @@ +/* ── Design tokens (8px grid) ─────────────────────────────────────────── */ + +:root { + --space-1: 4px; + --space-2: 8px; + --space-3: 12px; + --space-4: 16px; + --space-5: 20px; + --space-6: 24px; + --space-8: 32px; + --space-10: 40px; + --space-12: 48px; + --space-16: 64px; + --radius-sm: 8px; + --radius-md: 12px; + --radius-lg: 16px; + --radius-xl: 28px; + --radius-full: 999px; + --sidebar-w: 96px; + --content-max: 1200px; + --topbar-h: 80px; + --chat-bar-h: 92px; + + /* Material 3 expressive palette — indigo, azure, and coral */ + --md-sys-color-primary: #554fd8; + --md-sys-color-on-primary: #ffffff; + --md-sys-color-primary-container: #e4dfff; + --md-sys-color-on-primary-container: #171064; + --md-sys-color-secondary: #42618a; + --md-sys-color-on-secondary: #ffffff; + --md-sys-color-secondary-container: #d8e6ff; + --md-sys-color-on-secondary-container: #0b1b33; + --md-sys-color-tertiary: #a23f5c; + --md-sys-color-on-tertiary: #ffffff; + --md-sys-color-tertiary-container: #ffd9e1; + --md-sys-color-on-tertiary-container: #3f0019; + --md-sys-color-error: #ba1a1a; + --md-sys-color-on-error: #ffffff; + --md-sys-color-error-container: #ffdad6; + --md-sys-color-on-error-container: #410002; + --md-sys-color-background: #fbf8ff; + --md-sys-color-on-background: #1b1b22; + --md-sys-color-surface: #fbf8ff; + --md-sys-color-on-surface: #1b1b22; + --md-sys-color-surface-variant: #e4e1ec; + --md-sys-color-on-surface-variant: #47464f; + --md-sys-color-outline: #787680; + --md-sys-color-outline-variant: #c9c5d0; + --md-sys-color-surface-container-lowest: #ffffff; + --md-sys-color-surface-container-low: #f5f2fa; + --md-sys-color-surface-container: #efecf4; + --md-sys-color-surface-container-high: #e9e6ee; + --md-sys-color-surface-container-highest: #e3e0e8; + --md-sys-color-inverse-surface: #303038; + --md-sys-color-inverse-on-surface: #f2eff7; + --md-ref-typeface-plain: "Roboto Flex", system-ui, sans-serif; + --md-ref-typeface-brand: "Roboto Flex", system-ui, sans-serif; + --ok-bg: #d1fae5; --ok-fg: #065f46; + --warn-bg: #fef3c7; --warn-fg: #92400e; + --bad-bg: #fee2e2; --bad-fg: #991b1b; + --md-elevation-1: 0 1px 2px rgba(0, 0, 0, 0.10), 0 1px 3px 1px rgba(0, 0, 0, 0.05); + --md-elevation-2: 0 1px 2px rgba(0, 0, 0, 0.14), 0 2px 6px 2px rgba(0, 0, 0, 0.06); + --md-state-hover: color-mix(in srgb, var(--md-sys-color-on-surface) 8%, transparent); + --md-state-focus: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent); + color-scheme: light; +} + +@media (prefers-color-scheme: dark) { + :root { + --md-sys-color-primary: #c5c0ff; + --md-sys-color-on-primary: #262080; + --md-sys-color-primary-container: #3d37a9; + --md-sys-color-on-primary-container: #e4dfff; + --md-sys-color-secondary: #a9c8f5; + --md-sys-color-on-secondary: #113253; + --md-sys-color-secondary-container: #29496f; + --md-sys-color-on-secondary-container: #d8e6ff; + --md-sys-color-tertiary: #ffb1c2; + --md-sys-color-on-tertiary: #62002e; + --md-sys-color-tertiary-container: #822344; + --md-sys-color-on-tertiary-container: #ffd9e1; + --md-sys-color-error: #ffb4ab; + --md-sys-color-on-error: #690005; + --md-sys-color-error-container: #93000a; + --md-sys-color-on-error-container: #ffdad6; + --md-sys-color-background: #131318; + --md-sys-color-on-background: #e5e1e9; + --md-sys-color-surface: #131318; + --md-sys-color-on-surface: #e5e1e9; + --md-sys-color-surface-variant: #47464f; + --md-sys-color-on-surface-variant: #c9c5d0; + --md-sys-color-outline: #928f99; + --md-sys-color-outline-variant: #47464f; + --md-sys-color-surface-container-lowest: #0e0e13; + --md-sys-color-surface-container-low: #1b1b20; + --md-sys-color-surface-container: #1f1f24; + --md-sys-color-surface-container-high: #29292e; + --md-sys-color-surface-container-highest: #343339; + --md-sys-color-inverse-surface: #e5e1e9; + --md-sys-color-inverse-on-surface: #303038; + --ok-bg: #064e3b; --ok-fg: #a7f3d0; + --warn-bg: #78350f; --warn-fg: #fde68a; + --bad-bg: #7f1d1d; --bad-fg: #fecaca; + color-scheme: dark; + } +} + +/* ── Reset & shell ────────────────────────────────────────────────────── */ + +*, *::before, *::after { box-sizing: border-box; } + +body { + margin: 0; + font-family: var(--md-ref-typeface-plain); + font-size: 14px; + line-height: 1.5; + background: + radial-gradient(circle at top left, color-mix(in srgb, var(--md-sys-color-primary-container) 46%, transparent) 0, transparent 360px), + var(--md-sys-color-background); + color: var(--md-sys-color-on-background); + -webkit-font-smoothing: antialiased; +} + +#sidebar { + position: fixed; + inset: 0 auto 0 0; + width: var(--sidebar-w); + display: flex; + flex-direction: column; + align-items: center; + gap: var(--space-4); + padding: var(--space-4) var(--space-2); + background: var(--md-sys-color-surface-container); + border-right: 1px solid color-mix(in srgb, var(--md-sys-color-outline-variant) 70%, transparent); + overflow-y: auto; +} + +#top-app-bar { + position: fixed; + inset: 0 0 auto var(--sidebar-w); + height: var(--topbar-h); + z-index: 30; + display: flex; + align-items: center; + justify-content: space-between; + gap: var(--space-4); + padding: 0 var(--space-8); + background: color-mix(in srgb, var(--md-sys-color-surface-container-low) 94%, transparent); + border-bottom: 1px solid color-mix(in srgb, var(--md-sys-color-outline-variant) 70%, transparent); + backdrop-filter: blur(16px); +} +.top-app-bar-title { margin: 0; font-size: 22px; font-weight: 500; letter-spacing: 0; } +.top-app-bar-subtitle { margin: 2px 0 0; font-size: 12px; color: var(--md-sys-color-on-surface-variant); } +.top-app-bar-actions { display: flex; align-items: center; justify-content: flex-end; gap: var(--space-3); min-width: 0; } + +#content { + margin-left: var(--sidebar-w); + min-height: 100vh; + padding-top: var(--topbar-h); +} + +body.has-chat-bar #content { padding-bottom: var(--chat-bar-h); } + +/* ── Navigation rail ─────────────────────────────────────────────────── */ + +.brand { + display: flex; + flex-direction: column; + align-items: center; + gap: var(--space-1); + width: 100%; + min-height: 64px; +} +.brand-mark { + width: 48px; + height: 48px; + display: grid; + place-items: center; + border-radius: var(--radius-lg); + background: var(--md-sys-color-primary-container); + color: var(--md-sys-color-on-primary-container); + font-family: "Material Symbols Outlined"; + font-size: 28px; + font-variation-settings: "FILL" 1, "wght" 500, "GRAD" 0, "opsz" 24; +} +.brand-wordmark { + max-width: 80px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + font-size: 11px; + font-weight: 600; + color: var(--md-sys-color-on-surface-variant); +} + +.nav-label { display: none; } + +#nav { + display: flex; + flex-direction: column; + align-items: stretch; + gap: var(--space-2); + width: 100%; + flex: 1; + min-height: 0; +} + +.nav-item { + position: relative; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: var(--space-1); + min-height: 64px; + padding: var(--space-1) 0; + border-radius: var(--radius-xl); + cursor: pointer; + color: var(--md-sys-color-on-surface-variant); + font-size: 11px; + font-weight: 500; + line-height: 1.15; + text-align: center; + user-select: none; + transition: background 0.12s, color 0.12s; +} +.nav-item::before { + content: ""; + position: absolute; + top: 7px; + width: 56px; + height: 32px; + border-radius: var(--radius-full); + transition: background 0.12s; +} +.nav-item:hover::before { background: var(--md-state-hover); } +.nav-item.active { color: var(--md-sys-color-on-secondary-container); font-weight: 600; } +.nav-item.active::before { background: var(--md-sys-color-secondary-container); } +.nav-item md-icon { + --md-icon-size: 24px; + z-index: 1; + font-variation-settings: "FILL" 0, "wght" 400, "GRAD" 0, "opsz" 24; +} +.nav-item.active md-icon { font-variation-settings: "FILL" 1, "wght" 500, "GRAD" 0, "opsz" 24; } + +#status-block { + min-width: 320px; + display: flex; + align-items: center; + gap: var(--space-3); + padding: var(--space-2) var(--space-3); + background: var(--md-sys-color-surface-container-high); + border-radius: var(--radius-full); +} + +.live-pos { + font-size: 12px; + font-variant-numeric: tabular-nums; + color: var(--md-sys-color-on-surface); + line-height: 1.25; +} +.pos-age { + font-size: 11px; + color: var(--md-sys-color-on-surface-variant); + line-height: 1.25; +} + +.estop { + --md-filled-button-container-color: var(--md-sys-color-error); + --md-filled-button-label-text-color: var(--md-sys-color-on-error); + --md-filled-button-hover-label-text-color: var(--md-sys-color-on-error); + --md-filled-button-focus-label-text-color: var(--md-sys-color-on-error); + --md-filled-button-pressed-label-text-color: var(--md-sys-color-on-error); + --md-filled-button-icon-color: var(--md-sys-color-on-error); + --md-filled-button-hover-icon-color: var(--md-sys-color-on-error); +} + +/* ── Page layout ────────────────────────────────────────────────────── */ + +.page { + max-width: var(--content-max); + margin: 0 auto; + padding: var(--space-8) var(--space-8) var(--space-10); +} + +.page-header { margin-bottom: var(--space-6); } + +.eyebrow { + font-size: 10px; + font-weight: 700; + letter-spacing: 0.1em; + text-transform: uppercase; + color: var(--md-sys-color-tertiary); + margin: 0 0 var(--space-1); +} + +.page-title-row { + display: flex; + align-items: center; + justify-content: space-between; + gap: var(--space-3); + flex-wrap: wrap; +} + +.page-title { + font-size: 32px; + font-weight: 500; + letter-spacing: -0.02em; + margin: 0; + line-height: 1.25; +} + +.page-actions { + display: flex; + align-items: center; + gap: var(--space-2); + flex-wrap: wrap; +} + +.page-body { + display: flex; + flex-direction: column; + gap: var(--space-4); + align-items: stretch; +} + +.section { display: flex; flex-direction: column; gap: var(--space-3); } + +.section-title { + font-size: 14px; + font-weight: 600; + margin: 0; + color: var(--md-sys-color-on-surface); +} + +/* ── Cards & surfaces ───────────────────────────────────────────────── */ + +.card { + background: var(--md-sys-color-surface-container-low); + border: 1px solid color-mix(in srgb, var(--md-sys-color-outline-variant) 70%, transparent); + border-radius: var(--radius-xl); + box-shadow: var(--md-elevation-1); + overflow: hidden; +} + +.card-header { + padding: var(--space-3) var(--space-4); + border-bottom: 1px solid color-mix(in srgb, var(--md-sys-color-outline-variant) 70%, transparent); + background: transparent; +} + +.card-title { + font-size: 16px; + font-weight: 500; + margin: 0; +} + +.card-body { + padding: var(--space-4); + display: flex; + flex-direction: column; + gap: var(--space-3); +} + +/* ── Metrics ────────────────────────────────────────────────────────── */ + +.metric-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); + gap: var(--space-3); +} + +.metric { + background: var(--md-sys-color-surface-container); + border: 0; + border-radius: var(--radius-lg); + padding: var(--space-3); + min-width: 0; +} + +.metric-label { + font-size: 11px; + font-weight: 600; + letter-spacing: 0.06em; + text-transform: uppercase; + color: var(--md-sys-color-on-surface-variant); +} + +.metric-value { + font-size: 20px; + font-weight: 600; + margin-top: 2px; + font-variant-numeric: tabular-nums; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + line-height: 1.2; +} + +/* ── Utilities ──────────────────────────────────────────────────────── */ + +.pill { + display: inline-flex; + align-items: center; + gap: var(--space-1); + padding: var(--space-1) var(--space-3); + border-radius: var(--radius-full); + font-size: 12px; + font-weight: 600; + background: var(--md-sys-color-surface-container-high); + color: var(--md-sys-color-on-surface-variant); +} +.pill.ok { background: var(--ok-bg); color: var(--ok-fg); } +.pill.warn { background: var(--warn-bg); color: var(--warn-fg); } +.pill.bad { background: var(--bad-bg); color: var(--bad-fg); } + +.toolbar { + display: flex; + align-items: center; + gap: var(--space-2); + flex-wrap: wrap; +} + +.stack { + display: flex; + flex-direction: column; + gap: var(--space-3); + align-items: stretch; +} + +.split { + display: grid; + grid-template-columns: var(--split-ratio, 2fr 1fr); + gap: var(--space-4); + align-items: start; +} + +.card-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); + gap: var(--space-4); +} + +.caption { + font-size: 12px; + line-height: 1.45; + color: var(--md-sys-color-on-surface-variant); + margin: 0; +} + +.mono { font-family: "Roboto Mono", monospace; font-size: 12px; } + +.empty-state { + display: flex; + flex-direction: column; + align-items: center; + gap: var(--space-2); + padding: var(--space-6) var(--space-4); + text-align: center; + color: var(--md-sys-color-on-surface-variant); +} +.empty-state md-icon { --md-icon-size: 28px; opacity: 0.45; } +.empty-state p { margin: 0; max-width: 360px; font-size: 13px; } + +/* Top-aligned empty placeholder — no vertical centering in a huge void */ +.empty-panel { + display: flex; + align-items: center; + gap: var(--space-3); + width: 100%; + max-width: 520px; + padding: var(--space-3) var(--space-4); + background: var(--md-sys-color-surface-container-low); + border: 1px dashed var(--md-sys-color-outline-variant); + border-radius: var(--radius-md); + color: var(--md-sys-color-on-surface-variant); +} +.empty-panel md-icon { --md-icon-size: 22px; opacity: 0.5; flex-shrink: 0; } +.empty-panel p { margin: 0; font-size: 13px; line-height: 1.4; } + +/* ── Data display ───────────────────────────────────────────────────── */ + +pre.codeblock { + margin: 0; + background: var(--md-sys-color-surface-container); + border-radius: var(--radius-sm); + padding: var(--space-4); + font-family: "Roboto Mono", monospace; + font-size: 12px; + line-height: 1.5; + overflow-x: auto; + white-space: pre-wrap; + word-break: break-word; +} + +.data-table { + width: 100%; + border-collapse: collapse; + font-size: 13px; +} +.data-table th, +.data-table td { + text-align: left; + padding: var(--space-3) var(--space-4); + border-bottom: 1px solid var(--md-sys-color-outline-variant); +} +.data-table th { + font-size: 11px; + font-weight: 600; + letter-spacing: 0.05em; + text-transform: uppercase; + color: var(--md-sys-color-on-surface-variant); + background: var(--md-sys-color-surface-container-low); +} +.data-table tr:last-child td { border-bottom: none; } + +details.expander { + border: 1px solid var(--md-sys-color-outline-variant); + border-radius: var(--radius-md); + background: var(--md-sys-color-surface-container-lowest); + overflow: hidden; +} +details.expander summary { + cursor: pointer; + font-size: 14px; + font-weight: 500; + padding: var(--space-3) var(--space-4); + list-style: none; +} +details.expander summary::-webkit-details-marker { display: none; } +details.expander[open] summary { + border-bottom: 1px solid color-mix(in srgb, var(--md-sys-color-outline-variant) 70%, transparent); + background: transparent; +} +.expander-body { padding: var(--space-4); } + +.chart-box { position: relative; height: 220px; } +.chart-box.tall { height: 260px; } + +/* ── Form controls (dense) ──────────────────────────────────────────── */ + +md-filled-button, +md-outlined-button, +md-filled-tonal-button, +md-text-button { + --md-filled-button-container-height: 36px; + --md-outlined-button-container-height: 36px; + --md-filled-tonal-button-container-height: 36px; +} + +md-outlined-text-field, +md-outlined-select { + --md-outlined-field-container-shape: var(--radius-sm); + --md-outlined-text-field-container-shape: var(--radius-sm); + min-width: 0; +} + +md-outlined-text-field.grow, +md-outlined-select.grow { flex: 1; } + +.field-sm { width: 120px; flex-shrink: 0; } +.field-lg { min-width: 280px; flex: 1; } + +.chip-row { + display: flex; + gap: var(--space-2); + flex-wrap: wrap; +} + +.form-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); + gap: var(--space-4); + align-items: end; +} + +/* ── Garden map ─────────────────────────────────────────────────────── */ + +svg.garden-map { + width: 100%; + aspect-ratio: 16 / 10; + max-height: 520px; + background: var(--md-sys-color-surface-container-low); + border: 1px solid color-mix(in srgb, var(--md-sys-color-outline-variant) 70%, transparent); + border-radius: var(--radius-xl); + box-shadow: var(--md-elevation-1); + cursor: crosshair; +} + +.garden-legend { + display: flex; + gap: var(--space-4); + flex-wrap: wrap; + font-size: 12px; + margin-top: var(--space-2); +} +.garden-legend .swatch { + display: inline-block; + width: 10px; + height: 10px; + border-radius: 3px; + margin-right: var(--space-2); + vertical-align: middle; +} + +/* ── Motion D-pad ───────────────────────────────────────────────────── */ + +.jog-area { + display: flex; + align-items: center; + gap: var(--space-6); +} + +.dpad { + display: grid; + grid-template-columns: repeat(3, 48px); + grid-auto-rows: 48px; + gap: var(--space-2); + place-items: center; + width: fit-content; +} + +.z-col { + display: flex; + flex-direction: column; + align-items: center; + gap: var(--space-2); +} +.z-label { + font-size: 11px; + font-weight: 700; + letter-spacing: 0.08em; + color: var(--md-sys-color-on-surface-variant); +} + +/* Restrained M3 Expressive motion: circular controls become softly squared + while pressed, making state change tactile without distracting animation. */ +.dpad md-filled-icon-button, +.dpad md-filled-tonal-icon-button, +.z-col md-filled-tonal-icon-button { + transition: border-radius 160ms cubic-bezier(0.2, 0, 0, 1), + transform 160ms cubic-bezier(0.2, 0, 0, 1); +} +.dpad md-filled-icon-button:active, +.dpad md-filled-tonal-icon-button:active, +.z-col md-filled-tonal-icon-button:active { + border-radius: var(--radius-md); + transform: scale(0.94); +} + +/* ── Camera ─────────────────────────────────────────────────────────── */ + +img.frame { + width: 100%; + max-height: 60vh; + object-fit: contain; + border-radius: var(--radius-md); + background: var(--md-sys-color-surface-container); + border: 1px solid var(--md-sys-color-outline-variant); +} + +.gallery { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); + gap: var(--space-3); +} +.gallery img { + width: 100%; + aspect-ratio: 4 / 3; + object-fit: cover; + border-radius: var(--radius-sm); + border: 1px solid var(--md-sys-color-outline-variant); +} +.gallery figcaption { margin-top: var(--space-1); } + +/* ── Assistant chat ─────────────────────────────────────────────────── */ + +.chat-panel { + display: flex; + flex-direction: column; + gap: var(--space-4); +} + +.chat-scroll { + display: flex; + flex-direction: column; + gap: var(--space-4); + min-height: 200px; +} + +.msg { + display: flex; + gap: var(--space-3); + max-width: 720px; +} +.msg .avatar { + --md-icon-size: 20px; + flex-shrink: 0; + width: 32px; + height: 32px; + display: flex; + align-items: center; + justify-content: center; + border-radius: var(--radius-full); + background: var(--md-sys-color-surface-container-high); + color: var(--md-sys-color-on-surface-variant); +} +.msg .bubble { min-width: 0; flex: 1; } +.msg.user { flex-direction: row-reverse; margin-left: auto; } +.msg.user .avatar { background: var(--md-sys-color-primary-container); color: var(--md-sys-color-on-primary-container); } +.msg.user .bubble { + background: var(--md-sys-color-primary-container); + color: var(--md-sys-color-on-primary-container); + border-radius: var(--radius-lg) var(--radius-lg) var(--radius-sm) var(--radius-lg); + padding: var(--space-3) var(--space-4); + flex: 0 1 auto; + max-width: 85%; +} +.msg .bubble > div > p { margin: 0 0 var(--space-2); } +.msg .bubble > div > p:last-child { margin-bottom: 0; } +.streaming-text { white-space: pre-wrap; } +.msg .bubble img { max-width: 100%; max-height: 50vh; border-radius: var(--radius-sm); } +.chat-images { display: flex; gap: var(--space-2); flex-wrap: wrap; margin-top: var(--space-2); } +.chat-images img { width: 200px; border-radius: var(--radius-sm); } + +.proposal-card { + background: var(--md-sys-color-surface-container); + border: 0; + border-radius: var(--radius-lg); + padding: var(--space-4); + margin-top: var(--space-3); +} + +.model-picker { + display: grid; + grid-template-columns: 160px 1fr; + gap: var(--space-4); + align-items: end; +} + +.chat-input-bar { + position: fixed; + left: var(--sidebar-w); + right: 0; + bottom: 0; + z-index: 50; + background: var(--md-sys-color-surface-container-lowest); + border-top: 1px solid var(--md-sys-color-outline-variant); + box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.06); +} + +.chat-input-inner { + max-width: calc(var(--content-max) + var(--space-16)); + margin: 0 auto; + padding: var(--space-3) var(--space-8); + display: flex; + flex-direction: column; + gap: var(--space-2); +} + +.assistant-metrics { + font-size: 11px; + color: var(--md-sys-color-on-surface-variant); + text-align: center; +} + +.chat-input-row { + display: flex; + gap: var(--space-3); + align-items: center; +} +.chat-input-row md-outlined-text-field { flex: 1; } + +.session-list-item { + display: flex; + align-items: center; + gap: var(--space-3); + padding: var(--space-2) 0; + border-bottom: 1px solid var(--md-sys-color-outline-variant); +} +.session-list-item:last-child { border-bottom: none; } +.session-list-item .caption { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } + +/* ── Snackbar ───────────────────────────────────────────────────────── */ + +#snackbar-host { + position: fixed; + bottom: var(--space-6); + left: 50%; + transform: translateX(-50%); + display: flex; + flex-direction: column; + gap: var(--space-2); + z-index: 1000; + pointer-events: none; +} +.snackbar { + background: var(--md-sys-color-inverse-surface); + color: var(--md-sys-color-inverse-on-surface); + border-radius: var(--radius-sm); + padding: var(--space-3) var(--space-5); + font-size: 14px; + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2); + animation: snack-in 0.18s ease-out; + pointer-events: auto; +} +.snackbar.error { background: var(--md-sys-color-error); color: var(--md-sys-color-on-error); } +@keyframes snack-in { from { opacity: 0; transform: translateY(8px); } } + +/* ── Responsive ───────────────────────────────────────────────────────── */ + +@media (max-width: 900px) { + :root { --sidebar-w: 80px; } + #top-app-bar { padding: 0 var(--space-4); } + #status-block { min-width: 0; } + .top-app-bar-subtitle { display: none; } + .page { padding: var(--space-5) var(--space-4) var(--space-6); } + .split { grid-template-columns: 1fr; } + .model-picker { grid-template-columns: 1fr; } + .chat-input-inner { padding: var(--space-3) var(--space-4); } +} + +@media (max-width: 640px) { + :root { --sidebar-w: 0px; } + #sidebar { transform: translateX(-100%); } + #status-block { display: none; } + #top-app-bar { left: 0; } + #content { margin-left: 0; } + .chat-input-bar { left: 0; } +} + +/* Manually collapsed navigation rail — mirrors the mobile layout at any width. */ +body.sidebar-collapsed { --sidebar-w: 0px; } +body.sidebar-collapsed #sidebar { transform: translateX(-100%); } +body.sidebar-collapsed #top-app-bar { left: 0; } +body.sidebar-collapsed #content { margin-left: 0; } +body.sidebar-collapsed .chat-input-bar { left: 0; } diff --git a/apps/ui/src/twfarmbot_ui/static/index.html b/apps/ui/src/twfarmbot_ui/static/index.html new file mode 100644 index 0000000..cd2f4b2 --- /dev/null +++ b/apps/ui/src/twfarmbot_ui/static/index.html @@ -0,0 +1,62 @@ + + + + + + TWFarmBot Research + + + + + + + + + + + +
+
+

FarmBot console

+

Material 3 research controls · live hardware state

+
+
+ + left_panel_close + +
+ ● unknown +
+
X — · Y — · Z —
+
+
+
+ + refresh + Refresh + + + emergency + ESTOP + +
+
+
+
+ + diff --git a/apps/ui/src/twfarmbot_ui/static/js/api.js b/apps/ui/src/twfarmbot_ui/static/js/api.js new file mode 100644 index 0000000..64a55bc --- /dev/null +++ b/apps/ui/src/twfarmbot_ui/static/js/api.js @@ -0,0 +1,90 @@ +// Thin fetch wrapper mirroring the old Python ApiClient semantics: +// results are {ok, code, body}, POST /actions defaults to wait=false, +// and /chat/stream is consumed as Server-Sent Events. + +async function parseBody(resp) { + const text = await resp.text(); + try { return JSON.parse(text); } catch { return text; } +} + +export function errorMessage(result) { + const body = result.body; + if (body && typeof body === "object") { + if (body.detail !== undefined) return String(body.detail); + if (body.error !== undefined) return String(body.error); + } + if (typeof body === "string") return body; + return JSON.stringify(body); +} + +export async function request(url, { method = "GET", json, params, timeoutMs = 10000 } = {}) { + const qs = params ? `?${new URLSearchParams(params)}` : ""; + const opts = { method, signal: AbortSignal.timeout(timeoutMs) }; + if (json !== undefined) { + opts.headers = { "Content-Type": "application/json" }; + opts.body = JSON.stringify(json); + } + try { + const resp = await fetch(`${url}${qs}`, opts); + return { ok: resp.ok, code: resp.status, body: await parseBody(resp) }; + } catch (err) { + return { ok: false, code: 0, body: { error: `${err.name}: ${err.message}` } }; + } +} + +export const api = (path, opts) => request(`/api${path}`, opts); +export const resireg = (path, opts) => request(`/resireg${path}`, { timeoutMs: 120000, ...opts }); +export const ui = (path, opts) => request(`/ui${path}`, opts); + +// The FarmBot executes actions on a single worker queue; like the old UI we +// dispatch fire-and-forget by default and only wait for approved proposals. +export function postAction(kind, params = {}, { wait = false } = {}) { + return api("/actions", { + method: "POST", + json: { kind, params }, + params: { wait: String(wait) }, + timeoutMs: wait ? 120000 : 10000, + }); +} + +// POST-based SSE stream; yields parsed `data:` payloads. +export async function* sse(path, json, { timeoutMs = 90000 } = {}) { + const resp = await fetch(`/api${path}`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(json), + signal: AbortSignal.timeout(timeoutMs), + }); + if (!resp.ok) throw new Error(`HTTP ${resp.status}: ${errorMessage({ body: await parseBody(resp) })}`); + const reader = resp.body.getReader(); + const decoder = new TextDecoder(); + let buffer = ""; + for (;;) { + const { done, value } = await reader.read(); + if (done) break; + buffer += decoder.decode(value, { stream: true }); + const events = buffer.split("\n\n"); + buffer = events.pop(); + for (const chunk of events) { + for (const line of chunk.split("\n")) { + if (line.startsWith("data: ")) yield JSON.parse(line.slice(6)); + } + } + } +} + +// ── Local UI settings (auto-refresh intervals etc.) ───────────────────── + +const SETTINGS_KEY = "twfb_ui_settings"; +const DEFAULTS = { refreshPositionS: 5, refreshStatsS: 300, refreshCameraS: 0 }; + +export function getSettings() { + try { return { ...DEFAULTS, ...JSON.parse(localStorage.getItem(SETTINGS_KEY) || "{}") }; } + catch { return { ...DEFAULTS }; } +} + +export function saveSettings(patch) { + const next = { ...getSettings(), ...patch }; + localStorage.setItem(SETTINGS_KEY, JSON.stringify(next)); + return next; +} diff --git a/apps/ui/src/twfarmbot_ui/static/js/main.js b/apps/ui/src/twfarmbot_ui/static/js/main.js new file mode 100644 index 0000000..4fae961 --- /dev/null +++ b/apps/ui/src/twfarmbot_ui/static/js/main.js @@ -0,0 +1,138 @@ +import "./material.js"; +import { styles as typescaleStyles } from "@material/web/typography/md-typescale-styles.js"; + +import { postAction, errorMessage } from "./api.js"; +import { h, icon, snack, timeAgo, num } from "./ui.js"; +import * as state from "./state.js"; + +document.adoptedStyleSheets.push(typescaleStyles.styleSheet); + +const TABS = [ + { key: "overview", label: "Overview", icon: "monitoring" }, + { key: "garden", label: "Garden", icon: "psychiatry" }, + { key: "motion", label: "Motion", icon: "open_with" }, + { key: "camera", label: "Camera", icon: "photo_camera" }, + { key: "io", label: "I/O", icon: "settings_input_component" }, + { key: "assistant", label: "Assistant", icon: "smart_toy" }, + { key: "history", label: "History", icon: "history" }, + { key: "diagnostics", label: "Diagnostics", icon: "troubleshoot" }, + { key: "settings", label: "Settings", icon: "settings" }, +]; + +// Legacy routes from the old Sensors / Operations tabs now live under I/O. +const LEGACY_TABS = { sensors: "io", operations: "io", "i/o": "io" }; + +let activeTab = null; +let teardown = null; + +function tabFromUrl() { + const raw = (new URLSearchParams(location.search).get("tab") || "").toLowerCase(); + const key = LEGACY_TABS[raw] || raw; + return TABS.some((tab) => tab.key === key) ? key : TABS[0].key; +} + +async function showTab(key) { + if (key === activeTab) return; + if (typeof teardown === "function") teardown(); + activeTab = key; + const params = new URLSearchParams(location.search); + params.set("tab", key); + history.replaceState(null, "", `?${params}`); + + for (const item of document.querySelectorAll(".nav-item")) { + item.classList.toggle("active", item.dataset.tab === key); + } + document.body.classList.toggle("has-chat-bar", key === "assistant"); + const content = document.getElementById("content"); + content.replaceChildren(); + const tab = TABS.find((t) => t.key === key); + const view = await import(`./views/${tab.key}.js`); + // Ignore a slow module import if the user already selected another tab. + if (activeTab !== key) return; + teardown = await view.render(content); +} + +function buildNav() { + const nav = document.getElementById("nav"); + nav.append(h("div", { class: "nav-label" }, "Navigation")); + for (const tab of TABS) { + nav.append(h("div", { + class: "nav-item", + "data-tab": tab.key, + onClick: () => showTab(tab.key), + }, icon(tab.icon), tab.label)); + } +} + +function bindSidebar() { + const pill = document.getElementById("farmbot-pill"); + const livePos = document.getElementById("live-position"); + const posAge = document.getElementById("position-age"); + + state.on("health", (health) => { + const fb = String(health?.farmbot ?? "unknown"); + const css = fb === "connected" ? "ok" : fb.startsWith("failed") ? "bad" : "warn"; + pill.className = `pill ${css}`; + pill.textContent = `● ${fb}`; + }); + state.on("position", (pos) => { + livePos.textContent = `X ${num(pos?.x)} · Y ${num(pos?.y)} · Z ${num(pos?.z)}`; + }); + const updatePositionAge = () => { + posAge.textContent = state.store.lastPositionRefresh + ? `updated ${timeAgo(state.store.lastPositionRefresh)}` : ""; + }; + + const refreshAll = () => { + state.refreshPosition(); + state.refreshHealth(); + state.refreshMessages(); + }; + document.getElementById("refresh-btn").addEventListener("click", refreshAll); + document.getElementById("estop-btn").addEventListener("click", async () => { + const r = await postAction("e_stop"); + if (r.ok) snack("🛑 ESTOP sent"); + else snack(errorMessage(r), { error: true }); + }); + return updatePositionAge; +} + +async function boot() { + buildNav(); + bindSidebarToggle(); + const updatePositionAge = bindSidebar(); + await state.initSession(); + state.refreshHealth(); + state.refreshPosition(); + state.refreshMessages(); + state.startPolling(updatePositionAge); + showTab(tabFromUrl()); + window.addEventListener("popstate", () => showTab(tabFromUrl())); +} + +const SIDEBAR_COLLAPSED_KEY = "twfb_sidebar_collapsed"; + +function setSidebarCollapsed(collapsed) { + document.body.classList.toggle("sidebar-collapsed", collapsed); + const icon = document.querySelector("#sidebar-toggle md-icon"); + if (icon) icon.textContent = collapsed ? "left_panel_open" : "left_panel_close"; + const btn = document.getElementById("sidebar-toggle"); + if (btn) { + const label = collapsed ? "Show navigation rail" : "Hide navigation rail"; + btn.setAttribute("aria-label", label); + btn.setAttribute("title", label); + } +} + +function bindSidebarToggle() { + const btn = document.getElementById("sidebar-toggle"); + if (!btn) return; + setSidebarCollapsed(localStorage.getItem(SIDEBAR_COLLAPSED_KEY) === "1"); + btn.addEventListener("click", () => { + const next = !document.body.classList.contains("sidebar-collapsed"); + localStorage.setItem(SIDEBAR_COLLAPSED_KEY, next ? "1" : "0"); + setSidebarCollapsed(next); + }); +} + +boot(); diff --git a/apps/ui/src/twfarmbot_ui/static/js/markdown.js b/apps/ui/src/twfarmbot_ui/static/js/markdown.js new file mode 100644 index 0000000..18f02b6 --- /dev/null +++ b/apps/ui/src/twfarmbot_ui/static/js/markdown.js @@ -0,0 +1,8 @@ +// Assistant-only dependency: other tabs do not pay for Markdown parsing +// or HTML sanitization. +import { marked } from "marked"; +import DOMPurify from "dompurify"; + +export function markdown(text) { + return DOMPurify.sanitize(marked.parse(String(text ?? ""))); +} diff --git a/apps/ui/src/twfarmbot_ui/static/js/material.js b/apps/ui/src/twfarmbot_ui/static/js/material.js new file mode 100644 index 0000000..8fc48a3 --- /dev/null +++ b/apps/ui/src/twfarmbot_ui/static/js/material.js @@ -0,0 +1,5 @@ +// Register all Material Web components eagerly to avoid duplicate registrations +// when using esm.run CDN. CDN bundlers cannot deduplicate shared dependencies +// (like md-elevation, md-focus-ring, md-ripple) across individual component imports. +// See: https://github.com/material-components/material-web/issues/5107 +import "@material/web/all.js"; diff --git a/apps/ui/src/twfarmbot_ui/static/js/state.js b/apps/ui/src/twfarmbot_ui/static/js/state.js new file mode 100644 index 0000000..f805fe2 --- /dev/null +++ b/apps/ui/src/twfarmbot_ui/static/js/state.js @@ -0,0 +1,153 @@ +// Shared app state: health, position, telemetry, and the persisted session +// (chat history, camera gallery, garden world) stored via /ui/sessions. + +import { api, ui, getSettings } from "./api.js"; + +export const store = { + health: null, // {status, actions, farmbot} + position: null, // {x, y, z} + lastPositionRefresh: 0, + messages: [], + diag: {}, // last GET /status state + lastStatsRefresh: 0, + telemetry: [], // ring buffer of {time, cpu, memory, disk, wifi, soc} + session: null, // persisted snapshot +}; + +const listeners = new Map(); + +export function on(event, fn) { + if (!listeners.has(event)) listeners.set(event, new Set()); + listeners.get(event).add(fn); + return () => listeners.get(event).delete(fn); +} + +export function emit(event, payload) { + for (const fn of listeners.get(event) || []) fn(payload); +} + +// ── Refresh helpers ───────────────────────────────────────────────────── + +export async function refreshPosition() { + const r = await api("/position"); + if (r.ok && r.body?.xyz) { + store.position = r.body.xyz; + store.lastPositionRefresh = Date.now(); + emit("position", store.position); + } + return r; +} + +export async function refreshHealth() { + const r = await api("/health"); + if (r.ok && typeof r.body === "object") { + store.health = r.body; + emit("health", store.health); + } + return r; +} + +export async function refreshMessages() { + const r = await api("/messages"); + if (r.ok && Array.isArray(r.body?.last_messages)) { + store.messages = r.body.last_messages.slice(-20).map(String); + emit("messages", store.messages); + } + return r; +} + +export async function refreshStatus() { + const r = await api("/status"); + if (r.ok && typeof r.body === "object") { + store.diag = r.body.state || {}; + store.lastStatsRefresh = Date.now(); + const info = store.diag.informational_settings || {}; + store.telemetry.push({ + time: new Date().toLocaleTimeString(), + cpu: parseFloat(info.cpu_usage) || 0, + memory: parseFloat(info.memory_usage) || 0, + disk: parseFloat(info.disk_usage) || 0, + wifi: parseFloat(info.wifi_level_percent) || 0, + soc: parseFloat(info.soc_temp) || 0, + }); + store.telemetry = store.telemetry.slice(-60); + emit("status", store.diag); + } + return r; +} + +// ── Session persistence (server-side JSON files) ─────────────────────── + +function blankSession() { + const now = new Date().toISOString(); + const stamp = now.slice(0, 19).replaceAll(":", "-"); + const suffix = Math.random().toString(16).slice(2, 10); + return { + session_id: `${stamp}-${suffix}`, + label: null, + created_at: now, + updated_at: now, + assistant_messages: [], + assistant_selected_model: null, + assistant_metrics: {}, + executed_plans: [], + camera_images: [], + garden_world: null, + }; +} + +export async function initSession() { + const requested = new URLSearchParams(location.search).get("session"); + if (requested) { + const r = await ui(`/sessions/${encodeURIComponent(requested)}`); + if (r.ok) { + store.session = { ...blankSession(), ...r.body }; + return; + } + } + store.session = blankSession(); +} + +// A blank unsaved session isn't persisted until it has content. +function sessionHasContent() { + const s = store.session; + return s && (s.assistant_messages.length || s.camera_images.length || + s.garden_world || s.executed_plans.length || s.label); +} + +export async function persistSession() { + if (!sessionHasContent()) return; + const s = store.session; + await ui(`/sessions/${encodeURIComponent(s.session_id)}`, { method: "PUT", json: s }); +} + +export function loadSessionSnapshot(snapshot) { + store.session = { ...blankSession(), ...snapshot }; + const params = new URLSearchParams(location.search); + params.set("session", snapshot.session_id); + history.replaceState(null, "", `?${params}`); +} + +export function newSession() { + store.session = blankSession(); + const params = new URLSearchParams(location.search); + params.delete("session"); + history.replaceState(null, "", params.size ? `?${params}` : location.pathname); +} + +// ── Background polling ────────────────────────────────────────────────── + +export function startPolling(onTick) { + setInterval(() => { + const settings = getSettings(); + const now = Date.now(); + onTick?.(); + if (now - store.lastPositionRefresh >= settings.refreshPositionS * 1000) { + refreshPosition(); + } + if (now - store.lastStatsRefresh >= settings.refreshStatsS * 1000) { + refreshHealth(); + refreshStatus(); + } + }, 1000); +} diff --git a/apps/ui/src/twfarmbot_ui/static/js/ui.js b/apps/ui/src/twfarmbot_ui/static/js/ui.js new file mode 100644 index 0000000..b3277c4 --- /dev/null +++ b/apps/ui/src/twfarmbot_ui/static/js/ui.js @@ -0,0 +1,168 @@ +// Tiny DOM helpers + shared layout primitives for consistent page structure. + +export function h(tag, attrs = {}, ...children) { + const el = document.createElement(tag); + for (const [key, value] of Object.entries(attrs)) { + if (value === undefined || value === null) continue; + if (key === "class") el.className = value; + else if (key.startsWith("on") && typeof value === "function") { + el.addEventListener(key.slice(2).toLowerCase(), value); + } else if (key === "html") el.innerHTML = value; + else if (key in el && key !== "style" && typeof value !== "string") el[key] = value; + else el.setAttribute(key, value); + } + for (const child of children.flat()) { + if (child === undefined || child === null) continue; + el.append(child.nodeType ? child : document.createTextNode(String(child))); + } + return el; +} + +export const icon = (name) => h("md-icon", {}, name); + +/** + * Material button with a correctly slotted icon. + * variant: "filled" | "filled-tonal" | "outlined" | "text" + */ +export function btn(variant, { icon: iconName, ...attrs } = {}, ...children) { + const el = h(`md-${variant}-button`, attrs); + if (iconName) el.append(h("md-icon", { slot: "icon" }, iconName)); + el.append(...children.flat().filter((c) => c !== null && c !== undefined) + .map((c) => (c.nodeType ? c : document.createTextNode(String(c))))); + return el; +} + +/** Icon-only button (md-icon-button uses the default slot). */ +export function iconBtn(iconName, attrs = {}) { + return h("md-icon-button", attrs, icon(iconName)); +} + +export function snack(message, { error = false, ms = 3500 } = {}) { + const host = document.getElementById("snackbar-host"); + const bar = h("div", { class: `snackbar${error ? " error" : ""}` }, message); + host.append(bar); + setTimeout(() => bar.remove(), ms); +} + +// ── Layout primitives ─────────────────────────────────────────────────── + +/** Standard page shell: header + body. Pass `actions` for title-row buttons. */ +export function page(title, eyebrow, { actions, bodyClass = "" } = {}) { + const body = h("div", { class: `page-body${bodyClass ? ` ${bodyClass}` : ""}` }); + const header = h("header", { class: "page-header" }, + h("p", { class: "eyebrow" }, eyebrow ?? "TWFarmBot · UAS Technikum Wien"), + h("div", { class: "page-title-row" }, + h("h1", { class: "page-title" }, title), + actions ? h("div", { class: "page-actions" }, ...(Array.isArray(actions) ? actions : [actions])) : null)); + return { root: h("div", { class: "page" }, header, body), body }; +} + +/** Section with a consistent title and vertical rhythm. */ +export function section(title, ...children) { + return h("section", { class: "section" }, + title ? h("h2", { class: "section-title" }, title) : null, + ...children); +} + +/** Elevated surface card; optional title rendered as card header. */ +export function card(title, ...children) { + if (!title) { + return h("div", { class: "card" }, h("div", { class: "card-body" }, ...children)); + } + return h("div", { class: "card" }, + h("div", { class: "card-header" }, h("h3", { class: "card-title" }, title)), + h("div", { class: "card-body" }, ...children)); +} + +/** Horizontal button / control row. */ +export function toolbar(...children) { + return h("div", { class: "toolbar" }, ...children); +} + +/** Responsive metric grid (auto-fits 2–5 columns). */ +export function metricRow(pairs) { + return h("div", { class: "metric-grid" }, + pairs.map(([label, value]) => metric(label, value))); +} + +export function metric(label, value) { + return h("div", { class: "metric" }, + h("div", { class: "metric-label" }, label), + h("div", { class: "metric-value" }, value ?? "—")); +} + +/** Two-column layout for map + sidebar, camera + controls, etc. */ +export function split(main, side, { ratio = "2fr 1fr" } = {}) { + return h("div", { class: "split", style: `--split-ratio:${ratio}` }, main, side); +} + +export function stack(...children) { + return h("div", { class: "stack" }, ...children); +} + +export function emptyState(message, { iconName = "info", compact = false } = {}) { + return h("div", { class: compact ? "empty-panel" : "empty-state" }, icon(iconName), h("p", {}, message)); +} + +export function expander(label, ...children) { + return h("details", { class: "expander" }, h("summary", {}, label), h("div", { class: "expander-body" }, ...children)); +} + +export function jsonBlock(data) { + return h("pre", { class: "codeblock" }, JSON.stringify(data, null, 2)); +} + +export function dataTable(headers, rows) { + return h("table", { class: "data-table" }, + h("thead", {}, h("tr", {}, headers.map((head) => h("th", {}, head)))), + h("tbody", {}, rows.map((row) => h("tr", {}, row.map((cell) => h("td", {}, cell ?? "—")))))); +} + +// ── Formatting helpers ──────────────────────────────────────────────── + +export const num = (value) => { + const f = parseFloat(value); + return Number.isFinite(f) ? f.toFixed(1) : "—"; +}; + +export const flt = (value, fallback = 0) => { + const f = parseFloat(value); + return Number.isFinite(f) ? f : fallback; +}; + +export function parseNumber(value) { + if (typeof value === "number") return value; + const text = String(value).trim(); + if (!/^-?\d+(?:[.,]\d+)?$/.test(text)) return null; + return parseFloat(text.replace(",", ".")); +} + +export function timeAgo(tsMs) { + if (!tsMs) return "never"; + const delta = (Date.now() - tsMs) / 1000; + if (delta < 2) return "just now"; + if (delta < 60) return `${Math.floor(delta)}s ago`; + if (delta < 3600) return `${Math.floor(delta / 60)}min ago`; + return `${(delta / 3600).toFixed(1)}h ago`; +} + +const ACTION_ICONS = { + move: "➡️", move_path: "🧭", water: "💧", find_home: "🏠", take_photo: "📷", + read_pin: "📖", write_pin: "✏️", mount_tool: "🔧", dismount_tool: "🔧", e_stop: "🛑", +}; + +export function actionSummary(action) { + const kind = action.kind || "action"; + const params = action.params || {}; + const prefix = `${ACTION_ICONS[kind] || "🛠️"} ${kind}`; + switch (kind) { + case "move": return `${prefix} → (${num(params.x)}, ${num(params.y)}, ${num(params.z)})`; + case "move_path": return `${prefix} · ${(params.waypoints || []).length} waypoint(s)`; + case "water": return `${prefix} · ${params.seconds ?? "—"}s`; + case "find_home": return `${prefix} (axis=${params.axis || "all"})`; + case "read_pin": return `${prefix} ${params.pin ?? "—"} (${params.mode || "digital"})`; + case "write_pin": return `${prefix} ${params.pin ?? "—"} = ${params.value ?? "—"}`; + case "mount_tool": return `${prefix} ${params.tool_name ?? "—"}`; + default: return prefix; + } +} diff --git a/apps/ui/src/twfarmbot_ui/static/js/views/assistant.js b/apps/ui/src/twfarmbot_ui/static/js/views/assistant.js new file mode 100644 index 0000000..3b8b6e5 --- /dev/null +++ b/apps/ui/src/twfarmbot_ui/static/js/views/assistant.js @@ -0,0 +1,386 @@ +import { api, ui, sse, postAction, errorMessage } from "../api.js"; +import { h, btn, iconBtn, snack, page, toolbar, expander, jsonBlock, actionSummary } from "../ui.js"; +import { markdown as md } from "../markdown.js"; +import * as state from "../state.js"; + +const CHAT_TIMEOUT_MS = 90000; +const APPROVAL_WORDS = new Set(["yes", "y", "approve", "approved", "ok", "okay", "sure", + "go ahead", "do it", "confirm", "confirmed", "execute", "run it"]); +const REJECTION_WORDS = new Set(["no", "n", "reject", "rejected", "cancel", "cancelled", + "don't", "dont", "stop", "abort"]); + +const normalize = (text) => text.replace(/[!.? ]+$/g, "").trim().toLowerCase(); +const isApproval = (text) => APPROVAL_WORDS.has(normalize(text)); +const isRejection = (text) => REJECTION_WORDS.has(normalize(text)); + +function metricsFooter(metrics) { + if (!metrics) return ""; + const parts = []; + if (metrics.total_latency_s != null) parts.push(`total ${metrics.total_latency_s.toFixed(2)}s`); + if (metrics.ttft_s) parts.push(`ttft ${metrics.ttft_s.toFixed(2)}s`); + if (metrics.tokens_per_s) parts.push(`${metrics.tokens_per_s.toFixed(1)} tok/s`); + if (metrics.total_tokens) { + parts.push(`tokens ${metrics.prompt_tokens || 0}+${metrics.completion_tokens || 0}=${metrics.total_tokens}`); + } + if (metrics.resireg_latency_s) parts.push(`resireg ${metrics.resireg_latency_s.toFixed(2)}s`); + return parts.join(" · "); +} + +function toolCallLabel(name, args = {}) { + let label = name; + if (name === "analyze_image" && args.prompt) label += ` · ${args.prompt}`; + else if (name === "segment_image" && args.classes) label += ` · ${args.classes}`; + else if (name === "visualize_image_features") label += ` · ${args.n_clusters ?? 6} clusters`; + else if (name === "estimate_traversability" && args.prompt) label += ` · ${args.prompt}`; + return label; +} + +function toolCallEl(name, args, result) { + const parts = [expander(toolCallLabel(name, args || {}), jsonBlock({ args, result }))]; + if (result && typeof result === "object") { + const urls = result.image_urls || (result.image_url ? [result.image_url] : []); + if (urls.length) parts.push(h("div", { class: "chat-images" }, urls.map((src) => h("img", { src, alt: "" })))); + } + return h("div", {}, ...parts); +} + +async function fetchLatestImage() { + const r = await api("/images", { params: { limit: "1", refresh: "true" }, timeoutMs: 15000 }); + return ((r.ok && r.body?.images) || [])[0] || null; +} + +function imageIsNewer(image, previous) { + if (!previous) return true; + if (image.id != null && previous.id != null) return image.id !== previous.id; + return (image.created_at || "") > (previous.created_at || ""); +} + +async function waitForNewImage(previous, { attempts = 15, delayMs = 2000 } = {}) { + for (let i = 0; i < attempts; i++) { + await new Promise((resolve) => setTimeout(resolve, delayMs)); + const image = await fetchLatestImage(); + if (image && imageIsNewer(image, previous)) return image; + } + return null; +} + +async function executeProposedActions(actions, message) { + const willCapture = message && actions.some((a) => a.kind === "take_photo"); + const previousImage = willCapture ? await fetchLatestImage() : null; + const results = []; + for (const action of actions) { + const r = await postAction(action.kind, action.params || {}, { wait: true }); + results.push({ kind: action.kind, ok: r.ok, detail: typeof r.body === "string" ? r.body : r.body?.detail }); + } + if (willCapture) { + const image = await waitForNewImage(previousImage); + if (image) (message.images = message.images || []).push({ attachment_url: image.attachment_url }); + } + return results; +} + +function formatExecutionResults(results) { + if (!results.length) return "✅ Approved (no actions)."; + return results.map((res) => res.ok + ? `✅ ${actionSummary({ kind: res.kind })}` + : `❌ ${actionSummary({ kind: res.kind })} — ${res.detail || "error"}`).join("\n"); +} + +export async function render(container) { + const session = state.store.session; + const chatScroll = h("div", { class: "chat-scroll" }); + const metricsBar = h("div", { class: "assistant-metrics" }); + const sessionBox = h("div"); + const pickerBox = h("div", { class: "model-picker" }); + let busy = false; + + const clearBtn = btn("outlined", { + icon: "mop", + onClick: async () => { + session.assistant_messages = []; + await state.persistSession(); + drawMessages(); + }, + }, "Clear chat"); + + const { root, body } = page("Assistant", "TWFarmBot · UAS Technikum Wien", { actions: clearBtn }); + body.append( + sessionBox, + pickerBox, + h("div", { class: "chat-panel" }, chatScroll), + ); + container.append(root); + + // Fixed chat input bar — attached to body so it spans the full main area. + const input = h("md-outlined-text-field", { label: "Message", placeholder: "Ask the FarmBot assistant…" }); + const sendBtn = btn("filled", { icon: "send" }, "Send"); + const chatBar = h("div", { class: "chat-input-bar" }, + h("div", { class: "chat-input-inner" }, + metricsBar, + h("div", { class: "chat-input-row" }, input, sendBtn))); + document.body.append(chatBar); + + const send = async () => { + const prompt = input.value.trim(); + if (!prompt) return; + input.value = ""; + await sendPrompt(prompt); + }; + sendBtn.addEventListener("click", send); + input.addEventListener("keydown", (e) => { if (e.key === "Enter") send(); }); + + function messageEl(message) { + if (message.role === "tool") { + return h("div", { class: "msg" }, + h("md-icon", { class: "avatar" }, "build"), + h("div", { class: "bubble" }, toolCallEl(message.name, message.args, message.result))); + } + if (message.role === "user") { + return h("div", { class: "msg user" }, + h("md-icon", { class: "avatar" }, "person"), + h("div", { class: "bubble", html: md(message.content) })); + } + const bubble = h("div", { class: "bubble" }); + if (message.thinking) bubble.append(expander("Thinking", h("div", { html: md(message.thinking) }))); + bubble.append(h("div", { html: md(message.content) })); + if (message.images?.length) { + bubble.append(h("div", { class: "chat-images" }, + message.images.map((img) => h("img", { src: img.attachment_url, alt: "" })))); + } + const proposals = message.proposed_actions || []; + if (proposals.length && !message.approved && !message.rejected) { + bubble.append(h("div", { class: "proposal-card" }, + h("p", { class: "caption", style: "margin:0 0 8px" }, "Proposed actions:"), + ...proposals.map((a) => h("p", { class: "caption", style: "margin:0" }, actionSummary(a))), + toolbar( + btn("filled", { icon: "check", onClick: () => resolveProposal(message, true) }, "Approve"), + btn("outlined", { icon: "close", onClick: () => resolveProposal(message, false) }, "Reject")))); + } else if (message.approved) { + bubble.append(h("p", { class: "caption" }, "Approved")); + } else if (message.rejected) { + bubble.append(h("p", { class: "caption" }, "Rejected")); + } + return h("div", { class: "msg" }, h("md-icon", { class: "avatar" }, "smart_toy"), bubble); + } + + function drawMessages() { + chatScroll.replaceChildren(...session.assistant_messages.map(messageEl)); + metricsBar.textContent = metricsFooter(session.assistant_metrics); + chatScroll.lastElementChild?.scrollIntoView({ behavior: "smooth", block: "end" }); + } + + async function resolveProposal(message, approved) { + if (approved) { + const results = await executeProposedActions(message.proposed_actions, message); + message.approved = true; + message.content += `\n\n${formatExecutionResults(results)}`; + } else { + message.rejected = true; + message.content += "\n\n❌ Cancelled."; + } + await state.persistSession(); + drawMessages(); + } + + async function sendPrompt(prompt) { + if (busy) return; + const messages = session.assistant_messages; + const last = messages[messages.length - 1]; + const pending = last?.role === "assistant" && (last.proposed_actions || []).length + && !last.approved && !last.rejected; + + if (isApproval(prompt) || isRejection(prompt)) { + if (pending) { + messages.push({ role: "user", content: prompt }); + drawMessages(); + await resolveProposal(last, isApproval(prompt)); + return; + } + snack("No pending proposal to approve or reject."); + return; + } + + busy = true; + messages.push({ role: "user", content: prompt }); + drawMessages(); + + const liveBubble = h("div", { class: "bubble" }); + const liveMsg = h("div", { class: "msg" }, + h("md-icon", { class: "avatar" }, "smart_toy"), + h("div", { class: "stack" }, + h("p", { class: "caption", style: "margin:0" }, "Thinking…"), + liveBubble)); + chatScroll.append(liveMsg); + + let textDiv = null; + let accumulated = ""; + let segment = ""; + let lastScrollAt = 0; + const meta = { tool_calls: [], proposed_actions: [], metrics: {} }; + const thinkingParts = []; + let streamError = null; + const newSegment = () => { textDiv = null; segment = ""; }; + const appendText = (chunk) => { + accumulated += chunk; + segment += chunk; + if (!textDiv) { + textDiv = h("div", { class: "streaming-text" }); + liveBubble.append(textDiv); + } + // Parsing + sanitizing the full response for every token is O(n²). + // Stream plain text, then render Markdown once in drawMessages(). + textDiv.textContent = segment; + if (performance.now() - lastScrollAt > 120) { + liveMsg.scrollIntoView({ block: "end" }); + lastScrollAt = performance.now(); + } + }; + + try { + for await (const event of sse("/chat/stream", + { messages, model: session.assistant_selected_model }, + { timeoutMs: CHAT_TIMEOUT_MS })) { + if (event.type === "delta") appendText(event.content || ""); + else if (event.type === "thinking") { + newSegment(); + thinkingParts.push(String(event.content || "")); + liveBubble.append(expander("Thinking", h("div", { html: md(event.content) }))); + } else if (event.type === "tool_call") { + newSegment(); + const { name, args, result } = event; + messages.push({ role: "tool", name, args, result }); + if (name === "take_photo" && result?.status === "ok") { + const image = await fetchLatestImage(); + if (image) result.image_url = image.attachment_url; + } + liveBubble.append(toolCallEl(name, args, result)); + } else if (event.type === "meta") { + meta.tool_calls = event.tool_calls || []; + meta.proposed_actions = event.proposed_actions || []; + meta.metrics = event.metrics || {}; + } else if (event.type === "error") { + streamError = event.error || "stream error"; + } + } + } catch (err) { + streamError = `${err.name}: ${err.message}`; + } + + if (!accumulated && !meta.tool_calls.length && !meta.proposed_actions.length) { + const r = await api("/chat", { + method: "POST", + json: { messages, model: session.assistant_selected_model }, + timeoutMs: CHAT_TIMEOUT_MS, + }); + if (r.ok && typeof r.body === "object") { + accumulated = String(r.body.response || ""); + meta.tool_calls = r.body.tool_calls || []; + meta.metrics = r.body.metrics || {}; + for (const tc of meta.tool_calls) { + messages.push({ role: "tool", name: tc.name, args: tc.args, result: tc.result }); + } + meta.proposed_actions = meta.tool_calls + .filter((tc) => tc.result?.status === "proposed") + .map((tc) => ({ kind: tc.result.kind ?? tc.name, params: tc.result.params ?? tc.args ?? {} })); + thinkingParts.splice(0, thinkingParts.length, String(r.body.thinking || "")); + streamError = null; + } else if (!streamError) { + streamError = `Fallback failed: ${errorMessage(r)}`; + } + } + + if (Object.keys(meta.metrics).length) session.assistant_metrics = meta.metrics; + if (streamError) snack(`Assistant error: ${streamError}`, { error: true, ms: 8000 }); + if (accumulated || meta.tool_calls.length || meta.proposed_actions.length) { + messages.push({ + role: "assistant", content: accumulated, thinking: thinkingParts.join(""), + tool_calls: meta.tool_calls, proposed_actions: meta.proposed_actions, + images: [], metrics: meta.metrics, + }); + } + busy = false; + await state.persistSession(); + drawMessages(); + } + + async function drawPicker() { + const provRes = await api("/providers"); + const providers = (provRes.ok && provRes.body?.providers) || ["openrouter", "local"]; + let provider = (provRes.ok && provRes.body?.current) || providers[0]; + const providerSelect = h("md-outlined-select", { label: "Provider" }, + providers.map((p) => h("md-select-option", { value: p, selected: p === provider }, + h("div", { slot: "headline" }, p)))); + const modelBox = h("div"); + pickerBox.replaceChildren(providerSelect, modelBox); + + async function loadModels() { + const r = await api("/models", { params: { provider } }); + const models = (r.ok && r.body?.models) || []; + let current = session.assistant_selected_model || (r.ok && r.body?.current) || null; + if (models.length) { + if (!models.includes(current)) { + const preferred = ["openai/gpt-4o-mini", "openai/gpt-4o", "anthropic/claude-3.5-sonnet"]; + current = preferred.find((m) => models.includes(m)) || models[0]; + } + session.assistant_selected_model = current; + const modelSelect = h("md-outlined-select", { label: "Model", class: "grow" }, + models.map((m) => h("md-select-option", { value: m, selected: m === current }, + h("div", { slot: "headline" }, m)))); + modelSelect.addEventListener("change", () => { session.assistant_selected_model = modelSelect.value; }); + modelBox.replaceChildren(modelSelect); + } else { + modelBox.replaceChildren(h("md-outlined-text-field", { + label: "Model", value: current || "", class: "grow", + onInput: (e) => { session.assistant_selected_model = e.target.value || null; }, + })); + } + } + providerSelect.addEventListener("change", () => { provider = providerSelect.value; loadModels(); }); + await loadModels(); + } + + async function drawSessionBox() { + const labelField = h("md-outlined-text-field", { + label: "Session label", value: session.label || "", class: "grow", + onInput: (e) => { session.label = e.target.value.trim() || null; }, + }); + const listBox = h("div", { class: "stack" }); + sessionBox.replaceChildren(expander("Session", + toolbar(labelField, + btn("outlined", { + icon: "add", + onClick: async () => { await state.persistSession(); state.newSession(); location.reload(); }, + }, "New"), + btn("outlined", { + icon: "save", + onClick: async () => { await state.persistSession(); snack("Session saved"); }, + }, "Save")), + listBox)); + + const r = await ui("/sessions"); + const sessions = ((r.ok && r.body?.sessions) || []) + .filter((s) => s.session_id !== session.session_id).slice(0, 20); + listBox.replaceChildren(...sessions.map((s) => h("div", { class: "session-list-item" }, + h("span", { class: "caption" }, (s.label || s.session_id) + (s.preview ? ` · ${s.preview}` : "")), + h("md-text-button", { + onClick: async () => { + const res = await ui(`/sessions/${encodeURIComponent(s.session_id)}`); + if (!res.ok) { snack("Session not found", { error: true }); return; } + state.loadSessionSnapshot(res.body); + location.reload(); + }, + }, "Load"), + iconBtn("delete", { + onClick: async () => { + await ui(`/sessions/${encodeURIComponent(s.session_id)}`, { method: "DELETE" }); + drawSessionBox(); + }, + })))); + } + + drawMessages(); + drawSessionBox(); + drawPicker(); + + return () => chatBar.remove(); +} diff --git a/apps/ui/src/twfarmbot_ui/static/js/views/camera.js b/apps/ui/src/twfarmbot_ui/static/js/views/camera.js new file mode 100644 index 0000000..3f87c13 --- /dev/null +++ b/apps/ui/src/twfarmbot_ui/static/js/views/camera.js @@ -0,0 +1,188 @@ +import { api, resireg, postAction, errorMessage, getSettings } from "../api.js"; +import { h, btn, snack, page, section, card, toolbar, split, stack, metricRow, emptyState } from "../ui.js"; +import * as state from "../state.js"; + +function parseSegmentationLabels(labels) { + const out = {}; + for (const label of labels) { + for (const part of String(label).split(",")) { + const match = part.match(/(.+?)\s*\(\s*([0-9]*\.?[0-9]+)\s*%\s*\)/); + if (match) out[match[1].trim()] = Math.round(parseFloat(match[2]) * 10) / 1000; + } + } + return out; +} + +async function visionChat(imageUrl, text) { + const r = await resireg("/v1/chat/completions", { + method: "POST", + json: { + model: "SimonSchwaiger/resireg_mini", + messages: [{ role: "user", content: [ + { type: "text", text }, { type: "image_url", image_url: { url: imageUrl } }, + ] }], + }, + }); + if (!r.ok) throw new Error(errorMessage(r)); + const content = r.body.choices[0].message.content; + return typeof content === "string" ? JSON.parse(content) : content; +} + +const MODES = [ + "Open Language Similarity", + "Zero-Shot Segmentation", + "PCA Feature Visualization", + "Traversability Estimation", +]; + +export async function render(container) { + const takePhotoBtn = btn("filled", { + icon: "photo_camera", + onClick: async () => { + const r = await postAction("take_photo"); + if (r.ok) { snack("Capture queued"); loadGallery(); } + else snack(errorMessage(r), { error: true }); + }, + }, "Take photo"); + const refreshBtn = btn("outlined", { + icon: "refresh", + onClick: () => loadGallery(true), + }, "Refresh gallery"); + + const { root, body } = page("Camera", undefined, { actions: [takePhotoBtn, refreshBtn] }); + const galleryArea = h("div", { class: "stack" }); + const resultArea = h("div", { class: "stack" }); + let aiResult = null; + + body.append(galleryArea, resultArea); + container.append(root); + + async function loadGallery(refresh = false) { + const r = await api("/images", { params: refresh ? { refresh: "true" } : undefined, timeoutMs: 15000 }); + if (r.ok && Array.isArray(r.body?.images)) { + state.store.session.camera_images = r.body.images; + state.persistSession(); + draw(); + } else snack(errorMessage(r), { error: true }); + } + + function draw() { + const images = state.store.session?.camera_images || []; + if (!images.length) { + galleryArea.replaceChildren( + emptyState("Refresh the gallery to load FarmBot photos.", { iconName: "photo_library", compact: true })); + return; + } + let selected = images[0]; + const select = h("md-outlined-select", { label: "Research image", class: "field-lg" }, + images.map((img, i) => h("md-select-option", { value: String(i), selected: i === 0 }, + h("div", { slot: "headline" }, `${img.created_at || "Unknown"} · #${img.id ?? "—"}`)))); + const frame = h("img", { class: "frame", src: selected.attachment_url || "", alt: "FarmBot capture" }); + select.addEventListener("change", () => { + selected = images[Number(select.value)]; + frame.src = selected.attachment_url || ""; + }); + + let mode = MODES[0]; + const modeSelect = h("md-outlined-select", { label: "Analysis mode", class: "grow" }, + MODES.map((label, i) => h("md-select-option", { value: label, selected: i === 0 }, + h("div", { slot: "headline" }, label)))); + const promptField = h("md-outlined-text-field", { label: "Target prompt", class: "grow" }); + const classesField = h("md-outlined-text-field", { label: "Classes (comma-separated)", value: "plant, weed, soil, path", class: "grow" }); + const negativeField = h("md-outlined-text-field", { label: "Background prompt", class: "grow" }); + const clusterSlider = h("md-slider", { min: 2, max: 20, value: 6, labeled: true }); + const spinner = h("md-circular-progress", { indeterminate: true, style: "display:none" }); + + function syncFields() { + mode = modeSelect.value || MODES[0]; + const isSim = mode === "Open Language Similarity"; + const isSeg = mode === "Zero-Shot Segmentation"; + const isPca = mode === "PCA Feature Visualization"; + const isTrav = mode === "Traversability Estimation"; + promptField.style.display = isSim || isTrav ? "" : "none"; + promptField.label = isTrav ? "Traversable prompt" : "Target prompt"; + classesField.style.display = isSeg ? "" : "none"; + negativeField.style.display = isSeg || isTrav ? "" : "none"; + clusterSlider.style.display = isPca ? "" : "none"; + } + modeSelect.addEventListener("change", syncFields); + + async function analyze() { + spinner.style.display = ""; + try { + const url = selected.attachment_url; + if (mode === "Open Language Similarity") { + const prompt = promptField.value.trim(); + if (!prompt) throw new Error("Enter a target prompt."); + const result = await visionChat(url, prompt); + aiResult = { images: [result.result_image_base64], captions: [`Similarity · ${prompt}`] }; + } else if (mode === "Zero-Shot Segmentation") { + const classes = classesField.value.trim(); + if (!classes) throw new Error("Enter classes."); + const result = await visionChat(url, `/segment: ${classes}`); + const labels = [String(result.detected ?? ""), String(result.undetected ?? "")]; + aiResult = { + images: (result.result_images_base64 || []).slice(0, 2), + captions: ["Overlay", "Segmentation map"], + labels, classScores: parseSegmentationLabels(labels), + }; + } else if (mode === "PCA Feature Visualization") { + const n = Number(clusterSlider.value); + const result = await visionChat(url, `/pca: ${n}`); + aiResult = { + images: (result.result_images_base64 || []).slice(0, 3), + captions: ["PCA 1", "PCA 2", "PCA 3"], nClusters: n, + }; + } else { + const prompt = promptField.value.trim(); + if (!prompt) throw new Error("Enter a traversable prompt."); + const negatives = negativeField.value.trim(); + const result = await visionChat(url, `/traverse: ${prompt}${negatives ? ` vs ${negatives}` : ""}`); + aiResult = { images: [result.result_image_base64], captions: [`Traversability · ${prompt}`] }; + } + drawResult(); + } catch (err) { + snack(`AI processing failed: ${err.message}`, { error: true }); + } finally { + spinner.style.display = "none"; + } + } + + syncFields(); + galleryArea.replaceChildren( + select, + split( + h("div", {}, frame), + card("AI analysis", stack(modeSelect, promptField, classesField, negativeField, clusterSlider, + toolbar(btn("filled", { icon: "neurology", onClick: analyze }, "Analyze"), spinner))), + ), + images.length > 1 ? section("Recent captures", h("div", { class: "gallery" }, + images.slice(1, 7).map((img) => { + const meta = img.meta || {}; + return h("figure", {}, h("img", { src: img.attachment_url || "", alt: "" }), + h("figcaption", { class: "caption" }, `X ${meta.x ?? "—"} · Y ${meta.y ?? "—"}`)); + }))) : null, + ); + } + + function drawResult() { + if (!aiResult) { resultArea.replaceChildren(); return; } + const parts = [section("Analysis result", h("div", { class: "gallery" }, + aiResult.images.map((src, i) => h("figure", {}, + h("img", { src, alt: aiResult.captions[i] || "" }), + h("figcaption", { class: "caption" }, aiResult.captions[i] || "")))))]; + const scores = aiResult.classScores || {}; + if (Object.keys(scores).length) { + parts.push(metricRow(Object.entries(scores).map(([cls, score]) => [cls, `${(score * 100).toFixed(1)}%`]))); + } else if (aiResult.nClusters) { + parts.push(h("p", { class: "caption" }, `PCA with ${aiResult.nClusters} clusters`)); + } + for (const label of aiResult.labels || []) parts.push(h("p", { class: "caption" }, label)); + resultArea.replaceChildren(...parts); + } + + draw(); + const cameraS = getSettings().refreshCameraS; + const timer = cameraS > 0 ? setInterval(() => loadGallery(true), cameraS * 1000) : null; + return () => timer && clearInterval(timer); +} diff --git a/apps/ui/src/twfarmbot_ui/static/js/views/diagnostics.js b/apps/ui/src/twfarmbot_ui/static/js/views/diagnostics.js new file mode 100644 index 0000000..73aaadf --- /dev/null +++ b/apps/ui/src/twfarmbot_ui/static/js/views/diagnostics.js @@ -0,0 +1,62 @@ +import { errorMessage } from "../api.js"; +import { h, btn, snack, page, section, card, toolbar, metricRow, dataTable, emptyState } from "../ui.js"; +import * as state from "../state.js"; + +export async function render(container) { + const { root, body } = page("Diagnostics"); + const contentBox = h("div"); + + body.append( + toolbar(btn("filled-tonal", { + icon: "troubleshoot", + onClick: async () => { + const r = await state.refreshStatus(); + if (!r.ok) snack(`Read failed: ${errorMessage(r)}`, { error: true }); + draw(); + }, + }, "Load /status")), + contentBox, + ); + container.append(root); + + function draw() { + const payload = state.store.diag || {}; + const info = payload.informational_settings || {}; + const axes = payload.location_data?.axis_states || {}; + const pins = payload.pins || {}; + + if (!Object.keys(info).length && !Object.keys(axes).length && !Object.keys(pins).length) { + contentBox.replaceChildren(emptyState("Click “Load /status” to fetch diagnostic state.", { iconName: "troubleshoot", compact: true })); + return; + } + + contentBox.replaceChildren( + metricRow([ + ["Controller", info.controller_version ?? "—"], + ["Firmware", info.firmware_version ?? "—"], + ["Wi-Fi", `${info.wifi_level_percent ?? "—"}%`], + ["Uptime", `${info.uptime ?? "—"} s`], + ]), + h("div", { class: "card-grid" }, + card("Resources", + h("p", { class: "caption" }, `CPU ${info.cpu_usage ?? "—"}%`), + h("p", { class: "caption" }, `Memory ${info.memory_usage ?? "—"}% · Disk ${info.disk_usage ?? "—"}%`), + h("p", { class: "caption" }, `SoC ${info.soc_temp ?? "—"} °C`)), + card("Axis state", + h("p", { class: "caption" }, `X ${axes.x ?? "—"} · Y ${axes.y ?? "—"} · Z ${axes.z ?? "—"}`), + h("p", { class: "caption" }, `Busy: ${info.busy ?? "—"}`)), + card("Network", + h("p", { class: "caption" }, `${info.wifi_level ?? "—"} dBm`), + h("p", { class: "caption" }, `${info.private_ip ?? "—"}`), + h("p", { class: "caption" }, `Sync: ${info.sync_status ?? "—"}`)), + ), + Object.keys(pins).length + ? section("Pin snapshot", dataTable(["Pin", "Value", "Mode"], + Object.entries(pins).map(([pin, data]) => [pin, data?.value, data?.mode]))) + : null, + ); + } + + draw(); + return state.on("status", draw); +} diff --git a/apps/ui/src/twfarmbot_ui/static/js/views/garden.js b/apps/ui/src/twfarmbot_ui/static/js/views/garden.js new file mode 100644 index 0000000..af9707b --- /dev/null +++ b/apps/ui/src/twfarmbot_ui/static/js/views/garden.js @@ -0,0 +1,188 @@ +import { api, ui, errorMessage } from "../api.js"; +import { h, btn, snack, page, section, card, toolbar, metricRow, split, stack, num, dataTable } from "../ui.js"; +import * as state from "../state.js"; + +const SVG_NS = "http://www.w3.org/2000/svg"; +const GRID_STEP = 25; +const PALETTE = ["#554fd8", "#2685c7", "#d35d7b", "#8b5ed7", "#e57a44", "#00a59b", "#b54fc8"]; +const KINDS = ["plant", "obstacle", "tool", "marker", "sensor", "valve", "custom"]; + +const kindColor = (kind, offset = 0) => { + let hash = offset; + for (const ch of String(kind)) hash = (hash * 31 + ch.charCodeAt(0)) % 997; + return PALETTE[hash % PALETTE.length]; +}; + +function svgEl(tag, attrs, ...children) { + const el = document.createElementNS(SVG_NS, tag); + for (const [key, value] of Object.entries(attrs)) el.setAttribute(key, value); + el.append(...children); + return el; +} + +export async function render(container) { + const { root, body } = page("Garden map", "Spatial model · configured world state"); + const metricsBox = h("div"); + const mapBox = h("div"); + const sideBox = h("div", { class: "stack" }); + let selected = []; + + body.append( + toolbar(btn("filled-tonal", { icon: "refresh", onClick: () => loadWorld(true) }, "Refresh map")), + metricsBox, + split(mapBox, sideBox), + ); + container.append(root); + + async function loadWorld(force = false) { + let world = force ? null : state.store.session?.garden_world; + if (!world) { + const r = await api("/garden"); + if (!r.ok || typeof r.body !== "object") { + mapBox.replaceChildren(card(null, h("p", { class: "caption" }, + `Garden model unavailable: ${errorMessage(r)}`))); + return; + } + world = r.body; + state.store.session.garden_world = world; + state.persistSession(); + } + selected = []; + draw(world); + } + + function draw(world) { + const bounds = world.bounds || {}; + const camera = world.camera || {}; + const robot = world.robot || {}; + const entities = world.entities || []; + const zones = world.zones || []; + const [x0, y0] = [bounds.x || 0, bounds.y || 0]; + const [width, height] = [bounds.width || 1, bounds.height || 1]; + const pad = Math.max(width, height) * 0.03; + const flipY = (y) => y0 + height - (y - y0); + + metricsBox.replaceChildren(metricRow([ + ["Garden X", `${num(width)} mm`], ["Garden Y", `${num(height)} mm`], + ["Known objects", entities.length], ["Mapped zones", zones.length], + ])); + + const svg = svgEl("svg", { + class: "garden-map", + viewBox: `${x0 - pad} ${y0 - pad} ${width + 2 * pad} ${height + 2 * pad}`, + }); + svg.append(svgEl("rect", { + x: x0, y: y0, width, height, + fill: "none", stroke: "var(--md-sys-color-outline)", "stroke-width": pad * 0.2, + })); + for (const zone of zones) { + const zb = zone.bounds || {}; + const color = kindColor(zone.kind); + svg.append(svgEl("rect", { + x: zb.x, y: flipY(zb.y + zb.height), width: zb.width, height: zb.height, + fill: color, "fill-opacity": 0.15, stroke: color, "stroke-width": pad * 0.12, rx: 6, + }, svgEl("title", {}, `${zone.name} (${zone.kind})`))); + } + const marker = (x, y, r, color, label) => svgEl("circle", { + cx: x, cy: flipY(y), r, fill: color, stroke: "white", "stroke-width": r * 0.15, + }, svgEl("title", {}, label)); + for (const entity of entities) { + const p = entity.position || {}; + svg.append(marker(p.x, p.y, Math.max(entity.radius_mm || 20, 12), kindColor(entity.kind, 3), + `${entity.name} (${entity.kind})`)); + } + svg.append(marker(robot.x || 0, robot.y || 0, 20, "#554fd8", "FarmBot")); + const camPos = camera.position || {}; + svg.append(marker(camPos.x || 0, camPos.y || 0, 14, "#d35d7b", "Camera")); + + const selectionLayer = svgEl("g", {}); + svg.append(selectionLayer); + svg.addEventListener("click", (event) => { + const point = new DOMPoint(event.clientX, event.clientY).matrixTransform(svg.getScreenCTM().inverse()); + const gx = Math.round(point.x / GRID_STEP) * GRID_STEP; + const gy = Math.round((y0 + height - (point.y - y0)) / GRID_STEP) * GRID_STEP; + if (gx < x0 || gx > x0 + width || gy < y0 || gy > y0 + height) return; + const idx = selected.findIndex(([sx, sy]) => sx === gx && sy === gy); + if (idx >= 0) selected.splice(idx, 1); + else selected.push([gx, gy]); + drawSelection(); + }); + + function drawSelection() { + selectionLayer.replaceChildren(...selected.map(([sx, sy]) => svgEl("circle", { + cx: sx, cy: flipY(sy), r: 12, fill: "none", stroke: "#e53935", "stroke-width": 3, + }))); + drawSide(); + } + + mapBox.replaceChildren(svg, + h("div", { class: "garden-legend" }, + ...zones.map((z) => h("span", {}, + h("span", { class: "swatch", style: `background:${kindColor(z.kind)}` }), z.name)), + h("span", {}, h("span", { class: "swatch", style: "background:#554fd8" }), "FarmBot"), + h("span", {}, h("span", { class: "swatch", style: "background:#d35d7b" }), "Camera"), + h("span", { class: "caption" }, `Click to select ${GRID_STEP} mm grid points`))); + + function drawSide() { + const parts = []; + if (selected.length) { + let kind = "plant"; + const customField = h("md-outlined-text-field", { label: "Custom kind", class: "grow", style: "display:none" }); + const chips = h("md-chip-set", { class: "chip-row" }, KINDS.map((k) => + h("md-filter-chip", { + label: k, selected: k === kind, + onClick: (e) => { + e.preventDefault(); + kind = k; + for (const chip of chips.querySelectorAll("md-filter-chip")) chip.selected = chip.label === k; + customField.style.display = k === "custom" ? "" : "none"; + }, + }))); + const nameField = h("md-outlined-text-field", { label: "Name prefix", placeholder: "e.g. Tomato", class: "grow" }); + parts.push(card(`${selected.length} point(s) selected`, stack( + chips, customField, nameField, + toolbar( + h("md-filled-button", { + onClick: async () => { + const name = nameField.value.trim(); + if (!name) { snack("Please enter a name prefix.", { error: true }); return; } + const finalKind = kind === "custom" && customField.value.trim() ? customField.value.trim() : kind; + for (const [i, [px, py]] of selected.entries()) { + const res = await ui("/garden/entities", { + method: "POST", json: { x: px, y: py, kind: finalKind, name: `${name}-${i + 1}` }, + }); + if (!res.ok) { snack(errorMessage(res), { error: true }); return; } + } + snack(`Added ${selected.length} ${finalKind}(s)`); + loadWorld(true); + }, + }, `Assign ${selected.length}`), + h("md-outlined-button", { onClick: () => { selected = []; drawSelection(); } }, "Clear"))))); + } + parts.push( + section("Live pose", metricRow([["X", num(robot.x)], ["Y", num(robot.y)], ["Z", num(robot.z)]])), + section("Camera pose", + h("p", { class: "caption" }, `X ${num(camPos.x)} · Y ${num(camPos.y)} · Z ${num(camPos.z)} mm`), + h("p", { class: "caption" }, + `Yaw ${num(camera.yaw_deg)}° · Pitch ${num(camera.pitch_deg)}° · Roll ${num(camera.roll_deg)}°`)), + section("Mapped objects", entities.length + ? dataTable(["Name", "Kind"], entities.map((e) => [e.name, e.kind])) + : h("p", { class: "caption" }, "No objects mapped yet."))); + sideBox.replaceChildren(...parts); + } + drawSelection(); + } + + await loadWorld(); + const off = state.on("position", (pos) => { + const world = state.store.session?.garden_world; + if (!world || !pos) return; + world.robot = { ...pos }; + const offset = world.camera_offset || {}; + world.camera = { ...(world.camera || {}), position: { + x: (pos.x || 0) + (offset.x || 0), y: (pos.y || 0) + (offset.y || 0), z: (pos.z || 0) + (offset.z || 0), + }}; + if (!selected.length) draw(world); + }); + return off; +} diff --git a/apps/ui/src/twfarmbot_ui/static/js/views/history.js b/apps/ui/src/twfarmbot_ui/static/js/views/history.js new file mode 100644 index 0000000..d42a251 --- /dev/null +++ b/apps/ui/src/twfarmbot_ui/static/js/views/history.js @@ -0,0 +1,58 @@ +import { ui } from "../api.js"; +import { h, snack, page, section, card, toolbar, expander, emptyState, actionSummary } from "../ui.js"; +import * as state from "../state.js"; + +export async function render(container) { + const { root, body } = page("History"); + const r = await ui("/sessions"); + const sessions = (r.ok && r.body?.sessions) || []; + + if (!sessions.length) { + body.append(emptyState("No saved sessions yet. Chat is saved automatically.", { iconName: "history", compact: true })); + container.append(root); + return; + } + + const sessionList = h("div", { class: "stack" }); + body.append( + section("Chat sessions", sessionList), + ); + + sessionList.replaceChildren(...sessions.map((sess) => { + const updated = (sess.updated_at || "").slice(0, 19).replace("T", " "); + return card(null, h("div", { class: "toolbar", style: "justify-content:space-between" }, + h("div", {}, + h("b", {}, sess.label || sess.session_id), + h("p", { class: "caption" }, `Updated ${updated}` + (sess.preview ? ` · ${sess.preview}` : ""))), + h("md-filled-tonal-button", { + onClick: async () => { + const res = await ui(`/sessions/${encodeURIComponent(sess.session_id)}`); + if (!res.ok) { snack("Session not found", { error: true }); return; } + state.loadSessionSnapshot(res.body); + const params = new URLSearchParams(location.search); + params.set("tab", "assistant"); + location.search = params.toString(); + }, + }, "Load"))); + })); + + const executed = state.store.session?.executed_plans || []; + if (executed.length) { + body.append(section("Executed plans", h("div", { class: "stack" }, + executed.slice().reverse().map((plan, index) => { + const status = plan.status || "unknown"; + const icon = { ok: "✅", partial: "⚠️", failed: "❌" }[status] || "❓"; + const ts = (plan.queued_at || "").slice(0, 19).replace("T", " "); + return card(`${icon} Plan ${index + 1}`, + h("p", { class: "caption" }, plan.request || ""), + h("p", { class: "caption" }, `${ts} · ${(plan.actions || []).length} action(s) · ${status}`), + expander("Actions", ...(plan.actions || []).map((a) => h("p", { class: "caption" }, actionSummary(a)))), + (plan.results || []).length ? expander("Results", ...plan.results.map((res) => + h("p", { class: "caption" }, + `${res.ok ? "✅" : "❌"} ${actionSummary({ kind: res.kind })}` + + (res.detail ? ` — ${res.detail}` : "")))) : null); + })))); + } + + container.append(root); +} diff --git a/apps/ui/src/twfarmbot_ui/static/js/views/io.js b/apps/ui/src/twfarmbot_ui/static/js/views/io.js new file mode 100644 index 0000000..8a407e6 --- /dev/null +++ b/apps/ui/src/twfarmbot_ui/static/js/views/io.js @@ -0,0 +1,110 @@ +import { api, postAction, errorMessage } from "../api.js"; +import { h, btn, snack, page, section, card, toolbar, stack, split, emptyState } from "../ui.js"; + +async function writePin(pin, value, mode, seconds) { + const params = { pin, value, mode }; + if (seconds !== undefined) params.seconds = seconds; + const r = await postAction("write_pin", params); + if (r.ok) snack(`pin ${pin} = ${value}`); + else snack(errorMessage(r), { error: true }); +} + +export async function render(container) { + const { root, body } = page("I/O workspace"); + const r = await api("/pins"); + const pins = (r.ok && r.body?.pins) || []; + const sensors = pins.filter((p) => p.kind === "sensor"); + const outputs = pins.filter((p) => p.kind !== "sensor"); + + const sensorGrid = h("div", { class: "metric-grid" }); + body.append( + section("Sensors", sensors.length ? sensorGrid : emptyState("No sensor pins configured.", { iconName: "sensors", compact: true })), + section("Actuators", split( + card("Irrigation", (() => { + const secondsField = h("md-outlined-text-field", { + label: "Duration (seconds)", type: "number", value: "2", min: "0.1", max: "300", step: "0.5", class: "field-sm", + }); + return stack( + toolbar(secondsField, btn("filled", { + icon: "water_drop", + onClick: async () => { + const seconds = parseFloat(secondsField.value); + if (!Number.isFinite(seconds) || seconds <= 0) { snack("Enter a positive duration.", { error: true }); return; } + const res = await postAction("water", { seconds }); + if (res.ok) snack("Watering queued"); + else snack(errorMessage(res), { error: true }); + }, + }, "Water")), + h("p", { class: "caption" }, "Runs the pump for the selected duration.")); + })()), + card("Peripheral control", (() => { + const peripheralBody = h("div", { class: "stack" }); + if (!outputs.length) return emptyState("No output pins configured.", { iconName: "electrical_services", compact: true }); + const select = h("md-outlined-select", { label: "Output", class: "grow" }, + outputs.map((p, i) => h("md-select-option", { value: String(i), selected: i === 0 }, + h("div", { slot: "headline" }, `${p.label} · pin ${p.pin}`)))); + select.addEventListener("change", () => drawControls(outputs[Number(select.value)])); + function drawControls(sel) { + const mode = sel.mode || "digital"; + const parts = [h("span", { class: "pill" }, mode)]; + if (mode === "analog") { + const presets = sel.presets || {}; + if (Object.keys(presets).length) { + parts.push(toolbar(...Object.entries(presets) + .sort(([a], [b]) => Number(a) - Number(b)) + .map(([value, label]) => h("md-filled-tonal-button", { + onClick: () => writePin(sel.pin, Number(value), mode), + }, `${label} (${value})`)))); + } + const slider = h("md-slider", { min: 0, max: 255, value: 0, labeled: true }); + parts.push(toolbar(slider, h("md-outlined-button", { + onClick: () => writePin(sel.pin, Number(slider.value), mode), + }, "Apply"))); + } else { + const pulseSwitch = h("md-switch", { selected: true }); + const pulseField = h("md-outlined-text-field", { + label: "Pulse (seconds)", type: "number", value: "2", min: "0.1", max: "300", step: "0.5", class: "field-sm", + }); + pulseSwitch.addEventListener("change", () => { pulseField.style.display = pulseSwitch.selected ? "" : "none"; }); + parts.push( + h("label", { class: "toolbar" }, pulseSwitch, h("span", {}, "Timed pulse")), + pulseField, + toolbar( + btn("outlined", { icon: "power_settings_new", onClick: () => writePin(sel.pin, 0, mode) }, "OFF"), + btn("filled", { + icon: "power", + onClick: () => { + if (pulseSwitch.selected) { + const seconds = parseFloat(pulseField.value); + if (!Number.isFinite(seconds) || seconds <= 0) { snack("Enter a positive pulse duration.", { error: true }); return; } + writePin(sel.pin, 1, mode, seconds); + } else writePin(sel.pin, 1, mode); + }, + }, "ON"))); + } + peripheralBody.replaceChildren(...parts); + } + drawControls(outputs[0]); + return stack(select, peripheralBody); + })()), + )), + ); + container.append(root); + + sensorGrid.replaceChildren(...sensors.map((sensor) => { + const valueBox = h("div", { class: "metric-value", style: "font-size:20px" }, "—"); + return card(sensor.label, stack( + h("div", { class: "toolbar" }, + h("span", { class: "pill" }, sensor.mode || "analog"), + h("span", { class: "caption" }, `pin ${sensor.pin}`)), + valueBox, + btn("outlined", { + icon: "sensors", + onClick: async () => { + const res = await api(`/pin/${sensor.pin}`, { params: { mode: sensor.mode || "analog" } }); + valueBox.textContent = res.ok ? String(res.body?.value ?? "—") : "—"; + if (!res.ok) snack(errorMessage(res), { error: true }); + }, + }, "Read"))); + })); +} diff --git a/apps/ui/src/twfarmbot_ui/static/js/views/motion.js b/apps/ui/src/twfarmbot_ui/static/js/views/motion.js new file mode 100644 index 0000000..45b0264 --- /dev/null +++ b/apps/ui/src/twfarmbot_ui/static/js/views/motion.js @@ -0,0 +1,112 @@ +import { api, postAction, errorMessage } from "../api.js"; +import { h, btn, snack, page, section, card, toolbar, metricRow, num, flt, parseNumber } from "../ui.js"; +import * as state from "../state.js"; + +async function doMove(x, y, z, label = "") { + const r = await postAction("move", { x, y, z }); + if (r.ok) { snack(label ? `→ ${label}` : `→ (${x.toFixed(0)}, ${y.toFixed(0)}, ${z.toFixed(0)})`); state.refreshPosition(); } + else snack(errorMessage(r), { error: true }); +} + +export async function render(container) { + const { root, body } = page("Motion workspace"); + const posBox = h("div"); + const presetsBox = h("div", { class: "toolbar" }); + let step = 10; + + const cur = () => ({ + x: flt(state.store.position?.x), y: flt(state.store.position?.y), z: flt(state.store.position?.z), + }); + + const stepChips = h("md-chip-set", { class: "chip-row" }, [1, 10, 50, 100].map((value) => + h("md-filter-chip", { + label: `${value} mm`, selected: value === step, + onClick: (e) => { + e.preventDefault(); + step = value; + for (const chip of stepChips.querySelectorAll("md-filter-chip")) chip.selected = chip.label === `${value} mm`; + }, + }))); + + const jog = (dx, dy, dz, label) => () => { + const { x, y, z } = cur(); + doMove(x + dx * step, y + dy * step, z + dz * step, `${label}${step}`); + }; + + // XY pad (3×3) plus a separate labelled Z column so nothing floats. + const padBtn = (iconName, onClick, { filled = false, label } = {}) => + h(filled ? "md-filled-icon-button" : "md-filled-tonal-icon-button", + { onClick, "aria-label": label, title: label }, + h("md-icon", {}, iconName)); + + const xyPad = h("div", { class: "dpad" }, + h("span"), padBtn("arrow_upward", jog(0, 1, 0, "Y+"), { label: "Y+" }), h("span"), + padBtn("arrow_back", jog(-1, 0, 0, "X-"), { label: "X−" }), + padBtn("home", () => doMove(0, 0, 0, "Home"), { filled: true, label: "Home" }), + padBtn("arrow_forward", jog(1, 0, 0, "X+"), { label: "X+" }), + h("span"), padBtn("arrow_downward", jog(0, -1, 0, "Y-"), { label: "Y−" }), h("span")); + + const zCol = h("div", { class: "z-col" }, + padBtn("keyboard_arrow_up", jog(0, 0, 1, "Z+"), { label: "Z+" }), + h("span", { class: "z-label" }, "Z"), + padBtn("keyboard_arrow_down", jog(0, 0, -1, "Z-"), { label: "Z−" })); + + const fx = h("md-outlined-text-field", { label: "X", class: "field-sm" }); + const fy = h("md-outlined-text-field", { label: "Y", class: "field-sm" }); + const fz = h("md-outlined-text-field", { label: "Z", class: "field-sm" }); + const syncFields = () => { + const { x, y, z } = cur(); + fx.value = x.toFixed(2); fy.value = y.toFixed(2); fz.value = z.toFixed(2); + }; + + body.append( + section(null, posBox), + h("div", { class: "split", style: "--split-ratio:1fr 1fr" }, + card("Jog controls", + stepChips, + h("div", { class: "jog-area" }, xyPad, zCol)), + card("Absolute move", + toolbar(fx, fy, fz), + toolbar( + btn("filled", { + icon: "my_location", + onClick: () => { + const [x, y, z] = [parseNumber(fx.value), parseNumber(fy.value), parseNumber(fz.value)]; + if (x === null || y === null || z === null) { + snack("Invalid coordinates. Use a number like 123 or 123.4.", { error: true }); + return; + } + doMove(x, y, z); + }, + }, "Go to"), + btn("outlined", { + icon: "home_work", + onClick: async () => { + const r = await postAction("find_home"); + if (r.ok) snack("Homing queued"); + else snack(errorMessage(r), { error: true }); + }, + }, "Find home")))), + section("Preset locations", presetsBox), + ); + container.append(root); + syncFields(); + + function updatePos() { + const pos = state.store.position || {}; + posBox.replaceChildren(metricRow([["X · mm", num(pos.x)], ["Y · mm", num(pos.y)], ["Z · mm", num(pos.z)]])); + syncFields(); + } + updatePos(); + + const r = await api("/positions"); + const presets = (r.ok && r.body?.positions) || []; + presetsBox.replaceChildren(...(presets.length + ? presets.map((p) => btn("filled-tonal", { + icon: "place", + onClick: () => doMove(flt(p.x), flt(p.y), flt(p.z), p.label), + }, p.label || "?")) + : [h("p", { class: "caption" }, "No preset locations configured.")])); + + return state.on("position", updatePos); +} diff --git a/apps/ui/src/twfarmbot_ui/static/js/views/overview.js b/apps/ui/src/twfarmbot_ui/static/js/views/overview.js new file mode 100644 index 0000000..593a051 --- /dev/null +++ b/apps/ui/src/twfarmbot_ui/static/js/views/overview.js @@ -0,0 +1,151 @@ +import Chart from "chart.js/auto"; +import { h, btn, page, section, card, toolbar, metricRow, num, timeAgo } from "../ui.js"; +import * as state from "../state.js"; + +const EXPERIMENT_KEY = "twfb_experiment"; + +function chartConfig(datasets, { yMax } = {}) { + return { + type: "line", + data: { labels: state.store.telemetry.map((s) => s.time), datasets }, + options: { + responsive: true, + maintainAspectRatio: false, + animation: false, + scales: { + x: { grid: { display: false } }, + y: { beginAtZero: true, max: yMax, grid: { color: "rgba(128,128,128,0.1)" } }, + }, + plugins: { legend: { labels: { boxWidth: 12, padding: 16 } } }, + }, + }; +} + +function series(key, label, color) { + return { + label, + data: state.store.telemetry.map((s) => s[key]), + borderColor: color, + backgroundColor: color, + tension: 0.3, + pointRadius: 2, + borderWidth: 2, + }; +} + +export async function render(container) { + const { root, body } = page("Research overview"); + const posBox = h("div"); + const statusBox = h("div"); + const resourceBox = h("div"); + const chartsArea = h("div"); + const networkBox = h("div", { class: "stack" }); + const eventsBox = h("div"); + const charts = []; + let renderedTelemetryLast = null; + let renderedTelemetryLength = -1; + + const refreshBtn = btn("filled-tonal", { + icon: "refresh", + onClick: async () => { + await Promise.all([state.refreshHealth(), state.refreshPosition(), state.refreshStatus()]); + update(); + }, + }, "Refresh status"); + const clearBtn = btn("outlined", { + onClick: () => { state.store.telemetry = []; update(); }, + }, "Clear history"); + + const experiment = JSON.parse(localStorage.getItem(EXPERIMENT_KEY) || "{}"); + const saveExp = (key, value) => { + experiment[key] = value; + localStorage.setItem(EXPERIMENT_KEY, JSON.stringify(experiment)); + }; + + body.append( + section(null, posBox), + section("System status", toolbar(refreshBtn, clearBtn), statusBox), + section("Resources over time", resourceBox, chartsArea), + h("div", { class: "split" }, + card("Network & hardware", networkBox), + card("Recent events", eventsBox)), + section("Experiment", h("div", { class: "form-grid" }, + h("md-outlined-text-field", { label: "Run", value: experiment.run || "", class: "grow", + onInput: (e) => saveExp("run", e.target.value) }), + h("md-outlined-text-field", { label: "Operator", value: experiment.operator || "", class: "grow", + onInput: (e) => saveExp("operator", e.target.value) }), + h("md-outlined-text-field", { label: "Notes", type: "textarea", rows: 2, class: "grow", + value: experiment.notes || "", onInput: (e) => saveExp("notes", e.target.value) }))), + ); + container.append(root); + + function update() { + const pos = state.store.position || {}; + const info = state.store.diag.informational_settings || {}; + const loc = state.store.diag.location_data || {}; + const axes = loc.axis_states || {}; + + posBox.replaceChildren( + metricRow([["X · mm", num(pos.x)], ["Y · mm", num(pos.y)], ["Z · mm", num(pos.z)]]), + h("p", { class: "caption" }, `Position updated ${timeAgo(state.store.lastPositionRefresh)}`)); + + statusBox.replaceChildren(metricRow([ + ["FarmBot", state.store.health?.farmbot ?? "—"], + ["Uptime", `${num(info.uptime)} s`], + ["Wi-Fi", `${num(info.wifi_level_percent)}%`], + ["Sync", info.sync_status ?? "—"], + ["Busy", info.busy ? "Yes" : "No"], + ])); + + resourceBox.replaceChildren(metricRow([ + ["CPU", info.cpu_usage != null ? `${info.cpu_usage}%` : "—"], + ["Memory", info.memory_usage != null ? `${info.memory_usage}%` : "—"], + ["Disk", info.disk_usage != null ? `${info.disk_usage}%` : "—"], + ["SoC temp", info.soc_temp != null ? `${info.soc_temp}°C` : "—"], + ])); + + networkBox.replaceChildren( + h("p", { class: "caption" }, "Private IP: ", h("span", { class: "mono" }, info.private_ip ?? "—")), + h("p", { class: "caption" }, `Wi-Fi signal: ${num(info.wifi_level)} dBm`), + h("p", { class: "caption" }, `Controller: ${info.controller_version ?? "—"}`), + h("p", { class: "caption" }, `Firmware: ${info.firmware_version ?? "—"}`), + h("p", { class: "caption" }, + `Axis states · X ${axes.x ?? "—"} · Y ${axes.y ?? "—"} · Z ${axes.z ?? "—"}`)); + + const messages = state.store.messages; + eventsBox.replaceChildren(messages.length + ? h("pre", { class: "codeblock" }, messages.slice(-10).join("\n")) + : h("p", { class: "caption" }, "No events recorded.")); + + const telemetry = state.store.telemetry; + const telemetryLast = telemetry.at(-1); + if (telemetry.length === renderedTelemetryLength && telemetryLast === renderedTelemetryLast) { + return; + } + renderedTelemetryLength = telemetry.length; + renderedTelemetryLast = telemetryLast; + + charts.forEach((c) => c.destroy()); + charts.length = 0; + if (telemetry.length) { + const usageBox = h("div", { class: "chart-box tall" }, h("canvas")); + const wifiBox = h("div", { class: "chart-box" }, h("canvas")); + const socBox = h("div", { class: "chart-box" }, h("canvas")); + chartsArea.replaceChildren(usageBox, h("div", { class: "split", style: "--split-ratio:1fr 1fr" }, wifiBox, socBox)); + charts.push( + new Chart(usageBox.firstChild, chartConfig( + [series("cpu", "CPU", "#554fd8"), series("memory", "Memory", "#2685c7"), series("disk", "Disk", "#d35d7b")], + { yMax: 100 })), + new Chart(wifiBox.firstChild, chartConfig([series("wifi", "Wi-Fi %", "#2685c7")], { yMax: 100 })), + new Chart(socBox.firstChild, chartConfig([series("soc", "SoC °C", "#ba1a1a")]))); + } else { + chartsArea.replaceChildren(h("p", { class: "caption" }, + "Click “Refresh status” to start collecting telemetry for the charts.")); + } + } + + update(); + const offs = [state.on("position", update), state.on("status", update), + state.on("health", update), state.on("messages", update)]; + return () => { offs.forEach((off) => off()); charts.forEach((c) => c.destroy()); }; +} diff --git a/apps/ui/src/twfarmbot_ui/static/js/views/settings.js b/apps/ui/src/twfarmbot_ui/static/js/views/settings.js new file mode 100644 index 0000000..a8656b0 --- /dev/null +++ b/apps/ui/src/twfarmbot_ui/static/js/views/settings.js @@ -0,0 +1,72 @@ +import { ui, postAction, errorMessage, getSettings, saveSettings } from "../api.js"; +import { h, btn, snack, page, section, card, toolbar, expander, jsonBlock } from "../ui.js"; +import * as state from "../state.js"; + +export async function render(container) { + const { root, body } = page("Settings"); + const config = await ui("/config"); + const apiField = h("md-outlined-text-field", { + label: "API URL", value: (config.ok && config.body?.api_url) || "", class: "grow", + }); + const statusBox = h("div"); + + const drawStatus = () => statusBox.replaceChildren(jsonBlock({ + farmbot: state.store.health?.farmbot ?? "?", + api: apiField.value, + actions: state.store.health?.actions ?? [], + })); + + body.append( + section("Connection", toolbar(apiField, + btn("outlined", { + onClick: async () => { + const r = await ui("/config", { method: "PUT", json: { api_url: apiField.value } }); + if (!r.ok) { snack(errorMessage(r), { error: true }); return; } + await state.refreshHealth(); + snack("API URL updated"); + drawStatus(); + }, + }, "Apply"), + btn("filled-tonal", { + icon: "ecg_heart", + onClick: async () => { await state.refreshHealth(); drawStatus(); snack("Health checked"); }, + }, "Health check")), + statusBox), + section("Auto-refresh intervals", (() => { + const settings = getSettings(); + const field = (label, key, min, max) => h("md-outlined-text-field", { + label, type: "number", value: String(settings[key]), min: String(min), max: String(max), class: "field-sm", + onChange: (e) => { + const value = parseInt(e.target.value, 10); + if (Number.isFinite(value)) { saveSettings({ [key]: value }); snack("Saved"); } + }, + }); + return toolbar( + field("Position (s)", "refreshPositionS", 1, 300), + field("Stats (s)", "refreshStatsS", 10, 3600), + field("Camera (s, 0=off)", "refreshCameraS", 0, 3600)); + })()), + section("Raw action", expander("Fire a raw action", (() => { + const kindField = h("md-outlined-text-field", { label: "Kind", value: "move", class: "field-sm" }); + const paramsField = h("md-outlined-text-field", { + label: "Params (JSON)", type: "textarea", rows: 3, + value: '{"x": 0, "y": 0, "z": 0}', class: "grow", + }); + const resultBox = h("div"); + return card(null, toolbar(kindField, paramsField, + btn("filled", { + icon: "bolt", + onClick: async () => { + let params; + try { params = JSON.parse(paramsField.value); } + catch (err) { snack(`Bad JSON: ${err.message}`, { error: true }); return; } + const r = await postAction(kindField.value.trim(), params); + resultBox.replaceChildren(jsonBlock(r.body)); + }, + }, "Fire")), + resultBox); + })())), + ); + container.append(root); + drawStatus(); +} diff --git a/apps/ui/src/twfarmbot_ui/static/vendor/@material/web/all.js b/apps/ui/src/twfarmbot_ui/static/vendor/@material/web/all.js new file mode 100644 index 0000000..e9b8829 --- /dev/null +++ b/apps/ui/src/twfarmbot_ui/static/vendor/@material/web/all.js @@ -0,0 +1,881 @@ +/** + * Bundled by jsDelivr using Rollup v4.62.2 and esbuild v0.28.1. + * Original file: /npm/@material/web@2.4.0/all.js + * + * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files + */ +import{__decorate as o}from"/npm/tslib@2.8.1/+esm";import{customElement as b,property as l,state as k,query as g,queryAssignedElements as H,queryAll as fo,queryAssignedNodes as Qt,queryAsync as xr}from"/npm/lit@3.3.1/decorators.js/+esm";import{LitElement as _,html as d,css as v,isServer as T,nothing as c,render as _r}from"/npm/lit@3.3.1/+esm";import{classMap as S}from"/npm/lit@3.3.1/directives/class-map.js/+esm";import{literal as K,html as ze}from"/npm/lit@3.3.1/static-html.js/+esm";import{styleMap as fe}from"/npm/lit@3.3.1/directives/style-map.js/+esm";import{when as Jt}from"/npm/lit@3.3.1/directives/when.js/+esm";import{live as wr}from"/npm/lit@3.3.1/directives/live.js/+esm";class mo extends _{connectedCallback(){super.connectedCallback(),this.setAttribute("aria-hidden","true")}render(){return d``}}const bo=v`:host,.shadow,.shadow::before,.shadow::after{border-radius:inherit;inset:0;position:absolute;transition-duration:inherit;transition-property:inherit;transition-timing-function:inherit}:host{display:flex;pointer-events:none;transition-property:box-shadow,opacity}.shadow::before,.shadow::after{content:"";transition-property:box-shadow,opacity;--_level: var(--md-elevation-level, 0);--_shadow-color: var(--md-elevation-shadow-color, var(--md-sys-color-shadow, #000))}.shadow::before{box-shadow:0px calc(1px*(clamp(0,var(--_level),1) + clamp(0,var(--_level) - 3,1) + 2*clamp(0,var(--_level) - 4,1))) calc(1px*(2*clamp(0,var(--_level),1) + clamp(0,var(--_level) - 2,1) + clamp(0,var(--_level) - 4,1))) 0px var(--_shadow-color);opacity:.3}.shadow::after{box-shadow:0px calc(1px*(clamp(0,var(--_level),1) + clamp(0,var(--_level) - 1,1) + 2*clamp(0,var(--_level) - 2,3))) calc(1px*(3*clamp(0,var(--_level),2) + 2*clamp(0,var(--_level) - 2,3))) calc(1px*(clamp(0,var(--_level),4) + 2*clamp(0,var(--_level) - 4,1))) var(--_shadow-color);opacity:.15} +`;let Ne=class extends mo{};Ne.styles=[bo],Ne=o([b("md-elevation")],Ne);const kr=Symbol("attachableController");let Cr;T||(Cr=new MutationObserver(i=>{for(const e of i)e.target[kr]?.hostConnected()}));class Er{get htmlFor(){return this.host.getAttribute("for")}set htmlFor(e){e===null?this.host.removeAttribute("for"):this.host.setAttribute("for",e)}get control(){return this.host.hasAttribute("for")?!this.htmlFor||!this.host.isConnected?null:this.host.getRootNode().querySelector(`#${this.htmlFor}`):this.currentControl||this.host.parentElement}set control(e){e?this.attach(e):this.detach()}constructor(e,t){this.host=e,this.onControlChange=t,this.currentControl=null,e.addController(this),e[kr]=this,Cr?.observe(e,{attributeFilter:["for"]})}attach(e){e!==this.currentControl&&(this.setCurrentControl(e),this.host.removeAttribute("for"))}detach(){this.setCurrentControl(null),this.host.setAttribute("for","")}hostConnected(){this.setCurrentControl(this.control)}hostDisconnected(){this.setCurrentControl(null)}setCurrentControl(e){this.onControlChange(this.currentControl,e),this.currentControl=e}}const yo=["focusin","focusout","pointerdown"];class er extends _{constructor(){super(...arguments),this.visible=!1,this.inward=!1,this.attachableController=new Er(this,this.onControlChange.bind(this))}get htmlFor(){return this.attachableController.htmlFor}set htmlFor(e){this.attachableController.htmlFor=e}get control(){return this.attachableController.control}set control(e){this.attachableController.control=e}attach(e){this.attachableController.attach(e)}detach(){this.attachableController.detach()}connectedCallback(){super.connectedCallback(),this.setAttribute("aria-hidden","true")}handleEvent(e){if(!e[Ir]){switch(e.type){default:return;case"focusin":this.visible=this.control?.matches(":focus-visible")??!1;break;case"focusout":case"pointerdown":this.visible=!1;break}e[Ir]=!0}}onControlChange(e,t){if(!T)for(const r of yo)e?.removeEventListener(r,this),t?.addEventListener(r,this)}update(e){e.has("visible")&&this.dispatchEvent(new Event("visibility-changed")),super.update(e)}}o([l({type:Boolean,reflect:!0})],er.prototype,"visible",void 0),o([l({type:Boolean,reflect:!0})],er.prototype,"inward",void 0);const Ir=Symbol("handledByFocusRing");const go=v`:host{animation-delay:0s,calc(var(--md-focus-ring-duration, 600ms)*.25);animation-duration:calc(var(--md-focus-ring-duration, 600ms)*.25),calc(var(--md-focus-ring-duration, 600ms)*.75);animation-timing-function:cubic-bezier(0.2, 0, 0, 1);box-sizing:border-box;color:var(--md-focus-ring-color, var(--md-sys-color-secondary, #625b71));display:none;pointer-events:none;position:absolute}:host([visible]){display:flex}:host(:not([inward])){animation-name:outward-grow,outward-shrink;border-end-end-radius:calc(var(--md-focus-ring-shape-end-end, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) + var(--md-focus-ring-outward-offset, 2px));border-end-start-radius:calc(var(--md-focus-ring-shape-end-start, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) + var(--md-focus-ring-outward-offset, 2px));border-start-end-radius:calc(var(--md-focus-ring-shape-start-end, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) + var(--md-focus-ring-outward-offset, 2px));border-start-start-radius:calc(var(--md-focus-ring-shape-start-start, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) + var(--md-focus-ring-outward-offset, 2px));inset:calc(-1*var(--md-focus-ring-outward-offset, 2px));outline:var(--md-focus-ring-width, 3px) solid currentColor}:host([inward]){animation-name:inward-grow,inward-shrink;border-end-end-radius:calc(var(--md-focus-ring-shape-end-end, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) - var(--md-focus-ring-inward-offset, 0px));border-end-start-radius:calc(var(--md-focus-ring-shape-end-start, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) - var(--md-focus-ring-inward-offset, 0px));border-start-end-radius:calc(var(--md-focus-ring-shape-start-end, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) - var(--md-focus-ring-inward-offset, 0px));border-start-start-radius:calc(var(--md-focus-ring-shape-start-start, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) - var(--md-focus-ring-inward-offset, 0px));border:var(--md-focus-ring-width, 3px) solid currentColor;inset:var(--md-focus-ring-inward-offset, 0px)}@keyframes outward-grow{from{outline-width:0}to{outline-width:var(--md-focus-ring-active-width, 8px)}}@keyframes outward-shrink{from{outline-width:var(--md-focus-ring-active-width, 8px)}}@keyframes inward-grow{from{border-width:0}to{border-width:var(--md-focus-ring-active-width, 8px)}}@keyframes inward-shrink{from{border-width:var(--md-focus-ring-active-width, 8px)}}@media(prefers-reduced-motion){:host{animation:none}} +`;let Ve=class extends er{};Ve.styles=[go],Ve=o([b("md-focus-ring")],Ve);const Z={STANDARD:"cubic-bezier(0.2, 0, 0, 1)",EMPHASIZED:"cubic-bezier(.3,0,0,1)",EMPHASIZED_ACCELERATE:"cubic-bezier(.3,0,.8,.15)"};function xo(){let i=null;return{start(){return i?.abort(),i=new AbortController,i.signal},finish(){i=null}}}const _o=450,Tr=225,wo=.2,ko=10,Co=75,Eo=.35,Io="::after",To="forwards";var U;(function(i){i[i.INACTIVE=0]="INACTIVE",i[i.TOUCH_DELAY=1]="TOUCH_DELAY",i[i.HOLDING=2]="HOLDING",i[i.WAITING_FOR_CLICK=3]="WAITING_FOR_CLICK"})(U||(U={}));const zo=["click","contextmenu","pointercancel","pointerdown","pointerenter","pointerleave","pointerup"],Ao=150,So=T?null:window.matchMedia("(forced-colors: active)");class Ae extends _{constructor(){super(...arguments),this.disabled=!1,this.hovered=!1,this.pressed=!1,this.rippleSize="",this.rippleScale="",this.initialSize=0,this.state=U.INACTIVE,this.attachableController=new Er(this,this.onControlChange.bind(this))}get htmlFor(){return this.attachableController.htmlFor}set htmlFor(e){this.attachableController.htmlFor=e}get control(){return this.attachableController.control}set control(e){this.attachableController.control=e}attach(e){this.attachableController.attach(e)}detach(){this.attachableController.detach()}connectedCallback(){super.connectedCallback(),this.setAttribute("aria-hidden","true")}render(){const e={hovered:this.hovered,pressed:this.pressed};return d`
`}update(e){e.has("disabled")&&this.disabled&&(this.hovered=!1,this.pressed=!1),super.update(e)}handlePointerenter(e){this.shouldReactToEvent(e)&&(this.hovered=!0)}handlePointerleave(e){this.shouldReactToEvent(e)&&(this.hovered=!1,this.state!==U.INACTIVE&&this.endPressAnimation())}handlePointerup(e){if(this.shouldReactToEvent(e)){if(this.state===U.HOLDING){this.state=U.WAITING_FOR_CLICK;return}if(this.state===U.TOUCH_DELAY){this.state=U.WAITING_FOR_CLICK,this.startPressAnimation(this.rippleStartEvent);return}}}async handlePointerdown(e){if(this.shouldReactToEvent(e)){if(this.rippleStartEvent=e,!this.isTouch(e)){this.state=U.WAITING_FOR_CLICK,this.startPressAnimation(e);return}this.state=U.TOUCH_DELAY,await new Promise(t=>{setTimeout(t,Ao)}),this.state===U.TOUCH_DELAY&&(this.state=U.HOLDING,this.startPressAnimation(e))}}handleClick(){if(!this.disabled){if(this.state===U.WAITING_FOR_CLICK){this.endPressAnimation();return}this.state===U.INACTIVE&&(this.startPressAnimation(),this.endPressAnimation())}}handlePointercancel(e){this.shouldReactToEvent(e)&&this.endPressAnimation()}handleContextmenu(){this.disabled||this.endPressAnimation()}determineRippleSize(){const{height:e,width:t}=this.getBoundingClientRect(),r=Math.max(e,t),a=Math.max(Eo*r,Co),n=this.currentCSSZoom??1,s=Math.floor(r*wo/n),p=Math.sqrt(t**2+e**2)+ko;this.initialSize=s;const y=(p+a)/s;this.rippleScale=`${y/n}`,this.rippleSize=`${s}px`}getNormalizedPointerEventCoords(e){const{scrollX:t,scrollY:r}=window,{left:a,top:n}=this.getBoundingClientRect(),s=t+a,h=r+n,{pageX:p,pageY:y}=e,u=this.currentCSSZoom??1;return{x:(p-s)/u,y:(y-h)/u}}getTranslationCoordinates(e){const{height:t,width:r}=this.getBoundingClientRect(),a=this.currentCSSZoom??1,n={x:(r/a-this.initialSize)/2,y:(t/a-this.initialSize)/2};let s;return e instanceof PointerEvent?s=this.getNormalizedPointerEventCoords(e):s={x:r/a/2,y:t/a/2},s={x:s.x-this.initialSize/2,y:s.y-this.initialSize/2},{startPoint:s,endPoint:n}}startPressAnimation(e){if(!this.mdRoot)return;this.pressed=!0,this.growAnimation?.cancel(),this.determineRippleSize();const{startPoint:t,endPoint:r}=this.getTranslationCoordinates(e),a=`${t.x}px, ${t.y}px`,n=`${r.x}px, ${r.y}px`;this.growAnimation=this.mdRoot.animate({top:[0,0],left:[0,0],height:[this.rippleSize,this.rippleSize],width:[this.rippleSize,this.rippleSize],transform:[`translate(${a}) scale(1)`,`translate(${n}) scale(${this.rippleScale})`]},{pseudoElement:Io,duration:_o,easing:Z.STANDARD,fill:To})}async endPressAnimation(){this.rippleStartEvent=void 0,this.state=U.INACTIVE;const e=this.growAnimation;let t=1/0;if(typeof e?.currentTime=="number"?t=e.currentTime:e?.currentTime&&(t=e.currentTime.to("ms").value),t>=Tr){this.pressed=!1;return}await new Promise(r=>{setTimeout(r,Tr-t)}),this.growAnimation===e&&(this.pressed=!1)}shouldReactToEvent(e){if(this.disabled||!e.isPrimary||this.rippleStartEvent&&this.rippleStartEvent.pointerId!==e.pointerId)return!1;if(e.type==="pointerenter"||e.type==="pointerleave")return!this.isTouch(e);const t=e.buttons===1;return this.isTouch(e)||t}isTouch({pointerType:e}){return e==="touch"}async handleEvent(e){if(!So?.matches)switch(e.type){case"click":this.handleClick();break;case"contextmenu":this.handleContextmenu();break;case"pointercancel":this.handlePointercancel(e);break;case"pointerdown":await this.handlePointerdown(e);break;case"pointerenter":this.handlePointerenter(e);break;case"pointerleave":this.handlePointerleave(e);break;case"pointerup":this.handlePointerup(e);break}}onControlChange(e,t){if(!T)for(const r of zo)e?.removeEventListener(r,this),t?.addEventListener(r,this)}}o([l({type:Boolean,reflect:!0})],Ae.prototype,"disabled",void 0),o([k()],Ae.prototype,"hovered",void 0),o([k()],Ae.prototype,"pressed",void 0),o([g(".surface")],Ae.prototype,"mdRoot",void 0);const $o=v`:host{display:flex;margin:auto;pointer-events:none}:host([disabled]){display:none}@media(forced-colors: active){:host{display:none}}:host,.surface{border-radius:inherit;position:absolute;inset:0;overflow:hidden}.surface{-webkit-tap-highlight-color:rgba(0,0,0,0)}.surface::before,.surface::after{content:"";opacity:0;position:absolute}.surface::before{background-color:var(--md-ripple-hover-color, var(--md-sys-color-on-surface, #1d1b20));inset:0;transition:opacity 15ms linear,background-color 15ms linear}.surface::after{background:radial-gradient(closest-side, var(--md-ripple-pressed-color, var(--md-sys-color-on-surface, #1d1b20)) max(100% - 70px, 65%), transparent 100%);transform-origin:center center;transition:opacity 375ms linear}.hovered::before{background-color:var(--md-ripple-hover-color, var(--md-sys-color-on-surface, #1d1b20));opacity:var(--md-ripple-hover-opacity, 0.08)}.pressed::after{opacity:var(--md-ripple-pressed-opacity, 0.12);transition-duration:105ms} +`;let qe=class extends Ae{};qe.styles=[$o],qe=o([b("md-ripple")],qe);const zr=["role","ariaAtomic","ariaAutoComplete","ariaBusy","ariaChecked","ariaColCount","ariaColIndex","ariaColSpan","ariaCurrent","ariaDisabled","ariaExpanded","ariaHasPopup","ariaHidden","ariaInvalid","ariaKeyShortcuts","ariaLabel","ariaLevel","ariaLive","ariaModal","ariaMultiLine","ariaMultiSelectable","ariaOrientation","ariaPlaceholder","ariaPosInSet","ariaPressed","ariaReadOnly","ariaRequired","ariaRoleDescription","ariaRowCount","ariaRowIndex","ariaRowSpan","ariaSelected","ariaSetSize","ariaSort","ariaValueMax","ariaValueMin","ariaValueNow","ariaValueText"],Ro=zr.map(Ar);function tr(i){return Ro.includes(i)}function Ar(i){return i.replace("aria","aria-").replace(/Elements?/g,"").toLowerCase()}const He=Symbol("privateIgnoreAttributeChangesFor");function W(i){var e;if(T)return i;class t extends i{constructor(){super(...arguments),this[e]=new Set}attributeChangedCallback(a,n,s){if(!tr(a)){super.attributeChangedCallback(a,n,s);return}if(this[He].has(a))return;this[He].add(a),this.removeAttribute(a),this[He].delete(a);const h=or(a);s===null?delete this.dataset[h]:this.dataset[h]=s,this.requestUpdate(or(a),n)}getAttribute(a){return tr(a)?super.getAttribute(rr(a)):super.getAttribute(a)}removeAttribute(a){super.removeAttribute(a),tr(a)&&(super.removeAttribute(rr(a)),this.requestUpdate())}}return e=He,Oo(t),t}function Oo(i){for(const e of zr){const t=Ar(e),r=rr(t),a=or(t);i.createProperty(e,{attribute:t,noAccessor:!0}),i.createProperty(Symbol(r),{attribute:r,noAccessor:!0}),Object.defineProperty(i.prototype,e,{configurable:!0,enumerable:!0,get(){return this.dataset[a]??null},set(n){const s=this.dataset[a]??null;n!==s&&(n===null?delete this.dataset[a]:this.dataset[a]=n,this.requestUpdate(e,s))}})}}function rr(i){return`data-${i}`}function or(i){return i.replace(/-\w/,e=>e[1].toUpperCase())}const N=Symbol("internals"),ir=Symbol("privateInternals");function se(i){class e extends i{get[N](){return this[ir]||(this[ir]=this.attachInternals()),this[ir]}}return e}function Sr(i){T||i.addInitializer(e=>{const t=e;t.addEventListener("click",async r=>{const{type:a,[N]:n}=t,{form:s}=n;if(!(!s||a==="button")&&(await new Promise(h=>{setTimeout(h)}),!r.defaultPrevented)){if(a==="reset"){s.reset();return}s.addEventListener("submit",h=>{Object.defineProperty(h,"submitter",{configurable:!0,enumerable:!0,get:()=>t})},{capture:!0,once:!0}),n.setFormValue(t.value),s.requestSubmit()}})})}function Ue(i){const e=new MouseEvent("click",{bubbles:!0});return i.dispatchEvent(e),e}function Se(i){return i.currentTarget!==i.target||i.composedPath()[0]!==i.target||i.target.disabled?!1:!Lo(i)}function Lo(i){const e=ar;return e&&(i.preventDefault(),i.stopImmediatePropagation()),Fo(),e}let ar=!1;async function Fo(){ar=!0,await null,ar=!1}const Do=W(se(_));class P extends Do{get name(){return this.getAttribute("name")??""}set name(e){this.setAttribute("name",e)}get form(){return this[N].form}constructor(){super(),this.disabled=!1,this.softDisabled=!1,this.href="",this.download="",this.target="",this.trailingIcon=!1,this.hasIcon=!1,this.type="submit",this.value="",T||this.addEventListener("click",this.handleClick.bind(this))}focus(){this.buttonElement?.focus()}blur(){this.buttonElement?.blur()}render(){const e=this.disabled||this.softDisabled,t=this.href?this.renderLink():this.renderButton(),r=this.href?"link":"button";return d` + ${this.renderElevationOrOutline?.()} +
+ + + ${t} + `}renderButton(){const{ariaLabel:e,ariaHasPopup:t,ariaExpanded:r}=this;return d``}renderLink(){const{ariaLabel:e,ariaHasPopup:t,ariaExpanded:r}=this;return d`${this.renderContent()} + `}renderContent(){const e=d``;return d` + + ${this.trailingIcon?c:e} + + ${this.trailingIcon?e:c} + `}handleClick(e){if(this.softDisabled||this.disabled&&this.href){e.stopImmediatePropagation(),e.preventDefault();return}!Se(e)||!this.buttonElement||(this.focus(),Ue(this.buttonElement))}handleSlotChange(){this.hasIcon=this.assignedIcons.length>0}}Sr(P),P.formAssociated=!0,P.shadowRootOptions={mode:"open",delegatesFocus:!0},o([l({type:Boolean,reflect:!0})],P.prototype,"disabled",void 0),o([l({type:Boolean,attribute:"soft-disabled",reflect:!0})],P.prototype,"softDisabled",void 0),o([l()],P.prototype,"href",void 0),o([l()],P.prototype,"download",void 0),o([l()],P.prototype,"target",void 0),o([l({type:Boolean,attribute:"trailing-icon",reflect:!0})],P.prototype,"trailingIcon",void 0),o([l({type:Boolean,attribute:"has-icon",reflect:!0})],P.prototype,"hasIcon",void 0),o([l()],P.prototype,"type",void 0),o([l({reflect:!0})],P.prototype,"value",void 0),o([g(".button")],P.prototype,"buttonElement",void 0),o([H({slot:"icon",flatten:!0})],P.prototype,"assignedIcons",void 0);class Po extends P{renderElevationOrOutline(){return d``}}const Mo=v`:host{--_container-color: var(--md-elevated-button-container-color, var(--md-sys-color-surface-container-low, #f7f2fa));--_container-elevation: var(--md-elevated-button-container-elevation, 1);--_container-height: var(--md-elevated-button-container-height, 40px);--_container-shadow-color: var(--md-elevated-button-container-shadow-color, var(--md-sys-color-shadow, #000));--_disabled-container-color: var(--md-elevated-button-disabled-container-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-container-elevation: var(--md-elevated-button-disabled-container-elevation, 0);--_disabled-container-opacity: var(--md-elevated-button-disabled-container-opacity, 0.12);--_disabled-label-text-color: var(--md-elevated-button-disabled-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-label-text-opacity: var(--md-elevated-button-disabled-label-text-opacity, 0.38);--_focus-container-elevation: var(--md-elevated-button-focus-container-elevation, 1);--_focus-label-text-color: var(--md-elevated-button-focus-label-text-color, var(--md-sys-color-primary, #6750a4));--_hover-container-elevation: var(--md-elevated-button-hover-container-elevation, 2);--_hover-label-text-color: var(--md-elevated-button-hover-label-text-color, var(--md-sys-color-primary, #6750a4));--_hover-state-layer-color: var(--md-elevated-button-hover-state-layer-color, var(--md-sys-color-primary, #6750a4));--_hover-state-layer-opacity: var(--md-elevated-button-hover-state-layer-opacity, 0.08);--_label-text-color: var(--md-elevated-button-label-text-color, var(--md-sys-color-primary, #6750a4));--_label-text-font: var(--md-elevated-button-label-text-font, var(--md-sys-typescale-label-large-font, var(--md-ref-typeface-plain, Roboto)));--_label-text-line-height: var(--md-elevated-button-label-text-line-height, var(--md-sys-typescale-label-large-line-height, 1.25rem));--_label-text-size: var(--md-elevated-button-label-text-size, var(--md-sys-typescale-label-large-size, 0.875rem));--_label-text-weight: var(--md-elevated-button-label-text-weight, var(--md-sys-typescale-label-large-weight, var(--md-ref-typeface-weight-medium, 500)));--_pressed-container-elevation: var(--md-elevated-button-pressed-container-elevation, 1);--_pressed-label-text-color: var(--md-elevated-button-pressed-label-text-color, var(--md-sys-color-primary, #6750a4));--_pressed-state-layer-color: var(--md-elevated-button-pressed-state-layer-color, var(--md-sys-color-primary, #6750a4));--_pressed-state-layer-opacity: var(--md-elevated-button-pressed-state-layer-opacity, 0.12);--_disabled-icon-color: var(--md-elevated-button-disabled-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-icon-opacity: var(--md-elevated-button-disabled-icon-opacity, 0.38);--_focus-icon-color: var(--md-elevated-button-focus-icon-color, var(--md-sys-color-primary, #6750a4));--_hover-icon-color: var(--md-elevated-button-hover-icon-color, var(--md-sys-color-primary, #6750a4));--_icon-color: var(--md-elevated-button-icon-color, var(--md-sys-color-primary, #6750a4));--_icon-size: var(--md-elevated-button-icon-size, 18px);--_pressed-icon-color: var(--md-elevated-button-pressed-icon-color, var(--md-sys-color-primary, #6750a4));--_container-shape-start-start: var(--md-elevated-button-container-shape-start-start, var(--md-elevated-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-start-end: var(--md-elevated-button-container-shape-start-end, var(--md-elevated-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-end: var(--md-elevated-button-container-shape-end-end, var(--md-elevated-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-start: var(--md-elevated-button-container-shape-end-start, var(--md-elevated-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_leading-space: var(--md-elevated-button-leading-space, 24px);--_trailing-space: var(--md-elevated-button-trailing-space, 24px);--_with-leading-icon-leading-space: var(--md-elevated-button-with-leading-icon-leading-space, 16px);--_with-leading-icon-trailing-space: var(--md-elevated-button-with-leading-icon-trailing-space, 24px);--_with-trailing-icon-leading-space: var(--md-elevated-button-with-trailing-icon-leading-space, 24px);--_with-trailing-icon-trailing-space: var(--md-elevated-button-with-trailing-icon-trailing-space, 16px)} +`;const lr=v`md-elevation{transition-duration:280ms}:host(:is([disabled],[soft-disabled])) md-elevation{transition:none}md-elevation{--md-elevation-level: var(--_container-elevation);--md-elevation-shadow-color: var(--_container-shadow-color)}:host(:focus-within) md-elevation{--md-elevation-level: var(--_focus-container-elevation)}:host(:hover) md-elevation{--md-elevation-level: var(--_hover-container-elevation)}:host(:active) md-elevation{--md-elevation-level: var(--_pressed-container-elevation)}:host(:is([disabled],[soft-disabled])) md-elevation{--md-elevation-level: var(--_disabled-container-elevation)} +`;const $e=v`:host{border-start-start-radius:var(--_container-shape-start-start);border-start-end-radius:var(--_container-shape-start-end);border-end-start-radius:var(--_container-shape-end-start);border-end-end-radius:var(--_container-shape-end-end);box-sizing:border-box;cursor:pointer;display:inline-flex;gap:8px;min-height:var(--_container-height);outline:none;padding-block:calc((var(--_container-height) - max(var(--_label-text-line-height),var(--_icon-size)))/2);padding-inline-start:var(--_leading-space);padding-inline-end:var(--_trailing-space);place-content:center;place-items:center;position:relative;font-family:var(--_label-text-font);font-size:var(--_label-text-size);line-height:var(--_label-text-line-height);font-weight:var(--_label-text-weight);text-overflow:ellipsis;text-wrap:nowrap;user-select:none;-webkit-tap-highlight-color:rgba(0,0,0,0);vertical-align:top;--md-ripple-hover-color: var(--_hover-state-layer-color);--md-ripple-pressed-color: var(--_pressed-state-layer-color);--md-ripple-hover-opacity: var(--_hover-state-layer-opacity);--md-ripple-pressed-opacity: var(--_pressed-state-layer-opacity)}md-focus-ring{--md-focus-ring-shape-start-start: var(--_container-shape-start-start);--md-focus-ring-shape-start-end: var(--_container-shape-start-end);--md-focus-ring-shape-end-end: var(--_container-shape-end-end);--md-focus-ring-shape-end-start: var(--_container-shape-end-start)}:host(:is([disabled],[soft-disabled])){cursor:default;pointer-events:none}.button{border-radius:inherit;cursor:inherit;display:inline-flex;align-items:center;justify-content:center;border:none;outline:none;-webkit-appearance:none;vertical-align:middle;background:rgba(0,0,0,0);text-decoration:none;min-width:calc(64px - var(--_leading-space) - var(--_trailing-space));width:100%;z-index:0;height:100%;font:inherit;color:var(--_label-text-color);padding:0;gap:inherit;text-transform:inherit}.button::-moz-focus-inner{padding:0;border:0}:host(:hover) .button{color:var(--_hover-label-text-color)}:host(:focus-within) .button{color:var(--_focus-label-text-color)}:host(:active) .button{color:var(--_pressed-label-text-color)}.background{background:var(--_container-color);border-radius:inherit;inset:0;position:absolute}.label{overflow:hidden}:is(.button,.label,.label slot),.label ::slotted(*){text-overflow:inherit}:host(:is([disabled],[soft-disabled])) .label{color:var(--_disabled-label-text-color);opacity:var(--_disabled-label-text-opacity)}:host(:is([disabled],[soft-disabled])) .background{background:var(--_disabled-container-color);opacity:var(--_disabled-container-opacity)}@media(forced-colors: active){.background{border:1px solid CanvasText}:host(:is([disabled],[soft-disabled])){--_disabled-icon-color: GrayText;--_disabled-icon-opacity: 1;--_disabled-container-opacity: 1;--_disabled-label-text-color: GrayText;--_disabled-label-text-opacity: 1}}:host([has-icon]:not([trailing-icon])){padding-inline-start:var(--_with-leading-icon-leading-space);padding-inline-end:var(--_with-leading-icon-trailing-space)}:host([has-icon][trailing-icon]){padding-inline-start:var(--_with-trailing-icon-leading-space);padding-inline-end:var(--_with-trailing-icon-trailing-space)}::slotted([slot=icon]){display:inline-flex;position:relative;writing-mode:horizontal-tb;fill:currentColor;flex-shrink:0;color:var(--_icon-color);font-size:var(--_icon-size);inline-size:var(--_icon-size);block-size:var(--_icon-size)}:host(:hover) ::slotted([slot=icon]){color:var(--_hover-icon-color)}:host(:focus-within) ::slotted([slot=icon]){color:var(--_focus-icon-color)}:host(:active) ::slotted([slot=icon]){color:var(--_pressed-icon-color)}:host(:is([disabled],[soft-disabled])) ::slotted([slot=icon]){color:var(--_disabled-icon-color);opacity:var(--_disabled-icon-opacity)}.touch{position:absolute;top:50%;height:48px;left:0;right:0;transform:translateY(-50%)}:host([touch-target=wrapper]){margin:max(0px,(48px - var(--_container-height))/2) 0}:host([touch-target=none]) .touch{display:none} +`;let Ke=class extends Po{};Ke.styles=[$e,lr,Mo],Ke=o([b("md-elevated-button")],Ke);class Bo extends P{renderElevationOrOutline(){return d``}}const No=v`:host{--_container-color: var(--md-filled-button-container-color, var(--md-sys-color-primary, #6750a4));--_container-elevation: var(--md-filled-button-container-elevation, 0);--_container-height: var(--md-filled-button-container-height, 40px);--_container-shadow-color: var(--md-filled-button-container-shadow-color, var(--md-sys-color-shadow, #000));--_disabled-container-color: var(--md-filled-button-disabled-container-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-container-elevation: var(--md-filled-button-disabled-container-elevation, 0);--_disabled-container-opacity: var(--md-filled-button-disabled-container-opacity, 0.12);--_disabled-label-text-color: var(--md-filled-button-disabled-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-label-text-opacity: var(--md-filled-button-disabled-label-text-opacity, 0.38);--_focus-container-elevation: var(--md-filled-button-focus-container-elevation, 0);--_focus-label-text-color: var(--md-filled-button-focus-label-text-color, var(--md-sys-color-on-primary, #fff));--_hover-container-elevation: var(--md-filled-button-hover-container-elevation, 1);--_hover-label-text-color: var(--md-filled-button-hover-label-text-color, var(--md-sys-color-on-primary, #fff));--_hover-state-layer-color: var(--md-filled-button-hover-state-layer-color, var(--md-sys-color-on-primary, #fff));--_hover-state-layer-opacity: var(--md-filled-button-hover-state-layer-opacity, 0.08);--_label-text-color: var(--md-filled-button-label-text-color, var(--md-sys-color-on-primary, #fff));--_label-text-font: var(--md-filled-button-label-text-font, var(--md-sys-typescale-label-large-font, var(--md-ref-typeface-plain, Roboto)));--_label-text-line-height: var(--md-filled-button-label-text-line-height, var(--md-sys-typescale-label-large-line-height, 1.25rem));--_label-text-size: var(--md-filled-button-label-text-size, var(--md-sys-typescale-label-large-size, 0.875rem));--_label-text-weight: var(--md-filled-button-label-text-weight, var(--md-sys-typescale-label-large-weight, var(--md-ref-typeface-weight-medium, 500)));--_pressed-container-elevation: var(--md-filled-button-pressed-container-elevation, 0);--_pressed-label-text-color: var(--md-filled-button-pressed-label-text-color, var(--md-sys-color-on-primary, #fff));--_pressed-state-layer-color: var(--md-filled-button-pressed-state-layer-color, var(--md-sys-color-on-primary, #fff));--_pressed-state-layer-opacity: var(--md-filled-button-pressed-state-layer-opacity, 0.12);--_disabled-icon-color: var(--md-filled-button-disabled-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-icon-opacity: var(--md-filled-button-disabled-icon-opacity, 0.38);--_focus-icon-color: var(--md-filled-button-focus-icon-color, var(--md-sys-color-on-primary, #fff));--_hover-icon-color: var(--md-filled-button-hover-icon-color, var(--md-sys-color-on-primary, #fff));--_icon-color: var(--md-filled-button-icon-color, var(--md-sys-color-on-primary, #fff));--_icon-size: var(--md-filled-button-icon-size, 18px);--_pressed-icon-color: var(--md-filled-button-pressed-icon-color, var(--md-sys-color-on-primary, #fff));--_container-shape-start-start: var(--md-filled-button-container-shape-start-start, var(--md-filled-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-start-end: var(--md-filled-button-container-shape-start-end, var(--md-filled-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-end: var(--md-filled-button-container-shape-end-end, var(--md-filled-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-start: var(--md-filled-button-container-shape-end-start, var(--md-filled-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_leading-space: var(--md-filled-button-leading-space, 24px);--_trailing-space: var(--md-filled-button-trailing-space, 24px);--_with-leading-icon-leading-space: var(--md-filled-button-with-leading-icon-leading-space, 16px);--_with-leading-icon-trailing-space: var(--md-filled-button-with-leading-icon-trailing-space, 24px);--_with-trailing-icon-leading-space: var(--md-filled-button-with-trailing-icon-leading-space, 24px);--_with-trailing-icon-trailing-space: var(--md-filled-button-with-trailing-icon-trailing-space, 16px)} +`;let We=class extends Bo{};We.styles=[$e,lr,No],We=o([b("md-filled-button")],We);class Vo extends P{renderElevationOrOutline(){return d``}}const qo=v`:host{--_container-color: var(--md-filled-tonal-button-container-color, var(--md-sys-color-secondary-container, #e8def8));--_container-elevation: var(--md-filled-tonal-button-container-elevation, 0);--_container-height: var(--md-filled-tonal-button-container-height, 40px);--_container-shadow-color: var(--md-filled-tonal-button-container-shadow-color, var(--md-sys-color-shadow, #000));--_disabled-container-color: var(--md-filled-tonal-button-disabled-container-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-container-elevation: var(--md-filled-tonal-button-disabled-container-elevation, 0);--_disabled-container-opacity: var(--md-filled-tonal-button-disabled-container-opacity, 0.12);--_disabled-label-text-color: var(--md-filled-tonal-button-disabled-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-label-text-opacity: var(--md-filled-tonal-button-disabled-label-text-opacity, 0.38);--_focus-container-elevation: var(--md-filled-tonal-button-focus-container-elevation, 0);--_focus-label-text-color: var(--md-filled-tonal-button-focus-label-text-color, var(--md-sys-color-on-secondary-container, #1d192b));--_hover-container-elevation: var(--md-filled-tonal-button-hover-container-elevation, 1);--_hover-label-text-color: var(--md-filled-tonal-button-hover-label-text-color, var(--md-sys-color-on-secondary-container, #1d192b));--_hover-state-layer-color: var(--md-filled-tonal-button-hover-state-layer-color, var(--md-sys-color-on-secondary-container, #1d192b));--_hover-state-layer-opacity: var(--md-filled-tonal-button-hover-state-layer-opacity, 0.08);--_label-text-color: var(--md-filled-tonal-button-label-text-color, var(--md-sys-color-on-secondary-container, #1d192b));--_label-text-font: var(--md-filled-tonal-button-label-text-font, var(--md-sys-typescale-label-large-font, var(--md-ref-typeface-plain, Roboto)));--_label-text-line-height: var(--md-filled-tonal-button-label-text-line-height, var(--md-sys-typescale-label-large-line-height, 1.25rem));--_label-text-size: var(--md-filled-tonal-button-label-text-size, var(--md-sys-typescale-label-large-size, 0.875rem));--_label-text-weight: var(--md-filled-tonal-button-label-text-weight, var(--md-sys-typescale-label-large-weight, var(--md-ref-typeface-weight-medium, 500)));--_pressed-container-elevation: var(--md-filled-tonal-button-pressed-container-elevation, 0);--_pressed-label-text-color: var(--md-filled-tonal-button-pressed-label-text-color, var(--md-sys-color-on-secondary-container, #1d192b));--_pressed-state-layer-color: var(--md-filled-tonal-button-pressed-state-layer-color, var(--md-sys-color-on-secondary-container, #1d192b));--_pressed-state-layer-opacity: var(--md-filled-tonal-button-pressed-state-layer-opacity, 0.12);--_disabled-icon-color: var(--md-filled-tonal-button-disabled-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-icon-opacity: var(--md-filled-tonal-button-disabled-icon-opacity, 0.38);--_focus-icon-color: var(--md-filled-tonal-button-focus-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_hover-icon-color: var(--md-filled-tonal-button-hover-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_icon-color: var(--md-filled-tonal-button-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_icon-size: var(--md-filled-tonal-button-icon-size, 18px);--_pressed-icon-color: var(--md-filled-tonal-button-pressed-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_container-shape-start-start: var(--md-filled-tonal-button-container-shape-start-start, var(--md-filled-tonal-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-start-end: var(--md-filled-tonal-button-container-shape-start-end, var(--md-filled-tonal-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-end: var(--md-filled-tonal-button-container-shape-end-end, var(--md-filled-tonal-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-start: var(--md-filled-tonal-button-container-shape-end-start, var(--md-filled-tonal-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_leading-space: var(--md-filled-tonal-button-leading-space, 24px);--_trailing-space: var(--md-filled-tonal-button-trailing-space, 24px);--_with-leading-icon-leading-space: var(--md-filled-tonal-button-with-leading-icon-leading-space, 16px);--_with-leading-icon-trailing-space: var(--md-filled-tonal-button-with-leading-icon-trailing-space, 24px);--_with-trailing-icon-leading-space: var(--md-filled-tonal-button-with-trailing-icon-leading-space, 24px);--_with-trailing-icon-trailing-space: var(--md-filled-tonal-button-with-trailing-icon-trailing-space, 16px)} +`;let Ge=class extends Vo{};Ge.styles=[$e,lr,qo],Ge=o([b("md-filled-tonal-button")],Ge);class Ho extends P{renderElevationOrOutline(){return d`
`}}const Uo=v`:host{--_container-height: var(--md-outlined-button-container-height, 40px);--_disabled-label-text-color: var(--md-outlined-button-disabled-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-label-text-opacity: var(--md-outlined-button-disabled-label-text-opacity, 0.38);--_disabled-outline-color: var(--md-outlined-button-disabled-outline-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-outline-opacity: var(--md-outlined-button-disabled-outline-opacity, 0.12);--_focus-label-text-color: var(--md-outlined-button-focus-label-text-color, var(--md-sys-color-primary, #6750a4));--_hover-label-text-color: var(--md-outlined-button-hover-label-text-color, var(--md-sys-color-primary, #6750a4));--_hover-state-layer-color: var(--md-outlined-button-hover-state-layer-color, var(--md-sys-color-primary, #6750a4));--_hover-state-layer-opacity: var(--md-outlined-button-hover-state-layer-opacity, 0.08);--_label-text-color: var(--md-outlined-button-label-text-color, var(--md-sys-color-primary, #6750a4));--_label-text-font: var(--md-outlined-button-label-text-font, var(--md-sys-typescale-label-large-font, var(--md-ref-typeface-plain, Roboto)));--_label-text-line-height: var(--md-outlined-button-label-text-line-height, var(--md-sys-typescale-label-large-line-height, 1.25rem));--_label-text-size: var(--md-outlined-button-label-text-size, var(--md-sys-typescale-label-large-size, 0.875rem));--_label-text-weight: var(--md-outlined-button-label-text-weight, var(--md-sys-typescale-label-large-weight, var(--md-ref-typeface-weight-medium, 500)));--_outline-color: var(--md-outlined-button-outline-color, var(--md-sys-color-outline, #79747e));--_outline-width: var(--md-outlined-button-outline-width, 1px);--_pressed-label-text-color: var(--md-outlined-button-pressed-label-text-color, var(--md-sys-color-primary, #6750a4));--_pressed-outline-color: var(--md-outlined-button-pressed-outline-color, var(--md-sys-color-outline, #79747e));--_pressed-state-layer-color: var(--md-outlined-button-pressed-state-layer-color, var(--md-sys-color-primary, #6750a4));--_pressed-state-layer-opacity: var(--md-outlined-button-pressed-state-layer-opacity, 0.12);--_disabled-icon-color: var(--md-outlined-button-disabled-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-icon-opacity: var(--md-outlined-button-disabled-icon-opacity, 0.38);--_focus-icon-color: var(--md-outlined-button-focus-icon-color, var(--md-sys-color-primary, #6750a4));--_hover-icon-color: var(--md-outlined-button-hover-icon-color, var(--md-sys-color-primary, #6750a4));--_icon-color: var(--md-outlined-button-icon-color, var(--md-sys-color-primary, #6750a4));--_icon-size: var(--md-outlined-button-icon-size, 18px);--_pressed-icon-color: var(--md-outlined-button-pressed-icon-color, var(--md-sys-color-primary, #6750a4));--_container-shape-start-start: var(--md-outlined-button-container-shape-start-start, var(--md-outlined-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-start-end: var(--md-outlined-button-container-shape-start-end, var(--md-outlined-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-end: var(--md-outlined-button-container-shape-end-end, var(--md-outlined-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-start: var(--md-outlined-button-container-shape-end-start, var(--md-outlined-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_leading-space: var(--md-outlined-button-leading-space, 24px);--_trailing-space: var(--md-outlined-button-trailing-space, 24px);--_with-leading-icon-leading-space: var(--md-outlined-button-with-leading-icon-leading-space, 16px);--_with-leading-icon-trailing-space: var(--md-outlined-button-with-leading-icon-trailing-space, 24px);--_with-trailing-icon-leading-space: var(--md-outlined-button-with-trailing-icon-leading-space, 24px);--_with-trailing-icon-trailing-space: var(--md-outlined-button-with-trailing-icon-trailing-space, 16px);--_container-color: none;--_disabled-container-color: none;--_disabled-container-opacity: 0}.outline{inset:0;border-style:solid;position:absolute;box-sizing:border-box;border-color:var(--_outline-color);border-start-start-radius:var(--_container-shape-start-start);border-start-end-radius:var(--_container-shape-start-end);border-end-start-radius:var(--_container-shape-end-start);border-end-end-radius:var(--_container-shape-end-end)}:host(:active) .outline{border-color:var(--_pressed-outline-color)}:host(:is([disabled],[soft-disabled])) .outline{border-color:var(--_disabled-outline-color);opacity:var(--_disabled-outline-opacity)}@media(forced-colors: active){:host(:is([disabled],[soft-disabled])) .background{border-color:GrayText}:host(:is([disabled],[soft-disabled])) .outline{opacity:1}}.outline,md-ripple{border-width:var(--_outline-width)}md-ripple{inline-size:calc(100% - 2*var(--_outline-width));block-size:calc(100% - 2*var(--_outline-width));border-style:solid;border-color:rgba(0,0,0,0)} +`;let Xe=class extends Ho{};Xe.styles=[$e,Uo],Xe=o([b("md-outlined-button")],Xe);class Ko extends P{}const Wo=v`:host{--_container-height: var(--md-text-button-container-height, 40px);--_disabled-label-text-color: var(--md-text-button-disabled-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-label-text-opacity: var(--md-text-button-disabled-label-text-opacity, 0.38);--_focus-label-text-color: var(--md-text-button-focus-label-text-color, var(--md-sys-color-primary, #6750a4));--_hover-label-text-color: var(--md-text-button-hover-label-text-color, var(--md-sys-color-primary, #6750a4));--_hover-state-layer-color: var(--md-text-button-hover-state-layer-color, var(--md-sys-color-primary, #6750a4));--_hover-state-layer-opacity: var(--md-text-button-hover-state-layer-opacity, 0.08);--_label-text-color: var(--md-text-button-label-text-color, var(--md-sys-color-primary, #6750a4));--_label-text-font: var(--md-text-button-label-text-font, var(--md-sys-typescale-label-large-font, var(--md-ref-typeface-plain, Roboto)));--_label-text-line-height: var(--md-text-button-label-text-line-height, var(--md-sys-typescale-label-large-line-height, 1.25rem));--_label-text-size: var(--md-text-button-label-text-size, var(--md-sys-typescale-label-large-size, 0.875rem));--_label-text-weight: var(--md-text-button-label-text-weight, var(--md-sys-typescale-label-large-weight, var(--md-ref-typeface-weight-medium, 500)));--_pressed-label-text-color: var(--md-text-button-pressed-label-text-color, var(--md-sys-color-primary, #6750a4));--_pressed-state-layer-color: var(--md-text-button-pressed-state-layer-color, var(--md-sys-color-primary, #6750a4));--_pressed-state-layer-opacity: var(--md-text-button-pressed-state-layer-opacity, 0.12);--_disabled-icon-color: var(--md-text-button-disabled-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-icon-opacity: var(--md-text-button-disabled-icon-opacity, 0.38);--_focus-icon-color: var(--md-text-button-focus-icon-color, var(--md-sys-color-primary, #6750a4));--_hover-icon-color: var(--md-text-button-hover-icon-color, var(--md-sys-color-primary, #6750a4));--_icon-color: var(--md-text-button-icon-color, var(--md-sys-color-primary, #6750a4));--_icon-size: var(--md-text-button-icon-size, 18px);--_pressed-icon-color: var(--md-text-button-pressed-icon-color, var(--md-sys-color-primary, #6750a4));--_container-shape-start-start: var(--md-text-button-container-shape-start-start, var(--md-text-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-start-end: var(--md-text-button-container-shape-start-end, var(--md-text-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-end: var(--md-text-button-container-shape-end-end, var(--md-text-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-start: var(--md-text-button-container-shape-end-start, var(--md-text-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_leading-space: var(--md-text-button-leading-space, 12px);--_trailing-space: var(--md-text-button-trailing-space, 12px);--_with-leading-icon-leading-space: var(--md-text-button-with-leading-icon-leading-space, 12px);--_with-leading-icon-trailing-space: var(--md-text-button-with-leading-icon-trailing-space, 16px);--_with-trailing-icon-leading-space: var(--md-text-button-with-trailing-icon-leading-space, 16px);--_with-trailing-icon-trailing-space: var(--md-text-button-with-trailing-icon-trailing-space, 12px);--_container-color: none;--_disabled-container-color: none;--_disabled-container-opacity: 0} +`;let Ye=class extends Ko{};Ye.styles=[$e,Wo],Ye=o([b("md-text-button")],Ye);function de(i,e){e.bubbles&&(!i.shadowRoot||e.composed)&&e.stopPropagation();const t=Reflect.construct(e.constructor,[e.type,e]),r=i.dispatchEvent(t);return r||e.preventDefault(),r}const me=Symbol("createValidator"),be=Symbol("getValidityAnchor"),nr=Symbol("privateValidator"),oe=Symbol("privateSyncValidity"),je=Symbol("privateCustomValidationMessage");function Re(i){var e;class t extends i{constructor(){super(...arguments),this[e]=""}get validity(){return this[oe](),this[N].validity}get validationMessage(){return this[oe](),this[N].validationMessage}get willValidate(){return this[oe](),this[N].willValidate}checkValidity(){return this[oe](),this[N].checkValidity()}reportValidity(){return this[oe](),this[N].reportValidity()}setCustomValidity(a){this[je]=a,this[oe]()}requestUpdate(a,n,s){super.requestUpdate(a,n,s),this[oe]()}firstUpdated(a){super.firstUpdated(a),this[oe]()}[(e=je,oe)](){if(T)return;this[nr]||(this[nr]=this[me]());const{validity:a,validationMessage:n}=this[nr].getValidity(),s=!!this[je],h=this[je]||n;this[N].setValidity({...a,customError:s},h,this[be]()??void 0)}[me](){throw new Error("Implement [createValidator]")}[be](){throw new Error("Implement [getValidityAnchor]")}}return t}const ie=Symbol("getFormValue"),Oe=Symbol("getFormState");function we(i){class e extends i{get form(){return this[N].form}get labels(){return this[N].labels}get name(){return this.getAttribute("name")??""}set name(r){this.setAttribute("name",r)}get disabled(){return this.hasAttribute("disabled")}set disabled(r){this.toggleAttribute("disabled",r)}attributeChangedCallback(r,a,n){if(r==="name"||r==="disabled"){const s=r==="disabled"?a!==null:a;this.requestUpdate(r,s);return}super.attributeChangedCallback(r,a,n)}requestUpdate(r,a,n){super.requestUpdate(r,a,n),this[N].setFormValue(this[ie](),this[Oe]())}[ie](){throw new Error("Implement [getFormValue]")}[Oe](){return this[ie]()}formDisabledCallback(r){this.disabled=r}}return e.formAssociated=!0,o([l({noAccessor:!0})],e.prototype,"name",null),o([l({type:Boolean,noAccessor:!0})],e.prototype,"disabled",null),e}class Ze{constructor(e){this.getCurrentState=e,this.currentValidity={validity:{},validationMessage:""}}getValidity(){const e=this.getCurrentState();if(!(!this.prevState||!this.equals(this.prevState,e)))return this.currentValidity;const{validity:r,validationMessage:a}=this.computeValidity(e);return this.prevState=this.copy(e),this.currentValidity={validationMessage:a,validity:{badInput:r.badInput,customError:r.customError,patternMismatch:r.patternMismatch,rangeOverflow:r.rangeOverflow,rangeUnderflow:r.rangeUnderflow,stepMismatch:r.stepMismatch,tooLong:r.tooLong,tooShort:r.tooShort,typeMismatch:r.typeMismatch,valueMissing:r.valueMissing}},this.currentValidity}}class $r extends Ze{computeValidity(e){return this.checkboxControl||(this.checkboxControl=document.createElement("input"),this.checkboxControl.type="checkbox"),this.checkboxControl.checked=e.checked,this.checkboxControl.required=e.required,{validity:this.checkboxControl.validity,validationMessage:this.checkboxControl.validationMessage}}equals(e,t){return e.checked===t.checked&&e.required===t.required}copy({checked:e,required:t}){return{checked:e,required:t}}}const Go=W(Re(we(se(_))));class ee extends Go{constructor(){super(),this.checked=!1,this.indeterminate=!1,this.required=!1,this.value="on",this.prevChecked=!1,this.prevDisabled=!1,this.prevIndeterminate=!1,T||this.addEventListener("click",e=>{!Se(e)||!this.input||(this.focus(),Ue(this.input))})}update(e){(e.has("checked")||e.has("disabled")||e.has("indeterminate"))&&(this.prevChecked=e.get("checked")??this.checked,this.prevDisabled=e.get("disabled")??this.disabled,this.prevIndeterminate=e.get("indeterminate")??this.indeterminate),super.update(e)}render(){const e=!this.prevChecked&&!this.prevIndeterminate,t=this.prevChecked&&!this.prevIndeterminate,r=this.prevIndeterminate,a=this.checked&&!this.indeterminate,n=this.indeterminate,s=S({disabled:this.disabled,selected:a||n,unselected:!a&&!n,checked:a,indeterminate:n,"prev-unselected":e,"prev-checked":t,"prev-indeterminate":r,"prev-disabled":this.prevDisabled}),{ariaLabel:h,ariaInvalid:p}=this;return d` +
+ + +
+
+ + + +
+ `}handleInput(e){const t=e.target;this.checked=t.checked,this.indeterminate=t.indeterminate}handleChange(e){de(this,e)}[ie](){return!this.checked||this.indeterminate?null:this.value}[Oe](){return String(this.checked)}formResetCallback(){this.checked=this.hasAttribute("checked")}formStateRestoreCallback(e){this.checked=e==="true"}[me](){return new $r(()=>this)}[be](){return this.input}}ee.shadowRootOptions={..._.shadowRootOptions,delegatesFocus:!0},o([l({type:Boolean})],ee.prototype,"checked",void 0),o([l({type:Boolean})],ee.prototype,"indeterminate",void 0),o([l({type:Boolean})],ee.prototype,"required",void 0),o([l()],ee.prototype,"value",void 0),o([k()],ee.prototype,"prevChecked",void 0),o([k()],ee.prototype,"prevDisabled",void 0),o([k()],ee.prototype,"prevIndeterminate",void 0),o([g("input")],ee.prototype,"input",void 0);const Xo=v`:host{border-start-start-radius:var(--md-checkbox-container-shape-start-start, var(--md-checkbox-container-shape, 2px));border-start-end-radius:var(--md-checkbox-container-shape-start-end, var(--md-checkbox-container-shape, 2px));border-end-end-radius:var(--md-checkbox-container-shape-end-end, var(--md-checkbox-container-shape, 2px));border-end-start-radius:var(--md-checkbox-container-shape-end-start, var(--md-checkbox-container-shape, 2px));display:inline-flex;height:var(--md-checkbox-container-size, 18px);position:relative;vertical-align:top;width:var(--md-checkbox-container-size, 18px);-webkit-tap-highlight-color:rgba(0,0,0,0);cursor:pointer}:host([disabled]){cursor:default}:host([touch-target=wrapper]){margin:max(0px,(48px - var(--md-checkbox-container-size, 18px))/2)}md-focus-ring{height:44px;inset:unset;width:44px}input{appearance:none;height:48px;margin:0;opacity:0;outline:none;position:absolute;width:48px;z-index:1;cursor:inherit}:host([touch-target=none]) input{height:100%;width:100%}.container{border-radius:inherit;display:flex;height:100%;place-content:center;place-items:center;position:relative;width:100%}.outline,.background,.icon{inset:0;position:absolute}.outline,.background{border-radius:inherit}.outline{border-color:var(--md-checkbox-outline-color, var(--md-sys-color-on-surface-variant, #49454f));border-style:solid;border-width:var(--md-checkbox-outline-width, 2px);box-sizing:border-box}.background{background-color:var(--md-checkbox-selected-container-color, var(--md-sys-color-primary, #6750a4))}.background,.icon{opacity:0;transition-duration:150ms,50ms;transition-property:transform,opacity;transition-timing-function:cubic-bezier(0.3, 0, 0.8, 0.15),linear;transform:scale(0.6)}:where(.selected) :is(.background,.icon){opacity:1;transition-duration:350ms,50ms;transition-timing-function:cubic-bezier(0.05, 0.7, 0.1, 1),linear;transform:scale(1)}md-ripple{border-radius:var(--md-checkbox-state-layer-shape, var(--md-sys-shape-corner-full, 9999px));height:var(--md-checkbox-state-layer-size, 40px);inset:unset;width:var(--md-checkbox-state-layer-size, 40px);--md-ripple-hover-color: var(--md-checkbox-hover-state-layer-color, var(--md-sys-color-on-surface, #1d1b20));--md-ripple-hover-opacity: var(--md-checkbox-hover-state-layer-opacity, 0.08);--md-ripple-pressed-color: var(--md-checkbox-pressed-state-layer-color, var(--md-sys-color-primary, #6750a4));--md-ripple-pressed-opacity: var(--md-checkbox-pressed-state-layer-opacity, 0.12)}.selected md-ripple{--md-ripple-hover-color: var(--md-checkbox-selected-hover-state-layer-color, var(--md-sys-color-primary, #6750a4));--md-ripple-hover-opacity: var(--md-checkbox-selected-hover-state-layer-opacity, 0.08);--md-ripple-pressed-color: var(--md-checkbox-selected-pressed-state-layer-color, var(--md-sys-color-on-surface, #1d1b20));--md-ripple-pressed-opacity: var(--md-checkbox-selected-pressed-state-layer-opacity, 0.12)}.icon{fill:var(--md-checkbox-selected-icon-color, var(--md-sys-color-on-primary, #fff));height:var(--md-checkbox-icon-size, 18px);width:var(--md-checkbox-icon-size, 18px)}.mark.short{height:2px;transition-property:transform,height;width:2px}.mark.long{height:2px;transition-property:transform,width;width:10px}.mark{animation-duration:150ms;animation-timing-function:cubic-bezier(0.3, 0, 0.8, 0.15);transition-duration:150ms;transition-timing-function:cubic-bezier(0.3, 0, 0.8, 0.15)}.selected .mark{animation-duration:350ms;animation-timing-function:cubic-bezier(0.05, 0.7, 0.1, 1);transition-duration:350ms;transition-timing-function:cubic-bezier(0.05, 0.7, 0.1, 1)}.checked .mark,.prev-checked.unselected .mark{transform:scaleY(-1) translate(7px, -14px) rotate(45deg)}.checked .mark.short,.prev-checked.unselected .mark.short{height:5.6568542495px}.checked .mark.long,.prev-checked.unselected .mark.long{width:11.313708499px}.indeterminate .mark,.prev-indeterminate.unselected .mark{transform:scaleY(-1) translate(4px, -10px) rotate(0deg)}.prev-unselected .mark{transition-property:none}.prev-unselected.checked .mark.long{animation-name:prev-unselected-to-checked}@keyframes prev-unselected-to-checked{from{width:0}}:where(:hover) .outline{border-color:var(--md-checkbox-hover-outline-color, var(--md-sys-color-on-surface, #1d1b20));border-width:var(--md-checkbox-hover-outline-width, 2px)}:where(:hover) .background{background:var(--md-checkbox-selected-hover-container-color, var(--md-sys-color-primary, #6750a4))}:where(:hover) .icon{fill:var(--md-checkbox-selected-hover-icon-color, var(--md-sys-color-on-primary, #fff))}:where(:focus-within) .outline{border-color:var(--md-checkbox-focus-outline-color, var(--md-sys-color-on-surface, #1d1b20));border-width:var(--md-checkbox-focus-outline-width, 2px)}:where(:focus-within) .background{background:var(--md-checkbox-selected-focus-container-color, var(--md-sys-color-primary, #6750a4))}:where(:focus-within) .icon{fill:var(--md-checkbox-selected-focus-icon-color, var(--md-sys-color-on-primary, #fff))}:where(:active) .outline{border-color:var(--md-checkbox-pressed-outline-color, var(--md-sys-color-on-surface, #1d1b20));border-width:var(--md-checkbox-pressed-outline-width, 2px)}:where(:active) .background{background:var(--md-checkbox-selected-pressed-container-color, var(--md-sys-color-primary, #6750a4))}:where(:active) .icon{fill:var(--md-checkbox-selected-pressed-icon-color, var(--md-sys-color-on-primary, #fff))}:where(.disabled,.prev-disabled) :is(.background,.icon,.mark){animation-duration:0s;transition-duration:0s}:where(.disabled) .outline{border-color:var(--md-checkbox-disabled-outline-color, var(--md-sys-color-on-surface, #1d1b20));border-width:var(--md-checkbox-disabled-outline-width, 2px);opacity:var(--md-checkbox-disabled-container-opacity, 0.38)}:where(.selected.disabled) .outline{visibility:hidden}:where(.selected.disabled) .background{background:var(--md-checkbox-selected-disabled-container-color, var(--md-sys-color-on-surface, #1d1b20));opacity:var(--md-checkbox-selected-disabled-container-opacity, 0.38)}:where(.disabled) .icon{fill:var(--md-checkbox-selected-disabled-icon-color, var(--md-sys-color-surface, #fef7ff))}@media(forced-colors: active){.background{background-color:CanvasText}.selected.disabled .background{background-color:GrayText;opacity:1}.outline{border-color:CanvasText}.disabled .outline{border-color:GrayText;opacity:1}.icon{fill:Canvas}} +`;let Qe=class extends ee{};Qe.styles=[Xo],Qe=o([b("md-checkbox")],Qe);const Yo=W(_);class ae extends Yo{get rippleDisabled(){return this.disabled||this.softDisabled}constructor(){super(),this.disabled=!1,this.softDisabled=!1,this.alwaysFocusable=!1,this.label="",this.hasIcon=!1,T||this.addEventListener("click",this.handleClick.bind(this))}focus(e){this.disabled&&!this.alwaysFocusable||super.focus(e)}render(){return d` +
+ ${this.renderContainerContent()} +
+ `}updated(e){e.has("disabled")&&e.get("disabled")!==void 0&&this.dispatchEvent(new Event("update-focus",{bubbles:!0}))}getContainerClasses(){return{disabled:this.disabled||this.softDisabled,"has-icon":this.hasIcon}}renderContainerContent(){return d` + ${this.renderOutline()} + + + ${this.renderPrimaryAction(this.renderPrimaryContent())} + `}renderOutline(){return d``}renderLeadingIcon(){return d``}renderPrimaryContent(){return d` + + + + ${this.label?this.label:d``} + + + + `}handleIconChange(e){const t=e.target;this.hasIcon=t.assignedElements({flatten:!0}).length>0}handleClick(e){if(this.softDisabled||this.disabled&&this.alwaysFocusable){e.stopImmediatePropagation(),e.preventDefault();return}}}ae.shadowRootOptions={..._.shadowRootOptions,delegatesFocus:!0},o([l({type:Boolean,reflect:!0})],ae.prototype,"disabled",void 0),o([l({type:Boolean,attribute:"soft-disabled",reflect:!0})],ae.prototype,"softDisabled",void 0),o([l({type:Boolean,attribute:"always-focusable"})],ae.prototype,"alwaysFocusable",void 0),o([l()],ae.prototype,"label",void 0),o([l({type:Boolean,reflect:!0,attribute:"has-icon"})],ae.prototype,"hasIcon",void 0);class ke extends ae{constructor(){super(...arguments),this.elevated=!1,this.href="",this.download="",this.target=""}get primaryId(){return this.href?"link":"button"}get rippleDisabled(){return!this.href&&(this.disabled||this.softDisabled)}getContainerClasses(){return{...super.getContainerClasses(),disabled:!this.href&&(this.disabled||this.softDisabled),elevated:this.elevated,link:!!this.href}}renderPrimaryAction(e){const{ariaLabel:t}=this;return this.href?d` + ${e} + `:d` + + `}renderOutline(){return this.elevated?d``:super.renderOutline()}}o([l({type:Boolean})],ke.prototype,"elevated",void 0),o([l()],ke.prototype,"href",void 0),o([l()],ke.prototype,"download",void 0),o([l()],ke.prototype,"target",void 0);const jo=v`:host{--_container-height: var(--md-assist-chip-container-height, 32px);--_disabled-label-text-color: var(--md-assist-chip-disabled-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-label-text-opacity: var(--md-assist-chip-disabled-label-text-opacity, 0.38);--_elevated-container-color: var(--md-assist-chip-elevated-container-color, var(--md-sys-color-surface-container-low, #f7f2fa));--_elevated-container-elevation: var(--md-assist-chip-elevated-container-elevation, 1);--_elevated-container-shadow-color: var(--md-assist-chip-elevated-container-shadow-color, var(--md-sys-color-shadow, #000));--_elevated-disabled-container-color: var(--md-assist-chip-elevated-disabled-container-color, var(--md-sys-color-on-surface, #1d1b20));--_elevated-disabled-container-elevation: var(--md-assist-chip-elevated-disabled-container-elevation, 0);--_elevated-disabled-container-opacity: var(--md-assist-chip-elevated-disabled-container-opacity, 0.12);--_elevated-focus-container-elevation: var(--md-assist-chip-elevated-focus-container-elevation, 1);--_elevated-hover-container-elevation: var(--md-assist-chip-elevated-hover-container-elevation, 2);--_elevated-pressed-container-elevation: var(--md-assist-chip-elevated-pressed-container-elevation, 1);--_focus-label-text-color: var(--md-assist-chip-focus-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_hover-label-text-color: var(--md-assist-chip-hover-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_hover-state-layer-color: var(--md-assist-chip-hover-state-layer-color, var(--md-sys-color-on-surface, #1d1b20));--_hover-state-layer-opacity: var(--md-assist-chip-hover-state-layer-opacity, 0.08);--_label-text-color: var(--md-assist-chip-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_label-text-font: var(--md-assist-chip-label-text-font, var(--md-sys-typescale-label-large-font, var(--md-ref-typeface-plain, Roboto)));--_label-text-line-height: var(--md-assist-chip-label-text-line-height, var(--md-sys-typescale-label-large-line-height, 1.25rem));--_label-text-size: var(--md-assist-chip-label-text-size, var(--md-sys-typescale-label-large-size, 0.875rem));--_label-text-weight: var(--md-assist-chip-label-text-weight, var(--md-sys-typescale-label-large-weight, var(--md-ref-typeface-weight-medium, 500)));--_pressed-label-text-color: var(--md-assist-chip-pressed-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_pressed-state-layer-color: var(--md-assist-chip-pressed-state-layer-color, var(--md-sys-color-on-surface, #1d1b20));--_pressed-state-layer-opacity: var(--md-assist-chip-pressed-state-layer-opacity, 0.12);--_disabled-outline-color: var(--md-assist-chip-disabled-outline-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-outline-opacity: var(--md-assist-chip-disabled-outline-opacity, 0.12);--_focus-outline-color: var(--md-assist-chip-focus-outline-color, var(--md-sys-color-on-surface, #1d1b20));--_outline-color: var(--md-assist-chip-outline-color, var(--md-sys-color-outline, #79747e));--_outline-width: var(--md-assist-chip-outline-width, 1px);--_disabled-leading-icon-color: var(--md-assist-chip-disabled-leading-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-leading-icon-opacity: var(--md-assist-chip-disabled-leading-icon-opacity, 0.38);--_focus-leading-icon-color: var(--md-assist-chip-focus-leading-icon-color, var(--md-sys-color-primary, #6750a4));--_hover-leading-icon-color: var(--md-assist-chip-hover-leading-icon-color, var(--md-sys-color-primary, #6750a4));--_leading-icon-color: var(--md-assist-chip-leading-icon-color, var(--md-sys-color-primary, #6750a4));--_icon-size: var(--md-assist-chip-icon-size, 18px);--_pressed-leading-icon-color: var(--md-assist-chip-pressed-leading-icon-color, var(--md-sys-color-primary, #6750a4));--_container-shape-start-start: var(--md-assist-chip-container-shape-start-start, var(--md-assist-chip-container-shape, var(--md-sys-shape-corner-small, 8px)));--_container-shape-start-end: var(--md-assist-chip-container-shape-start-end, var(--md-assist-chip-container-shape, var(--md-sys-shape-corner-small, 8px)));--_container-shape-end-end: var(--md-assist-chip-container-shape-end-end, var(--md-assist-chip-container-shape, var(--md-sys-shape-corner-small, 8px)));--_container-shape-end-start: var(--md-assist-chip-container-shape-end-start, var(--md-assist-chip-container-shape, var(--md-sys-shape-corner-small, 8px)));--_leading-space: var(--md-assist-chip-leading-space, 16px);--_trailing-space: var(--md-assist-chip-trailing-space, 16px);--_icon-label-space: var(--md-assist-chip-icon-label-space, 8px);--_with-leading-icon-leading-space: var(--md-assist-chip-with-leading-icon-leading-space, 8px)}@media(forced-colors: active){.link .outline{border-color:ActiveText}} +`;const sr=v`.elevated{--md-elevation-level: var(--_elevated-container-elevation);--md-elevation-shadow-color: var(--_elevated-container-shadow-color)}.elevated::before{background:var(--_elevated-container-color)}.elevated:hover{--md-elevation-level: var(--_elevated-hover-container-elevation)}.elevated:focus-within{--md-elevation-level: var(--_elevated-focus-container-elevation)}.elevated:active{--md-elevation-level: var(--_elevated-pressed-container-elevation)}.elevated.disabled{--md-elevation-level: var(--_elevated-disabled-container-elevation)}.elevated.disabled::before{background:var(--_elevated-disabled-container-color);opacity:var(--_elevated-disabled-container-opacity)}@media(forced-colors: active){.elevated md-elevation{border:1px solid CanvasText}.elevated.disabled md-elevation{border-color:GrayText}} +`;const Je=v`:host{border-start-start-radius:var(--_container-shape-start-start);border-start-end-radius:var(--_container-shape-start-end);border-end-start-radius:var(--_container-shape-end-start);border-end-end-radius:var(--_container-shape-end-end);display:inline-flex;height:var(--_container-height);cursor:pointer;-webkit-tap-highlight-color:rgba(0,0,0,0);--md-ripple-hover-color: var(--_hover-state-layer-color);--md-ripple-hover-opacity: var(--_hover-state-layer-opacity);--md-ripple-pressed-color: var(--_pressed-state-layer-color);--md-ripple-pressed-opacity: var(--_pressed-state-layer-opacity)}:host(:is([disabled],[soft-disabled])){pointer-events:none}:host([touch-target=wrapper]){margin:max(0px,(48px - var(--_container-height))/2) 0}md-focus-ring{--md-focus-ring-shape-start-start: var(--_container-shape-start-start);--md-focus-ring-shape-start-end: var(--_container-shape-start-end);--md-focus-ring-shape-end-end: var(--_container-shape-end-end);--md-focus-ring-shape-end-start: var(--_container-shape-end-start)}.container{border-radius:inherit;box-sizing:border-box;display:flex;height:100%;position:relative;width:100%}.container::before{border-radius:inherit;content:"";inset:0;pointer-events:none;position:absolute}.container:not(.disabled){cursor:pointer}.container.disabled{pointer-events:none}.cell{display:flex}.action{align-items:baseline;appearance:none;background:none;border:none;border-radius:inherit;display:flex;outline:none;padding:0;position:relative;text-decoration:none}.primary.action{min-width:0;padding-inline-start:var(--_leading-space);padding-inline-end:var(--_trailing-space)}.has-icon .primary.action{padding-inline-start:var(--_with-leading-icon-leading-space)}.touch{height:48px;inset:50% 0 0;position:absolute;transform:translateY(-50%);width:100%}:host([touch-target=none]) .touch{display:none}.outline{border:var(--_outline-width) solid var(--_outline-color);border-radius:inherit;inset:0;pointer-events:none;position:absolute}:where(:focus) .outline{border-color:var(--_focus-outline-color)}:where(.disabled) .outline{border-color:var(--_disabled-outline-color);opacity:var(--_disabled-outline-opacity)}md-ripple{border-radius:inherit}.label,.icon,.touch{z-index:1}.label{align-items:center;color:var(--_label-text-color);display:flex;font-family:var(--_label-text-font);font-size:var(--_label-text-size);font-weight:var(--_label-text-weight);height:100%;line-height:var(--_label-text-line-height);overflow:hidden;user-select:none}.label-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:where(:hover) .label{color:var(--_hover-label-text-color)}:where(:focus) .label{color:var(--_focus-label-text-color)}:where(:active) .label{color:var(--_pressed-label-text-color)}:where(.disabled) .label{color:var(--_disabled-label-text-color);opacity:var(--_disabled-label-text-opacity)}.icon{align-self:center;display:flex;fill:currentColor;position:relative}.icon ::slotted(:first-child){font-size:var(--_icon-size);height:var(--_icon-size);width:var(--_icon-size)}.leading.icon{color:var(--_leading-icon-color)}.leading.icon ::slotted(*),.leading.icon svg{margin-inline-end:var(--_icon-label-space)}:where(:hover) .leading.icon{color:var(--_hover-leading-icon-color)}:where(:focus) .leading.icon{color:var(--_focus-leading-icon-color)}:where(:active) .leading.icon{color:var(--_pressed-leading-icon-color)}:where(.disabled) .leading.icon{color:var(--_disabled-leading-icon-color);opacity:var(--_disabled-leading-icon-opacity)}@media(forced-colors: active){:where(.disabled) :is(.label,.outline,.leading.icon){color:GrayText;opacity:1}}a,button{text-transform:inherit}a,button:not(:disabled,[aria-disabled=true]){cursor:inherit} +`;let et=class extends ke{};et.styles=[Je,sr,jo],et=o([b("md-assist-chip")],et);class Rr extends _{get chips(){return this.childElements.filter(e=>e instanceof ae)}constructor(){super(),this.internals=this.attachInternals(),T||(this.addEventListener("focusin",this.updateTabIndices.bind(this)),this.addEventListener("update-focus",this.updateTabIndices.bind(this)),this.addEventListener("keydown",this.handleKeyDown.bind(this)),this.internals.role="toolbar")}render(){return d``}handleKeyDown(e){const t=e.key==="ArrowLeft",r=e.key==="ArrowRight",a=e.key==="Home",n=e.key==="End";if(!t&&!r&&!a&&!n)return;const{chips:s}=this;if(s.length<2)return;if(e.preventDefault(),a||n){const m=a?0:s.length-1;s[m].focus({trailing:n}),this.updateTabIndices();return}const p=getComputedStyle(this).direction==="rtl"?t:r,y=s.find(m=>m.matches(":focus-within"));if(!y){(p?s[0]:s[s.length-1]).focus({trailing:!p}),this.updateTabIndices();return}const u=s.indexOf(y);let f=p?u+1:u-1;for(;f!==u;){f>=s.length?f=0:f<0&&(f=s.length-1);const m=s[f];if(m.disabled&&!m.alwaysFocusable){p?f++:f--;continue}m.focus({trailing:!p}),this.updateTabIndices();break}}updateTabIndices(){const{chips:e}=this;let t;for(const r of e){const a=r.alwaysFocusable||!r.disabled;if(r.matches(":focus-within")&&a){t=r;continue}a&&!t&&(t=r),r.tabIndex=-1}t&&(t.tabIndex=0)}}o([H()],Rr.prototype,"childElements",void 0);const Zo=v`:host{display:flex;flex-wrap:wrap;gap:8px} +`;let tt=class extends Rr{};tt.styles=[Zo],tt=o([b("md-chip-set")],tt);const rt="aria-label-remove";class Or extends ae{get ariaLabelRemove(){if(this.hasAttribute(rt))return this.getAttribute(rt);const{ariaLabel:e}=this;return e||this.label?`Remove ${e||this.label}`:null}set ariaLabelRemove(e){const t=this.ariaLabelRemove;e!==t&&(e===null?this.removeAttribute(rt):this.setAttribute(rt,e),this.requestUpdate())}constructor(){super(),this.handleTrailingActionFocus=this.handleTrailingActionFocus.bind(this),T||this.addEventListener("keydown",this.handleKeyDown.bind(this))}focus(e){if((this.alwaysFocusable||!this.disabled)&&e?.trailing&&this.trailingAction){this.trailingAction.focus(e);return}super.focus(e)}renderContainerContent(){return d` + ${super.renderContainerContent()} + ${this.renderTrailingAction(this.handleTrailingActionFocus)} + `}handleKeyDown(e){const t=e.key==="ArrowLeft",r=e.key==="ArrowRight";if(!t&&!r||!this.primaryAction||!this.trailingAction)return;const n=getComputedStyle(this).direction==="rtl"?t:r,s=this.primaryAction?.matches(":focus-within"),h=this.trailingAction?.matches(":focus-within");if(n&&h||!n&&s)return;e.preventDefault(),e.stopPropagation(),(n?this.trailingAction:this.primaryAction).focus()}handleTrailingActionFocus(){const{primaryAction:e,trailingAction:t}=this;!e||!t||(e.tabIndex=-1,t.addEventListener("focusout",()=>{e.tabIndex=0},{once:!0}))}}function Lr({ariaLabel:i,disabled:e,focusListener:t,tabbable:r=!1}){return d` + + + `}function Qo(i){this.disabled||this.softDisabled||(i.stopPropagation(),!this.dispatchEvent(new Event("remove",{cancelable:!0})))||this.remove()}class ye extends Or{constructor(){super(...arguments),this.elevated=!1,this.removable=!1,this.selected=!1,this.hasSelectedIcon=!1}get primaryId(){return"button"}getContainerClasses(){return{...super.getContainerClasses(),elevated:this.elevated,selected:this.selected,"has-trailing":this.removable,"has-icon":this.hasIcon||this.selected}}renderPrimaryAction(e){const{ariaLabel:t}=this;return d` + + `}renderLeadingIcon(){return this.selected?d` + + + + `:super.renderLeadingIcon()}renderTrailingAction(e){return this.removable?Lr({focusListener:e,ariaLabel:this.ariaLabelRemove,disabled:this.disabled||this.softDisabled}):c}renderOutline(){return this.elevated?d``:super.renderOutline()}handleClickOnChild(e){if(this.disabled||this.softDisabled)return;const t=this.selected;if(this.selected=!this.selected,!de(this,e)){this.selected=t;return}}}o([l({type:Boolean})],ye.prototype,"elevated",void 0),o([l({type:Boolean})],ye.prototype,"removable",void 0),o([l({type:Boolean,reflect:!0})],ye.prototype,"selected",void 0),o([l({type:Boolean,reflect:!0,attribute:"has-selected-icon"})],ye.prototype,"hasSelectedIcon",void 0),o([g(".primary.action")],ye.prototype,"primaryAction",void 0),o([g(".trailing.action")],ye.prototype,"trailingAction",void 0);const Jo=v`:host{--_container-height: var(--md-filter-chip-container-height, 32px);--_disabled-label-text-color: var(--md-filter-chip-disabled-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-label-text-opacity: var(--md-filter-chip-disabled-label-text-opacity, 0.38);--_elevated-container-elevation: var(--md-filter-chip-elevated-container-elevation, 1);--_elevated-container-shadow-color: var(--md-filter-chip-elevated-container-shadow-color, var(--md-sys-color-shadow, #000));--_elevated-disabled-container-color: var(--md-filter-chip-elevated-disabled-container-color, var(--md-sys-color-on-surface, #1d1b20));--_elevated-disabled-container-elevation: var(--md-filter-chip-elevated-disabled-container-elevation, 0);--_elevated-disabled-container-opacity: var(--md-filter-chip-elevated-disabled-container-opacity, 0.12);--_elevated-focus-container-elevation: var(--md-filter-chip-elevated-focus-container-elevation, 1);--_elevated-hover-container-elevation: var(--md-filter-chip-elevated-hover-container-elevation, 2);--_elevated-pressed-container-elevation: var(--md-filter-chip-elevated-pressed-container-elevation, 1);--_elevated-selected-container-color: var(--md-filter-chip-elevated-selected-container-color, var(--md-sys-color-secondary-container, #e8def8));--_label-text-font: var(--md-filter-chip-label-text-font, var(--md-sys-typescale-label-large-font, var(--md-ref-typeface-plain, Roboto)));--_label-text-line-height: var(--md-filter-chip-label-text-line-height, var(--md-sys-typescale-label-large-line-height, 1.25rem));--_label-text-size: var(--md-filter-chip-label-text-size, var(--md-sys-typescale-label-large-size, 0.875rem));--_label-text-weight: var(--md-filter-chip-label-text-weight, var(--md-sys-typescale-label-large-weight, var(--md-ref-typeface-weight-medium, 500)));--_selected-focus-label-text-color: var(--md-filter-chip-selected-focus-label-text-color, var(--md-sys-color-on-secondary-container, #1d192b));--_selected-hover-label-text-color: var(--md-filter-chip-selected-hover-label-text-color, var(--md-sys-color-on-secondary-container, #1d192b));--_selected-hover-state-layer-color: var(--md-filter-chip-selected-hover-state-layer-color, var(--md-sys-color-on-secondary-container, #1d192b));--_selected-hover-state-layer-opacity: var(--md-filter-chip-selected-hover-state-layer-opacity, 0.08);--_selected-label-text-color: var(--md-filter-chip-selected-label-text-color, var(--md-sys-color-on-secondary-container, #1d192b));--_selected-pressed-label-text-color: var(--md-filter-chip-selected-pressed-label-text-color, var(--md-sys-color-on-secondary-container, #1d192b));--_selected-pressed-state-layer-color: var(--md-filter-chip-selected-pressed-state-layer-color, var(--md-sys-color-on-surface-variant, #49454f));--_selected-pressed-state-layer-opacity: var(--md-filter-chip-selected-pressed-state-layer-opacity, 0.12);--_elevated-container-color: var(--md-filter-chip-elevated-container-color, var(--md-sys-color-surface-container-low, #f7f2fa));--_disabled-outline-color: var(--md-filter-chip-disabled-outline-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-outline-opacity: var(--md-filter-chip-disabled-outline-opacity, 0.12);--_disabled-selected-container-color: var(--md-filter-chip-disabled-selected-container-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-selected-container-opacity: var(--md-filter-chip-disabled-selected-container-opacity, 0.12);--_focus-outline-color: var(--md-filter-chip-focus-outline-color, var(--md-sys-color-on-surface-variant, #49454f));--_outline-color: var(--md-filter-chip-outline-color, var(--md-sys-color-outline, #79747e));--_outline-width: var(--md-filter-chip-outline-width, 1px);--_selected-container-color: var(--md-filter-chip-selected-container-color, var(--md-sys-color-secondary-container, #e8def8));--_selected-outline-width: var(--md-filter-chip-selected-outline-width, 0px);--_focus-label-text-color: var(--md-filter-chip-focus-label-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-label-text-color: var(--md-filter-chip-hover-label-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-state-layer-color: var(--md-filter-chip-hover-state-layer-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-state-layer-opacity: var(--md-filter-chip-hover-state-layer-opacity, 0.08);--_label-text-color: var(--md-filter-chip-label-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_pressed-label-text-color: var(--md-filter-chip-pressed-label-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_pressed-state-layer-color: var(--md-filter-chip-pressed-state-layer-color, var(--md-sys-color-on-secondary-container, #1d192b));--_pressed-state-layer-opacity: var(--md-filter-chip-pressed-state-layer-opacity, 0.12);--_icon-size: var(--md-filter-chip-icon-size, 18px);--_disabled-leading-icon-color: var(--md-filter-chip-disabled-leading-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-leading-icon-opacity: var(--md-filter-chip-disabled-leading-icon-opacity, 0.38);--_selected-focus-leading-icon-color: var(--md-filter-chip-selected-focus-leading-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_selected-hover-leading-icon-color: var(--md-filter-chip-selected-hover-leading-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_selected-leading-icon-color: var(--md-filter-chip-selected-leading-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_selected-pressed-leading-icon-color: var(--md-filter-chip-selected-pressed-leading-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_focus-leading-icon-color: var(--md-filter-chip-focus-leading-icon-color, var(--md-sys-color-primary, #6750a4));--_hover-leading-icon-color: var(--md-filter-chip-hover-leading-icon-color, var(--md-sys-color-primary, #6750a4));--_leading-icon-color: var(--md-filter-chip-leading-icon-color, var(--md-sys-color-primary, #6750a4));--_pressed-leading-icon-color: var(--md-filter-chip-pressed-leading-icon-color, var(--md-sys-color-primary, #6750a4));--_disabled-trailing-icon-color: var(--md-filter-chip-disabled-trailing-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-trailing-icon-opacity: var(--md-filter-chip-disabled-trailing-icon-opacity, 0.38);--_selected-focus-trailing-icon-color: var(--md-filter-chip-selected-focus-trailing-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_selected-hover-trailing-icon-color: var(--md-filter-chip-selected-hover-trailing-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_selected-pressed-trailing-icon-color: var(--md-filter-chip-selected-pressed-trailing-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_selected-trailing-icon-color: var(--md-filter-chip-selected-trailing-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_focus-trailing-icon-color: var(--md-filter-chip-focus-trailing-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-trailing-icon-color: var(--md-filter-chip-hover-trailing-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_pressed-trailing-icon-color: var(--md-filter-chip-pressed-trailing-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_trailing-icon-color: var(--md-filter-chip-trailing-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_container-shape-start-start: var(--md-filter-chip-container-shape-start-start, var(--md-filter-chip-container-shape, var(--md-sys-shape-corner-small, 8px)));--_container-shape-start-end: var(--md-filter-chip-container-shape-start-end, var(--md-filter-chip-container-shape, var(--md-sys-shape-corner-small, 8px)));--_container-shape-end-end: var(--md-filter-chip-container-shape-end-end, var(--md-filter-chip-container-shape, var(--md-sys-shape-corner-small, 8px)));--_container-shape-end-start: var(--md-filter-chip-container-shape-end-start, var(--md-filter-chip-container-shape, var(--md-sys-shape-corner-small, 8px)));--_leading-space: var(--md-filter-chip-leading-space, 16px);--_trailing-space: var(--md-filter-chip-trailing-space, 16px);--_icon-label-space: var(--md-filter-chip-icon-label-space, 8px);--_with-leading-icon-leading-space: var(--md-filter-chip-with-leading-icon-leading-space, 8px);--_with-trailing-icon-trailing-space: var(--md-filter-chip-with-trailing-icon-trailing-space, 8px)}.selected.elevated::before{background:var(--_elevated-selected-container-color)}.checkmark{height:var(--_icon-size);width:var(--_icon-size)}.disabled .checkmark{opacity:var(--_disabled-leading-icon-opacity)}@media(forced-colors: active){.disabled .checkmark{opacity:1}} +`;const Fr=v`.selected{--md-ripple-hover-color: var(--_selected-hover-state-layer-color);--md-ripple-hover-opacity: var(--_selected-hover-state-layer-opacity);--md-ripple-pressed-color: var(--_selected-pressed-state-layer-color);--md-ripple-pressed-opacity: var(--_selected-pressed-state-layer-opacity)}:where(.selected)::before{background:var(--_selected-container-color)}:where(.selected) .outline{border-width:var(--_selected-outline-width)}:where(.selected.disabled)::before{background:var(--_disabled-selected-container-color);opacity:var(--_disabled-selected-container-opacity)}:where(.selected) .label{color:var(--_selected-label-text-color)}:where(.selected:hover) .label{color:var(--_selected-hover-label-text-color)}:where(.selected:focus) .label{color:var(--_selected-focus-label-text-color)}:where(.selected:active) .label{color:var(--_selected-pressed-label-text-color)}:where(.selected) .leading.icon{color:var(--_selected-leading-icon-color)}:where(.selected:hover) .leading.icon{color:var(--_selected-hover-leading-icon-color)}:where(.selected:focus) .leading.icon{color:var(--_selected-focus-leading-icon-color)}:where(.selected:active) .leading.icon{color:var(--_selected-pressed-leading-icon-color)}@media(forced-colors: active){:where(.selected:not(.elevated))::before{border:1px solid CanvasText}:where(.selected) .outline{border-width:1px}} +`;const Dr=v`.trailing.action{align-items:center;justify-content:center;padding-inline-start:var(--_icon-label-space);padding-inline-end:var(--_with-trailing-icon-trailing-space)}.trailing.action :is(md-ripple,md-focus-ring){border-radius:50%;height:calc(1.3333333333*var(--_icon-size));width:calc(1.3333333333*var(--_icon-size))}.trailing.action md-focus-ring{inset:unset}.has-trailing .primary.action{padding-inline-end:0}.trailing.icon{color:var(--_trailing-icon-color);height:var(--_icon-size);width:var(--_icon-size)}:where(:hover) .trailing.icon{color:var(--_hover-trailing-icon-color)}:where(:focus) .trailing.icon{color:var(--_focus-trailing-icon-color)}:where(:active) .trailing.icon{color:var(--_pressed-trailing-icon-color)}:where(.disabled) .trailing.icon{color:var(--_disabled-trailing-icon-color);opacity:var(--_disabled-trailing-icon-opacity)}:where(.selected) .trailing.icon{color:var(--_selected-trailing-icon-color)}:where(.selected:hover) .trailing.icon{color:var(--_selected-hover-trailing-icon-color)}:where(.selected:focus) .trailing.icon{color:var(--_selected-focus-trailing-icon-color)}:where(.selected:active) .trailing.icon{color:var(--_selected-pressed-trailing-icon-color)}@media(forced-colors: active){.trailing.icon{color:ButtonText}:where(.disabled) .trailing.icon{color:GrayText;opacity:1}} +`;let ot=class extends ye{};ot.styles=[Je,sr,Dr,Fr,Jo],ot=o([b("md-filter-chip")],ot);class ge extends Or{constructor(){super(...arguments),this.avatar=!1,this.href="",this.target="",this.removeOnly=!1,this.selected=!1}get primaryId(){return this.href?"link":this.removeOnly?"":"button"}get rippleDisabled(){return!this.href&&(this.disabled||this.softDisabled)}get primaryAction(){return this.removeOnly?null:this.renderRoot.querySelector(".primary.action")}getContainerClasses(){return{...super.getContainerClasses(),avatar:this.avatar,disabled:!this.href&&(this.disabled||this.softDisabled),link:!!this.href,selected:this.selected,"has-trailing":!0}}renderPrimaryAction(e){const{ariaLabel:t}=this;return this.href?d` + ${e} + `:this.removeOnly?d` + + ${e} + + `:d` + + `}renderTrailingAction(e){return Lr({focusListener:e,ariaLabel:this.ariaLabelRemove,disabled:!this.href&&(this.disabled||this.softDisabled),tabbable:this.removeOnly})}}o([l({type:Boolean})],ge.prototype,"avatar",void 0),o([l()],ge.prototype,"href",void 0),o([l()],ge.prototype,"target",void 0),o([l({type:Boolean,attribute:"remove-only"})],ge.prototype,"removeOnly",void 0),o([l({type:Boolean,reflect:!0})],ge.prototype,"selected",void 0),o([g(".trailing.action")],ge.prototype,"trailingAction",void 0);const ei=v`:host{--_container-height: var(--md-input-chip-container-height, 32px);--_disabled-label-text-color: var(--md-input-chip-disabled-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-label-text-opacity: var(--md-input-chip-disabled-label-text-opacity, 0.38);--_disabled-selected-container-color: var(--md-input-chip-disabled-selected-container-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-selected-container-opacity: var(--md-input-chip-disabled-selected-container-opacity, 0.12);--_label-text-font: var(--md-input-chip-label-text-font, var(--md-sys-typescale-label-large-font, var(--md-ref-typeface-plain, Roboto)));--_label-text-line-height: var(--md-input-chip-label-text-line-height, var(--md-sys-typescale-label-large-line-height, 1.25rem));--_label-text-size: var(--md-input-chip-label-text-size, var(--md-sys-typescale-label-large-size, 0.875rem));--_label-text-weight: var(--md-input-chip-label-text-weight, var(--md-sys-typescale-label-large-weight, var(--md-ref-typeface-weight-medium, 500)));--_selected-container-color: var(--md-input-chip-selected-container-color, var(--md-sys-color-secondary-container, #e8def8));--_selected-focus-label-text-color: var(--md-input-chip-selected-focus-label-text-color, var(--md-sys-color-on-secondary-container, #1d192b));--_selected-hover-label-text-color: var(--md-input-chip-selected-hover-label-text-color, var(--md-sys-color-on-secondary-container, #1d192b));--_selected-hover-state-layer-color: var(--md-input-chip-selected-hover-state-layer-color, var(--md-sys-color-on-secondary-container, #1d192b));--_selected-hover-state-layer-opacity: var(--md-input-chip-selected-hover-state-layer-opacity, 0.08);--_selected-label-text-color: var(--md-input-chip-selected-label-text-color, var(--md-sys-color-on-secondary-container, #1d192b));--_selected-outline-width: var(--md-input-chip-selected-outline-width, 0px);--_selected-pressed-label-text-color: var(--md-input-chip-selected-pressed-label-text-color, var(--md-sys-color-on-secondary-container, #1d192b));--_selected-pressed-state-layer-color: var(--md-input-chip-selected-pressed-state-layer-color, var(--md-sys-color-on-secondary-container, #1d192b));--_selected-pressed-state-layer-opacity: var(--md-input-chip-selected-pressed-state-layer-opacity, 0.12);--_disabled-outline-color: var(--md-input-chip-disabled-outline-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-outline-opacity: var(--md-input-chip-disabled-outline-opacity, 0.12);--_focus-label-text-color: var(--md-input-chip-focus-label-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_focus-outline-color: var(--md-input-chip-focus-outline-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-label-text-color: var(--md-input-chip-hover-label-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-state-layer-color: var(--md-input-chip-hover-state-layer-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-state-layer-opacity: var(--md-input-chip-hover-state-layer-opacity, 0.08);--_label-text-color: var(--md-input-chip-label-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_outline-color: var(--md-input-chip-outline-color, var(--md-sys-color-outline, #79747e));--_outline-width: var(--md-input-chip-outline-width, 1px);--_pressed-label-text-color: var(--md-input-chip-pressed-label-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_pressed-state-layer-color: var(--md-input-chip-pressed-state-layer-color, var(--md-sys-color-on-surface-variant, #49454f));--_pressed-state-layer-opacity: var(--md-input-chip-pressed-state-layer-opacity, 0.12);--_avatar-shape: var(--md-input-chip-avatar-shape, var(--md-sys-shape-corner-full, 9999px));--_avatar-size: var(--md-input-chip-avatar-size, 24px);--_disabled-avatar-opacity: var(--md-input-chip-disabled-avatar-opacity, 0.38);--_disabled-leading-icon-color: var(--md-input-chip-disabled-leading-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-leading-icon-opacity: var(--md-input-chip-disabled-leading-icon-opacity, 0.38);--_icon-size: var(--md-input-chip-icon-size, 18px);--_selected-focus-leading-icon-color: var(--md-input-chip-selected-focus-leading-icon-color, var(--md-sys-color-primary, #6750a4));--_selected-hover-leading-icon-color: var(--md-input-chip-selected-hover-leading-icon-color, var(--md-sys-color-primary, #6750a4));--_selected-leading-icon-color: var(--md-input-chip-selected-leading-icon-color, var(--md-sys-color-primary, #6750a4));--_selected-pressed-leading-icon-color: var(--md-input-chip-selected-pressed-leading-icon-color, var(--md-sys-color-primary, #6750a4));--_focus-leading-icon-color: var(--md-input-chip-focus-leading-icon-color, var(--md-sys-color-primary, #6750a4));--_hover-leading-icon-color: var(--md-input-chip-hover-leading-icon-color, var(--md-sys-color-primary, #6750a4));--_leading-icon-color: var(--md-input-chip-leading-icon-color, var(--md-sys-color-primary, #6750a4));--_pressed-leading-icon-color: var(--md-input-chip-pressed-leading-icon-color, var(--md-sys-color-primary, #6750a4));--_disabled-trailing-icon-color: var(--md-input-chip-disabled-trailing-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-trailing-icon-opacity: var(--md-input-chip-disabled-trailing-icon-opacity, 0.38);--_selected-focus-trailing-icon-color: var(--md-input-chip-selected-focus-trailing-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_selected-hover-trailing-icon-color: var(--md-input-chip-selected-hover-trailing-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_selected-pressed-trailing-icon-color: var(--md-input-chip-selected-pressed-trailing-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_selected-trailing-icon-color: var(--md-input-chip-selected-trailing-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_focus-trailing-icon-color: var(--md-input-chip-focus-trailing-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-trailing-icon-color: var(--md-input-chip-hover-trailing-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_pressed-trailing-icon-color: var(--md-input-chip-pressed-trailing-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_trailing-icon-color: var(--md-input-chip-trailing-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_container-shape-start-start: var(--md-input-chip-container-shape-start-start, var(--md-input-chip-container-shape, var(--md-sys-shape-corner-small, 8px)));--_container-shape-start-end: var(--md-input-chip-container-shape-start-end, var(--md-input-chip-container-shape, var(--md-sys-shape-corner-small, 8px)));--_container-shape-end-end: var(--md-input-chip-container-shape-end-end, var(--md-input-chip-container-shape, var(--md-sys-shape-corner-small, 8px)));--_container-shape-end-start: var(--md-input-chip-container-shape-end-start, var(--md-input-chip-container-shape, var(--md-sys-shape-corner-small, 8px)));--_leading-space: var(--md-input-chip-leading-space, 16px);--_trailing-space: var(--md-input-chip-trailing-space, 16px);--_icon-label-space: var(--md-input-chip-icon-label-space, 8px);--_with-leading-icon-leading-space: var(--md-input-chip-with-leading-icon-leading-space, 8px);--_with-trailing-icon-trailing-space: var(--md-input-chip-with-trailing-icon-trailing-space, 8px)}:host([avatar]){--_container-shape-start-start: var( --md-input-chip-container-shape-start-start, var(--md-input-chip-container-shape, calc(var(--_container-height) / 2)) );--_container-shape-start-end: var( --md-input-chip-container-shape-start-end, var(--md-input-chip-container-shape, calc(var(--_container-height) / 2)) );--_container-shape-end-end: var( --md-input-chip-container-shape-end-end, var(--md-input-chip-container-shape, calc(var(--_container-height) / 2)) );--_container-shape-end-start: var( --md-input-chip-container-shape-end-start, var(--md-input-chip-container-shape, calc(var(--_container-height) / 2)) )}.avatar .primary.action{padding-inline-start:4px}.avatar .leading.icon ::slotted(:first-child){border-radius:var(--_avatar-shape);height:var(--_avatar-size);width:var(--_avatar-size)}.disabled.avatar .leading.icon{opacity:var(--_disabled-avatar-opacity)}@media(forced-colors: active){.link .outline{border-color:ActiveText}.disabled.avatar .leading.icon{opacity:1}} +`;let it=class extends ge{};it.styles=[Je,Dr,Fr,ei],it=o([b("md-input-chip")],it);class ti extends ke{}const ri=v`:host{--_container-height: var(--md-suggestion-chip-container-height, 32px);--_disabled-label-text-color: var(--md-suggestion-chip-disabled-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-label-text-opacity: var(--md-suggestion-chip-disabled-label-text-opacity, 0.38);--_elevated-container-color: var(--md-suggestion-chip-elevated-container-color, var(--md-sys-color-surface-container-low, #f7f2fa));--_elevated-container-elevation: var(--md-suggestion-chip-elevated-container-elevation, 1);--_elevated-container-shadow-color: var(--md-suggestion-chip-elevated-container-shadow-color, var(--md-sys-color-shadow, #000));--_elevated-disabled-container-color: var(--md-suggestion-chip-elevated-disabled-container-color, var(--md-sys-color-on-surface, #1d1b20));--_elevated-disabled-container-elevation: var(--md-suggestion-chip-elevated-disabled-container-elevation, 0);--_elevated-disabled-container-opacity: var(--md-suggestion-chip-elevated-disabled-container-opacity, 0.12);--_elevated-focus-container-elevation: var(--md-suggestion-chip-elevated-focus-container-elevation, 1);--_elevated-hover-container-elevation: var(--md-suggestion-chip-elevated-hover-container-elevation, 2);--_elevated-pressed-container-elevation: var(--md-suggestion-chip-elevated-pressed-container-elevation, 1);--_focus-label-text-color: var(--md-suggestion-chip-focus-label-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-label-text-color: var(--md-suggestion-chip-hover-label-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-state-layer-color: var(--md-suggestion-chip-hover-state-layer-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-state-layer-opacity: var(--md-suggestion-chip-hover-state-layer-opacity, 0.08);--_label-text-color: var(--md-suggestion-chip-label-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_label-text-font: var(--md-suggestion-chip-label-text-font, var(--md-sys-typescale-label-large-font, var(--md-ref-typeface-plain, Roboto)));--_label-text-line-height: var(--md-suggestion-chip-label-text-line-height, var(--md-sys-typescale-label-large-line-height, 1.25rem));--_label-text-size: var(--md-suggestion-chip-label-text-size, var(--md-sys-typescale-label-large-size, 0.875rem));--_label-text-weight: var(--md-suggestion-chip-label-text-weight, var(--md-sys-typescale-label-large-weight, var(--md-ref-typeface-weight-medium, 500)));--_pressed-label-text-color: var(--md-suggestion-chip-pressed-label-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_pressed-state-layer-color: var(--md-suggestion-chip-pressed-state-layer-color, var(--md-sys-color-on-surface-variant, #49454f));--_pressed-state-layer-opacity: var(--md-suggestion-chip-pressed-state-layer-opacity, 0.12);--_disabled-outline-color: var(--md-suggestion-chip-disabled-outline-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-outline-opacity: var(--md-suggestion-chip-disabled-outline-opacity, 0.12);--_focus-outline-color: var(--md-suggestion-chip-focus-outline-color, var(--md-sys-color-on-surface-variant, #49454f));--_outline-color: var(--md-suggestion-chip-outline-color, var(--md-sys-color-outline, #79747e));--_outline-width: var(--md-suggestion-chip-outline-width, 1px);--_disabled-leading-icon-color: var(--md-suggestion-chip-disabled-leading-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-leading-icon-opacity: var(--md-suggestion-chip-disabled-leading-icon-opacity, 0.38);--_focus-leading-icon-color: var(--md-suggestion-chip-focus-leading-icon-color, var(--md-sys-color-primary, #6750a4));--_hover-leading-icon-color: var(--md-suggestion-chip-hover-leading-icon-color, var(--md-sys-color-primary, #6750a4));--_leading-icon-color: var(--md-suggestion-chip-leading-icon-color, var(--md-sys-color-primary, #6750a4));--_pressed-leading-icon-color: var(--md-suggestion-chip-pressed-leading-icon-color, var(--md-sys-color-primary, #6750a4));--_icon-size: var(--md-suggestion-chip-icon-size, 18px);--_container-shape-start-start: var(--md-suggestion-chip-container-shape-start-start, var(--md-suggestion-chip-container-shape, var(--md-sys-shape-corner-small, 8px)));--_container-shape-start-end: var(--md-suggestion-chip-container-shape-start-end, var(--md-suggestion-chip-container-shape, var(--md-sys-shape-corner-small, 8px)));--_container-shape-end-end: var(--md-suggestion-chip-container-shape-end-end, var(--md-suggestion-chip-container-shape, var(--md-sys-shape-corner-small, 8px)));--_container-shape-end-start: var(--md-suggestion-chip-container-shape-end-start, var(--md-suggestion-chip-container-shape, var(--md-sys-shape-corner-small, 8px)));--_leading-space: var(--md-suggestion-chip-leading-space, 16px);--_trailing-space: var(--md-suggestion-chip-trailing-space, 16px);--_icon-label-space: var(--md-suggestion-chip-icon-label-space, 8px);--_with-leading-icon-leading-space: var(--md-suggestion-chip-with-leading-icon-leading-space, 8px)}@media(forced-colors: active){.link .outline{border-color:ActiveText}} +`;let at=class extends ti{};at.styles=[Je,sr,ri],at=o([b("md-suggestion-chip")],at);class lt extends _{constructor(){super(...arguments),this.inset=!1,this.insetStart=!1,this.insetEnd=!1}}o([l({type:Boolean,reflect:!0})],lt.prototype,"inset",void 0),o([l({type:Boolean,reflect:!0,attribute:"inset-start"})],lt.prototype,"insetStart",void 0),o([l({type:Boolean,reflect:!0,attribute:"inset-end"})],lt.prototype,"insetEnd",void 0);const oi=v`:host{box-sizing:border-box;color:var(--md-divider-color, var(--md-sys-color-outline-variant, #cac4d0));display:flex;height:var(--md-divider-thickness, 1px);width:100%}:host([inset]),:host([inset-start]){padding-inline-start:16px}:host([inset]),:host([inset-end]){padding-inline-end:16px}:host::before{background:currentColor;content:"";height:100%;width:100%}@media(forced-colors: active){:host::before{background:CanvasText}} +`;let nt=class extends lt{};nt.styles=[oi],nt=o([b("md-divider")],nt);const ii={dialog:[[[{transform:"translateY(-50px)"},{transform:"translateY(0)"}],{duration:500,easing:Z.EMPHASIZED}]],scrim:[[[{opacity:0},{opacity:.32}],{duration:500,easing:"linear"}]],container:[[[{opacity:0},{opacity:1}],{duration:50,easing:"linear",pseudoElement:"::before"}],[[{height:"35%"},{height:"100%"}],{duration:500,easing:Z.EMPHASIZED,pseudoElement:"::before"}]],headline:[[[{opacity:0},{opacity:0,offset:.2},{opacity:1}],{duration:250,easing:"linear",fill:"forwards"}]],content:[[[{opacity:0},{opacity:0,offset:.2},{opacity:1}],{duration:250,easing:"linear",fill:"forwards"}]],actions:[[[{opacity:0},{opacity:0,offset:.5},{opacity:1}],{duration:300,easing:"linear",fill:"forwards"}]]},ai={dialog:[[[{transform:"translateY(0)"},{transform:"translateY(-50px)"}],{duration:150,easing:Z.EMPHASIZED_ACCELERATE}]],scrim:[[[{opacity:.32},{opacity:0}],{duration:150,easing:"linear"}]],container:[[[{height:"100%"},{height:"35%"}],{duration:150,easing:Z.EMPHASIZED_ACCELERATE,pseudoElement:"::before"}],[[{opacity:"1"},{opacity:"0"}],{delay:100,duration:50,easing:"linear",pseudoElement:"::before"}]],headline:[[[{opacity:1},{opacity:0}],{duration:100,easing:"linear",fill:"forwards"}]],content:[[[{opacity:1},{opacity:0}],{duration:100,easing:"linear",fill:"forwards"}]],actions:[[[{opacity:1},{opacity:0}],{duration:100,easing:"linear",fill:"forwards"}]]};const li=W(_);class O extends li{get open(){return this.isOpen}set open(e){e!==this.isOpen&&(this.isOpen=e,e?(this.setAttribute("open",""),this.show()):(this.removeAttribute("open"),this.close()))}constructor(){super(),this.quick=!1,this.returnValue="",this.noFocusTrap=!1,this.getOpenAnimation=()=>ii,this.getCloseAnimation=()=>ai,this.isOpen=!1,this.isOpening=!1,this.isConnectedPromise=this.getIsConnectedPromise(),this.isAtScrollTop=!1,this.isAtScrollBottom=!1,this.nextClickIsFromContent=!1,this.hasHeadline=!1,this.hasActions=!1,this.hasIcon=!1,this.escapePressedWithoutCancel=!1,this.treewalker=T?null:document.createTreeWalker(this,NodeFilter.SHOW_ELEMENT),T||this.addEventListener("submit",this.handleSubmit)}async show(){this.isOpening=!0,await this.isConnectedPromise,await this.updateComplete;const e=this.dialog;if(e.open||!this.isOpening){this.isOpening=!1;return}if(!this.dispatchEvent(new Event("open",{cancelable:!0}))){this.open=!1,this.isOpening=!1;return}e.showModal(),this.open=!0,this.scroller&&(this.scroller.scrollTop=0),this.querySelector("[autofocus]")?.focus(),await this.animateDialog(this.getOpenAnimation()),this.dispatchEvent(new Event("opened")),this.isOpening=!1}async close(e=this.returnValue){if(this.isOpening=!1,!this.isConnected){this.open=!1;return}await this.updateComplete;const t=this.dialog;if(!t.open||this.isOpening){this.open=!1;return}const r=this.returnValue;if(this.returnValue=e,!this.dispatchEvent(new Event("close",{cancelable:!0}))){this.returnValue=r;return}await this.animateDialog(this.getCloseAnimation()),t.close(e),this.open=!1,this.dispatchEvent(new Event("closed"))}connectedCallback(){super.connectedCallback(),this.isConnectedPromiseResolve()}disconnectedCallback(){super.disconnectedCallback(),this.isConnectedPromise=this.getIsConnectedPromise()}render(){const e=this.open&&!(this.isAtScrollTop&&this.isAtScrollBottom),t={"has-headline":this.hasHeadline,"has-actions":this.hasActions,"has-icon":this.hasIcon,scrollable:e,"show-top-divider":e&&!this.isAtScrollTop,"show-bottom-divider":e&&!this.isAtScrollBottom},r=this.open&&!this.noFocusTrap,a=d` + + `,{ariaLabel:n}=this;return d` +
+ + ${r?a:c} +
+
+ +

+ +

+ +
+
+
+
+ +
+
+
+
+ + +
+
+ ${r?a:c} +
+ `}firstUpdated(){this.intersectionObserver=new IntersectionObserver(e=>{for(const t of e)this.handleAnchorIntersection(t)},{root:this.scroller}),this.intersectionObserver.observe(this.topAnchor),this.intersectionObserver.observe(this.bottomAnchor)}handleDialogClick(){if(this.nextClickIsFromContent){this.nextClickIsFromContent=!1;return}this.dispatchEvent(new Event("cancel",{cancelable:!0}))&&this.close()}handleContentClick(){this.nextClickIsFromContent=!0}handleSubmit(e){const t=e.target,{submitter:r}=e;t.getAttribute("method")!=="dialog"||!r||this.close(r.getAttribute("value")??this.returnValue)}handleCancel(e){if(e.target!==this.dialog)return;this.escapePressedWithoutCancel=!1;const t=!de(this,e);e.preventDefault(),!t&&this.close()}handleClose(){this.escapePressedWithoutCancel&&(this.escapePressedWithoutCancel=!1,this.dialog?.dispatchEvent(new Event("cancel",{cancelable:!0})))}handleKeydown(e){e.key==="Escape"&&(this.escapePressedWithoutCancel=!0,setTimeout(()=>{this.escapePressedWithoutCancel=!1}))}async animateDialog(e){if(this.cancelAnimations?.abort(),this.cancelAnimations=new AbortController,this.quick)return;const{dialog:t,scrim:r,container:a,headline:n,content:s,actions:h}=this;if(!t||!r||!a||!n||!s||!h)return;const{container:p,dialog:y,scrim:u,headline:f,content:m,actions:w}=e,L=[[t,y??[]],[r,u??[]],[a,p??[]],[n,f??[]],[s,m??[]],[h,w??[]]],E=[];for(const[A,F]of L)for(const I of F){const B=A.animate(...I);this.cancelAnimations.signal.addEventListener("abort",()=>{B.cancel()}),E.push(B)}await Promise.all(E.map(A=>A.finished.catch(()=>{})))}handleHeadlineChange(e){const t=e.target;this.hasHeadline=t.assignedElements().length>0}handleActionsChange(e){const t=e.target;this.hasActions=t.assignedElements().length>0}handleIconChange(e){const t=e.target;this.hasIcon=t.assignedElements().length>0}handleAnchorIntersection(e){const{target:t,isIntersecting:r}=e;t===this.topAnchor&&(this.isAtScrollTop=r),t===this.bottomAnchor&&(this.isAtScrollBottom=r)}getIsConnectedPromise(){return new Promise(e=>{this.isConnectedPromiseResolve=e})}handleFocusTrapFocus(e){const[t,r]=this.getFirstAndLastFocusableChildren();if(!t||!r){this.dialog?.focus();return}const a=e.target===this.firstFocusTrap,n=!a,s=e.relatedTarget===t,h=e.relatedTarget===r,p=!s&&!h;if(n&&h||a&&p){t.focus();return}if(a&&s||n&&p){r.focus();return}}getFirstAndLastFocusableChildren(){if(!this.treewalker)return[null,null];let e=null,t=null;for(this.treewalker.currentNode=this.treewalker.root;this.treewalker.nextNode();){const r=this.treewalker.currentNode;ni(r)&&(e||(e=r),t=r)}return[e,t]}}o([l({type:Boolean})],O.prototype,"open",null),o([l({type:Boolean})],O.prototype,"quick",void 0),o([l({attribute:!1})],O.prototype,"returnValue",void 0),o([l()],O.prototype,"type",void 0),o([l({type:Boolean,attribute:"no-focus-trap"})],O.prototype,"noFocusTrap",void 0),o([g("dialog")],O.prototype,"dialog",void 0),o([g(".scrim")],O.prototype,"scrim",void 0),o([g(".container")],O.prototype,"container",void 0),o([g(".headline")],O.prototype,"headline",void 0),o([g(".content")],O.prototype,"content",void 0),o([g(".actions")],O.prototype,"actions",void 0),o([k()],O.prototype,"isAtScrollTop",void 0),o([k()],O.prototype,"isAtScrollBottom",void 0),o([g(".scroller")],O.prototype,"scroller",void 0),o([g(".top.anchor")],O.prototype,"topAnchor",void 0),o([g(".bottom.anchor")],O.prototype,"bottomAnchor",void 0),o([g(".focus-trap")],O.prototype,"firstFocusTrap",void 0),o([k()],O.prototype,"hasHeadline",void 0),o([k()],O.prototype,"hasActions",void 0),o([k()],O.prototype,"hasIcon",void 0);function ni(i){const e=":is(button,input,select,textarea,object,:is(a,area)[href],[tabindex],[contenteditable=true])",t=":not(:disabled,[disabled])";return i.matches(e+t+':not([tabindex^="-"])')?!0:!i.localName.includes("-")||!i.matches(t)?!1:i.shadowRoot?.delegatesFocus??!1}const si=v`:host{border-start-start-radius:var(--md-dialog-container-shape-start-start, var(--md-dialog-container-shape, var(--md-sys-shape-corner-extra-large, 28px)));border-start-end-radius:var(--md-dialog-container-shape-start-end, var(--md-dialog-container-shape, var(--md-sys-shape-corner-extra-large, 28px)));border-end-end-radius:var(--md-dialog-container-shape-end-end, var(--md-dialog-container-shape, var(--md-sys-shape-corner-extra-large, 28px)));border-end-start-radius:var(--md-dialog-container-shape-end-start, var(--md-dialog-container-shape, var(--md-sys-shape-corner-extra-large, 28px)));display:contents;margin:auto;max-height:min(560px,100% - 48px);max-width:min(560px,100% - 48px);min-height:140px;min-width:280px;position:fixed;height:fit-content;width:fit-content}dialog{background:rgba(0,0,0,0);border:none;border-radius:inherit;flex-direction:column;height:inherit;margin:inherit;max-height:inherit;max-width:inherit;min-height:inherit;min-width:inherit;outline:none;overflow:visible;padding:0;width:inherit}dialog[open]{display:flex}::backdrop{background:none}.scrim{background:var(--md-sys-color-scrim, #000);display:none;inset:0;opacity:32%;pointer-events:none;position:fixed;z-index:1}:host([open]) .scrim{display:flex}h2{all:unset;align-self:stretch}.headline{align-items:center;color:var(--md-dialog-headline-color, var(--md-sys-color-on-surface, #1d1b20));display:flex;flex-direction:column;font-family:var(--md-dialog-headline-font, var(--md-sys-typescale-headline-small-font, var(--md-ref-typeface-brand, Roboto)));font-size:var(--md-dialog-headline-size, var(--md-sys-typescale-headline-small-size, 1.5rem));line-height:var(--md-dialog-headline-line-height, var(--md-sys-typescale-headline-small-line-height, 2rem));font-weight:var(--md-dialog-headline-weight, var(--md-sys-typescale-headline-small-weight, var(--md-ref-typeface-weight-regular, 400)));position:relative}slot[name=headline]::slotted(*){align-items:center;align-self:stretch;box-sizing:border-box;display:flex;gap:8px;padding:24px 24px 0}.icon{display:flex}slot[name=icon]::slotted(*){color:var(--md-dialog-icon-color, var(--md-sys-color-secondary, #625b71));fill:currentColor;font-size:var(--md-dialog-icon-size, 24px);margin-top:24px;height:var(--md-dialog-icon-size, 24px);width:var(--md-dialog-icon-size, 24px)}.has-icon slot[name=headline]::slotted(*){justify-content:center;padding-top:16px}.scrollable slot[name=headline]::slotted(*){padding-bottom:16px}.scrollable.has-headline slot[name=content]::slotted(*){padding-top:8px}.container{border-radius:inherit;display:flex;flex-direction:column;flex-grow:1;overflow:hidden;position:relative;transform-origin:top}.container::before{background:var(--md-dialog-container-color, var(--md-sys-color-surface-container-high, #ece6f0));border-radius:inherit;content:"";inset:0;position:absolute}.scroller{display:flex;flex:1;flex-direction:column;overflow:hidden;z-index:1}.scrollable .scroller{overflow-y:scroll}.content{color:var(--md-dialog-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));font-family:var(--md-dialog-supporting-text-font, var(--md-sys-typescale-body-medium-font, var(--md-ref-typeface-plain, Roboto)));font-size:var(--md-dialog-supporting-text-size, var(--md-sys-typescale-body-medium-size, 0.875rem));line-height:var(--md-dialog-supporting-text-line-height, var(--md-sys-typescale-body-medium-line-height, 1.25rem));flex:1;font-weight:var(--md-dialog-supporting-text-weight, var(--md-sys-typescale-body-medium-weight, var(--md-ref-typeface-weight-regular, 400)));height:min-content;position:relative}slot[name=content]::slotted(*){box-sizing:border-box;padding:24px}.anchor{position:absolute}.top.anchor{top:0}.bottom.anchor{bottom:0}.actions{position:relative}slot[name=actions]::slotted(*){box-sizing:border-box;display:flex;gap:8px;justify-content:flex-end;padding:16px 24px 24px}.has-actions slot[name=content]::slotted(*){padding-bottom:8px}md-divider{display:none;position:absolute}.has-headline.show-top-divider .headline md-divider,.has-actions.show-bottom-divider .actions md-divider{display:flex}.headline md-divider{bottom:0}.actions md-divider{top:0}@media(forced-colors: active){dialog{outline:2px solid WindowText}} +`;let st=class extends O{};st.styles=[si],st=o([b("md-dialog")],st);const di=W(_);class Le extends di{constructor(){super(...arguments),this.size="medium",this.label="",this.lowered=!1}render(){const{ariaLabel:e}=this;return d` + + `}getRenderClasses(){const e=!!this.label;return{lowered:this.lowered,small:this.size==="small"&&!e,large:this.size==="large"&&!e,extended:e}}renderTouchTarget(){return d`
`}renderLabel(){return this.label?d`${this.label}`:""}renderIcon(){const{ariaLabel:e}=this;return d` + + + + `}}Le.shadowRootOptions={mode:"open",delegatesFocus:!0},o([l({reflect:!0})],Le.prototype,"size",void 0),o([l()],Le.prototype,"label",void 0),o([l({type:Boolean})],Le.prototype,"lowered",void 0);class dr extends Le{constructor(){super(...arguments),this.variant="surface"}getRenderClasses(){return{...super.getRenderClasses(),primary:this.variant==="primary",secondary:this.variant==="secondary",tertiary:this.variant==="tertiary"}}}o([l()],dr.prototype,"variant",void 0);const ci=v`:host{--_container-color: var(--md-fab-branded-container-color, var(--md-sys-color-surface-container-high, #ece6f0));--_container-elevation: var(--md-fab-branded-container-elevation, 3);--_container-height: var(--md-fab-branded-container-height, 56px);--_container-shadow-color: var(--md-fab-branded-container-shadow-color, var(--md-sys-color-shadow, #000));--_container-width: var(--md-fab-branded-container-width, 56px);--_focus-container-elevation: var(--md-fab-branded-focus-container-elevation, 3);--_hover-container-elevation: var(--md-fab-branded-hover-container-elevation, 4);--_hover-state-layer-color: var(--md-fab-branded-hover-state-layer-color, var(--md-sys-color-primary, #6750a4));--_hover-state-layer-opacity: var(--md-fab-branded-hover-state-layer-opacity, 0.08);--_icon-size: var(--md-fab-branded-icon-size, 36px);--_lowered-container-color: var(--md-fab-branded-lowered-container-color, var(--md-sys-color-surface-container-low, #f7f2fa));--_lowered-container-elevation: var(--md-fab-branded-lowered-container-elevation, 1);--_lowered-focus-container-elevation: var(--md-fab-branded-lowered-focus-container-elevation, 1);--_lowered-hover-container-elevation: var(--md-fab-branded-lowered-hover-container-elevation, 2);--_lowered-pressed-container-elevation: var(--md-fab-branded-lowered-pressed-container-elevation, 1);--_pressed-container-elevation: var(--md-fab-branded-pressed-container-elevation, 3);--_pressed-state-layer-color: var(--md-fab-branded-pressed-state-layer-color, var(--md-sys-color-primary, #6750a4));--_pressed-state-layer-opacity: var(--md-fab-branded-pressed-state-layer-opacity, 0.12);--_focus-label-text-color: var(--md-fab-branded-focus-label-text-color, var(--md-sys-color-primary, #6750a4));--_hover-label-text-color: var(--md-fab-branded-hover-label-text-color, var(--md-sys-color-primary, #6750a4));--_label-text-color: var(--md-fab-branded-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_label-text-font: var(--md-fab-branded-label-text-font, var(--md-sys-typescale-label-large-font, var(--md-ref-typeface-plain, Roboto)));--_label-text-size: var(--md-fab-branded-label-text-size, var(--md-sys-typescale-label-large-size, 0.875rem));--_label-text-line-height: var(--md-fab-branded-label-text-line-height, var(--md-sys-typescale-label-large-line-height, 1.25rem));--_label-text-weight: var(--md-fab-branded-label-text-weight, var(--md-sys-typescale-label-large-weight, var(--md-ref-typeface-weight-medium, 500)));--_large-container-height: var(--md-fab-branded-large-container-height, 96px);--_large-container-width: var(--md-fab-branded-large-container-width, 96px);--_large-icon-size: var(--md-fab-branded-large-icon-size, 48px);--_pressed-label-text-color: var(--md-fab-branded-pressed-label-text-color, var(--md-sys-color-primary, #6750a4));--_container-shape-start-start: var(--md-fab-branded-container-shape-start-start, var(--md-fab-branded-container-shape, var(--md-sys-shape-corner-large, 16px)));--_container-shape-start-end: var(--md-fab-branded-container-shape-start-end, var(--md-fab-branded-container-shape, var(--md-sys-shape-corner-large, 16px)));--_container-shape-end-end: var(--md-fab-branded-container-shape-end-end, var(--md-fab-branded-container-shape, var(--md-sys-shape-corner-large, 16px)));--_container-shape-end-start: var(--md-fab-branded-container-shape-end-start, var(--md-fab-branded-container-shape, var(--md-sys-shape-corner-large, 16px)));--_large-container-shape-start-start: var(--md-fab-branded-large-container-shape-start-start, var(--md-fab-branded-large-container-shape, var(--md-sys-shape-corner-extra-large, 28px)));--_large-container-shape-start-end: var(--md-fab-branded-large-container-shape-start-end, var(--md-fab-branded-large-container-shape, var(--md-sys-shape-corner-extra-large, 28px)));--_large-container-shape-end-end: var(--md-fab-branded-large-container-shape-end-end, var(--md-fab-branded-large-container-shape, var(--md-sys-shape-corner-extra-large, 28px)));--_large-container-shape-end-start: var(--md-fab-branded-large-container-shape-end-start, var(--md-fab-branded-large-container-shape, var(--md-sys-shape-corner-extra-large, 28px)))} +`;const Pr=v`@media(forced-colors: active){.fab{border:1px solid ButtonText}.fab.extended{padding-inline-start:15px;padding-inline-end:19px}md-focus-ring{--md-focus-ring-outward-offset: 3px}} +`;const Mr=v`:host{--md-ripple-hover-opacity: var(--_hover-state-layer-opacity);--md-ripple-pressed-opacity: var(--_pressed-state-layer-opacity);display:inline-flex;-webkit-tap-highlight-color:rgba(0,0,0,0)}:host([size=medium][touch-target=wrapper]){margin:max(0px,48px - var(--_container-height))}:host([size=large][touch-target=wrapper]){margin:max(0px,48px - var(--_large-container-height))}.fab,.icon,.icon ::slotted(*){display:flex}.fab{align-items:center;justify-content:center;vertical-align:middle;padding:0;position:relative;height:var(--_container-height);transition-property:background-color;border-width:0px;outline:none;z-index:0;text-transform:inherit;--md-elevation-level: var(--_container-elevation);--md-elevation-shadow-color: var(--_container-shadow-color);background-color:var(--_container-color);--md-ripple-hover-color: var(--_hover-state-layer-color);--md-ripple-pressed-color: var(--_pressed-state-layer-color)}.fab.extended{width:inherit;box-sizing:border-box;padding-inline-start:16px;padding-inline-end:20px}.fab:not(.extended){width:var(--_container-width)}.fab.large{width:var(--_large-container-width);height:var(--_large-container-height)}.fab.large .icon ::slotted(*){width:var(--_large-icon-size);height:var(--_large-icon-size);font-size:var(--_large-icon-size)}.fab.large,.fab.large .ripple{border-start-start-radius:var(--_large-container-shape-start-start);border-start-end-radius:var(--_large-container-shape-start-end);border-end-start-radius:var(--_large-container-shape-end-start);border-end-end-radius:var(--_large-container-shape-end-end)}.fab.large md-focus-ring{--md-focus-ring-shape-start-start: var(--_large-container-shape-start-start);--md-focus-ring-shape-start-end: var(--_large-container-shape-start-end);--md-focus-ring-shape-end-end: var(--_large-container-shape-end-end);--md-focus-ring-shape-end-start: var(--_large-container-shape-end-start)}.fab:focus{--md-elevation-level: var(--_focus-container-elevation)}.fab:hover{--md-elevation-level: var(--_hover-container-elevation)}.fab:active{--md-elevation-level: var(--_pressed-container-elevation)}.fab.lowered{background-color:var(--_lowered-container-color);--md-elevation-level: var(--_lowered-container-elevation)}.fab.lowered:focus{--md-elevation-level: var(--_lowered-focus-container-elevation)}.fab.lowered:hover{--md-elevation-level: var(--_lowered-hover-container-elevation)}.fab.lowered:active{--md-elevation-level: var(--_lowered-pressed-container-elevation)}.fab .label{color:var(--_label-text-color)}.fab:hover .fab .label{color:var(--_hover-label-text-color)}.fab:focus .fab .label{color:var(--_focus-label-text-color)}.fab:active .fab .label{color:var(--_pressed-label-text-color)}.label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:var(--_label-text-font);font-size:var(--_label-text-size);line-height:var(--_label-text-line-height);font-weight:var(--_label-text-weight)}.fab.extended .icon ::slotted(*){margin-inline-end:12px}.ripple{overflow:hidden}.ripple,md-elevation{z-index:-1}.touch-target{position:absolute;top:50%;height:48px;left:50%;width:48px;transform:translate(-50%, -50%)}:host([touch-target=none]) .touch-target{display:none}md-elevation,.fab{transition-duration:280ms;transition-timing-function:cubic-bezier(0.2, 0, 0, 1)}.fab,.ripple{border-start-start-radius:var(--_container-shape-start-start);border-start-end-radius:var(--_container-shape-start-end);border-end-start-radius:var(--_container-shape-end-start);border-end-end-radius:var(--_container-shape-end-end)}md-focus-ring{--md-focus-ring-shape-start-start: var(--_container-shape-start-start);--md-focus-ring-shape-start-end: var(--_container-shape-start-end);--md-focus-ring-shape-end-end: var(--_container-shape-end-end);--md-focus-ring-shape-end-start: var(--_container-shape-end-start)}.icon ::slotted(*){width:var(--_icon-size);height:var(--_icon-size);font-size:var(--_icon-size)} +`;let dt=class extends dr{getRenderClasses(){return{...super.getRenderClasses(),primary:!1,secondary:!1,tertiary:!1,small:!1}}};dt.styles=[Mr,ci,Pr],dt=o([b("md-branded-fab")],dt);const hi=v`:host{--_container-color: var(--md-fab-container-color, var(--md-sys-color-surface-container-high, #ece6f0));--_container-elevation: var(--md-fab-container-elevation, 3);--_container-height: var(--md-fab-container-height, 56px);--_container-shadow-color: var(--md-fab-container-shadow-color, var(--md-sys-color-shadow, #000));--_container-width: var(--md-fab-container-width, 56px);--_focus-container-elevation: var(--md-fab-focus-container-elevation, 3);--_focus-icon-color: var(--md-fab-focus-icon-color, var(--md-sys-color-primary, #6750a4));--_hover-container-elevation: var(--md-fab-hover-container-elevation, 4);--_hover-icon-color: var(--md-fab-hover-icon-color, var(--md-sys-color-primary, #6750a4));--_hover-state-layer-color: var(--md-fab-hover-state-layer-color, var(--md-sys-color-primary, #6750a4));--_hover-state-layer-opacity: var(--md-fab-hover-state-layer-opacity, 0.08);--_icon-color: var(--md-fab-icon-color, var(--md-sys-color-primary, #6750a4));--_icon-size: var(--md-fab-icon-size, 24px);--_lowered-container-color: var(--md-fab-lowered-container-color, var(--md-sys-color-surface-container-low, #f7f2fa));--_lowered-container-elevation: var(--md-fab-lowered-container-elevation, 1);--_lowered-focus-container-elevation: var(--md-fab-lowered-focus-container-elevation, 1);--_lowered-hover-container-elevation: var(--md-fab-lowered-hover-container-elevation, 2);--_lowered-pressed-container-elevation: var(--md-fab-lowered-pressed-container-elevation, 1);--_pressed-container-elevation: var(--md-fab-pressed-container-elevation, 3);--_pressed-icon-color: var(--md-fab-pressed-icon-color, var(--md-sys-color-primary, #6750a4));--_pressed-state-layer-color: var(--md-fab-pressed-state-layer-color, var(--md-sys-color-primary, #6750a4));--_pressed-state-layer-opacity: var(--md-fab-pressed-state-layer-opacity, 0.12);--_focus-label-text-color: var(--md-fab-focus-label-text-color, var(--md-sys-color-primary, #6750a4));--_hover-label-text-color: var(--md-fab-hover-label-text-color, var(--md-sys-color-primary, #6750a4));--_label-text-color: var(--md-fab-label-text-color, var(--md-sys-color-primary, #6750a4));--_label-text-font: var(--md-fab-label-text-font, var(--md-sys-typescale-label-large-font, var(--md-ref-typeface-plain, Roboto)));--_label-text-line-height: var(--md-fab-label-text-line-height, var(--md-sys-typescale-label-large-line-height, 1.25rem));--_label-text-size: var(--md-fab-label-text-size, var(--md-sys-typescale-label-large-size, 0.875rem));--_label-text-weight: var(--md-fab-label-text-weight, var(--md-sys-typescale-label-large-weight, var(--md-ref-typeface-weight-medium, 500)));--_large-container-height: var(--md-fab-large-container-height, 96px);--_large-container-width: var(--md-fab-large-container-width, 96px);--_large-icon-size: var(--md-fab-large-icon-size, 36px);--_pressed-label-text-color: var(--md-fab-pressed-label-text-color, var(--md-sys-color-primary, #6750a4));--_primary-container-color: var(--md-fab-primary-container-color, var(--md-sys-color-primary-container, #eaddff));--_primary-focus-icon-color: var(--md-fab-primary-focus-icon-color, var(--md-sys-color-on-primary-container, #21005d));--_primary-focus-label-text-color: var(--md-fab-primary-focus-label-text-color, var(--md-sys-color-on-primary-container, #21005d));--_primary-hover-icon-color: var(--md-fab-primary-hover-icon-color, var(--md-sys-color-on-primary-container, #21005d));--_primary-hover-label-text-color: var(--md-fab-primary-hover-label-text-color, var(--md-sys-color-on-primary-container, #21005d));--_primary-hover-state-layer-color: var(--md-fab-primary-hover-state-layer-color, var(--md-sys-color-on-primary-container, #21005d));--_primary-icon-color: var(--md-fab-primary-icon-color, var(--md-sys-color-on-primary-container, #21005d));--_primary-label-text-color: var(--md-fab-primary-label-text-color, var(--md-sys-color-on-primary-container, #21005d));--_primary-pressed-icon-color: var(--md-fab-primary-pressed-icon-color, var(--md-sys-color-on-primary-container, #21005d));--_primary-pressed-label-text-color: var(--md-fab-primary-pressed-label-text-color, var(--md-sys-color-on-primary-container, #21005d));--_primary-pressed-state-layer-color: var(--md-fab-primary-pressed-state-layer-color, var(--md-sys-color-on-primary-container, #21005d));--_secondary-container-color: var(--md-fab-secondary-container-color, var(--md-sys-color-secondary-container, #e8def8));--_secondary-focus-icon-color: var(--md-fab-secondary-focus-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_secondary-focus-label-text-color: var(--md-fab-secondary-focus-label-text-color, var(--md-sys-color-on-secondary-container, #1d192b));--_secondary-hover-icon-color: var(--md-fab-secondary-hover-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_secondary-hover-label-text-color: var(--md-fab-secondary-hover-label-text-color, var(--md-sys-color-on-secondary-container, #1d192b));--_secondary-hover-state-layer-color: var(--md-fab-secondary-hover-state-layer-color, var(--md-sys-color-on-secondary-container, #1d192b));--_secondary-icon-color: var(--md-fab-secondary-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_secondary-label-text-color: var(--md-fab-secondary-label-text-color, var(--md-sys-color-on-secondary-container, #1d192b));--_secondary-pressed-icon-color: var(--md-fab-secondary-pressed-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_secondary-pressed-label-text-color: var(--md-fab-secondary-pressed-label-text-color, var(--md-sys-color-on-secondary-container, #1d192b));--_secondary-pressed-state-layer-color: var(--md-fab-secondary-pressed-state-layer-color, var(--md-sys-color-on-secondary-container, #1d192b));--_small-container-height: var(--md-fab-small-container-height, 40px);--_small-container-width: var(--md-fab-small-container-width, 40px);--_small-icon-size: var(--md-fab-small-icon-size, 24px);--_tertiary-container-color: var(--md-fab-tertiary-container-color, var(--md-sys-color-tertiary-container, #ffd8e4));--_tertiary-focus-icon-color: var(--md-fab-tertiary-focus-icon-color, var(--md-sys-color-on-tertiary-container, #31111d));--_tertiary-focus-label-text-color: var(--md-fab-tertiary-focus-label-text-color, var(--md-sys-color-on-tertiary-container, #31111d));--_tertiary-hover-icon-color: var(--md-fab-tertiary-hover-icon-color, var(--md-sys-color-on-tertiary-container, #31111d));--_tertiary-hover-label-text-color: var(--md-fab-tertiary-hover-label-text-color, var(--md-sys-color-on-tertiary-container, #31111d));--_tertiary-hover-state-layer-color: var(--md-fab-tertiary-hover-state-layer-color, var(--md-sys-color-on-tertiary-container, #31111d));--_tertiary-icon-color: var(--md-fab-tertiary-icon-color, var(--md-sys-color-on-tertiary-container, #31111d));--_tertiary-label-text-color: var(--md-fab-tertiary-label-text-color, var(--md-sys-color-on-tertiary-container, #31111d));--_tertiary-pressed-icon-color: var(--md-fab-tertiary-pressed-icon-color, var(--md-sys-color-on-tertiary-container, #31111d));--_tertiary-pressed-label-text-color: var(--md-fab-tertiary-pressed-label-text-color, var(--md-sys-color-on-tertiary-container, #31111d));--_tertiary-pressed-state-layer-color: var(--md-fab-tertiary-pressed-state-layer-color, var(--md-sys-color-on-tertiary-container, #31111d));--_container-shape-start-start: var(--md-fab-container-shape-start-start, var(--md-fab-container-shape, var(--md-sys-shape-corner-large, 16px)));--_container-shape-start-end: var(--md-fab-container-shape-start-end, var(--md-fab-container-shape, var(--md-sys-shape-corner-large, 16px)));--_container-shape-end-end: var(--md-fab-container-shape-end-end, var(--md-fab-container-shape, var(--md-sys-shape-corner-large, 16px)));--_container-shape-end-start: var(--md-fab-container-shape-end-start, var(--md-fab-container-shape, var(--md-sys-shape-corner-large, 16px)));--_large-container-shape-start-start: var(--md-fab-large-container-shape-start-start, var(--md-fab-large-container-shape, var(--md-sys-shape-corner-extra-large, 28px)));--_large-container-shape-start-end: var(--md-fab-large-container-shape-start-end, var(--md-fab-large-container-shape, var(--md-sys-shape-corner-extra-large, 28px)));--_large-container-shape-end-end: var(--md-fab-large-container-shape-end-end, var(--md-fab-large-container-shape, var(--md-sys-shape-corner-extra-large, 28px)));--_large-container-shape-end-start: var(--md-fab-large-container-shape-end-start, var(--md-fab-large-container-shape, var(--md-sys-shape-corner-extra-large, 28px)));--_small-container-shape-start-start: var(--md-fab-small-container-shape-start-start, var(--md-fab-small-container-shape, var(--md-sys-shape-corner-medium, 12px)));--_small-container-shape-start-end: var(--md-fab-small-container-shape-start-end, var(--md-fab-small-container-shape, var(--md-sys-shape-corner-medium, 12px)));--_small-container-shape-end-end: var(--md-fab-small-container-shape-end-end, var(--md-fab-small-container-shape, var(--md-sys-shape-corner-medium, 12px)));--_small-container-shape-end-start: var(--md-fab-small-container-shape-end-start, var(--md-fab-small-container-shape, var(--md-sys-shape-corner-medium, 12px)));cursor:pointer}:host([size=small][touch-target=wrapper]){margin:max(0px,48px - var(--_small-container-height))}.fab{cursor:inherit}.fab .icon ::slotted(*){color:var(--_icon-color)}.fab:focus{color:var(--_focus-icon-color)}.fab:hover{color:var(--_hover-icon-color)}.fab:active{color:var(--_pressed-icon-color)}.fab.primary{background-color:var(--_primary-container-color);--md-ripple-hover-color: var(--_primary-hover-state-layer-color);--md-ripple-pressed-color: var(--_primary-pressed-state-layer-color)}.fab.primary .icon ::slotted(*){color:var(--_primary-icon-color)}.fab.primary:focus{color:var(--_primary-focus-icon-color)}.fab.primary:hover{color:var(--_primary-hover-icon-color)}.fab.primary:active{color:var(--_primary-pressed-icon-color)}.fab.primary .label{color:var(--_primary-label-text-color)}.fab:hover .fab.primary .label{color:var(--_primary-hover-label-text-color)}.fab:focus .fab.primary .label{color:var(--_primary-focus-label-text-color)}.fab:active .fab.primary .label{color:var(--_primary-pressed-label-text-color)}.fab.secondary{background-color:var(--_secondary-container-color);--md-ripple-hover-color: var(--_secondary-hover-state-layer-color);--md-ripple-pressed-color: var(--_secondary-pressed-state-layer-color)}.fab.secondary .icon ::slotted(*){color:var(--_secondary-icon-color)}.fab.secondary:focus{color:var(--_secondary-focus-icon-color)}.fab.secondary:hover{color:var(--_secondary-hover-icon-color)}.fab.secondary:active{color:var(--_secondary-pressed-icon-color)}.fab.secondary .label{color:var(--_secondary-label-text-color)}.fab:hover .fab.secondary .label{color:var(--_secondary-hover-label-text-color)}.fab:focus .fab.secondary .label{color:var(--_secondary-focus-label-text-color)}.fab:active .fab.secondary .label{color:var(--_secondary-pressed-label-text-color)}.fab.tertiary{background-color:var(--_tertiary-container-color);--md-ripple-hover-color: var(--_tertiary-hover-state-layer-color);--md-ripple-pressed-color: var(--_tertiary-pressed-state-layer-color)}.fab.tertiary .icon ::slotted(*){color:var(--_tertiary-icon-color)}.fab.tertiary:focus{color:var(--_tertiary-focus-icon-color)}.fab.tertiary:hover{color:var(--_tertiary-hover-icon-color)}.fab.tertiary:active{color:var(--_tertiary-pressed-icon-color)}.fab.tertiary .label{color:var(--_tertiary-label-text-color)}.fab:hover .fab.tertiary .label{color:var(--_tertiary-hover-label-text-color)}.fab:focus .fab.tertiary .label{color:var(--_tertiary-focus-label-text-color)}.fab:active .fab.tertiary .label{color:var(--_tertiary-pressed-label-text-color)}.fab.extended slot span{padding-inline-start:4px}.fab.small{width:var(--_small-container-width);height:var(--_small-container-height)}.fab.small .icon ::slotted(*){width:var(--_small-icon-size);height:var(--_small-icon-size);font-size:var(--_small-icon-size)}.fab.small,.fab.small .ripple{border-start-start-radius:var(--_small-container-shape-start-start);border-start-end-radius:var(--_small-container-shape-start-end);border-end-start-radius:var(--_small-container-shape-end-start);border-end-end-radius:var(--_small-container-shape-end-end)}.fab.small md-focus-ring{--md-focus-ring-shape-start-start: var(--_small-container-shape-start-start);--md-focus-ring-shape-start-end: var(--_small-container-shape-start-end);--md-focus-ring-shape-end-end: var(--_small-container-shape-end-end);--md-focus-ring-shape-end-start: var(--_small-container-shape-end-start)} +`;let ct=class extends dr{};ct.styles=[Mr,hi,Pr],ct=o([b("md-fab")],ct);class $ extends _{constructor(){super(...arguments),this.disabled=!1,this.error=!1,this.focused=!1,this.label="",this.noAsterisk=!1,this.populated=!1,this.required=!1,this.resizable=!1,this.supportingText="",this.errorText="",this.count=-1,this.max=-1,this.hasStart=!1,this.hasEnd=!1,this.isAnimating=!1,this.refreshErrorAlert=!1,this.disableTransitions=!1}get counterText(){const e=this.count??-1,t=this.max??-1;return e<0||t<=0?"":`${e} / ${t}`}get supportingOrErrorText(){return this.error&&this.errorText?this.errorText:this.supportingText}reannounceError(){this.refreshErrorAlert=!0}update(e){e.has("disabled")&&e.get("disabled")!==void 0&&(this.disableTransitions=!0),this.disabled&&this.focused&&(e.set("focused",!0),this.focused=!1),this.animateLabelIfNeeded({wasFocused:e.get("focused"),wasPopulated:e.get("populated")}),super.update(e)}render(){const e=this.renderLabel(!0),t=this.renderLabel(!1),r=this.renderOutline?.(e),a={disabled:this.disabled,"disable-transitions":this.disableTransitions,error:this.error&&!this.disabled,focused:this.focused,"with-start":this.hasStart,"with-end":this.hasEnd,populated:this.populated,resizable:this.resizable,required:this.required,"no-label":!this.label};return d` +
+
+ ${this.renderBackground?.()} + + ${this.renderStateLayer?.()} ${this.renderIndicator?.()} ${r} +
+
+ +
+
+
+ ${t} ${r?c:e} +
+
+ +
+
+
+ +
+
+
+ ${this.renderSupportingText()} +
+ `}updated(e){(e.has("supportingText")||e.has("errorText")||e.has("count")||e.has("max"))&&this.updateSlottedAriaDescribedBy(),this.refreshErrorAlert&&requestAnimationFrame(()=>{this.refreshErrorAlert=!1}),this.disableTransitions&&requestAnimationFrame(()=>{this.disableTransitions=!1})}renderSupportingText(){const{supportingOrErrorText:e,counterText:t}=this;if(!e&&!t)return c;const r=d`${e}`,a=t?d`${t}`:c,s=this.error&&this.errorText&&!this.refreshErrorAlert?"alert":c;return d` +
${r}${a}
+ + `}updateSlottedAriaDescribedBy(){for(const e of this.slottedAriaDescribedBy)_r(d`${this.supportingOrErrorText} ${this.counterText}`,e),e.setAttribute("hidden","")}renderLabel(e){if(!this.label)return c;let t;e?t=this.focused||this.populated||this.isAnimating:t=!this.focused&&!this.populated&&!this.isAnimating;const r={hidden:!t,floating:e,resting:!e},a=`${this.label}${this.required&&!this.noAsterisk?"*":""}`;return d` + ${a} + `}animateLabelIfNeeded({wasFocused:e,wasPopulated:t}){if(!this.label)return;e??=this.focused,t??=this.populated;const r=e||t,a=this.focused||this.populated;r!==a&&(this.isAnimating=!0,this.labelAnimation?.cancel(),this.labelAnimation=this.floatingLabelEl?.animate(this.getLabelKeyframes(),{duration:150,easing:Z.STANDARD}),this.labelAnimation?.addEventListener("finish",()=>{this.isAnimating=!1}))}getLabelKeyframes(){const{floatingLabelEl:e,restingLabelEl:t}=this;if(!e||!t)return[];const{x:r,y:a,height:n}=e.getBoundingClientRect(),{x:s,y:h,height:p}=t.getBoundingClientRect(),y=e.scrollWidth,u=t.scrollWidth,f=u/y,m=s-r,w=h-a+Math.round((p-n*f)/2),L=`translateX(${m}px) translateY(${w}px) scale(${f})`,E="translateX(0) translateY(0) scale(1)",A=t.clientWidth,I=u>A?`${A/f}px`:"";return this.focused||this.populated?[{transform:L,width:I},{transform:E,width:I}]:[{transform:E,width:I},{transform:L,width:I}]}getSurfacePositionClientRect(){return this.containerEl.getBoundingClientRect()}}o([l({type:Boolean})],$.prototype,"disabled",void 0),o([l({type:Boolean})],$.prototype,"error",void 0),o([l({type:Boolean})],$.prototype,"focused",void 0),o([l()],$.prototype,"label",void 0),o([l({type:Boolean,attribute:"no-asterisk"})],$.prototype,"noAsterisk",void 0),o([l({type:Boolean})],$.prototype,"populated",void 0),o([l({type:Boolean})],$.prototype,"required",void 0),o([l({type:Boolean})],$.prototype,"resizable",void 0),o([l({attribute:"supporting-text"})],$.prototype,"supportingText",void 0),o([l({attribute:"error-text"})],$.prototype,"errorText",void 0),o([l({type:Number})],$.prototype,"count",void 0),o([l({type:Number})],$.prototype,"max",void 0),o([l({type:Boolean,attribute:"has-start"})],$.prototype,"hasStart",void 0),o([l({type:Boolean,attribute:"has-end"})],$.prototype,"hasEnd",void 0),o([H({slot:"aria-describedby"})],$.prototype,"slottedAriaDescribedBy",void 0),o([k()],$.prototype,"isAnimating",void 0),o([k()],$.prototype,"refreshErrorAlert",void 0),o([k()],$.prototype,"disableTransitions",void 0),o([g(".label.floating")],$.prototype,"floatingLabelEl",void 0),o([g(".label.resting")],$.prototype,"restingLabelEl",void 0),o([g(".container")],$.prototype,"containerEl",void 0);class pi extends ${renderBackground(){return d`
`}renderStateLayer(){return d`
`}renderIndicator(){return d`
`}}const vi=v`@layer styles{:host{--_active-indicator-color: var(--md-filled-field-active-indicator-color, var(--md-sys-color-on-surface-variant, #49454f));--_active-indicator-height: var(--md-filled-field-active-indicator-height, 1px);--_bottom-space: var(--md-filled-field-bottom-space, 16px);--_container-color: var(--md-filled-field-container-color, var(--md-sys-color-surface-container-highest, #e6e0e9));--_content-color: var(--md-filled-field-content-color, var(--md-sys-color-on-surface, #1d1b20));--_content-font: var(--md-filled-field-content-font, var(--md-sys-typescale-body-large-font, var(--md-ref-typeface-plain, Roboto)));--_content-line-height: var(--md-filled-field-content-line-height, var(--md-sys-typescale-body-large-line-height, 1.5rem));--_content-size: var(--md-filled-field-content-size, var(--md-sys-typescale-body-large-size, 1rem));--_content-space: var(--md-filled-field-content-space, 16px);--_content-weight: var(--md-filled-field-content-weight, var(--md-sys-typescale-body-large-weight, var(--md-ref-typeface-weight-regular, 400)));--_disabled-active-indicator-color: var(--md-filled-field-disabled-active-indicator-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-active-indicator-height: var(--md-filled-field-disabled-active-indicator-height, 1px);--_disabled-active-indicator-opacity: var(--md-filled-field-disabled-active-indicator-opacity, 0.38);--_disabled-container-color: var(--md-filled-field-disabled-container-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-container-opacity: var(--md-filled-field-disabled-container-opacity, 0.04);--_disabled-content-color: var(--md-filled-field-disabled-content-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-content-opacity: var(--md-filled-field-disabled-content-opacity, 0.38);--_disabled-label-text-color: var(--md-filled-field-disabled-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-label-text-opacity: var(--md-filled-field-disabled-label-text-opacity, 0.38);--_disabled-leading-content-color: var(--md-filled-field-disabled-leading-content-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-leading-content-opacity: var(--md-filled-field-disabled-leading-content-opacity, 0.38);--_disabled-supporting-text-color: var(--md-filled-field-disabled-supporting-text-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-supporting-text-opacity: var(--md-filled-field-disabled-supporting-text-opacity, 0.38);--_disabled-trailing-content-color: var(--md-filled-field-disabled-trailing-content-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-trailing-content-opacity: var(--md-filled-field-disabled-trailing-content-opacity, 0.38);--_error-active-indicator-color: var(--md-filled-field-error-active-indicator-color, var(--md-sys-color-error, #b3261e));--_error-content-color: var(--md-filled-field-error-content-color, var(--md-sys-color-on-surface, #1d1b20));--_error-focus-active-indicator-color: var(--md-filled-field-error-focus-active-indicator-color, var(--md-sys-color-error, #b3261e));--_error-focus-content-color: var(--md-filled-field-error-focus-content-color, var(--md-sys-color-on-surface-variant, #49454f));--_error-focus-label-text-color: var(--md-filled-field-error-focus-label-text-color, var(--md-sys-color-error, #b3261e));--_error-focus-leading-content-color: var(--md-filled-field-error-focus-leading-content-color, var(--md-sys-color-on-surface-variant, #49454f));--_error-focus-supporting-text-color: var(--md-filled-field-error-focus-supporting-text-color, var(--md-sys-color-error, #b3261e));--_error-focus-trailing-content-color: var(--md-filled-field-error-focus-trailing-content-color, var(--md-sys-color-error, #b3261e));--_error-hover-active-indicator-color: var(--md-filled-field-error-hover-active-indicator-color, var(--md-sys-color-on-error-container, #410e0b));--_error-hover-content-color: var(--md-filled-field-error-hover-content-color, var(--md-sys-color-on-surface, #1d1b20));--_error-hover-label-text-color: var(--md-filled-field-error-hover-label-text-color, var(--md-sys-color-on-error-container, #410e0b));--_error-hover-leading-content-color: var(--md-filled-field-error-hover-leading-content-color, var(--md-sys-color-on-surface-variant, #49454f));--_error-hover-state-layer-color: var(--md-filled-field-error-hover-state-layer-color, var(--md-sys-color-on-surface, #1d1b20));--_error-hover-state-layer-opacity: var(--md-filled-field-error-hover-state-layer-opacity, 0.08);--_error-hover-supporting-text-color: var(--md-filled-field-error-hover-supporting-text-color, var(--md-sys-color-error, #b3261e));--_error-hover-trailing-content-color: var(--md-filled-field-error-hover-trailing-content-color, var(--md-sys-color-on-error-container, #410e0b));--_error-label-text-color: var(--md-filled-field-error-label-text-color, var(--md-sys-color-error, #b3261e));--_error-leading-content-color: var(--md-filled-field-error-leading-content-color, var(--md-sys-color-on-surface-variant, #49454f));--_error-supporting-text-color: var(--md-filled-field-error-supporting-text-color, var(--md-sys-color-error, #b3261e));--_error-trailing-content-color: var(--md-filled-field-error-trailing-content-color, var(--md-sys-color-error, #b3261e));--_focus-active-indicator-color: var(--md-filled-field-focus-active-indicator-color, var(--md-sys-color-primary, #6750a4));--_focus-active-indicator-height: var(--md-filled-field-focus-active-indicator-height, 3px);--_focus-content-color: var(--md-filled-field-focus-content-color, var(--md-sys-color-on-surface, #1d1b20));--_focus-label-text-color: var(--md-filled-field-focus-label-text-color, var(--md-sys-color-primary, #6750a4));--_focus-leading-content-color: var(--md-filled-field-focus-leading-content-color, var(--md-sys-color-on-surface-variant, #49454f));--_focus-supporting-text-color: var(--md-filled-field-focus-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_focus-trailing-content-color: var(--md-filled-field-focus-trailing-content-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-active-indicator-color: var(--md-filled-field-hover-active-indicator-color, var(--md-sys-color-on-surface, #1d1b20));--_hover-active-indicator-height: var(--md-filled-field-hover-active-indicator-height, 1px);--_hover-content-color: var(--md-filled-field-hover-content-color, var(--md-sys-color-on-surface, #1d1b20));--_hover-label-text-color: var(--md-filled-field-hover-label-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-leading-content-color: var(--md-filled-field-hover-leading-content-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-state-layer-color: var(--md-filled-field-hover-state-layer-color, var(--md-sys-color-on-surface, #1d1b20));--_hover-state-layer-opacity: var(--md-filled-field-hover-state-layer-opacity, 0.08);--_hover-supporting-text-color: var(--md-filled-field-hover-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-trailing-content-color: var(--md-filled-field-hover-trailing-content-color, var(--md-sys-color-on-surface-variant, #49454f));--_label-text-color: var(--md-filled-field-label-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_label-text-font: var(--md-filled-field-label-text-font, var(--md-sys-typescale-body-large-font, var(--md-ref-typeface-plain, Roboto)));--_label-text-line-height: var(--md-filled-field-label-text-line-height, var(--md-sys-typescale-body-large-line-height, 1.5rem));--_label-text-populated-line-height: var(--md-filled-field-label-text-populated-line-height, var(--md-sys-typescale-body-small-line-height, 1rem));--_label-text-populated-size: var(--md-filled-field-label-text-populated-size, var(--md-sys-typescale-body-small-size, 0.75rem));--_label-text-size: var(--md-filled-field-label-text-size, var(--md-sys-typescale-body-large-size, 1rem));--_label-text-weight: var(--md-filled-field-label-text-weight, var(--md-sys-typescale-body-large-weight, var(--md-ref-typeface-weight-regular, 400)));--_leading-content-color: var(--md-filled-field-leading-content-color, var(--md-sys-color-on-surface-variant, #49454f));--_leading-space: var(--md-filled-field-leading-space, 16px);--_supporting-text-color: var(--md-filled-field-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_supporting-text-font: var(--md-filled-field-supporting-text-font, var(--md-sys-typescale-body-small-font, var(--md-ref-typeface-plain, Roboto)));--_supporting-text-leading-space: var(--md-filled-field-supporting-text-leading-space, 16px);--_supporting-text-line-height: var(--md-filled-field-supporting-text-line-height, var(--md-sys-typescale-body-small-line-height, 1rem));--_supporting-text-size: var(--md-filled-field-supporting-text-size, var(--md-sys-typescale-body-small-size, 0.75rem));--_supporting-text-top-space: var(--md-filled-field-supporting-text-top-space, 4px);--_supporting-text-trailing-space: var(--md-filled-field-supporting-text-trailing-space, 16px);--_supporting-text-weight: var(--md-filled-field-supporting-text-weight, var(--md-sys-typescale-body-small-weight, var(--md-ref-typeface-weight-regular, 400)));--_top-space: var(--md-filled-field-top-space, 16px);--_trailing-content-color: var(--md-filled-field-trailing-content-color, var(--md-sys-color-on-surface-variant, #49454f));--_trailing-space: var(--md-filled-field-trailing-space, 16px);--_with-label-bottom-space: var(--md-filled-field-with-label-bottom-space, 8px);--_with-label-top-space: var(--md-filled-field-with-label-top-space, 8px);--_with-leading-content-leading-space: var(--md-filled-field-with-leading-content-leading-space, 12px);--_with-trailing-content-trailing-space: var(--md-filled-field-with-trailing-content-trailing-space, 12px);--_container-shape-start-start: var(--md-filled-field-container-shape-start-start, var(--md-filled-field-container-shape, var(--md-sys-shape-corner-extra-small, 4px)));--_container-shape-start-end: var(--md-filled-field-container-shape-start-end, var(--md-filled-field-container-shape, var(--md-sys-shape-corner-extra-small, 4px)));--_container-shape-end-end: var(--md-filled-field-container-shape-end-end, var(--md-filled-field-container-shape, var(--md-sys-shape-corner-none, 0px)));--_container-shape-end-start: var(--md-filled-field-container-shape-end-start, var(--md-filled-field-container-shape, var(--md-sys-shape-corner-none, 0px)))}.background,.state-layer{border-radius:inherit;inset:0;pointer-events:none;position:absolute}.background{background:var(--_container-color)}.state-layer{visibility:hidden}.field:not(.disabled):hover .state-layer{visibility:visible}.label.floating{position:absolute;top:var(--_with-label-top-space)}.field:not(.with-start) .label-wrapper{margin-inline-start:var(--_leading-space)}.field:not(.with-end) .label-wrapper{margin-inline-end:var(--_trailing-space)}.active-indicator{inset:auto 0 0 0;pointer-events:none;position:absolute;width:100%;z-index:1}.active-indicator::before,.active-indicator::after{border-bottom:var(--_active-indicator-height) solid var(--_active-indicator-color);inset:auto 0 0 0;content:"";position:absolute;width:100%}.active-indicator::after{opacity:0;transition:opacity 150ms cubic-bezier(0.2, 0, 0, 1)}.focused .active-indicator::after{opacity:1}.field:not(.with-start) .content ::slotted(*){padding-inline-start:var(--_leading-space)}.field:not(.with-end) .content ::slotted(*){padding-inline-end:var(--_trailing-space)}.field:not(.no-label) .content ::slotted(:not(textarea)){padding-bottom:var(--_with-label-bottom-space);padding-top:calc(var(--_with-label-top-space) + var(--_label-text-populated-line-height))}.field:not(.no-label) .content ::slotted(textarea){margin-bottom:var(--_with-label-bottom-space);margin-top:calc(var(--_with-label-top-space) + var(--_label-text-populated-line-height))}:hover .active-indicator::before{border-bottom-color:var(--_hover-active-indicator-color);border-bottom-width:var(--_hover-active-indicator-height)}.active-indicator::after{border-bottom-color:var(--_focus-active-indicator-color);border-bottom-width:var(--_focus-active-indicator-height)}:hover .state-layer{background:var(--_hover-state-layer-color);opacity:var(--_hover-state-layer-opacity)}.disabled .active-indicator::before{border-bottom-color:var(--_disabled-active-indicator-color);border-bottom-width:var(--_disabled-active-indicator-height);opacity:var(--_disabled-active-indicator-opacity)}.disabled .background{background:var(--_disabled-container-color);opacity:var(--_disabled-container-opacity)}.error .active-indicator::before{border-bottom-color:var(--_error-active-indicator-color)}.error:hover .active-indicator::before{border-bottom-color:var(--_error-hover-active-indicator-color)}.error:hover .state-layer{background:var(--_error-hover-state-layer-color);opacity:var(--_error-hover-state-layer-opacity)}.error .active-indicator::after{border-bottom-color:var(--_error-focus-active-indicator-color)}.resizable .container{bottom:var(--_focus-active-indicator-height);clip-path:inset(var(--_focus-active-indicator-height) 0 0 0)}.resizable .container>*{top:var(--_focus-active-indicator-height)}}@layer hcm{@media(forced-colors: active){.disabled .active-indicator::before{border-color:GrayText;opacity:1}}} +`;const Br=v`:host{display:inline-flex;resize:both}.field{display:flex;flex:1;flex-direction:column;writing-mode:horizontal-tb;max-width:100%}.container-overflow{border-start-start-radius:var(--_container-shape-start-start);border-start-end-radius:var(--_container-shape-start-end);border-end-end-radius:var(--_container-shape-end-end);border-end-start-radius:var(--_container-shape-end-start);display:flex;height:100%;position:relative}.container{align-items:center;border-radius:inherit;display:flex;flex:1;max-height:100%;min-height:100%;min-width:min-content;position:relative}.field,.container-overflow{resize:inherit}.resizable:not(.disabled) .container{resize:inherit;overflow:hidden}.disabled{pointer-events:none}slot[name=container]{border-radius:inherit}slot[name=container]::slotted(*){border-radius:inherit;inset:0;pointer-events:none;position:absolute}@layer styles{.start,.middle,.end{display:flex;box-sizing:border-box;height:100%;position:relative}.start{color:var(--_leading-content-color)}.end{color:var(--_trailing-content-color)}.start,.end{align-items:center;justify-content:center}.with-start .start{margin-inline:var(--_with-leading-content-leading-space) var(--_content-space)}.with-end .end{margin-inline:var(--_content-space) var(--_with-trailing-content-trailing-space)}.middle{align-items:stretch;align-self:baseline;flex:1}.content{color:var(--_content-color);display:flex;flex:1;opacity:0;transition:opacity 83ms cubic-bezier(0.2, 0, 0, 1)}.no-label .content,.focused .content,.populated .content{opacity:1;transition-delay:67ms}:is(.disabled,.disable-transitions) .content{transition:none}.content ::slotted(*){all:unset;color:currentColor;font-family:var(--_content-font);font-size:var(--_content-size);line-height:var(--_content-line-height);font-weight:var(--_content-weight);width:100%;overflow-wrap:revert;white-space:revert}.content ::slotted(:not(textarea)){padding-top:var(--_top-space);padding-bottom:var(--_bottom-space)}.content ::slotted(textarea){margin-top:var(--_top-space);margin-bottom:var(--_bottom-space)}:hover .content{color:var(--_hover-content-color)}:hover .start{color:var(--_hover-leading-content-color)}:hover .end{color:var(--_hover-trailing-content-color)}.focused .content{color:var(--_focus-content-color)}.focused .start{color:var(--_focus-leading-content-color)}.focused .end{color:var(--_focus-trailing-content-color)}.disabled .content{color:var(--_disabled-content-color)}.disabled.no-label .content,.disabled.focused .content,.disabled.populated .content{opacity:var(--_disabled-content-opacity)}.disabled .start{color:var(--_disabled-leading-content-color);opacity:var(--_disabled-leading-content-opacity)}.disabled .end{color:var(--_disabled-trailing-content-color);opacity:var(--_disabled-trailing-content-opacity)}.error .content{color:var(--_error-content-color)}.error .start{color:var(--_error-leading-content-color)}.error .end{color:var(--_error-trailing-content-color)}.error:hover .content{color:var(--_error-hover-content-color)}.error:hover .start{color:var(--_error-hover-leading-content-color)}.error:hover .end{color:var(--_error-hover-trailing-content-color)}.error.focused .content{color:var(--_error-focus-content-color)}.error.focused .start{color:var(--_error-focus-leading-content-color)}.error.focused .end{color:var(--_error-focus-trailing-content-color)}}@layer hcm{@media(forced-colors: active){.disabled :is(.start,.content,.end){color:GrayText;opacity:1}}}@layer styles{.label{box-sizing:border-box;color:var(--_label-text-color);overflow:hidden;max-width:100%;text-overflow:ellipsis;white-space:nowrap;z-index:1;font-family:var(--_label-text-font);font-size:var(--_label-text-size);line-height:var(--_label-text-line-height);font-weight:var(--_label-text-weight);width:min-content}.label-wrapper{inset:0;pointer-events:none;position:absolute}.label.resting{position:absolute;top:var(--_top-space)}.label.floating{font-size:var(--_label-text-populated-size);line-height:var(--_label-text-populated-line-height);transform-origin:top left}.label.hidden{opacity:0}.no-label .label{display:none}.label-wrapper{inset:0;position:absolute;text-align:initial}:hover .label{color:var(--_hover-label-text-color)}.focused .label{color:var(--_focus-label-text-color)}.disabled .label{color:var(--_disabled-label-text-color)}.disabled .label:not(.hidden){opacity:var(--_disabled-label-text-opacity)}.error .label{color:var(--_error-label-text-color)}.error:hover .label{color:var(--_error-hover-label-text-color)}.error.focused .label{color:var(--_error-focus-label-text-color)}}@layer hcm{@media(forced-colors: active){.disabled .label:not(.hidden){color:GrayText;opacity:1}}}@layer styles{.supporting-text{color:var(--_supporting-text-color);display:flex;font-family:var(--_supporting-text-font);font-size:var(--_supporting-text-size);line-height:var(--_supporting-text-line-height);font-weight:var(--_supporting-text-weight);gap:16px;justify-content:space-between;padding-inline-start:var(--_supporting-text-leading-space);padding-inline-end:var(--_supporting-text-trailing-space);padding-top:var(--_supporting-text-top-space)}.supporting-text :nth-child(2){flex-shrink:0}:hover .supporting-text{color:var(--_hover-supporting-text-color)}.focus .supporting-text{color:var(--_focus-supporting-text-color)}.disabled .supporting-text{color:var(--_disabled-supporting-text-color);opacity:var(--_disabled-supporting-text-opacity)}.error .supporting-text{color:var(--_error-supporting-text-color)}.error:hover .supporting-text{color:var(--_error-hover-supporting-text-color)}.error.focus .supporting-text{color:var(--_error-focus-supporting-text-color)}}@layer hcm{@media(forced-colors: active){.disabled .supporting-text{color:GrayText;opacity:1}}} +`;let ht=class extends pi{};ht.styles=[Br,vi],ht=o([b("md-filled-field")],ht);class ui extends ${renderOutline(e){return d` +
+
+
+
+
+
${e}
+
+
+
+ `}}const fi=v`@layer styles{:host{--_bottom-space: var(--md-outlined-field-bottom-space, 16px);--_content-color: var(--md-outlined-field-content-color, var(--md-sys-color-on-surface, #1d1b20));--_content-font: var(--md-outlined-field-content-font, var(--md-sys-typescale-body-large-font, var(--md-ref-typeface-plain, Roboto)));--_content-line-height: var(--md-outlined-field-content-line-height, var(--md-sys-typescale-body-large-line-height, 1.5rem));--_content-size: var(--md-outlined-field-content-size, var(--md-sys-typescale-body-large-size, 1rem));--_content-space: var(--md-outlined-field-content-space, 16px);--_content-weight: var(--md-outlined-field-content-weight, var(--md-sys-typescale-body-large-weight, var(--md-ref-typeface-weight-regular, 400)));--_disabled-content-color: var(--md-outlined-field-disabled-content-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-content-opacity: var(--md-outlined-field-disabled-content-opacity, 0.38);--_disabled-label-text-color: var(--md-outlined-field-disabled-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-label-text-opacity: var(--md-outlined-field-disabled-label-text-opacity, 0.38);--_disabled-leading-content-color: var(--md-outlined-field-disabled-leading-content-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-leading-content-opacity: var(--md-outlined-field-disabled-leading-content-opacity, 0.38);--_disabled-outline-color: var(--md-outlined-field-disabled-outline-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-outline-opacity: var(--md-outlined-field-disabled-outline-opacity, 0.12);--_disabled-outline-width: var(--md-outlined-field-disabled-outline-width, 1px);--_disabled-supporting-text-color: var(--md-outlined-field-disabled-supporting-text-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-supporting-text-opacity: var(--md-outlined-field-disabled-supporting-text-opacity, 0.38);--_disabled-trailing-content-color: var(--md-outlined-field-disabled-trailing-content-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-trailing-content-opacity: var(--md-outlined-field-disabled-trailing-content-opacity, 0.38);--_error-content-color: var(--md-outlined-field-error-content-color, var(--md-sys-color-on-surface, #1d1b20));--_error-focus-content-color: var(--md-outlined-field-error-focus-content-color, var(--md-sys-color-on-surface, #1d1b20));--_error-focus-label-text-color: var(--md-outlined-field-error-focus-label-text-color, var(--md-sys-color-error, #b3261e));--_error-focus-leading-content-color: var(--md-outlined-field-error-focus-leading-content-color, var(--md-sys-color-on-surface-variant, #49454f));--_error-focus-outline-color: var(--md-outlined-field-error-focus-outline-color, var(--md-sys-color-error, #b3261e));--_error-focus-supporting-text-color: var(--md-outlined-field-error-focus-supporting-text-color, var(--md-sys-color-error, #b3261e));--_error-focus-trailing-content-color: var(--md-outlined-field-error-focus-trailing-content-color, var(--md-sys-color-error, #b3261e));--_error-hover-content-color: var(--md-outlined-field-error-hover-content-color, var(--md-sys-color-on-surface, #1d1b20));--_error-hover-label-text-color: var(--md-outlined-field-error-hover-label-text-color, var(--md-sys-color-on-error-container, #410e0b));--_error-hover-leading-content-color: var(--md-outlined-field-error-hover-leading-content-color, var(--md-sys-color-on-surface-variant, #49454f));--_error-hover-outline-color: var(--md-outlined-field-error-hover-outline-color, var(--md-sys-color-on-error-container, #410e0b));--_error-hover-supporting-text-color: var(--md-outlined-field-error-hover-supporting-text-color, var(--md-sys-color-error, #b3261e));--_error-hover-trailing-content-color: var(--md-outlined-field-error-hover-trailing-content-color, var(--md-sys-color-on-error-container, #410e0b));--_error-label-text-color: var(--md-outlined-field-error-label-text-color, var(--md-sys-color-error, #b3261e));--_error-leading-content-color: var(--md-outlined-field-error-leading-content-color, var(--md-sys-color-on-surface-variant, #49454f));--_error-outline-color: var(--md-outlined-field-error-outline-color, var(--md-sys-color-error, #b3261e));--_error-supporting-text-color: var(--md-outlined-field-error-supporting-text-color, var(--md-sys-color-error, #b3261e));--_error-trailing-content-color: var(--md-outlined-field-error-trailing-content-color, var(--md-sys-color-error, #b3261e));--_focus-content-color: var(--md-outlined-field-focus-content-color, var(--md-sys-color-on-surface, #1d1b20));--_focus-label-text-color: var(--md-outlined-field-focus-label-text-color, var(--md-sys-color-primary, #6750a4));--_focus-leading-content-color: var(--md-outlined-field-focus-leading-content-color, var(--md-sys-color-on-surface-variant, #49454f));--_focus-outline-color: var(--md-outlined-field-focus-outline-color, var(--md-sys-color-primary, #6750a4));--_focus-outline-width: var(--md-outlined-field-focus-outline-width, 3px);--_focus-supporting-text-color: var(--md-outlined-field-focus-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_focus-trailing-content-color: var(--md-outlined-field-focus-trailing-content-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-content-color: var(--md-outlined-field-hover-content-color, var(--md-sys-color-on-surface, #1d1b20));--_hover-label-text-color: var(--md-outlined-field-hover-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_hover-leading-content-color: var(--md-outlined-field-hover-leading-content-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-outline-color: var(--md-outlined-field-hover-outline-color, var(--md-sys-color-on-surface, #1d1b20));--_hover-outline-width: var(--md-outlined-field-hover-outline-width, 1px);--_hover-supporting-text-color: var(--md-outlined-field-hover-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-trailing-content-color: var(--md-outlined-field-hover-trailing-content-color, var(--md-sys-color-on-surface-variant, #49454f));--_label-text-color: var(--md-outlined-field-label-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_label-text-font: var(--md-outlined-field-label-text-font, var(--md-sys-typescale-body-large-font, var(--md-ref-typeface-plain, Roboto)));--_label-text-line-height: var(--md-outlined-field-label-text-line-height, var(--md-sys-typescale-body-large-line-height, 1.5rem));--_label-text-padding-bottom: var(--md-outlined-field-label-text-padding-bottom, 8px);--_label-text-populated-line-height: var(--md-outlined-field-label-text-populated-line-height, var(--md-sys-typescale-body-small-line-height, 1rem));--_label-text-populated-size: var(--md-outlined-field-label-text-populated-size, var(--md-sys-typescale-body-small-size, 0.75rem));--_label-text-size: var(--md-outlined-field-label-text-size, var(--md-sys-typescale-body-large-size, 1rem));--_label-text-weight: var(--md-outlined-field-label-text-weight, var(--md-sys-typescale-body-large-weight, var(--md-ref-typeface-weight-regular, 400)));--_leading-content-color: var(--md-outlined-field-leading-content-color, var(--md-sys-color-on-surface-variant, #49454f));--_leading-space: var(--md-outlined-field-leading-space, 16px);--_outline-color: var(--md-outlined-field-outline-color, var(--md-sys-color-outline, #79747e));--_outline-label-padding: var(--md-outlined-field-outline-label-padding, 4px);--_outline-width: var(--md-outlined-field-outline-width, 1px);--_supporting-text-color: var(--md-outlined-field-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_supporting-text-font: var(--md-outlined-field-supporting-text-font, var(--md-sys-typescale-body-small-font, var(--md-ref-typeface-plain, Roboto)));--_supporting-text-leading-space: var(--md-outlined-field-supporting-text-leading-space, 16px);--_supporting-text-line-height: var(--md-outlined-field-supporting-text-line-height, var(--md-sys-typescale-body-small-line-height, 1rem));--_supporting-text-size: var(--md-outlined-field-supporting-text-size, var(--md-sys-typescale-body-small-size, 0.75rem));--_supporting-text-top-space: var(--md-outlined-field-supporting-text-top-space, 4px);--_supporting-text-trailing-space: var(--md-outlined-field-supporting-text-trailing-space, 16px);--_supporting-text-weight: var(--md-outlined-field-supporting-text-weight, var(--md-sys-typescale-body-small-weight, var(--md-ref-typeface-weight-regular, 400)));--_top-space: var(--md-outlined-field-top-space, 16px);--_trailing-content-color: var(--md-outlined-field-trailing-content-color, var(--md-sys-color-on-surface-variant, #49454f));--_trailing-space: var(--md-outlined-field-trailing-space, 16px);--_with-leading-content-leading-space: var(--md-outlined-field-with-leading-content-leading-space, 12px);--_with-trailing-content-trailing-space: var(--md-outlined-field-with-trailing-content-trailing-space, 12px);--_container-shape-start-start: var(--md-outlined-field-container-shape-start-start, var(--md-outlined-field-container-shape, var(--md-sys-shape-corner-extra-small, 4px)));--_container-shape-start-end: var(--md-outlined-field-container-shape-start-end, var(--md-outlined-field-container-shape, var(--md-sys-shape-corner-extra-small, 4px)));--_container-shape-end-end: var(--md-outlined-field-container-shape-end-end, var(--md-outlined-field-container-shape, var(--md-sys-shape-corner-extra-small, 4px)));--_container-shape-end-start: var(--md-outlined-field-container-shape-end-start, var(--md-outlined-field-container-shape, var(--md-sys-shape-corner-extra-small, 4px)))}.outline{border-color:var(--_outline-color);border-radius:inherit;display:flex;pointer-events:none;height:100%;position:absolute;width:100%;z-index:1}.outline-start::before,.outline-start::after,.outline-panel-inactive::before,.outline-panel-inactive::after,.outline-panel-active::before,.outline-panel-active::after,.outline-end::before,.outline-end::after{border:inherit;content:"";inset:0;position:absolute}.outline-start,.outline-end{border:inherit;border-radius:inherit;box-sizing:border-box;position:relative}.outline-start::before,.outline-start::after,.outline-end::before,.outline-end::after{border-bottom-style:solid;border-top-style:solid}.outline-start::after,.outline-end::after{opacity:0;transition:opacity 150ms cubic-bezier(0.2, 0, 0, 1)}.focused .outline-start::after,.focused .outline-end::after{opacity:1}.outline-start::before,.outline-start::after{border-inline-start-style:solid;border-inline-end-style:none;border-start-start-radius:inherit;border-start-end-radius:0;border-end-start-radius:inherit;border-end-end-radius:0;margin-inline-end:var(--_outline-label-padding)}.outline-end{flex-grow:1;margin-inline-start:calc(-1*var(--_outline-label-padding))}.outline-end::before,.outline-end::after{border-inline-start-style:none;border-inline-end-style:solid;border-start-start-radius:0;border-start-end-radius:inherit;border-end-start-radius:0;border-end-end-radius:inherit}.outline-notch{align-items:flex-start;border:inherit;display:flex;margin-inline-start:calc(-1*var(--_outline-label-padding));margin-inline-end:var(--_outline-label-padding);max-width:calc(100% - var(--_leading-space) - var(--_trailing-space));padding:0 var(--_outline-label-padding);position:relative}.no-label .outline-notch{display:none}.outline-panel-inactive,.outline-panel-active{border:inherit;border-bottom-style:solid;inset:0;position:absolute}.outline-panel-inactive::before,.outline-panel-inactive::after,.outline-panel-active::before,.outline-panel-active::after{border-top-style:solid;border-bottom:none;bottom:auto;transform:scaleX(1);transition:transform 150ms cubic-bezier(0.2, 0, 0, 1)}.outline-panel-inactive::before,.outline-panel-active::before{right:50%;transform-origin:top left}.outline-panel-inactive::after,.outline-panel-active::after{left:50%;transform-origin:top right}.populated .outline-panel-inactive::before,.populated .outline-panel-inactive::after,.populated .outline-panel-active::before,.populated .outline-panel-active::after,.focused .outline-panel-inactive::before,.focused .outline-panel-inactive::after,.focused .outline-panel-active::before,.focused .outline-panel-active::after{transform:scaleX(0)}.outline-panel-active{opacity:0;transition:opacity 150ms cubic-bezier(0.2, 0, 0, 1)}.focused .outline-panel-active{opacity:1}.outline-label{display:flex;max-width:100%;transform:translateY(calc(-100% + var(--_label-text-padding-bottom)))}.outline-start,.field:not(.with-start) .content ::slotted(*){padding-inline-start:max(var(--_leading-space),max(var(--_container-shape-start-start),var(--_container-shape-end-start)) + var(--_outline-label-padding))}.field:not(.with-start) .label-wrapper{margin-inline-start:max(var(--_leading-space),max(var(--_container-shape-start-start),var(--_container-shape-end-start)) + var(--_outline-label-padding))}.field:not(.with-end) .content ::slotted(*){padding-inline-end:max(var(--_trailing-space),max(var(--_container-shape-start-end),var(--_container-shape-end-end)))}.field:not(.with-end) .label-wrapper{margin-inline-end:max(var(--_trailing-space),max(var(--_container-shape-start-end),var(--_container-shape-end-end)))}.outline-start::before,.outline-end::before,.outline-panel-inactive,.outline-panel-inactive::before,.outline-panel-inactive::after{border-width:var(--_outline-width)}:hover .outline{border-color:var(--_hover-outline-color);color:var(--_hover-outline-color)}:hover .outline-start::before,:hover .outline-end::before,:hover .outline-panel-inactive,:hover .outline-panel-inactive::before,:hover .outline-panel-inactive::after{border-width:var(--_hover-outline-width)}.focused .outline{border-color:var(--_focus-outline-color);color:var(--_focus-outline-color)}.outline-start::after,.outline-end::after,.outline-panel-active,.outline-panel-active::before,.outline-panel-active::after{border-width:var(--_focus-outline-width)}.disabled .outline{border-color:var(--_disabled-outline-color);color:var(--_disabled-outline-color)}.disabled .outline-start,.disabled .outline-end,.disabled .outline-panel-inactive{opacity:var(--_disabled-outline-opacity)}.disabled .outline-start::before,.disabled .outline-end::before,.disabled .outline-panel-inactive,.disabled .outline-panel-inactive::before,.disabled .outline-panel-inactive::after{border-width:var(--_disabled-outline-width)}.error .outline{border-color:var(--_error-outline-color);color:var(--_error-outline-color)}.error:hover .outline{border-color:var(--_error-hover-outline-color);color:var(--_error-hover-outline-color)}.error.focused .outline{border-color:var(--_error-focus-outline-color);color:var(--_error-focus-outline-color)}.resizable .container{bottom:var(--_focus-outline-width);inset-inline-end:var(--_focus-outline-width);clip-path:inset(var(--_focus-outline-width) 0 0 var(--_focus-outline-width))}.resizable .container>*{top:var(--_focus-outline-width);inset-inline-start:var(--_focus-outline-width)}.resizable .container:dir(rtl){clip-path:inset(var(--_focus-outline-width) var(--_focus-outline-width) 0 0)}}@layer hcm{@media(forced-colors: active){.disabled .outline{border-color:GrayText;color:GrayText}.disabled :is(.outline-start,.outline-end,.outline-panel-inactive){opacity:1}}} +`;let pt=class extends ui{};pt.styles=[Br,fi],pt=o([b("md-outlined-field")],pt);class mi extends _{render(){return d``}connectedCallback(){if(super.connectedCallback(),this.getAttribute("aria-hidden")==="false"){this.removeAttribute("aria-hidden");return}this.setAttribute("aria-hidden","true")}}const bi=v`:host{font-size:var(--md-icon-size, 24px);width:var(--md-icon-size, 24px);height:var(--md-icon-size, 24px);color:inherit;font-variation-settings:inherit;font-weight:400;font-family:var(--md-icon-font, Material Symbols Outlined);display:inline-flex;font-style:normal;place-items:center;place-content:center;line-height:1;overflow:hidden;letter-spacing:normal;text-transform:none;user-select:none;white-space:nowrap;word-wrap:normal;flex-shrink:0;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale}::slotted(svg){fill:currentColor}::slotted(*){height:100%;width:100%} +`;let vt=class extends mi{};vt.styles=[bi],vt=o([b("md-icon")],vt);const yi=v`:host{--_container-color: var(--md-filled-icon-button-container-color, var(--md-sys-color-primary, #6750a4));--_container-height: var(--md-filled-icon-button-container-height, 40px);--_container-width: var(--md-filled-icon-button-container-width, 40px);--_disabled-container-color: var(--md-filled-icon-button-disabled-container-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-container-opacity: var(--md-filled-icon-button-disabled-container-opacity, 0.12);--_disabled-icon-color: var(--md-filled-icon-button-disabled-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-icon-opacity: var(--md-filled-icon-button-disabled-icon-opacity, 0.38);--_focus-icon-color: var(--md-filled-icon-button-focus-icon-color, var(--md-sys-color-on-primary, #fff));--_hover-icon-color: var(--md-filled-icon-button-hover-icon-color, var(--md-sys-color-on-primary, #fff));--_hover-state-layer-color: var(--md-filled-icon-button-hover-state-layer-color, var(--md-sys-color-on-primary, #fff));--_hover-state-layer-opacity: var(--md-filled-icon-button-hover-state-layer-opacity, 0.08);--_icon-color: var(--md-filled-icon-button-icon-color, var(--md-sys-color-on-primary, #fff));--_icon-size: var(--md-filled-icon-button-icon-size, 24px);--_pressed-icon-color: var(--md-filled-icon-button-pressed-icon-color, var(--md-sys-color-on-primary, #fff));--_pressed-state-layer-color: var(--md-filled-icon-button-pressed-state-layer-color, var(--md-sys-color-on-primary, #fff));--_pressed-state-layer-opacity: var(--md-filled-icon-button-pressed-state-layer-opacity, 0.12);--_selected-container-color: var(--md-filled-icon-button-selected-container-color, var(--md-sys-color-primary, #6750a4));--_toggle-selected-focus-icon-color: var(--md-filled-icon-button-toggle-selected-focus-icon-color, var(--md-sys-color-on-primary, #fff));--_toggle-selected-hover-icon-color: var(--md-filled-icon-button-toggle-selected-hover-icon-color, var(--md-sys-color-on-primary, #fff));--_toggle-selected-hover-state-layer-color: var(--md-filled-icon-button-toggle-selected-hover-state-layer-color, var(--md-sys-color-on-primary, #fff));--_toggle-selected-icon-color: var(--md-filled-icon-button-toggle-selected-icon-color, var(--md-sys-color-on-primary, #fff));--_toggle-selected-pressed-icon-color: var(--md-filled-icon-button-toggle-selected-pressed-icon-color, var(--md-sys-color-on-primary, #fff));--_toggle-selected-pressed-state-layer-color: var(--md-filled-icon-button-toggle-selected-pressed-state-layer-color, var(--md-sys-color-on-primary, #fff));--_unselected-container-color: var(--md-filled-icon-button-unselected-container-color, var(--md-sys-color-surface-container-highest, #e6e0e9));--_toggle-focus-icon-color: var(--md-filled-icon-button-toggle-focus-icon-color, var(--md-sys-color-primary, #6750a4));--_toggle-hover-icon-color: var(--md-filled-icon-button-toggle-hover-icon-color, var(--md-sys-color-primary, #6750a4));--_toggle-hover-state-layer-color: var(--md-filled-icon-button-toggle-hover-state-layer-color, var(--md-sys-color-primary, #6750a4));--_toggle-icon-color: var(--md-filled-icon-button-toggle-icon-color, var(--md-sys-color-primary, #6750a4));--_toggle-pressed-icon-color: var(--md-filled-icon-button-toggle-pressed-icon-color, var(--md-sys-color-primary, #6750a4));--_toggle-pressed-state-layer-color: var(--md-filled-icon-button-toggle-pressed-state-layer-color, var(--md-sys-color-primary, #6750a4));--_container-shape-start-start: var(--md-filled-icon-button-container-shape-start-start, var(--md-filled-icon-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-start-end: var(--md-filled-icon-button-container-shape-start-end, var(--md-filled-icon-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-end: var(--md-filled-icon-button-container-shape-end-end, var(--md-filled-icon-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-start: var(--md-filled-icon-button-container-shape-end-start, var(--md-filled-icon-button-container-shape, var(--md-sys-shape-corner-full, 9999px)))}.icon-button{color:var(--_icon-color);--md-ripple-hover-color: var(--_hover-state-layer-color);--md-ripple-hover-opacity: var(--_hover-state-layer-opacity);--md-ripple-pressed-color: var(--_pressed-state-layer-color);--md-ripple-pressed-opacity: var(--_pressed-state-layer-opacity)}.icon-button:hover{color:var(--_hover-icon-color)}.icon-button:focus{color:var(--_focus-icon-color)}.icon-button:active{color:var(--_pressed-icon-color)}.icon-button:is(:disabled,[aria-disabled=true]){color:var(--_disabled-icon-color)}.icon-button::before{background-color:var(--_container-color);border-radius:inherit;content:"";inset:0;position:absolute;z-index:-1}.icon-button:is(:disabled,[aria-disabled=true])::before{background-color:var(--_disabled-container-color);opacity:var(--_disabled-container-opacity)}.icon-button:is(:disabled,[aria-disabled=true]) .icon{opacity:var(--_disabled-icon-opacity)}.toggle-filled{--md-ripple-hover-color: var(--_toggle-hover-state-layer-color);--md-ripple-pressed-color: var(--_toggle-pressed-state-layer-color)}.toggle-filled:not(:disabled,[aria-disabled=true]){color:var(--_toggle-icon-color)}.toggle-filled:not(:disabled,[aria-disabled=true]):hover{color:var(--_toggle-hover-icon-color)}.toggle-filled:not(:disabled,[aria-disabled=true]):focus{color:var(--_toggle-focus-icon-color)}.toggle-filled:not(:disabled,[aria-disabled=true]):active{color:var(--_toggle-pressed-icon-color)}.toggle-filled:not(:disabled,[aria-disabled=true])::before{background-color:var(--_unselected-container-color)}.selected{--md-ripple-hover-color: var(--_toggle-selected-hover-state-layer-color);--md-ripple-pressed-color: var(--_toggle-selected-pressed-state-layer-color)}.selected:not(:disabled,[aria-disabled=true]){color:var(--_toggle-selected-icon-color)}.selected:not(:disabled,[aria-disabled=true]):hover{color:var(--_toggle-selected-hover-icon-color)}.selected:not(:disabled,[aria-disabled=true]):focus{color:var(--_toggle-selected-focus-icon-color)}.selected:not(:disabled,[aria-disabled=true]):active{color:var(--_toggle-selected-pressed-icon-color)}.selected:not(:disabled,[aria-disabled=true])::before{background-color:var(--_selected-container-color)} +`;function Nr(i,e=!0){return e&&getComputedStyle(i).getPropertyValue("direction").trim()==="rtl"}const gi=W(se(_));class M extends gi{get name(){return this.getAttribute("name")??""}set name(e){this.setAttribute("name",e)}get form(){return this[N].form}get labels(){return this[N].labels}constructor(){super(),this.disabled=!1,this.softDisabled=!1,this.flipIconInRtl=!1,this.href="",this.download="",this.target="",this.ariaLabelSelected="",this.toggle=!1,this.selected=!1,this.type="submit",this.value="",this.flipIcon=Nr(this,this.flipIconInRtl),T||this.addEventListener("click",this.handleClick.bind(this))}willUpdate(){this.href&&(this.disabled=!1,this.softDisabled=!1)}render(){const e=this.href?K`div`:K`button`,{ariaLabel:t,ariaHasPopup:r,ariaExpanded:a}=this,n=t&&this.ariaLabelSelected,s=this.toggle?this.selected:c;let h=c;return this.href||(h=n&&this.selected?this.ariaLabelSelected:t),ze`<${e} + class="icon-button ${S(this.getRenderClasses())}" + id="button" + aria-label="${h||c}" + aria-haspopup="${!this.href&&r||c}" + aria-expanded="${!this.href&&a||c}" + aria-pressed="${s}" + aria-disabled=${!this.href&&this.softDisabled||c} + ?disabled="${!this.href&&this.disabled}" + @click="${this.handleClickOnChild}"> + ${this.renderFocusRing()} + ${this.renderRipple()} + ${this.selected?c:this.renderIcon()} + ${this.selected?this.renderSelectedIcon():c} + ${this.href?this.renderLink():this.renderTouchTarget()} + `}renderLink(){const{ariaLabel:e}=this;return d` + + ${this.renderTouchTarget()} + + `}getRenderClasses(){return{"flip-icon":this.flipIcon,selected:this.toggle&&this.selected}}renderIcon(){return d``}renderSelectedIcon(){return d``}renderTouchTarget(){return d``}renderFocusRing(){return d``}renderRipple(){const e=!this.href&&(this.disabled||this.softDisabled);return d``}connectedCallback(){this.flipIcon=Nr(this,this.flipIconInRtl),super.connectedCallback()}handleClick(e){if(!this.href&&this.softDisabled){e.stopImmediatePropagation(),e.preventDefault();return}}async handleClickOnChild(e){await 0,!(!this.toggle||this.disabled||this.softDisabled||e.defaultPrevented)&&(this.selected=!this.selected,this.dispatchEvent(new InputEvent("input",{bubbles:!0,composed:!0})),this.dispatchEvent(new Event("change",{bubbles:!0})))}}Sr(M),M.formAssociated=!0,M.shadowRootOptions={mode:"open",delegatesFocus:!0},o([l({type:Boolean,reflect:!0})],M.prototype,"disabled",void 0),o([l({type:Boolean,attribute:"soft-disabled",reflect:!0})],M.prototype,"softDisabled",void 0),o([l({type:Boolean,attribute:"flip-icon-in-rtl"})],M.prototype,"flipIconInRtl",void 0),o([l()],M.prototype,"href",void 0),o([l()],M.prototype,"download",void 0),o([l()],M.prototype,"target",void 0),o([l({attribute:"aria-label-selected"})],M.prototype,"ariaLabelSelected",void 0),o([l({type:Boolean})],M.prototype,"toggle",void 0),o([l({type:Boolean,reflect:!0})],M.prototype,"selected",void 0),o([l()],M.prototype,"type",void 0),o([l({reflect:!0})],M.prototype,"value",void 0),o([k()],M.prototype,"flipIcon",void 0);const ut=v`:host{display:inline-flex;outline:none;-webkit-tap-highlight-color:rgba(0,0,0,0);height:var(--_container-height);width:var(--_container-width);justify-content:center}:host([touch-target=wrapper]){margin:max(0px,(48px - var(--_container-height))/2) max(0px,(48px - var(--_container-width))/2)}md-focus-ring{--md-focus-ring-shape-start-start: var(--_container-shape-start-start);--md-focus-ring-shape-start-end: var(--_container-shape-start-end);--md-focus-ring-shape-end-end: var(--_container-shape-end-end);--md-focus-ring-shape-end-start: var(--_container-shape-end-start)}:host(:is([disabled],[soft-disabled])){pointer-events:none}.icon-button{place-items:center;background:none;border:none;box-sizing:border-box;cursor:pointer;display:flex;place-content:center;outline:none;padding:0;position:relative;text-decoration:none;user-select:none;z-index:0;flex:1;border-start-start-radius:var(--_container-shape-start-start);border-start-end-radius:var(--_container-shape-start-end);border-end-start-radius:var(--_container-shape-end-start);border-end-end-radius:var(--_container-shape-end-end)}.icon ::slotted(*){font-size:var(--_icon-size);height:var(--_icon-size);width:var(--_icon-size);font-weight:inherit}md-ripple{z-index:-1;border-start-start-radius:var(--_container-shape-start-start);border-start-end-radius:var(--_container-shape-start-end);border-end-start-radius:var(--_container-shape-end-start);border-end-end-radius:var(--_container-shape-end-end)}.flip-icon .icon{transform:scaleX(-1)}.icon{display:inline-flex}.link{display:grid;height:100%;outline:none;place-items:center;position:absolute;width:100%}.touch{position:absolute;height:max(48px,100%);width:max(48px,100%)}:host([touch-target=none]) .touch{display:none}@media(forced-colors: active){:host(:is([disabled],[soft-disabled])){--_disabled-icon-color: GrayText;--_disabled-icon-opacity: 1}} +`;let ft=class extends M{getRenderClasses(){return{...super.getRenderClasses(),filled:!0,"toggle-filled":this.toggle}}};ft.styles=[ut,yi],ft=o([b("md-filled-icon-button")],ft);const xi=v`:host{--_container-color: var(--md-filled-tonal-icon-button-container-color, var(--md-sys-color-secondary-container, #e8def8));--_container-height: var(--md-filled-tonal-icon-button-container-height, 40px);--_container-width: var(--md-filled-tonal-icon-button-container-width, 40px);--_disabled-container-color: var(--md-filled-tonal-icon-button-disabled-container-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-container-opacity: var(--md-filled-tonal-icon-button-disabled-container-opacity, 0.12);--_disabled-icon-color: var(--md-filled-tonal-icon-button-disabled-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-icon-opacity: var(--md-filled-tonal-icon-button-disabled-icon-opacity, 0.38);--_focus-icon-color: var(--md-filled-tonal-icon-button-focus-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_hover-icon-color: var(--md-filled-tonal-icon-button-hover-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_hover-state-layer-color: var(--md-filled-tonal-icon-button-hover-state-layer-color, var(--md-sys-color-on-secondary-container, #1d192b));--_hover-state-layer-opacity: var(--md-filled-tonal-icon-button-hover-state-layer-opacity, 0.08);--_icon-color: var(--md-filled-tonal-icon-button-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_icon-size: var(--md-filled-tonal-icon-button-icon-size, 24px);--_pressed-icon-color: var(--md-filled-tonal-icon-button-pressed-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_pressed-state-layer-color: var(--md-filled-tonal-icon-button-pressed-state-layer-color, var(--md-sys-color-on-secondary-container, #1d192b));--_pressed-state-layer-opacity: var(--md-filled-tonal-icon-button-pressed-state-layer-opacity, 0.12);--_selected-container-color: var(--md-filled-tonal-icon-button-selected-container-color, var(--md-sys-color-secondary-container, #e8def8));--_toggle-selected-focus-icon-color: var(--md-filled-tonal-icon-button-toggle-selected-focus-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_toggle-selected-hover-icon-color: var(--md-filled-tonal-icon-button-toggle-selected-hover-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_toggle-selected-hover-state-layer-color: var(--md-filled-tonal-icon-button-toggle-selected-hover-state-layer-color, var(--md-sys-color-on-secondary-container, #1d192b));--_toggle-selected-icon-color: var(--md-filled-tonal-icon-button-toggle-selected-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_toggle-selected-pressed-icon-color: var(--md-filled-tonal-icon-button-toggle-selected-pressed-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_toggle-selected-pressed-state-layer-color: var(--md-filled-tonal-icon-button-toggle-selected-pressed-state-layer-color, var(--md-sys-color-on-secondary-container, #1d192b));--_unselected-container-color: var(--md-filled-tonal-icon-button-unselected-container-color, var(--md-sys-color-surface-container-highest, #e6e0e9));--_toggle-focus-icon-color: var(--md-filled-tonal-icon-button-toggle-focus-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_toggle-hover-icon-color: var(--md-filled-tonal-icon-button-toggle-hover-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_toggle-hover-state-layer-color: var(--md-filled-tonal-icon-button-toggle-hover-state-layer-color, var(--md-sys-color-on-surface-variant, #49454f));--_toggle-icon-color: var(--md-filled-tonal-icon-button-toggle-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_toggle-pressed-icon-color: var(--md-filled-tonal-icon-button-toggle-pressed-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_toggle-pressed-state-layer-color: var(--md-filled-tonal-icon-button-toggle-pressed-state-layer-color, var(--md-sys-color-on-surface-variant, #49454f));--_container-shape-start-start: var(--md-filled-tonal-icon-button-container-shape-start-start, var(--md-filled-tonal-icon-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-start-end: var(--md-filled-tonal-icon-button-container-shape-start-end, var(--md-filled-tonal-icon-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-end: var(--md-filled-tonal-icon-button-container-shape-end-end, var(--md-filled-tonal-icon-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-start: var(--md-filled-tonal-icon-button-container-shape-end-start, var(--md-filled-tonal-icon-button-container-shape, var(--md-sys-shape-corner-full, 9999px)))}.icon-button{color:var(--_icon-color);--md-ripple-hover-color: var(--_hover-state-layer-color);--md-ripple-hover-opacity: var(--_hover-state-layer-opacity);--md-ripple-pressed-color: var(--_pressed-state-layer-color);--md-ripple-pressed-opacity: var(--_pressed-state-layer-opacity)}.icon-button:hover{color:var(--_hover-icon-color)}.icon-button:focus{color:var(--_focus-icon-color)}.icon-button:active{color:var(--_pressed-icon-color)}.icon-button:is(:disabled,[aria-disabled=true]){color:var(--_disabled-icon-color)}.icon-button::before{background-color:var(--_container-color);border-radius:inherit;content:"";inset:0;position:absolute;z-index:-1}.icon-button:is(:disabled,[aria-disabled=true])::before{background-color:var(--_disabled-container-color);opacity:var(--_disabled-container-opacity)}.icon-button:is(:disabled,[aria-disabled=true]) .icon{opacity:var(--_disabled-icon-opacity)}.toggle-filled-tonal{--md-ripple-hover-color: var(--_toggle-hover-state-layer-color);--md-ripple-pressed-color: var(--_toggle-pressed-state-layer-color)}.toggle-filled-tonal:not(:disabled,[aria-disabled=true]){color:var(--_toggle-icon-color)}.toggle-filled-tonal:not(:disabled,[aria-disabled=true]):hover{color:var(--_toggle-hover-icon-color)}.toggle-filled-tonal:not(:disabled,[aria-disabled=true]):focus{color:var(--_toggle-focus-icon-color)}.toggle-filled-tonal:not(:disabled,[aria-disabled=true]):active{color:var(--_toggle-pressed-icon-color)}.toggle-filled-tonal:not(:disabled,[aria-disabled=true])::before{background-color:var(--_unselected-container-color)}.selected{--md-ripple-hover-color: var(--_toggle-selected-hover-state-layer-color);--md-ripple-pressed-color: var(--_toggle-selected-pressed-state-layer-color)}.selected:not(:disabled,[aria-disabled=true]){color:var(--_toggle-selected-icon-color)}.selected:not(:disabled,[aria-disabled=true]):hover{color:var(--_toggle-selected-hover-icon-color)}.selected:not(:disabled,[aria-disabled=true]):focus{color:var(--_toggle-selected-focus-icon-color)}.selected:not(:disabled,[aria-disabled=true]):active{color:var(--_toggle-selected-pressed-icon-color)}.selected:not(:disabled,[aria-disabled=true])::before{background-color:var(--_selected-container-color)} +`;let mt=class extends M{getRenderClasses(){return{...super.getRenderClasses(),"filled-tonal":!0,"toggle-filled-tonal":this.toggle}}};mt.styles=[ut,xi],mt=o([b("md-filled-tonal-icon-button")],mt);const _i=v`:host{--_disabled-icon-color: var(--md-icon-button-disabled-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-icon-opacity: var(--md-icon-button-disabled-icon-opacity, 0.38);--_icon-size: var(--md-icon-button-icon-size, 24px);--_selected-focus-icon-color: var(--md-icon-button-selected-focus-icon-color, var(--md-sys-color-primary, #6750a4));--_selected-hover-icon-color: var(--md-icon-button-selected-hover-icon-color, var(--md-sys-color-primary, #6750a4));--_selected-hover-state-layer-color: var(--md-icon-button-selected-hover-state-layer-color, var(--md-sys-color-primary, #6750a4));--_selected-hover-state-layer-opacity: var(--md-icon-button-selected-hover-state-layer-opacity, 0.08);--_selected-icon-color: var(--md-icon-button-selected-icon-color, var(--md-sys-color-primary, #6750a4));--_selected-pressed-icon-color: var(--md-icon-button-selected-pressed-icon-color, var(--md-sys-color-primary, #6750a4));--_selected-pressed-state-layer-color: var(--md-icon-button-selected-pressed-state-layer-color, var(--md-sys-color-primary, #6750a4));--_selected-pressed-state-layer-opacity: var(--md-icon-button-selected-pressed-state-layer-opacity, 0.12);--_state-layer-height: var(--md-icon-button-state-layer-height, 40px);--_state-layer-shape: var(--md-icon-button-state-layer-shape, var(--md-sys-shape-corner-full, 9999px));--_state-layer-width: var(--md-icon-button-state-layer-width, 40px);--_focus-icon-color: var(--md-icon-button-focus-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-icon-color: var(--md-icon-button-hover-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-state-layer-color: var(--md-icon-button-hover-state-layer-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-state-layer-opacity: var(--md-icon-button-hover-state-layer-opacity, 0.08);--_icon-color: var(--md-icon-button-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_pressed-icon-color: var(--md-icon-button-pressed-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_pressed-state-layer-color: var(--md-icon-button-pressed-state-layer-color, var(--md-sys-color-on-surface-variant, #49454f));--_pressed-state-layer-opacity: var(--md-icon-button-pressed-state-layer-opacity, 0.12);--_container-shape-start-start: 0;--_container-shape-start-end: 0;--_container-shape-end-end: 0;--_container-shape-end-start: 0;--_container-height: 0;--_container-width: 0;height:var(--_state-layer-height);width:var(--_state-layer-width)}:host([touch-target=wrapper]){margin:max(0px,(48px - var(--_state-layer-height))/2) max(0px,(48px - var(--_state-layer-width))/2)}md-focus-ring{--md-focus-ring-shape-start-start: var(--_state-layer-shape);--md-focus-ring-shape-start-end: var(--_state-layer-shape);--md-focus-ring-shape-end-end: var(--_state-layer-shape);--md-focus-ring-shape-end-start: var(--_state-layer-shape)}.standard{background-color:rgba(0,0,0,0);color:var(--_icon-color);--md-ripple-hover-color: var(--_hover-state-layer-color);--md-ripple-hover-opacity: var(--_hover-state-layer-opacity);--md-ripple-pressed-color: var(--_pressed-state-layer-color);--md-ripple-pressed-opacity: var(--_pressed-state-layer-opacity)}.standard:hover{color:var(--_hover-icon-color)}.standard:focus{color:var(--_focus-icon-color)}.standard:active{color:var(--_pressed-icon-color)}.standard:is(:disabled,[aria-disabled=true]){color:var(--_disabled-icon-color)}md-ripple{border-radius:var(--_state-layer-shape)}.standard:is(:disabled,[aria-disabled=true]){opacity:var(--_disabled-icon-opacity)}.selected{--md-ripple-hover-color: var(--_selected-hover-state-layer-color);--md-ripple-hover-opacity: var(--_selected-hover-state-layer-opacity);--md-ripple-pressed-color: var(--_selected-pressed-state-layer-color);--md-ripple-pressed-opacity: var(--_selected-pressed-state-layer-opacity)}.selected:not(:disabled,[aria-disabled=true]){color:var(--_selected-icon-color)}.selected:not(:disabled,[aria-disabled=true]):hover{color:var(--_selected-hover-icon-color)}.selected:not(:disabled,[aria-disabled=true]):focus{color:var(--_selected-focus-icon-color)}.selected:not(:disabled,[aria-disabled=true]):active{color:var(--_selected-pressed-icon-color)} +`;let bt=class extends M{getRenderClasses(){return{...super.getRenderClasses(),standard:!0}}};bt.styles=[ut,_i],bt=o([b("md-icon-button")],bt);const wi=v`:host{--_container-height: var(--md-outlined-icon-button-container-height, 40px);--_container-width: var(--md-outlined-icon-button-container-width, 40px);--_disabled-icon-color: var(--md-outlined-icon-button-disabled-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-icon-opacity: var(--md-outlined-icon-button-disabled-icon-opacity, 0.38);--_disabled-selected-container-color: var(--md-outlined-icon-button-disabled-selected-container-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-selected-container-opacity: var(--md-outlined-icon-button-disabled-selected-container-opacity, 0.12);--_hover-state-layer-opacity: var(--md-outlined-icon-button-hover-state-layer-opacity, 0.08);--_icon-size: var(--md-outlined-icon-button-icon-size, 24px);--_pressed-state-layer-opacity: var(--md-outlined-icon-button-pressed-state-layer-opacity, 0.12);--_selected-container-color: var(--md-outlined-icon-button-selected-container-color, var(--md-sys-color-inverse-surface, #322f35));--_selected-focus-icon-color: var(--md-outlined-icon-button-selected-focus-icon-color, var(--md-sys-color-inverse-on-surface, #f5eff7));--_selected-hover-icon-color: var(--md-outlined-icon-button-selected-hover-icon-color, var(--md-sys-color-inverse-on-surface, #f5eff7));--_selected-hover-state-layer-color: var(--md-outlined-icon-button-selected-hover-state-layer-color, var(--md-sys-color-inverse-on-surface, #f5eff7));--_selected-icon-color: var(--md-outlined-icon-button-selected-icon-color, var(--md-sys-color-inverse-on-surface, #f5eff7));--_selected-pressed-icon-color: var(--md-outlined-icon-button-selected-pressed-icon-color, var(--md-sys-color-inverse-on-surface, #f5eff7));--_selected-pressed-state-layer-color: var(--md-outlined-icon-button-selected-pressed-state-layer-color, var(--md-sys-color-inverse-on-surface, #f5eff7));--_disabled-outline-color: var(--md-outlined-icon-button-disabled-outline-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-outline-opacity: var(--md-outlined-icon-button-disabled-outline-opacity, 0.12);--_focus-icon-color: var(--md-outlined-icon-button-focus-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-icon-color: var(--md-outlined-icon-button-hover-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-state-layer-color: var(--md-outlined-icon-button-hover-state-layer-color, var(--md-sys-color-on-surface-variant, #49454f));--_icon-color: var(--md-outlined-icon-button-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_outline-color: var(--md-outlined-icon-button-outline-color, var(--md-sys-color-outline, #79747e));--_outline-width: var(--md-outlined-icon-button-outline-width, 1px);--_pressed-icon-color: var(--md-outlined-icon-button-pressed-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_pressed-state-layer-color: var(--md-outlined-icon-button-pressed-state-layer-color, var(--md-sys-color-on-surface, #1d1b20));--_container-shape-start-start: var(--md-outlined-icon-button-container-shape-start-start, var(--md-outlined-icon-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-start-end: var(--md-outlined-icon-button-container-shape-start-end, var(--md-outlined-icon-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-end: var(--md-outlined-icon-button-container-shape-end-end, var(--md-outlined-icon-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-start: var(--md-outlined-icon-button-container-shape-end-start, var(--md-outlined-icon-button-container-shape, var(--md-sys-shape-corner-full, 9999px)))}.outlined{background-color:rgba(0,0,0,0);color:var(--_icon-color);--md-ripple-hover-color: var(--_hover-state-layer-color);--md-ripple-hover-opacity: var(--_hover-state-layer-opacity);--md-ripple-pressed-color: var(--_pressed-state-layer-color);--md-ripple-pressed-opacity: var(--_pressed-state-layer-opacity)}.outlined::before{border-color:var(--_outline-color);border-width:var(--_outline-width)}.outlined:hover{color:var(--_hover-icon-color)}.outlined:focus{color:var(--_focus-icon-color)}.outlined:active{color:var(--_pressed-icon-color)}.outlined:is(:disabled,[aria-disabled=true]){color:var(--_disabled-icon-color)}.outlined:is(:disabled,[aria-disabled=true])::before{border-color:var(--_disabled-outline-color);opacity:var(--_disabled-outline-opacity)}.outlined:is(:disabled,[aria-disabled=true]) .icon{opacity:var(--_disabled-icon-opacity)}.outlined::before{block-size:100%;border-style:solid;border-radius:inherit;box-sizing:border-box;content:"";inline-size:100%;inset:0;pointer-events:none;position:absolute;z-index:-1}.outlined.selected::before{border-width:0}.selected{--md-ripple-hover-color: var(--_selected-hover-state-layer-color);--md-ripple-hover-opacity: var(--_hover-state-layer-opacity);--md-ripple-pressed-color: var(--_selected-pressed-state-layer-color);--md-ripple-pressed-opacity: var(--_pressed-state-layer-opacity)}.selected:not(:disabled,[aria-disabled=true]){color:var(--_selected-icon-color)}.selected:not(:disabled,[aria-disabled=true]):hover{color:var(--_selected-hover-icon-color)}.selected:not(:disabled,[aria-disabled=true]):focus{color:var(--_selected-focus-icon-color)}.selected:not(:disabled,[aria-disabled=true]):active{color:var(--_selected-pressed-icon-color)}.selected:not(:disabled,[aria-disabled=true])::before{background-color:var(--_selected-container-color)}.selected:is(:disabled,[aria-disabled=true])::before{background-color:var(--_disabled-selected-container-color);opacity:var(--_disabled-selected-container-opacity)}@media(forced-colors: active){:host(:is([disabled],[soft-disabled])){--_disabled-outline-opacity: 1}.selected::before{border-color:CanvasText;border-width:var(--_outline-width)}.selected:is(:disabled,[aria-disabled=true])::before{border-color:GrayText;opacity:1}} +`;let yt=class extends M{getRenderClasses(){return{...super.getRenderClasses(),outlined:!0}}};yt.styles=[ut,wi],yt=o([b("md-outlined-icon-button")],yt);function Vr(i,e=te){const t=gt(i,e);return t&&(t.tabIndex=0,t.focus()),t}function qr(i,e=te){const t=Hr(i,e);return t&&(t.tabIndex=0,t.focus()),t}function ki(i,e=te){const t=Ce(i,e);return t&&(t.item.tabIndex=-1),t}function Ce(i,e=te){for(let t=0;t=0;t--){const r=i[t];if(e(r))return r}return null}function Ci(i,e,t=te,r=!0){for(let a=1;ae&&!r)return null;const s=i[n];if(t(s))return s}return i[e]?i[e]:null}function Ur(i,e,t=te,r=!0){if(e){const a=Ci(i,e.index,t,r);return a&&(a.tabIndex=0,a.focus()),a}else return Vr(i,t)}function Kr(i,e,t=te,r=!0){if(e){const a=Ei(i,e.index,t,r);return a&&(a.tabIndex=0,a.focus()),a}else return qr(i,t)}function xt(){return new Event("deactivate-items",{bubbles:!0,composed:!0})}function Wr(){return new Event("request-activation",{bubbles:!0,composed:!0})}function te(i){return!i.disabled}const V={ArrowDown:"ArrowDown",ArrowLeft:"ArrowLeft",ArrowUp:"ArrowUp",ArrowRight:"ArrowRight",Home:"Home",End:"End"};class Gr{constructor(e){this.handleKeydown=u=>{const f=u.key;if(u.defaultPrevented||!this.isNavigableKey(f))return;const m=this.items;if(!m.length)return;const w=Ce(m,this.isActivatable);u.preventDefault();const L=this.isRtl(),E=L?V.ArrowRight:V.ArrowLeft,A=L?V.ArrowLeft:V.ArrowRight;let F=null;switch(f){case V.ArrowDown:case A:F=Ur(m,w,this.isActivatable,this.wrapNavigation());break;case V.ArrowUp:case E:F=Kr(m,w,this.isActivatable,this.wrapNavigation());break;case V.Home:F=Vr(m,this.isActivatable);break;case V.End:F=qr(m,this.isActivatable);break}F&&w&&w.item!==F&&(w.item.tabIndex=-1)},this.onDeactivateItems=()=>{const u=this.items;for(const f of u)this.deactivateItem(f)},this.onRequestActivation=u=>{this.onDeactivateItems();const f=u.target;this.activateItem(f),f.focus()},this.onSlotchange=()=>{const u=this.items;let f=!1;for(const w of u){if(!w.disabled&&w.tabIndex>-1&&!f){f=!0,w.tabIndex=0;continue}w.tabIndex=-1}if(f)return;const m=gt(u,this.isActivatable);m&&(m.tabIndex=0)};const{isItem:t,getPossibleItems:r,isRtl:a,deactivateItem:n,activateItem:s,isNavigableKey:h,isActivatable:p,wrapNavigation:y}=e;this.isItem=t,this.getPossibleItems=r,this.isRtl=a,this.deactivateItem=n,this.activateItem=s,this.isNavigableKey=h,this.isActivatable=p,this.wrapNavigation=y??(()=>!0)}get items(){const e=this.getPossibleItems(),t=[];for(const r of e){if(this.isItem(r)){t.push(r);continue}const n=r.item;n&&this.isItem(n)&&t.push(n)}return t}activateNextItem(){const e=this.items,t=Ce(e,this.isActivatable);return t&&(t.item.tabIndex=-1),Ur(e,t,this.isActivatable,this.wrapNavigation())}activatePreviousItem(){const e=this.items,t=Ce(e,this.isActivatable);return t&&(t.item.tabIndex=-1),Kr(e,t,this.isActivatable,this.wrapNavigation())}}const Ii=new Set(Object.values(V));class Xr extends _{get items(){return this.listController.items}constructor(){super(),this.listController=new Gr({isItem:e=>e.hasAttribute("md-list-item"),getPossibleItems:()=>this.slotItems,isRtl:()=>getComputedStyle(this).direction==="rtl",deactivateItem:e=>{e.tabIndex=-1},activateItem:e=>{e.tabIndex=0},isNavigableKey:e=>Ii.has(e),isActivatable:e=>!e.disabled&&e.type!=="text"}),this.internals=this.attachInternals(),T||(this.internals.role="list",this.addEventListener("keydown",this.listController.handleKeydown))}render(){return d` + + + `}activateNextItem(){return this.listController.activateNextItem()}activatePreviousItem(){return this.listController.activatePreviousItem()}}o([H({flatten:!0})],Xr.prototype,"slotItems",void 0);const Ti=v`:host{background:var(--md-list-container-color, var(--md-sys-color-surface, #fef7ff));color:unset;display:flex;flex-direction:column;outline:none;padding:8px 0;position:relative} +`;let _t=class extends Xr{};_t.styles=[Ti],_t=o([b("md-list")],_t);class cr extends _{constructor(){super(...arguments),this.multiline=!1}render(){return d` + + +
+ + + + +
+ + + `}handleTextSlotChange(){let e=!1,t=0;for(const r of this.textSlots)if(zi(r)&&(t+=1),t>1){e=!0;break}this.multiline=e}}o([l({type:Boolean,reflect:!0})],cr.prototype,"multiline",void 0),o([fo(".text slot")],cr.prototype,"textSlots",void 0);function zi(i){for(const e of i.assignedNodes({flatten:!0})){const t=e.nodeType===Node.ELEMENT_NODE,r=e.nodeType===Node.TEXT_NODE&&e.textContent?.match(/\S/);if(t||r)return!0}return!1}const Ai=v`:host{color:var(--md-sys-color-on-surface, #1d1b20);font-family:var(--md-sys-typescale-body-large-font, var(--md-ref-typeface-plain, Roboto));font-size:var(--md-sys-typescale-body-large-size, 1rem);font-weight:var(--md-sys-typescale-body-large-weight, var(--md-ref-typeface-weight-regular, 400));line-height:var(--md-sys-typescale-body-large-line-height, 1.5rem);align-items:center;box-sizing:border-box;display:flex;gap:16px;min-height:56px;overflow:hidden;padding:12px 16px;position:relative;text-overflow:ellipsis}:host([multiline]){min-height:72px}[name=overline]{color:var(--md-sys-color-on-surface-variant, #49454f);font-family:var(--md-sys-typescale-label-small-font, var(--md-ref-typeface-plain, Roboto));font-size:var(--md-sys-typescale-label-small-size, 0.6875rem);font-weight:var(--md-sys-typescale-label-small-weight, var(--md-ref-typeface-weight-medium, 500));line-height:var(--md-sys-typescale-label-small-line-height, 1rem)}[name=supporting-text]{color:var(--md-sys-color-on-surface-variant, #49454f);font-family:var(--md-sys-typescale-body-medium-font, var(--md-ref-typeface-plain, Roboto));font-size:var(--md-sys-typescale-body-medium-size, 0.875rem);font-weight:var(--md-sys-typescale-body-medium-weight, var(--md-ref-typeface-weight-regular, 400));line-height:var(--md-sys-typescale-body-medium-line-height, 1.25rem)}[name=trailing-supporting-text]{color:var(--md-sys-color-on-surface-variant, #49454f);font-family:var(--md-sys-typescale-label-small-font, var(--md-ref-typeface-plain, Roboto));font-size:var(--md-sys-typescale-label-small-size, 0.6875rem);font-weight:var(--md-sys-typescale-label-small-weight, var(--md-ref-typeface-weight-medium, 500));line-height:var(--md-sys-typescale-label-small-line-height, 1rem)}[name=container]::slotted(*){inset:0;position:absolute}.default-slot{display:inline}.default-slot,.text ::slotted(*){overflow:hidden;text-overflow:ellipsis}.text{display:flex;flex:1;flex-direction:column;overflow:hidden} +`;let hr=class extends cr{};hr.styles=[Ai],hr=o([b("md-item")],hr);const Si=W(_);class ce extends Si{constructor(){super(...arguments),this.disabled=!1,this.type="text",this.isListItem=!0,this.href="",this.target=""}get isDisabled(){return this.disabled&&this.type!=="link"}willUpdate(e){this.href&&(this.type="link"),super.willUpdate(e)}render(){return this.renderListItem(d` + +
+ ${this.renderRipple()} ${this.renderFocusRing()} +
+ + + ${this.renderBody()} +
+ `)}renderListItem(e){const t=this.type==="link";let r;switch(this.type){case"link":r=K`a`;break;case"button":r=K`button`;break;default:case"text":r=K`li`;break}const a=this.type!=="text",n=t&&this.target?this.target:c;return ze` + <${r} + id="item" + tabindex="${this.isDisabled||!a?-1:0}" + ?disabled=${this.isDisabled} + role="listitem" + aria-selected=${this.ariaSelected||c} + aria-checked=${this.ariaChecked||c} + aria-expanded=${this.ariaExpanded||c} + aria-haspopup=${this.ariaHasPopup||c} + class="list-item ${S(this.getRenderClasses())}" + href=${this.href||c} + target=${n} + @focus=${this.onFocus} + >${e} + `}renderRipple(){return this.type==="text"?c:d` `}renderFocusRing(){return this.type==="text"?c:d` `}onFocusRingVisibilityChanged(e){}getRenderClasses(){return{disabled:this.isDisabled}}renderBody(){return d` + + + + + + `}onFocus(){this.tabIndex===-1&&this.dispatchEvent(Wr())}focus(){this.listItemRoot?.focus()}click(){if(!this.listItemRoot){super.click();return}this.listItemRoot.click()}}ce.shadowRootOptions={..._.shadowRootOptions,delegatesFocus:!0},o([l({type:Boolean,reflect:!0})],ce.prototype,"disabled",void 0),o([l({reflect:!0})],ce.prototype,"type",void 0),o([l({type:Boolean,attribute:"md-list-item",reflect:!0})],ce.prototype,"isListItem",void 0),o([l()],ce.prototype,"href",void 0),o([l()],ce.prototype,"target",void 0),o([g(".list-item")],ce.prototype,"listItemRoot",void 0);const $i=v`:host{display:flex;-webkit-tap-highlight-color:rgba(0,0,0,0);--md-ripple-hover-color: var(--md-list-item-hover-state-layer-color, var(--md-sys-color-on-surface, #1d1b20));--md-ripple-hover-opacity: var(--md-list-item-hover-state-layer-opacity, 0.08);--md-ripple-pressed-color: var(--md-list-item-pressed-state-layer-color, var(--md-sys-color-on-surface, #1d1b20));--md-ripple-pressed-opacity: var(--md-list-item-pressed-state-layer-opacity, 0.12)}:host(:is([type=button]:not([disabled]),[type=link])){cursor:pointer}md-focus-ring{z-index:1;--md-focus-ring-shape: 8px}a,button,li{background:none;border:none;cursor:inherit;padding:0;margin:0;text-align:unset;text-decoration:none}.list-item{border-radius:inherit;display:flex;flex:1;max-width:inherit;min-width:inherit;outline:none;-webkit-tap-highlight-color:rgba(0,0,0,0);width:100%}.list-item.interactive{cursor:pointer}.list-item.disabled{opacity:var(--md-list-item-disabled-opacity, 0.3);pointer-events:none}[slot=container]{pointer-events:none}md-ripple{border-radius:inherit}md-item{border-radius:inherit;flex:1;height:100%;color:var(--md-list-item-label-text-color, var(--md-sys-color-on-surface, #1d1b20));font-family:var(--md-list-item-label-text-font, var(--md-sys-typescale-body-large-font, var(--md-ref-typeface-plain, Roboto)));font-size:var(--md-list-item-label-text-size, var(--md-sys-typescale-body-large-size, 1rem));line-height:var(--md-list-item-label-text-line-height, var(--md-sys-typescale-body-large-line-height, 1.5rem));font-weight:var(--md-list-item-label-text-weight, var(--md-sys-typescale-body-large-weight, var(--md-ref-typeface-weight-regular, 400)));min-height:var(--md-list-item-one-line-container-height, 56px);padding-top:var(--md-list-item-top-space, 12px);padding-bottom:var(--md-list-item-bottom-space, 12px);padding-inline-start:var(--md-list-item-leading-space, 16px);padding-inline-end:var(--md-list-item-trailing-space, 16px)}md-item[multiline]{min-height:var(--md-list-item-two-line-container-height, 72px)}[slot=supporting-text]{color:var(--md-list-item-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));font-family:var(--md-list-item-supporting-text-font, var(--md-sys-typescale-body-medium-font, var(--md-ref-typeface-plain, Roboto)));font-size:var(--md-list-item-supporting-text-size, var(--md-sys-typescale-body-medium-size, 0.875rem));line-height:var(--md-list-item-supporting-text-line-height, var(--md-sys-typescale-body-medium-line-height, 1.25rem));font-weight:var(--md-list-item-supporting-text-weight, var(--md-sys-typescale-body-medium-weight, var(--md-ref-typeface-weight-regular, 400)))}[slot=trailing-supporting-text]{color:var(--md-list-item-trailing-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));font-family:var(--md-list-item-trailing-supporting-text-font, var(--md-sys-typescale-label-small-font, var(--md-ref-typeface-plain, Roboto)));font-size:var(--md-list-item-trailing-supporting-text-size, var(--md-sys-typescale-label-small-size, 0.6875rem));line-height:var(--md-list-item-trailing-supporting-text-line-height, var(--md-sys-typescale-label-small-line-height, 1rem));font-weight:var(--md-list-item-trailing-supporting-text-weight, var(--md-sys-typescale-label-small-weight, var(--md-ref-typeface-weight-medium, 500)))}:is([slot=start],[slot=end])::slotted(*){fill:currentColor}[slot=start]{color:var(--md-list-item-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f))}[slot=end]{color:var(--md-list-item-trailing-icon-color, var(--md-sys-color-on-surface-variant, #49454f))}@media(forced-colors: active){.disabled slot{color:GrayText}.list-item.disabled{color:GrayText;opacity:1}} +`;let wt=class extends ce{};wt.styles=[$i],wt=o([b("md-list-item")],wt);function Ri(i,e){return new CustomEvent("close-menu",{bubbles:!0,composed:!0,detail:{initiator:i,reason:e,itemPath:[i]}})}const Yr=Ri;function Oi(){return new Event("deactivate-typeahead",{bubbles:!0,composed:!0})}function pr(){return new Event("activate-typeahead",{bubbles:!0,composed:!0})}const he={RIGHT:"ArrowRight",LEFT:"ArrowLeft"},Ee={SPACE:"Space",ENTER:"Enter"},kt={CLICK_SELECTION:"click-selection",KEYDOWN:"keydown"},vr={ESCAPE:"Escape",SPACE:Ee.SPACE,ENTER:Ee.ENTER};function jr(i){return Object.values(vr).some(e=>e===i)}function Li(i){return Object.values(Ee).some(e=>e===i)}function ur(i,e){const t=new Event("md-contains",{bubbles:!0,composed:!0});let r=[];const a=s=>{r=s.composedPath()};return e.addEventListener("md-contains",a),i.dispatchEvent(t),e.removeEventListener("md-contains",a),r.length>0}const X={NONE:"none",LIST_ROOT:"list-root",FIRST_ITEM:"first-item",LAST_ITEM:"last-item"};const Fe={END_START:"end-start",END_END:"end-end",START_START:"start-start",START_END:"start-end"};class Fi{constructor(e,t){this.host=e,this.getProperties=t,this.surfaceStylesInternal={display:"none"},this.lastValues={isOpen:!1},this.host.addController(this)}get surfaceStyles(){return this.surfaceStylesInternal}async position(){const{surfaceEl:e,anchorEl:t,anchorCorner:r,surfaceCorner:a,positioning:n,xOffset:s,yOffset:h,disableBlockFlip:p,disableInlineFlip:y,repositionStrategy:u}=this.getProperties(),f=r.toLowerCase().trim(),m=a.toLowerCase().trim();if(!e||!t)return;const w=window.innerWidth,L=window.innerHeight,E=document.createElement("div");E.style.opacity="0",E.style.position="fixed",E.style.display="block",E.style.inset="0",document.body.appendChild(E);const A=E.getBoundingClientRect();E.remove();const F=window.innerHeight-A.bottom,I=window.innerWidth-A.right;this.surfaceStylesInternal={display:"block",opacity:"0"},this.host.requestUpdate(),await this.host.updateComplete,e.popover&&e.isConnected&&e.showPopover();const B=e.getSurfacePositionClientRect?e.getSurfacePositionClientRect():e.getBoundingClientRect(),q=t.getSurfacePositionClientRect?t.getSurfacePositionClientRect():t.getBoundingClientRect(),[D,le]=m.split("-"),[ne,ue]=f.split("-"),Me=getComputedStyle(e).direction==="ltr";let{blockInset:xe,blockOutOfBoundsCorrection:J,surfaceBlockProperty:yr}=this.calculateBlock({surfaceRect:B,anchorRect:q,anchorBlock:ne,surfaceBlock:D,yOffset:h,positioning:n,windowInnerHeight:L,blockScrollbarHeight:F});if(J&&!p){const jt=D==="start"?"end":"start",Zt=ne==="start"?"end":"start",re=this.calculateBlock({surfaceRect:B,anchorRect:q,anchorBlock:Zt,surfaceBlock:jt,yOffset:h,positioning:n,windowInnerHeight:L,blockScrollbarHeight:F});J>re.blockOutOfBoundsCorrection&&(xe=re.blockInset,J=re.blockOutOfBoundsCorrection,yr=re.surfaceBlockProperty)}let{inlineInset:Be,inlineOutOfBoundsCorrection:_e,surfaceInlineProperty:gr}=this.calculateInline({surfaceRect:B,anchorRect:q,anchorInline:ue,surfaceInline:le,xOffset:s,positioning:n,isLTR:Me,windowInnerWidth:w,inlineScrollbarWidth:I});if(_e&&!y){const jt=le==="start"?"end":"start",Zt=ue==="start"?"end":"start",re=this.calculateInline({surfaceRect:B,anchorRect:q,anchorInline:Zt,surfaceInline:jt,xOffset:s,positioning:n,isLTR:Me,windowInnerWidth:w,inlineScrollbarWidth:I});Math.abs(_e)>Math.abs(re.inlineOutOfBoundsCorrection)&&(Be=re.inlineInset,_e=re.inlineOutOfBoundsCorrection,gr=re.surfaceInlineProperty)}u==="move"&&(xe=xe-J,Be=Be-_e),this.surfaceStylesInternal={display:"block",opacity:"1",[yr]:`${xe}px`,[gr]:`${Be}px`},u==="resize"&&(J&&(this.surfaceStylesInternal.height=`${B.height-J}px`),_e&&(this.surfaceStylesInternal.width=`${B.width-_e}px`)),this.host.requestUpdate()}calculateBlock(e){const{surfaceRect:t,anchorRect:r,anchorBlock:a,surfaceBlock:n,yOffset:s,positioning:h,windowInnerHeight:p,blockScrollbarHeight:y}=e,u=h==="fixed"||h==="document"?1:0,f=h==="document"?1:0,m=n==="start"?1:0,w=n==="end"?1:0,E=(a!==n?1:0)*r.height+s,A=m*r.top+w*(p-r.bottom-y),F=m*window.scrollY-w*window.scrollY,I=Math.abs(Math.min(0,p-A-E-t.height));return{blockInset:u*A+f*F+E,blockOutOfBoundsCorrection:I,surfaceBlockProperty:n==="start"?"inset-block-start":"inset-block-end"}}calculateInline(e){const{isLTR:t,surfaceInline:r,anchorInline:a,anchorRect:n,surfaceRect:s,xOffset:h,positioning:p,windowInnerWidth:y,inlineScrollbarWidth:u}=e,f=p==="fixed"||p==="document"?1:0,m=p==="document"?1:0,w=t?1:0,L=t?0:1,E=r==="start"?1:0,A=r==="end"?1:0,I=(a!==r?1:0)*n.width+h,B=E*n.left+A*(y-n.right-u),q=E*(y-n.right-u)+A*n.left,D=w*B+L*q,le=E*window.scrollX-A*window.scrollX,ne=A*window.scrollX-E*window.scrollX,ue=w*le+L*ne,Me=Math.abs(Math.min(0,y-D-I-s.width)),xe=f*D+I+m*ue;let J=r==="start"?"inset-inline-start":"inset-inline-end";return(p==="document"||p==="fixed")&&(r==="start"&&t||r==="end"&&!t?J="left":J="right"),{inlineInset:xe,inlineOutOfBoundsCorrection:Me,surfaceInlineProperty:J}}hostUpdate(){this.onUpdate()}hostUpdated(){this.onUpdate()}async onUpdate(){const e=this.getProperties();let t=!1;for(const[s,h]of Object.entries(e))if(t=t||h!==this.lastValues[s],t)break;const r=this.lastValues.isOpen!==e.isOpen,a=!!e.anchorEl,n=!!e.surfaceEl;t&&a&&n&&(this.lastValues.isOpen=e.isOpen,e.isOpen?(this.lastValues=e,await this.position(),e.onOpen()):r&&(await e.beforeClose(),this.close(),e.onClose()))}close(){this.surfaceStylesInternal={display:"none"},this.host.requestUpdate();const e=this.getProperties().surfaceEl;e?.popover&&e?.isConnected&&e.hidePopover()}}const Y={INDEX:0,ITEM:1,TEXT:2};class Di{constructor(e){this.getProperties=e,this.typeaheadRecords=[],this.typaheadBuffer="",this.cancelTypeaheadTimeout=0,this.isTypingAhead=!1,this.lastActiveRecord=null,this.onKeydown=t=>{this.isTypingAhead?this.typeahead(t):this.beginTypeahead(t)},this.endTypeahead=()=>{this.isTypingAhead=!1,this.typaheadBuffer="",this.typeaheadRecords=[]}}get items(){return this.getProperties().getItems()}get active(){return this.getProperties().active}beginTypeahead(e){this.active&&(e.code==="Space"||e.code==="Enter"||e.code.startsWith("Arrow")||e.code==="Escape"||(this.isTypingAhead=!0,this.typeaheadRecords=this.items.map((t,r)=>[r,t,t.typeaheadText.trim().toLowerCase()]),this.lastActiveRecord=this.typeaheadRecords.find(t=>t[Y.ITEM].tabIndex===0)??null,this.lastActiveRecord&&(this.lastActiveRecord[Y.ITEM].tabIndex=-1),this.typeahead(e)))}typeahead(e){if(e.defaultPrevented)return;if(clearTimeout(this.cancelTypeaheadTimeout),e.code==="Enter"||e.code.startsWith("Arrow")||e.code==="Escape"){this.endTypeahead(),this.lastActiveRecord&&(this.lastActiveRecord[Y.ITEM].tabIndex=-1);return}e.code==="Space"&&e.preventDefault(),this.cancelTypeaheadTimeout=setTimeout(this.endTypeahead,this.getProperties().typeaheadBufferTime),this.typaheadBuffer+=e.key.toLowerCase();const t=this.lastActiveRecord?this.lastActiveRecord[Y.INDEX]:-1,r=this.typeaheadRecords.length,a=p=>(p[Y.INDEX]+r-t)%r,n=this.typeaheadRecords.filter(p=>!p[Y.ITEM].disabled&&p[Y.TEXT].startsWith(this.typaheadBuffer)).sort((p,y)=>a(p)-a(y));if(n.length===0){clearTimeout(this.cancelTypeaheadTimeout),this.lastActiveRecord&&(this.lastActiveRecord[Y.ITEM].tabIndex=-1),this.endTypeahead();return}const s=this.typaheadBuffer.length===1;let h;this.lastActiveRecord===n[0]&&s?h=n[1]??n[0]:h=n[0],this.lastActiveRecord&&(this.lastActiveRecord[Y.ITEM].tabIndex=-1),this.lastActiveRecord=h,h[Y.ITEM].tabIndex=0,h[Y.ITEM].focus()}}const Zr=200,Qr=new Set([V.ArrowDown,V.ArrowUp,V.Home,V.End]),Pi=new Set([V.ArrowLeft,V.ArrowRight,...Qr]);function Mi(i=document){let e=i.activeElement;for(;e&&e?.shadowRoot?.activeElement;)e=e.shadowRoot.activeElement;return e}class R extends _{get openDirection(){return this.menuCorner.split("-")[0]==="start"?"DOWN":"UP"}get anchorElement(){return this.anchor?this.getRootNode().querySelector(`#${this.anchor}`):this.currentAnchorElement}set anchorElement(e){this.currentAnchorElement=e,this.requestUpdate("anchorElement")}constructor(){super(),this.anchor="",this.positioning="absolute",this.quick=!1,this.hasOverflow=!1,this.open=!1,this.xOffset=0,this.yOffset=0,this.noHorizontalFlip=!1,this.noVerticalFlip=!1,this.typeaheadDelay=Zr,this.anchorCorner=Fe.END_START,this.menuCorner=Fe.START_START,this.stayOpenOnOutsideClick=!1,this.stayOpenOnFocusout=!1,this.skipRestoreFocus=!1,this.defaultFocus=X.FIRST_ITEM,this.noNavigationWrap=!1,this.typeaheadActive=!0,this.isSubmenu=!1,this.pointerPath=[],this.isRepositioning=!1,this.openCloseAnimationSignal=xo(),this.listController=new Gr({isItem:e=>e.hasAttribute("md-menu-item"),getPossibleItems:()=>this.slotItems,isRtl:()=>getComputedStyle(this).direction==="rtl",deactivateItem:e=>{e.selected=!1,e.tabIndex=-1},activateItem:e=>{e.selected=!0,e.tabIndex=0},isNavigableKey:e=>{if(!this.isSubmenu)return Pi.has(e);const r=getComputedStyle(this).direction==="rtl"?V.ArrowLeft:V.ArrowRight;return e===r?!0:Qr.has(e)},wrapNavigation:()=>!this.noNavigationWrap}),this.lastFocusedElement=null,this.typeaheadController=new Di(()=>({getItems:()=>this.items,typeaheadBufferTime:this.typeaheadDelay,active:this.typeaheadActive})),this.currentAnchorElement=null,this.internals=this.attachInternals(),this.menuPositionController=new Fi(this,()=>({anchorCorner:this.anchorCorner,surfaceCorner:this.menuCorner,surfaceEl:this.surfaceEl,anchorEl:this.anchorElement,positioning:this.positioning==="popover"?"document":this.positioning,isOpen:this.open,xOffset:this.xOffset,yOffset:this.yOffset,disableBlockFlip:this.noVerticalFlip,disableInlineFlip:this.noHorizontalFlip,onOpen:this.onOpened,beforeClose:this.beforeClose,onClose:this.onClosed,repositionStrategy:this.hasOverflow&&this.positioning!=="popover"?"move":"resize"})),this.onWindowResize=()=>{this.isRepositioning||this.positioning!=="document"&&this.positioning!=="fixed"&&this.positioning!=="popover"||(this.isRepositioning=!0,this.reposition(),this.isRepositioning=!1)},this.handleFocusout=async e=>{const t=this.anchorElement;if(this.stayOpenOnFocusout||!this.open||this.pointerPath.includes(t))return;if(e.relatedTarget){if(ur(e.relatedTarget,this)||this.pointerPath.length!==0&&ur(e.relatedTarget,t))return}else if(this.pointerPath.includes(this))return;const r=this.skipRestoreFocus;this.skipRestoreFocus=!0,this.close(),await this.updateComplete,this.skipRestoreFocus=r},this.onOpened=async()=>{this.lastFocusedElement=Mi();const e=this.items,t=Ce(e);t&&this.defaultFocus!==X.NONE&&(t.item.tabIndex=-1);let r=!this.quick;switch(this.quick?this.dispatchEvent(new Event("opening")):r=!!await this.animateOpen(),this.defaultFocus){case X.FIRST_ITEM:const a=gt(e);a&&(a.tabIndex=0,a.focus(),await a.updateComplete);break;case X.LAST_ITEM:const n=Hr(e);n&&(n.tabIndex=0,n.focus(),await n.updateComplete);break;case X.LIST_ROOT:this.focus();break;default:case X.NONE:break}r||this.dispatchEvent(new Event("opened"))},this.beforeClose=async()=>{this.open=!1,this.skipRestoreFocus||this.lastFocusedElement?.focus?.(),this.quick||await this.animateClose()},this.onClosed=()=>{this.quick&&(this.dispatchEvent(new Event("closing")),this.dispatchEvent(new Event("closed")))},this.onWindowPointerdown=e=>{this.pointerPath=e.composedPath()},this.onDocumentClick=e=>{if(!this.open)return;const t=e.composedPath();!this.stayOpenOnOutsideClick&&!t.includes(this)&&!t.includes(this.anchorElement)&&(this.open=!1)},T||(this.internals.role="menu",this.addEventListener("keydown",this.handleKeydown),this.addEventListener("keydown",this.captureKeydown,{capture:!0}),this.addEventListener("focusout",this.handleFocusout))}get items(){return this.listController.items}willUpdate(e){if(e.has("open")){if(this.open){this.removeAttribute("aria-hidden");return}this.setAttribute("aria-hidden","true")}}update(e){e.has("open")&&(this.open?this.setUpGlobalEventListeners():this.cleanUpGlobalEventListeners()),e.has("positioning")&&this.positioning==="popover"&&!this.showPopover&&(this.positioning="fixed"),super.update(e)}connectedCallback(){super.connectedCallback(),this.open&&this.setUpGlobalEventListeners()}disconnectedCallback(){super.disconnectedCallback(),this.cleanUpGlobalEventListeners()}getBoundingClientRect(){return this.surfaceEl?this.surfaceEl.getBoundingClientRect():super.getBoundingClientRect()}getClientRects(){return this.surfaceEl?this.surfaceEl.getClientRects():super.getClientRects()}render(){return this.renderSurface()}renderSurface(){return d` + + `}renderMenuItems(){return d``}renderElevation(){return d``}getSurfaceClasses(){return{open:this.open,fixed:this.positioning==="fixed","has-overflow":this.hasOverflow}}captureKeydown(e){e.target===this&&!e.defaultPrevented&&jr(e.code)&&(e.preventDefault(),this.close()),this.typeaheadController.onKeydown(e)}async animateOpen(){const e=this.surfaceEl,t=this.slotEl;if(!e||!t)return!0;const r=this.openDirection;this.dispatchEvent(new Event("opening")),e.classList.toggle("animating",!0);const a=this.openCloseAnimationSignal.start(),n=e.offsetHeight,s=r==="UP",h=this.items,p=500,y=50,u=250,f=(p-u)/h.length,m=e.animate([{height:"0px"},{height:`${n}px`}],{duration:p,easing:Z.EMPHASIZED}),w=t.animate([{transform:s?`translateY(-${n}px)`:""},{transform:""}],{duration:p,easing:Z.EMPHASIZED}),L=e.animate([{opacity:0},{opacity:1}],y),E=[];for(let I=0;I{q.classList.toggle("md-menu-hidden",!1)}),E.push([q,D])}let A=I=>{};const F=new Promise(I=>{A=I});return a.addEventListener("abort",()=>{m.cancel(),w.cancel(),L.cancel(),E.forEach(([I,B])=>{I.classList.toggle("md-menu-hidden",!1),B.cancel()}),A(!0)}),m.addEventListener("finish",()=>{e.classList.toggle("animating",!1),this.openCloseAnimationSignal.finish(),A(!1)}),await F}animateClose(){let e;const t=new Promise(D=>{e=D}),r=this.surfaceEl,a=this.slotEl;if(!r||!a)return e(!1),t;const s=this.openDirection==="UP";this.dispatchEvent(new Event("closing")),r.classList.toggle("animating",!0);const h=this.openCloseAnimationSignal.start(),p=r.offsetHeight,y=this.items,u=150,f=50,m=u-f,w=50,L=50,E=.35,A=(u-L-w)/y.length,F=r.animate([{height:`${p}px`},{height:`${p*E}px`}],{duration:u,easing:Z.EMPHASIZED_ACCELERATE}),I=a.animate([{transform:""},{transform:s?`translateY(-${p*(1-E)}px)`:""}],{duration:u,easing:Z.EMPHASIZED_ACCELERATE}),B=r.animate([{opacity:1},{opacity:0}],{duration:f,delay:m}),q=[];for(let D=0;D{ne.classList.toggle("md-menu-hidden",!0)}),q.push([ne,ue])}return h.addEventListener("abort",()=>{F.cancel(),I.cancel(),B.cancel(),q.forEach(([D,le])=>{le.cancel(),D.classList.toggle("md-menu-hidden",!1)}),e(!1)}),F.addEventListener("finish",()=>{r.classList.toggle("animating",!1),q.forEach(([D])=>{D.classList.toggle("md-menu-hidden",!1)}),this.openCloseAnimationSignal.finish(),this.dispatchEvent(new Event("closed")),e(!0)}),t}handleKeydown(e){this.pointerPath=[],this.listController.handleKeydown(e)}setUpGlobalEventListeners(){document.addEventListener("click",this.onDocumentClick,{capture:!0}),window.addEventListener("pointerdown",this.onWindowPointerdown),document.addEventListener("resize",this.onWindowResize,{passive:!0}),window.addEventListener("resize",this.onWindowResize,{passive:!0})}cleanUpGlobalEventListeners(){document.removeEventListener("click",this.onDocumentClick,{capture:!0}),window.removeEventListener("pointerdown",this.onWindowPointerdown),document.removeEventListener("resize",this.onWindowResize),window.removeEventListener("resize",this.onWindowResize)}onCloseMenu(){this.close()}onDeactivateItems(e){e.stopPropagation(),this.listController.onDeactivateItems()}onRequestActivation(e){e.stopPropagation(),this.listController.onRequestActivation(e)}handleDeactivateTypeahead(e){e.stopPropagation(),this.typeaheadActive=!1}handleActivateTypeahead(e){e.stopPropagation(),this.typeaheadActive=!0}handleStayOpenOnFocusout(e){e.stopPropagation(),this.stayOpenOnFocusout=!0}handleCloseOnFocusout(e){e.stopPropagation(),this.stayOpenOnFocusout=!1}close(){this.open=!1,this.slotItems.forEach(t=>{t.close?.()})}show(){this.open=!0}activateNextItem(){return this.listController.activateNextItem()??null}activatePreviousItem(){return this.listController.activatePreviousItem()??null}reposition(){this.open&&this.menuPositionController.position()}}o([g(".menu")],R.prototype,"surfaceEl",void 0),o([g("slot")],R.prototype,"slotEl",void 0),o([l()],R.prototype,"anchor",void 0),o([l()],R.prototype,"positioning",void 0),o([l({type:Boolean})],R.prototype,"quick",void 0),o([l({type:Boolean,attribute:"has-overflow"})],R.prototype,"hasOverflow",void 0),o([l({type:Boolean,reflect:!0})],R.prototype,"open",void 0),o([l({type:Number,attribute:"x-offset"})],R.prototype,"xOffset",void 0),o([l({type:Number,attribute:"y-offset"})],R.prototype,"yOffset",void 0),o([l({type:Boolean,attribute:"no-horizontal-flip"})],R.prototype,"noHorizontalFlip",void 0),o([l({type:Boolean,attribute:"no-vertical-flip"})],R.prototype,"noVerticalFlip",void 0),o([l({type:Number,attribute:"typeahead-delay"})],R.prototype,"typeaheadDelay",void 0),o([l({attribute:"anchor-corner"})],R.prototype,"anchorCorner",void 0),o([l({attribute:"menu-corner"})],R.prototype,"menuCorner",void 0),o([l({type:Boolean,attribute:"stay-open-on-outside-click"})],R.prototype,"stayOpenOnOutsideClick",void 0),o([l({type:Boolean,attribute:"stay-open-on-focusout"})],R.prototype,"stayOpenOnFocusout",void 0),o([l({type:Boolean,attribute:"skip-restore-focus"})],R.prototype,"skipRestoreFocus",void 0),o([l({attribute:"default-focus"})],R.prototype,"defaultFocus",void 0),o([l({type:Boolean,attribute:"no-navigation-wrap"})],R.prototype,"noNavigationWrap",void 0),o([H({flatten:!0})],R.prototype,"slotItems",void 0),o([k()],R.prototype,"typeaheadActive",void 0);const Bi=v`:host{--md-elevation-level: var(--md-menu-container-elevation, 2);--md-elevation-shadow-color: var(--md-menu-container-shadow-color, var(--md-sys-color-shadow, #000));min-width:112px;color:unset;display:contents}md-focus-ring{--md-focus-ring-shape: var(--md-menu-container-shape, var(--md-sys-shape-corner-extra-small, 4px))}.menu{border-radius:var(--md-menu-container-shape, var(--md-sys-shape-corner-extra-small, 4px));display:none;inset:auto;border:none;padding:0px;overflow:visible;background-color:rgba(0,0,0,0);color:inherit;opacity:0;z-index:20;position:absolute;user-select:none;max-height:inherit;height:inherit;min-width:inherit;max-width:inherit;scrollbar-width:inherit}.menu::backdrop{display:none}.fixed{position:fixed}.items{display:block;list-style-type:none;margin:0;outline:none;box-sizing:border-box;background-color:var(--md-menu-container-color, var(--md-sys-color-surface-container, #f3edf7));height:inherit;max-height:inherit;overflow:auto;min-width:inherit;max-width:inherit;border-radius:inherit;scrollbar-width:inherit}.item-padding{padding-block:var(--md-menu-top-space, 8px) var(--md-menu-bottom-space, 8px)}.has-overflow:not([popover]) .items{overflow:visible}.has-overflow.animating .items,.animating .items{overflow:hidden}.has-overflow.animating .items{pointer-events:none}.animating ::slotted(.md-menu-hidden){opacity:0}slot{display:block;height:inherit;max-height:inherit}::slotted(:is(md-divider,[role=separator])){margin:8px 0}@media(forced-colors: active){.menu{border-style:solid;border-color:CanvasText;border-width:1px}} +`;let Ct=class extends R{};Ct.styles=[Bi],Ct=o([b("md-menu")],Ct);class Jr{constructor(e,t){this.host=e,this.internalTypeaheadText=null,this.onClick=()=>{this.host.keepOpen||this.host.dispatchEvent(Yr(this.host,{kind:kt.CLICK_SELECTION}))},this.onKeydown=r=>{if(this.host.href&&r.code==="Enter"){const n=this.getInteractiveElement();n instanceof HTMLAnchorElement&&n.click()}if(r.defaultPrevented)return;const a=r.code;this.host.keepOpen&&a!=="Escape"||jr(a)&&(r.preventDefault(),this.host.dispatchEvent(Yr(this.host,{kind:kt.KEYDOWN,key:a})))},this.getHeadlineElements=t.getHeadlineElements,this.getSupportingTextElements=t.getSupportingTextElements,this.getDefaultElements=t.getDefaultElements,this.getInteractiveElement=t.getInteractiveElement,this.host.addController(this)}get typeaheadText(){if(this.internalTypeaheadText!==null)return this.internalTypeaheadText;const e=this.getHeadlineElements(),t=[];return e.forEach(r=>{r.textContent&&r.textContent.trim()&&t.push(r.textContent.trim())}),t.length===0&&this.getDefaultElements().forEach(r=>{r.textContent&&r.textContent.trim()&&t.push(r.textContent.trim())}),t.length===0&&this.getSupportingTextElements().forEach(r=>{r.textContent&&r.textContent.trim()&&t.push(r.textContent.trim())}),t.join(" ")}get tagName(){switch(this.host.type){case"link":return"a";case"button":return"button";default:case"menuitem":case"option":return"li"}}get role(){return this.host.type==="option"?"option":"menuitem"}hostConnected(){this.host.toggleAttribute("md-menu-item",!0)}hostUpdate(){this.host.href&&(this.host.type="link")}setTypeaheadText(e){this.internalTypeaheadText=e}}const Ni=W(_);class G extends Ni{constructor(){super(...arguments),this.disabled=!1,this.type="menuitem",this.href="",this.target="",this.keepOpen=!1,this.selected=!1,this.menuItemController=new Jr(this,{getHeadlineElements:()=>this.headlineElements,getSupportingTextElements:()=>this.supportingTextElements,getDefaultElements:()=>this.defaultElements,getInteractiveElement:()=>this.listItemRoot})}get typeaheadText(){return this.menuItemController.typeaheadText}set typeaheadText(e){this.menuItemController.setTypeaheadText(e)}render(){return this.renderListItem(d` + +
+ ${this.renderRipple()} ${this.renderFocusRing()} +
+ + + ${this.renderBody()} +
+ `)}renderListItem(e){const t=this.type==="link";let r;switch(this.menuItemController.tagName){case"a":r=K`a`;break;case"button":r=K`button`;break;default:case"li":r=K`li`;break}const a=t&&this.target?this.target:c;return ze` + <${r} + id="item" + tabindex=${this.disabled&&!t?-1:0} + role=${this.menuItemController.role} + aria-label=${this.ariaLabel||c} + aria-selected=${this.ariaSelected||c} + aria-checked=${this.ariaChecked||c} + aria-expanded=${this.ariaExpanded||c} + aria-haspopup=${this.ariaHasPopup||c} + class="list-item ${S(this.getRenderClasses())}" + href=${this.href||c} + target=${a} + @click=${this.menuItemController.onClick} + @keydown=${this.menuItemController.onKeydown} + >${e} + `}renderRipple(){return d` `}renderFocusRing(){return d` `}getRenderClasses(){return{disabled:this.disabled,selected:this.selected}}renderBody(){return d` + + + + + + `}focus(){this.listItemRoot?.focus()}}G.shadowRootOptions={..._.shadowRootOptions,delegatesFocus:!0},o([l({type:Boolean,reflect:!0})],G.prototype,"disabled",void 0),o([l()],G.prototype,"type",void 0),o([l()],G.prototype,"href",void 0),o([l()],G.prototype,"target",void 0),o([l({type:Boolean,attribute:"keep-open"})],G.prototype,"keepOpen",void 0),o([l({type:Boolean})],G.prototype,"selected",void 0),o([g(".list-item")],G.prototype,"listItemRoot",void 0),o([H({slot:"headline"})],G.prototype,"headlineElements",void 0),o([H({slot:"supporting-text"})],G.prototype,"supportingTextElements",void 0),o([Qt({slot:""})],G.prototype,"defaultElements",void 0),o([l({attribute:"typeahead-text"})],G.prototype,"typeaheadText",null);const eo=v`:host{display:flex;--md-ripple-hover-color: var(--md-menu-item-hover-state-layer-color, var(--md-sys-color-on-surface, #1d1b20));--md-ripple-hover-opacity: var(--md-menu-item-hover-state-layer-opacity, 0.08);--md-ripple-pressed-color: var(--md-menu-item-pressed-state-layer-color, var(--md-sys-color-on-surface, #1d1b20));--md-ripple-pressed-opacity: var(--md-menu-item-pressed-state-layer-opacity, 0.12)}:host([disabled]){opacity:var(--md-menu-item-disabled-opacity, 0.3);pointer-events:none}md-focus-ring{z-index:1;--md-focus-ring-shape: 8px}a,button,li{background:none;border:none;padding:0;margin:0;text-align:unset;text-decoration:none}.list-item{border-radius:inherit;display:flex;flex:1;max-width:inherit;min-width:inherit;outline:none;-webkit-tap-highlight-color:rgba(0,0,0,0)}.list-item:not(.disabled){cursor:pointer}[slot=container]{pointer-events:none}md-ripple{border-radius:inherit}md-item{border-radius:inherit;flex:1;color:var(--md-menu-item-label-text-color, var(--md-sys-color-on-surface, #1d1b20));font-family:var(--md-menu-item-label-text-font, var(--md-sys-typescale-body-large-font, var(--md-ref-typeface-plain, Roboto)));font-size:var(--md-menu-item-label-text-size, var(--md-sys-typescale-body-large-size, 1rem));line-height:var(--md-menu-item-label-text-line-height, var(--md-sys-typescale-body-large-line-height, 1.5rem));font-weight:var(--md-menu-item-label-text-weight, var(--md-sys-typescale-body-large-weight, var(--md-ref-typeface-weight-regular, 400)));min-height:var(--md-menu-item-one-line-container-height, 56px);padding-top:var(--md-menu-item-top-space, 12px);padding-bottom:var(--md-menu-item-bottom-space, 12px);padding-inline-start:var(--md-menu-item-leading-space, 16px);padding-inline-end:var(--md-menu-item-trailing-space, 16px)}md-item[multiline]{min-height:var(--md-menu-item-two-line-container-height, 72px)}[slot=supporting-text]{color:var(--md-menu-item-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));font-family:var(--md-menu-item-supporting-text-font, var(--md-sys-typescale-body-medium-font, var(--md-ref-typeface-plain, Roboto)));font-size:var(--md-menu-item-supporting-text-size, var(--md-sys-typescale-body-medium-size, 0.875rem));line-height:var(--md-menu-item-supporting-text-line-height, var(--md-sys-typescale-body-medium-line-height, 1.25rem));font-weight:var(--md-menu-item-supporting-text-weight, var(--md-sys-typescale-body-medium-weight, var(--md-ref-typeface-weight-regular, 400)))}[slot=trailing-supporting-text]{color:var(--md-menu-item-trailing-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));font-family:var(--md-menu-item-trailing-supporting-text-font, var(--md-sys-typescale-label-small-font, var(--md-ref-typeface-plain, Roboto)));font-size:var(--md-menu-item-trailing-supporting-text-size, var(--md-sys-typescale-label-small-size, 0.6875rem));line-height:var(--md-menu-item-trailing-supporting-text-line-height, var(--md-sys-typescale-label-small-line-height, 1rem));font-weight:var(--md-menu-item-trailing-supporting-text-weight, var(--md-sys-typescale-label-small-weight, var(--md-ref-typeface-weight-medium, 500)))}:is([slot=start],[slot=end])::slotted(*){fill:currentColor}[slot=start]{color:var(--md-menu-item-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f))}[slot=end]{color:var(--md-menu-item-trailing-icon-color, var(--md-sys-color-on-surface-variant, #49454f))}.list-item{background-color:var(--md-menu-item-container-color, transparent)}.list-item.selected{background-color:var(--md-menu-item-selected-container-color, var(--md-sys-color-secondary-container, #e8def8))}.selected:not(.disabled) ::slotted(*){color:var(--md-menu-item-selected-label-text-color, var(--md-sys-color-on-secondary-container, #1d192b))}@media(forced-colors: active){:host([disabled]),:host([disabled]) slot{color:GrayText;opacity:1}.list-item{position:relative}.list-item.selected::before{content:"";position:absolute;inset:0;box-sizing:border-box;border-radius:inherit;pointer-events:none;border:3px double CanvasText}} +`;let Et=class extends G{};Et.styles=[eo],Et=o([b("md-menu-item")],Et);class pe extends _{get item(){return this.items[0]??null}get menu(){return this.menus[0]??null}constructor(){super(),this.anchorCorner=Fe.START_END,this.menuCorner=Fe.START_START,this.hoverOpenDelay=400,this.hoverCloseDelay=400,this.isSubMenu=!0,this.previousOpenTimeout=0,this.previousCloseTimeout=0,this.onMouseenter=()=>{clearTimeout(this.previousOpenTimeout),clearTimeout(this.previousCloseTimeout),!this.menu?.open&&(this.hoverOpenDelay?this.previousOpenTimeout=setTimeout(()=>{this.show()},this.hoverOpenDelay):this.show())},this.onMouseleave=()=>{clearTimeout(this.previousCloseTimeout),clearTimeout(this.previousOpenTimeout),this.hoverCloseDelay?this.previousCloseTimeout=setTimeout(()=>{this.close()},this.hoverCloseDelay):this.close()},T||(this.addEventListener("mouseenter",this.onMouseenter),this.addEventListener("mouseleave",this.onMouseleave))}render(){return d` + + + + + `}firstUpdated(){this.onSlotchange()}async show(){const e=this.menu;if(!e||e.open)return;e.addEventListener("closed",()=>{this.item.ariaExpanded="false",this.dispatchEvent(pr()),this.dispatchEvent(xt()),e.ariaHidden="true"},{once:!0}),e.positioning==="document"&&(e.positioning="absolute"),e.quick=!0,e.hasOverflow=!0,e.anchorCorner=this.anchorCorner,e.menuCorner=this.menuCorner,e.anchorElement=this.item,e.defaultFocus="first-item",e.removeAttribute("aria-hidden"),e.skipRestoreFocus=!1;const t=e.open;if(e.show(),this.item.ariaExpanded="true",this.item.ariaHasPopup="menu",e.id&&this.item.setAttribute("aria-controls",e.id),this.dispatchEvent(xt()),this.dispatchEvent(Oi()),this.item.selected=!0,!t){let r=n=>{};const a=new Promise(n=>{r=n});e.addEventListener("opened",r,{once:!0}),await a}}async close(){const e=this.menu;if(!e||!e.open)return;this.dispatchEvent(pr()),e.quick=!0,e.close(),this.dispatchEvent(xt());let t=a=>{};const r=new Promise(a=>{t=a});e.addEventListener("closed",t,{once:!0}),await r}onSlotchange(){if(!this.item)return;this.item.ariaExpanded="false",this.item.ariaHasPopup="menu",this.menu?.id&&this.item.setAttribute("aria-controls",this.menu.id),this.item.keepOpen=!0;const e=this.menu;e&&(e.isSubmenu=!0,e.ariaHidden="true")}onClick(){this.show()}async onKeydown(e){const t=this.isSubmenuOpenKey(e.code);if(e.defaultPrevented)return;const r=t&&(he.LEFT===e.code||he.RIGHT===e.code);if((e.code===Ee.SPACE||r)&&(e.preventDefault(),r&&e.stopPropagation()),!t)return;const a=this.menu;if(!a)return;const n=a.items,s=gt(n);if(s){await this.show(),s.tabIndex=0,s.focus();return}}onCloseSubmenu(e){const{itemPath:t,reason:r}=e.detail;if(t.push(this.item),this.dispatchEvent(pr()),r.kind===kt.KEYDOWN&&r.key===vr.ESCAPE){e.stopPropagation(),this.item.dispatchEvent(Wr());return}this.dispatchEvent(xt())}async onSubMenuKeydown(e){if(e.defaultPrevented)return;const{close:t,keyCode:r}=this.isSubmenuCloseKey(e.code);t&&(e.preventDefault(),(r===he.LEFT||r===he.RIGHT)&&e.stopPropagation(),await this.close(),ki(this.menu.items),this.item?.focus(),this.item.tabIndex=0,this.item.focus())}isSubmenuOpenKey(e){const r=getComputedStyle(this).direction==="rtl"?he.LEFT:he.RIGHT;switch(e){case r:case Ee.SPACE:case Ee.ENTER:return!0;default:return!1}}isSubmenuCloseKey(e){const r=getComputedStyle(this).direction==="rtl"?he.RIGHT:he.LEFT;switch(e){case r:case vr.ESCAPE:return{close:!0,keyCode:e};default:return{close:!1}}}}o([l({attribute:"anchor-corner"})],pe.prototype,"anchorCorner",void 0),o([l({attribute:"menu-corner"})],pe.prototype,"menuCorner",void 0),o([l({type:Number,attribute:"hover-open-delay"})],pe.prototype,"hoverOpenDelay",void 0),o([l({type:Number,attribute:"hover-close-delay"})],pe.prototype,"hoverCloseDelay",void 0),o([l({type:Boolean,reflect:!0,attribute:"md-sub-menu"})],pe.prototype,"isSubMenu",void 0),o([H({slot:"item",flatten:!0})],pe.prototype,"items",void 0),o([H({slot:"menu",flatten:!0})],pe.prototype,"menus",void 0);const Vi=v`:host{position:relative;display:flex;flex-direction:column} +`;let It=class extends pe{};It.styles=[Vi],It=o([b("md-sub-menu")],It);const qi=W(_);class Ie extends qi{constructor(){super(...arguments),this.value=0,this.max=1,this.indeterminate=!1,this.fourColor=!1}render(){const{ariaLabel:e}=this;return d` +
${this.renderIndicator()}
+ `}getRenderClasses(){return{indeterminate:this.indeterminate,"four-color":this.fourColor}}}o([l({type:Number})],Ie.prototype,"value",void 0),o([l({type:Number})],Ie.prototype,"max",void 0),o([l({type:Boolean})],Ie.prototype,"indeterminate",void 0),o([l({type:Boolean,attribute:"four-color"})],Ie.prototype,"fourColor",void 0);class Hi extends Ie{renderIndicator(){return this.indeterminate?this.renderIndeterminateContainer():this.renderDeterminateContainer()}renderDeterminateContainer(){const e=(1-this.value/this.max)*100;return d` + + + + + `}renderIndeterminateContainer(){return d`
+
+
+
+
+
+
+
`}}const Ui=v`:host{--_active-indicator-color: var(--md-circular-progress-active-indicator-color, var(--md-sys-color-primary, #6750a4));--_active-indicator-width: var(--md-circular-progress-active-indicator-width, 10);--_four-color-active-indicator-four-color: var(--md-circular-progress-four-color-active-indicator-four-color, var(--md-sys-color-tertiary-container, #ffd8e4));--_four-color-active-indicator-one-color: var(--md-circular-progress-four-color-active-indicator-one-color, var(--md-sys-color-primary, #6750a4));--_four-color-active-indicator-three-color: var(--md-circular-progress-four-color-active-indicator-three-color, var(--md-sys-color-tertiary, #7d5260));--_four-color-active-indicator-two-color: var(--md-circular-progress-four-color-active-indicator-two-color, var(--md-sys-color-primary-container, #eaddff));--_size: var(--md-circular-progress-size, 48px);display:inline-flex;vertical-align:middle;width:var(--_size);height:var(--_size);position:relative;align-items:center;justify-content:center;contain:strict;content-visibility:auto}.progress{flex:1;align-self:stretch;margin:4px}.progress,.spinner,.left,.right,.circle,svg,.track,.active-track{position:absolute;inset:0}svg{transform:rotate(-90deg)}circle{cx:50%;cy:50%;r:calc(50%*(1 - var(--_active-indicator-width)/100));stroke-width:calc(var(--_active-indicator-width)*1%);stroke-dasharray:100;fill:rgba(0,0,0,0)}.active-track{transition:stroke-dashoffset 500ms cubic-bezier(0, 0, 0.2, 1);stroke:var(--_active-indicator-color)}.track{stroke:rgba(0,0,0,0)}.progress.indeterminate{animation:linear infinite linear-rotate;animation-duration:1568.2352941176ms}.spinner{animation:infinite both rotate-arc;animation-duration:5332ms;animation-timing-function:cubic-bezier(0.4, 0, 0.2, 1)}.left{overflow:hidden;inset:0 50% 0 0}.right{overflow:hidden;inset:0 0 0 50%}.circle{box-sizing:border-box;border-radius:50%;border:solid calc(var(--_active-indicator-width)/100*(var(--_size) - 8px));border-color:var(--_active-indicator-color) var(--_active-indicator-color) rgba(0,0,0,0) rgba(0,0,0,0);animation:expand-arc;animation-iteration-count:infinite;animation-fill-mode:both;animation-duration:1333ms,5332ms;animation-timing-function:cubic-bezier(0.4, 0, 0.2, 1)}.four-color .circle{animation-name:expand-arc,four-color}.left .circle{rotate:135deg;inset:0 -100% 0 0}.right .circle{rotate:100deg;inset:0 0 0 -100%;animation-delay:-666.5ms,0ms}@media(forced-colors: active){.active-track{stroke:CanvasText}.circle{border-color:CanvasText CanvasText Canvas Canvas}}@keyframes expand-arc{0%{transform:rotate(265deg)}50%{transform:rotate(130deg)}100%{transform:rotate(265deg)}}@keyframes rotate-arc{12.5%{transform:rotate(135deg)}25%{transform:rotate(270deg)}37.5%{transform:rotate(405deg)}50%{transform:rotate(540deg)}62.5%{transform:rotate(675deg)}75%{transform:rotate(810deg)}87.5%{transform:rotate(945deg)}100%{transform:rotate(1080deg)}}@keyframes linear-rotate{to{transform:rotate(360deg)}}@keyframes four-color{0%{border-top-color:var(--_four-color-active-indicator-one-color);border-right-color:var(--_four-color-active-indicator-one-color)}15%{border-top-color:var(--_four-color-active-indicator-one-color);border-right-color:var(--_four-color-active-indicator-one-color)}25%{border-top-color:var(--_four-color-active-indicator-two-color);border-right-color:var(--_four-color-active-indicator-two-color)}40%{border-top-color:var(--_four-color-active-indicator-two-color);border-right-color:var(--_four-color-active-indicator-two-color)}50%{border-top-color:var(--_four-color-active-indicator-three-color);border-right-color:var(--_four-color-active-indicator-three-color)}65%{border-top-color:var(--_four-color-active-indicator-three-color);border-right-color:var(--_four-color-active-indicator-three-color)}75%{border-top-color:var(--_four-color-active-indicator-four-color);border-right-color:var(--_four-color-active-indicator-four-color)}90%{border-top-color:var(--_four-color-active-indicator-four-color);border-right-color:var(--_four-color-active-indicator-four-color)}100%{border-top-color:var(--_four-color-active-indicator-one-color);border-right-color:var(--_four-color-active-indicator-one-color)}} +`;let Tt=class extends Hi{};Tt.styles=[Ui],Tt=o([b("md-circular-progress")],Tt);class to extends Ie{constructor(){super(...arguments),this.buffer=0}renderIndicator(){const e={transform:`scaleX(${(this.indeterminate?1:this.value/this.max)*100}%)`},t=this.buffer??0,r=t>0,n={transform:`scaleX(${(this.indeterminate||!r?1:t/this.max)*100}%)`},s=this.indeterminate||!r||t>=this.max||this.value>=this.max;return d` +
+
+
+
+
+
+
+
+ `}}o([l({type:Number})],to.prototype,"buffer",void 0);const Ki=v`:host{--_active-indicator-color: var(--md-linear-progress-active-indicator-color, var(--md-sys-color-primary, #6750a4));--_active-indicator-height: var(--md-linear-progress-active-indicator-height, 4px);--_four-color-active-indicator-four-color: var(--md-linear-progress-four-color-active-indicator-four-color, var(--md-sys-color-tertiary-container, #ffd8e4));--_four-color-active-indicator-one-color: var(--md-linear-progress-four-color-active-indicator-one-color, var(--md-sys-color-primary, #6750a4));--_four-color-active-indicator-three-color: var(--md-linear-progress-four-color-active-indicator-three-color, var(--md-sys-color-tertiary, #7d5260));--_four-color-active-indicator-two-color: var(--md-linear-progress-four-color-active-indicator-two-color, var(--md-sys-color-primary-container, #eaddff));--_track-color: var(--md-linear-progress-track-color, var(--md-sys-color-surface-container-highest, #e6e0e9));--_track-height: var(--md-linear-progress-track-height, 4px);--_track-shape: var(--md-linear-progress-track-shape, var(--md-sys-shape-corner-none, 0px));border-radius:var(--_track-shape);display:flex;position:relative;min-width:80px;height:var(--_track-height);content-visibility:auto;contain:strict}.progress,.dots,.inactive-track,.bar,.bar-inner{position:absolute}.progress{direction:ltr;inset:0;border-radius:inherit;overflow:hidden;display:flex;align-items:center}.bar{animation:none;width:100%;height:var(--_active-indicator-height);transform-origin:left center;transition:transform 250ms cubic-bezier(0.4, 0, 0.6, 1)}.secondary-bar{display:none}.bar-inner{inset:0;animation:none;background:var(--_active-indicator-color)}.inactive-track{background:var(--_track-color);inset:0;transition:transform 250ms cubic-bezier(0.4, 0, 0.6, 1);transform-origin:left center}.dots{inset:0;animation:linear infinite 250ms;animation-name:buffering;background-color:var(--_track-color);background-repeat:repeat-x;-webkit-mask-image:url("data:image/svg+xml,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 5 2' preserveAspectRatio='xMinYMin slice'%3E%3Ccircle cx='1' cy='1' r='1'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 5 2' preserveAspectRatio='xMinYMin slice'%3E%3Ccircle cx='1' cy='1' r='1'/%3E%3C/svg%3E");z-index:-1}.dots[hidden]{display:none}.indeterminate .bar{transition:none}.indeterminate .primary-bar{inset-inline-start:-145.167%}.indeterminate .secondary-bar{inset-inline-start:-54.8889%;display:block}.indeterminate .primary-bar{animation:linear infinite 2s;animation-name:primary-indeterminate-translate}.indeterminate .primary-bar>.bar-inner{animation:linear infinite 2s primary-indeterminate-scale}.indeterminate.four-color .primary-bar>.bar-inner{animation-name:primary-indeterminate-scale,four-color;animation-duration:2s,4s}.indeterminate .secondary-bar{animation:linear infinite 2s;animation-name:secondary-indeterminate-translate}.indeterminate .secondary-bar>.bar-inner{animation:linear infinite 2s secondary-indeterminate-scale}.indeterminate.four-color .secondary-bar>.bar-inner{animation-name:secondary-indeterminate-scale,four-color;animation-duration:2s,4s}:host(:dir(rtl)){transform:scale(-1)}@keyframes primary-indeterminate-scale{0%{transform:scaleX(0.08)}36.65%{animation-timing-function:cubic-bezier(0.334731, 0.12482, 0.785844, 1);transform:scaleX(0.08)}69.15%{animation-timing-function:cubic-bezier(0.06, 0.11, 0.6, 1);transform:scaleX(0.661479)}100%{transform:scaleX(0.08)}}@keyframes secondary-indeterminate-scale{0%{animation-timing-function:cubic-bezier(0.205028, 0.057051, 0.57661, 0.453971);transform:scaleX(0.08)}19.15%{animation-timing-function:cubic-bezier(0.152313, 0.196432, 0.648374, 1.00432);transform:scaleX(0.457104)}44.15%{animation-timing-function:cubic-bezier(0.257759, -0.003163, 0.211762, 1.38179);transform:scaleX(0.72796)}100%{transform:scaleX(0.08)}}@keyframes buffering{0%{transform:translateX(calc(var(--_track-height) / 2 * 5))}}@keyframes primary-indeterminate-translate{0%{transform:translateX(0px)}20%{animation-timing-function:cubic-bezier(0.5, 0, 0.701732, 0.495819);transform:translateX(0px)}59.15%{animation-timing-function:cubic-bezier(0.302435, 0.381352, 0.55, 0.956352);transform:translateX(83.6714%)}100%{transform:translateX(200.611%)}}@keyframes secondary-indeterminate-translate{0%{animation-timing-function:cubic-bezier(0.15, 0, 0.515058, 0.409685);transform:translateX(0px)}25%{animation-timing-function:cubic-bezier(0.31033, 0.284058, 0.8, 0.733712);transform:translateX(37.6519%)}48.35%{animation-timing-function:cubic-bezier(0.4, 0.627035, 0.6, 0.902026);transform:translateX(84.3862%)}100%{transform:translateX(160.278%)}}@keyframes four-color{0%{background:var(--_four-color-active-indicator-one-color)}15%{background:var(--_four-color-active-indicator-one-color)}25%{background:var(--_four-color-active-indicator-two-color)}40%{background:var(--_four-color-active-indicator-two-color)}50%{background:var(--_four-color-active-indicator-three-color)}65%{background:var(--_four-color-active-indicator-three-color)}75%{background:var(--_four-color-active-indicator-four-color)}90%{background:var(--_four-color-active-indicator-four-color)}100%{background:var(--_four-color-active-indicator-one-color)}}@media(forced-colors: active){:host{outline:1px solid CanvasText}.bar-inner,.dots{background-color:CanvasText}} +`;let zt=class extends to{};zt.styles=[Ki],zt=o([b("md-linear-progress")],zt);const At=Symbol("isFocusable"),fr=Symbol("privateIsFocusable"),St=Symbol("externalTabIndex"),$t=Symbol("isUpdatingTabIndex"),Rt=Symbol("updateTabIndex");function ro(i){var e,t,r;class a extends i{constructor(){super(...arguments),this[e]=!0,this[t]=null,this[r]=!1}get[At](){return this[fr]}set[At](s){this[At]!==s&&(this[fr]=s,this[Rt]())}connectedCallback(){super.connectedCallback(),this[Rt]()}attributeChangedCallback(s,h,p){if(s!=="tabindex"){super.attributeChangedCallback(s,h,p);return}if(this.requestUpdate("tabIndex",Number(h??-1)),!this[$t]){if(!this.hasAttribute("tabindex")){this[St]=null,this[Rt]();return}this[St]=this.tabIndex}}[(e=fr,t=St,r=$t,Rt)](){const s=this[At]?0:-1,h=this[St]??s;this[$t]=!0,this.tabIndex=h,this[$t]=!1}}return o([l({noAccessor:!0})],a.prototype,"tabIndex",void 0),a}class Wi extends Ze{computeValidity(e){this.radioElement||(this.radioElement=document.createElement("input"),this.radioElement.type="radio",this.radioElement.name="group");let t=!1,r=!1;for(const{checked:a,required:n}of e)n&&(t=!0),a&&(r=!0);return this.radioElement.checked=r,this.radioElement.required=t,{validity:{valueMissing:t&&!r},validationMessage:this.radioElement.validationMessage}}equals(e,t){if(e.length!==t.length)return!1;for(let r=0;r({checked:t,required:r}))}}class Gi{get controls(){const e=this.host.getAttribute("name");return!e||!this.root||!this.host.isConnected?[this.host]:Array.from(this.root.querySelectorAll(`[name="${e}"]`))}constructor(e){this.host=e,this.focused=!1,this.root=null,this.handleFocusIn=()=>{this.focused=!0,this.updateTabIndices()},this.handleFocusOut=()=>{this.focused=!1,this.updateTabIndices()},this.handleKeyDown=t=>{const r=t.key==="ArrowDown",a=t.key==="ArrowUp",n=t.key==="ArrowLeft",s=t.key==="ArrowRight";if(!n&&!s&&!r&&!a)return;const h=this.controls;if(!h.length)return;t.preventDefault();const y=getComputedStyle(this.host).direction==="rtl"?n||r:s||r,u=h.indexOf(this.host);let f=y?u+1:u-1;for(;f!==u;){f>=h.length?f=0:f<0&&(f=h.length-1);const m=h[f];if(m.hasAttribute("disabled")){y?f++:f--;continue}for(const w of h)w!==m&&(w.checked=!1,w.tabIndex=-1,w.blur());m.checked=!0,m.tabIndex=0,m.focus(),m.dispatchEvent(new Event("change",{bubbles:!0}));break}}}hostConnected(){this.root=this.host.getRootNode(),this.host.addEventListener("keydown",this.handleKeyDown),this.host.addEventListener("focusin",this.handleFocusIn),this.host.addEventListener("focusout",this.handleFocusOut),this.host.checked&&this.uncheckSiblings(),queueMicrotask(()=>{this.updateTabIndices()})}hostDisconnected(){this.host.removeEventListener("keydown",this.handleKeyDown),this.host.removeEventListener("focusin",this.handleFocusIn),this.host.removeEventListener("focusout",this.handleFocusOut),queueMicrotask(()=>{this.updateTabIndices(),this.root=null})}handleCheckedChange(){this.host.checked&&(this.uncheckSiblings(),this.updateTabIndices())}uncheckSiblings(){for(const e of this.controls)e!==this.host&&(e.checked=!1)}updateTabIndices(){const e=this.controls,t=e.find(r=>r.checked);if(t||this.focused){const r=t||this.host;r.tabIndex=0;for(const a of e)a!==r&&(a.tabIndex=-1);return}for(const r of e)r.tabIndex=0}}var oo;const mr=Symbol("checked");let Xi=0;const Yi=Re(we(se(ro(_))));class De extends Yi{get checked(){return this[mr]}set checked(e){const t=this.checked;t!==e&&(this[mr]=e,this.requestUpdate("checked",t),this.selectionController.handleCheckedChange())}constructor(){super(),this.maskId=`cutout${++Xi}`,this[oo]=!1,this.required=!1,this.value="on",this.selectionController=new Gi(this),this.addController(this.selectionController),T||(this[N].role="radio",this.addEventListener("click",this.handleClick.bind(this)),this.addEventListener("keydown",this.handleKeydown.bind(this)))}render(){const e={checked:this.checked};return d` + + `}updated(){this[N].ariaChecked=String(this.checked)}async handleClick(e){this.disabled||(await 0,!e.defaultPrevented&&(Se(e)&&this.focus(),this.checked=!0,this.dispatchEvent(new Event("change",{bubbles:!0})),this.dispatchEvent(new InputEvent("input",{bubbles:!0,composed:!0}))))}async handleKeydown(e){await 0,!(e.key!==" "||e.defaultPrevented)&&this.click()}[(oo=mr,ie)](){return this.checked?this.value:null}[Oe](){return String(this.checked)}formResetCallback(){this.checked=this.hasAttribute("checked")}formStateRestoreCallback(e){this.checked=e==="true"}[me](){return new Wi(()=>this.selectionController?this.selectionController.controls:[this])}[be](){return this.container}}o([l({type:Boolean})],De.prototype,"checked",null),o([l({type:Boolean})],De.prototype,"required",void 0),o([l()],De.prototype,"value",void 0),o([g(".container")],De.prototype,"container",void 0);const ji=v`@layer{:host{display:inline-flex;height:var(--md-radio-icon-size, 20px);outline:none;position:relative;vertical-align:top;width:var(--md-radio-icon-size, 20px);-webkit-tap-highlight-color:rgba(0,0,0,0);cursor:pointer;--md-ripple-hover-color: var(--md-radio-hover-state-layer-color, var(--md-sys-color-on-surface, #1d1b20));--md-ripple-hover-opacity: var(--md-radio-hover-state-layer-opacity, 0.08);--md-ripple-pressed-color: var(--md-radio-pressed-state-layer-color, var(--md-sys-color-primary, #6750a4));--md-ripple-pressed-opacity: var(--md-radio-pressed-state-layer-opacity, 0.12)}:host([disabled]){cursor:default}:host([touch-target=wrapper]){margin:max(0px,(48px - var(--md-radio-icon-size, 20px))/2)}.container{display:flex;height:100%;place-content:center;place-items:center;width:100%}md-focus-ring{height:44px;inset:unset;width:44px}.checked{--md-ripple-hover-color: var(--md-radio-selected-hover-state-layer-color, var(--md-sys-color-primary, #6750a4));--md-ripple-hover-opacity: var(--md-radio-selected-hover-state-layer-opacity, 0.08);--md-ripple-pressed-color: var(--md-radio-selected-pressed-state-layer-color, var(--md-sys-color-on-surface, #1d1b20));--md-ripple-pressed-opacity: var(--md-radio-selected-pressed-state-layer-opacity, 0.12)}.touch-target{height:48px;position:absolute;width:48px}:host([touch-target=none]) .touch-target{display:none}md-ripple{border-radius:50%;height:var(--md-radio-state-layer-size, 40px);inset:unset;width:var(--md-radio-state-layer-size, 40px)}.icon{fill:var(--md-radio-icon-color, var(--md-sys-color-on-surface-variant, #49454f));inset:0;position:absolute}.outer.circle{transition:fill 50ms linear}.inner.circle{opacity:0;transform-origin:center;transition:opacity 50ms linear}.checked .icon{fill:var(--md-radio-selected-icon-color, var(--md-sys-color-primary, #6750a4))}.checked .inner.circle{animation:inner-circle-grow 300ms cubic-bezier(0.05, 0.7, 0.1, 1);opacity:1}@keyframes inner-circle-grow{from{transform:scale(0)}to{transform:scale(1)}}:host([disabled]) .circle{animation-duration:0s;transition-duration:0s}:host(:hover) .icon{fill:var(--md-radio-hover-icon-color, var(--md-sys-color-on-surface, #1d1b20))}:host(:focus-within) .icon{fill:var(--md-radio-focus-icon-color, var(--md-sys-color-on-surface, #1d1b20))}:host(:active) .icon{fill:var(--md-radio-pressed-icon-color, var(--md-sys-color-on-surface, #1d1b20))}:host([disabled]) .icon{fill:var(--md-radio-disabled-unselected-icon-color, var(--md-sys-color-on-surface, #1d1b20));opacity:var(--md-radio-disabled-unselected-icon-opacity, 0.38)}:host(:hover) .checked .icon{fill:var(--md-radio-selected-hover-icon-color, var(--md-sys-color-primary, #6750a4))}:host(:focus-within) .checked .icon{fill:var(--md-radio-selected-focus-icon-color, var(--md-sys-color-primary, #6750a4))}:host(:active) .checked .icon{fill:var(--md-radio-selected-pressed-icon-color, var(--md-sys-color-primary, #6750a4))}:host([disabled]) .checked .icon{fill:var(--md-radio-disabled-selected-icon-color, var(--md-sys-color-on-surface, #1d1b20));opacity:var(--md-radio-disabled-selected-icon-opacity, 0.38)}}@layer hcm{@media(forced-colors: active){.icon{fill:CanvasText}:host([disabled]) .icon{fill:GrayText;opacity:1}}} +`;let Ot=class extends De{};Ot.styles=[ji],Ot=o([b("md-radio")],Ot);const Lt=Symbol("onReportValidity"),Ft=Symbol("privateCleanupFormListeners"),Dt=Symbol("privateDoNotReportInvalid"),Pt=Symbol("privateIsSelfReportingValidity"),Mt=Symbol("privateCallOnReportValidity");function io(i){var e,t,r;class a extends i{constructor(...s){super(...s),this[e]=new AbortController,this[t]=!1,this[r]=!1,!T&&this.addEventListener("invalid",h=>{this[Dt]||!h.isTrusted||this.addEventListener("invalid",()=>{this[Mt](h)},{once:!0})},{capture:!0})}checkValidity(){this[Dt]=!0;const s=super.checkValidity();return this[Dt]=!1,s}reportValidity(){this[Pt]=!0;const s=super.reportValidity();return s&&this[Mt](null),this[Pt]=!1,s}[(e=Ft,t=Dt,r=Pt,Mt)](s){const h=s?.defaultPrevented;h||(this[Lt](s),!(!h&&s?.defaultPrevented))||(this[Pt]||Ji(this[N].form,this))&&this.focus()}[Lt](s){throw new Error("Implement [onReportValidity]")}formAssociatedCallback(s){super.formAssociatedCallback&&super.formAssociatedCallback(s),this[Ft].abort(),s&&(this[Ft]=new AbortController,Zi(this,s,()=>{this[Mt](null)},this[Ft].signal))}}return a}function Zi(i,e,t,r){const a=Qi(e);let n=!1,s,h=!1;a.addEventListener("before",()=>{h=!0,s=new AbortController,n=!1,i.addEventListener("invalid",()=>{n=!0},{signal:s.signal})},{signal:r}),a.addEventListener("after",()=>{h=!1,s?.abort(),!n&&t()},{signal:r}),e.addEventListener("submit",()=>{h||t()},{signal:r})}const br=new WeakMap;function Qi(i){if(!br.has(i)){const e=new EventTarget;br.set(i,e);for(const t of["reportValidity","requestSubmit"]){const r=i[t];i[t]=function(){e.dispatchEvent(new Event("before"));const a=Reflect.apply(r,this,arguments);return e.dispatchEvent(new Event("after")),a}}}return br.get(i)}function Ji(i,e){if(!i)return!0;let t;for(const r of i.elements)if(r.matches(":invalid")){t=r;break}return t===e}class ea extends Ze{computeValidity(e){return this.selectControl||(this.selectControl=document.createElement("select")),_r(d``,this.selectControl),this.selectControl.value=e.value,this.selectControl.required=e.required,{validity:this.selectControl.validity,validationMessage:this.selectControl.validationMessage}}equals(e,t){return e.value===t.value&&e.required===t.required}copy({value:e,required:t}){return{value:e,required:t}}}function ta(i){const e=[];for(let t=0;te)}get hasError(){return this.error||this.nativeError}constructor(){super(),this.quick=!1,this.required=!1,this.errorText="",this.label="",this.noAsterisk=!1,this.supportingText="",this.error=!1,this.menuPositioning="popover",this.clampMenuWidth=!1,this.typeaheadDelay=Zr,this.hasLeadingIcon=!1,this.displayText="",this.menuAlign="start",this[ao]="",this.lastUserSetValue=null,this.lastUserSetSelectedIndex=null,this.lastSelectedOption=null,this.lastSelectedOptionRecords=[],this.nativeError=!1,this.nativeErrorText="",this.focused=!1,this.open=!1,this.defaultFocus=X.NONE,this.prevOpen=this.open,this.selectWidth=0,!T&&(this.addEventListener("focus",this.handleFocus.bind(this)),this.addEventListener("blur",this.handleBlur.bind(this)))}select(e){const t=this.options.find(r=>r.value===e);t&&this.selectItem(t)}selectIndex(e){const t=this.options[e];t&&this.selectItem(t)}reset(){for(const e of this.options)e.selected=e.hasAttribute("selected");this.updateValueAndDisplayText(),this.nativeError=!1,this.nativeErrorText=""}showPicker(){this.open=!0}[(ao=Bt,Lt)](e){e?.preventDefault();const t=this.getErrorText();this.nativeError=!!e,this.nativeErrorText=this.validationMessage,t===this.getErrorText()&&this.field?.reannounceError()}update(e){if(this.hasUpdated||this.initUserSelection(),this.prevOpen!==this.open&&this.open){const t=this.getBoundingClientRect();this.selectWidth=t.width}this.prevOpen=this.open,super.update(e)}render(){return d` + + ${this.renderField()} ${this.renderMenu()} + + `}async firstUpdated(e){await this.menu?.updateComplete,this.lastSelectedOptionRecords.length||this.initUserSelection(),!this.lastSelectedOptionRecords.length&&!T&&!this.options.length&&setTimeout(()=>{this.updateValueAndDisplayText()}),super.firstUpdated(e)}getRenderClasses(){return{disabled:this.disabled,error:this.error,open:this.open}}renderField(){const e=this.ariaLabel||this.label;return ze` + <${this.fieldTag} + aria-haspopup="listbox" + role="combobox" + part="field" + id="field" + tabindex=${this.disabled?"-1":"0"} + aria-label=${e||c} + aria-describedby="description" + aria-expanded=${this.open?"true":"false"} + aria-controls="listbox" + class="field" + label=${this.label} + ?no-asterisk=${this.noAsterisk} + .focused=${this.focused||this.open} + .populated=${!!this.displayText} + .disabled=${this.disabled} + .required=${this.required} + .error=${this.hasError} + ?has-start=${this.hasLeadingIcon} + has-end + supporting-text=${this.supportingText} + error-text=${this.getErrorText()} + @keydown=${this.handleKeydown} + @click=${this.handleClick}> + ${this.renderFieldContent()} +
+ `}renderFieldContent(){return[this.renderLeadingIcon(),this.renderLabel(),this.renderTrailingIcon()]}renderLeadingIcon(){return d` + + + + `}renderTrailingIcon(){return d` + + + + + + + + + `}renderLabel(){return d`
${this.displayText||d` `}
`}renderMenu(){const e=this.label||this.ariaLabel;return d``}renderMenuContent(){return d``}handleKeydown(e){if(this.open||this.disabled||!this.menu)return;const t=this.menu.typeaheadController,r=e.code==="Space"||e.code==="ArrowDown"||e.code==="ArrowUp"||e.code==="End"||e.code==="Home"||e.code==="Enter";if(!t.isTypingAhead&&r){switch(e.preventDefault(),this.open=!0,e.code){case"Space":case"ArrowDown":case"Enter":this.defaultFocus=X.NONE;break;case"End":this.defaultFocus=X.LAST_ITEM;break;case"ArrowUp":case"Home":this.defaultFocus=X.FIRST_ITEM;break}return}if(e.key.length===1){t.onKeydown(e),e.preventDefault();const{lastActiveRecord:n}=t;if(!n)return;this.labelEl?.setAttribute?.("aria-live","polite"),this.selectItem(n[Y.ITEM])&&this.dispatchInteractionEvents()}}handleClick(){this.open=!this.open}handleFocus(){this.focused=!0}handleBlur(){this.focused=!1}handleFocusout(e){e.relatedTarget&&ur(e.relatedTarget,this)||(this.open=!1)}getSelectedOptions(){if(!this.menu)return this.lastSelectedOptionRecords=[],null;const e=this.menu.items;return this.lastSelectedOptionRecords=ta(e),this.lastSelectedOptionRecords}async getUpdateComplete(){return await this.menu?.updateComplete,super.getUpdateComplete()}updateValueAndDisplayText(){const e=this.getSelectedOptions()??[];let t=!1;if(e.length){const[r]=e[0];t=this.lastSelectedOption!==r,this.lastSelectedOption=r,this[Bt]=r.value,this.displayText=r.displayText}else t=this.lastSelectedOption!==null,this.lastSelectedOption=null,this[Bt]="",this.displayText="";return t}async handleOpening(e){if(this.labelEl?.removeAttribute?.("aria-live"),this.redispatchEvent(e),this.defaultFocus!==X.NONE)return;const t=this.menu.items,r=Ce(t)?.item;let[a]=this.lastSelectedOptionRecords[0]??[null];r&&r!==a&&(r.tabIndex=-1),a=a??t[0],a&&(a.tabIndex=0,a.focus())}redispatchEvent(e){de(this,e)}handleClosed(e){this.open=!1,this.redispatchEvent(e)}handleCloseMenu(e){const t=e.detail.reason,r=e.detail.itemPath[0];this.open=!1;let a=!1;t.kind==="click-selection"?a=this.selectItem(r):t.kind==="keydown"&&Li(t.key)?a=this.selectItem(r):(r.tabIndex=-1,r.blur()),a&&this.dispatchInteractionEvents()}selectItem(e){return(this.getSelectedOptions()??[]).forEach(([r])=>{e!==r&&(r.selected=!1)}),e.selected=!0,this.updateValueAndDisplayText()}handleRequestSelection(e){const t=e.target;this.lastSelectedOptionRecords.some(([r])=>r===t)||this.selectItem(t)}handleRequestDeselection(e){const t=e.target;this.lastSelectedOptionRecords.some(([r])=>r===t)&&this.updateValueAndDisplayText()}initUserSelection(){this.lastUserSetValue&&!this.lastSelectedOptionRecords.length?this.select(this.lastUserSetValue):this.lastUserSetSelectedIndex!==null&&!this.lastSelectedOptionRecords.length?this.selectIndex(this.lastUserSetSelectedIndex):this.updateValueAndDisplayText()}handleIconChange(){this.hasLeadingIcon=this.leadingIcons.length>0}dispatchInteractionEvents(){this.dispatchEvent(new Event("input",{bubbles:!0,composed:!0})),this.dispatchEvent(new Event("change",{bubbles:!0}))}getErrorText(){return this.error?this.errorText:this.nativeErrorText}[ie](){return this.value}formResetCallback(){this.reset()}formStateRestoreCallback(e){this.value=e}click(){this.field?.click()}[me](){return new ea(()=>this)}[be](){return this.field}}z.shadowRootOptions={..._.shadowRootOptions,delegatesFocus:!0},o([l({type:Boolean})],z.prototype,"quick",void 0),o([l({type:Boolean})],z.prototype,"required",void 0),o([l({type:String,attribute:"error-text"})],z.prototype,"errorText",void 0),o([l()],z.prototype,"label",void 0),o([l({type:Boolean,attribute:"no-asterisk"})],z.prototype,"noAsterisk",void 0),o([l({type:String,attribute:"supporting-text"})],z.prototype,"supportingText",void 0),o([l({type:Boolean,reflect:!0})],z.prototype,"error",void 0),o([l({attribute:"menu-positioning"})],z.prototype,"menuPositioning",void 0),o([l({type:Boolean,attribute:"clamp-menu-width"})],z.prototype,"clampMenuWidth",void 0),o([l({type:Number,attribute:"typeahead-delay"})],z.prototype,"typeaheadDelay",void 0),o([l({type:Boolean,attribute:"has-leading-icon"})],z.prototype,"hasLeadingIcon",void 0),o([l({attribute:"display-text"})],z.prototype,"displayText",void 0),o([l({attribute:"menu-align"})],z.prototype,"menuAlign",void 0),o([l()],z.prototype,"value",null),o([l({type:Number,attribute:"selected-index"})],z.prototype,"selectedIndex",null),o([k()],z.prototype,"nativeError",void 0),o([k()],z.prototype,"nativeErrorText",void 0),o([k()],z.prototype,"focused",void 0),o([k()],z.prototype,"open",void 0),o([k()],z.prototype,"defaultFocus",void 0),o([g(".field")],z.prototype,"field",void 0),o([g("md-menu")],z.prototype,"menu",void 0),o([g("#label")],z.prototype,"labelEl",void 0),o([H({slot:"leading-icon",flatten:!0})],z.prototype,"leadingIcons",void 0);class oa extends z{constructor(){super(...arguments),this.fieldTag=K`md-filled-field`}}const ia=v`:host{--_text-field-active-indicator-color: var(--md-filled-select-text-field-active-indicator-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-active-indicator-height: var(--md-filled-select-text-field-active-indicator-height, 1px);--_text-field-container-color: var(--md-filled-select-text-field-container-color, var(--md-sys-color-surface-container-highest, #e6e0e9));--_text-field-disabled-active-indicator-color: var(--md-filled-select-text-field-disabled-active-indicator-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-disabled-active-indicator-height: var(--md-filled-select-text-field-disabled-active-indicator-height, 1px);--_text-field-disabled-active-indicator-opacity: var(--md-filled-select-text-field-disabled-active-indicator-opacity, 0.38);--_text-field-disabled-container-color: var(--md-filled-select-text-field-disabled-container-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-disabled-container-opacity: var(--md-filled-select-text-field-disabled-container-opacity, 0.04);--_text-field-disabled-input-text-color: var(--md-filled-select-text-field-disabled-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-disabled-input-text-opacity: var(--md-filled-select-text-field-disabled-input-text-opacity, 0.38);--_text-field-disabled-label-text-color: var(--md-filled-select-text-field-disabled-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-disabled-label-text-opacity: var(--md-filled-select-text-field-disabled-label-text-opacity, 0.38);--_text-field-disabled-leading-icon-color: var(--md-filled-select-text-field-disabled-leading-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-disabled-leading-icon-opacity: var(--md-filled-select-text-field-disabled-leading-icon-opacity, 0.38);--_text-field-disabled-supporting-text-color: var(--md-filled-select-text-field-disabled-supporting-text-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-disabled-supporting-text-opacity: var(--md-filled-select-text-field-disabled-supporting-text-opacity, 0.38);--_text-field-disabled-trailing-icon-color: var(--md-filled-select-text-field-disabled-trailing-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-disabled-trailing-icon-opacity: var(--md-filled-select-text-field-disabled-trailing-icon-opacity, 0.38);--_text-field-error-active-indicator-color: var(--md-filled-select-text-field-error-active-indicator-color, var(--md-sys-color-error, #b3261e));--_text-field-error-focus-active-indicator-color: var(--md-filled-select-text-field-error-focus-active-indicator-color, var(--md-sys-color-error, #b3261e));--_text-field-error-focus-input-text-color: var(--md-filled-select-text-field-error-focus-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-error-focus-label-text-color: var(--md-filled-select-text-field-error-focus-label-text-color, var(--md-sys-color-error, #b3261e));--_text-field-error-focus-leading-icon-color: var(--md-filled-select-text-field-error-focus-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-error-focus-supporting-text-color: var(--md-filled-select-text-field-error-focus-supporting-text-color, var(--md-sys-color-error, #b3261e));--_text-field-error-focus-trailing-icon-color: var(--md-filled-select-text-field-error-focus-trailing-icon-color, var(--md-sys-color-error, #b3261e));--_text-field-error-hover-active-indicator-color: var(--md-filled-select-text-field-error-hover-active-indicator-color, var(--md-sys-color-on-error-container, #410e0b));--_text-field-error-hover-input-text-color: var(--md-filled-select-text-field-error-hover-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-error-hover-label-text-color: var(--md-filled-select-text-field-error-hover-label-text-color, var(--md-sys-color-on-error-container, #410e0b));--_text-field-error-hover-leading-icon-color: var(--md-filled-select-text-field-error-hover-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-error-hover-state-layer-color: var(--md-filled-select-text-field-error-hover-state-layer-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-error-hover-state-layer-opacity: var(--md-filled-select-text-field-error-hover-state-layer-opacity, 0.08);--_text-field-error-hover-supporting-text-color: var(--md-filled-select-text-field-error-hover-supporting-text-color, var(--md-sys-color-error, #b3261e));--_text-field-error-hover-trailing-icon-color: var(--md-filled-select-text-field-error-hover-trailing-icon-color, var(--md-sys-color-on-error-container, #410e0b));--_text-field-error-input-text-color: var(--md-filled-select-text-field-error-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-error-label-text-color: var(--md-filled-select-text-field-error-label-text-color, var(--md-sys-color-error, #b3261e));--_text-field-error-leading-icon-color: var(--md-filled-select-text-field-error-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-error-supporting-text-color: var(--md-filled-select-text-field-error-supporting-text-color, var(--md-sys-color-error, #b3261e));--_text-field-error-trailing-icon-color: var(--md-filled-select-text-field-error-trailing-icon-color, var(--md-sys-color-error, #b3261e));--_text-field-focus-active-indicator-color: var(--md-filled-select-text-field-focus-active-indicator-color, var(--md-sys-color-primary, #6750a4));--_text-field-focus-active-indicator-height: var(--md-filled-select-text-field-focus-active-indicator-height, 3px);--_text-field-focus-input-text-color: var(--md-filled-select-text-field-focus-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-focus-label-text-color: var(--md-filled-select-text-field-focus-label-text-color, var(--md-sys-color-primary, #6750a4));--_text-field-focus-leading-icon-color: var(--md-filled-select-text-field-focus-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-focus-supporting-text-color: var(--md-filled-select-text-field-focus-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-focus-trailing-icon-color: var(--md-filled-select-text-field-focus-trailing-icon-color, var(--md-sys-color-primary, #6750a4));--_text-field-hover-active-indicator-color: var(--md-filled-select-text-field-hover-active-indicator-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-hover-active-indicator-height: var(--md-filled-select-text-field-hover-active-indicator-height, 1px);--_text-field-hover-input-text-color: var(--md-filled-select-text-field-hover-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-hover-label-text-color: var(--md-filled-select-text-field-hover-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-hover-leading-icon-color: var(--md-filled-select-text-field-hover-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-hover-state-layer-color: var(--md-filled-select-text-field-hover-state-layer-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-hover-state-layer-opacity: var(--md-filled-select-text-field-hover-state-layer-opacity, 0.08);--_text-field-hover-supporting-text-color: var(--md-filled-select-text-field-hover-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-hover-trailing-icon-color: var(--md-filled-select-text-field-hover-trailing-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-input-text-color: var(--md-filled-select-text-field-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-input-text-font: var(--md-filled-select-text-field-input-text-font, var(--md-sys-typescale-body-large-font, var(--md-ref-typeface-plain, Roboto)));--_text-field-input-text-line-height: var(--md-filled-select-text-field-input-text-line-height, var(--md-sys-typescale-body-large-line-height, 1.5rem));--_text-field-input-text-size: var(--md-filled-select-text-field-input-text-size, var(--md-sys-typescale-body-large-size, 1rem));--_text-field-input-text-weight: var(--md-filled-select-text-field-input-text-weight, var(--md-sys-typescale-body-large-weight, var(--md-ref-typeface-weight-regular, 400)));--_text-field-label-text-color: var(--md-filled-select-text-field-label-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-label-text-font: var(--md-filled-select-text-field-label-text-font, var(--md-sys-typescale-body-large-font, var(--md-ref-typeface-plain, Roboto)));--_text-field-label-text-line-height: var(--md-filled-select-text-field-label-text-line-height, var(--md-sys-typescale-body-large-line-height, 1.5rem));--_text-field-label-text-populated-line-height: var(--md-filled-select-text-field-label-text-populated-line-height, var(--md-sys-typescale-body-small-line-height, 1rem));--_text-field-label-text-populated-size: var(--md-filled-select-text-field-label-text-populated-size, var(--md-sys-typescale-body-small-size, 0.75rem));--_text-field-label-text-size: var(--md-filled-select-text-field-label-text-size, var(--md-sys-typescale-body-large-size, 1rem));--_text-field-label-text-weight: var(--md-filled-select-text-field-label-text-weight, var(--md-sys-typescale-body-large-weight, var(--md-ref-typeface-weight-regular, 400)));--_text-field-leading-icon-color: var(--md-filled-select-text-field-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-leading-icon-size: var(--md-filled-select-text-field-leading-icon-size, 24px);--_text-field-supporting-text-color: var(--md-filled-select-text-field-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-supporting-text-font: var(--md-filled-select-text-field-supporting-text-font, var(--md-sys-typescale-body-small-font, var(--md-ref-typeface-plain, Roboto)));--_text-field-supporting-text-line-height: var(--md-filled-select-text-field-supporting-text-line-height, var(--md-sys-typescale-body-small-line-height, 1rem));--_text-field-supporting-text-size: var(--md-filled-select-text-field-supporting-text-size, var(--md-sys-typescale-body-small-size, 0.75rem));--_text-field-supporting-text-weight: var(--md-filled-select-text-field-supporting-text-weight, var(--md-sys-typescale-body-small-weight, var(--md-ref-typeface-weight-regular, 400)));--_text-field-trailing-icon-color: var(--md-filled-select-text-field-trailing-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-trailing-icon-size: var(--md-filled-select-text-field-trailing-icon-size, 24px);--_text-field-container-shape-start-start: var(--md-filled-select-text-field-container-shape-start-start, var(--md-filled-select-text-field-container-shape, var(--md-sys-shape-corner-extra-small, 4px)));--_text-field-container-shape-start-end: var(--md-filled-select-text-field-container-shape-start-end, var(--md-filled-select-text-field-container-shape, var(--md-sys-shape-corner-extra-small, 4px)));--_text-field-container-shape-end-end: var(--md-filled-select-text-field-container-shape-end-end, var(--md-filled-select-text-field-container-shape, var(--md-sys-shape-corner-none, 0px)));--_text-field-container-shape-end-start: var(--md-filled-select-text-field-container-shape-end-start, var(--md-filled-select-text-field-container-shape, var(--md-sys-shape-corner-none, 0px)));--md-filled-field-active-indicator-color: var(--_text-field-active-indicator-color);--md-filled-field-active-indicator-height: var(--_text-field-active-indicator-height);--md-filled-field-container-color: var(--_text-field-container-color);--md-filled-field-container-shape-end-end: var(--_text-field-container-shape-end-end);--md-filled-field-container-shape-end-start: var(--_text-field-container-shape-end-start);--md-filled-field-container-shape-start-end: var(--_text-field-container-shape-start-end);--md-filled-field-container-shape-start-start: var(--_text-field-container-shape-start-start);--md-filled-field-content-color: var(--_text-field-input-text-color);--md-filled-field-content-font: var(--_text-field-input-text-font);--md-filled-field-content-line-height: var(--_text-field-input-text-line-height);--md-filled-field-content-size: var(--_text-field-input-text-size);--md-filled-field-content-weight: var(--_text-field-input-text-weight);--md-filled-field-disabled-active-indicator-color: var(--_text-field-disabled-active-indicator-color);--md-filled-field-disabled-active-indicator-height: var(--_text-field-disabled-active-indicator-height);--md-filled-field-disabled-active-indicator-opacity: var(--_text-field-disabled-active-indicator-opacity);--md-filled-field-disabled-container-color: var(--_text-field-disabled-container-color);--md-filled-field-disabled-container-opacity: var(--_text-field-disabled-container-opacity);--md-filled-field-disabled-content-color: var(--_text-field-disabled-input-text-color);--md-filled-field-disabled-content-opacity: var(--_text-field-disabled-input-text-opacity);--md-filled-field-disabled-label-text-color: var(--_text-field-disabled-label-text-color);--md-filled-field-disabled-label-text-opacity: var(--_text-field-disabled-label-text-opacity);--md-filled-field-disabled-leading-content-color: var(--_text-field-disabled-leading-icon-color);--md-filled-field-disabled-leading-content-opacity: var(--_text-field-disabled-leading-icon-opacity);--md-filled-field-disabled-supporting-text-color: var(--_text-field-disabled-supporting-text-color);--md-filled-field-disabled-supporting-text-opacity: var(--_text-field-disabled-supporting-text-opacity);--md-filled-field-disabled-trailing-content-color: var(--_text-field-disabled-trailing-icon-color);--md-filled-field-disabled-trailing-content-opacity: var(--_text-field-disabled-trailing-icon-opacity);--md-filled-field-error-active-indicator-color: var(--_text-field-error-active-indicator-color);--md-filled-field-error-content-color: var(--_text-field-error-input-text-color);--md-filled-field-error-focus-active-indicator-color: var(--_text-field-error-focus-active-indicator-color);--md-filled-field-error-focus-content-color: var(--_text-field-error-focus-input-text-color);--md-filled-field-error-focus-label-text-color: var(--_text-field-error-focus-label-text-color);--md-filled-field-error-focus-leading-content-color: var(--_text-field-error-focus-leading-icon-color);--md-filled-field-error-focus-supporting-text-color: var(--_text-field-error-focus-supporting-text-color);--md-filled-field-error-focus-trailing-content-color: var(--_text-field-error-focus-trailing-icon-color);--md-filled-field-error-hover-active-indicator-color: var(--_text-field-error-hover-active-indicator-color);--md-filled-field-error-hover-content-color: var(--_text-field-error-hover-input-text-color);--md-filled-field-error-hover-label-text-color: var(--_text-field-error-hover-label-text-color);--md-filled-field-error-hover-leading-content-color: var(--_text-field-error-hover-leading-icon-color);--md-filled-field-error-hover-state-layer-color: var(--_text-field-error-hover-state-layer-color);--md-filled-field-error-hover-state-layer-opacity: var(--_text-field-error-hover-state-layer-opacity);--md-filled-field-error-hover-supporting-text-color: var(--_text-field-error-hover-supporting-text-color);--md-filled-field-error-hover-trailing-content-color: var(--_text-field-error-hover-trailing-icon-color);--md-filled-field-error-label-text-color: var(--_text-field-error-label-text-color);--md-filled-field-error-leading-content-color: var(--_text-field-error-leading-icon-color);--md-filled-field-error-supporting-text-color: var(--_text-field-error-supporting-text-color);--md-filled-field-error-trailing-content-color: var(--_text-field-error-trailing-icon-color);--md-filled-field-focus-active-indicator-color: var(--_text-field-focus-active-indicator-color);--md-filled-field-focus-active-indicator-height: var(--_text-field-focus-active-indicator-height);--md-filled-field-focus-content-color: var(--_text-field-focus-input-text-color);--md-filled-field-focus-label-text-color: var(--_text-field-focus-label-text-color);--md-filled-field-focus-leading-content-color: var(--_text-field-focus-leading-icon-color);--md-filled-field-focus-supporting-text-color: var(--_text-field-focus-supporting-text-color);--md-filled-field-focus-trailing-content-color: var(--_text-field-focus-trailing-icon-color);--md-filled-field-hover-active-indicator-color: var(--_text-field-hover-active-indicator-color);--md-filled-field-hover-active-indicator-height: var(--_text-field-hover-active-indicator-height);--md-filled-field-hover-content-color: var(--_text-field-hover-input-text-color);--md-filled-field-hover-label-text-color: var(--_text-field-hover-label-text-color);--md-filled-field-hover-leading-content-color: var(--_text-field-hover-leading-icon-color);--md-filled-field-hover-state-layer-color: var(--_text-field-hover-state-layer-color);--md-filled-field-hover-state-layer-opacity: var(--_text-field-hover-state-layer-opacity);--md-filled-field-hover-supporting-text-color: var(--_text-field-hover-supporting-text-color);--md-filled-field-hover-trailing-content-color: var(--_text-field-hover-trailing-icon-color);--md-filled-field-label-text-color: var(--_text-field-label-text-color);--md-filled-field-label-text-font: var(--_text-field-label-text-font);--md-filled-field-label-text-line-height: var(--_text-field-label-text-line-height);--md-filled-field-label-text-populated-line-height: var(--_text-field-label-text-populated-line-height);--md-filled-field-label-text-populated-size: var(--_text-field-label-text-populated-size);--md-filled-field-label-text-size: var(--_text-field-label-text-size);--md-filled-field-label-text-weight: var(--_text-field-label-text-weight);--md-filled-field-leading-content-color: var(--_text-field-leading-icon-color);--md-filled-field-supporting-text-color: var(--_text-field-supporting-text-color);--md-filled-field-supporting-text-font: var(--_text-field-supporting-text-font);--md-filled-field-supporting-text-line-height: var(--_text-field-supporting-text-line-height);--md-filled-field-supporting-text-size: var(--_text-field-supporting-text-size);--md-filled-field-supporting-text-weight: var(--_text-field-supporting-text-weight);--md-filled-field-trailing-content-color: var(--_text-field-trailing-icon-color)}[has-start] .icon.leading{font-size:var(--_text-field-leading-icon-size);height:var(--_text-field-leading-icon-size);width:var(--_text-field-leading-icon-size)}.icon.trailing{font-size:var(--_text-field-trailing-icon-size);height:var(--_text-field-trailing-icon-size);width:var(--_text-field-trailing-icon-size)} +`;const lo=v`:host{color:unset;min-width:210px;display:flex}.field{cursor:default;outline:none}.select{position:relative;flex-direction:column}.icon.trailing svg,.icon ::slotted(*){fill:currentColor}.icon ::slotted(*){width:inherit;height:inherit;font-size:inherit}.icon slot{display:flex;height:100%;width:100%;align-items:center;justify-content:center}.icon.trailing :is(.up,.down){opacity:0;transition:opacity 75ms linear 75ms}.select:not(.open) .down,.select.open .up{opacity:1}.field,.select,md-menu{min-width:inherit;width:inherit;max-width:inherit;display:flex}md-menu{min-width:var(--__menu-min-width);max-width:var(--__menu-max-width, inherit)}.menu-wrapper{width:0px;height:0px;max-width:inherit}md-menu ::slotted(:not[disabled]){cursor:pointer}.field,.select{width:100%}:host{display:inline-flex}:host([disabled]){pointer-events:none} +`;let Nt=class extends oa{};Nt.styles=[lo,ia],Nt=o([b("md-filled-select")],Nt);class aa extends z{constructor(){super(...arguments),this.fieldTag=K`md-outlined-field`}}const la=v`:host{--_text-field-disabled-input-text-color: var(--md-outlined-select-text-field-disabled-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-disabled-input-text-opacity: var(--md-outlined-select-text-field-disabled-input-text-opacity, 0.38);--_text-field-disabled-label-text-color: var(--md-outlined-select-text-field-disabled-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-disabled-label-text-opacity: var(--md-outlined-select-text-field-disabled-label-text-opacity, 0.38);--_text-field-disabled-leading-icon-color: var(--md-outlined-select-text-field-disabled-leading-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-disabled-leading-icon-opacity: var(--md-outlined-select-text-field-disabled-leading-icon-opacity, 0.38);--_text-field-disabled-outline-color: var(--md-outlined-select-text-field-disabled-outline-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-disabled-outline-opacity: var(--md-outlined-select-text-field-disabled-outline-opacity, 0.12);--_text-field-disabled-outline-width: var(--md-outlined-select-text-field-disabled-outline-width, 1px);--_text-field-disabled-supporting-text-color: var(--md-outlined-select-text-field-disabled-supporting-text-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-disabled-supporting-text-opacity: var(--md-outlined-select-text-field-disabled-supporting-text-opacity, 0.38);--_text-field-disabled-trailing-icon-color: var(--md-outlined-select-text-field-disabled-trailing-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-disabled-trailing-icon-opacity: var(--md-outlined-select-text-field-disabled-trailing-icon-opacity, 0.38);--_text-field-error-focus-input-text-color: var(--md-outlined-select-text-field-error-focus-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-error-focus-label-text-color: var(--md-outlined-select-text-field-error-focus-label-text-color, var(--md-sys-color-error, #b3261e));--_text-field-error-focus-leading-icon-color: var(--md-outlined-select-text-field-error-focus-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-error-focus-outline-color: var(--md-outlined-select-text-field-error-focus-outline-color, var(--md-sys-color-error, #b3261e));--_text-field-error-focus-supporting-text-color: var(--md-outlined-select-text-field-error-focus-supporting-text-color, var(--md-sys-color-error, #b3261e));--_text-field-error-focus-trailing-icon-color: var(--md-outlined-select-text-field-error-focus-trailing-icon-color, var(--md-sys-color-error, #b3261e));--_text-field-error-hover-input-text-color: var(--md-outlined-select-text-field-error-hover-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-error-hover-label-text-color: var(--md-outlined-select-text-field-error-hover-label-text-color, var(--md-sys-color-on-error-container, #410e0b));--_text-field-error-hover-leading-icon-color: var(--md-outlined-select-text-field-error-hover-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-error-hover-outline-color: var(--md-outlined-select-text-field-error-hover-outline-color, var(--md-sys-color-on-error-container, #410e0b));--_text-field-error-hover-supporting-text-color: var(--md-outlined-select-text-field-error-hover-supporting-text-color, var(--md-sys-color-error, #b3261e));--_text-field-error-hover-trailing-icon-color: var(--md-outlined-select-text-field-error-hover-trailing-icon-color, var(--md-sys-color-on-error-container, #410e0b));--_text-field-error-input-text-color: var(--md-outlined-select-text-field-error-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-error-label-text-color: var(--md-outlined-select-text-field-error-label-text-color, var(--md-sys-color-error, #b3261e));--_text-field-error-leading-icon-color: var(--md-outlined-select-text-field-error-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-error-outline-color: var(--md-outlined-select-text-field-error-outline-color, var(--md-sys-color-error, #b3261e));--_text-field-error-supporting-text-color: var(--md-outlined-select-text-field-error-supporting-text-color, var(--md-sys-color-error, #b3261e));--_text-field-error-trailing-icon-color: var(--md-outlined-select-text-field-error-trailing-icon-color, var(--md-sys-color-error, #b3261e));--_text-field-focus-input-text-color: var(--md-outlined-select-text-field-focus-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-focus-label-text-color: var(--md-outlined-select-text-field-focus-label-text-color, var(--md-sys-color-primary, #6750a4));--_text-field-focus-leading-icon-color: var(--md-outlined-select-text-field-focus-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-focus-outline-color: var(--md-outlined-select-text-field-focus-outline-color, var(--md-sys-color-primary, #6750a4));--_text-field-focus-outline-width: var(--md-outlined-select-text-field-focus-outline-width, 3px);--_text-field-focus-supporting-text-color: var(--md-outlined-select-text-field-focus-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-focus-trailing-icon-color: var(--md-outlined-select-text-field-focus-trailing-icon-color, var(--md-sys-color-primary, #6750a4));--_text-field-hover-input-text-color: var(--md-outlined-select-text-field-hover-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-hover-label-text-color: var(--md-outlined-select-text-field-hover-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-hover-leading-icon-color: var(--md-outlined-select-text-field-hover-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-hover-outline-color: var(--md-outlined-select-text-field-hover-outline-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-hover-outline-width: var(--md-outlined-select-text-field-hover-outline-width, 1px);--_text-field-hover-supporting-text-color: var(--md-outlined-select-text-field-hover-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-hover-trailing-icon-color: var(--md-outlined-select-text-field-hover-trailing-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-input-text-color: var(--md-outlined-select-text-field-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-input-text-font: var(--md-outlined-select-text-field-input-text-font, var(--md-sys-typescale-body-large-font, var(--md-ref-typeface-plain, Roboto)));--_text-field-input-text-line-height: var(--md-outlined-select-text-field-input-text-line-height, var(--md-sys-typescale-body-large-line-height, 1.5rem));--_text-field-input-text-size: var(--md-outlined-select-text-field-input-text-size, var(--md-sys-typescale-body-large-size, 1rem));--_text-field-input-text-weight: var(--md-outlined-select-text-field-input-text-weight, var(--md-sys-typescale-body-large-weight, var(--md-ref-typeface-weight-regular, 400)));--_text-field-label-text-color: var(--md-outlined-select-text-field-label-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-label-text-font: var(--md-outlined-select-text-field-label-text-font, var(--md-sys-typescale-body-large-font, var(--md-ref-typeface-plain, Roboto)));--_text-field-label-text-line-height: var(--md-outlined-select-text-field-label-text-line-height, var(--md-sys-typescale-body-large-line-height, 1.5rem));--_text-field-label-text-populated-line-height: var(--md-outlined-select-text-field-label-text-populated-line-height, var(--md-sys-typescale-body-small-line-height, 1rem));--_text-field-label-text-populated-size: var(--md-outlined-select-text-field-label-text-populated-size, var(--md-sys-typescale-body-small-size, 0.75rem));--_text-field-label-text-size: var(--md-outlined-select-text-field-label-text-size, var(--md-sys-typescale-body-large-size, 1rem));--_text-field-label-text-weight: var(--md-outlined-select-text-field-label-text-weight, var(--md-sys-typescale-body-large-weight, var(--md-ref-typeface-weight-regular, 400)));--_text-field-leading-icon-color: var(--md-outlined-select-text-field-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-leading-icon-size: var(--md-outlined-select-text-field-leading-icon-size, 24px);--_text-field-outline-color: var(--md-outlined-select-text-field-outline-color, var(--md-sys-color-outline, #79747e));--_text-field-outline-width: var(--md-outlined-select-text-field-outline-width, 1px);--_text-field-supporting-text-color: var(--md-outlined-select-text-field-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-supporting-text-font: var(--md-outlined-select-text-field-supporting-text-font, var(--md-sys-typescale-body-small-font, var(--md-ref-typeface-plain, Roboto)));--_text-field-supporting-text-line-height: var(--md-outlined-select-text-field-supporting-text-line-height, var(--md-sys-typescale-body-small-line-height, 1rem));--_text-field-supporting-text-size: var(--md-outlined-select-text-field-supporting-text-size, var(--md-sys-typescale-body-small-size, 0.75rem));--_text-field-supporting-text-weight: var(--md-outlined-select-text-field-supporting-text-weight, var(--md-sys-typescale-body-small-weight, var(--md-ref-typeface-weight-regular, 400)));--_text-field-trailing-icon-color: var(--md-outlined-select-text-field-trailing-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-trailing-icon-size: var(--md-outlined-select-text-field-trailing-icon-size, 24px);--_text-field-container-shape-start-start: var(--md-outlined-select-text-field-container-shape-start-start, var(--md-outlined-select-text-field-container-shape, var(--md-sys-shape-corner-extra-small, 4px)));--_text-field-container-shape-start-end: var(--md-outlined-select-text-field-container-shape-start-end, var(--md-outlined-select-text-field-container-shape, var(--md-sys-shape-corner-extra-small, 4px)));--_text-field-container-shape-end-end: var(--md-outlined-select-text-field-container-shape-end-end, var(--md-outlined-select-text-field-container-shape, var(--md-sys-shape-corner-extra-small, 4px)));--_text-field-container-shape-end-start: var(--md-outlined-select-text-field-container-shape-end-start, var(--md-outlined-select-text-field-container-shape, var(--md-sys-shape-corner-extra-small, 4px)));--md-outlined-field-container-shape-end-end: var(--_text-field-container-shape-end-end);--md-outlined-field-container-shape-end-start: var(--_text-field-container-shape-end-start);--md-outlined-field-container-shape-start-end: var(--_text-field-container-shape-start-end);--md-outlined-field-container-shape-start-start: var(--_text-field-container-shape-start-start);--md-outlined-field-content-color: var(--_text-field-input-text-color);--md-outlined-field-content-font: var(--_text-field-input-text-font);--md-outlined-field-content-line-height: var(--_text-field-input-text-line-height);--md-outlined-field-content-size: var(--_text-field-input-text-size);--md-outlined-field-content-weight: var(--_text-field-input-text-weight);--md-outlined-field-disabled-content-color: var(--_text-field-disabled-input-text-color);--md-outlined-field-disabled-content-opacity: var(--_text-field-disabled-input-text-opacity);--md-outlined-field-disabled-label-text-color: var(--_text-field-disabled-label-text-color);--md-outlined-field-disabled-label-text-opacity: var(--_text-field-disabled-label-text-opacity);--md-outlined-field-disabled-leading-content-color: var(--_text-field-disabled-leading-icon-color);--md-outlined-field-disabled-leading-content-opacity: var(--_text-field-disabled-leading-icon-opacity);--md-outlined-field-disabled-outline-color: var(--_text-field-disabled-outline-color);--md-outlined-field-disabled-outline-opacity: var(--_text-field-disabled-outline-opacity);--md-outlined-field-disabled-outline-width: var(--_text-field-disabled-outline-width);--md-outlined-field-disabled-supporting-text-color: var(--_text-field-disabled-supporting-text-color);--md-outlined-field-disabled-supporting-text-opacity: var(--_text-field-disabled-supporting-text-opacity);--md-outlined-field-disabled-trailing-content-color: var(--_text-field-disabled-trailing-icon-color);--md-outlined-field-disabled-trailing-content-opacity: var(--_text-field-disabled-trailing-icon-opacity);--md-outlined-field-error-content-color: var(--_text-field-error-input-text-color);--md-outlined-field-error-focus-content-color: var(--_text-field-error-focus-input-text-color);--md-outlined-field-error-focus-label-text-color: var(--_text-field-error-focus-label-text-color);--md-outlined-field-error-focus-leading-content-color: var(--_text-field-error-focus-leading-icon-color);--md-outlined-field-error-focus-outline-color: var(--_text-field-error-focus-outline-color);--md-outlined-field-error-focus-supporting-text-color: var(--_text-field-error-focus-supporting-text-color);--md-outlined-field-error-focus-trailing-content-color: var(--_text-field-error-focus-trailing-icon-color);--md-outlined-field-error-hover-content-color: var(--_text-field-error-hover-input-text-color);--md-outlined-field-error-hover-label-text-color: var(--_text-field-error-hover-label-text-color);--md-outlined-field-error-hover-leading-content-color: var(--_text-field-error-hover-leading-icon-color);--md-outlined-field-error-hover-outline-color: var(--_text-field-error-hover-outline-color);--md-outlined-field-error-hover-supporting-text-color: var(--_text-field-error-hover-supporting-text-color);--md-outlined-field-error-hover-trailing-content-color: var(--_text-field-error-hover-trailing-icon-color);--md-outlined-field-error-label-text-color: var(--_text-field-error-label-text-color);--md-outlined-field-error-leading-content-color: var(--_text-field-error-leading-icon-color);--md-outlined-field-error-outline-color: var(--_text-field-error-outline-color);--md-outlined-field-error-supporting-text-color: var(--_text-field-error-supporting-text-color);--md-outlined-field-error-trailing-content-color: var(--_text-field-error-trailing-icon-color);--md-outlined-field-focus-content-color: var(--_text-field-focus-input-text-color);--md-outlined-field-focus-label-text-color: var(--_text-field-focus-label-text-color);--md-outlined-field-focus-leading-content-color: var(--_text-field-focus-leading-icon-color);--md-outlined-field-focus-outline-color: var(--_text-field-focus-outline-color);--md-outlined-field-focus-outline-width: var(--_text-field-focus-outline-width);--md-outlined-field-focus-supporting-text-color: var(--_text-field-focus-supporting-text-color);--md-outlined-field-focus-trailing-content-color: var(--_text-field-focus-trailing-icon-color);--md-outlined-field-hover-content-color: var(--_text-field-hover-input-text-color);--md-outlined-field-hover-label-text-color: var(--_text-field-hover-label-text-color);--md-outlined-field-hover-leading-content-color: var(--_text-field-hover-leading-icon-color);--md-outlined-field-hover-outline-color: var(--_text-field-hover-outline-color);--md-outlined-field-hover-outline-width: var(--_text-field-hover-outline-width);--md-outlined-field-hover-supporting-text-color: var(--_text-field-hover-supporting-text-color);--md-outlined-field-hover-trailing-content-color: var(--_text-field-hover-trailing-icon-color);--md-outlined-field-label-text-color: var(--_text-field-label-text-color);--md-outlined-field-label-text-font: var(--_text-field-label-text-font);--md-outlined-field-label-text-line-height: var(--_text-field-label-text-line-height);--md-outlined-field-label-text-populated-line-height: var(--_text-field-label-text-populated-line-height);--md-outlined-field-label-text-populated-size: var(--_text-field-label-text-populated-size);--md-outlined-field-label-text-size: var(--_text-field-label-text-size);--md-outlined-field-label-text-weight: var(--_text-field-label-text-weight);--md-outlined-field-leading-content-color: var(--_text-field-leading-icon-color);--md-outlined-field-outline-color: var(--_text-field-outline-color);--md-outlined-field-outline-width: var(--_text-field-outline-width);--md-outlined-field-supporting-text-color: var(--_text-field-supporting-text-color);--md-outlined-field-supporting-text-font: var(--_text-field-supporting-text-font);--md-outlined-field-supporting-text-line-height: var(--_text-field-supporting-text-line-height);--md-outlined-field-supporting-text-size: var(--_text-field-supporting-text-size);--md-outlined-field-supporting-text-weight: var(--_text-field-supporting-text-weight);--md-outlined-field-trailing-content-color: var(--_text-field-trailing-icon-color)}[has-start] .icon.leading{font-size:var(--_text-field-leading-icon-size);height:var(--_text-field-leading-icon-size);width:var(--_text-field-leading-icon-size)}.icon.trailing{font-size:var(--_text-field-trailing-icon-size);height:var(--_text-field-trailing-icon-size);width:var(--_text-field-trailing-icon-size)} +`;let Vt=class extends aa{};Vt.styles=[lo,la],Vt=o([b("md-outlined-select")],Vt);function na(){return new Event("request-selection",{bubbles:!0,composed:!0})}function sa(){return new Event("request-deselection",{bubbles:!0,composed:!0})}class da{get role(){return this.menuItemController.role}get typeaheadText(){return this.menuItemController.typeaheadText}setTypeaheadText(e){this.menuItemController.setTypeaheadText(e)}get displayText(){return this.internalDisplayText!==null?this.internalDisplayText:this.menuItemController.typeaheadText}setDisplayText(e){this.internalDisplayText=e}constructor(e,t){this.host=e,this.internalDisplayText=null,this.firstUpdate=!0,this.onClick=()=>{this.menuItemController.onClick()},this.onKeydown=r=>{this.menuItemController.onKeydown(r)},this.lastSelected=this.host.selected,this.menuItemController=new Jr(e,t),e.addController(this)}hostUpdate(){this.lastSelected!==this.host.selected&&(this.host.ariaSelected=this.host.selected?"true":"false")}hostUpdated(){this.lastSelected!==this.host.selected&&!this.firstUpdate&&(this.host.selected?this.host.dispatchEvent(na()):this.host.dispatchEvent(sa())),this.lastSelected=this.host.selected,this.firstUpdate=!1}}const ca=W(_);class j extends ca{constructor(){super(...arguments),this.disabled=!1,this.isMenuItem=!0,this.selected=!1,this.value="",this.type="option",this.selectOptionController=new da(this,{getHeadlineElements:()=>this.headlineElements,getSupportingTextElements:()=>this.supportingTextElements,getDefaultElements:()=>this.defaultElements,getInteractiveElement:()=>this.listItemRoot})}get typeaheadText(){return this.selectOptionController.typeaheadText}set typeaheadText(e){this.selectOptionController.setTypeaheadText(e)}get displayText(){return this.selectOptionController.displayText}set displayText(e){this.selectOptionController.setDisplayText(e)}render(){return this.renderListItem(d` + +
+ ${this.renderRipple()} ${this.renderFocusRing()} +
+ + + ${this.renderBody()} +
+ `)}renderListItem(e){return d` +
  • ${e}
  • + `}renderRipple(){return d` `}renderFocusRing(){return d` `}getRenderClasses(){return{disabled:this.disabled,selected:this.selected}}renderBody(){return d` + + + + + + `}focus(){this.listItemRoot?.focus()}}j.shadowRootOptions={..._.shadowRootOptions,delegatesFocus:!0},o([l({type:Boolean,reflect:!0})],j.prototype,"disabled",void 0),o([l({type:Boolean,attribute:"md-menu-item",reflect:!0})],j.prototype,"isMenuItem",void 0),o([l({type:Boolean})],j.prototype,"selected",void 0),o([l()],j.prototype,"value",void 0),o([g(".list-item")],j.prototype,"listItemRoot",void 0),o([H({slot:"headline"})],j.prototype,"headlineElements",void 0),o([H({slot:"supporting-text"})],j.prototype,"supportingTextElements",void 0),o([Qt({slot:""})],j.prototype,"defaultElements",void 0),o([l({attribute:"typeahead-text"})],j.prototype,"typeaheadText",null),o([l({attribute:"display-text"})],j.prototype,"displayText",null);let qt=class extends j{};qt.styles=[eo],qt=o([b("md-select-option")],qt);const ha=v`@media(forced-colors: active){:host{--md-slider-active-track-color: CanvasText;--md-slider-disabled-active-track-color: GrayText;--md-slider-disabled-active-track-opacity: 1;--md-slider-disabled-handle-color: GrayText;--md-slider-disabled-inactive-track-color: GrayText;--md-slider-disabled-inactive-track-opacity: 1;--md-slider-focus-handle-color: CanvasText;--md-slider-handle-color: CanvasText;--md-slider-handle-shadow-color: Canvas;--md-slider-hover-handle-color: CanvasText;--md-slider-hover-state-layer-color: Canvas;--md-slider-hover-state-layer-opacity: 1;--md-slider-inactive-track-color: Canvas;--md-slider-label-container-color: Canvas;--md-slider-label-text-color: CanvasText;--md-slider-pressed-handle-color: CanvasText;--md-slider-pressed-state-layer-color: Canvas;--md-slider-pressed-state-layer-opacity: 1;--md-slider-with-overlap-handle-outline-color: CanvasText}.label,.label::before{border:var(--_with-overlap-handle-outline-color) solid var(--_with-overlap-handle-outline-width)}:host(:not([disabled])) .track::before{border:1px solid var(--_active-track-color)}.tickmarks::before{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='CanvasText'%3E%3Ccircle cx='2' cy='2' r='1'/%3E%3C/svg%3E")}.tickmarks::after{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='Canvas'%3E%3Ccircle cx='2' cy='2' r='1'/%3E%3C/svg%3E")}:host([disabled]) .tickmarks::before{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='Canvas'%3E%3Ccircle cx='2' cy='2' r='1'/%3E%3C/svg%3E")}} +`;const pa=W(we(se(_)));class C extends pa{get nameStart(){return this.getAttribute("name-start")??this.name}set nameStart(e){this.setAttribute("name-start",e)}get nameEnd(){return this.getAttribute("name-end")??this.nameStart}set nameEnd(e){this.setAttribute("name-end",e)}get renderAriaLabelStart(){const{ariaLabel:e}=this;return this.ariaLabelStart||e&&`${e} start`||this.valueLabelStart||String(this.valueStart)}get renderAriaValueTextStart(){return this.ariaValueTextStart||this.valueLabelStart||String(this.valueStart)}get renderAriaLabelEnd(){const{ariaLabel:e}=this;return this.range?this.ariaLabelEnd||e&&`${e} end`||this.valueLabelEnd||String(this.valueEnd):e||this.valueLabel||String(this.value)}get renderAriaValueTextEnd(){if(this.range)return this.ariaValueTextEnd||this.valueLabelEnd||String(this.valueEnd);const{ariaValueText:e}=this;return e||this.valueLabel||String(this.value)}constructor(){super(),this.min=0,this.max=100,this.valueLabel="",this.valueLabelStart="",this.valueLabelEnd="",this.ariaLabelStart="",this.ariaValueTextStart="",this.ariaLabelEnd="",this.ariaValueTextEnd="",this.step=1,this.ticks=!1,this.labeled=!1,this.range=!1,this.handleStartHover=!1,this.handleEndHover=!1,this.startOnTop=!1,this.handlesOverlapping=!1,this.ripplePointerId=1,this.isRedispatchingEvent=!1,T||this.addEventListener("click",e=>{!Se(e)||!this.inputEnd||(this.focus(),Ue(this.inputEnd))})}focus(){this.inputEnd?.focus()}willUpdate(e){this.renderValueStart=e.has("valueStart")?this.valueStart:this.inputStart?.valueAsNumber;const t=e.has("valueEnd")&&this.range||e.has("value");this.renderValueEnd=t?this.range?this.valueEnd:this.value:this.inputEnd?.valueAsNumber,e.get("handleStartHover")!==void 0?this.toggleRippleHover(this.rippleStart,this.handleStartHover):e.get("handleEndHover")!==void 0&&this.toggleRippleHover(this.rippleEnd,this.handleEndHover)}updated(e){if(this.range&&(this.renderValueStart=this.inputStart.valueAsNumber),this.renderValueEnd=this.inputEnd.valueAsNumber,this.range){const t=(this.max-this.min)/3;if(this.valueStart===void 0){this.inputStart.valueAsNumber=this.min+t;const r=this.inputStart.valueAsNumber;this.valueStart=this.renderValueStart=r}if(this.valueEnd===void 0){this.inputEnd.valueAsNumber=this.min+2*t;const r=this.inputEnd.valueAsNumber;this.valueEnd=this.renderValueEnd=r}}else this.value??=this.renderValueEnd;if(e.has("range")||e.has("renderValueStart")||e.has("renderValueEnd")||this.isUpdatePending){const t=this.handleStart?.querySelector(".handleNub"),r=this.handleEnd?.querySelector(".handleNub");this.handlesOverlapping=va(t,r)}this.performUpdate()}render(){const e=this.step===0?1:this.step,t=Math.max(this.max-this.min,e),r=this.range?((this.renderValueStart??this.min)-this.min)/t:0,a=((this.renderValueEnd??this.min)-this.min)/t,n={"--_start-fraction":String(r),"--_end-fraction":String(a),"--_tick-count":String(t/e)},s={ranged:this.range},h=this.valueLabelStart||String(this.renderValueStart),p=(this.range?this.valueLabelEnd:this.valueLabel)||String(this.renderValueEnd),y={start:!0,value:this.renderValueStart,ariaLabel:this.renderAriaLabelStart,ariaValueText:this.renderAriaValueTextStart,ariaMin:this.min,ariaMax:this.valueEnd??this.max},u={start:!1,value:this.renderValueEnd,ariaLabel:this.renderAriaLabelEnd,ariaValueText:this.renderAriaValueTextEnd,ariaMin:this.range?this.valueStart??this.min:this.min,ariaMax:this.max},f={start:!0,hover:this.handleStartHover,label:h},m={start:!1,hover:this.handleEndHover,label:p},w={hover:this.handleStartHover||this.handleEndHover};return d`
    + ${Jt(this.range,()=>this.renderInput(y))} + ${this.renderInput(u)} ${this.renderTrack()} +
    +
    +
    + ${Jt(this.range,()=>this.renderHandle(f))} + ${this.renderHandle(m)} +
    +
    +
    +
    `}renderTrack(){return d` +
    + ${this.ticks?d`
    `:c} + `}renderLabel(e){return d``}renderHandle({start:e,hover:t,label:r}){const a=!this.disabled&&e===this.startOnTop,n=!this.disabled&&this.handlesOverlapping,s=e?"start":"end";return d`
    + + +
    + +
    + ${Jt(this.labeled,()=>this.renderLabel(r))} +
    `}renderInput({start:e,value:t,ariaLabel:r,ariaValueText:a,ariaMin:n,ariaMax:s}){const h=e?"start":"end";return d``}async toggleRippleHover(e,t){const r=await e;r&&(t?r.handlePointerenter(new PointerEvent("pointerenter",{isPrimary:!0,pointerId:this.ripplePointerId})):r.handlePointerleave(new PointerEvent("pointerleave",{isPrimary:!0,pointerId:this.ripplePointerId})))}handleFocus(e){this.updateOnTop(e.target)}startAction(e){const t=e.target,r=t===this.inputStart?this.inputEnd:this.inputStart;this.action={canFlip:e.type==="pointerdown",flipped:!1,target:t,fixed:r,values:new Map([[t,t.valueAsNumber],[r,r?.valueAsNumber]])}}finishAction(e){this.action=void 0}handleKeydown(e){this.startAction(e)}handleKeyup(e){this.finishAction(e)}handleDown(e){this.startAction(e),this.ripplePointerId=e.pointerId;const t=e.target===this.inputStart;this.handleStartHover=!this.disabled&&t&&!!this.handleStart,this.handleEndHover=!this.disabled&&!t&&!!this.handleEnd}async handleUp(e){if(!this.action)return;const{target:t,values:r,flipped:a}=this.action;await new Promise(requestAnimationFrame),t!==void 0&&(t.focus(),a&&t.valueAsNumber!==r.get(t)&&t.dispatchEvent(new Event("change",{bubbles:!0}))),this.finishAction(e)}handleMove(e){this.handleStartHover=!this.disabled&&no(e,this.handleStart),this.handleEndHover=!this.disabled&&no(e,this.handleEnd)}handleEnter(e){this.handleMove(e)}handleLeave(){this.handleStartHover=!1,this.handleEndHover=!1}updateOnTop(e){this.startOnTop=e.classList.contains("start")}needsClamping(){if(!this.action)return!1;const{target:e,fixed:t}=this.action;return e===this.inputStart?e.valueAsNumber>t.valueAsNumber:e.valueAsNumber=a&&i<=s&&e>=r&&e<=n}function va(i,e){if(!(i&&e))return!1;const t=i.getBoundingClientRect(),r=e.getBoundingClientRect();return!(t.top>r.bottom||t.rightr.right)}const ua=v`:host{--_active-track-color: var(--md-slider-active-track-color, var(--md-sys-color-primary, #6750a4));--_active-track-height: var(--md-slider-active-track-height, 4px);--_active-track-shape: var(--md-slider-active-track-shape, var(--md-sys-shape-corner-full, 9999px));--_disabled-active-track-color: var(--md-slider-disabled-active-track-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-active-track-opacity: var(--md-slider-disabled-active-track-opacity, 0.38);--_disabled-handle-color: var(--md-slider-disabled-handle-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-handle-elevation: var(--md-slider-disabled-handle-elevation, 0);--_disabled-inactive-track-color: var(--md-slider-disabled-inactive-track-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-inactive-track-opacity: var(--md-slider-disabled-inactive-track-opacity, 0.12);--_focus-handle-color: var(--md-slider-focus-handle-color, var(--md-sys-color-primary, #6750a4));--_handle-color: var(--md-slider-handle-color, var(--md-sys-color-primary, #6750a4));--_handle-elevation: var(--md-slider-handle-elevation, 1);--_handle-height: var(--md-slider-handle-height, 20px);--_handle-shadow-color: var(--md-slider-handle-shadow-color, var(--md-sys-color-shadow, #000));--_handle-shape: var(--md-slider-handle-shape, var(--md-sys-shape-corner-full, 9999px));--_handle-width: var(--md-slider-handle-width, 20px);--_hover-handle-color: var(--md-slider-hover-handle-color, var(--md-sys-color-primary, #6750a4));--_hover-state-layer-color: var(--md-slider-hover-state-layer-color, var(--md-sys-color-primary, #6750a4));--_hover-state-layer-opacity: var(--md-slider-hover-state-layer-opacity, 0.08);--_inactive-track-color: var(--md-slider-inactive-track-color, var(--md-sys-color-surface-container-highest, #e6e0e9));--_inactive-track-height: var(--md-slider-inactive-track-height, 4px);--_inactive-track-shape: var(--md-slider-inactive-track-shape, var(--md-sys-shape-corner-full, 9999px));--_label-container-color: var(--md-slider-label-container-color, var(--md-sys-color-primary, #6750a4));--_label-container-height: var(--md-slider-label-container-height, 28px);--_pressed-handle-color: var(--md-slider-pressed-handle-color, var(--md-sys-color-primary, #6750a4));--_pressed-state-layer-color: var(--md-slider-pressed-state-layer-color, var(--md-sys-color-primary, #6750a4));--_pressed-state-layer-opacity: var(--md-slider-pressed-state-layer-opacity, 0.12);--_state-layer-size: var(--md-slider-state-layer-size, 40px);--_with-overlap-handle-outline-color: var(--md-slider-with-overlap-handle-outline-color, var(--md-sys-color-on-primary, #fff));--_with-overlap-handle-outline-width: var(--md-slider-with-overlap-handle-outline-width, 1px);--_with-tick-marks-active-container-color: var(--md-slider-with-tick-marks-active-container-color, var(--md-sys-color-on-primary, #fff));--_with-tick-marks-container-size: var(--md-slider-with-tick-marks-container-size, 2px);--_with-tick-marks-disabled-container-color: var(--md-slider-with-tick-marks-disabled-container-color, var(--md-sys-color-on-surface, #1d1b20));--_with-tick-marks-inactive-container-color: var(--md-slider-with-tick-marks-inactive-container-color, var(--md-sys-color-on-surface-variant, #49454f));--_label-text-color: var(--md-slider-label-text-color, var(--md-sys-color-on-primary, #fff));--_label-text-font: var(--md-slider-label-text-font, var(--md-sys-typescale-label-medium-font, var(--md-ref-typeface-plain, Roboto)));--_label-text-line-height: var(--md-slider-label-text-line-height, var(--md-sys-typescale-label-medium-line-height, 1rem));--_label-text-size: var(--md-slider-label-text-size, var(--md-sys-typescale-label-medium-size, 0.75rem));--_label-text-weight: var(--md-slider-label-text-weight, var(--md-sys-typescale-label-medium-weight, var(--md-ref-typeface-weight-medium, 500)));--_start-fraction: 0;--_end-fraction: 0;--_tick-count: 0;display:inline-flex;vertical-align:middle;min-inline-size:200px;--md-elevation-level: var(--_handle-elevation);--md-elevation-shadow-color: var(--_handle-shadow-color)}md-focus-ring{height:48px;inset:unset;width:48px}md-elevation{transition-duration:250ms}@media(prefers-reduced-motion){.label{transition-duration:0}}:host([disabled]){opacity:var(--_disabled-active-track-opacity);--md-elevation-level: var(--_disabled-handle-elevation)}.container{flex:1;display:flex;align-items:center;position:relative;block-size:var(--_state-layer-size);pointer-events:none;touch-action:none}.track,.tickmarks{position:absolute;inset:0;display:flex;align-items:center}.track::before,.tickmarks::before,.track::after,.tickmarks::after{position:absolute;content:"";inset-inline-start:calc(var(--_state-layer-size)/2 - var(--_with-tick-marks-container-size));inset-inline-end:calc(var(--_state-layer-size)/2 - var(--_with-tick-marks-container-size));background-size:calc((100% - var(--_with-tick-marks-container-size)*2)/var(--_tick-count)) 100%}.track::before,.tickmarks::before{block-size:var(--_inactive-track-height);border-radius:var(--_inactive-track-shape)}.track::before{background:var(--_inactive-track-color)}.tickmarks::before{background-image:radial-gradient(circle at var(--_with-tick-marks-container-size) center, var(--_with-tick-marks-inactive-container-color) 0, var(--_with-tick-marks-inactive-container-color) calc(var(--_with-tick-marks-container-size) / 2), transparent calc(var(--_with-tick-marks-container-size) / 2))}:host([disabled]) .track::before{opacity:calc(1/var(--_disabled-active-track-opacity)*var(--_disabled-inactive-track-opacity));background:var(--_disabled-inactive-track-color)}.track::after,.tickmarks::after{block-size:var(--_active-track-height);border-radius:var(--_active-track-shape);clip-path:inset(0 calc(var(--_with-tick-marks-container-size) * min((1 - var(--_end-fraction)) * 1000000000, 1) + (100% - var(--_with-tick-marks-container-size) * 2) * (1 - var(--_end-fraction))) 0 calc(var(--_with-tick-marks-container-size) * min(var(--_start-fraction) * 1000000000, 1) + (100% - var(--_with-tick-marks-container-size) * 2) * var(--_start-fraction)))}.track::after{background:var(--_active-track-color)}.tickmarks::after{background-image:radial-gradient(circle at var(--_with-tick-marks-container-size) center, var(--_with-tick-marks-active-container-color) 0, var(--_with-tick-marks-active-container-color) calc(var(--_with-tick-marks-container-size) / 2), transparent calc(var(--_with-tick-marks-container-size) / 2))}.track:dir(rtl)::after{clip-path:inset(0 calc(var(--_with-tick-marks-container-size) * min(var(--_start-fraction) * 1000000000, 1) + (100% - var(--_with-tick-marks-container-size) * 2) * var(--_start-fraction)) 0 calc(var(--_with-tick-marks-container-size) * min((1 - var(--_end-fraction)) * 1000000000, 1) + (100% - var(--_with-tick-marks-container-size) * 2) * (1 - var(--_end-fraction))))}.tickmarks:dir(rtl)::after{clip-path:inset(0 calc(var(--_with-tick-marks-container-size) * min(var(--_start-fraction) * 1000000000, 1) + (100% - var(--_with-tick-marks-container-size) * 2) * var(--_start-fraction)) 0 calc(var(--_with-tick-marks-container-size) * min((1 - var(--_end-fraction)) * 1000000000, 1) + (100% - var(--_with-tick-marks-container-size) * 2) * (1 - var(--_end-fraction))))}:host([disabled]) .track::after{background:var(--_disabled-active-track-color)}:host([disabled]) .tickmarks::before{background-image:radial-gradient(circle at var(--_with-tick-marks-container-size) center, var(--_with-tick-marks-disabled-container-color) 0, var(--_with-tick-marks-disabled-container-color) calc(var(--_with-tick-marks-container-size) / 2), transparent calc(var(--_with-tick-marks-container-size) / 2))}.handleContainerPadded{position:relative;block-size:100%;inline-size:100%;padding-inline:calc(var(--_state-layer-size)/2)}.handleContainerBlock{position:relative;block-size:100%;inline-size:100%}.handleContainer{position:absolute;inset-block-start:0;inset-block-end:0;inset-inline-start:calc(100%*var(--_start-fraction));inline-size:calc(100%*(var(--_end-fraction) - var(--_start-fraction)))}.handle{position:absolute;block-size:var(--_state-layer-size);inline-size:var(--_state-layer-size);border-radius:var(--_handle-shape);display:flex;place-content:center;place-items:center}.handleNub{position:absolute;height:var(--_handle-height);width:var(--_handle-width);border-radius:var(--_handle-shape);background:var(--_handle-color)}:host([disabled]) .handleNub{background:var(--_disabled-handle-color)}input.end:focus~.handleContainerPadded .handle.end>.handleNub,input.start:focus~.handleContainerPadded .handle.start>.handleNub{background:var(--_focus-handle-color)}.container>.handleContainerPadded .handle.hover>.handleNub{background:var(--_hover-handle-color)}:host(:not([disabled])) input.end:active~.handleContainerPadded .handle.end>.handleNub,:host(:not([disabled])) input.start:active~.handleContainerPadded .handle.start>.handleNub{background:var(--_pressed-handle-color)}.onTop.isOverlapping .label,.onTop.isOverlapping .label::before{outline:var(--_with-overlap-handle-outline-color) solid var(--_with-overlap-handle-outline-width)}.onTop.isOverlapping .handleNub{border:var(--_with-overlap-handle-outline-color) solid var(--_with-overlap-handle-outline-width)}.handle.start{inset-inline-start:calc(0px - var(--_state-layer-size)/2)}.handle.end{inset-inline-end:calc(0px - var(--_state-layer-size)/2)}.label{position:absolute;box-sizing:border-box;display:flex;padding:4px;place-content:center;place-items:center;border-radius:var(--md-sys-shape-corner-full, 9999px);color:var(--_label-text-color);font-family:var(--_label-text-font);font-size:var(--_label-text-size);line-height:var(--_label-text-line-height);font-weight:var(--_label-text-weight);inset-block-end:100%;min-inline-size:var(--_label-container-height);min-block-size:var(--_label-container-height);background:var(--_label-container-color);transition:transform 100ms cubic-bezier(0.2, 0, 0, 1);transform-origin:center bottom;transform:scale(0)}:host(:focus-within) .label,.handleContainer.hover .label,:where(:has(input:active)) .label{transform:scale(1)}.label::before,.label::after{position:absolute;display:block;content:"";background:inherit}.label::before{inline-size:calc(var(--_label-container-height)/2);block-size:calc(var(--_label-container-height)/2);bottom:calc(var(--_label-container-height)/-10);transform:rotate(45deg)}.label::after{inset:0px;border-radius:inherit}.labelContent{z-index:1}input[type=range]{opacity:0;-webkit-tap-highlight-color:rgba(0,0,0,0);position:absolute;box-sizing:border-box;height:100%;width:100%;margin:0;background:rgba(0,0,0,0);cursor:pointer;pointer-events:auto;appearance:none}input[type=range]:focus{outline:none}::-webkit-slider-runnable-track{-webkit-appearance:none}::-moz-range-track{appearance:none}::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;block-size:var(--_handle-height);inline-size:var(--_handle-width);opacity:0;z-index:2}input.end::-webkit-slider-thumb{--_track-and-knob-padding: calc( (var(--_state-layer-size) - var(--_handle-width)) / 2 );--_x-translate: calc( var(--_track-and-knob-padding) - 2 * var(--_end-fraction) * var(--_track-and-knob-padding) );transform:translateX(var(--_x-translate))}input.end:dir(rtl)::-webkit-slider-thumb{transform:translateX(calc(-1 * var(--_x-translate)))}input.start::-webkit-slider-thumb{--_track-and-knob-padding: calc( (var(--_state-layer-size) - var(--_handle-width)) / 2 );--_x-translate: calc( var(--_track-and-knob-padding) - 2 * var(--_start-fraction) * var(--_track-and-knob-padding) );transform:translateX(var(--_x-translate))}input.start:dir(rtl)::-webkit-slider-thumb{transform:translateX(calc(-1 * var(--_x-translate)))}::-moz-range-thumb{appearance:none;block-size:var(--_state-layer-size);inline-size:var(--_state-layer-size);transform:scaleX(0);opacity:0;z-index:2}.ranged input.start{clip-path:inset(0 calc(100% - (var(--_state-layer-size) / 2 + (100% - var(--_state-layer-size)) * (var(--_start-fraction) + (var(--_end-fraction) - var(--_start-fraction)) / 2))) 0 0)}.ranged input.start:dir(rtl){clip-path:inset(0 0 0 calc(100% - (var(--_state-layer-size) / 2 + (100% - var(--_state-layer-size)) * (var(--_start-fraction) + (var(--_end-fraction) - var(--_start-fraction)) / 2))))}.ranged input.end{clip-path:inset(0 0 0 calc(var(--_state-layer-size) / 2 + (100% - var(--_state-layer-size)) * (var(--_start-fraction) + (var(--_end-fraction) - var(--_start-fraction)) / 2)))}.ranged input.end:dir(rtl){clip-path:inset(0 calc(var(--_state-layer-size) / 2 + (100% - var(--_state-layer-size)) * (var(--_start-fraction) + (var(--_end-fraction) - var(--_start-fraction)) / 2)) 0 0)}.onTop{z-index:1}.handle{--md-ripple-hover-color: var(--_hover-state-layer-color);--md-ripple-hover-opacity: var(--_hover-state-layer-opacity);--md-ripple-pressed-color: var(--_pressed-state-layer-color);--md-ripple-pressed-opacity: var(--_pressed-state-layer-opacity)}md-ripple{border-radius:50%;height:var(--_state-layer-size);width:var(--_state-layer-size)} +`;let Ht=class extends C{};Ht.styles=[ua,ha],Ht=o([b("md-slider")],Ht);const so=Symbol("dispatchHooks");function fa(i,e){const t=i[so];if(!t)throw new Error(`'${i.type}' event needs setupDispatchHooks().`);t.addEventListener("after",e)}const co=new WeakMap;function ma(i,...e){let t=co.get(i);t||(t=new Set,co.set(i,t));for(const r of e){if(t.has(r))continue;let a=!1;i.addEventListener(r,n=>{if(a)return;n.stopImmediatePropagation();const s=Reflect.construct(n.constructor,[n.type,n]),h=new EventTarget;s[so]=h,a=!0;const p=i.dispatchEvent(s);a=!1,p||n.preventDefault(),h.dispatchEvent(new Event("after"))},{capture:!0}),t.add(r)}}const ba=W(Re(we(se(_))));class ve extends ba{constructor(){super(),this.selected=!1,this.icons=!1,this.showOnlySelectedIcon=!1,this.required=!1,this.value="on",!T&&(this.addEventListener("click",e=>{!Se(e)||!this.input||(this.focus(),Ue(this.input))}),ma(this,"keydown"),this.addEventListener("keydown",e=>{fa(e,()=>{e.defaultPrevented||e.key!=="Enter"||this.disabled||!this.input||this.input.click()})}))}render(){return d` +
    + + + + ${this.renderHandle()} +
    + `}getRenderClasses(){return{selected:this.selected,unselected:!this.selected,disabled:this.disabled}}renderHandle(){const e={"with-icon":this.showOnlySelectedIcon?this.selected:this.icons};return d` + ${this.renderTouchTarget()} + + + + ${this.shouldShowIcons()?this.renderIcons():d``} + + + `}renderIcons(){return d` +
    + ${this.renderOnIcon()} + ${this.showOnlySelectedIcon?d``:this.renderOffIcon()} +
    + `}renderOnIcon(){return d` + + + + + + `}renderOffIcon(){return d` + + + + + + `}renderTouchTarget(){return d``}shouldShowIcons(){return this.icons||this.showOnlySelectedIcon}handleInput(e){const t=e.target;this.selected=t.checked}handleChange(e){de(this,e)}[ie](){return this.selected?this.value:null}[Oe](){return String(this.selected)}formResetCallback(){this.selected=this.hasAttribute("selected")}formStateRestoreCallback(e){this.selected=e==="true"}[me](){return new $r(()=>({checked:this.selected,required:this.required}))}[be](){return this.input}}ve.shadowRootOptions={mode:"open",delegatesFocus:!0},o([l({type:Boolean})],ve.prototype,"selected",void 0),o([l({type:Boolean})],ve.prototype,"icons",void 0),o([l({type:Boolean,attribute:"show-only-selected-icon"})],ve.prototype,"showOnlySelectedIcon",void 0),o([l({type:Boolean})],ve.prototype,"required",void 0),o([l()],ve.prototype,"value",void 0),o([g("input")],ve.prototype,"input",void 0);const ya=v`@layer styles, hcm;@layer styles{:host{display:inline-flex;outline:none;vertical-align:top;-webkit-tap-highlight-color:rgba(0,0,0,0);cursor:pointer}:host([disabled]){cursor:default}:host([touch-target=wrapper]){margin:max(0px,(48px - var(--md-switch-track-height, 32px))/2) 0px}md-focus-ring{--md-focus-ring-shape-start-start: var(--md-switch-track-shape-start-start, var(--md-switch-track-shape, var(--md-sys-shape-corner-full, 9999px)));--md-focus-ring-shape-start-end: var(--md-switch-track-shape-start-end, var(--md-switch-track-shape, var(--md-sys-shape-corner-full, 9999px)));--md-focus-ring-shape-end-end: var(--md-switch-track-shape-end-end, var(--md-switch-track-shape, var(--md-sys-shape-corner-full, 9999px)));--md-focus-ring-shape-end-start: var(--md-switch-track-shape-end-start, var(--md-switch-track-shape, var(--md-sys-shape-corner-full, 9999px)))}.switch{align-items:center;display:inline-flex;flex-shrink:0;position:relative;width:var(--md-switch-track-width, 52px);height:var(--md-switch-track-height, 32px);border-start-start-radius:var(--md-switch-track-shape-start-start, var(--md-switch-track-shape, var(--md-sys-shape-corner-full, 9999px)));border-start-end-radius:var(--md-switch-track-shape-start-end, var(--md-switch-track-shape, var(--md-sys-shape-corner-full, 9999px)));border-end-end-radius:var(--md-switch-track-shape-end-end, var(--md-switch-track-shape, var(--md-sys-shape-corner-full, 9999px)));border-end-start-radius:var(--md-switch-track-shape-end-start, var(--md-switch-track-shape, var(--md-sys-shape-corner-full, 9999px)))}input{appearance:none;height:max(100%,var(--md-switch-touch-target-size, 48px));outline:none;margin:0;position:absolute;width:max(100%,var(--md-switch-touch-target-size, 48px));z-index:1;cursor:inherit;top:50%;left:50%;transform:translate(-50%, -50%)}:host([touch-target=none]) input{display:none}}@layer styles{.track{position:absolute;width:100%;height:100%;box-sizing:border-box;border-radius:inherit;display:flex;justify-content:center;align-items:center}.track::before{content:"";display:flex;position:absolute;height:100%;width:100%;border-radius:inherit;box-sizing:border-box;transition-property:opacity,background-color;transition-timing-function:linear;transition-duration:67ms}.disabled .track{background-color:rgba(0,0,0,0);border-color:rgba(0,0,0,0)}.disabled .track::before,.disabled .track::after{transition:none;opacity:var(--md-switch-disabled-track-opacity, 0.12)}.disabled .track::before{background-clip:content-box}.selected .track::before{background-color:var(--md-switch-selected-track-color, var(--md-sys-color-primary, #6750a4))}.selected:hover .track::before{background-color:var(--md-switch-selected-hover-track-color, var(--md-sys-color-primary, #6750a4))}.selected:focus-within .track::before{background-color:var(--md-switch-selected-focus-track-color, var(--md-sys-color-primary, #6750a4))}.selected:active .track::before{background-color:var(--md-switch-selected-pressed-track-color, var(--md-sys-color-primary, #6750a4))}.selected.disabled .track{background-clip:border-box}.selected.disabled .track::before{background-color:var(--md-switch-disabled-selected-track-color, var(--md-sys-color-on-surface, #1d1b20))}.unselected .track::before{background-color:var(--md-switch-track-color, var(--md-sys-color-surface-container-highest, #e6e0e9));border-color:var(--md-switch-track-outline-color, var(--md-sys-color-outline, #79747e));border-style:solid;border-width:var(--md-switch-track-outline-width, 2px)}.unselected:hover .track::before{background-color:var(--md-switch-hover-track-color, var(--md-sys-color-surface-container-highest, #e6e0e9));border-color:var(--md-switch-hover-track-outline-color, var(--md-sys-color-outline, #79747e))}.unselected:focus-visible .track::before{background-color:var(--md-switch-focus-track-color, var(--md-sys-color-surface-container-highest, #e6e0e9));border-color:var(--md-switch-focus-track-outline-color, var(--md-sys-color-outline, #79747e))}.unselected:active .track::before{background-color:var(--md-switch-pressed-track-color, var(--md-sys-color-surface-container-highest, #e6e0e9));border-color:var(--md-switch-pressed-track-outline-color, var(--md-sys-color-outline, #79747e))}.unselected.disabled .track::before{background-color:var(--md-switch-disabled-track-color, var(--md-sys-color-surface-container-highest, #e6e0e9));border-color:var(--md-switch-disabled-track-outline-color, var(--md-sys-color-on-surface, #1d1b20))}}@layer hcm{@media(forced-colors: active){.selected .track::before{background:ButtonText;border-color:ButtonText}.disabled .track::before{border-color:GrayText;opacity:1}.disabled.selected .track::before{background:GrayText}}}@layer styles{.handle-container{display:flex;place-content:center;place-items:center;position:relative;transition:margin 300ms cubic-bezier(0.175, 0.885, 0.32, 1.275)}.selected .handle-container{margin-inline-start:calc(var(--md-switch-track-width, 52px) - var(--md-switch-track-height, 32px))}.unselected .handle-container{margin-inline-end:calc(var(--md-switch-track-width, 52px) - var(--md-switch-track-height, 32px))}.disabled .handle-container{transition:none}.handle{border-start-start-radius:var(--md-switch-handle-shape-start-start, var(--md-switch-handle-shape, var(--md-sys-shape-corner-full, 9999px)));border-start-end-radius:var(--md-switch-handle-shape-start-end, var(--md-switch-handle-shape, var(--md-sys-shape-corner-full, 9999px)));border-end-end-radius:var(--md-switch-handle-shape-end-end, var(--md-switch-handle-shape, var(--md-sys-shape-corner-full, 9999px)));border-end-start-radius:var(--md-switch-handle-shape-end-start, var(--md-switch-handle-shape, var(--md-sys-shape-corner-full, 9999px)));height:var(--md-switch-handle-height, 16px);width:var(--md-switch-handle-width, 16px);transform-origin:center;transition-property:height,width;transition-duration:250ms,250ms;transition-timing-function:cubic-bezier(0.2, 0, 0, 1),cubic-bezier(0.2, 0, 0, 1);z-index:0}.handle::before{content:"";display:flex;inset:0;position:absolute;border-radius:inherit;box-sizing:border-box;transition:background-color 67ms linear}.disabled .handle,.disabled .handle::before{transition:none}.selected .handle{height:var(--md-switch-selected-handle-height, 24px);width:var(--md-switch-selected-handle-width, 24px)}.handle.with-icon{height:var(--md-switch-with-icon-handle-height, 24px);width:var(--md-switch-with-icon-handle-width, 24px)}.selected:not(.disabled):active .handle,.unselected:not(.disabled):active .handle{height:var(--md-switch-pressed-handle-height, 28px);width:var(--md-switch-pressed-handle-width, 28px);transition-timing-function:linear;transition-duration:100ms}.selected .handle::before{background-color:var(--md-switch-selected-handle-color, var(--md-sys-color-on-primary, #fff))}.selected:hover .handle::before{background-color:var(--md-switch-selected-hover-handle-color, var(--md-sys-color-primary-container, #eaddff))}.selected:focus-within .handle::before{background-color:var(--md-switch-selected-focus-handle-color, var(--md-sys-color-primary-container, #eaddff))}.selected:active .handle::before{background-color:var(--md-switch-selected-pressed-handle-color, var(--md-sys-color-primary-container, #eaddff))}.selected.disabled .handle::before{background-color:var(--md-switch-disabled-selected-handle-color, var(--md-sys-color-surface, #fef7ff));opacity:var(--md-switch-disabled-selected-handle-opacity, 1)}.unselected .handle::before{background-color:var(--md-switch-handle-color, var(--md-sys-color-outline, #79747e))}.unselected:hover .handle::before{background-color:var(--md-switch-hover-handle-color, var(--md-sys-color-on-surface-variant, #49454f))}.unselected:focus-within .handle::before{background-color:var(--md-switch-focus-handle-color, var(--md-sys-color-on-surface-variant, #49454f))}.unselected:active .handle::before{background-color:var(--md-switch-pressed-handle-color, var(--md-sys-color-on-surface-variant, #49454f))}.unselected.disabled .handle::before{background-color:var(--md-switch-disabled-handle-color, var(--md-sys-color-on-surface, #1d1b20));opacity:var(--md-switch-disabled-handle-opacity, 0.38)}md-ripple{border-radius:var(--md-switch-state-layer-shape, var(--md-sys-shape-corner-full, 9999px));height:var(--md-switch-state-layer-size, 40px);inset:unset;width:var(--md-switch-state-layer-size, 40px)}.selected md-ripple{--md-ripple-hover-color: var(--md-switch-selected-hover-state-layer-color, var(--md-sys-color-primary, #6750a4));--md-ripple-pressed-color: var(--md-switch-selected-pressed-state-layer-color, var(--md-sys-color-primary, #6750a4));--md-ripple-hover-opacity: var(--md-switch-selected-hover-state-layer-opacity, 0.08);--md-ripple-pressed-opacity: var(--md-switch-selected-pressed-state-layer-opacity, 0.12)}.unselected md-ripple{--md-ripple-hover-color: var(--md-switch-hover-state-layer-color, var(--md-sys-color-on-surface, #1d1b20));--md-ripple-pressed-color: var(--md-switch-pressed-state-layer-color, var(--md-sys-color-on-surface, #1d1b20));--md-ripple-hover-opacity: var(--md-switch-hover-state-layer-opacity, 0.08);--md-ripple-pressed-opacity: var(--md-switch-pressed-state-layer-opacity, 0.12)}}@layer hcm{@media(forced-colors: active){.unselected .handle::before{background:ButtonText}.disabled .handle::before{opacity:1}.disabled.unselected .handle::before{background:GrayText}}}@layer styles{.icons{position:relative;height:100%;width:100%}.icon{position:absolute;inset:0;margin:auto;display:flex;align-items:center;justify-content:center;fill:currentColor;transition:fill 67ms linear,opacity 33ms linear,transform 167ms cubic-bezier(0.2, 0, 0, 1);opacity:0}.disabled .icon{transition:none}.selected .icon--on,.unselected .icon--off{opacity:1}.unselected .handle:not(.with-icon) .icon--on{transform:rotate(-45deg)}.icon--off{width:var(--md-switch-icon-size, 16px);height:var(--md-switch-icon-size, 16px);color:var(--md-switch-icon-color, var(--md-sys-color-surface-container-highest, #e6e0e9))}.unselected:hover .icon--off{color:var(--md-switch-hover-icon-color, var(--md-sys-color-surface-container-highest, #e6e0e9))}.unselected:focus-within .icon--off{color:var(--md-switch-focus-icon-color, var(--md-sys-color-surface-container-highest, #e6e0e9))}.unselected:active .icon--off{color:var(--md-switch-pressed-icon-color, var(--md-sys-color-surface-container-highest, #e6e0e9))}.unselected.disabled .icon--off{color:var(--md-switch-disabled-icon-color, var(--md-sys-color-surface-container-highest, #e6e0e9));opacity:var(--md-switch-disabled-icon-opacity, 0.38)}.icon--on{width:var(--md-switch-selected-icon-size, 16px);height:var(--md-switch-selected-icon-size, 16px);color:var(--md-switch-selected-icon-color, var(--md-sys-color-on-primary-container, #21005d))}.selected:hover .icon--on{color:var(--md-switch-selected-hover-icon-color, var(--md-sys-color-on-primary-container, #21005d))}.selected:focus-within .icon--on{color:var(--md-switch-selected-focus-icon-color, var(--md-sys-color-on-primary-container, #21005d))}.selected:active .icon--on{color:var(--md-switch-selected-pressed-icon-color, var(--md-sys-color-on-primary-container, #21005d))}.selected.disabled .icon--on{color:var(--md-switch-disabled-selected-icon-color, var(--md-sys-color-on-surface, #1d1b20));opacity:var(--md-switch-disabled-selected-icon-opacity, 0.38)}}@layer hcm{@media(forced-colors: active){.icon--off{fill:Canvas}.icon--on{fill:ButtonText}.disabled.unselected .icon--off,.disabled.selected .icon--on{opacity:1}.disabled .icon--on{fill:GrayText}}} +`;let Ut=class extends ve{};Ut.styles=[ya],Ut=o([b("md-switch")],Ut);const ho=Symbol("animateIndicator"),ga=ro(_);class Q extends ga{get selected(){return this.active}set selected(e){this.active=e}constructor(){super(),this.isTab=!0,this.active=!1,this.hasIcon=!1,this.iconOnly=!1,this.fullWidthIndicator=!1,this.internals=this.attachInternals(),T||(this.internals.role="tab",this.addEventListener("keydown",this.handleKeydown.bind(this)))}render(){const e=d`
    `;return d``}getContentClasses(){return{"has-icon":this.hasIcon,"has-label":!this.iconOnly}}updated(){this.internals.ariaSelected=String(this.active)}async handleKeydown(e){await 0,!e.defaultPrevented&&(e.key==="Enter"||e.key===" ")&&(e.preventDefault(),this.click())}handleContentClick(e){e.stopPropagation(),this.click()}[ho](e){if(!this.indicator)return;this.indicator.getAnimations().forEach(r=>{r.cancel()});const t=this.getKeyframes(e);t!==null&&this.indicator.animate(t,{duration:250,easing:Z.EMPHASIZED})}getKeyframes(e){const t=xa();if(!this.active)return t?[{opacity:1},{transform:"none"}]:null;const r={},a=e.indicator?.getBoundingClientRect()??{},n=a.left,s=a.width,h=this.indicator.getBoundingClientRect(),p=h.left,y=h.width,u=s/y;return!t&&n!==void 0&&p!==void 0&&!isNaN(u)?r.transform=`translateX(${(n-p).toFixed(4)}px) scaleX(${u.toFixed(4)})`:r.opacity=0,[r,{transform:"none"}]}handleSlotChange(){this.iconOnly=!1;for(const e of this.assignedDefaultNodes){const t=e.nodeType===Node.TEXT_NODE&&!!e.wholeText.match(/\S/);if(e.nodeType===Node.ELEMENT_NODE||t)return}this.iconOnly=!0}handleIconSlotChange(){this.hasIcon=this.assignedIcons.length>0}}o([l({type:Boolean,reflect:!0,attribute:"md-tab"})],Q.prototype,"isTab",void 0),o([l({type:Boolean,reflect:!0})],Q.prototype,"active",void 0),o([l({type:Boolean})],Q.prototype,"selected",null),o([l({type:Boolean,attribute:"has-icon"})],Q.prototype,"hasIcon",void 0),o([l({type:Boolean,attribute:"icon-only"})],Q.prototype,"iconOnly",void 0),o([g(".indicator")],Q.prototype,"indicator",void 0),o([k()],Q.prototype,"fullWidthIndicator",void 0),o([Qt({flatten:!0})],Q.prototype,"assignedDefaultNodes",void 0),o([H({slot:"icon",flatten:!0})],Q.prototype,"assignedIcons",void 0);function xa(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}class po extends Q{constructor(){super(...arguments),this.inlineIcon=!1}getContentClasses(){return{...super.getContentClasses(),stacked:!this.inlineIcon}}}o([l({type:Boolean,attribute:"inline-icon"})],po.prototype,"inlineIcon",void 0);const _a=v`:host{--_active-indicator-color: var(--md-primary-tab-active-indicator-color, var(--md-sys-color-primary, #6750a4));--_active-indicator-height: var(--md-primary-tab-active-indicator-height, 3px);--_active-indicator-shape: var(--md-primary-tab-active-indicator-shape, 3px 3px 0px 0px);--_active-hover-state-layer-color: var(--md-primary-tab-active-hover-state-layer-color, var(--md-sys-color-primary, #6750a4));--_active-hover-state-layer-opacity: var(--md-primary-tab-active-hover-state-layer-opacity, 0.08);--_active-pressed-state-layer-color: var(--md-primary-tab-active-pressed-state-layer-color, var(--md-sys-color-primary, #6750a4));--_active-pressed-state-layer-opacity: var(--md-primary-tab-active-pressed-state-layer-opacity, 0.12);--_container-color: var(--md-primary-tab-container-color, var(--md-sys-color-surface, #fef7ff));--_container-elevation: var(--md-primary-tab-container-elevation, 0);--_container-height: var(--md-primary-tab-container-height, 48px);--_with-icon-and-label-text-container-height: var(--md-primary-tab-with-icon-and-label-text-container-height, 64px);--_hover-state-layer-color: var(--md-primary-tab-hover-state-layer-color, var(--md-sys-color-on-surface, #1d1b20));--_hover-state-layer-opacity: var(--md-primary-tab-hover-state-layer-opacity, 0.08);--_pressed-state-layer-color: var(--md-primary-tab-pressed-state-layer-color, var(--md-sys-color-primary, #6750a4));--_pressed-state-layer-opacity: var(--md-primary-tab-pressed-state-layer-opacity, 0.12);--_active-focus-icon-color: var(--md-primary-tab-active-focus-icon-color, var(--md-sys-color-primary, #6750a4));--_active-hover-icon-color: var(--md-primary-tab-active-hover-icon-color, var(--md-sys-color-primary, #6750a4));--_active-icon-color: var(--md-primary-tab-active-icon-color, var(--md-sys-color-primary, #6750a4));--_active-pressed-icon-color: var(--md-primary-tab-active-pressed-icon-color, var(--md-sys-color-primary, #6750a4));--_icon-size: var(--md-primary-tab-icon-size, 24px);--_focus-icon-color: var(--md-primary-tab-focus-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_hover-icon-color: var(--md-primary-tab-hover-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_icon-color: var(--md-primary-tab-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_pressed-icon-color: var(--md-primary-tab-pressed-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_label-text-font: var(--md-primary-tab-label-text-font, var(--md-sys-typescale-title-small-font, var(--md-ref-typeface-plain, Roboto)));--_label-text-line-height: var(--md-primary-tab-label-text-line-height, var(--md-sys-typescale-title-small-line-height, 1.25rem));--_label-text-size: var(--md-primary-tab-label-text-size, var(--md-sys-typescale-title-small-size, 0.875rem));--_label-text-weight: var(--md-primary-tab-label-text-weight, var(--md-sys-typescale-title-small-weight, var(--md-ref-typeface-weight-medium, 500)));--_active-focus-label-text-color: var(--md-primary-tab-active-focus-label-text-color, var(--md-sys-color-primary, #6750a4));--_active-hover-label-text-color: var(--md-primary-tab-active-hover-label-text-color, var(--md-sys-color-primary, #6750a4));--_active-label-text-color: var(--md-primary-tab-active-label-text-color, var(--md-sys-color-primary, #6750a4));--_active-pressed-label-text-color: var(--md-primary-tab-active-pressed-label-text-color, var(--md-sys-color-primary, #6750a4));--_focus-label-text-color: var(--md-primary-tab-focus-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_hover-label-text-color: var(--md-primary-tab-hover-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_label-text-color: var(--md-primary-tab-label-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_pressed-label-text-color: var(--md-primary-tab-pressed-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_container-shape-start-start: var(--md-primary-tab-container-shape-start-start, var(--md-primary-tab-container-shape, var(--md-sys-shape-corner-none, 0px)));--_container-shape-start-end: var(--md-primary-tab-container-shape-start-end, var(--md-primary-tab-container-shape, var(--md-sys-shape-corner-none, 0px)));--_container-shape-end-end: var(--md-primary-tab-container-shape-end-end, var(--md-primary-tab-container-shape, var(--md-sys-shape-corner-none, 0px)));--_container-shape-end-start: var(--md-primary-tab-container-shape-end-start, var(--md-primary-tab-container-shape, var(--md-sys-shape-corner-none, 0px)))}.content.stacked{flex-direction:column;gap:2px}.content.stacked.has-icon.has-label{height:var(--_with-icon-and-label-text-container-height)} +`;const vo=v`:host{display:inline-flex;align-items:center;justify-content:center;outline:none;padding:0 16px;position:relative;-webkit-tap-highlight-color:rgba(0,0,0,0);vertical-align:middle;user-select:none;font-family:var(--_label-text-font);font-size:var(--_label-text-size);line-height:var(--_label-text-line-height);font-weight:var(--_label-text-weight);color:var(--_label-text-color);z-index:0;--md-ripple-hover-color: var(--_hover-state-layer-color);--md-ripple-hover-opacity: var(--_hover-state-layer-opacity);--md-ripple-pressed-color: var(--_pressed-state-layer-color);--md-ripple-pressed-opacity: var(--_pressed-state-layer-opacity);--md-elevation-level: var(--_container-elevation)}md-focus-ring{--md-focus-ring-shape: 8px}:host([active]) md-focus-ring{margin-bottom:calc(var(--_active-indicator-height) + 1px)}.button::before{background:var(--_container-color);content:"";inset:0;position:absolute;z-index:-1}.button::before,md-ripple,md-elevation{border-start-start-radius:var(--_container-shape-start-start);border-start-end-radius:var(--_container-shape-start-end);border-end-end-radius:var(--_container-shape-end-end);border-end-start-radius:var(--_container-shape-end-start)}.content{position:relative;box-sizing:border-box;display:inline-flex;flex-direction:row;align-items:center;justify-content:center;height:var(--_container-height);gap:8px}.indicator{position:absolute;box-sizing:border-box;z-index:-1;transform-origin:bottom left;background:var(--_active-indicator-color);border-radius:var(--_active-indicator-shape);height:var(--_active-indicator-height);inset:auto 0 0 0;opacity:0}::slotted([slot=icon]){display:inline-flex;position:relative;writing-mode:horizontal-tb;fill:currentColor;color:var(--_icon-color);font-size:var(--_icon-size);width:var(--_icon-size);height:var(--_icon-size)}:host(:hover){color:var(--_hover-label-text-color);cursor:pointer}:host(:hover) ::slotted([slot=icon]){color:var(--_hover-icon-color)}:host(:focus){color:var(--_focus-label-text-color)}:host(:focus) ::slotted([slot=icon]){color:var(--_focus-icon-color)}:host(:active){color:var(--_pressed-label-text-color)}:host(:active) ::slotted([slot=icon]){color:var(--_pressed-icon-color)}:host([active]) .indicator{opacity:1}:host([active]){color:var(--_active-label-text-color);--md-ripple-hover-color: var(--_active-hover-state-layer-color);--md-ripple-hover-opacity: var(--_active-hover-state-layer-opacity);--md-ripple-pressed-color: var(--_active-pressed-state-layer-color);--md-ripple-pressed-opacity: var(--_active-pressed-state-layer-opacity)}:host([active]) ::slotted([slot=icon]){color:var(--_active-icon-color)}:host([active]:hover){color:var(--_active-hover-label-text-color)}:host([active]:hover) ::slotted([slot=icon]){color:var(--_active-hover-icon-color)}:host([active]:focus){color:var(--_active-focus-label-text-color)}:host([active]:focus) ::slotted([slot=icon]){color:var(--_active-focus-icon-color)}:host([active]:active){color:var(--_active-pressed-label-text-color)}:host([active]:active) ::slotted([slot=icon]){color:var(--_active-pressed-icon-color)}:host,::slotted(*){white-space:nowrap}@media(forced-colors: active){.indicator{background:CanvasText}} +`;let Kt=class extends po{};Kt.styles=[vo,_a],Kt=o([b("md-primary-tab")],Kt);class wa extends Q{constructor(){super(...arguments),this.fullWidthIndicator=!0}}const ka=v`:host{--_active-indicator-color: var(--md-secondary-tab-active-indicator-color, var(--md-sys-color-primary, #6750a4));--_active-indicator-height: var(--md-secondary-tab-active-indicator-height, 2px);--_active-label-text-color: var(--md-secondary-tab-active-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_container-color: var(--md-secondary-tab-container-color, var(--md-sys-color-surface, #fef7ff));--_container-elevation: var(--md-secondary-tab-container-elevation, 0);--_container-height: var(--md-secondary-tab-container-height, 48px);--_focus-label-text-color: var(--md-secondary-tab-focus-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_hover-label-text-color: var(--md-secondary-tab-hover-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_hover-state-layer-color: var(--md-secondary-tab-hover-state-layer-color, var(--md-sys-color-on-surface, #1d1b20));--_hover-state-layer-opacity: var(--md-secondary-tab-hover-state-layer-opacity, 0.08);--_label-text-font: var(--md-secondary-tab-label-text-font, var(--md-sys-typescale-title-small-font, var(--md-ref-typeface-plain, Roboto)));--_label-text-line-height: var(--md-secondary-tab-label-text-line-height, var(--md-sys-typescale-title-small-line-height, 1.25rem));--_label-text-size: var(--md-secondary-tab-label-text-size, var(--md-sys-typescale-title-small-size, 0.875rem));--_label-text-weight: var(--md-secondary-tab-label-text-weight, var(--md-sys-typescale-title-small-weight, var(--md-ref-typeface-weight-medium, 500)));--_pressed-label-text-color: var(--md-secondary-tab-pressed-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_pressed-state-layer-color: var(--md-secondary-tab-pressed-state-layer-color, var(--md-sys-color-on-surface, #1d1b20));--_pressed-state-layer-opacity: var(--md-secondary-tab-pressed-state-layer-opacity, 0.12);--_active-focus-icon-color: var(--md-secondary-tab-active-focus-icon-color, );--_active-focus-label-text-color: var(--md-secondary-tab-active-focus-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_active-hover-icon-color: var(--md-secondary-tab-active-hover-icon-color, );--_active-hover-label-text-color: var(--md-secondary-tab-active-hover-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_active-hover-state-layer-color: var(--md-secondary-tab-active-hover-state-layer-color, var(--md-sys-color-on-surface, #1d1b20));--_active-hover-state-layer-opacity: var(--md-secondary-tab-active-hover-state-layer-opacity, 0.08);--_active-icon-color: var(--md-secondary-tab-active-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_active-indicator-shape: var(--md-secondary-tab-active-indicator-shape, 0);--_active-pressed-icon-color: var(--md-secondary-tab-active-pressed-icon-color, );--_active-pressed-label-text-color: var(--md-secondary-tab-active-pressed-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_active-pressed-state-layer-color: var(--md-secondary-tab-active-pressed-state-layer-color, var(--md-sys-color-on-surface, #1d1b20));--_active-pressed-state-layer-opacity: var(--md-secondary-tab-active-pressed-state-layer-opacity, 0.12);--_label-text-color: var(--md-secondary-tab-label-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_focus-icon-color: var(--md-secondary-tab-focus-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_hover-icon-color: var(--md-secondary-tab-hover-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_icon-size: var(--md-secondary-tab-icon-size, 24px);--_icon-color: var(--md-secondary-tab-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_pressed-icon-color: var(--md-secondary-tab-pressed-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_container-shape-start-start: var(--md-secondary-tab-container-shape-start-start, var(--md-secondary-tab-container-shape, var(--md-sys-shape-corner-none, 0px)));--_container-shape-start-end: var(--md-secondary-tab-container-shape-start-end, var(--md-secondary-tab-container-shape, var(--md-sys-shape-corner-none, 0px)));--_container-shape-end-end: var(--md-secondary-tab-container-shape-end-end, var(--md-secondary-tab-container-shape, var(--md-sys-shape-corner-none, 0px)));--_container-shape-end-start: var(--md-secondary-tab-container-shape-end-start, var(--md-secondary-tab-container-shape, var(--md-sys-shape-corner-none, 0px)))} +`;let Wt=class extends wa{};Wt.styles=[vo,ka],Wt=o([b("md-secondary-tab")],Wt);class Te extends _{get activeTab(){return this.tabs.find(e=>e.active)??null}set activeTab(e){e&&this.activateTab(e)}get activeTabIndex(){return this.tabs.findIndex(e=>e.active)}set activeTabIndex(e){const t=()=>{const r=this.tabs[e];r&&this.activateTab(r)};if(!this.slotElement){this.updateComplete.then(t);return}t()}get focusedTab(){return this.tabs.find(e=>e.matches(":focus-within"))}constructor(){super(),this.autoActivate=!1,this.internals=this.attachInternals(),T||(this.internals.role="tablist",this.addEventListener("keydown",this.handleKeydown.bind(this)),this.addEventListener("keyup",this.handleKeyup.bind(this)),this.addEventListener("focusout",this.handleFocusout.bind(this)))}async scrollToTab(e){await this.updateComplete;const{tabs:t}=this;if(e??=this.activeTab,!e||!t.includes(e)||!this.tabsScrollerElement)return;for(const m of this.tabs)await m.updateComplete;const r=e.offsetLeft,a=e.offsetWidth,n=this.scrollLeft,s=this.offsetWidth,h=48,p=r-h,y=r+a-s+h,u=Math.min(p,Math.max(y,n)),f=this.focusedTab?"auto":"instant";this.tabsScrollerElement.scrollTo({behavior:f,top:0,left:u})}render(){return d` +
    + +
    + + `}async handleTabClick(e){const t=e.target;await 0,!(e.defaultPrevented||!Ca(t)||t.active)&&this.activateTab(t)}activateTab(e){const{tabs:t}=this,r=this.activeTab;if(!(!t.includes(e)||r===e)){for(const a of t)a.active=a===e;if(r){if(!this.dispatchEvent(new Event("change",{bubbles:!0,cancelable:!0}))){for(const n of t)n.active=n===r;return}e[ho](r)}this.updateFocusableTab(e),this.scrollToTab(e)}}updateFocusableTab(e){for(const t of this.tabs)t.tabIndex=t===e?0:-1}async handleKeydown(e){await 0;const t=e.key==="ArrowLeft",r=e.key==="ArrowRight",a=e.key==="Home",n=e.key==="End";if(e.defaultPrevented||!t&&!r&&!a&&!n)return;const{tabs:s}=this;if(s.length<2)return;e.preventDefault();let h;if(a||n)h=a?0:s.length-1;else{const u=getComputedStyle(this).direction==="rtl"?t:r,{focusedTab:f}=this;if(!f)h=u?0:s.length-1;else{const m=this.tabs.indexOf(f);h=u?m+1:m-1,h>=s.length?h=0:h<0&&(h=s.length-1)}}const p=s[h];p.focus(),this.autoActivate?this.activateTab(p):this.updateFocusableTab(p)}handleKeyup(){this.scrollToTab(this.focusedTab??this.activeTab)}handleFocusout(){if(this.matches(":focus-within"))return;const{activeTab:e}=this;e&&this.updateFocusableTab(e)}handleSlotChange(){const e=this.tabs[0];!this.activeTab&&e&&this.activateTab(e),this.scrollToTab(this.activeTab)}}o([H({flatten:!0,selector:"[md-tab]"})],Te.prototype,"tabs",void 0),o([l({type:Number,attribute:"active-tab-index"})],Te.prototype,"activeTabIndex",null),o([l({type:Boolean,attribute:"auto-activate"})],Te.prototype,"autoActivate",void 0),o([g(".tabs")],Te.prototype,"tabsScrollerElement",void 0),o([g("slot")],Te.prototype,"slotElement",void 0);function Ca(i){return i instanceof HTMLElement&&i.hasAttribute("md-tab")}const Ea=v`:host{box-sizing:border-box;display:flex;flex-direction:column;overflow:auto;scroll-behavior:smooth;scrollbar-width:none;position:relative}:host([hidden]){display:none}:host::-webkit-scrollbar{display:none}.tabs{align-items:end;display:flex;height:100%;overflow:inherit;scroll-behavior:inherit;scrollbar-width:inherit;justify-content:space-between;width:100%}::slotted(*){flex:1}::slotted([active]){z-index:1} +`;let Gt=class extends Te{};Gt.styles=[Ea],Gt=o([b("md-tabs")],Gt);const Ia=v`:host{--_active-indicator-color: var(--md-filled-text-field-active-indicator-color, var(--md-sys-color-on-surface-variant, #49454f));--_active-indicator-height: var(--md-filled-text-field-active-indicator-height, 1px);--_caret-color: var(--md-filled-text-field-caret-color, var(--md-sys-color-primary, #6750a4));--_container-color: var(--md-filled-text-field-container-color, var(--md-sys-color-surface-container-highest, #e6e0e9));--_disabled-active-indicator-color: var(--md-filled-text-field-disabled-active-indicator-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-active-indicator-height: var(--md-filled-text-field-disabled-active-indicator-height, 1px);--_disabled-active-indicator-opacity: var(--md-filled-text-field-disabled-active-indicator-opacity, 0.38);--_disabled-container-color: var(--md-filled-text-field-disabled-container-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-container-opacity: var(--md-filled-text-field-disabled-container-opacity, 0.04);--_disabled-input-text-color: var(--md-filled-text-field-disabled-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-input-text-opacity: var(--md-filled-text-field-disabled-input-text-opacity, 0.38);--_disabled-label-text-color: var(--md-filled-text-field-disabled-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-label-text-opacity: var(--md-filled-text-field-disabled-label-text-opacity, 0.38);--_disabled-leading-icon-color: var(--md-filled-text-field-disabled-leading-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-leading-icon-opacity: var(--md-filled-text-field-disabled-leading-icon-opacity, 0.38);--_disabled-supporting-text-color: var(--md-filled-text-field-disabled-supporting-text-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-supporting-text-opacity: var(--md-filled-text-field-disabled-supporting-text-opacity, 0.38);--_disabled-trailing-icon-color: var(--md-filled-text-field-disabled-trailing-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-trailing-icon-opacity: var(--md-filled-text-field-disabled-trailing-icon-opacity, 0.38);--_error-active-indicator-color: var(--md-filled-text-field-error-active-indicator-color, var(--md-sys-color-error, #b3261e));--_error-focus-active-indicator-color: var(--md-filled-text-field-error-focus-active-indicator-color, var(--md-sys-color-error, #b3261e));--_error-focus-caret-color: var(--md-filled-text-field-error-focus-caret-color, var(--md-sys-color-error, #b3261e));--_error-focus-input-text-color: var(--md-filled-text-field-error-focus-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_error-focus-label-text-color: var(--md-filled-text-field-error-focus-label-text-color, var(--md-sys-color-error, #b3261e));--_error-focus-leading-icon-color: var(--md-filled-text-field-error-focus-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_error-focus-supporting-text-color: var(--md-filled-text-field-error-focus-supporting-text-color, var(--md-sys-color-error, #b3261e));--_error-focus-trailing-icon-color: var(--md-filled-text-field-error-focus-trailing-icon-color, var(--md-sys-color-error, #b3261e));--_error-hover-active-indicator-color: var(--md-filled-text-field-error-hover-active-indicator-color, var(--md-sys-color-on-error-container, #410e0b));--_error-hover-input-text-color: var(--md-filled-text-field-error-hover-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_error-hover-label-text-color: var(--md-filled-text-field-error-hover-label-text-color, var(--md-sys-color-on-error-container, #410e0b));--_error-hover-leading-icon-color: var(--md-filled-text-field-error-hover-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_error-hover-state-layer-color: var(--md-filled-text-field-error-hover-state-layer-color, var(--md-sys-color-on-surface, #1d1b20));--_error-hover-state-layer-opacity: var(--md-filled-text-field-error-hover-state-layer-opacity, 0.08);--_error-hover-supporting-text-color: var(--md-filled-text-field-error-hover-supporting-text-color, var(--md-sys-color-error, #b3261e));--_error-hover-trailing-icon-color: var(--md-filled-text-field-error-hover-trailing-icon-color, var(--md-sys-color-on-error-container, #410e0b));--_error-input-text-color: var(--md-filled-text-field-error-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_error-label-text-color: var(--md-filled-text-field-error-label-text-color, var(--md-sys-color-error, #b3261e));--_error-leading-icon-color: var(--md-filled-text-field-error-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_error-supporting-text-color: var(--md-filled-text-field-error-supporting-text-color, var(--md-sys-color-error, #b3261e));--_error-trailing-icon-color: var(--md-filled-text-field-error-trailing-icon-color, var(--md-sys-color-error, #b3261e));--_focus-active-indicator-color: var(--md-filled-text-field-focus-active-indicator-color, var(--md-sys-color-primary, #6750a4));--_focus-active-indicator-height: var(--md-filled-text-field-focus-active-indicator-height, 3px);--_focus-input-text-color: var(--md-filled-text-field-focus-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_focus-label-text-color: var(--md-filled-text-field-focus-label-text-color, var(--md-sys-color-primary, #6750a4));--_focus-leading-icon-color: var(--md-filled-text-field-focus-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_focus-supporting-text-color: var(--md-filled-text-field-focus-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_focus-trailing-icon-color: var(--md-filled-text-field-focus-trailing-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-active-indicator-color: var(--md-filled-text-field-hover-active-indicator-color, var(--md-sys-color-on-surface, #1d1b20));--_hover-active-indicator-height: var(--md-filled-text-field-hover-active-indicator-height, 1px);--_hover-input-text-color: var(--md-filled-text-field-hover-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_hover-label-text-color: var(--md-filled-text-field-hover-label-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-leading-icon-color: var(--md-filled-text-field-hover-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-state-layer-color: var(--md-filled-text-field-hover-state-layer-color, var(--md-sys-color-on-surface, #1d1b20));--_hover-state-layer-opacity: var(--md-filled-text-field-hover-state-layer-opacity, 0.08);--_hover-supporting-text-color: var(--md-filled-text-field-hover-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-trailing-icon-color: var(--md-filled-text-field-hover-trailing-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_input-text-color: var(--md-filled-text-field-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_input-text-font: var(--md-filled-text-field-input-text-font, var(--md-sys-typescale-body-large-font, var(--md-ref-typeface-plain, Roboto)));--_input-text-line-height: var(--md-filled-text-field-input-text-line-height, var(--md-sys-typescale-body-large-line-height, 1.5rem));--_input-text-placeholder-color: var(--md-filled-text-field-input-text-placeholder-color, var(--md-sys-color-on-surface-variant, #49454f));--_input-text-prefix-color: var(--md-filled-text-field-input-text-prefix-color, var(--md-sys-color-on-surface-variant, #49454f));--_input-text-size: var(--md-filled-text-field-input-text-size, var(--md-sys-typescale-body-large-size, 1rem));--_input-text-suffix-color: var(--md-filled-text-field-input-text-suffix-color, var(--md-sys-color-on-surface-variant, #49454f));--_input-text-weight: var(--md-filled-text-field-input-text-weight, var(--md-sys-typescale-body-large-weight, var(--md-ref-typeface-weight-regular, 400)));--_label-text-color: var(--md-filled-text-field-label-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_label-text-font: var(--md-filled-text-field-label-text-font, var(--md-sys-typescale-body-large-font, var(--md-ref-typeface-plain, Roboto)));--_label-text-line-height: var(--md-filled-text-field-label-text-line-height, var(--md-sys-typescale-body-large-line-height, 1.5rem));--_label-text-populated-line-height: var(--md-filled-text-field-label-text-populated-line-height, var(--md-sys-typescale-body-small-line-height, 1rem));--_label-text-populated-size: var(--md-filled-text-field-label-text-populated-size, var(--md-sys-typescale-body-small-size, 0.75rem));--_label-text-size: var(--md-filled-text-field-label-text-size, var(--md-sys-typescale-body-large-size, 1rem));--_label-text-weight: var(--md-filled-text-field-label-text-weight, var(--md-sys-typescale-body-large-weight, var(--md-ref-typeface-weight-regular, 400)));--_leading-icon-color: var(--md-filled-text-field-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_leading-icon-size: var(--md-filled-text-field-leading-icon-size, 24px);--_supporting-text-color: var(--md-filled-text-field-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_supporting-text-font: var(--md-filled-text-field-supporting-text-font, var(--md-sys-typescale-body-small-font, var(--md-ref-typeface-plain, Roboto)));--_supporting-text-line-height: var(--md-filled-text-field-supporting-text-line-height, var(--md-sys-typescale-body-small-line-height, 1rem));--_supporting-text-size: var(--md-filled-text-field-supporting-text-size, var(--md-sys-typescale-body-small-size, 0.75rem));--_supporting-text-weight: var(--md-filled-text-field-supporting-text-weight, var(--md-sys-typescale-body-small-weight, var(--md-ref-typeface-weight-regular, 400)));--_trailing-icon-color: var(--md-filled-text-field-trailing-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_trailing-icon-size: var(--md-filled-text-field-trailing-icon-size, 24px);--_container-shape-start-start: var(--md-filled-text-field-container-shape-start-start, var(--md-filled-text-field-container-shape, var(--md-sys-shape-corner-extra-small, 4px)));--_container-shape-start-end: var(--md-filled-text-field-container-shape-start-end, var(--md-filled-text-field-container-shape, var(--md-sys-shape-corner-extra-small, 4px)));--_container-shape-end-end: var(--md-filled-text-field-container-shape-end-end, var(--md-filled-text-field-container-shape, var(--md-sys-shape-corner-none, 0px)));--_container-shape-end-start: var(--md-filled-text-field-container-shape-end-start, var(--md-filled-text-field-container-shape, var(--md-sys-shape-corner-none, 0px)));--_icon-input-space: var(--md-filled-text-field-icon-input-space, 16px);--_leading-space: var(--md-filled-text-field-leading-space, 16px);--_trailing-space: var(--md-filled-text-field-trailing-space, 16px);--_top-space: var(--md-filled-text-field-top-space, 16px);--_bottom-space: var(--md-filled-text-field-bottom-space, 16px);--_input-text-prefix-trailing-space: var(--md-filled-text-field-input-text-prefix-trailing-space, 2px);--_input-text-suffix-leading-space: var(--md-filled-text-field-input-text-suffix-leading-space, 2px);--_with-label-top-space: var(--md-filled-text-field-with-label-top-space, 8px);--_with-label-bottom-space: var(--md-filled-text-field-with-label-bottom-space, 8px);--_focus-caret-color: var(--md-filled-text-field-focus-caret-color, var(--md-sys-color-primary, #6750a4));--_with-leading-icon-leading-space: var(--md-filled-text-field-with-leading-icon-leading-space, 12px);--_with-trailing-icon-trailing-space: var(--md-filled-text-field-with-trailing-icon-trailing-space, 12px);--md-filled-field-active-indicator-color: var(--_active-indicator-color);--md-filled-field-active-indicator-height: var(--_active-indicator-height);--md-filled-field-bottom-space: var(--_bottom-space);--md-filled-field-container-color: var(--_container-color);--md-filled-field-container-shape-end-end: var(--_container-shape-end-end);--md-filled-field-container-shape-end-start: var(--_container-shape-end-start);--md-filled-field-container-shape-start-end: var(--_container-shape-start-end);--md-filled-field-container-shape-start-start: var(--_container-shape-start-start);--md-filled-field-content-color: var(--_input-text-color);--md-filled-field-content-font: var(--_input-text-font);--md-filled-field-content-line-height: var(--_input-text-line-height);--md-filled-field-content-size: var(--_input-text-size);--md-filled-field-content-space: var(--_icon-input-space);--md-filled-field-content-weight: var(--_input-text-weight);--md-filled-field-disabled-active-indicator-color: var(--_disabled-active-indicator-color);--md-filled-field-disabled-active-indicator-height: var(--_disabled-active-indicator-height);--md-filled-field-disabled-active-indicator-opacity: var(--_disabled-active-indicator-opacity);--md-filled-field-disabled-container-color: var(--_disabled-container-color);--md-filled-field-disabled-container-opacity: var(--_disabled-container-opacity);--md-filled-field-disabled-content-color: var(--_disabled-input-text-color);--md-filled-field-disabled-content-opacity: var(--_disabled-input-text-opacity);--md-filled-field-disabled-label-text-color: var(--_disabled-label-text-color);--md-filled-field-disabled-label-text-opacity: var(--_disabled-label-text-opacity);--md-filled-field-disabled-leading-content-color: var(--_disabled-leading-icon-color);--md-filled-field-disabled-leading-content-opacity: var(--_disabled-leading-icon-opacity);--md-filled-field-disabled-supporting-text-color: var(--_disabled-supporting-text-color);--md-filled-field-disabled-supporting-text-opacity: var(--_disabled-supporting-text-opacity);--md-filled-field-disabled-trailing-content-color: var(--_disabled-trailing-icon-color);--md-filled-field-disabled-trailing-content-opacity: var(--_disabled-trailing-icon-opacity);--md-filled-field-error-active-indicator-color: var(--_error-active-indicator-color);--md-filled-field-error-content-color: var(--_error-input-text-color);--md-filled-field-error-focus-active-indicator-color: var(--_error-focus-active-indicator-color);--md-filled-field-error-focus-content-color: var(--_error-focus-input-text-color);--md-filled-field-error-focus-label-text-color: var(--_error-focus-label-text-color);--md-filled-field-error-focus-leading-content-color: var(--_error-focus-leading-icon-color);--md-filled-field-error-focus-supporting-text-color: var(--_error-focus-supporting-text-color);--md-filled-field-error-focus-trailing-content-color: var(--_error-focus-trailing-icon-color);--md-filled-field-error-hover-active-indicator-color: var(--_error-hover-active-indicator-color);--md-filled-field-error-hover-content-color: var(--_error-hover-input-text-color);--md-filled-field-error-hover-label-text-color: var(--_error-hover-label-text-color);--md-filled-field-error-hover-leading-content-color: var(--_error-hover-leading-icon-color);--md-filled-field-error-hover-state-layer-color: var(--_error-hover-state-layer-color);--md-filled-field-error-hover-state-layer-opacity: var(--_error-hover-state-layer-opacity);--md-filled-field-error-hover-supporting-text-color: var(--_error-hover-supporting-text-color);--md-filled-field-error-hover-trailing-content-color: var(--_error-hover-trailing-icon-color);--md-filled-field-error-label-text-color: var(--_error-label-text-color);--md-filled-field-error-leading-content-color: var(--_error-leading-icon-color);--md-filled-field-error-supporting-text-color: var(--_error-supporting-text-color);--md-filled-field-error-trailing-content-color: var(--_error-trailing-icon-color);--md-filled-field-focus-active-indicator-color: var(--_focus-active-indicator-color);--md-filled-field-focus-active-indicator-height: var(--_focus-active-indicator-height);--md-filled-field-focus-content-color: var(--_focus-input-text-color);--md-filled-field-focus-label-text-color: var(--_focus-label-text-color);--md-filled-field-focus-leading-content-color: var(--_focus-leading-icon-color);--md-filled-field-focus-supporting-text-color: var(--_focus-supporting-text-color);--md-filled-field-focus-trailing-content-color: var(--_focus-trailing-icon-color);--md-filled-field-hover-active-indicator-color: var(--_hover-active-indicator-color);--md-filled-field-hover-active-indicator-height: var(--_hover-active-indicator-height);--md-filled-field-hover-content-color: var(--_hover-input-text-color);--md-filled-field-hover-label-text-color: var(--_hover-label-text-color);--md-filled-field-hover-leading-content-color: var(--_hover-leading-icon-color);--md-filled-field-hover-state-layer-color: var(--_hover-state-layer-color);--md-filled-field-hover-state-layer-opacity: var(--_hover-state-layer-opacity);--md-filled-field-hover-supporting-text-color: var(--_hover-supporting-text-color);--md-filled-field-hover-trailing-content-color: var(--_hover-trailing-icon-color);--md-filled-field-label-text-color: var(--_label-text-color);--md-filled-field-label-text-font: var(--_label-text-font);--md-filled-field-label-text-line-height: var(--_label-text-line-height);--md-filled-field-label-text-populated-line-height: var(--_label-text-populated-line-height);--md-filled-field-label-text-populated-size: var(--_label-text-populated-size);--md-filled-field-label-text-size: var(--_label-text-size);--md-filled-field-label-text-weight: var(--_label-text-weight);--md-filled-field-leading-content-color: var(--_leading-icon-color);--md-filled-field-leading-space: var(--_leading-space);--md-filled-field-supporting-text-color: var(--_supporting-text-color);--md-filled-field-supporting-text-font: var(--_supporting-text-font);--md-filled-field-supporting-text-line-height: var(--_supporting-text-line-height);--md-filled-field-supporting-text-size: var(--_supporting-text-size);--md-filled-field-supporting-text-weight: var(--_supporting-text-weight);--md-filled-field-top-space: var(--_top-space);--md-filled-field-trailing-content-color: var(--_trailing-icon-color);--md-filled-field-trailing-space: var(--_trailing-space);--md-filled-field-with-label-bottom-space: var(--_with-label-bottom-space);--md-filled-field-with-label-top-space: var(--_with-label-top-space);--md-filled-field-with-leading-content-leading-space: var(--_with-leading-icon-leading-space);--md-filled-field-with-trailing-content-trailing-space: var(--_with-trailing-icon-trailing-space)} +`;const Ta={fromAttribute(i){return i??""},toAttribute(i){return i||null}};class za extends Ze{computeValidity({state:e,renderedControl:t}){let r=t;Pe(e)&&!r?(r=this.inputControl||document.createElement("input"),this.inputControl=r):r||(r=this.textAreaControl||document.createElement("textarea"),this.textAreaControl=r);const a=Pe(e)?r:null;if(a&&(a.type=e.type),r.value!==e.value&&(r.value=e.value),r.required=e.required,a){const n=e;n.pattern?a.pattern=n.pattern:a.removeAttribute("pattern"),n.min?a.min=n.min:a.removeAttribute("min"),n.max?a.max=n.max:a.removeAttribute("max"),n.step?a.step=n.step:a.removeAttribute("step")}return(e.minLength??-1)>-1?r.setAttribute("minlength",String(e.minLength)):r.removeAttribute("minlength"),(e.maxLength??-1)>-1?r.setAttribute("maxlength",String(e.maxLength)):r.removeAttribute("maxlength"),{validity:r.validity,validationMessage:r.validationMessage}}equals({state:e},{state:t}){const r=e.type===t.type&&e.value===t.value&&e.required===t.required&&e.minLength===t.minLength&&e.maxLength===t.maxLength;return!Pe(e)||!Pe(t)?r:r&&e.pattern===t.pattern&&e.min===t.min&&e.max===t.max&&e.step===t.step}copy({state:e}){return{state:Pe(e)?this.copyInput(e):this.copyTextArea(e),renderedControl:null}}copyInput(e){const{type:t,pattern:r,min:a,max:n,step:s}=e;return{...this.copySharedState(e),type:t,pattern:r,min:a,max:n,step:s}}copyTextArea(e){return{...this.copySharedState(e),type:e.type}}copySharedState({value:e,required:t,minLength:r,maxLength:a}){return{value:e,required:t,minLength:r,maxLength:a}}}function Pe(i){return i.type!=="textarea"}const Aa=W(io(Re(we(se(_)))));class x extends Aa{constructor(){super(...arguments),this.error=!1,this.errorText="",this.label="",this.noAsterisk=!1,this.required=!1,this.value="",this.prefixText="",this.suffixText="",this.hasLeadingIcon=!1,this.hasTrailingIcon=!1,this.supportingText="",this.textDirection="",this.rows=2,this.cols=20,this.inputMode="",this.max="",this.maxLength=-1,this.min="",this.minLength=-1,this.noSpinner=!1,this.pattern="",this.placeholder="",this.readOnly=!1,this.multiple=!1,this.step="",this.type="text",this.autocomplete="",this.dirty=!1,this.focused=!1,this.nativeError=!1,this.nativeErrorText=""}get selectionDirection(){return this.getInputOrTextarea().selectionDirection}set selectionDirection(e){this.getInputOrTextarea().selectionDirection=e}get selectionEnd(){return this.getInputOrTextarea().selectionEnd}set selectionEnd(e){this.getInputOrTextarea().selectionEnd=e}get selectionStart(){return this.getInputOrTextarea().selectionStart}set selectionStart(e){this.getInputOrTextarea().selectionStart=e}get valueAsNumber(){const e=this.getInput();return e?e.valueAsNumber:NaN}set valueAsNumber(e){const t=this.getInput();t&&(t.valueAsNumber=e,this.value=t.value)}get valueAsDate(){const e=this.getInput();return e?e.valueAsDate:null}set valueAsDate(e){const t=this.getInput();t&&(t.valueAsDate=e,this.value=t.value)}get hasError(){return this.error||this.nativeError}select(){this.getInputOrTextarea().select()}setRangeText(...e){this.getInputOrTextarea().setRangeText(...e),this.value=this.getInputOrTextarea().value}setSelectionRange(e,t,r){this.getInputOrTextarea().setSelectionRange(e,t,r)}showPicker(){const e=this.getInput();e&&e.showPicker()}stepDown(e){const t=this.getInput();t&&(t.stepDown(e),this.value=t.value)}stepUp(e){const t=this.getInput();t&&(t.stepUp(e),this.value=t.value)}reset(){this.dirty=!1,this.value=this.getAttribute("value")??"",this.nativeError=!1,this.nativeErrorText=""}attributeChangedCallback(e,t,r){e==="value"&&this.dirty||super.attributeChangedCallback(e,t,r)}render(){const e={disabled:this.disabled,error:!this.disabled&&this.hasError,textarea:this.type==="textarea","no-spinner":this.noSpinner};return d` + + ${this.renderField()} + + `}updated(e){const t=this.getInputOrTextarea().value;this.value!==t&&(this.value=t)}renderField(){return ze`<${this.fieldTag} + class="field" + count=${this.value.length} + ?disabled=${this.disabled} + ?error=${this.hasError} + error-text=${this.getErrorText()} + ?focused=${this.focused} + ?has-end=${this.hasTrailingIcon} + ?has-start=${this.hasLeadingIcon} + label=${this.label} + ?no-asterisk=${this.noAsterisk} + max=${this.maxLength} + ?populated=${!!this.value} + ?required=${this.required} + ?resizable=${this.type==="textarea"} + supporting-text=${this.supportingText} + > + ${this.renderLeadingIcon()} + ${this.renderInputOrTextarea()} + ${this.renderTrailingIcon()} +
    + + `}renderLeadingIcon(){return d` + + + + `}renderTrailingIcon(){return d` + + + + `}renderInputOrTextarea(){const e={direction:this.textDirection},t=this.ariaLabel||this.label||c,r=this.autocomplete,a=(this.maxLength??-1)>-1,n=(this.minLength??-1)>-1;if(this.type==="textarea")return d` + + `;const s=this.renderPrefix(),h=this.renderSuffix(),p=this.inputMode;return d` +
    + ${s} + + ${h} +
    + `}renderPrefix(){return this.renderAffix(this.prefixText,!1)}renderSuffix(){return this.renderAffix(this.suffixText,!0)}renderAffix(e,t){return e?d`${e}`:c}getErrorText(){return this.error?this.errorText:this.nativeErrorText}handleFocusChange(){this.focused=this.inputOrTextarea?.matches(":focus")??!1}handleInput(e){this.dirty=!0,this.value=e.target.value}redispatchEvent(e){de(this,e)}getInputOrTextarea(){return this.inputOrTextarea||(this.connectedCallback(),this.scheduleUpdate()),this.isUpdatePending&&this.scheduleUpdate(),this.inputOrTextarea}getInput(){return this.type==="textarea"?null:this.getInputOrTextarea()}handleIconChange(){this.hasLeadingIcon=this.leadingIcons.length>0,this.hasTrailingIcon=this.trailingIcons.length>0}[ie](){return this.value}formResetCallback(){this.reset()}formStateRestoreCallback(e){this.value=e}focus(){this.getInputOrTextarea().focus()}[me](){return new za(()=>({state:this,renderedControl:this.inputOrTextarea}))}[be](){return this.inputOrTextarea}[Lt](e){e?.preventDefault();const t=this.getErrorText();this.nativeError=!!e,this.nativeErrorText=this.validationMessage,t===this.getErrorText()&&this.field?.reannounceError()}}x.shadowRootOptions={..._.shadowRootOptions,delegatesFocus:!0},o([l({type:Boolean,reflect:!0})],x.prototype,"error",void 0),o([l({attribute:"error-text"})],x.prototype,"errorText",void 0),o([l()],x.prototype,"label",void 0),o([l({type:Boolean,attribute:"no-asterisk"})],x.prototype,"noAsterisk",void 0),o([l({type:Boolean,reflect:!0})],x.prototype,"required",void 0),o([l()],x.prototype,"value",void 0),o([l({attribute:"prefix-text"})],x.prototype,"prefixText",void 0),o([l({attribute:"suffix-text"})],x.prototype,"suffixText",void 0),o([l({type:Boolean,attribute:"has-leading-icon"})],x.prototype,"hasLeadingIcon",void 0),o([l({type:Boolean,attribute:"has-trailing-icon"})],x.prototype,"hasTrailingIcon",void 0),o([l({attribute:"supporting-text"})],x.prototype,"supportingText",void 0),o([l({attribute:"text-direction"})],x.prototype,"textDirection",void 0),o([l({type:Number})],x.prototype,"rows",void 0),o([l({type:Number})],x.prototype,"cols",void 0),o([l({reflect:!0})],x.prototype,"inputMode",void 0),o([l()],x.prototype,"max",void 0),o([l({type:Number})],x.prototype,"maxLength",void 0),o([l()],x.prototype,"min",void 0),o([l({type:Number})],x.prototype,"minLength",void 0),o([l({type:Boolean,attribute:"no-spinner"})],x.prototype,"noSpinner",void 0),o([l()],x.prototype,"pattern",void 0),o([l({reflect:!0,converter:Ta})],x.prototype,"placeholder",void 0),o([l({type:Boolean,reflect:!0})],x.prototype,"readOnly",void 0),o([l({type:Boolean,reflect:!0})],x.prototype,"multiple",void 0),o([l()],x.prototype,"step",void 0),o([l({reflect:!0})],x.prototype,"type",void 0),o([l({reflect:!0})],x.prototype,"autocomplete",void 0),o([k()],x.prototype,"dirty",void 0),o([k()],x.prototype,"focused",void 0),o([k()],x.prototype,"nativeError",void 0),o([k()],x.prototype,"nativeErrorText",void 0),o([g(".input")],x.prototype,"inputOrTextarea",void 0),o([g(".field")],x.prototype,"field",void 0),o([H({slot:"leading-icon"})],x.prototype,"leadingIcons",void 0),o([H({slot:"trailing-icon"})],x.prototype,"trailingIcons",void 0);class Sa extends x{constructor(){super(...arguments),this.fieldTag=K`md-filled-field`}}const uo=v`:host{display:inline-flex;outline:none;resize:both;text-align:start;-webkit-tap-highlight-color:rgba(0,0,0,0)}.text-field,.field{width:100%}.text-field{display:inline-flex}.field{cursor:text}.disabled .field{cursor:default}.text-field,.textarea .field{resize:inherit}slot[name=container]{border-radius:inherit}.icon{color:currentColor;display:flex;align-items:center;justify-content:center;fill:currentColor;position:relative}.icon ::slotted(*){display:flex;position:absolute}[has-start] .icon.leading{font-size:var(--_leading-icon-size);height:var(--_leading-icon-size);width:var(--_leading-icon-size)}[has-end] .icon.trailing{font-size:var(--_trailing-icon-size);height:var(--_trailing-icon-size);width:var(--_trailing-icon-size)}.input-wrapper{display:flex}.input-wrapper>*{all:inherit;padding:0}.input{caret-color:var(--_caret-color);overflow-x:hidden;text-align:inherit}.input::placeholder{color:currentColor;opacity:1}.input::-webkit-calendar-picker-indicator{display:none}.input::-webkit-search-decoration,.input::-webkit-search-cancel-button{display:none}@media(forced-colors: active){.input{background:none}}.no-spinner .input::-webkit-inner-spin-button,.no-spinner .input::-webkit-outer-spin-button{display:none}.no-spinner .input[type=number]{-moz-appearance:textfield}:focus-within .input{caret-color:var(--_focus-caret-color)}.error:focus-within .input{caret-color:var(--_error-focus-caret-color)}.text-field:not(.disabled) .prefix{color:var(--_input-text-prefix-color)}.text-field:not(.disabled) .suffix{color:var(--_input-text-suffix-color)}.text-field:not(.disabled) .input::placeholder{color:var(--_input-text-placeholder-color)}.prefix,.suffix{text-wrap:nowrap;width:min-content}.prefix{padding-inline-end:var(--_input-text-prefix-trailing-space)}.suffix{padding-inline-start:var(--_input-text-suffix-leading-space)} +`;let Xt=class extends Sa{constructor(){super(...arguments),this.fieldTag=K`md-filled-field`}};Xt.styles=[uo,Ia],Xt=o([b("md-filled-text-field")],Xt);const $a=v`:host{--_caret-color: var(--md-outlined-text-field-caret-color, var(--md-sys-color-primary, #6750a4));--_disabled-input-text-color: var(--md-outlined-text-field-disabled-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-input-text-opacity: var(--md-outlined-text-field-disabled-input-text-opacity, 0.38);--_disabled-label-text-color: var(--md-outlined-text-field-disabled-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-label-text-opacity: var(--md-outlined-text-field-disabled-label-text-opacity, 0.38);--_disabled-leading-icon-color: var(--md-outlined-text-field-disabled-leading-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-leading-icon-opacity: var(--md-outlined-text-field-disabled-leading-icon-opacity, 0.38);--_disabled-outline-color: var(--md-outlined-text-field-disabled-outline-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-outline-opacity: var(--md-outlined-text-field-disabled-outline-opacity, 0.12);--_disabled-outline-width: var(--md-outlined-text-field-disabled-outline-width, 1px);--_disabled-supporting-text-color: var(--md-outlined-text-field-disabled-supporting-text-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-supporting-text-opacity: var(--md-outlined-text-field-disabled-supporting-text-opacity, 0.38);--_disabled-trailing-icon-color: var(--md-outlined-text-field-disabled-trailing-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-trailing-icon-opacity: var(--md-outlined-text-field-disabled-trailing-icon-opacity, 0.38);--_error-focus-caret-color: var(--md-outlined-text-field-error-focus-caret-color, var(--md-sys-color-error, #b3261e));--_error-focus-input-text-color: var(--md-outlined-text-field-error-focus-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_error-focus-label-text-color: var(--md-outlined-text-field-error-focus-label-text-color, var(--md-sys-color-error, #b3261e));--_error-focus-leading-icon-color: var(--md-outlined-text-field-error-focus-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_error-focus-outline-color: var(--md-outlined-text-field-error-focus-outline-color, var(--md-sys-color-error, #b3261e));--_error-focus-supporting-text-color: var(--md-outlined-text-field-error-focus-supporting-text-color, var(--md-sys-color-error, #b3261e));--_error-focus-trailing-icon-color: var(--md-outlined-text-field-error-focus-trailing-icon-color, var(--md-sys-color-error, #b3261e));--_error-hover-input-text-color: var(--md-outlined-text-field-error-hover-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_error-hover-label-text-color: var(--md-outlined-text-field-error-hover-label-text-color, var(--md-sys-color-on-error-container, #410e0b));--_error-hover-leading-icon-color: var(--md-outlined-text-field-error-hover-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_error-hover-outline-color: var(--md-outlined-text-field-error-hover-outline-color, var(--md-sys-color-on-error-container, #410e0b));--_error-hover-supporting-text-color: var(--md-outlined-text-field-error-hover-supporting-text-color, var(--md-sys-color-error, #b3261e));--_error-hover-trailing-icon-color: var(--md-outlined-text-field-error-hover-trailing-icon-color, var(--md-sys-color-on-error-container, #410e0b));--_error-input-text-color: var(--md-outlined-text-field-error-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_error-label-text-color: var(--md-outlined-text-field-error-label-text-color, var(--md-sys-color-error, #b3261e));--_error-leading-icon-color: var(--md-outlined-text-field-error-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_error-outline-color: var(--md-outlined-text-field-error-outline-color, var(--md-sys-color-error, #b3261e));--_error-supporting-text-color: var(--md-outlined-text-field-error-supporting-text-color, var(--md-sys-color-error, #b3261e));--_error-trailing-icon-color: var(--md-outlined-text-field-error-trailing-icon-color, var(--md-sys-color-error, #b3261e));--_focus-input-text-color: var(--md-outlined-text-field-focus-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_focus-label-text-color: var(--md-outlined-text-field-focus-label-text-color, var(--md-sys-color-primary, #6750a4));--_focus-leading-icon-color: var(--md-outlined-text-field-focus-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_focus-outline-color: var(--md-outlined-text-field-focus-outline-color, var(--md-sys-color-primary, #6750a4));--_focus-outline-width: var(--md-outlined-text-field-focus-outline-width, 3px);--_focus-supporting-text-color: var(--md-outlined-text-field-focus-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_focus-trailing-icon-color: var(--md-outlined-text-field-focus-trailing-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-input-text-color: var(--md-outlined-text-field-hover-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_hover-label-text-color: var(--md-outlined-text-field-hover-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_hover-leading-icon-color: var(--md-outlined-text-field-hover-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-outline-color: var(--md-outlined-text-field-hover-outline-color, var(--md-sys-color-on-surface, #1d1b20));--_hover-outline-width: var(--md-outlined-text-field-hover-outline-width, 1px);--_hover-supporting-text-color: var(--md-outlined-text-field-hover-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-trailing-icon-color: var(--md-outlined-text-field-hover-trailing-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_input-text-color: var(--md-outlined-text-field-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_input-text-font: var(--md-outlined-text-field-input-text-font, var(--md-sys-typescale-body-large-font, var(--md-ref-typeface-plain, Roboto)));--_input-text-line-height: var(--md-outlined-text-field-input-text-line-height, var(--md-sys-typescale-body-large-line-height, 1.5rem));--_input-text-placeholder-color: var(--md-outlined-text-field-input-text-placeholder-color, var(--md-sys-color-on-surface-variant, #49454f));--_input-text-prefix-color: var(--md-outlined-text-field-input-text-prefix-color, var(--md-sys-color-on-surface-variant, #49454f));--_input-text-size: var(--md-outlined-text-field-input-text-size, var(--md-sys-typescale-body-large-size, 1rem));--_input-text-suffix-color: var(--md-outlined-text-field-input-text-suffix-color, var(--md-sys-color-on-surface-variant, #49454f));--_input-text-weight: var(--md-outlined-text-field-input-text-weight, var(--md-sys-typescale-body-large-weight, var(--md-ref-typeface-weight-regular, 400)));--_label-text-color: var(--md-outlined-text-field-label-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_label-text-font: var(--md-outlined-text-field-label-text-font, var(--md-sys-typescale-body-large-font, var(--md-ref-typeface-plain, Roboto)));--_label-text-line-height: var(--md-outlined-text-field-label-text-line-height, var(--md-sys-typescale-body-large-line-height, 1.5rem));--_label-text-populated-line-height: var(--md-outlined-text-field-label-text-populated-line-height, var(--md-sys-typescale-body-small-line-height, 1rem));--_label-text-populated-size: var(--md-outlined-text-field-label-text-populated-size, var(--md-sys-typescale-body-small-size, 0.75rem));--_label-text-size: var(--md-outlined-text-field-label-text-size, var(--md-sys-typescale-body-large-size, 1rem));--_label-text-weight: var(--md-outlined-text-field-label-text-weight, var(--md-sys-typescale-body-large-weight, var(--md-ref-typeface-weight-regular, 400)));--_leading-icon-color: var(--md-outlined-text-field-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_leading-icon-size: var(--md-outlined-text-field-leading-icon-size, 24px);--_outline-color: var(--md-outlined-text-field-outline-color, var(--md-sys-color-outline, #79747e));--_outline-width: var(--md-outlined-text-field-outline-width, 1px);--_supporting-text-color: var(--md-outlined-text-field-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_supporting-text-font: var(--md-outlined-text-field-supporting-text-font, var(--md-sys-typescale-body-small-font, var(--md-ref-typeface-plain, Roboto)));--_supporting-text-line-height: var(--md-outlined-text-field-supporting-text-line-height, var(--md-sys-typescale-body-small-line-height, 1rem));--_supporting-text-size: var(--md-outlined-text-field-supporting-text-size, var(--md-sys-typescale-body-small-size, 0.75rem));--_supporting-text-weight: var(--md-outlined-text-field-supporting-text-weight, var(--md-sys-typescale-body-small-weight, var(--md-ref-typeface-weight-regular, 400)));--_trailing-icon-color: var(--md-outlined-text-field-trailing-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_trailing-icon-size: var(--md-outlined-text-field-trailing-icon-size, 24px);--_container-shape-start-start: var(--md-outlined-text-field-container-shape-start-start, var(--md-outlined-text-field-container-shape, var(--md-sys-shape-corner-extra-small, 4px)));--_container-shape-start-end: var(--md-outlined-text-field-container-shape-start-end, var(--md-outlined-text-field-container-shape, var(--md-sys-shape-corner-extra-small, 4px)));--_container-shape-end-end: var(--md-outlined-text-field-container-shape-end-end, var(--md-outlined-text-field-container-shape, var(--md-sys-shape-corner-extra-small, 4px)));--_container-shape-end-start: var(--md-outlined-text-field-container-shape-end-start, var(--md-outlined-text-field-container-shape, var(--md-sys-shape-corner-extra-small, 4px)));--_icon-input-space: var(--md-outlined-text-field-icon-input-space, 16px);--_leading-space: var(--md-outlined-text-field-leading-space, 16px);--_trailing-space: var(--md-outlined-text-field-trailing-space, 16px);--_top-space: var(--md-outlined-text-field-top-space, 16px);--_bottom-space: var(--md-outlined-text-field-bottom-space, 16px);--_input-text-prefix-trailing-space: var(--md-outlined-text-field-input-text-prefix-trailing-space, 2px);--_input-text-suffix-leading-space: var(--md-outlined-text-field-input-text-suffix-leading-space, 2px);--_focus-caret-color: var(--md-outlined-text-field-focus-caret-color, var(--md-sys-color-primary, #6750a4));--_with-leading-icon-leading-space: var(--md-outlined-text-field-with-leading-icon-leading-space, 12px);--_with-trailing-icon-trailing-space: var(--md-outlined-text-field-with-trailing-icon-trailing-space, 12px);--md-outlined-field-bottom-space: var(--_bottom-space);--md-outlined-field-container-shape-end-end: var(--_container-shape-end-end);--md-outlined-field-container-shape-end-start: var(--_container-shape-end-start);--md-outlined-field-container-shape-start-end: var(--_container-shape-start-end);--md-outlined-field-container-shape-start-start: var(--_container-shape-start-start);--md-outlined-field-content-color: var(--_input-text-color);--md-outlined-field-content-font: var(--_input-text-font);--md-outlined-field-content-line-height: var(--_input-text-line-height);--md-outlined-field-content-size: var(--_input-text-size);--md-outlined-field-content-space: var(--_icon-input-space);--md-outlined-field-content-weight: var(--_input-text-weight);--md-outlined-field-disabled-content-color: var(--_disabled-input-text-color);--md-outlined-field-disabled-content-opacity: var(--_disabled-input-text-opacity);--md-outlined-field-disabled-label-text-color: var(--_disabled-label-text-color);--md-outlined-field-disabled-label-text-opacity: var(--_disabled-label-text-opacity);--md-outlined-field-disabled-leading-content-color: var(--_disabled-leading-icon-color);--md-outlined-field-disabled-leading-content-opacity: var(--_disabled-leading-icon-opacity);--md-outlined-field-disabled-outline-color: var(--_disabled-outline-color);--md-outlined-field-disabled-outline-opacity: var(--_disabled-outline-opacity);--md-outlined-field-disabled-outline-width: var(--_disabled-outline-width);--md-outlined-field-disabled-supporting-text-color: var(--_disabled-supporting-text-color);--md-outlined-field-disabled-supporting-text-opacity: var(--_disabled-supporting-text-opacity);--md-outlined-field-disabled-trailing-content-color: var(--_disabled-trailing-icon-color);--md-outlined-field-disabled-trailing-content-opacity: var(--_disabled-trailing-icon-opacity);--md-outlined-field-error-content-color: var(--_error-input-text-color);--md-outlined-field-error-focus-content-color: var(--_error-focus-input-text-color);--md-outlined-field-error-focus-label-text-color: var(--_error-focus-label-text-color);--md-outlined-field-error-focus-leading-content-color: var(--_error-focus-leading-icon-color);--md-outlined-field-error-focus-outline-color: var(--_error-focus-outline-color);--md-outlined-field-error-focus-supporting-text-color: var(--_error-focus-supporting-text-color);--md-outlined-field-error-focus-trailing-content-color: var(--_error-focus-trailing-icon-color);--md-outlined-field-error-hover-content-color: var(--_error-hover-input-text-color);--md-outlined-field-error-hover-label-text-color: var(--_error-hover-label-text-color);--md-outlined-field-error-hover-leading-content-color: var(--_error-hover-leading-icon-color);--md-outlined-field-error-hover-outline-color: var(--_error-hover-outline-color);--md-outlined-field-error-hover-supporting-text-color: var(--_error-hover-supporting-text-color);--md-outlined-field-error-hover-trailing-content-color: var(--_error-hover-trailing-icon-color);--md-outlined-field-error-label-text-color: var(--_error-label-text-color);--md-outlined-field-error-leading-content-color: var(--_error-leading-icon-color);--md-outlined-field-error-outline-color: var(--_error-outline-color);--md-outlined-field-error-supporting-text-color: var(--_error-supporting-text-color);--md-outlined-field-error-trailing-content-color: var(--_error-trailing-icon-color);--md-outlined-field-focus-content-color: var(--_focus-input-text-color);--md-outlined-field-focus-label-text-color: var(--_focus-label-text-color);--md-outlined-field-focus-leading-content-color: var(--_focus-leading-icon-color);--md-outlined-field-focus-outline-color: var(--_focus-outline-color);--md-outlined-field-focus-outline-width: var(--_focus-outline-width);--md-outlined-field-focus-supporting-text-color: var(--_focus-supporting-text-color);--md-outlined-field-focus-trailing-content-color: var(--_focus-trailing-icon-color);--md-outlined-field-hover-content-color: var(--_hover-input-text-color);--md-outlined-field-hover-label-text-color: var(--_hover-label-text-color);--md-outlined-field-hover-leading-content-color: var(--_hover-leading-icon-color);--md-outlined-field-hover-outline-color: var(--_hover-outline-color);--md-outlined-field-hover-outline-width: var(--_hover-outline-width);--md-outlined-field-hover-supporting-text-color: var(--_hover-supporting-text-color);--md-outlined-field-hover-trailing-content-color: var(--_hover-trailing-icon-color);--md-outlined-field-label-text-color: var(--_label-text-color);--md-outlined-field-label-text-font: var(--_label-text-font);--md-outlined-field-label-text-line-height: var(--_label-text-line-height);--md-outlined-field-label-text-populated-line-height: var(--_label-text-populated-line-height);--md-outlined-field-label-text-populated-size: var(--_label-text-populated-size);--md-outlined-field-label-text-size: var(--_label-text-size);--md-outlined-field-label-text-weight: var(--_label-text-weight);--md-outlined-field-leading-content-color: var(--_leading-icon-color);--md-outlined-field-leading-space: var(--_leading-space);--md-outlined-field-outline-color: var(--_outline-color);--md-outlined-field-outline-width: var(--_outline-width);--md-outlined-field-supporting-text-color: var(--_supporting-text-color);--md-outlined-field-supporting-text-font: var(--_supporting-text-font);--md-outlined-field-supporting-text-line-height: var(--_supporting-text-line-height);--md-outlined-field-supporting-text-size: var(--_supporting-text-size);--md-outlined-field-supporting-text-weight: var(--_supporting-text-weight);--md-outlined-field-top-space: var(--_top-space);--md-outlined-field-trailing-content-color: var(--_trailing-icon-color);--md-outlined-field-trailing-space: var(--_trailing-space);--md-outlined-field-with-leading-content-leading-space: var(--_with-leading-icon-leading-space);--md-outlined-field-with-trailing-content-trailing-space: var(--_with-trailing-icon-trailing-space)} +`;class Ra extends x{constructor(){super(...arguments),this.fieldTag=K`md-outlined-field`}}let Yt=class extends Ra{constructor(){super(...arguments),this.fieldTag=K`md-outlined-field`}};Yt.styles=[uo,$a],Yt=o([b("md-outlined-text-field")],Yt);export{kt as CloseReason,Fe as Corner,X as FocusState,et as MdAssistChip,dt as MdBrandedFab,Qe as MdCheckbox,tt as MdChipSet,Tt as MdCircularProgress,st as MdDialog,nt as MdDivider,Ke as MdElevatedButton,Ne as MdElevation,ct as MdFab,We as MdFilledButton,ht as MdFilledField,ft as MdFilledIconButton,Nt as MdFilledSelect,Xt as MdFilledTextField,Ge as MdFilledTonalButton,mt as MdFilledTonalIconButton,ot as MdFilterChip,Ve as MdFocusRing,vt as MdIcon,bt as MdIconButton,it as MdInputChip,zt as MdLinearProgress,_t as MdList,wt as MdListItem,Ct as MdMenu,Et as MdMenuItem,Xe as MdOutlinedButton,pt as MdOutlinedField,yt as MdOutlinedIconButton,Vt as MdOutlinedSelect,Yt as MdOutlinedTextField,Kt as MdPrimaryTab,Ot as MdRadio,qe as MdRipple,Wt as MdSecondaryTab,qt as MdSelectOption,Ht as MdSlider,It as MdSubMenu,at as MdSuggestionChip,Ut as MdSwitch,Gt as MdTabs,Ye as MdTextButton}; +//# sourceMappingURL=/sm/1ae4cc8ce70d28c1b959e7c49b075c4aefec9f71a4ac065e8cb13b5b61d9d54c.map \ No newline at end of file diff --git a/apps/ui/src/twfarmbot_ui/static/vendor/@material/web/typography/md-typescale-styles.js b/apps/ui/src/twfarmbot_ui/static/vendor/@material/web/typography/md-typescale-styles.js new file mode 100644 index 0000000..447a10a --- /dev/null +++ b/apps/ui/src/twfarmbot_ui/static/vendor/@material/web/typography/md-typescale-styles.js @@ -0,0 +1,9 @@ +/** + * Bundled by jsDelivr using Rollup v4.62.2 and esbuild v0.28.1. + * Original file: /npm/@material/web@2.4.0/typography/md-typescale-styles.js + * + * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files + */ +import{css as e}from"/npm/lit@3.3.1/+esm";const a=e`@layer{.md-typescale-display-small,.md-typescale-display-small-prominent{font:var(--md-sys-typescale-display-small-weight, var(--md-ref-typeface-weight-regular, 400)) var(--md-sys-typescale-display-small-size, 2.25rem)/var(--md-sys-typescale-display-small-line-height, 2.75rem) var(--md-sys-typescale-display-small-font, var(--md-ref-typeface-brand, Roboto))}.md-typescale-display-medium,.md-typescale-display-medium-prominent{font:var(--md-sys-typescale-display-medium-weight, var(--md-ref-typeface-weight-regular, 400)) var(--md-sys-typescale-display-medium-size, 2.8125rem)/var(--md-sys-typescale-display-medium-line-height, 3.25rem) var(--md-sys-typescale-display-medium-font, var(--md-ref-typeface-brand, Roboto))}.md-typescale-display-large,.md-typescale-display-large-prominent{font:var(--md-sys-typescale-display-large-weight, var(--md-ref-typeface-weight-regular, 400)) var(--md-sys-typescale-display-large-size, 3.5625rem)/var(--md-sys-typescale-display-large-line-height, 4rem) var(--md-sys-typescale-display-large-font, var(--md-ref-typeface-brand, Roboto))}.md-typescale-headline-small,.md-typescale-headline-small-prominent{font:var(--md-sys-typescale-headline-small-weight, var(--md-ref-typeface-weight-regular, 400)) var(--md-sys-typescale-headline-small-size, 1.5rem)/var(--md-sys-typescale-headline-small-line-height, 2rem) var(--md-sys-typescale-headline-small-font, var(--md-ref-typeface-brand, Roboto))}.md-typescale-headline-medium,.md-typescale-headline-medium-prominent{font:var(--md-sys-typescale-headline-medium-weight, var(--md-ref-typeface-weight-regular, 400)) var(--md-sys-typescale-headline-medium-size, 1.75rem)/var(--md-sys-typescale-headline-medium-line-height, 2.25rem) var(--md-sys-typescale-headline-medium-font, var(--md-ref-typeface-brand, Roboto))}.md-typescale-headline-large,.md-typescale-headline-large-prominent{font:var(--md-sys-typescale-headline-large-weight, var(--md-ref-typeface-weight-regular, 400)) var(--md-sys-typescale-headline-large-size, 2rem)/var(--md-sys-typescale-headline-large-line-height, 2.5rem) var(--md-sys-typescale-headline-large-font, var(--md-ref-typeface-brand, Roboto))}.md-typescale-title-small,.md-typescale-title-small-prominent{font:var(--md-sys-typescale-title-small-weight, var(--md-ref-typeface-weight-medium, 500)) var(--md-sys-typescale-title-small-size, 0.875rem)/var(--md-sys-typescale-title-small-line-height, 1.25rem) var(--md-sys-typescale-title-small-font, var(--md-ref-typeface-plain, Roboto))}.md-typescale-title-medium,.md-typescale-title-medium-prominent{font:var(--md-sys-typescale-title-medium-weight, var(--md-ref-typeface-weight-medium, 500)) var(--md-sys-typescale-title-medium-size, 1rem)/var(--md-sys-typescale-title-medium-line-height, 1.5rem) var(--md-sys-typescale-title-medium-font, var(--md-ref-typeface-plain, Roboto))}.md-typescale-title-large,.md-typescale-title-large-prominent{font:var(--md-sys-typescale-title-large-weight, var(--md-ref-typeface-weight-regular, 400)) var(--md-sys-typescale-title-large-size, 1.375rem)/var(--md-sys-typescale-title-large-line-height, 1.75rem) var(--md-sys-typescale-title-large-font, var(--md-ref-typeface-brand, Roboto))}.md-typescale-body-small,.md-typescale-body-small-prominent{font:var(--md-sys-typescale-body-small-weight, var(--md-ref-typeface-weight-regular, 400)) var(--md-sys-typescale-body-small-size, 0.75rem)/var(--md-sys-typescale-body-small-line-height, 1rem) var(--md-sys-typescale-body-small-font, var(--md-ref-typeface-plain, Roboto))}.md-typescale-body-medium,.md-typescale-body-medium-prominent{font:var(--md-sys-typescale-body-medium-weight, var(--md-ref-typeface-weight-regular, 400)) var(--md-sys-typescale-body-medium-size, 0.875rem)/var(--md-sys-typescale-body-medium-line-height, 1.25rem) var(--md-sys-typescale-body-medium-font, var(--md-ref-typeface-plain, Roboto))}.md-typescale-body-large,.md-typescale-body-large-prominent{font:var(--md-sys-typescale-body-large-weight, var(--md-ref-typeface-weight-regular, 400)) var(--md-sys-typescale-body-large-size, 1rem)/var(--md-sys-typescale-body-large-line-height, 1.5rem) var(--md-sys-typescale-body-large-font, var(--md-ref-typeface-plain, Roboto))}.md-typescale-label-small,.md-typescale-label-small-prominent{font:var(--md-sys-typescale-label-small-weight, var(--md-ref-typeface-weight-medium, 500)) var(--md-sys-typescale-label-small-size, 0.6875rem)/var(--md-sys-typescale-label-small-line-height, 1rem) var(--md-sys-typescale-label-small-font, var(--md-ref-typeface-plain, Roboto))}.md-typescale-label-medium,.md-typescale-label-medium-prominent{font:var(--md-sys-typescale-label-medium-weight, var(--md-ref-typeface-weight-medium, 500)) var(--md-sys-typescale-label-medium-size, 0.75rem)/var(--md-sys-typescale-label-medium-line-height, 1rem) var(--md-sys-typescale-label-medium-font, var(--md-ref-typeface-plain, Roboto))}.md-typescale-label-medium-prominent{font-weight:var(--md-sys-typescale-label-medium-weight-prominent, var(--md-ref-typeface-weight-bold, 700))}.md-typescale-label-large,.md-typescale-label-large-prominent{font:var(--md-sys-typescale-label-large-weight, var(--md-ref-typeface-weight-medium, 500)) var(--md-sys-typescale-label-large-size, 0.875rem)/var(--md-sys-typescale-label-large-line-height, 1.25rem) var(--md-sys-typescale-label-large-font, var(--md-ref-typeface-plain, Roboto))}.md-typescale-label-large-prominent{font-weight:var(--md-sys-typescale-label-large-weight-prominent, var(--md-ref-typeface-weight-bold, 700))}} +`;export{a as styles}; +//# sourceMappingURL=/sm/80c401c19a5a64cf0acf8c5317eb5335bdc922fd4887252b32d6acd3a3b08ab5.map \ No newline at end of file diff --git a/apps/ui/src/twfarmbot_ui/static/vendor/chart.js/auto.js b/apps/ui/src/twfarmbot_ui/static/vendor/chart.js/auto.js new file mode 100644 index 0000000..5164cef --- /dev/null +++ b/apps/ui/src/twfarmbot_ui/static/vendor/chart.js/auto.js @@ -0,0 +1,10 @@ +/** + * Bundled by jsDelivr using Rollup v4.62.2 and esbuild v0.28.1. + * Original file: /npm/chart.js@4.4.9/auto/auto.js + * + * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files + */ +import{Color as Mi}from"/npm/@kurkle/color@0.3.4/+esm";function lt(){}const go=(()=>{let i=0;return()=>i++})();function A(i){return i==null}function V(i){if(Array.isArray&&Array.isArray(i))return!0;const t=Object.prototype.toString.call(i);return t.slice(0,7)==="[object"&&t.slice(-6)==="Array]"}function O(i){return i!==null&&Object.prototype.toString.call(i)==="[object Object]"}function W(i){return(typeof i=="number"||i instanceof Number)&&isFinite(+i)}function Z(i,t){return W(i)?i:t}function P(i,t){return typeof i>"u"?t:i}const po=(i,t)=>typeof i=="string"&&i.endsWith("%")?parseFloat(i)/100:+i/t,ki=(i,t)=>typeof i=="string"&&i.endsWith("%")?parseFloat(i)/100*t:+i;function E(i,t,e){if(i&&typeof i.call=="function")return i.apply(e,t)}function T(i,t,e,s){let n,o,r;if(V(i))for(o=i.length,n=0;ni,x:i=>i.x,y:i=>i.y};function xo(i){const t=i.split("."),e=[];let s="";for(const n of t)s+=n,s.endsWith("\\")?s=s.slice(0,-1)+".":(e.push(s),s="");return e}function _o(i){const t=xo(i);return e=>{for(const s of t){if(s==="")break;e=e&&e[s]}return e}}function gt(i,t){return(wi[t]||(wi[t]=_o(t)))(i)}function Be(i){return i.charAt(0).toUpperCase()+i.slice(1)}const jt=i=>typeof i<"u",pt=i=>typeof i=="function",Pi=(i,t)=>{if(i.size!==t.size)return!1;for(const e of i)if(!t.has(e))return!1;return!0};function yo(i){return i.type==="mouseup"||i.type==="click"||i.type==="contextmenu"}const I=Math.PI,z=2*I,vo=z+I,ue=Number.POSITIVE_INFINITY,Mo=I/180,H=I/2,Mt=I/4,Di=I*2/3,mt=Math.log10,nt=Math.sign;function $t(i,t,e){return Math.abs(i-t)n-o).pop(),t}function So(i){return typeof i=="symbol"||typeof i=="object"&&i!==null&&!(Symbol.toPrimitive in i||"toString"in i||"valueOf"in i)}function Et(i){return!So(i)&&!isNaN(parseFloat(i))&&isFinite(i)}function wo(i,t){const e=Math.round(i);return e-t<=i&&e+t>=i}function Ai(i,t,e){let s,n,o;for(s=0,n=i.length;sl&&c=Math.min(t,e)-s&&i<=Math.max(t,e)+s}function Ne(i,t,e){e=e||(r=>i[r]1;)o=n+s>>1,e(o)?n=o:s=o;return{lo:n,hi:s}}const ht=(i,t,e,s)=>Ne(i,e,s?n=>{const o=i[n][t];return oi[n][t]Ne(i,e,s=>i[s][t]>=e);function Ao(i,t,e){let s=0,n=i.length;for(;ss&&i[n-1]>e;)n--;return s>0||n{const s="_onData"+Be(e),n=i[e];Object.defineProperty(i,e,{configurable:!0,enumerable:!1,value(...o){const r=n.apply(this,o);return i._chartjs.listeners.forEach(a=>{typeof a[s]=="function"&&a[s](...o)}),r}})})}function Ri(i,t){const e=i._chartjs;if(!e)return;const s=e.listeners,n=s.indexOf(t);n!==-1&&s.splice(n,1),!(s.length>0)&&(Ti.forEach(o=>{delete i[o]}),delete i._chartjs)}function Ei(i){const t=new Set(i);return t.size===i.length?i:Array.from(t)}const Ii=(function(){return typeof window>"u"?function(i){return i()}:window.requestAnimationFrame})();function zi(i,t){let e=[],s=!1;return function(...n){e=n,s||(s=!0,Ii.call(window,()=>{s=!1,i.apply(t,e)}))}}function Lo(i,t){let e;return function(...s){return t?(clearTimeout(e),e=setTimeout(i,t,s)):i.apply(this,s),t}}const He=i=>i==="start"?"left":i==="end"?"right":"center",K=(i,t,e)=>i==="start"?t:i==="end"?e:(t+e)/2,To=(i,t,e,s)=>i===(s?"left":"right")?e:i==="center"?(t+e)/2:t;function Fi(i,t,e){const s=t.length;let n=0,o=s;if(i._sorted){const{iScale:r,vScale:a,_parsed:l}=i,c=i.dataset&&i.dataset.options?i.dataset.options.spanGaps:null,h=r.axis,{min:d,max:u,minDefined:f,maxDefined:g}=r.getUserBounds();if(f){if(n=Math.min(ht(l,h,d).lo,e?s:ht(t,h,r.getPixelForValue(d)).lo),c){const p=l.slice(0,n+1).reverse().findIndex(m=>!A(m[a.axis]));n-=Math.max(0,p)}n=$(n,0,s-1)}if(g){let p=Math.max(ht(l,r.axis,u,!0).hi+1,e?0:ht(t,h,r.getPixelForValue(u),!0).hi+1);if(c){const m=l.slice(p-1).findIndex(b=>!A(b[a.axis]));p+=Math.max(0,m)}o=$(p,n,s)-n}else o=s-n}return{start:n,count:o}}function Bi(i){const{xScale:t,yScale:e,_scaleRanges:s}=i,n={xmin:t.min,xmax:t.max,ymin:e.min,ymax:e.max};if(!s)return i._scaleRanges=n,!0;const o=s.xmin!==t.min||s.xmax!==t.max||s.ymin!==e.min||s.ymax!==e.max;return Object.assign(s,n),o}const fe=i=>i===0||i===1,Vi=(i,t,e)=>-(Math.pow(2,10*(i-=1))*Math.sin((i-t)*z/e)),Wi=(i,t,e)=>Math.pow(2,-10*i)*Math.sin((i-t)*z/e)+1,Yt={linear:i=>i,easeInQuad:i=>i*i,easeOutQuad:i=>-i*(i-2),easeInOutQuad:i=>(i/=.5)<1?.5*i*i:-.5*(--i*(i-2)-1),easeInCubic:i=>i*i*i,easeOutCubic:i=>(i-=1)*i*i+1,easeInOutCubic:i=>(i/=.5)<1?.5*i*i*i:.5*((i-=2)*i*i+2),easeInQuart:i=>i*i*i*i,easeOutQuart:i=>-((i-=1)*i*i*i-1),easeInOutQuart:i=>(i/=.5)<1?.5*i*i*i*i:-.5*((i-=2)*i*i*i-2),easeInQuint:i=>i*i*i*i*i,easeOutQuint:i=>(i-=1)*i*i*i*i+1,easeInOutQuint:i=>(i/=.5)<1?.5*i*i*i*i*i:.5*((i-=2)*i*i*i*i+2),easeInSine:i=>-Math.cos(i*H)+1,easeOutSine:i=>Math.sin(i*H),easeInOutSine:i=>-.5*(Math.cos(I*i)-1),easeInExpo:i=>i===0?0:Math.pow(2,10*(i-1)),easeOutExpo:i=>i===1?1:-Math.pow(2,-10*i)+1,easeInOutExpo:i=>fe(i)?i:i<.5?.5*Math.pow(2,10*(i*2-1)):.5*(-Math.pow(2,-10*(i*2-1))+2),easeInCirc:i=>i>=1?i:-(Math.sqrt(1-i*i)-1),easeOutCirc:i=>Math.sqrt(1-(i-=1)*i),easeInOutCirc:i=>(i/=.5)<1?-.5*(Math.sqrt(1-i*i)-1):.5*(Math.sqrt(1-(i-=2)*i)+1),easeInElastic:i=>fe(i)?i:Vi(i,.075,.3),easeOutElastic:i=>fe(i)?i:Wi(i,.075,.3),easeInOutElastic(i){return fe(i)?i:i<.5?.5*Vi(i*2,.1125,.45):.5+.5*Wi(i*2-1,.1125,.45)},easeInBack(i){return i*i*((1.70158+1)*i-1.70158)},easeOutBack(i){return(i-=1)*i*((1.70158+1)*i+1.70158)+1},easeInOutBack(i){let t=1.70158;return(i/=.5)<1?.5*(i*i*(((t*=1.525)+1)*i-t)):.5*((i-=2)*i*(((t*=1.525)+1)*i+t)+2)},easeInBounce:i=>1-Yt.easeOutBounce(1-i),easeOutBounce(i){return i<1/2.75?7.5625*i*i:i<2/2.75?7.5625*(i-=1.5/2.75)*i+.75:i<2.5/2.75?7.5625*(i-=2.25/2.75)*i+.9375:7.5625*(i-=2.625/2.75)*i+.984375},easeInOutBounce:i=>i<.5?Yt.easeInBounce(i*2)*.5:Yt.easeOutBounce(i*2-1)*.5+.5};function je(i){if(i&&typeof i=="object"){const t=i.toString();return t==="[object CanvasPattern]"||t==="[object CanvasGradient]"}return!1}function Ni(i){return je(i)?i:new Mi(i)}function $e(i){return je(i)?i:new Mi(i).saturate(.5).darken(.1).hexString()}const Ro=["x","y","borderWidth","radius","tension"],Eo=["color","borderColor","backgroundColor"];function Io(i){i.set("animation",{delay:void 0,duration:1e3,easing:"easeOutQuart",fn:void 0,from:void 0,loop:void 0,to:void 0,type:void 0}),i.describe("animation",{_fallback:!1,_indexable:!1,_scriptable:t=>t!=="onProgress"&&t!=="onComplete"&&t!=="fn"}),i.set("animations",{colors:{type:"color",properties:Eo},numbers:{type:"number",properties:Ro}}),i.describe("animations",{_fallback:"animation"}),i.set("transitions",{active:{animation:{duration:400}},resize:{animation:{duration:0}},show:{animations:{colors:{from:"transparent"},visible:{type:"boolean",duration:0}}},hide:{animations:{colors:{to:"transparent"},visible:{type:"boolean",easing:"linear",fn:t=>t|0}}}})}function zo(i){i.set("layout",{autoPadding:!0,padding:{top:0,right:0,bottom:0,left:0}})}const Hi=new Map;function Fo(i,t){t=t||{};const e=i+JSON.stringify(t);let s=Hi.get(e);return s||(s=new Intl.NumberFormat(i,t),Hi.set(e,s)),s}function Xt(i,t,e){return Fo(t,e).format(i)}const ji={values(i){return V(i)?i:""+i},numeric(i,t,e){if(i===0)return"0";const s=this.chart.options.locale;let n,o=i;if(e.length>1){const c=Math.max(Math.abs(e[0].value),Math.abs(e[e.length-1].value));(c<1e-4||c>1e15)&&(n="scientific"),o=Bo(i,e)}const r=mt(Math.abs(o)),a=isNaN(r)?1:Math.max(Math.min(-1*Math.floor(r),20),0),l={notation:n,minimumFractionDigits:a,maximumFractionDigits:a};return Object.assign(l,this.options.ticks.format),Xt(i,s,l)},logarithmic(i,t,e){if(i===0)return"0";const s=e[t].significand||i/Math.pow(10,Math.floor(mt(i)));return[1,2,3,5,10,15].includes(s)||t>.8*e.length?ji.numeric.call(this,i,t,e):""}};function Bo(i,t){let e=t.length>3?t[2].value-t[1].value:t[1].value-t[0].value;return Math.abs(e)>=1&&i!==Math.floor(i)&&(e=i-Math.floor(i)),e}var Kt={formatters:ji};function Vo(i){i.set("scale",{display:!0,offset:!1,reverse:!1,beginAtZero:!1,bounds:"ticks",clip:!0,grace:0,grid:{display:!0,lineWidth:1,drawOnChartArea:!0,drawTicks:!0,tickLength:8,tickWidth:(t,e)=>e.lineWidth,tickColor:(t,e)=>e.color,offset:!1},border:{display:!0,dash:[],dashOffset:0,width:1},title:{display:!1,text:"",padding:{top:4,bottom:4}},ticks:{minRotation:0,maxRotation:50,mirror:!1,textStrokeWidth:0,textStrokeColor:"",padding:3,display:!0,autoSkip:!0,autoSkipPadding:3,labelOffset:0,callback:Kt.formatters.values,minor:{},major:{},align:"center",crossAlign:"near",showLabelBackdrop:!1,backdropColor:"rgba(255, 255, 255, 0.75)",backdropPadding:2}}),i.route("scale.ticks","color","","color"),i.route("scale.grid","color","","borderColor"),i.route("scale.border","color","","borderColor"),i.route("scale.title","color","","color"),i.describe("scale",{_fallback:!1,_scriptable:t=>!t.startsWith("before")&&!t.startsWith("after")&&t!=="callback"&&t!=="parser",_indexable:t=>t!=="borderDash"&&t!=="tickBorderDash"&&t!=="dash"}),i.describe("scales",{_fallback:"scale"}),i.describe("scale.ticks",{_scriptable:t=>t!=="backdropPadding"&&t!=="callback",_indexable:t=>t!=="backdropPadding"})}const kt=Object.create(null),Ue=Object.create(null);function Gt(i,t){if(!t)return i;const e=t.split(".");for(let s=0,n=e.length;ss.chart.platform.getDevicePixelRatio(),this.elements={},this.events=["mousemove","mouseout","click","touchstart","touchmove"],this.font={family:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",size:12,style:"normal",lineHeight:1.2,weight:null},this.hover={},this.hoverBackgroundColor=(s,n)=>$e(n.backgroundColor),this.hoverBorderColor=(s,n)=>$e(n.borderColor),this.hoverColor=(s,n)=>$e(n.color),this.indexAxis="x",this.interaction={mode:"nearest",intersect:!0,includeInvisible:!1},this.maintainAspectRatio=!0,this.onHover=null,this.onClick=null,this.parsing=!0,this.plugins={},this.responsive=!0,this.scale=void 0,this.scales={},this.showLine=!0,this.drawActiveElementsOnTop=!0,this.describe(t),this.apply(e)}set(t,e){return Ye(this,t,e)}get(t){return Gt(this,t)}describe(t,e){return Ye(Ue,t,e)}override(t,e){return Ye(kt,t,e)}route(t,e,s,n){const o=Gt(this,t),r=Gt(this,s),a="_"+e;Object.defineProperties(o,{[a]:{value:o[e],writable:!0},[e]:{enumerable:!0,get(){const l=this[a],c=r[n];return O(l)?Object.assign({},c,l):P(l,c)},set(l){this[a]=l}}})}apply(t){t.forEach(e=>e(this))}}var F=new Wo({_scriptable:i=>!i.startsWith("on"),_indexable:i=>i!=="events",hover:{_fallback:"interaction"},interaction:{_scriptable:!1,_indexable:!1}},[Io,zo,Vo]);function No(i){return!i||A(i.size)||A(i.family)?null:(i.style?i.style+" ":"")+(i.weight?i.weight+" ":"")+i.size+"px "+i.family}function ge(i,t,e,s,n){let o=t[n];return o||(o=t[n]=i.measureText(n).width,e.push(n)),o>s&&(s=o),s}function Ho(i,t,e,s){s=s||{};let n=s.data=s.data||{},o=s.garbageCollect=s.garbageCollect||[];s.font!==t&&(n=s.data={},o=s.garbageCollect=[],s.font=t),i.save(),i.font=t;let r=0;const a=e.length;let l,c,h,d,u;for(l=0;le.length){for(l=0;l0&&i.stroke()}}function dt(i,t,e){return e=e||.5,!t||i&&i.x>t.left-e&&i.xt.top-e&&i.y0&&o.strokeColor!=="";let l,c;for(i.save(),i.font=n.string,Uo(i,o),l=0;l+i||0;function Ke(i,t){const e={},s=O(t),n=s?Object.keys(t):t,o=O(i)?s?r=>P(i[r],i[t[r]]):r=>i[r]:()=>i;for(const r of n)e[r]=Jo(o(r));return e}function Yi(i){return Ke(i,{top:"y",right:"x",bottom:"y",left:"x"})}function Pt(i){return Ke(i,["topLeft","topRight","bottomLeft","bottomRight"])}function G(i){const t=Yi(i);return t.width=t.left+t.right,t.height=t.top+t.bottom,t}function j(i,t){i=i||{},t=t||F.font;let e=P(i.size,t.size);typeof e=="string"&&(e=parseInt(e,10));let s=P(i.style,t.style);s&&!(""+s).match(Go)&&(console.warn('Invalid font style specified: "'+s+'"'),s=void 0);const n={family:P(i.family,t.family),lineHeight:qo(P(i.lineHeight,t.lineHeight),e),size:e,style:s,weight:P(i.weight,t.weight),string:""};return n.string=No(n),n}function Jt(i,t,e,s){let n,o,r;for(n=0,o=i.length;ne&&a===0?0:a+l;return{min:r(s,-Math.abs(o)),max:r(n,o)}}function bt(i,t){return Object.assign(Object.create(i),t)}function Ge(i,t=[""],e,s,n=()=>i[0]){const o=e||i;typeof s>"u"&&(s=Ji("_fallback",i));const r={[Symbol.toStringTag]:"Object",_cacheable:!0,_scopes:i,_rootScopes:o,_fallback:s,_getTarget:n,override:a=>Ge([a,...i],t,o,s)};return new Proxy(r,{deleteProperty(a,l){return delete a[l],delete a._keys,delete i[0][l],!0},get(a,l){return Ki(a,l,()=>rr(l,t,i,a))},getOwnPropertyDescriptor(a,l){return Reflect.getOwnPropertyDescriptor(a._scopes[0],l)},getPrototypeOf(){return Reflect.getPrototypeOf(i[0])},has(a,l){return Qi(a).includes(l)},ownKeys(a){return Qi(a)},set(a,l,c){const h=a._storage||(a._storage=n());return a[l]=h[l]=c,delete a._keys,!0}})}function It(i,t,e,s){const n={_cacheable:!1,_proxy:i,_context:t,_subProxy:e,_stack:new Set,_descriptors:Xi(i,s),setContext:o=>It(i,o,e,s),override:o=>It(i.override(o),t,e,s)};return new Proxy(n,{deleteProperty(o,r){return delete o[r],delete i[r],!0},get(o,r,a){return Ki(o,r,()=>tr(o,r,a))},getOwnPropertyDescriptor(o,r){return o._descriptors.allKeys?Reflect.has(i,r)?{enumerable:!0,configurable:!0}:void 0:Reflect.getOwnPropertyDescriptor(i,r)},getPrototypeOf(){return Reflect.getPrototypeOf(i)},has(o,r){return Reflect.has(i,r)},ownKeys(){return Reflect.ownKeys(i)},set(o,r,a){return i[r]=a,delete o[r],!0}})}function Xi(i,t={scriptable:!0,indexable:!0}){const{_scriptable:e=t.scriptable,_indexable:s=t.indexable,_allKeys:n=t.allKeys}=i;return{allKeys:n,scriptable:e,indexable:s,isScriptable:pt(e)?e:()=>e,isIndexable:pt(s)?s:()=>s}}const Zo=(i,t)=>i?i+Be(t):t,qe=(i,t)=>O(t)&&i!=="adapters"&&(Object.getPrototypeOf(t)===null||t.constructor===Object);function Ki(i,t,e){if(Object.prototype.hasOwnProperty.call(i,t)||t==="constructor")return i[t];const s=e();return i[t]=s,s}function tr(i,t,e){const{_proxy:s,_context:n,_subProxy:o,_descriptors:r}=i;let a=s[t];return pt(a)&&r.isScriptable(t)&&(a=er(t,a,i,e)),V(a)&&a.length&&(a=ir(t,a,i,r.isIndexable)),qe(t,a)&&(a=It(a,n,o&&o[t],r)),a}function er(i,t,e,s){const{_proxy:n,_context:o,_subProxy:r,_stack:a}=e;if(a.has(i))throw new Error("Recursion detected: "+Array.from(a).join("->")+"->"+i);a.add(i);let l=t(o,r||s);return a.delete(i),qe(i,l)&&(l=Je(n._scopes,n,i,l)),l}function ir(i,t,e,s){const{_proxy:n,_context:o,_subProxy:r,_descriptors:a}=e;if(typeof o.index<"u"&&s(i))return t[o.index%t.length];if(O(t[0])){const l=t,c=n._scopes.filter(h=>h!==l);t=[];for(const h of l){const d=Je(c,n,i,h);t.push(It(d,o,r&&r[i],a))}}return t}function Gi(i,t,e){return pt(i)?i(t,e):i}const sr=(i,t)=>i===!0?t:typeof i=="string"?gt(t,i):void 0;function nr(i,t,e,s,n){for(const o of t){const r=sr(e,o);if(r){i.add(r);const a=Gi(r._fallback,e,n);if(typeof a<"u"&&a!==e&&a!==s)return a}else if(r===!1&&typeof s<"u"&&e!==s)return null}return!1}function Je(i,t,e,s){const n=t._rootScopes,o=Gi(t._fallback,e,s),r=[...i,...n],a=new Set;a.add(s);let l=qi(a,r,e,o||e,s);return l===null||typeof o<"u"&&o!==e&&(l=qi(a,r,o,l,s),l===null)?!1:Ge(Array.from(a),[""],n,o,()=>or(t,e,s))}function qi(i,t,e,s,n){for(;e;)e=nr(i,t,e,s,n);return e}function or(i,t,e){const s=i._getTarget();t in s||(s[t]={});const n=s[t];return V(n)&&O(e)?e:n||{}}function rr(i,t,e,s){let n;for(const o of t)if(n=Ji(Zo(o,i),e),typeof n<"u")return qe(i,n)?Je(e,s,i,n):n}function Ji(i,t){for(const e of t){if(!e)continue;const s=e[i];if(typeof s<"u")return s}}function Qi(i){let t=i._keys;return t||(t=i._keys=ar(i._scopes)),t}function ar(i){const t=new Set;for(const e of i)for(const s of Object.keys(e).filter(n=>!n.startsWith("_")))t.add(s);return Array.from(t)}function Zi(i,t,e,s){const{iScale:n}=i,{key:o="r"}=this._parsing,r=new Array(s);let a,l,c,h;for(a=0,l=s;ati==="x"?"y":"x";function cr(i,t,e,s){const n=i.skip?t:i,o=t,r=e.skip?t:e,a=We(o,n),l=We(r,o);let c=a/(a+l),h=l/(a+l);c=isNaN(c)?0:c,h=isNaN(h)?0:h;const d=s*c,u=s*h;return{previous:{x:o.x-d*(r.x-n.x),y:o.y-d*(r.y-n.y)},next:{x:o.x+u*(r.x-n.x),y:o.y+u*(r.y-n.y)}}}function hr(i,t,e){const s=i.length;let n,o,r,a,l,c=zt(i,0);for(let h=0;h!c.skip)),t.cubicInterpolationMode==="monotone")ur(i,n);else{let c=s?i[i.length-1]:i[0];for(o=0,r=i.length;oi.ownerDocument.defaultView.getComputedStyle(i,null);function pr(i,t){return _e(i).getPropertyValue(t)}const mr=["top","right","bottom","left"];function Dt(i,t,e){const s={};e=e?"-"+e:"";for(let n=0;n<4;n++){const o=mr[n];s[o]=parseFloat(i[t+"-"+o+e])||0}return s.width=s.left+s.right,s.height=s.top+s.bottom,s}const br=(i,t,e)=>(i>0||t>0)&&(!e||!e.shadowRoot);function xr(i,t){const e=i.touches,s=e&&e.length?e[0]:i,{offsetX:n,offsetY:o}=s;let r=!1,a,l;if(br(n,o,i.target))a=n,l=o;else{const c=t.getBoundingClientRect();a=s.clientX-c.left,l=s.clientY-c.top,r=!0}return{x:a,y:l,box:r}}function Ct(i,t){if("native"in i)return i;const{canvas:e,currentDevicePixelRatio:s}=t,n=_e(e),o=n.boxSizing==="border-box",r=Dt(n,"padding"),a=Dt(n,"border","width"),{x:l,y:c,box:h}=xr(i,e),d=r.left+(h&&a.left),u=r.top+(h&&a.top);let{width:f,height:g}=t;return o&&(f-=r.width+a.width,g-=r.height+a.height),{x:Math.round((l-d)/f*e.width/s),y:Math.round((c-u)/g*e.height/s)}}function _r(i,t,e){let s,n;if(t===void 0||e===void 0){const o=i&&Ze(i);if(!o)t=i.clientWidth,e=i.clientHeight;else{const r=o.getBoundingClientRect(),a=_e(o),l=Dt(a,"border","width"),c=Dt(a,"padding");t=r.width-c.width-l.width,e=r.height-c.height-l.height,s=xe(a.maxWidth,o,"clientWidth"),n=xe(a.maxHeight,o,"clientHeight")}}return{width:t,height:e,maxWidth:s||ue,maxHeight:n||ue}}const ye=i=>Math.round(i*10)/10;function yr(i,t,e,s){const n=_e(i),o=Dt(n,"margin"),r=xe(n.maxWidth,i,"clientWidth")||ue,a=xe(n.maxHeight,i,"clientHeight")||ue,l=_r(i,t,e);let{width:c,height:h}=l;if(n.boxSizing==="content-box"){const u=Dt(n,"border","width"),f=Dt(n,"padding");c-=f.width+u.width,h-=f.height+u.height}return c=Math.max(0,c-o.width),h=Math.max(0,s?c/s:h-o.height),c=ye(Math.min(c,r,l.maxWidth)),h=ye(Math.min(h,a,l.maxHeight)),c&&!h&&(h=ye(c/2)),(t!==void 0||e!==void 0)&&s&&l.height&&h>l.height&&(h=l.height,c=ye(Math.floor(h*s))),{width:c,height:h}}function es(i,t,e){const s=t||1,n=Math.floor(i.height*s),o=Math.floor(i.width*s);i.height=Math.floor(i.height),i.width=Math.floor(i.width);const r=i.canvas;return r.style&&(e||!r.style.height&&!r.style.width)&&(r.style.height=`${i.height}px`,r.style.width=`${i.width}px`),i.currentDevicePixelRatio!==s||r.height!==n||r.width!==o?(i.currentDevicePixelRatio=s,r.height=n,r.width=o,i.ctx.setTransform(s,0,0,s,0,0),!0):!1}const vr=(function(){let i=!1;try{const t={get passive(){return i=!0,!1}};Qe()&&(window.addEventListener("test",null,t),window.removeEventListener("test",null,t))}catch{}return i})();function is(i,t){const e=pr(i,t),s=e&&e.match(/^(\d+)(\.\d+)?px$/);return s?+s[1]:void 0}function At(i,t,e,s){return{x:i.x+e*(t.x-i.x),y:i.y+e*(t.y-i.y)}}function Mr(i,t,e,s){return{x:i.x+e*(t.x-i.x),y:s==="middle"?e<.5?i.y:t.y:s==="after"?e<1?i.y:t.y:e>0?t.y:i.y}}function kr(i,t,e,s){const n={x:i.cp2x,y:i.cp2y},o={x:t.cp1x,y:t.cp1y},r=At(i,n,e),a=At(n,o,e),l=At(o,t,e),c=At(r,a,e),h=At(a,l,e);return At(c,h,e)}const Sr=function(i,t){return{x(e){return i+i+t-e},setWidth(e){t=e},textAlign(e){return e==="center"?e:e==="right"?"left":"right"},xPlus(e,s){return e-s},leftForLtr(e,s){return e-s}}},wr=function(){return{x(i){return i},setWidth(i){},textAlign(i){return i},xPlus(i,t){return i+t},leftForLtr(i,t){return i}}};function Ft(i,t,e){return i?Sr(t,e):wr()}function ss(i,t){let e,s;(t==="ltr"||t==="rtl")&&(e=i.canvas.style,s=[e.getPropertyValue("direction"),e.getPropertyPriority("direction")],e.setProperty("direction",t,"important"),i.prevTextDirection=s)}function ns(i,t){t!==void 0&&(delete i.prevTextDirection,i.canvas.style.setProperty("direction",t[0],t[1]))}function os(i){return i==="angle"?{between:Ut,compare:Po,normalize:tt}:{between:ct,compare:(t,e)=>t-e,normalize:t=>t}}function rs({start:i,end:t,count:e,loop:s,style:n}){return{start:i%e,end:t%e,loop:s&&(t-i+1)%e===0,style:n}}function Pr(i,t,e){const{property:s,start:n,end:o}=e,{between:r,normalize:a}=os(s),l=t.length;let{start:c,end:h,loop:d}=i,u,f;if(d){for(c+=l,h+=l,u=0,f=l;ul(n,v,b)&&a(n,v)!==0,_=()=>a(o,b)===0||l(o,v,b),M=()=>p||y(),k=()=>!p||_();for(let S=h,w=h;S<=d;++S)x=t[S%r],!x.skip&&(b=c(x[s]),b!==v&&(p=l(b,n,o),m===null&&M()&&(m=a(b,n)===0?S:w),m!==null&&k()&&(g.push(rs({start:m,end:S,loop:u,count:r,style:f})),m=null),w=S,v=b));return m!==null&&g.push(rs({start:m,end:d,loop:u,count:r,style:f})),g}function ls(i,t){const e=[],s=i.segments;for(let n=0;nn&&i[o%t].skip;)o--;return o%=t,{start:n,end:o}}function Cr(i,t,e,s){const n=i.length,o=[];let r=t,a=i[t],l;for(l=t+1;l<=e;++l){const c=i[l%n];c.skip||c.stop?a.skip||(s=!1,o.push({start:t%n,end:(l-1)%n,loop:s}),t=r=c.stop?l:null):(r=l,a.skip&&(t=l)),a=c}return r!==null&&o.push({start:t%n,end:r%n,loop:s}),o}function Ar(i,t){const e=i.points,s=i.options.spanGaps,n=e.length;if(!n)return[];const o=!!i._loop,{start:r,end:a}=Dr(e,n,o,s);if(s===!0)return cs(i,[{start:r,end:a,loop:o}],e,t);const l=aa({chart:t,initial:e.initial,numSteps:r,currentStep:Math.min(s-e.start,r)}))}_refresh(){this._request||(this._running=!0,this._request=Ii.call(window,()=>{this._update(),this._request=null,this._running&&this._refresh()}))}_update(t=Date.now()){let e=0;this._charts.forEach((s,n)=>{if(!s.running||!s.items.length)return;const o=s.items;let r=o.length-1,a=!1,l;for(;r>=0;--r)l=o[r],l._active?(l._total>s.duration&&(s.duration=l._total),l.tick(t),a=!0):(o[r]=o[o.length-1],o.pop());a&&(n.draw(),this._notify(n,s,t,"progress")),o.length||(s.running=!1,this._notify(n,s,t,"complete"),s.initial=!1),e+=o.length}),this._lastDate=t,e===0&&(this._running=!1)}_getAnims(t){const e=this._charts;let s=e.get(t);return s||(s={running:!1,initial:!0,items:[],listeners:{complete:[],progress:[]}},e.set(t,s)),s}listen(t,e,s){this._getAnims(t).listeners[e].push(s)}add(t,e){!e||!e.length||this._getAnims(t).items.push(...e)}has(t){return this._getAnims(t).items.length>0}start(t){const e=this._charts.get(t);e&&(e.running=!0,e.start=Date.now(),e.duration=e.items.reduce((s,n)=>Math.max(s,n._duration),0),this._refresh())}running(t){if(!this._running)return!1;const e=this._charts.get(t);return!(!e||!e.running||!e.items.length)}stop(t){const e=this._charts.get(t);if(!e||!e.items.length)return;const s=e.items;let n=s.length-1;for(;n>=0;--n)s[n].cancel();e.items=[],this._notify(t,e,Date.now(),"complete")}remove(t){return this._charts.delete(t)}}var ot=new Rr;const us="transparent",Er={boolean(i,t,e){return e>.5?t:i},color(i,t,e){const s=Ni(i||us),n=s.valid&&Ni(t||us);return n&&n.valid?n.mix(s,e).hexString():t},number(i,t,e){return i+(t-i)*e}};class fs{constructor(t,e,s,n){const o=e[s];n=Jt([t.to,n,o,t.from]);const r=Jt([t.from,o,n]);this._active=!0,this._fn=t.fn||Er[t.type||typeof r],this._easing=Yt[t.easing]||Yt.linear,this._start=Math.floor(Date.now()+(t.delay||0)),this._duration=this._total=Math.floor(t.duration),this._loop=!!t.loop,this._target=e,this._prop=s,this._from=r,this._to=n,this._promises=void 0}active(){return this._active}update(t,e,s){if(this._active){this._notify(!1);const n=this._target[this._prop],o=s-this._start,r=this._duration-o;this._start=s,this._duration=Math.floor(Math.max(r,t.duration)),this._total+=o,this._loop=!!t.loop,this._to=Jt([t.to,e,n,t.from]),this._from=Jt([t.from,n,e])}}cancel(){this._active&&(this.tick(Date.now()),this._active=!1,this._notify(!1))}tick(t){const e=t-this._start,s=this._duration,n=this._prop,o=this._from,r=this._loop,a=this._to;let l;if(this._active=o!==a&&(r||e1?2-l:l,l=this._easing(Math.min(1,Math.max(0,l))),this._target[n]=this._fn(o,a,l)}wait(){const t=this._promises||(this._promises=[]);return new Promise((e,s)=>{t.push({res:e,rej:s})})}_notify(t){const e=t?"res":"rej",s=this._promises||[];for(let n=0;n{const o=t[n];if(!O(o))return;const r={};for(const a of e)r[a]=o[a];(V(o.properties)&&o.properties||[n]).forEach(a=>{(a===n||!s.has(a))&&s.set(a,r)})})}_animateOptions(t,e){const s=e.options,n=zr(t,s);if(!n)return[];const o=this._createAnimations(n,s);return s.$shared&&Ir(t.options.$animations,s).then(()=>{t.options=s},()=>{}),o}_createAnimations(t,e){const s=this._properties,n=[],o=t.$animations||(t.$animations={}),r=Object.keys(e),a=Date.now();let l;for(l=r.length-1;l>=0;--l){const c=r[l];if(c.charAt(0)==="$")continue;if(c==="options"){n.push(...this._animateOptions(t,e));continue}const h=e[c];let d=o[c];const u=s.get(c);if(d)if(u&&d.active()){d.update(u,h,a);continue}else d.cancel();if(!u||!u.duration){t[c]=h;continue}o[c]=d=new fs(u,t,c,h),n.push(d)}return n}update(t,e){if(this._properties.size===0){Object.assign(t,e);return}const s=this._createAnimations(t,e);if(s.length)return ot.add(this._chart,s),!0}}function Ir(i,t){const e=[],s=Object.keys(t);for(let n=0;n0||!e&&o<0)return n.index}return null}function xs(i,t){const{chart:e,_cachedMeta:s}=i,n=e._stacks||(e._stacks={}),{iScale:o,vScale:r,index:a}=s,l=o.axis,c=r.axis,h=Wr(o,r,s),d=t.length;let u;for(let f=0;fe[s].axis===t).shift()}function jr(i,t){return bt(i,{active:!1,dataset:void 0,datasetIndex:t,index:t,mode:"default",type:"dataset"})}function $r(i,t,e){return bt(i,{active:!1,dataIndex:t,parsed:void 0,raw:void 0,element:e,index:t,mode:"default",type:"data"})}function Qt(i,t){const e=i.controller.index,s=i.vScale&&i.vScale.axis;if(s){t=t||i._parsed;for(const n of t){const o=n._stacks;if(!o||o[s]===void 0||o[s][e]===void 0)return;delete o[s][e],o[s]._visualValues!==void 0&&o[s]._visualValues[e]!==void 0&&delete o[s]._visualValues[e]}}}const si=i=>i==="reset"||i==="none",_s=(i,t)=>t?i:Object.assign({},i),Ur=(i,t,e)=>i&&!t.hidden&&t._stacked&&{keys:ps(e,!0),values:null};class ut{static defaults={};static datasetElementType=null;static dataElementType=null;constructor(t,e){this.chart=t,this._ctx=t.ctx,this.index=e,this._cachedDataOpts={},this._cachedMeta=this.getMeta(),this._type=this._cachedMeta.type,this.options=void 0,this._parsing=!1,this._data=void 0,this._objectData=void 0,this._sharedOptions=void 0,this._drawStart=void 0,this._drawCount=void 0,this.enableOptionSharing=!1,this.supportsDecimation=!1,this.$context=void 0,this._syncList=[],this.datasetElementType=new.target.datasetElementType,this.dataElementType=new.target.dataElementType,this.initialize()}initialize(){const t=this._cachedMeta;this.configure(),this.linkScales(),t._stacked=ei(t.vScale,t),this.addElements(),this.options.fill&&!this.chart.isPluginEnabled("filler")&&console.warn("Tried to use the 'fill' option without the 'Filler' plugin enabled. Please import and register the 'Filler' plugin and make sure it is not disabled in the options")}updateIndex(t){this.index!==t&&Qt(this._cachedMeta),this.index=t}linkScales(){const t=this.chart,e=this._cachedMeta,s=this.getDataset(),n=(d,u,f,g)=>d==="x"?u:d==="r"?g:f,o=e.xAxisID=P(s.xAxisID,ii(t,"x")),r=e.yAxisID=P(s.yAxisID,ii(t,"y")),a=e.rAxisID=P(s.rAxisID,ii(t,"r")),l=e.indexAxis,c=e.iAxisID=n(l,o,r,a),h=e.vAxisID=n(l,r,o,a);e.xScale=this.getScaleForId(o),e.yScale=this.getScaleForId(r),e.rScale=this.getScaleForId(a),e.iScale=this.getScaleForId(c),e.vScale=this.getScaleForId(h)}getDataset(){return this.chart.data.datasets[this.index]}getMeta(){return this.chart.getDatasetMeta(this.index)}getScaleForId(t){return this.chart.scales[t]}_getOtherScale(t){const e=this._cachedMeta;return t===e.iScale?e.vScale:e.iScale}reset(){this._update("reset")}_destroy(){const t=this._cachedMeta;this._data&&Ri(this._data,this),t._stacked&&Qt(t)}_dataCheck(){const t=this.getDataset(),e=t.data||(t.data=[]),s=this._data;if(O(e)){const n=this._cachedMeta;this._data=Vr(e,n)}else if(s!==e){if(s){Ri(s,this);const n=this._cachedMeta;Qt(n),n._parsed=[]}e&&Object.isExtensible(e)&&Oo(e,this),this._syncList=[],this._data=e}}addElements(){const t=this._cachedMeta;this._dataCheck(),this.datasetElementType&&(t.dataset=new this.datasetElementType)}buildOrUpdateElements(t){const e=this._cachedMeta,s=this.getDataset();let n=!1;this._dataCheck();const o=e._stacked;e._stacked=ei(e.vScale,e),e.stack!==s.stack&&(n=!0,Qt(e),e.stack=s.stack),this._resyncElements(t),(n||o!==e._stacked)&&(xs(this,e._parsed),e._stacked=ei(e.vScale,e))}configure(){const t=this.chart.config,e=t.datasetScopeKeys(this._type),s=t.getOptionScopes(this.getDataset(),e,!0);this.options=t.createResolver(s,this.getContext()),this._parsing=this.options.parsing,this._cachedDataOpts={}}parse(t,e){const{_cachedMeta:s,_data:n}=this,{iScale:o,_stacked:r}=s,a=o.axis;let l=t===0&&e===n.length?!0:s._sorted,c=t>0&&s._parsed[t-1],h,d,u;if(this._parsing===!1)s._parsed=n,s._sorted=!0,u=n;else{V(n[t])?u=this.parseArrayData(s,n,t,e):O(n[t])?u=this.parseObjectData(s,n,t,e):u=this.parsePrimitiveData(s,n,t,e);const f=()=>d[a]===null||c&&d[a]p||d=0;--u)if(!g()){this.updateRangeFromParsed(c,t,f,l);break}}return c}getAllParsedValues(t){const e=this._cachedMeta._parsed,s=[];let n,o,r;for(n=0,o=e.length;n=0&&tthis.getContext(s,n,e),p=c.resolveNamedOptions(u,f,g,d);return p.$shared&&(p.$shared=l,o[r]=Object.freeze(_s(p,l))),p}_resolveAnimations(t,e,s){const n=this.chart,o=this._cachedDataOpts,r=`animation-${e}`,a=o[r];if(a)return a;let l;if(n.options.animation!==!1){const h=this.chart.config,d=h.datasetAnimationScopeKeys(this._type,e),u=h.getOptionScopes(this.getDataset(),d);l=h.createResolver(u,this.getContext(t,s,e))}const c=new ti(n,l&&l.animations);return l&&l._cacheable&&(o[r]=Object.freeze(c)),c}getSharedOptions(t){if(t.$shared)return this._sharedOptions||(this._sharedOptions=Object.assign({},t))}includeOptions(t,e){return!e||si(t)||this.chart._animationsDisabled}_getSharedOptions(t,e){const s=this.resolveDataElementOptions(t,e),n=this._sharedOptions,o=this.getSharedOptions(s),r=this.includeOptions(e,o)||o!==n;return this.updateSharedOptions(o,e,s),{sharedOptions:o,includeOptions:r}}updateElement(t,e,s,n){si(n)?Object.assign(t,s):this._resolveAnimations(e,n).update(t,s)}updateSharedOptions(t,e,s){t&&!si(e)&&this._resolveAnimations(void 0,e).update(t,s)}_setStyle(t,e,s,n){t.active=n;const o=this.getStyle(e,n);this._resolveAnimations(e,s,n).update(t,{options:!n&&this.getSharedOptions(o)||o})}removeHoverStyle(t,e,s){this._setStyle(t,s,"active",!1)}setHoverStyle(t,e,s){this._setStyle(t,s,"active",!0)}_removeDatasetHoverStyle(){const t=this._cachedMeta.dataset;t&&this._setStyle(t,void 0,"active",!1)}_setDatasetHoverStyle(){const t=this._cachedMeta.dataset;t&&this._setStyle(t,void 0,"active",!0)}_resyncElements(t){const e=this._data,s=this._cachedMeta.data;for(const[a,l,c]of this._syncList)this[a](l,c);this._syncList=[];const n=s.length,o=e.length,r=Math.min(o,n);r&&this.parse(0,r),o>n?this._insertElements(n,o-n,t):o{for(c.length+=e,a=c.length-1;a>=r;a--)c[a]=c[a-e]};for(l(o),a=t;an-o))}return i._cache.$bar}function Xr(i){const t=i.iScale,e=Yr(t,i.type);let s=t._length,n,o,r,a;const l=()=>{r===32767||r===-32768||(jt(a)&&(s=Math.min(s,Math.abs(r-a)||s)),a=r)};for(n=0,o=e.length;n0?n[i-1]:null,a=iMath.abs(a)&&(l=a,c=r),t[e.axis]=c,t._custom={barStart:l,barEnd:c,start:n,end:o,min:r,max:a}}function ys(i,t,e,s){return V(i)?qr(i,t,e,s):t[e.axis]=e.parse(i,s),t}function vs(i,t,e,s){const n=i.iScale,o=i.vScale,r=n.getLabels(),a=n===o,l=[];let c,h,d,u;for(c=e,h=e+s;c=e?1:-1)}function Qr(i){let t,e,s,n,o;return i.horizontal?(t=i.base>i.x,e="left",s="right"):(t=i.baseh.controller.options.grouped),o=s.options.stacked,r=[],a=this._cachedMeta.controller.getParsed(e),l=a&&a[s.axis],c=h=>{const d=h._parsed.find(f=>f[s.axis]===l),u=d&&d[h.vScale.axis];if(A(u)||isNaN(u))return!0};for(const h of n)if(!(e!==void 0&&c(h))&&((o===!1||r.indexOf(h.stack)===-1||o===void 0&&h.stack===void 0)&&r.push(h.stack),h.index===t))break;return r.length||r.push(void 0),r}_getStackCount(t){return this._getStacks(void 0,t).length}_getStackIndex(t,e,s){const n=this._getStacks(t,s),o=e!==void 0?n.indexOf(e):-1;return o===-1?n.length-1:o}_getRuler(){const t=this.options,e=this._cachedMeta,s=e.iScale,n=[];let o,r;for(o=0,r=e.data.length;o=0;--s)e=Math.max(e,t[s].size(this.resolveDataElementOptions(s))/2);return e>0&&e}getLabelAndValue(t){const e=this._cachedMeta,s=this.chart.data.labels||[],{xScale:n,yScale:o}=e,r=this.getParsed(t),a=n.getLabelForValue(r.x),l=o.getLabelForValue(r.y),c=r._custom;return{label:s[t]||"",value:"("+a+", "+l+(c?", "+c:"")+")"}}update(t){const e=this._cachedMeta.data;this.updateElements(e,0,e.length,t)}updateElements(t,e,s,n){const o=n==="reset",{iScale:r,vScale:a}=this._cachedMeta,{sharedOptions:l,includeOptions:c}=this._getSharedOptions(e,n),h=r.axis,d=a.axis;for(let u=e;uUt(v,a,l,!0)?1:Math.max(y,y*e,_,_*e),g=(v,y,_)=>Ut(v,a,l,!0)?-1:Math.min(y,y*e,_,_*e),p=f(0,c,d),m=f(H,h,u),b=g(I,c,d),x=g(I+H,h,u);s=(p-b)/2,n=(m-x)/2,o=-(p+b)/2,r=-(m+x)/2}return{ratioX:s,ratioY:n,offsetX:o,offsetY:r}}class Me extends ut{static id="doughnut";static defaults={datasetElementType:!1,dataElementType:"arc",animation:{animateRotate:!0,animateScale:!1},animations:{numbers:{type:"number",properties:["circumference","endAngle","innerRadius","outerRadius","startAngle","x","y","offset","borderWidth","spacing"]}},cutout:"50%",rotation:0,circumference:360,radius:"100%",spacing:0,indexAxis:"r"};static descriptors={_scriptable:t=>t!=="spacing",_indexable:t=>t!=="spacing"&&!t.startsWith("borderDash")&&!t.startsWith("hoverBorderDash")};static overrides={aspectRatio:1,plugins:{legend:{labels:{generateLabels(t){const e=t.data;if(e.labels.length&&e.datasets.length){const{labels:{pointStyle:s,color:n}}=t.legend.options;return e.labels.map((o,r)=>{const l=t.getDatasetMeta(0).controller.getStyle(r);return{text:o,fillStyle:l.backgroundColor,strokeStyle:l.borderColor,fontColor:n,lineWidth:l.borderWidth,pointStyle:s,hidden:!t.getDataVisibility(r),index:r}})}return[]}},onClick(t,e,s){s.chart.toggleDataVisibility(e.index),s.chart.update()}}}};constructor(t,e){super(t,e),this.enableOptionSharing=!0,this.innerRadius=void 0,this.outerRadius=void 0,this.offsetX=void 0,this.offsetY=void 0}linkScales(){}parse(t,e){const s=this.getDataset().data,n=this._cachedMeta;if(this._parsing===!1)n._parsed=s;else{let o=l=>+s[l];if(O(s[t])){const{key:l="value"}=this._parsing;o=c=>+gt(s[c],l)}let r,a;for(r=t,a=t+e;r0&&!isNaN(t)?z*(Math.abs(t)/e):0}getLabelAndValue(t){const e=this._cachedMeta,s=this.chart,n=s.data.labels||[],o=Xt(e._parsed[t],s.options.locale);return{label:n[t]||"",value:o}}getMaxBorderWidth(t){let e=0;const s=this.chart;let n,o,r,a,l;if(!t){for(n=0,o=s.data.datasets.length;n0&&this.getParsed(e-1);for(let _=0;_=x){k.skip=!0;continue}const S=this.getParsed(_),w=A(S[f]),D=k[u]=r.getPixelForValue(S[u],_),C=k[f]=o||w?a.getBasePixel():a.getPixelForValue(l?this.applyStack(a,S,l):S[f],_);k.skip=isNaN(D)||isNaN(C)||w,k.stop=_>0&&Math.abs(S[u]-y[u])>m,p&&(k.parsed=S,k.raw=c.data[_]),d&&(k.options=h||this.resolveDataElementOptions(_,M.active?"active":n)),b||this.updateElement(M,_,k,n),y=S}}getMaxOverflow(){const t=this._cachedMeta,e=t.dataset,s=e.options&&e.options.borderWidth||0,n=t.data||[];if(!n.length)return s;const o=n[0].size(this.resolveDataElementOptions(0)),r=n[n.length-1].size(this.resolveDataElementOptions(n.length-1));return Math.max(s,o,r)/2}draw(){const t=this._cachedMeta;t.dataset.updateControlPoints(this.chart.chartArea,t.iScale.axis),super.draw()}}class oi extends ut{static id="polarArea";static defaults={dataElementType:"arc",animation:{animateRotate:!0,animateScale:!0},animations:{numbers:{type:"number",properties:["x","y","startAngle","endAngle","innerRadius","outerRadius"]}},indexAxis:"r",startAngle:0};static overrides={aspectRatio:1,plugins:{legend:{labels:{generateLabels(t){const e=t.data;if(e.labels.length&&e.datasets.length){const{labels:{pointStyle:s,color:n}}=t.legend.options;return e.labels.map((o,r)=>{const l=t.getDatasetMeta(0).controller.getStyle(r);return{text:o,fillStyle:l.backgroundColor,strokeStyle:l.borderColor,fontColor:n,lineWidth:l.borderWidth,pointStyle:s,hidden:!t.getDataVisibility(r),index:r}})}return[]}},onClick(t,e,s){s.chart.toggleDataVisibility(e.index),s.chart.update()}}},scales:{r:{type:"radialLinear",angleLines:{display:!1},beginAtZero:!0,grid:{circular:!0},pointLabels:{display:!1},startAngle:0}}};constructor(t,e){super(t,e),this.innerRadius=void 0,this.outerRadius=void 0}getLabelAndValue(t){const e=this._cachedMeta,s=this.chart,n=s.data.labels||[],o=Xt(e._parsed[t].r,s.options.locale);return{label:n[t]||"",value:o}}parseObjectData(t,e,s,n){return Zi.bind(this)(t,e,s,n)}update(t){const e=this._cachedMeta.data;this._updateRadius(),this.updateElements(e,0,e.length,t)}getMinMax(){const t=this._cachedMeta,e={min:Number.POSITIVE_INFINITY,max:Number.NEGATIVE_INFINITY};return t.data.forEach((s,n)=>{const o=this.getParsed(n).r;!isNaN(o)&&this.chart.getDataVisibility(n)&&(oe.max&&(e.max=o))}),e}_updateRadius(){const t=this.chart,e=t.chartArea,s=t.options,n=Math.min(e.right-e.left,e.bottom-e.top),o=Math.max(n/2,0),r=Math.max(s.cutoutPercentage?o/100*s.cutoutPercentage:1,0),a=(o-r)/t.getVisibleDatasetCount();this.outerRadius=o-a*this.index,this.innerRadius=this.outerRadius-a}updateElements(t,e,s,n){const o=n==="reset",r=this.chart,l=r.options.animation,c=this._cachedMeta.rScale,h=c.xCenter,d=c.yCenter,u=c.getIndexAngle(0)-.5*I;let f=u,g;const p=360/this.countVisibleElements();for(g=0;g{!isNaN(this.getParsed(n).r)&&this.chart.getDataVisibility(n)&&e++}),e}_computeAngle(t,e,s){return this.chart.getDataVisibility(t)?it(this.resolveDataElementOptions(t,e).angle||s):0}}class Ds extends Me{static id="pie";static defaults={cutout:0,rotation:0,circumference:360,radius:"100%"}}class Cs extends ut{static id="radar";static defaults={datasetElementType:"line",dataElementType:"point",indexAxis:"r",showLine:!0,elements:{line:{fill:"start"}}};static overrides={aspectRatio:1,scales:{r:{type:"radialLinear"}}};getLabelAndValue(t){const e=this._cachedMeta.vScale,s=this.getParsed(t);return{label:e.getLabels()[t],value:""+e.getLabelForValue(s[e.axis])}}parseObjectData(t,e,s,n){return Zi.bind(this)(t,e,s,n)}update(t){const e=this._cachedMeta,s=e.dataset,n=e.data||[],o=e.iScale.getLabels();if(s.points=n,t!=="resize"){const r=this.resolveDatasetElementOptions(t);this.options.showLine||(r.borderWidth=0);const a={_loop:!0,_fullLoop:o.length===n.length,options:r};this.updateElement(s,void 0,a,t)}this.updateElements(n,0,n.length,t)}updateElements(t,e,s,n){const o=this._cachedMeta.rScale,r=n==="reset";for(let a=e;a0&&this.getParsed(e-1);for(let y=e;y0&&Math.abs(M[f]-v[f])>b,m&&(k.parsed=M,k.raw=c.data[y]),u&&(k.options=d||this.resolveDataElementOptions(y,_.active?"active":n)),x||this.updateElement(_,y,k,n),v=M}this.updateSharedOptions(d,n,h)}getMaxOverflow(){const t=this._cachedMeta,e=t.data||[];if(!this.options.showLine){let a=0;for(let l=e.length-1;l>=0;--l)a=Math.max(a,e[l].size(this.resolveDataElementOptions(l))/2);return a>0&&a}const s=t.dataset,n=s.options&&s.options.borderWidth||0;if(!e.length)return n;const o=e[0].size(this.resolveDataElementOptions(0)),r=e[e.length-1].size(this.resolveDataElementOptions(e.length-1));return Math.max(n,o,r)/2}}var Os=Object.freeze({__proto__:null,BarController:Ss,BubbleController:ws,DoughnutController:Me,LineController:Ps,PieController:Ds,PolarAreaController:oi,RadarController:Cs,ScatterController:As});function Ot(){throw new Error("This method is not implemented: Check that a complete date adapter is provided.")}class vi{static override(t){Object.assign(vi.prototype,t)}options;constructor(t){this.options=t||{}}init(){}formats(){return Ot()}parse(){return Ot()}format(){return Ot()}add(){return Ot()}diff(){return Ot()}startOf(){return Ot()}endOf(){return Ot()}}var Ls={_date:vi};function sa(i,t,e,s){const{controller:n,data:o,_sorted:r}=i,a=n._cachedMeta.iScale,l=i.dataset&&i.dataset.options?i.dataset.options.spanGaps:null;if(a&&t===a.axis&&t!=="r"&&r&&o.length){const c=a._reversePixels?Co:ht;if(s){if(n._sharedOptions){const h=o[0],d=typeof h.getRange=="function"&&h.getRange(t);if(d){const u=c(o,t,e-d),f=c(o,t,e+d);return{lo:u.lo,hi:f.hi}}}}else{const h=c(o,t,e);if(l){const{vScale:d}=n._cachedMeta,{_parsed:u}=i,f=u.slice(0,h.lo+1).reverse().findIndex(p=>!A(p[d.axis]));h.lo-=Math.max(0,f);const g=u.slice(h.hi).findIndex(p=>!A(p[d.axis]));h.hi+=Math.max(0,g)}return h}}return{lo:0,hi:o.length-1}}function Zt(i,t,e,s,n){const o=i.getSortedVisibleDatasetMetas(),r=e[t];for(let a=0,l=o.length;a{l[r]&&l[r](t[e],n)&&(o.push({element:l,datasetIndex:c,index:h}),a=a||l.inRange(t.x,t.y,n))}),s&&!a?[]:o}var Rs={evaluateInteractionItems:Zt,modes:{index(i,t,e,s){const n=Ct(t,i),o=e.axis||"x",r=e.includeInvisible||!1,a=e.intersect?ri(i,n,o,s,r):ai(i,n,o,!1,s,r),l=[];return a.length?(i.getSortedVisibleDatasetMetas().forEach(c=>{const h=a[0].index,d=c.data[h];d&&!d.skip&&l.push({element:d,datasetIndex:c.index,index:h})}),l):[]},dataset(i,t,e,s){const n=Ct(t,i),o=e.axis||"xy",r=e.includeInvisible||!1;let a=e.intersect?ri(i,n,o,s,r):ai(i,n,o,!1,s,r);if(a.length>0){const l=a[0].datasetIndex,c=i.getDatasetMeta(l).data;a=[];for(let h=0;he.pos===t)}function Is(i,t){return i.filter(e=>Es.indexOf(e.pos)===-1&&e.box.axis===t)}function ee(i,t){return i.sort((e,s)=>{const n=t?s:e,o=t?e:s;return n.weight===o.weight?n.index-o.index:n.weight-o.weight})}function aa(i){const t=[];let e,s,n,o,r,a;for(e=0,s=(i||[]).length;ec.box.fullSize),!0),s=ee(te(t,"left"),!0),n=ee(te(t,"right")),o=ee(te(t,"top"),!0),r=ee(te(t,"bottom")),a=Is(t,"x"),l=Is(t,"y");return{fullSize:e,leftAndTop:s.concat(o),rightAndBottom:n.concat(l).concat(r).concat(a),chartArea:te(t,"chartArea"),vertical:s.concat(n).concat(l),horizontal:o.concat(r).concat(a)}}function zs(i,t,e,s){return Math.max(i[e],t[e])+Math.max(i[s],t[s])}function Fs(i,t){i.top=Math.max(i.top,t.top),i.left=Math.max(i.left,t.left),i.bottom=Math.max(i.bottom,t.bottom),i.right=Math.max(i.right,t.right)}function da(i,t,e,s){const{pos:n,box:o}=e,r=i.maxPadding;if(!O(n)){e.size&&(i[n]-=e.size);const d=s[e.stack]||{size:0,count:1};d.size=Math.max(d.size,e.horizontal?o.height:o.width),e.size=d.size/d.count,i[n]+=e.size}o.getPadding&&Fs(r,o.getPadding());const a=Math.max(0,t.outerWidth-zs(r,i,"left","right")),l=Math.max(0,t.outerHeight-zs(r,i,"top","bottom")),c=a!==i.w,h=l!==i.h;return i.w=a,i.h=l,e.horizontal?{same:c,other:h}:{same:h,other:c}}function ua(i){const t=i.maxPadding;function e(s){const n=Math.max(t[s]-i[s],0);return i[s]+=n,n}i.y+=e("top"),i.x+=e("left"),e("right"),e("bottom")}function fa(i,t){const e=t.maxPadding;function s(n){const o={left:0,top:0,right:0,bottom:0};return n.forEach(r=>{o[r]=Math.max(t[r],e[r])}),o}return s(i?["left","right"]:["top","bottom"])}function ie(i,t,e,s){const n=[];let o,r,a,l,c,h;for(o=0,r=i.length,c=0;o{typeof p.beforeLayout=="function"&&p.beforeLayout()});const h=l.reduce((p,m)=>m.box.options&&m.box.options.display===!1?p:p+1,0)||1,d=Object.freeze({outerWidth:t,outerHeight:e,padding:n,availableWidth:o,availableHeight:r,vBoxMaxWidth:o/2/h,hBoxMaxHeight:r/2}),u=Object.assign({},n);Fs(u,G(s));const f=Object.assign({maxPadding:u,w:o,h:r,x:n.left,y:n.top},n),g=ca(l.concat(c),d);ie(a.fullSize,f,d,g),ie(l,f,d,g),ie(c,f,d,g)&&ie(l,f,d,g),ua(f),Bs(a.leftAndTop,f,d,g),f.x+=f.w,f.y+=f.h,Bs(a.rightAndBottom,f,d,g),i.chartArea={left:f.left,top:f.top,right:f.left+f.w,bottom:f.top+f.h,height:f.h,width:f.w},T(a.chartArea,p=>{const m=p.box;Object.assign(m,i.chartArea),m.update(f.w,f.h,{left:0,top:0,right:0,bottom:0})})}};class li{acquireContext(t,e){}releaseContext(t){return!1}addEventListener(t,e,s){}removeEventListener(t,e,s){}getDevicePixelRatio(){return 1}getMaximumSize(t,e,s,n){return e=Math.max(0,e||t.width),s=s||t.height,{width:e,height:Math.max(0,n?Math.floor(e/n):s)}}isAttached(t){return!0}updateConfig(t){}}class Vs extends li{acquireContext(t){return t&&t.getContext&&t.getContext("2d")||null}updateConfig(t){t.options.animation=!1}}const Se="$chartjs",ga={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"},Ws=i=>i===null||i==="";function pa(i,t){const e=i.style,s=i.getAttribute("height"),n=i.getAttribute("width");if(i[Se]={initial:{height:s,width:n,style:{display:e.display,height:e.height,width:e.width}}},e.display=e.display||"block",e.boxSizing=e.boxSizing||"border-box",Ws(n)){const o=is(i,"width");o!==void 0&&(i.width=o)}if(Ws(s))if(i.style.height==="")i.height=i.width/(t||2);else{const o=is(i,"height");o!==void 0&&(i.height=o)}return i}const Ns=vr?{passive:!0}:!1;function ma(i,t,e){i&&i.addEventListener(t,e,Ns)}function ba(i,t,e){i&&i.canvas&&i.canvas.removeEventListener(t,e,Ns)}function xa(i,t){const e=ga[i.type]||i.type,{x:s,y:n}=Ct(i,t);return{type:e,chart:t,native:i,x:s!==void 0?s:null,y:n!==void 0?n:null}}function we(i,t){for(const e of i)if(e===t||e.contains(t))return!0}function _a(i,t,e){const s=i.canvas,n=new MutationObserver(o=>{let r=!1;for(const a of o)r=r||we(a.addedNodes,s),r=r&&!we(a.removedNodes,s);r&&e()});return n.observe(document,{childList:!0,subtree:!0}),n}function ya(i,t,e){const s=i.canvas,n=new MutationObserver(o=>{let r=!1;for(const a of o)r=r||we(a.removedNodes,s),r=r&&!we(a.addedNodes,s);r&&e()});return n.observe(document,{childList:!0,subtree:!0}),n}const se=new Map;let Hs=0;function js(){const i=window.devicePixelRatio;i!==Hs&&(Hs=i,se.forEach((t,e)=>{e.currentDevicePixelRatio!==i&&t()}))}function va(i,t){se.size||window.addEventListener("resize",js),se.set(i,t)}function Ma(i){se.delete(i),se.size||window.removeEventListener("resize",js)}function ka(i,t,e){const s=i.canvas,n=s&&Ze(s);if(!n)return;const o=zi((a,l)=>{const c=n.clientWidth;e(a,l),c{const l=a[0],c=l.contentRect.width,h=l.contentRect.height;c===0&&h===0||o(c,h)});return r.observe(n),va(i,o),r}function ci(i,t,e){e&&e.disconnect(),t==="resize"&&Ma(i)}function Sa(i,t,e){const s=i.canvas,n=zi(o=>{i.ctx!==null&&e(xa(o,i))},i);return ma(s,t,n),n}class $s extends li{acquireContext(t,e){const s=t&&t.getContext&&t.getContext("2d");return s&&s.canvas===t?(pa(t,e),s):null}releaseContext(t){const e=t.canvas;if(!e[Se])return!1;const s=e[Se].initial;["height","width"].forEach(o=>{const r=s[o];A(r)?e.removeAttribute(o):e.setAttribute(o,r)});const n=s.style||{};return Object.keys(n).forEach(o=>{e.style[o]=n[o]}),e.width=e.width,delete e[Se],!0}addEventListener(t,e,s){this.removeEventListener(t,e);const n=t.$proxies||(t.$proxies={}),r={attach:_a,detach:ya,resize:ka}[e]||Sa;n[e]=r(t,e,s)}removeEventListener(t,e){const s=t.$proxies||(t.$proxies={}),n=s[e];if(!n)return;({attach:ci,detach:ci,resize:ci}[e]||ba)(t,e,n),s[e]=void 0}getDevicePixelRatio(){return window.devicePixelRatio}getMaximumSize(t,e,s,n){return yr(t,e,s,n)}isAttached(t){const e=t&&Ze(t);return!!(e&&e.isConnected)}}function Us(i){return!Qe()||typeof OffscreenCanvas<"u"&&i instanceof OffscreenCanvas?Vs:$s}class rt{static defaults={};static defaultRoutes=void 0;x;y;active=!1;options;$animations;tooltipPosition(t){const{x:e,y:s}=this.getProps(["x","y"],t);return{x:e,y:s}}hasValue(){return Et(this.x)&&Et(this.y)}getProps(t,e){const s=this.$animations;if(!e||!s)return this;const n={};return t.forEach(o=>{n[o]=s[o]&&s[o].active()?s[o]._to:this[o]}),n}}function wa(i,t){const e=i.options.ticks,s=Pa(i),n=Math.min(e.maxTicksLimit||s,s),o=e.major.enabled?Ca(t):[],r=o.length,a=o[0],l=o[r-1],c=[];if(r>n)return Aa(t,c,o,r/n),c;const h=Da(o,t,n);if(r>0){let d,u;const f=r>1?Math.round((l-a)/(r-1)):null;for(Pe(t,c,h,A(f)?0:a-f,a),d=0,u=r-1;dn)return l}return Math.max(n,1)}function Ca(i){const t=[];let e,s;for(e=0,s=i.length;ei==="left"?"right":i==="right"?"left":i,Ys=(i,t,e)=>t==="top"||t==="left"?i[t]+e:i[t]-e,Xs=(i,t)=>Math.min(t||i,i);function Ks(i,t){const e=[],s=i.length/t,n=i.length;let o=0;for(;or+a)))return l}function Ra(i,t){T(i,e=>{const s=e.gc,n=s.length/2;let o;if(n>t){for(o=0;os?s:e,s=n&&e>s?e:s,{min:Z(e,Z(s,e)),max:Z(s,Z(e,s))}}getPadding(){return{left:this.paddingLeft||0,top:this.paddingTop||0,right:this.paddingRight||0,bottom:this.paddingBottom||0}}getTicks(){return this.ticks}getLabels(){const t=this.chart.data;return this.options.labels||(this.isHorizontal()?t.xLabels:t.yLabels)||t.labels||[]}getLabelItems(t=this.chart.chartArea){return this._labelItems||(this._labelItems=this._computeLabelItems(t))}beforeLayout(){this._cache={},this._dataLimitsCached=!1}beforeUpdate(){E(this.options.beforeUpdate,[this])}update(t,e,s){const{beginAtZero:n,grace:o,ticks:r}=this.options,a=r.sampleSize;this.beforeUpdate(),this.maxWidth=t,this.maxHeight=e,this._margins=s=Object.assign({left:0,right:0,top:0,bottom:0},s),this.ticks=null,this._labelSizes=null,this._gridLineItems=null,this._labelItems=null,this.beforeSetDimensions(),this.setDimensions(),this.afterSetDimensions(),this._maxLength=this.isHorizontal()?this.width+s.left+s.right:this.height+s.top+s.bottom,this._dataLimitsCached||(this.beforeDataLimits(),this.determineDataLimits(),this.afterDataLimits(),this._range=Qo(this,o,n),this._dataLimitsCached=!0),this.beforeBuildTicks(),this.ticks=this.buildTicks()||[],this.afterBuildTicks();const l=a=o||s<=1||!this.isHorizontal()){this.labelRotation=n;return}const h=this._getLabelSizes(),d=h.widest.width,u=h.highest.height,f=$(this.chart.width-d,0,this.maxWidth);a=t.offset?this.maxWidth/s:f/(s-1),d+6>a&&(a=f/(s-(t.offset?.5:1)),l=this.maxHeight-ne(t.grid)-e.padding-Gs(t.title,this.chart.options.font),c=Math.sqrt(d*d+u*u),r=Ve(Math.min(Math.asin($((h.highest.height+6)/a,-1,1)),Math.asin($(l/c,-1,1))-Math.asin($(u/c,-1,1)))),r=Math.max(n,Math.min(o,r))),this.labelRotation=r}afterCalculateLabelRotation(){E(this.options.afterCalculateLabelRotation,[this])}afterAutoSkip(){}beforeFit(){E(this.options.beforeFit,[this])}fit(){const t={width:0,height:0},{chart:e,options:{ticks:s,title:n,grid:o}}=this,r=this._isVisible(),a=this.isHorizontal();if(r){const l=Gs(n,e.options.font);if(a?(t.width=this.maxWidth,t.height=ne(o)+l):(t.height=this.maxHeight,t.width=ne(o)+l),s.display&&this.ticks.length){const{first:c,last:h,widest:d,highest:u}=this._getLabelSizes(),f=s.padding*2,g=it(this.labelRotation),p=Math.cos(g),m=Math.sin(g);if(a){const b=s.mirror?0:m*d.width+p*u.height;t.height=Math.min(this.maxHeight,t.height+b+f)}else{const b=s.mirror?0:p*d.width+m*u.height;t.width=Math.min(this.maxWidth,t.width+b+f)}this._calculatePadding(c,h,m,p)}}this._handleMargins(),a?(this.width=this._length=e.width-this._margins.left-this._margins.right,this.height=t.height):(this.width=t.width,this.height=this._length=e.height-this._margins.top-this._margins.bottom)}_calculatePadding(t,e,s,n){const{ticks:{align:o,padding:r},position:a}=this.options,l=this.labelRotation!==0,c=a!=="top"&&this.axis==="x";if(this.isHorizontal()){const h=this.getPixelForTick(0)-this.left,d=this.right-this.getPixelForTick(this.ticks.length-1);let u=0,f=0;l?c?(u=n*t.width,f=s*e.height):(u=s*t.height,f=n*e.width):o==="start"?f=e.width:o==="end"?u=t.width:o!=="inner"&&(u=t.width/2,f=e.width/2),this.paddingLeft=Math.max((u-h+r)*this.width/(this.width-h),0),this.paddingRight=Math.max((f-d+r)*this.width/(this.width-d),0)}else{let h=e.height/2,d=t.height/2;o==="start"?(h=0,d=t.height):o==="end"&&(h=e.height,d=0),this.paddingTop=h+r,this.paddingBottom=d+r}}_handleMargins(){this._margins&&(this._margins.left=Math.max(this.paddingLeft,this._margins.left),this._margins.top=Math.max(this.paddingTop,this._margins.top),this._margins.right=Math.max(this.paddingRight,this._margins.right),this._margins.bottom=Math.max(this.paddingBottom,this._margins.bottom))}afterFit(){E(this.options.afterFit,[this])}isHorizontal(){const{axis:t,position:e}=this.options;return e==="top"||e==="bottom"||t==="x"}isFullSize(){return this.options.fullSize}_convertTicksToLabels(t){this.beforeTickToLabelConversion(),this.generateTickLabels(t);let e,s;for(e=0,s=t.length;e({width:r[w]||0,height:a[w]||0});return{first:S(0),last:S(e-1),widest:S(M),highest:S(k),widths:r,heights:a}}getLabelForValue(t){return t}getPixelForValue(t,e){return NaN}getValueForPixel(t){}getPixelForTick(t){const e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t].value)}getPixelForDecimal(t){this._reversePixels&&(t=1-t);const e=this._startPixel+t*this._length;return Do(this._alignToPixels?St(this.chart,e,0):e)}getDecimalForPixel(t){const e=(t-this._startPixel)/this._length;return this._reversePixels?1-e:e}getBasePixel(){return this.getPixelForValue(this.getBaseValue())}getBaseValue(){const{min:t,max:e}=this;return t<0&&e<0?e:t>0&&e>0?t:0}getContext(t){const e=this.ticks||[];if(t>=0&&ta*n?a/s:l/n:l*n0}_computeGridLineItems(t){const e=this.axis,s=this.chart,n=this.options,{grid:o,position:r,border:a}=n,l=o.offset,c=this.isHorizontal(),d=this.ticks.length+(l?1:0),u=ne(o),f=[],g=a.setContext(this.getContext()),p=g.display?g.width:0,m=p/2,b=function(B){return St(s,B,p)};let x,v,y,_,M,k,S,w,D,C,L,U;if(r==="top")x=b(this.bottom),k=this.bottom-u,w=x-m,C=b(t.top)+m,U=t.bottom;else if(r==="bottom")x=b(this.top),C=t.top,U=b(t.bottom)-m,k=x+m,w=this.top+u;else if(r==="left")x=b(this.right),M=this.right-u,S=x-m,D=b(t.left)+m,L=t.right;else if(r==="right")x=b(this.left),D=t.left,L=b(t.right)-m,M=x+m,S=this.left+u;else if(e==="x"){if(r==="center")x=b((t.top+t.bottom)/2+.5);else if(O(r)){const B=Object.keys(r)[0],N=r[B];x=b(this.chart.scales[B].getPixelForValue(N))}C=t.top,U=t.bottom,k=x+m,w=k+u}else if(e==="y"){if(r==="center")x=b((t.left+t.right)/2);else if(O(r)){const B=Object.keys(r)[0],N=r[B];x=b(this.chart.scales[B].getPixelForValue(N))}M=x-m,S=M-u,D=t.left,L=t.right}const Q=P(n.ticks.maxTicksLimit,d),R=Math.max(1,Math.ceil(d/Q));for(v=0;v0&&(vt-=yt/2);break}ce={left:vt,top:Wt,width:yt+Rt.width,height:Vt+Rt.height,color:R.backdropColor}}m.push({label:y,font:w,textOffset:L,options:{rotation:p,color:N,strokeColor:et,strokeWidth:X,textAlign:Tt,textBaseline:U,translation:[_,M],backdrop:ce}})}return m}_getXAxisLabelAlignment(){const{position:t,ticks:e}=this.options;if(-it(this.labelRotation))return t==="top"?"left":"right";let n="center";return e.align==="start"?n="left":e.align==="end"?n="right":e.align==="inner"&&(n="inner"),n}_getYAxisLabelAlignment(t){const{position:e,ticks:{crossAlign:s,mirror:n,padding:o}}=this.options,r=this._getLabelSizes(),a=t+o,l=r.widest.width;let c,h;return e==="left"?n?(h=this.right+o,s==="near"?c="left":s==="center"?(c="center",h+=l/2):(c="right",h+=l)):(h=this.right-a,s==="near"?c="right":s==="center"?(c="center",h-=l/2):(c="left",h=this.left)):e==="right"?n?(h=this.left+o,s==="near"?c="right":s==="center"?(c="center",h-=l/2):(c="left",h-=l)):(h=this.left+a,s==="near"?c="left":s==="center"?(c="center",h+=l/2):(c="right",h=this.right)):c="right",{textAlign:c,x:h}}_computeLabelArea(){if(this.options.ticks.mirror)return;const t=this.chart,e=this.options.position;if(e==="left"||e==="right")return{top:0,left:this.left,bottom:t.height,right:this.right};if(e==="top"||e==="bottom")return{top:this.top,left:0,bottom:this.bottom,right:t.width}}drawBackground(){const{ctx:t,options:{backgroundColor:e},left:s,top:n,width:o,height:r}=this;e&&(t.save(),t.fillStyle=e,t.fillRect(s,n,o,r),t.restore())}getLineWidthForValue(t){const e=this.options.grid;if(!this._isVisible()||!e.display)return 0;const n=this.ticks.findIndex(o=>o.value===t);return n>=0?e.setContext(this.getContext(n)).lineWidth:0}drawGrid(t){const e=this.options.grid,s=this.ctx,n=this._gridLineItems||(this._gridLineItems=this._computeGridLineItems(t));let o,r;const a=(l,c,h)=>{!h.width||!h.color||(s.save(),s.lineWidth=h.width,s.strokeStyle=h.color,s.setLineDash(h.borderDash||[]),s.lineDashOffset=h.borderDashOffset,s.beginPath(),s.moveTo(l.x,l.y),s.lineTo(c.x,c.y),s.stroke(),s.restore())};if(e.display)for(o=0,r=n.length;o{this.draw(o)}}]:[{z:s,draw:o=>{this.drawBackground(),this.drawGrid(o),this.drawTitle()}},{z:n,draw:()=>{this.drawBorder()}},{z:e,draw:o=>{this.drawLabels(o)}}]}getMatchingVisibleMetas(t){const e=this.chart.getSortedVisibleDatasetMetas(),s=this.axis+"AxisID",n=[];let o,r;for(o=0,r=e.length;o{const s=e.split("."),n=s.pop(),o=[i].concat(s).join("."),r=t[e].split("."),a=r.pop(),l=r.join(".");F.route(o,n,l,a)})}function Wa(i){return"id"in i&&"defaults"in i}class Na{constructor(){this.controllers=new De(ut,"datasets",!0),this.elements=new De(rt,"elements"),this.plugins=new De(Object,"plugins"),this.scales=new De(_t,"scales"),this._typedRegistries=[this.controllers,this.scales,this.elements]}add(...t){this._each("register",t)}remove(...t){this._each("unregister",t)}addControllers(...t){this._each("register",t,this.controllers)}addElements(...t){this._each("register",t,this.elements)}addPlugins(...t){this._each("register",t,this.plugins)}addScales(...t){this._each("register",t,this.scales)}getController(t){return this._get(t,this.controllers,"controller")}getElement(t){return this._get(t,this.elements,"element")}getPlugin(t){return this._get(t,this.plugins,"plugin")}getScale(t){return this._get(t,this.scales,"scale")}removeControllers(...t){this._each("unregister",t,this.controllers)}removeElements(...t){this._each("unregister",t,this.elements)}removePlugins(...t){this._each("unregister",t,this.plugins)}removeScales(...t){this._each("unregister",t,this.scales)}_each(t,e,s){[...e].forEach(n=>{const o=s||this._getRegistryForType(n);s||o.isForType(n)||o===this.plugins&&n.id?this._exec(t,o,n):T(n,r=>{const a=s||this._getRegistryForType(r);this._exec(t,a,r)})})}_exec(t,e,s){const n=Be(t);E(s["before"+n],[],s),e[t](s),E(s["after"+n],[],s)}_getRegistryForType(t){for(let e=0;eo.filter(a=>!r.some(l=>a.plugin.id===l.plugin.id));this._notify(n(e,s),t,"stop"),this._notify(n(s,e),t,"start")}}function ja(i){const t={},e=[],s=Object.keys(st.plugins.items);for(let o=0;o1&&qs(i[0].toLowerCase());if(s)return s}throw new Error(`Cannot determine type of '${i}' axis. Please provide 'axis' or 'position' option.`)}function Js(i,t,e){if(e[t+"AxisID"]===i)return{axis:t}}function qa(i,t){if(t.data&&t.data.datasets){const e=t.data.datasets.filter(s=>s.xAxisID===i||s.yAxisID===i);if(e.length)return Js(i,"x",e[0])||Js(i,"y",e[0])}return{}}function Ja(i,t){const e=kt[i.type]||{scales:{}},s=t.scales||{},n=hi(i.type,t),o=Object.create(null);return Object.keys(s).forEach(r=>{const a=s[r];if(!O(a))return console.error(`Invalid scale configuration for scale: ${r}`);if(a._proxy)return console.warn(`Ignoring resolver passed as options for scale: ${r}`);const l=di(r,a,qa(r,i),F.scales[a.type]),c=Ka(l,n),h=e.scales||{};o[r]=Ht(Object.create(null),[{axis:l},a,h[l],h[c]])}),i.data.datasets.forEach(r=>{const a=r.type||i.type,l=r.indexAxis||hi(a,t),h=(kt[a]||{}).scales||{};Object.keys(h).forEach(d=>{const u=Xa(d,l),f=r[u+"AxisID"]||u;o[f]=o[f]||Object.create(null),Ht(o[f],[{axis:u},s[f],h[d]])})}),Object.keys(o).forEach(r=>{const a=o[r];Ht(a,[F.scales[a.type],F.scale])}),o}function Qs(i){const t=i.options||(i.options={});t.plugins=P(t.plugins,{}),t.scales=Ja(i,t)}function Zs(i){return i=i||{},i.datasets=i.datasets||[],i.labels=i.labels||[],i}function Qa(i){return i=i||{},i.data=Zs(i.data),Qs(i),i}const tn=new Map,en=new Set;function Ce(i,t){let e=tn.get(i);return e||(e=t(),tn.set(i,e),en.add(e)),e}const oe=(i,t,e)=>{const s=gt(t,e);s!==void 0&&i.add(s)};class Za{constructor(t){this._config=Qa(t),this._scopeCache=new Map,this._resolverCache=new Map}get platform(){return this._config.platform}get type(){return this._config.type}set type(t){this._config.type=t}get data(){return this._config.data}set data(t){this._config.data=Zs(t)}get options(){return this._config.options}set options(t){this._config.options=t}get plugins(){return this._config.plugins}update(){const t=this._config;this.clearCache(),Qs(t)}clearCache(){this._scopeCache.clear(),this._resolverCache.clear()}datasetScopeKeys(t){return Ce(t,()=>[[`datasets.${t}`,""]])}datasetAnimationScopeKeys(t,e){return Ce(`${t}.transition.${e}`,()=>[[`datasets.${t}.transitions.${e}`,`transitions.${e}`],[`datasets.${t}`,""]])}datasetElementScopeKeys(t,e){return Ce(`${t}-${e}`,()=>[[`datasets.${t}.elements.${e}`,`datasets.${t}`,`elements.${e}`,""]])}pluginScopeKeys(t){const e=t.id,s=this.type;return Ce(`${s}-plugin-${e}`,()=>[[`plugins.${e}`,...t.additionalOptionScopes||[]]])}_cachedScopes(t,e){const s=this._scopeCache;let n=s.get(t);return(!n||e)&&(n=new Map,s.set(t,n)),n}getOptionScopes(t,e,s){const{options:n,type:o}=this,r=this._cachedScopes(t,s),a=r.get(e);if(a)return a;const l=new Set;e.forEach(h=>{t&&(l.add(t),h.forEach(d=>oe(l,t,d))),h.forEach(d=>oe(l,n,d)),h.forEach(d=>oe(l,kt[o]||{},d)),h.forEach(d=>oe(l,F,d)),h.forEach(d=>oe(l,Ue,d))});const c=Array.from(l);return c.length===0&&c.push(Object.create(null)),en.has(e)&&r.set(e,c),c}chartOptionScopes(){const{options:t,type:e}=this;return[t,kt[e]||{},F.datasets[e]||{},{type:e},F,Ue]}resolveNamedOptions(t,e,s,n=[""]){const o={$shared:!0},{resolver:r,subPrefixes:a}=sn(this._resolverCache,t,n);let l=r;if(el(r,e)){o.$shared=!1,s=pt(s)?s():s;const c=this.createResolver(t,s,a);l=It(r,s,c)}for(const c of e)o[c]=l[c];return o}createResolver(t,e,s=[""],n){const{resolver:o}=sn(this._resolverCache,t,s);return O(e)?It(o,e,void 0,n):o}}function sn(i,t,e){let s=i.get(t);s||(s=new Map,i.set(t,s));const n=e.join();let o=s.get(n);return o||(o={resolver:Ge(t,e),subPrefixes:e.filter(a=>!a.toLowerCase().includes("hover"))},s.set(n,o)),o}const tl=i=>O(i)&&Object.getOwnPropertyNames(i).some(t=>pt(i[t]));function el(i,t){const{isScriptable:e,isIndexable:s}=Xi(i);for(const n of t){const o=e(n),r=s(n),a=(r||o)&&i[n];if(o&&(pt(a)||tl(a))||r&&V(a))return!0}return!1}var il="4.4.9";const sl=["top","bottom","left","right","chartArea"];function nn(i,t){return i==="top"||i==="bottom"||sl.indexOf(i)===-1&&t==="x"}function on(i,t){return function(e,s){return e[i]===s[i]?e[t]-s[t]:e[i]-s[i]}}function rn(i){const t=i.chart,e=t.options.animation;t.notifyPlugins("afterRender"),E(e&&e.onComplete,[i],t)}function nl(i){const t=i.chart,e=t.options.animation;E(e&&e.onProgress,[i],t)}function an(i){return Qe()&&typeof i=="string"?i=document.getElementById(i):i&&i.length&&(i=i[0]),i&&i.canvas&&(i=i.canvas),i}const Ae={},ln=i=>{const t=an(i);return Object.values(Ae).filter(e=>e.canvas===t).pop()};function ol(i,t,e){const s=Object.keys(i);for(const n of s){const o=+n;if(o>=t){const r=i[n];delete i[n],(e>0||o>t)&&(i[o+e]=r)}}}function rl(i,t,e,s){return!e||i.type==="mouseout"?null:s?t:i}class Oe{static defaults=F;static instances=Ae;static overrides=kt;static registry=st;static version=il;static getChart=ln;static register(...t){st.add(...t),cn()}static unregister(...t){st.remove(...t),cn()}constructor(t,e){const s=this.config=new Za(e),n=an(t),o=ln(n);if(o)throw new Error("Canvas is already in use. Chart with ID '"+o.id+"' must be destroyed before the canvas with ID '"+o.canvas.id+"' can be reused.");const r=s.createResolver(s.chartOptionScopes(),this.getContext());this.platform=new(s.platform||Us(n)),this.platform.updateConfig(s);const a=this.platform.acquireContext(n,r.aspectRatio),l=a&&a.canvas,c=l&&l.height,h=l&&l.width;if(this.id=go(),this.ctx=a,this.canvas=l,this.width=h,this.height=c,this._options=r,this._aspectRatio=this.aspectRatio,this._layers=[],this._metasets=[],this._stacks=void 0,this.boxes=[],this.currentDevicePixelRatio=void 0,this.chartArea=void 0,this._active=[],this._lastEvent=void 0,this._listeners={},this._responsiveListeners=void 0,this._sortedMetasets=[],this.scales={},this._plugins=new Ha,this.$proxies={},this._hiddenIndices={},this.attached=!1,this._animationsDisabled=void 0,this.$context=void 0,this._doResize=Lo(d=>this.update(d),r.resizeDelay||0),this._dataChanges=[],Ae[this.id]=this,!a||!l){console.error("Failed to create chart: can't acquire context from the given item");return}ot.listen(this,"complete",rn),ot.listen(this,"progress",nl),this._initialize(),this.attached&&this.update()}get aspectRatio(){const{options:{aspectRatio:t,maintainAspectRatio:e},width:s,height:n,_aspectRatio:o}=this;return A(t)?e&&o?o:n?s/n:null:t}get data(){return this.config.data}set data(t){this.config.data=t}get options(){return this._options}set options(t){this.config.options=t}get registry(){return st}_initialize(){return this.notifyPlugins("beforeInit"),this.options.responsive?this.resize():es(this,this.options.devicePixelRatio),this.bindEvents(),this.notifyPlugins("afterInit"),this}clear(){return $i(this.canvas,this.ctx),this}stop(){return ot.stop(this),this}resize(t,e){ot.running(this)?this._resizeBeforeDraw={width:t,height:e}:this._resize(t,e)}_resize(t,e){const s=this.options,n=this.canvas,o=s.maintainAspectRatio&&this.aspectRatio,r=this.platform.getMaximumSize(n,t,e,o),a=s.devicePixelRatio||this.platform.getDevicePixelRatio(),l=this.width?"resize":"attach";this.width=r.width,this.height=r.height,this._aspectRatio=this.aspectRatio,es(this,a,!0)&&(this.notifyPlugins("resize",{size:r}),E(s.onResize,[this,r],this),this.attached&&this._doResize(l)&&this.render())}ensureScalesHaveIDs(){const e=this.options.scales||{};T(e,(s,n)=>{s.id=n})}buildOrUpdateScales(){const t=this.options,e=t.scales,s=this.scales,n=Object.keys(s).reduce((r,a)=>(r[a]=!1,r),{});let o=[];e&&(o=o.concat(Object.keys(e).map(r=>{const a=e[r],l=di(r,a),c=l==="r",h=l==="x";return{options:a,dposition:c?"chartArea":h?"bottom":"left",dtype:c?"radialLinear":h?"category":"linear"}}))),T(o,r=>{const a=r.options,l=a.id,c=di(l,a),h=P(a.type,r.dtype);(a.position===void 0||nn(a.position,c)!==nn(r.dposition))&&(a.position=r.dposition),n[l]=!0;let d=null;if(l in s&&s[l].type===h)d=s[l];else{const u=st.getScale(h);d=new u({id:l,type:h,ctx:this.ctx,chart:this}),s[d.id]=d}d.init(a,t)}),T(n,(r,a)=>{r||delete s[a]}),T(s,r=>{Y.configure(this,r,r.options),Y.addBox(this,r)})}_updateMetasets(){const t=this._metasets,e=this.data.datasets.length,s=t.length;if(t.sort((n,o)=>n.index-o.index),s>e){for(let n=e;ne.length&&delete this._stacks,t.forEach((s,n)=>{e.filter(o=>o===s._dataset).length===0&&this._destroyDatasetMeta(n)})}buildOrUpdateControllers(){const t=[],e=this.data.datasets;let s,n;for(this._removeUnreferencedMetasets(),s=0,n=e.length;s{this.getDatasetMeta(e).controller.reset()},this)}reset(){this._resetElements(),this.notifyPlugins("reset")}update(t){const e=this.config;e.update();const s=this._options=e.createResolver(e.chartOptionScopes(),this.getContext()),n=this._animationsDisabled=!s.animation;if(this._updateScales(),this._checkEventBindings(),this._updateHiddenIndices(),this._plugins.invalidate(),this.notifyPlugins("beforeUpdate",{mode:t,cancelable:!0})===!1)return;const o=this.buildOrUpdateControllers();this.notifyPlugins("beforeElementsUpdate");let r=0;for(let c=0,h=this.data.datasets.length;c{c.reset()}),this._updateDatasets(t),this.notifyPlugins("afterUpdate",{mode:t}),this._layers.sort(on("z","_idx"));const{_active:a,_lastEvent:l}=this;l?this._eventHandler(l,!0):a.length&&this._updateHoverStyles(a,a,!0),this.render()}_updateScales(){T(this.scales,t=>{Y.removeBox(this,t)}),this.ensureScalesHaveIDs(),this.buildOrUpdateScales()}_checkEventBindings(){const t=this.options,e=new Set(Object.keys(this._listeners)),s=new Set(t.events);(!Pi(e,s)||!!this._responsiveListeners!==t.responsive)&&(this.unbindEvents(),this.bindEvents())}_updateHiddenIndices(){const{_hiddenIndices:t}=this,e=this._getUniformDataChanges()||[];for(const{method:s,start:n,count:o}of e){const r=s==="_removeElements"?-o:o;ol(t,n,r)}}_getUniformDataChanges(){const t=this._dataChanges;if(!t||!t.length)return;this._dataChanges=[];const e=this.data.datasets.length,s=o=>new Set(t.filter(r=>r[0]===o).map((r,a)=>a+","+r.splice(1).join(","))),n=s(0);for(let o=1;oo.split(",")).map(o=>({method:o[1],start:+o[2],count:+o[3]}))}_updateLayout(t){if(this.notifyPlugins("beforeLayout",{cancelable:!0})===!1)return;Y.update(this,this.width,this.height,t);const e=this.chartArea,s=e.width<=0||e.height<=0;this._layers=[],T(this.boxes,n=>{s&&n.position==="chartArea"||(n.configure&&n.configure(),this._layers.push(...n._layers()))},this),this._layers.forEach((n,o)=>{n._idx=o}),this.notifyPlugins("afterLayout")}_updateDatasets(t){if(this.notifyPlugins("beforeDatasetsUpdate",{mode:t,cancelable:!0})!==!1){for(let e=0,s=this.data.datasets.length;e=0;--e)this._drawDataset(t[e]);this.notifyPlugins("afterDatasetsDraw")}_drawDataset(t){const e=this.ctx,s={meta:t,index:t.index,cancelable:!0},n=ds(this,t);this.notifyPlugins("beforeDatasetDraw",s)!==!1&&(n&&pe(e,n),t.controller.draw(),n&&me(e),s.cancelable=!1,this.notifyPlugins("afterDatasetDraw",s))}isPointInArea(t){return dt(t,this.chartArea,this._minPadding)}getElementsAtEventForMode(t,e,s,n){const o=Rs.modes[e];return typeof o=="function"?o(this,t,s,n):[]}getDatasetMeta(t){const e=this.data.datasets[t],s=this._metasets;let n=s.filter(o=>o&&o._dataset===e).pop();return n||(n={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null,order:e&&e.order||0,index:t,_dataset:e,_parsed:[],_sorted:!1},s.push(n)),n}getContext(){return this.$context||(this.$context=bt(null,{chart:this,type:"chart"}))}getVisibleDatasetCount(){return this.getSortedVisibleDatasetMetas().length}isDatasetVisible(t){const e=this.data.datasets[t];if(!e)return!1;const s=this.getDatasetMeta(t);return typeof s.hidden=="boolean"?!s.hidden:!e.hidden}setDatasetVisibility(t,e){const s=this.getDatasetMeta(t);s.hidden=!e}toggleDataVisibility(t){this._hiddenIndices[t]=!this._hiddenIndices[t]}getDataVisibility(t){return!this._hiddenIndices[t]}_updateVisibility(t,e,s){const n=s?"show":"hide",o=this.getDatasetMeta(t),r=o.controller._resolveAnimations(void 0,n);jt(e)?(o.data[e].hidden=!s,this.update()):(this.setDatasetVisibility(t,s),r.update(o,{visible:s}),this.update(a=>a.datasetIndex===t?n:void 0))}hide(t,e){this._updateVisibility(t,e,!1)}show(t,e){this._updateVisibility(t,e,!0)}_destroyDatasetMeta(t){const e=this._metasets[t];e&&e.controller&&e.controller._destroy(),delete this._metasets[t]}_stop(){let t,e;for(this.stop(),ot.remove(this),t=0,e=this.data.datasets.length;t{e.addEventListener(this,o,r),t[o]=r},n=(o,r,a)=>{o.offsetX=r,o.offsetY=a,this._eventHandler(o)};T(this.options.events,o=>s(o,n))}bindResponsiveEvents(){this._responsiveListeners||(this._responsiveListeners={});const t=this._responsiveListeners,e=this.platform,s=(l,c)=>{e.addEventListener(this,l,c),t[l]=c},n=(l,c)=>{t[l]&&(e.removeEventListener(this,l,c),delete t[l])},o=(l,c)=>{this.canvas&&this.resize(l,c)};let r;const a=()=>{n("attach",a),this.attached=!0,this.resize(),s("resize",o),s("detach",r)};r=()=>{this.attached=!1,n("resize",o),this._stop(),this._resize(0,0),s("attach",a)},e.isAttached(this.canvas)?a():r()}unbindEvents(){T(this._listeners,(t,e)=>{this.platform.removeEventListener(this,e,t)}),this._listeners={},T(this._responsiveListeners,(t,e)=>{this.platform.removeEventListener(this,e,t)}),this._responsiveListeners=void 0}updateHoverStyle(t,e,s){const n=s?"set":"remove";let o,r,a,l;for(e==="dataset"&&(o=this.getDatasetMeta(t[0].datasetIndex),o.controller["_"+n+"DatasetHoverStyle"]()),a=0,l=t.length;a{const a=this.getDatasetMeta(o);if(!a)throw new Error("No dataset found at index "+o);return{datasetIndex:o,element:a.data[r],index:r}});!he(s,e)&&(this._active=s,this._lastEvent=null,this._updateHoverStyles(s,e))}notifyPlugins(t,e,s){return this._plugins.notify(this,t,e,s)}isPluginEnabled(t){return this._plugins._cache.filter(e=>e.plugin.id===t).length===1}_updateHoverStyles(t,e,s){const n=this.options.hover,o=(l,c)=>l.filter(h=>!c.some(d=>h.datasetIndex===d.datasetIndex&&h.index===d.index)),r=o(e,t),a=s?t:o(t,e);r.length&&this.updateHoverStyle(r,n.mode,!1),a.length&&n.mode&&this.updateHoverStyle(a,n.mode,!0)}_eventHandler(t,e){const s={event:t,replay:e,cancelable:!0,inChartArea:this.isPointInArea(t)},n=r=>(r.options.events||this.options.events).includes(t.native.type);if(this.notifyPlugins("beforeEvent",s,n)===!1)return;const o=this._handleEvent(t,e,s.inChartArea);return s.cancelable=!1,this.notifyPlugins("afterEvent",s,n),(o||s.changed)&&this.render(),this}_handleEvent(t,e,s){const{_active:n=[],options:o}=this,r=e,a=this._getActiveElements(t,n,s,r),l=yo(t),c=rl(t,this._lastEvent,s,l);s&&(this._lastEvent=null,E(o.onHover,[t,a,this],this),l&&E(o.onClick,[t,a,this],this));const h=!he(a,n);return(h||e)&&(this._active=a,this._updateHoverStyles(a,n,e)),this._lastEvent=c,h}_getActiveElements(t,e,s,n){if(t.type==="mouseout")return[];if(!s)return e;const o=this.options.hover;return this.getElementsAtEventForMode(t,o.mode,o,n)}}function cn(){return T(Oe.instances,i=>i._plugins.invalidate())}function al(i,t,e){const{startAngle:s,pixelMargin:n,x:o,y:r,outerRadius:a,innerRadius:l}=t;let c=n/a;i.beginPath(),i.arc(o,r,a,s-c,e+c),l>n?(c=n/l,i.arc(o,r,l,e+c,s-c,!0)):i.arc(o,r,n,e+H,s-H),i.closePath(),i.clip()}function ll(i){return Ke(i,["outerStart","outerEnd","innerStart","innerEnd"])}function cl(i,t,e,s){const n=ll(i.options.borderRadius),o=(e-t)/2,r=Math.min(o,s*t/2),a=l=>{const c=(e-Math.min(o,l))*s/2;return $(l,0,Math.min(o,c))};return{outerStart:a(n.outerStart),outerEnd:a(n.outerEnd),innerStart:$(n.innerStart,0,r),innerEnd:$(n.innerEnd,0,r)}}function Bt(i,t,e,s){return{x:e+i*Math.cos(t),y:s+i*Math.sin(t)}}function Le(i,t,e,s,n,o){const{x:r,y:a,startAngle:l,pixelMargin:c,innerRadius:h}=t,d=Math.max(t.outerRadius+s+e-c,0),u=h>0?h+s+e+c:0;let f=0;const g=n-l;if(s){const R=h>0?h-s:0,B=d>0?d-s:0,N=(R+B)/2,et=N!==0?g*N/(N+s):g;f=(g-et)/2}const p=Math.max(.001,g*d-e/I)/d,m=(g-p)/2,b=l+m+f,x=n-m-f,{outerStart:v,outerEnd:y,innerStart:_,innerEnd:M}=cl(t,u,d,x-b),k=d-v,S=d-y,w=b+v/k,D=x-y/S,C=u+_,L=u+M,U=b+_/C,Q=x-M/L;if(i.beginPath(),o){const R=(w+D)/2;if(i.arc(r,a,d,w,R),i.arc(r,a,d,R,D),y>0){const X=Bt(S,D,r,a);i.arc(X.x,X.y,y,D,x+H)}const B=Bt(L,x,r,a);if(i.lineTo(B.x,B.y),M>0){const X=Bt(L,Q,r,a);i.arc(X.x,X.y,M,x+H,Q+Math.PI)}const N=(x-M/u+(b+_/u))/2;if(i.arc(r,a,u,x-M/u,N,!0),i.arc(r,a,u,N,b+_/u,!0),_>0){const X=Bt(C,U,r,a);i.arc(X.x,X.y,_,U+Math.PI,b-H)}const et=Bt(k,b,r,a);if(i.lineTo(et.x,et.y),v>0){const X=Bt(k,w,r,a);i.arc(X.x,X.y,v,b-H,w)}}else{i.moveTo(r,a);const R=Math.cos(w)*d+r,B=Math.sin(w)*d+a;i.lineTo(R,B);const N=Math.cos(D)*d+r,et=Math.sin(D)*d+a;i.lineTo(N,et)}i.closePath()}function hl(i,t,e,s,n){const{fullCircles:o,startAngle:r,circumference:a}=t;let l=t.endAngle;if(o){Le(i,t,e,s,l,n);for(let c=0;ct!=="borderDash"};circumference;endAngle;fullCircles;innerRadius;outerRadius;pixelMargin;startAngle;constructor(t){super(),this.options=void 0,this.circumference=void 0,this.startAngle=void 0,this.endAngle=void 0,this.innerRadius=void 0,this.outerRadius=void 0,this.pixelMargin=0,this.fullCircles=0,t&&Object.assign(this,t)}inRange(t,e,s){const n=this.getProps(["x","y"],s),{angle:o,distance:r}=Li(n,{x:t,y:e}),{startAngle:a,endAngle:l,innerRadius:c,outerRadius:h,circumference:d}=this.getProps(["startAngle","endAngle","innerRadius","outerRadius","circumference"],s),u=(this.options.spacing+this.options.borderWidth)/2,f=P(d,l-a),g=Ut(o,a,l)&&a!==l,p=f>=z||g,m=ct(r,c+u,h+u);return p&&m}getCenterPoint(t){const{x:e,y:s,startAngle:n,endAngle:o,innerRadius:r,outerRadius:a}=this.getProps(["x","y","startAngle","endAngle","innerRadius","outerRadius"],t),{offset:l,spacing:c}=this.options,h=(n+o)/2,d=(r+a+c+l)/2;return{x:e+Math.cos(h)*d,y:s+Math.sin(h)*d}}tooltipPosition(t){return this.getCenterPoint(t)}draw(t){const{options:e,circumference:s}=this,n=(e.offset||0)/4,o=(e.spacing||0)/2,r=e.circular;if(this.pixelMargin=e.borderAlign==="inner"?.33:0,this.fullCircles=s>z?Math.floor(s/z):0,s===0||this.innerRadius<0||this.outerRadius<0)return;t.save();const a=(this.startAngle+this.endAngle)/2;t.translate(Math.cos(a)*n,Math.sin(a)*n);const l=1-Math.sin(Math.min(I,s||0)),c=n*l;t.fillStyle=e.backgroundColor,t.strokeStyle=e.borderColor,hl(t,this,c,o,r),dl(t,this,c,o,r),t.restore()}}function dn(i,t,e=t){i.lineCap=P(e.borderCapStyle,t.borderCapStyle),i.setLineDash(P(e.borderDash,t.borderDash)),i.lineDashOffset=P(e.borderDashOffset,t.borderDashOffset),i.lineJoin=P(e.borderJoinStyle,t.borderJoinStyle),i.lineWidth=P(e.borderWidth,t.borderWidth),i.strokeStyle=P(e.borderColor,t.borderColor)}function ul(i,t,e){i.lineTo(e.x,e.y)}function fl(i){return i.stepped?jo:i.tension||i.cubicInterpolationMode==="monotone"?$o:ul}function un(i,t,e={}){const s=i.length,{start:n=0,end:o=s-1}=e,{start:r,end:a}=t,l=Math.max(n,r),c=Math.min(o,a),h=na&&o>a;return{count:s,start:l,loop:t.loop,ilen:c(r+(c?a-y:y))%o,v=()=>{p!==m&&(i.lineTo(h,m),i.lineTo(h,p),i.lineTo(h,b))};for(l&&(f=n[x(0)],i.moveTo(f.x,f.y)),u=0;u<=a;++u){if(f=n[x(u)],f.skip)continue;const y=f.x,_=f.y,M=y|0;M===g?(_m&&(m=_),h=(d*h+y)/++d):(v(),i.lineTo(y,_),g=M,d=0,p=m=_),b=_}v()}function ui(i){const t=i.options,e=t.borderDash&&t.borderDash.length;return!i._decimated&&!i._loop&&!t.tension&&t.cubicInterpolationMode!=="monotone"&&!t.stepped&&!e?pl:gl}function ml(i){return i.stepped?Mr:i.tension||i.cubicInterpolationMode==="monotone"?kr:At}function bl(i,t,e,s){let n=t._path;n||(n=t._path=new Path2D,t.path(n,e,s)&&n.closePath()),dn(i,t.options),i.stroke(n)}function xl(i,t,e,s){const{segments:n,options:o}=t,r=ui(t);for(const a of n)dn(i,o,a.style),i.beginPath(),r(i,t,a,{start:e,end:e+s-1})&&i.closePath(),i.stroke()}const _l=typeof Path2D=="function";function yl(i,t,e,s){_l&&!t.options.segment?bl(i,t,e,s):xl(i,t,e,s)}class re extends rt{static id="line";static defaults={borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",borderWidth:3,capBezierPoints:!0,cubicInterpolationMode:"default",fill:!1,spanGaps:!1,stepped:!1,tension:0};static defaultRoutes={backgroundColor:"backgroundColor",borderColor:"borderColor"};static descriptors={_scriptable:!0,_indexable:t=>t!=="borderDash"&&t!=="fill"};constructor(t){super(),this.animated=!0,this.options=void 0,this._chart=void 0,this._loop=void 0,this._fullLoop=void 0,this._path=void 0,this._points=void 0,this._segments=void 0,this._decimated=!1,this._pointsUpdated=!1,this._datasetIndex=void 0,t&&Object.assign(this,t)}updateControlPoints(t,e){const s=this.options;if((s.tension||s.cubicInterpolationMode==="monotone")&&!s.stepped&&!this._pointsUpdated){const n=s.spanGaps?this._loop:this._fullLoop;gr(this._points,s,t,n,e),this._pointsUpdated=!0}}set points(t){this._points=t,delete this._segments,delete this._path,this._pointsUpdated=!1}get points(){return this._points}get segments(){return this._segments||(this._segments=Ar(this,this.options.segment))}first(){const t=this.segments,e=this.points;return t.length&&e[t[0].start]}last(){const t=this.segments,e=this.points,s=t.length;return s&&e[t[s-1].end]}interpolate(t,e){const s=this.options,n=t[e],o=this.points,r=ls(this,{property:e,start:n,end:n});if(!r.length)return;const a=[],l=ml(s);let c,h;for(c=0,h=r.length;ci.replace("rgb(","rgba(").replace(")",", 0.5)"));function _n(i){return pi[i%pi.length]}function yn(i){return xn[i%xn.length]}function Pl(i,t){return i.borderColor=_n(t),i.backgroundColor=yn(t),++t}function Dl(i,t){return i.backgroundColor=i.data.map(()=>_n(t++)),t}function Cl(i,t){return i.backgroundColor=i.data.map(()=>yn(t++)),t}function Al(i){let t=0;return(e,s)=>{const n=i.getDatasetMeta(s).controller;n instanceof Me?t=Dl(e,t):n instanceof oi?t=Cl(e,t):n&&(t=Pl(e,t))}}function vn(i){let t;for(t in i)if(i[t].borderColor||i[t].backgroundColor)return!0;return!1}function Ol(i){return i&&(i.borderColor||i.backgroundColor)}function Ll(){return F.borderColor!=="rgba(0,0,0,0.1)"||F.backgroundColor!=="rgba(0,0,0,0.1)"}var Mn={id:"colors",defaults:{enabled:!0,forceOverride:!1},beforeLayout(i,t,e){if(!e.enabled)return;const{data:{datasets:s},options:n}=i.config,{elements:o}=n,r=vn(s)||Ol(n)||o&&vn(o)||Ll();if(!e.forceOverride&&r)return;const a=Al(i);s.forEach(a)}};function Tl(i,t,e,s,n){const o=n.samples||s;if(o>=e)return i.slice(t,t+e);const r=[],a=(e-2)/(o-2);let l=0;const c=t+e-1;let h=t,d,u,f,g,p;for(r[l++]=i[h],d=0;df&&(f=g,u=i[x],p=x);r[l++]=u,h=p}return r[l++]=i[c],r}function Rl(i,t,e,s){let n=0,o=0,r,a,l,c,h,d,u,f,g,p;const m=[],b=t+e-1,x=i[t].x,y=i[b].x-x;for(r=t;rp&&(p=c,u=r),n=(o*n+a.x)/++o;else{const M=r-1;if(!A(d)&&!A(u)){const k=Math.min(d,u),S=Math.max(d,u);k!==f&&k!==M&&m.push({...i[k],x:n}),S!==f&&S!==M&&m.push({...i[S],x:n})}r>0&&M!==f&&m.push(i[M]),m.push(a),h=_,o=0,g=p=c,d=u=f=r}}return m}function kn(i){if(i._decimated){const t=i._data;delete i._decimated,delete i._data,Object.defineProperty(i,"data",{configurable:!0,enumerable:!0,writable:!0,value:t})}}function Sn(i){i.data.datasets.forEach(t=>{kn(t)})}function El(i,t){const e=t.length;let s=0,n;const{iScale:o}=i,{min:r,max:a,minDefined:l,maxDefined:c}=o.getUserBounds();return l&&(s=$(ht(t,o.axis,r).lo,0,e-1)),c?n=$(ht(t,o.axis,a).hi+1,s,e)-s:n=e-s,{start:s,count:n}}var wn={id:"decimation",defaults:{algorithm:"min-max",enabled:!1},beforeElementsUpdate:(i,t,e)=>{if(!e.enabled){Sn(i);return}const s=i.width;i.data.datasets.forEach((n,o)=>{const{_data:r,indexAxis:a}=n,l=i.getDatasetMeta(o),c=r||n.data;if(Jt([a,i.options.indexAxis])==="y"||!l.controller.supportsDecimation)return;const h=i.scales[l.xAxisID];if(h.type!=="linear"&&h.type!=="time"||i.options.parsing)return;let{start:d,count:u}=El(l,c);const f=e.threshold||4*s;if(u<=f){kn(n);return}A(r)&&(n._data=c,delete n.data,Object.defineProperty(n,"data",{configurable:!0,enumerable:!0,get:function(){return this._decimated},set:function(p){this._data=p}}));let g;switch(e.algorithm){case"lttb":g=Tl(c,d,u,s,e);break;case"min-max":g=Rl(c,d,u,s);break;default:throw new Error(`Unsupported decimation algorithm '${e.algorithm}'`)}n._decimated=g})},destroy(i){Sn(i)}};function Il(i,t,e){const s=i.segments,n=i.points,o=t.points,r=[];for(const a of s){let{start:l,end:c}=a;c=bi(l,c,n);const h=mi(e,n[l],n[c],a.loop);if(!t.segments){r.push({source:a,target:h,start:n[l],end:n[c]});continue}const d=ls(t,h);for(const u of d){const f=mi(e,o[u.start],o[u.end],u.loop),g=as(a,n,f);for(const p of g)r.push({source:p,target:u,start:{[e]:Pn(h,f,"start",Math.max)},end:{[e]:Pn(h,f,"end",Math.min)}})}}return r}function mi(i,t,e,s){if(s)return;let n=t[i],o=e[i];return i==="angle"&&(n=tt(n),o=tt(o)),{property:i,start:n,end:o}}function zl(i,t){const{x:e=null,y:s=null}=i||{},n=t.points,o=[];return t.segments.forEach(({start:r,end:a})=>{a=bi(r,a,n);const l=n[r],c=n[a];s!==null?(o.push({x:l.x,y:s}),o.push({x:c.x,y:s})):e!==null&&(o.push({x:e,y:l.y}),o.push({x:e,y:c.y}))}),o}function bi(i,t,e){for(;t>i;t--){const s=e[t];if(!isNaN(s.x)&&!isNaN(s.y))break}return t}function Pn(i,t,e,s){return i&&t?s(i[e],t[e]):i?i[e]:t?t[e]:0}function Dn(i,t){let e=[],s=!1;return V(i)?(s=!0,e=i):e=zl(i,t),e.length?new re({points:e,options:{tension:0},_loop:s,_fullLoop:s}):null}function Cn(i){return i&&i.fill!==!1}function Fl(i,t,e){let n=i[t].fill;const o=[t];let r;if(!e)return n;for(;n!==!1&&o.indexOf(n)===-1;){if(!W(n))return n;if(r=i[n],!r)return!1;if(r.visible)return n;o.push(n),n=r.fill}return!1}function Bl(i,t,e){const s=Hl(i);if(O(s))return isNaN(s.value)?!1:s;let n=parseFloat(s);return W(n)&&Math.floor(n)===n?Vl(s[0],t,n,e):["origin","start","end","stack","shape"].indexOf(s)>=0&&s}function Vl(i,t,e,s){return(i==="-"||i==="+")&&(e=t+e),e===t||e<0||e>=s?!1:e}function Wl(i,t){let e=null;return i==="start"?e=t.bottom:i==="end"?e=t.top:O(i)?e=t.getPixelForValue(i.value):t.getBasePixel&&(e=t.getBasePixel()),e}function Nl(i,t,e){let s;return i==="start"?s=e:i==="end"?s=t.options.reverse?t.min:t.max:O(i)?s=i.value:s=t.getBaseValue(),s}function Hl(i){const t=i.options,e=t.fill;let s=P(e&&e.target,e);return s===void 0&&(s=!!t.backgroundColor),s===!1||s===null?!1:s===!0?"origin":s}function jl(i){const{scale:t,index:e,line:s}=i,n=[],o=s.segments,r=s.points,a=$l(t,e);a.push(Dn({x:null,y:t.bottom},s));for(let l=0;l=0;--r){const a=n[r].$filler;a&&(a.line.updateControlPoints(o,a.axis),s&&a.fill&&xi(i.ctx,a,o))}},beforeDatasetsDraw(i,t,e){if(e.drawTime!=="beforeDatasetsDraw")return;const s=i.getSortedVisibleDatasetMetas();for(let n=s.length-1;n>=0;--n){const o=s[n].$filler;Cn(o)&&xi(i.ctx,o,i.chartArea)}},beforeDatasetDraw(i,t,e){const s=t.meta.$filler;!Cn(s)||e.drawTime!=="beforeDatasetDraw"||xi(i.ctx,s,i.chartArea)},defaults:{propagate:!0,drawTime:"beforeDatasetDraw"}};const En=(i,t)=>{let{boxHeight:e=t,boxWidth:s=t}=i;return i.usePointStyle&&(e=Math.min(e,t),s=i.pointStyleWidth||Math.min(s,t)),{boxWidth:s,boxHeight:e,itemHeight:Math.max(t,e)}},tc=(i,t)=>i!==null&&t!==null&&i.datasetIndex===t.datasetIndex&&i.index===t.index;class In extends rt{constructor(t){super(),this._added=!1,this.legendHitBoxes=[],this._hoveredItem=null,this.doughnutMode=!1,this.chart=t.chart,this.options=t.options,this.ctx=t.ctx,this.legendItems=void 0,this.columnSizes=void 0,this.lineWidths=void 0,this.maxHeight=void 0,this.maxWidth=void 0,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.height=void 0,this.width=void 0,this._margins=void 0,this.position=void 0,this.weight=void 0,this.fullSize=void 0}update(t,e,s){this.maxWidth=t,this.maxHeight=e,this._margins=s,this.setDimensions(),this.buildLabels(),this.fit()}setDimensions(){this.isHorizontal()?(this.width=this.maxWidth,this.left=this._margins.left,this.right=this.width):(this.height=this.maxHeight,this.top=this._margins.top,this.bottom=this.height)}buildLabels(){const t=this.options.labels||{};let e=E(t.generateLabels,[this.chart],this)||[];t.filter&&(e=e.filter(s=>t.filter(s,this.chart.data))),t.sort&&(e=e.sort((s,n)=>t.sort(s,n,this.chart.data))),this.options.reverse&&e.reverse(),this.legendItems=e}fit(){const{options:t,ctx:e}=this;if(!t.display){this.width=this.height=0;return}const s=t.labels,n=j(s.font),o=n.size,r=this._computeTitleHeight(),{boxWidth:a,itemHeight:l}=En(s,o);let c,h;e.font=n.string,this.isHorizontal()?(c=this.maxWidth,h=this._fitRows(r,o,a,l)+10):(h=this.maxHeight,c=this._fitCols(r,n,a,l)+10),this.width=Math.min(c,t.maxWidth||this.maxWidth),this.height=Math.min(h,t.maxHeight||this.maxHeight)}_fitRows(t,e,s,n){const{ctx:o,maxWidth:r,options:{labels:{padding:a}}}=this,l=this.legendHitBoxes=[],c=this.lineWidths=[0],h=n+a;let d=t;o.textAlign="left",o.textBaseline="middle";let u=-1,f=-h;return this.legendItems.forEach((g,p)=>{const m=s+e/2+o.measureText(g.text).width;(p===0||c[c.length-1]+m+2*a>r)&&(d+=h,c[c.length-(p>0?0:1)]=0,f+=h,u++),l[p]={left:0,top:f,row:u,width:m,height:n},c[c.length-1]+=m+a}),d}_fitCols(t,e,s,n){const{ctx:o,maxHeight:r,options:{labels:{padding:a}}}=this,l=this.legendHitBoxes=[],c=this.columnSizes=[],h=r-t;let d=a,u=0,f=0,g=0,p=0;return this.legendItems.forEach((m,b)=>{const{itemWidth:x,itemHeight:v}=ec(s,e,o,m,n);b>0&&f+v+2*a>h&&(d+=u+a,c.push({width:u,height:f}),g+=u+a,p++,u=f=0),l[b]={left:g,top:f,col:p,width:x,height:v},u=Math.max(u,x),f+=v+a}),d+=u,c.push({width:u,height:f}),d}adjustHitBoxes(){if(!this.options.display)return;const t=this._computeTitleHeight(),{legendHitBoxes:e,options:{align:s,labels:{padding:n},rtl:o}}=this,r=Ft(o,this.left,this.width);if(this.isHorizontal()){let a=0,l=K(s,this.left+n,this.right-this.lineWidths[a]);for(const c of e)a!==c.row&&(a=c.row,l=K(s,this.left+n,this.right-this.lineWidths[a])),c.top+=this.top+t+n,c.left=r.leftForLtr(r.x(l),c.width),l+=c.width+n}else{let a=0,l=K(s,this.top+t+n,this.bottom-this.columnSizes[a].height);for(const c of e)c.col!==a&&(a=c.col,l=K(s,this.top+t+n,this.bottom-this.columnSizes[a].height)),c.top=l,c.left+=this.left+n,c.left=r.leftForLtr(r.x(c.left),c.width),l+=c.height+n}}isHorizontal(){return this.options.position==="top"||this.options.position==="bottom"}draw(){if(this.options.display){const t=this.ctx;pe(t,this),this._draw(),me(t)}}_draw(){const{options:t,columnSizes:e,lineWidths:s,ctx:n}=this,{align:o,labels:r}=t,a=F.color,l=Ft(t.rtl,this.left,this.width),c=j(r.font),{padding:h}=r,d=c.size,u=d/2;let f;this.drawTitle(),n.textAlign=l.textAlign("left"),n.textBaseline="middle",n.lineWidth=.5,n.font=c.string;const{boxWidth:g,boxHeight:p,itemHeight:m}=En(r,d),b=function(M,k,S){if(isNaN(g)||g<=0||isNaN(p)||p<0)return;n.save();const w=P(S.lineWidth,1);if(n.fillStyle=P(S.fillStyle,a),n.lineCap=P(S.lineCap,"butt"),n.lineDashOffset=P(S.lineDashOffset,0),n.lineJoin=P(S.lineJoin,"miter"),n.lineWidth=w,n.strokeStyle=P(S.strokeStyle,a),n.setLineDash(P(S.lineDash,[])),r.usePointStyle){const D={radius:p*Math.SQRT2/2,pointStyle:S.pointStyle,rotation:S.rotation,borderWidth:w},C=l.xPlus(M,g/2),L=k+u;Ui(n,D,C,L,r.pointStyleWidth&&g)}else{const D=k+Math.max((d-p)/2,0),C=l.leftForLtr(M,g),L=Pt(S.borderRadius);n.beginPath(),Object.values(L).some(U=>U!==0)?qt(n,{x:C,y:D,w:g,h:p,radius:L}):n.rect(C,D,g,p),n.fill(),w!==0&&n.stroke()}n.restore()},x=function(M,k,S){wt(n,S.text,M,k+m/2,c,{strikethrough:S.hidden,textAlign:l.textAlign(S.textAlign)})},v=this.isHorizontal(),y=this._computeTitleHeight();v?f={x:K(o,this.left+h,this.right-s[0]),y:this.top+h+y,line:0}:f={x:this.left+h,y:K(o,this.top+y+h,this.bottom-e[0].height),line:0},ss(this.ctx,t.textDirection);const _=m+h;this.legendItems.forEach((M,k)=>{n.strokeStyle=M.fontColor,n.fillStyle=M.fontColor;const S=n.measureText(M.text).width,w=l.textAlign(M.textAlign||(M.textAlign=r.textAlign)),D=g+u+S;let C=f.x,L=f.y;l.setWidth(this.width),v?k>0&&C+D+h>this.right&&(L=f.y+=_,f.line++,C=f.x=K(o,this.left+h,this.right-s[f.line])):k>0&&L+_>this.bottom&&(C=f.x=C+e[f.line].width+h,f.line++,L=f.y=K(o,this.top+y+h,this.bottom-e[f.line].height));const U=l.x(C);if(b(U,L,M),C=To(w,C+g+u,v?C+D:this.right,t.rtl),x(l.x(C),L,M),v)f.x+=D+h;else if(typeof M.text!="string"){const Q=c.lineHeight;f.y+=zn(M,Q)+h}else f.y+=_}),ns(this.ctx,t.textDirection)}drawTitle(){const t=this.options,e=t.title,s=j(e.font),n=G(e.padding);if(!e.display)return;const o=Ft(t.rtl,this.left,this.width),r=this.ctx,a=e.position,l=s.size/2,c=n.top+l;let h,d=this.left,u=this.width;if(this.isHorizontal())u=Math.max(...this.lineWidths),h=this.top+c,d=K(t.align,d,this.right-u);else{const g=this.columnSizes.reduce((p,m)=>Math.max(p,m.height),0);h=c+K(t.align,this.top,this.bottom-g-t.labels.padding-this._computeTitleHeight())}const f=K(a,d,d+u);r.textAlign=o.textAlign(He(a)),r.textBaseline="middle",r.strokeStyle=e.color,r.fillStyle=e.color,r.font=s.string,wt(r,e.text,f,h,s)}_computeTitleHeight(){const t=this.options.title,e=j(t.font),s=G(t.padding);return t.display?e.lineHeight+s.height:0}_getLegendItemAt(t,e){let s,n,o;if(ct(t,this.left,this.right)&&ct(e,this.top,this.bottom)){for(o=this.legendHitBoxes,s=0;so.length>r.length?o:r)),t+e.size/2+s.measureText(n).width}function sc(i,t,e){let s=i;return typeof t.text!="string"&&(s=zn(t,e)),s}function zn(i,t){const e=i.text?i.text.length:0;return t*e}function nc(i,t){return!!((i==="mousemove"||i==="mouseout")&&(t.onHover||t.onLeave)||t.onClick&&(i==="click"||i==="mouseup"))}var Fn={id:"legend",_element:In,start(i,t,e){const s=i.legend=new In({ctx:i.ctx,options:e,chart:i});Y.configure(i,s,e),Y.addBox(i,s)},stop(i){Y.removeBox(i,i.legend),delete i.legend},beforeUpdate(i,t,e){const s=i.legend;Y.configure(i,s,e),s.options=e},afterUpdate(i){const t=i.legend;t.buildLabels(),t.adjustHitBoxes()},afterEvent(i,t){t.replay||i.legend.handleEvent(t.event)},defaults:{display:!0,position:"top",align:"center",fullSize:!0,reverse:!1,weight:1e3,onClick(i,t,e){const s=t.datasetIndex,n=e.chart;n.isDatasetVisible(s)?(n.hide(s),t.hidden=!0):(n.show(s),t.hidden=!1)},onHover:null,onLeave:null,labels:{color:i=>i.chart.options.color,boxWidth:40,padding:10,generateLabels(i){const t=i.data.datasets,{labels:{usePointStyle:e,pointStyle:s,textAlign:n,color:o,useBorderRadius:r,borderRadius:a}}=i.legend.options;return i._getSortedDatasetMetas().map(l=>{const c=l.controller.getStyle(e?0:void 0),h=G(c.borderWidth);return{text:t[l.index].label,fillStyle:c.backgroundColor,fontColor:o,hidden:!l.visible,lineCap:c.borderCapStyle,lineDash:c.borderDash,lineDashOffset:c.borderDashOffset,lineJoin:c.borderJoinStyle,lineWidth:(h.width+h.height)/4,strokeStyle:c.borderColor,pointStyle:s||c.pointStyle,rotation:c.rotation,textAlign:n||c.textAlign,borderRadius:r&&(a||c.borderRadius),datasetIndex:l.index}},this)}},title:{color:i=>i.chart.options.color,display:!1,position:"center",text:""}},descriptors:{_scriptable:i=>!i.startsWith("on"),labels:{_scriptable:i=>!["generateLabels","filter","sort"].includes(i)}}};class _i extends rt{constructor(t){super(),this.chart=t.chart,this.options=t.options,this.ctx=t.ctx,this._padding=void 0,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.width=void 0,this.height=void 0,this.position=void 0,this.weight=void 0,this.fullSize=void 0}update(t,e){const s=this.options;if(this.left=0,this.top=0,!s.display){this.width=this.height=this.right=this.bottom=0;return}this.width=this.right=t,this.height=this.bottom=e;const n=V(s.text)?s.text.length:1;this._padding=G(s.padding);const o=n*j(s.font).lineHeight+this._padding.height;this.isHorizontal()?this.height=o:this.width=o}isHorizontal(){const t=this.options.position;return t==="top"||t==="bottom"}_drawArgs(t){const{top:e,left:s,bottom:n,right:o,options:r}=this,a=r.align;let l=0,c,h,d;return this.isHorizontal()?(h=K(a,s,o),d=e+t,c=o-s):(r.position==="left"?(h=s+t,d=K(a,n,e),l=I*-.5):(h=o-t,d=K(a,e,n),l=I*.5),c=n-e),{titleX:h,titleY:d,maxWidth:c,rotation:l}}draw(){const t=this.ctx,e=this.options;if(!e.display)return;const s=j(e.font),o=s.lineHeight/2+this._padding.top,{titleX:r,titleY:a,maxWidth:l,rotation:c}=this._drawArgs(o);wt(t,e.text,0,0,s,{color:e.color,maxWidth:l,rotation:c,textAlign:He(e.align),textBaseline:"middle",translation:[r,a]})}}function oc(i,t){const e=new _i({ctx:i.ctx,options:t,chart:i});Y.configure(i,e,t),Y.addBox(i,e),i.titleBlock=e}var Bn={id:"title",_element:_i,start(i,t,e){oc(i,e)},stop(i){const t=i.titleBlock;Y.removeBox(i,t),delete i.titleBlock},beforeUpdate(i,t,e){const s=i.titleBlock;Y.configure(i,s,e),s.options=e},defaults:{align:"center",display:!1,font:{weight:"bold"},fullSize:!0,padding:10,position:"top",text:"",weight:2e3},defaultRoutes:{color:"color"},descriptors:{_scriptable:!0,_indexable:!1}};const Te=new WeakMap;var Vn={id:"subtitle",start(i,t,e){const s=new _i({ctx:i.ctx,options:e,chart:i});Y.configure(i,s,e),Y.addBox(i,s),Te.set(i,s)},stop(i){Y.removeBox(i,Te.get(i)),Te.delete(i)},beforeUpdate(i,t,e){const s=Te.get(i);Y.configure(i,s,e),s.options=e},defaults:{align:"center",display:!1,font:{weight:"normal"},fullSize:!0,padding:0,position:"top",text:"",weight:1500},defaultRoutes:{color:"color"},descriptors:{_scriptable:!0,_indexable:!1}};const ae={average(i){if(!i.length)return!1;let t,e,s=new Set,n=0,o=0;for(t=0,e=i.length;ta+l)/s.size,y:n/o}},nearest(i,t){if(!i.length)return!1;let e=t.x,s=t.y,n=Number.POSITIVE_INFINITY,o,r,a;for(o=0,r=i.length;o-1?i.split(` +`):i}function rc(i,t){const{element:e,datasetIndex:s,index:n}=t,o=i.getDatasetMeta(s).controller,{label:r,value:a}=o.getLabelAndValue(n);return{chart:i,label:r,parsed:o.getParsed(n),raw:i.data.datasets[s].data[n],formattedValue:a,dataset:o.getDataset(),dataIndex:n,datasetIndex:s,element:e}}function Wn(i,t){const e=i.chart.ctx,{body:s,footer:n,title:o}=i,{boxWidth:r,boxHeight:a}=t,l=j(t.bodyFont),c=j(t.titleFont),h=j(t.footerFont),d=o.length,u=n.length,f=s.length,g=G(t.padding);let p=g.height,m=0,b=s.reduce((y,_)=>y+_.before.length+_.lines.length+_.after.length,0);if(b+=i.beforeBody.length+i.afterBody.length,d&&(p+=d*c.lineHeight+(d-1)*t.titleSpacing+t.titleMarginBottom),b){const y=t.displayColors?Math.max(a,l.lineHeight):l.lineHeight;p+=f*y+(b-f)*l.lineHeight+(b-1)*t.bodySpacing}u&&(p+=t.footerMarginTop+u*h.lineHeight+(u-1)*t.footerSpacing);let x=0;const v=function(y){m=Math.max(m,e.measureText(y).width+x)};return e.save(),e.font=c.string,T(i.title,v),e.font=l.string,T(i.beforeBody.concat(i.afterBody),v),x=t.displayColors?r+2+t.boxPadding:0,T(s,y=>{T(y.before,v),T(y.lines,v),T(y.after,v)}),x=0,e.font=h.string,T(i.footer,v),e.restore(),m+=g.width,{width:m,height:p}}function ac(i,t){const{y:e,height:s}=t;return ei.height-s/2?"bottom":"center"}function lc(i,t,e,s){const{x:n,width:o}=s,r=e.caretSize+e.caretPadding;if(i==="left"&&n+o+r>t.width||i==="right"&&n-o-r<0)return!0}function cc(i,t,e,s){const{x:n,width:o}=e,{width:r,chartArea:{left:a,right:l}}=i;let c="center";return s==="center"?c=n<=(a+l)/2?"left":"right":n<=o/2?c="left":n>=r-o/2&&(c="right"),lc(c,i,t,e)&&(c="center"),c}function Nn(i,t,e){const s=e.yAlign||t.yAlign||ac(i,e);return{xAlign:e.xAlign||t.xAlign||cc(i,t,e,s),yAlign:s}}function hc(i,t){let{x:e,width:s}=i;return t==="right"?e-=s:t==="center"&&(e-=s/2),e}function dc(i,t,e){let{y:s,height:n}=i;return t==="top"?s+=e:t==="bottom"?s-=n+e:s-=n/2,s}function Hn(i,t,e,s){const{caretSize:n,caretPadding:o,cornerRadius:r}=i,{xAlign:a,yAlign:l}=e,c=n+o,{topLeft:h,topRight:d,bottomLeft:u,bottomRight:f}=Pt(r);let g=hc(t,a);const p=dc(t,l,c);return l==="center"?a==="left"?g+=c:a==="right"&&(g-=c):a==="left"?g-=Math.max(h,u)+n:a==="right"&&(g+=Math.max(d,f)+n),{x:$(g,0,s.width-t.width),y:$(p,0,s.height-t.height)}}function Re(i,t,e){const s=G(e.padding);return t==="center"?i.x+i.width/2:t==="right"?i.x+i.width-s.right:i.x+s.left}function jn(i){return at([],ft(i))}function uc(i,t,e){return bt(i,{tooltip:t,tooltipItems:e,type:"tooltip"})}function $n(i,t){const e=t&&t.dataset&&t.dataset.tooltip&&t.dataset.tooltip.callbacks;return e?i.override(e):i}const Un={beforeTitle:lt,title(i){if(i.length>0){const t=i[0],e=t.chart.data.labels,s=e?e.length:0;if(this&&this.options&&this.options.mode==="dataset")return t.dataset.label||"";if(t.label)return t.label;if(s>0&&t.dataIndex"u"?Un[t].call(e,s):n}class Yn extends rt{static positioners=ae;constructor(t){super(),this.opacity=0,this._active=[],this._eventPosition=void 0,this._size=void 0,this._cachedAnimations=void 0,this._tooltipItems=[],this.$animations=void 0,this.$context=void 0,this.chart=t.chart,this.options=t.options,this.dataPoints=void 0,this.title=void 0,this.beforeBody=void 0,this.body=void 0,this.afterBody=void 0,this.footer=void 0,this.xAlign=void 0,this.yAlign=void 0,this.x=void 0,this.y=void 0,this.height=void 0,this.width=void 0,this.caretX=void 0,this.caretY=void 0,this.labelColors=void 0,this.labelPointStyles=void 0,this.labelTextColors=void 0}initialize(t){this.options=t,this._cachedAnimations=void 0,this.$context=void 0}_resolveAnimations(){const t=this._cachedAnimations;if(t)return t;const e=this.chart,s=this.options.setContext(this.getContext()),n=s.enabled&&e.options.animation&&s.animations,o=new ti(this.chart,n);return n._cacheable&&(this._cachedAnimations=Object.freeze(o)),o}getContext(){return this.$context||(this.$context=uc(this.chart.getContext(),this,this._tooltipItems))}getTitle(t,e){const{callbacks:s}=e,n=q(s,"beforeTitle",this,t),o=q(s,"title",this,t),r=q(s,"afterTitle",this,t);let a=[];return a=at(a,ft(n)),a=at(a,ft(o)),a=at(a,ft(r)),a}getBeforeBody(t,e){return jn(q(e.callbacks,"beforeBody",this,t))}getBody(t,e){const{callbacks:s}=e,n=[];return T(t,o=>{const r={before:[],lines:[],after:[]},a=$n(s,o);at(r.before,ft(q(a,"beforeLabel",this,o))),at(r.lines,q(a,"label",this,o)),at(r.after,ft(q(a,"afterLabel",this,o))),n.push(r)}),n}getAfterBody(t,e){return jn(q(e.callbacks,"afterBody",this,t))}getFooter(t,e){const{callbacks:s}=e,n=q(s,"beforeFooter",this,t),o=q(s,"footer",this,t),r=q(s,"afterFooter",this,t);let a=[];return a=at(a,ft(n)),a=at(a,ft(o)),a=at(a,ft(r)),a}_createItems(t){const e=this._active,s=this.chart.data,n=[],o=[],r=[];let a=[],l,c;for(l=0,c=e.length;lt.filter(h,d,u,s))),t.itemSort&&(a=a.sort((h,d)=>t.itemSort(h,d,s))),T(a,h=>{const d=$n(t.callbacks,h);n.push(q(d,"labelColor",this,h)),o.push(q(d,"labelPointStyle",this,h)),r.push(q(d,"labelTextColor",this,h))}),this.labelColors=n,this.labelPointStyles=o,this.labelTextColors=r,this.dataPoints=a,a}update(t,e){const s=this.options.setContext(this.getContext()),n=this._active;let o,r=[];if(!n.length)this.opacity!==0&&(o={opacity:0});else{const a=ae[s.position].call(this,n,this._eventPosition);r=this._createItems(s),this.title=this.getTitle(r,s),this.beforeBody=this.getBeforeBody(r,s),this.body=this.getBody(r,s),this.afterBody=this.getAfterBody(r,s),this.footer=this.getFooter(r,s);const l=this._size=Wn(this,s),c=Object.assign({},a,l),h=Nn(this.chart,s,c),d=Hn(s,c,h,this.chart);this.xAlign=h.xAlign,this.yAlign=h.yAlign,o={opacity:1,x:d.x,y:d.y,width:l.width,height:l.height,caretX:a.x,caretY:a.y}}this._tooltipItems=r,this.$context=void 0,o&&this._resolveAnimations().update(this,o),t&&s.external&&s.external.call(this,{chart:this.chart,tooltip:this,replay:e})}drawCaret(t,e,s,n){const o=this.getCaretPosition(t,s,n);e.lineTo(o.x1,o.y1),e.lineTo(o.x2,o.y2),e.lineTo(o.x3,o.y3)}getCaretPosition(t,e,s){const{xAlign:n,yAlign:o}=this,{caretSize:r,cornerRadius:a}=s,{topLeft:l,topRight:c,bottomLeft:h,bottomRight:d}=Pt(a),{x:u,y:f}=t,{width:g,height:p}=e;let m,b,x,v,y,_;return o==="center"?(y=f+p/2,n==="left"?(m=u,b=m-r,v=y+r,_=y-r):(m=u+g,b=m+r,v=y-r,_=y+r),x=m):(n==="left"?b=u+Math.max(l,h)+r:n==="right"?b=u+g-Math.max(c,d)-r:b=this.caretX,o==="top"?(v=f,y=v-r,m=b-r,x=b+r):(v=f+p,y=v+r,m=b+r,x=b-r),_=v),{x1:m,x2:b,x3:x,y1:v,y2:y,y3:_}}drawTitle(t,e,s){const n=this.title,o=n.length;let r,a,l;if(o){const c=Ft(s.rtl,this.x,this.width);for(t.x=Re(this,s.titleAlign,s),e.textAlign=c.textAlign(s.titleAlign),e.textBaseline="middle",r=j(s.titleFont),a=s.titleSpacing,e.fillStyle=s.titleColor,e.font=r.string,l=0;lx!==0)?(t.beginPath(),t.fillStyle=o.multiKeyBackground,qt(t,{x:p,y:g,w:c,h:l,radius:b}),t.fill(),t.stroke(),t.fillStyle=r.backgroundColor,t.beginPath(),qt(t,{x:m,y:g+1,w:c-2,h:l-2,radius:b}),t.fill()):(t.fillStyle=o.multiKeyBackground,t.fillRect(p,g,c,l),t.strokeRect(p,g,c,l),t.fillStyle=r.backgroundColor,t.fillRect(m,g+1,c-2,l-2))}t.fillStyle=this.labelTextColors[s]}drawBody(t,e,s){const{body:n}=this,{bodySpacing:o,bodyAlign:r,displayColors:a,boxHeight:l,boxWidth:c,boxPadding:h}=s,d=j(s.bodyFont);let u=d.lineHeight,f=0;const g=Ft(s.rtl,this.x,this.width),p=function(S){e.fillText(S,g.x(t.x+f),t.y+u/2),t.y+=u+o},m=g.textAlign(r);let b,x,v,y,_,M,k;for(e.textAlign=r,e.textBaseline="middle",e.font=d.string,t.x=Re(this,m,s),e.fillStyle=s.bodyColor,T(this.beforeBody,p),f=a&&m!=="right"?r==="center"?c/2+h:c+2+h:0,y=0,M=n.length;y0&&e.stroke()}_updateAnimationTarget(t){const e=this.chart,s=this.$animations,n=s&&s.x,o=s&&s.y;if(n||o){const r=ae[t.position].call(this,this._active,this._eventPosition);if(!r)return;const a=this._size=Wn(this,t),l=Object.assign({},r,this._size),c=Nn(e,t,l),h=Hn(t,l,c,e);(n._to!==h.x||o._to!==h.y)&&(this.xAlign=c.xAlign,this.yAlign=c.yAlign,this.width=a.width,this.height=a.height,this.caretX=r.x,this.caretY=r.y,this._resolveAnimations().update(this,h))}}_willRender(){return!!this.opacity}draw(t){const e=this.options.setContext(this.getContext());let s=this.opacity;if(!s)return;this._updateAnimationTarget(e);const n={width:this.width,height:this.height},o={x:this.x,y:this.y};s=Math.abs(s)<.001?0:s;const r=G(e.padding),a=this.title.length||this.beforeBody.length||this.body.length||this.afterBody.length||this.footer.length;e.enabled&&a&&(t.save(),t.globalAlpha=s,this.drawBackground(o,t,n,e),ss(t,e.textDirection),o.y+=r.top,this.drawTitle(o,t,e),this.drawBody(o,t,e),this.drawFooter(o,t,e),ns(t,e.textDirection),t.restore())}getActiveElements(){return this._active||[]}setActiveElements(t,e){const s=this._active,n=t.map(({datasetIndex:a,index:l})=>{const c=this.chart.getDatasetMeta(a);if(!c)throw new Error("Cannot find a dataset at index "+a);return{datasetIndex:a,element:c.data[l],index:l}}),o=!he(s,n),r=this._positionChanged(n,e);(o||r)&&(this._active=n,this._eventPosition=e,this._ignoreReplayEvents=!0,this.update(!0))}handleEvent(t,e,s=!0){if(e&&this._ignoreReplayEvents)return!1;this._ignoreReplayEvents=!1;const n=this.options,o=this._active||[],r=this._getActiveElements(t,o,e,s),a=this._positionChanged(r,t),l=e||!he(r,o)||a;return l&&(this._active=r,(n.enabled||n.external)&&(this._eventPosition={x:t.x,y:t.y},this.update(!0,e))),l}_getActiveElements(t,e,s,n){const o=this.options;if(t.type==="mouseout")return[];if(!n)return e.filter(a=>this.chart.data.datasets[a.datasetIndex]&&this.chart.getDatasetMeta(a.datasetIndex).controller.getParsed(a.index)!==void 0);const r=this.chart.getElementsAtEventForMode(t,o.mode,o,s);return o.reverse&&r.reverse(),r}_positionChanged(t,e){const{caretX:s,caretY:n,options:o}=this,r=ae[o.position].call(this,t,e);return r!==!1&&(s!==r.x||n!==r.y)}}var Xn={id:"tooltip",_element:Yn,positioners:ae,afterInit(i,t,e){e&&(i.tooltip=new Yn({chart:i,options:e}))},beforeUpdate(i,t,e){i.tooltip&&i.tooltip.initialize(e)},reset(i,t,e){i.tooltip&&i.tooltip.initialize(e)},afterDraw(i){const t=i.tooltip;if(t&&t._willRender()){const e={tooltip:t};if(i.notifyPlugins("beforeTooltipDraw",{...e,cancelable:!0})===!1)return;t.draw(i.ctx),i.notifyPlugins("afterTooltipDraw",e)}},afterEvent(i,t){if(i.tooltip){const e=t.replay;i.tooltip.handleEvent(t.event,e,t.inChartArea)&&(t.changed=!0)}},defaults:{enabled:!0,external:null,position:"average",backgroundColor:"rgba(0,0,0,0.8)",titleColor:"#fff",titleFont:{weight:"bold"},titleSpacing:2,titleMarginBottom:6,titleAlign:"left",bodyColor:"#fff",bodySpacing:2,bodyFont:{},bodyAlign:"left",footerColor:"#fff",footerSpacing:2,footerMarginTop:6,footerFont:{weight:"bold"},footerAlign:"left",padding:6,caretPadding:2,caretSize:5,cornerRadius:6,boxHeight:(i,t)=>t.bodyFont.size,boxWidth:(i,t)=>t.bodyFont.size,multiKeyBackground:"#fff",displayColors:!0,boxPadding:0,borderColor:"rgba(0,0,0,0)",borderWidth:0,animation:{duration:400,easing:"easeOutQuart"},animations:{numbers:{type:"number",properties:["x","y","width","height","caretX","caretY"]},opacity:{easing:"linear",duration:200}},callbacks:Un},defaultRoutes:{bodyFont:"font",footerFont:"font",titleFont:"font"},descriptors:{_scriptable:i=>i!=="filter"&&i!=="itemSort"&&i!=="external",_indexable:!1,callbacks:{_scriptable:!1,_indexable:!1},animation:{_fallback:!1},animations:{_fallback:"animation"}},additionalOptionScopes:["interaction"]},Kn=Object.freeze({__proto__:null,Colors:Mn,Decimation:wn,Filler:Rn,Legend:Fn,SubTitle:Vn,Title:Bn,Tooltip:Xn});const fc=(i,t,e,s)=>(typeof t=="string"?(e=i.push(t)-1,s.unshift({index:e,label:t})):isNaN(t)&&(e=null),e);function gc(i,t,e,s){const n=i.indexOf(t);if(n===-1)return fc(i,t,e,s);const o=i.lastIndexOf(t);return n!==o?e:n}const pc=(i,t)=>i===null?null:$(Math.round(i),0,t);function Gn(i){const t=this.getLabels();return i>=0&&ie.length-1?null:this.getPixelForValue(e[t].value)}getValueForPixel(t){return Math.round(this._startValue+this.getDecimalForPixel(t)*this._valueRange)}getBasePixel(){return this.bottom}}function mc(i,t){const e=[],{bounds:n,step:o,min:r,max:a,precision:l,count:c,maxTicks:h,maxDigits:d,includeBounds:u}=i,f=o||1,g=h-1,{min:p,max:m}=t,b=!A(r),x=!A(a),v=!A(c),y=(m-p)/(d+1);let _=Ci((m-p)/g/f)*f,M,k,S,w;if(_<1e-14&&!b&&!x)return[{value:p},{value:m}];w=Math.ceil(m/_)-Math.floor(p/_),w>g&&(_=Ci(w*_/g/f)*f),A(l)||(M=Math.pow(10,l),_=Math.ceil(_*M)/M),n==="ticks"?(k=Math.floor(p/_)*_,S=Math.ceil(m/_)*_):(k=p,S=m),b&&x&&o&&wo((a-r)/o,_/1e3)?(w=Math.round(Math.min((a-r)/_,h)),_=(a-r)/w,k=r,S=a):v?(k=b?r:k,S=x?a:S,w=c-1,_=(S-k)/w):(w=(S-k)/_,$t(w,Math.round(w),_/1e3)?w=Math.round(w):w=Math.ceil(w));const D=Math.max(Oi(_),Oi(k));M=Math.pow(10,A(l)?D:l),k=Math.round(k*M)/M,S=Math.round(S*M)/M;let C=0;for(b&&(u&&k!==r?(e.push({value:r}),ka)break;e.push({value:L})}return x&&u&&S!==a?e.length&&$t(e[e.length-1].value,a,Jn(a,y,i))?e[e.length-1].value=a:e.push({value:a}):(!x||S===a)&&e.push({value:S}),e}function Jn(i,t,{horizontal:e,minRotation:s}){const n=it(s),o=(e?Math.sin(n):Math.cos(n))||.001,r=.75*t*(""+i).length;return Math.min(t/o,r)}class Ee extends _t{constructor(t){super(t),this.start=void 0,this.end=void 0,this._startValue=void 0,this._endValue=void 0,this._valueRange=0}parse(t,e){return A(t)||(typeof t=="number"||t instanceof Number)&&!isFinite(+t)?null:+t}handleTickRangeOptions(){const{beginAtZero:t}=this.options,{minDefined:e,maxDefined:s}=this.getUserBounds();let{min:n,max:o}=this;const r=l=>n=e?n:l,a=l=>o=s?o:l;if(t){const l=nt(n),c=nt(o);l<0&&c<0?a(0):l>0&&c>0&&r(0)}if(n===o){let l=o===0?1:Math.abs(o*.05);a(o+l),t||r(n-l)}this.min=n,this.max=o}getTickLimit(){const t=this.options.ticks;let{maxTicksLimit:e,stepSize:s}=t,n;return s?(n=Math.ceil(this.max/s)-Math.floor(this.min/s)+1,n>1e3&&(console.warn(`scales.${this.id}.ticks.stepSize: ${s} would result generating up to ${n} ticks. Limiting to 1000.`),n=1e3)):(n=this.computeTickLimit(),e=e||11),e&&(n=Math.min(e,n)),n}computeTickLimit(){return Number.POSITIVE_INFINITY}buildTicks(){const t=this.options,e=t.ticks;let s=this.getTickLimit();s=Math.max(2,s);const n={maxTicks:s,bounds:t.bounds,min:t.min,max:t.max,precision:e.precision,step:e.stepSize,count:e.count,maxDigits:this._maxDigits(),horizontal:this.isHorizontal(),minRotation:e.minRotation||0,includeBounds:e.includeBounds!==!1},o=this._range||this,r=mc(n,o);return t.bounds==="ticks"&&Ai(r,this,"value"),t.reverse?(r.reverse(),this.start=this.max,this.end=this.min):(this.start=this.min,this.end=this.max),r}configure(){const t=this.ticks;let e=this.min,s=this.max;if(super.configure(),this.options.offset&&t.length){const n=(s-e)/Math.max(t.length-1,1)/2;e-=n,s+=n}this._startValue=e,this._endValue=s,this._valueRange=s-e}getLabelForValue(t){return Xt(t,this.chart.options.locale,this.options.ticks.format)}}class Qn extends Ee{static id="linear";static defaults={ticks:{callback:Kt.formatters.numeric}};determineDataLimits(){const{min:t,max:e}=this.getMinMax(!0);this.min=W(t)?t:0,this.max=W(e)?e:1,this.handleTickRangeOptions()}computeTickLimit(){const t=this.isHorizontal(),e=t?this.width:this.height,s=it(this.options.ticks.minRotation),n=(t?Math.sin(s):Math.cos(s))||.001,o=this._resolveTickFontOptions(0);return Math.ceil(e/Math.min(40,o.lineHeight/n))}getPixelForValue(t){return t===null?NaN:this.getPixelForDecimal((t-this._startValue)/this._valueRange)}getValueForPixel(t){return this._startValue+this.getDecimalForPixel(t)*this._valueRange}}const le=i=>Math.floor(mt(i)),Lt=(i,t)=>Math.pow(10,le(i)+t);function Zn(i){return i/Math.pow(10,le(i))===1}function to(i,t,e){const s=Math.pow(10,e),n=Math.floor(i/s);return Math.ceil(t/s)-n}function bc(i,t){const e=t-i;let s=le(e);for(;to(i,t,s)>10;)s++;for(;to(i,t,s)<10;)s--;return Math.min(s,le(i))}function xc(i,{min:t,max:e}){t=Z(i.min,t);const s=[],n=le(t);let o=bc(t,e),r=o<0?Math.pow(10,Math.abs(o)):1;const a=Math.pow(10,o),l=n>o?Math.pow(10,n):0,c=Math.round((t-l)*r)/r,h=Math.floor((t-l)/a/10)*a*10;let d=Math.floor((c-h)/Math.pow(10,o)),u=Z(i.min,Math.round((l+h+d*Math.pow(10,o))*r)/r);for(;u=10?d=d<15?15:20:d++,d>=20&&(o++,d=2,r=o>=0?1:r),u=Math.round((l+h+d*Math.pow(10,o))*r)/r;const f=Z(i.max,u);return s.push({value:f,major:Zn(f),significand:d}),s}class eo extends _t{static id="logarithmic";static defaults={ticks:{callback:Kt.formatters.logarithmic,major:{enabled:!0}}};constructor(t){super(t),this.start=void 0,this.end=void 0,this._startValue=void 0,this._valueRange=0}parse(t,e){const s=Ee.prototype.parse.apply(this,[t,e]);if(s===0){this._zero=!0;return}return W(s)&&s>0?s:null}determineDataLimits(){const{min:t,max:e}=this.getMinMax(!0);this.min=W(t)?Math.max(0,t):null,this.max=W(e)?Math.max(0,e):null,this.options.beginAtZero&&(this._zero=!0),this._zero&&this.min!==this._suggestedMin&&!W(this._userMin)&&(this.min=t===Lt(this.min,0)?Lt(this.min,-1):Lt(this.min,0)),this.handleTickRangeOptions()}handleTickRangeOptions(){const{minDefined:t,maxDefined:e}=this.getUserBounds();let s=this.min,n=this.max;const o=a=>s=t?s:a,r=a=>n=e?n:a;s===n&&(s<=0?(o(1),r(10)):(o(Lt(s,-1)),r(Lt(n,1)))),s<=0&&o(Lt(n,-1)),n<=0&&r(Lt(s,1)),this.min=s,this.max=n}buildTicks(){const t=this.options,e={min:this._userMin,max:this._userMax},s=xc(e,this);return t.bounds==="ticks"&&Ai(s,this,"value"),t.reverse?(s.reverse(),this.start=this.max,this.end=this.min):(this.start=this.min,this.end=this.max),s}getLabelForValue(t){return t===void 0?"0":Xt(t,this.chart.options.locale,this.options.ticks.format)}configure(){const t=this.min;super.configure(),this._startValue=mt(t),this._valueRange=mt(this.max)-mt(t)}getPixelForValue(t){return(t===void 0||t===0)&&(t=this.min),t===null||isNaN(t)?NaN:this.getPixelForDecimal(t===this.min?0:(mt(t)-this._startValue)/this._valueRange)}getValueForPixel(t){const e=this.getDecimalForPixel(t);return Math.pow(10,this._startValue+e*this._valueRange)}}function yi(i){const t=i.ticks;if(t.display&&i.display){const e=G(t.backdropPadding);return P(t.font&&t.font.size,F.font.size)+e.height}return 0}function _c(i,t,e){return e=V(e)?e:[e],{w:Ho(i,t.string,e),h:e.length*t.lineHeight}}function io(i,t,e,s,n){return i===s||i===n?{start:t-e/2,end:t+e/2}:in?{start:t-e,end:t}:{start:t,end:t+e}}function yc(i){const t={l:i.left+i._padding.left,r:i.right-i._padding.right,t:i.top+i._padding.top,b:i.bottom-i._padding.bottom},e=Object.assign({},t),s=[],n=[],o=i._pointLabels.length,r=i.options.pointLabels,a=r.centerPointLabels?I/o:0;for(let l=0;lt.r&&(a=(s.end-t.r)/o,i.r=Math.max(i.r,t.r+a)),n.startt.b&&(l=(n.end-t.b)/r,i.b=Math.max(i.b,t.b+l))}function Mc(i,t,e){const s=i.drawingArea,{extra:n,additionalAngle:o,padding:r,size:a}=e,l=i.getPointPosition(t,s+n+r,o),c=Math.round(Ve(tt(l.angle+H))),h=Dc(l.y,a.h,c),d=wc(c),u=Pc(l.x,a.w,d);return{visible:!0,x:l.x,y:h,textAlign:d,left:u,top:h,right:u+a.w,bottom:h+a.h}}function kc(i,t){if(!t)return!0;const{left:e,top:s,right:n,bottom:o}=i;return!(dt({x:e,y:s},t)||dt({x:e,y:o},t)||dt({x:n,y:s},t)||dt({x:n,y:o},t))}function Sc(i,t,e){const s=[],n=i._pointLabels.length,o=i.options,{centerPointLabels:r,display:a}=o.pointLabels,l={extra:yi(o)/2,additionalAngle:r?I/n:0};let c;for(let h=0;h270||e<90)&&(i-=t),i}function Cc(i,t,e){const{left:s,top:n,right:o,bottom:r}=e,{backdropColor:a}=t;if(!A(a)){const l=Pt(t.borderRadius),c=G(t.backdropPadding);i.fillStyle=a;const h=s-c.left,d=n-c.top,u=o-s+c.width,f=r-n+c.height;Object.values(l).some(g=>g!==0)?(i.beginPath(),qt(i,{x:h,y:d,w:u,h:f,radius:l}),i.fill()):i.fillRect(h,d,u,f)}}function Ac(i,t){const{ctx:e,options:{pointLabels:s}}=i;for(let n=t-1;n>=0;n--){const o=i._pointLabelItems[n];if(!o.visible)continue;const r=s.setContext(i.getPointLabelContext(n));Cc(e,r,o);const a=j(r.font),{x:l,y:c,textAlign:h}=o;wt(e,i._pointLabels[n],l,c+a.lineHeight/2,a,{color:r.color,textAlign:h,textBaseline:"middle"})}}function so(i,t,e,s){const{ctx:n}=i;if(e)n.arc(i.xCenter,i.yCenter,t,0,z);else{let o=i.getPointPosition(0,t);n.moveTo(o.x,o.y);for(let r=1;r{const n=E(this.options.pointLabels.callback,[e,s],this);return n||n===0?n:""}).filter((e,s)=>this.chart.getDataVisibility(s))}fit(){const t=this.options;t.display&&t.pointLabels.display?yc(this):this.setCenterPoint(0,0,0,0)}setCenterPoint(t,e,s,n){this.xCenter+=Math.floor((t-e)/2),this.yCenter+=Math.floor((s-n)/2),this.drawingArea-=Math.min(this.drawingArea/2,Math.max(t,e,s,n))}getIndexAngle(t){const e=z/(this._pointLabels.length||1),s=this.options.startAngle||0;return tt(t*e+it(s))}getDistanceFromCenterForValue(t){if(A(t))return NaN;const e=this.drawingArea/(this.max-this.min);return this.options.reverse?(this.max-t)*e:(t-this.min)*e}getValueForDistanceFromCenter(t){if(A(t))return NaN;const e=t/(this.drawingArea/(this.max-this.min));return this.options.reverse?this.max-e:this.min+e}getPointLabelContext(t){const e=this._pointLabels||[];if(t>=0&&t{if(d!==0||d===0&&this.min<0){l=this.getDistanceFromCenterForValue(h.value);const u=this.getContext(d),f=n.setContext(u),g=o.setContext(u);Oc(this,f,l,r,g)}}),s.display){for(t.save(),a=r-1;a>=0;a--){const h=s.setContext(this.getPointLabelContext(a)),{color:d,lineWidth:u}=h;!u||!d||(t.lineWidth=u,t.strokeStyle=d,t.setLineDash(h.borderDash),t.lineDashOffset=h.borderDashOffset,l=this.getDistanceFromCenterForValue(e.reverse?this.min:this.max),c=this.getPointPosition(a,l),t.beginPath(),t.moveTo(this.xCenter,this.yCenter),t.lineTo(c.x,c.y),t.stroke())}t.restore()}}drawBorder(){}drawLabels(){const t=this.ctx,e=this.options,s=e.ticks;if(!s.display)return;const n=this.getIndexAngle(0);let o,r;t.save(),t.translate(this.xCenter,this.yCenter),t.rotate(n),t.textAlign="center",t.textBaseline="middle",this.ticks.forEach((a,l)=>{if(l===0&&this.min>=0&&!e.reverse)return;const c=s.setContext(this.getContext(l)),h=j(c.font);if(o=this.getDistanceFromCenterForValue(this.ticks[l].value),c.showLabelBackdrop){t.font=h.string,r=t.measureText(a.label).width,t.fillStyle=c.backdropColor;const d=G(c.backdropPadding);t.fillRect(-r/2-d.left,-o-h.size/2-d.top,r+d.width,h.size+d.height)}wt(t,a.label,0,-o,h,{color:c.color,strokeColor:c.textStrokeColor,strokeWidth:c.textStrokeWidth})}),t.restore()}drawTitle(){}}const Ie={millisecond:{common:!0,size:1,steps:1e3},second:{common:!0,size:1e3,steps:60},minute:{common:!0,size:6e4,steps:60},hour:{common:!0,size:36e5,steps:24},day:{common:!0,size:864e5,steps:30},week:{common:!1,size:6048e5,steps:4},month:{common:!0,size:2628e6,steps:12},quarter:{common:!1,size:7884e6,steps:4},year:{common:!0,size:3154e7}},J=Object.keys(Ie);function oo(i,t){return i-t}function ro(i,t){if(A(t))return null;const e=i._adapter,{parser:s,round:n,isoWeekday:o}=i._parseOpts;let r=t;return typeof s=="function"&&(r=s(r)),W(r)||(r=typeof s=="string"?e.parse(r,s):e.parse(r)),r===null?null:(n&&(r=n==="week"&&(Et(o)||o===!0)?e.startOf(r,"isoWeek",o):e.startOf(r,n)),+r)}function ao(i,t,e,s){const n=J.length;for(let o=J.indexOf(i);o=J.indexOf(e);o--){const r=J[o];if(Ie[r].common&&i._adapter.diff(n,s,r)>=t-1)return r}return J[e?J.indexOf(e):0]}function Rc(i){for(let t=J.indexOf(i)+1,e=J.length;t=t?e[s]:e[n];i[o]=!0}}function Ec(i,t,e,s){const n=i._adapter,o=+n.startOf(t[0].value,s),r=t[t.length-1].value;let a,l;for(a=o;a<=r;a=+n.add(a,1,s))l=e[a],l>=0&&(t[l].major=!0);return t}function co(i,t,e){const s=[],n={},o=t.length;let r,a;for(r=0;r+t.value))}initOffsets(t=[]){let e=0,s=0,n,o;this.options.offset&&t.length&&(n=this.getDecimalForValue(t[0]),t.length===1?e=1-n:e=(this.getDecimalForValue(t[1])-n)/2,o=this.getDecimalForValue(t[t.length-1]),t.length===1?s=o:s=(o-this.getDecimalForValue(t[t.length-2]))/2);const r=t.length<3?.5:.25;e=$(e,0,r),s=$(s,0,r),this._offsets={start:e,end:s,factor:1/(e+1+s)}}_generate(){const t=this._adapter,e=this.min,s=this.max,n=this.options,o=n.time,r=o.unit||ao(o.minUnit,e,s,this._getLabelCapacity(e)),a=P(n.ticks.stepSize,1),l=r==="week"?o.isoWeekday:!1,c=Et(l)||l===!0,h={};let d=e,u,f;if(c&&(d=+t.startOf(d,"isoWeek",l)),d=+t.startOf(d,c?"day":r),t.diff(s,e,r)>1e5*a)throw new Error(e+" and "+s+" are too far apart with stepSize of "+a+" "+r);const g=n.ticks.source==="data"&&this.getDataTimestamps();for(u=d,f=0;u+p)}getLabelForValue(t){const e=this._adapter,s=this.options.time;return s.tooltipFormat?e.format(t,s.tooltipFormat):e.format(t,s.displayFormats.datetime)}format(t,e){const n=this.options.time.displayFormats,o=this._unit,r=e||n[o];return this._adapter.format(t,r)}_tickFormatFunction(t,e,s,n){const o=this.options,r=o.ticks.callback;if(r)return E(r,[t,e,s],this);const a=o.time.displayFormats,l=this._unit,c=this._majorUnit,h=l&&a[l],d=c&&a[c],u=s[e],f=c&&d&&u&&u.major;return this._adapter.format(t,n||(f?d:h))}generateTickLabels(t){let e,s,n;for(e=0,s=t.length;e0?a:1}getDataTimestamps(){let t=this._cache.data||[],e,s;if(t.length)return t;const n=this.getMatchingVisibleMetas();if(this._normalized&&n.length)return this._cache.data=n[0].controller.getAllParsedValues(this);for(e=0,s=n.length;e=i[s].pos&&t<=i[n].pos&&({lo:s,hi:n}=ht(i,"pos",t)),{pos:o,time:a}=i[s],{pos:r,time:l}=i[n]):(t>=i[s].time&&t<=i[n].time&&({lo:s,hi:n}=ht(i,"time",t)),{time:o,pos:a}=i[s],{time:r,pos:l}=i[n]);const c=r-o;return c?a+(l-a)*(t-o)/c:a}class ho extends ze{static id="timeseries";static defaults=ze.defaults;constructor(t){super(t),this._table=[],this._minPos=void 0,this._tableRange=void 0}initOffsets(){const t=this._getTimestampsForTable(),e=this._table=this.buildLookupTable(t);this._minPos=Fe(e,this.min),this._tableRange=Fe(e,this.max)-this._minPos,super.initOffsets(t)}buildLookupTable(t){const{min:e,max:s}=this,n=[],o=[];let r,a,l,c,h;for(r=0,a=t.length;r=e&&c<=s&&n.push(c);if(n.length<2)return[{time:e,pos:0},{time:s,pos:1}];for(r=0,a=n.length;rn-o)}_getTimestampsForTable(){let t=this._cache.all||[];if(t.length)return t;const e=this.getDataTimestamps(),s=this.getLabelTimestamps();return e.length&&s.length?t=this.normalize(e.concat(s)):t=e.length?e:s,t=this._cache.all=t,t}getDecimalForValue(t){return(Fe(this._table,t)-this._minPos)/this._tableRange}getValueForPixel(t){const e=this._offsets,s=this.getDecimalForPixel(t)/e.factor-e.end;return Fe(this._table,s*this._tableRange+this._minPos,!0)}}var uo=Object.freeze({__proto__:null,CategoryScale:qn,LinearScale:Qn,LogarithmicScale:eo,RadialLinearScale:no,TimeScale:ze,TimeSeriesScale:ho});const fo=[Os,bn,Kn,uo];Oe.register(...fo);export{fs as Animation,ti as Animations,hn as ArcElement,Ss as BarController,mn as BarElement,li as BasePlatform,Vs as BasicPlatform,ws as BubbleController,qn as CategoryScale,Oe as Chart,Mn as Colors,ut as DatasetController,wn as Decimation,$s as DomPlatform,Me as DoughnutController,rt as Element,Rn as Filler,Rs as Interaction,Fn as Legend,Ps as LineController,re as LineElement,Qn as LinearScale,eo as LogarithmicScale,Ds as PieController,gn as PointElement,oi as PolarAreaController,Cs as RadarController,no as RadialLinearScale,_t as Scale,As as ScatterController,Vn as SubTitle,Kt as Ticks,ze as TimeScale,ho as TimeSeriesScale,Bn as Title,Xn as Tooltip,Ls as _adapters,Us as _detectPlatform,ot as animator,Os as controllers,Oe as default,F as defaults,bn as elements,Y as layouts,Kn as plugins,fo as registerables,st as registry,uo as scales}; +//# sourceMappingURL=/sm/dd5ee2e759d62a936d850f27d6e037939135852fe9f24e4457286b45b9726629.map \ No newline at end of file diff --git a/apps/ui/src/twfarmbot_ui/static/vendor/dompurify.js b/apps/ui/src/twfarmbot_ui/static/vendor/dompurify.js new file mode 100644 index 0000000..954d72c --- /dev/null +++ b/apps/ui/src/twfarmbot_ui/static/vendor/dompurify.js @@ -0,0 +1,9 @@ +/** + * Bundled by jsDelivr using Rollup v4.62.2 and esbuild v0.28.1. + * Original file: /npm/dompurify@3.2.6/dist/purify.es.mjs + * + * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files + */ +const{entries:rt,setPrototypeOf:st,isFrozen:Bt,getPrototypeOf:Yt,getOwnPropertyDescriptor:Xt}=Object;let{freeze:A,seal:y,create:lt}=Object,{apply:Ne,construct:be}=typeof Reflect<"u"&&Reflect;A||(A=function(o){return o}),y||(y=function(o){return o}),Ne||(Ne=function(o,l,s){return o.apply(l,s)}),be||(be=function(o,l){return new o(...l)});const le=R(Array.prototype.forEach),jt=R(Array.prototype.lastIndexOf),ct=R(Array.prototype.pop),$=R(Array.prototype.push),Vt=R(Array.prototype.splice),ce=R(String.prototype.toLowerCase),Ie=R(String.prototype.toString),ft=R(String.prototype.match),q=R(String.prototype.replace),$t=R(String.prototype.indexOf),qt=R(String.prototype.trim),L=R(Object.prototype.hasOwnProperty),S=R(RegExp.prototype.test),K=Kt(TypeError);function R(r){return function(o){o instanceof RegExp&&(o.lastIndex=0);for(var l=arguments.length,s=new Array(l>1?l-1:0),T=1;T2&&arguments[2]!==void 0?arguments[2]:ce;st&&st(r,null);let s=o.length;for(;s--;){let T=o[s];if(typeof T=="string"){const N=l(T);N!==T&&(Bt(o)||(o[s]=N),T=N)}r[T]=!0}return r}function Zt(r){for(let o=0;o/gm),nn=y(/\$\{[\w\W]*/gm),on=y(/^data-[\-\w.\u00B7-\uFFFF]+$/),an=y(/^aria-[\-\w]+$/),Tt=y(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),rn=y(/^(?:\w+script|data):/i),sn=y(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),_t=y(/^html$/i),ln=y(/^[a-z][.\w]*(-[.\w]+)+$/i);var Et=Object.freeze({__proto__:null,ARIA_ATTR:an,ATTR_WHITESPACE:sn,CUSTOM_ELEMENT:ln,DATA_ATTR:on,DOCTYPE_NAME:_t,ERB_EXPR:tn,IS_ALLOWED_URI:Tt,IS_SCRIPT_OR_DATA:rn,MUSTACHE_EXPR:en,TMPLIT_EXPR:nn});const J={element:1,text:3,progressingInstruction:7,comment:8,document:9},cn=function(){return typeof window>"u"?null:window},fn=function(o,l){if(typeof o!="object"||typeof o.createPolicy!="function")return null;let s=null;const T="data-tt-policy-suffix";l&&l.hasAttribute(T)&&(s=l.getAttribute(T));const N="dompurify"+(s?"#"+s:"");try{return o.createPolicy(N,{createHTML(x){return x},createScriptURL(x){return x}})}catch{return console.warn("TrustedTypes policy "+N+" could not be created."),null}},gt=function(){return{afterSanitizeAttributes:[],afterSanitizeElements:[],afterSanitizeShadowDOM:[],beforeSanitizeAttributes:[],beforeSanitizeElements:[],beforeSanitizeShadowDOM:[],uponSanitizeAttribute:[],uponSanitizeElement:[],uponSanitizeShadowNode:[]}};function ht(){let r=arguments.length>0&&arguments[0]!==void 0?arguments[0]:cn();const o=i=>ht(i);if(o.version="3.2.6",o.removed=[],!r||!r.document||r.document.nodeType!==J.document||!r.Element)return o.isSupported=!1,o;let{document:l}=r;const s=l,T=s.currentScript,{DocumentFragment:N,HTMLTemplateElement:x,Node:ue,Element:Pe,NodeFilter:G,NamedNodeMap:At=r.NamedNodeMap||r.MozNamedAttrMap,HTMLFormElement:St,DOMParser:Rt,trustedTypes:Q}=r,W=Pe.prototype,Ot=Z(W,"cloneNode"),yt=Z(W,"remove"),Lt=Z(W,"nextSibling"),Dt=Z(W,"childNodes"),ee=Z(W,"parentNode");if(typeof x=="function"){const i=l.createElement("template");i.content&&i.content.ownerDocument&&(l=i.content.ownerDocument)}let g,B="";const{implementation:me,createNodeIterator:Nt,createDocumentFragment:bt,getElementsByTagName:It}=l,{importNode:Mt}=s;let h=gt();o.isSupported=typeof rt=="function"&&typeof ee=="function"&&me&&me.createHTMLDocument!==void 0;const{MUSTACHE_EXPR:pe,ERB_EXPR:de,TMPLIT_EXPR:Te,DATA_ATTR:Ct,ARIA_ATTR:wt,IS_SCRIPT_OR_DATA:xt,ATTR_WHITESPACE:ve,CUSTOM_ELEMENT:Pt}=Et;let{IS_ALLOWED_URI:ke}=Et,m=null;const Ue=a({},[...ut,...Me,...Ce,...we,...mt]);let d=null;const Fe=a({},[...pt,...xe,...dt,...fe]);let f=Object.seal(lt(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),Y=null,_e=null,He=!0,Ee=!0,ze=!1,Ge=!0,P=!1,te=!0,w=!1,ge=!1,he=!1,v=!1,ne=!1,oe=!1,We=!0,Be=!1;const vt="user-content-";let Ae=!0,X=!1,k={},U=null;const Ye=a({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]);let Xe=null;const je=a({},["audio","video","img","source","image","track"]);let Se=null;const Ve=a({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),ie="http://www.w3.org/1998/Math/MathML",ae="http://www.w3.org/2000/svg",b="http://www.w3.org/1999/xhtml";let F=b,Re=!1,Oe=null;const kt=a({},[ie,ae,b],Ie);let re=a({},["mi","mo","mn","ms","mtext"]),se=a({},["annotation-xml"]);const Ut=a({},["title","style","font","a","script"]);let j=null;const Ft=["application/xhtml+xml","text/html"],Ht="text/html";let p=null,H=null;const zt=l.createElement("form"),$e=function(e){return e instanceof RegExp||e instanceof Function},ye=function(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};if(!(H&&H===e)){if((!e||typeof e!="object")&&(e={}),e=C(e),j=Ft.indexOf(e.PARSER_MEDIA_TYPE)===-1?Ht:e.PARSER_MEDIA_TYPE,p=j==="application/xhtml+xml"?Ie:ce,m=L(e,"ALLOWED_TAGS")?a({},e.ALLOWED_TAGS,p):Ue,d=L(e,"ALLOWED_ATTR")?a({},e.ALLOWED_ATTR,p):Fe,Oe=L(e,"ALLOWED_NAMESPACES")?a({},e.ALLOWED_NAMESPACES,Ie):kt,Se=L(e,"ADD_URI_SAFE_ATTR")?a(C(Ve),e.ADD_URI_SAFE_ATTR,p):Ve,Xe=L(e,"ADD_DATA_URI_TAGS")?a(C(je),e.ADD_DATA_URI_TAGS,p):je,U=L(e,"FORBID_CONTENTS")?a({},e.FORBID_CONTENTS,p):Ye,Y=L(e,"FORBID_TAGS")?a({},e.FORBID_TAGS,p):C({}),_e=L(e,"FORBID_ATTR")?a({},e.FORBID_ATTR,p):C({}),k=L(e,"USE_PROFILES")?e.USE_PROFILES:!1,He=e.ALLOW_ARIA_ATTR!==!1,Ee=e.ALLOW_DATA_ATTR!==!1,ze=e.ALLOW_UNKNOWN_PROTOCOLS||!1,Ge=e.ALLOW_SELF_CLOSE_IN_ATTR!==!1,P=e.SAFE_FOR_TEMPLATES||!1,te=e.SAFE_FOR_XML!==!1,w=e.WHOLE_DOCUMENT||!1,v=e.RETURN_DOM||!1,ne=e.RETURN_DOM_FRAGMENT||!1,oe=e.RETURN_TRUSTED_TYPE||!1,he=e.FORCE_BODY||!1,We=e.SANITIZE_DOM!==!1,Be=e.SANITIZE_NAMED_PROPS||!1,Ae=e.KEEP_CONTENT!==!1,X=e.IN_PLACE||!1,ke=e.ALLOWED_URI_REGEXP||Tt,F=e.NAMESPACE||b,re=e.MATHML_TEXT_INTEGRATION_POINTS||re,se=e.HTML_INTEGRATION_POINTS||se,f=e.CUSTOM_ELEMENT_HANDLING||{},e.CUSTOM_ELEMENT_HANDLING&&$e(e.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(f.tagNameCheck=e.CUSTOM_ELEMENT_HANDLING.tagNameCheck),e.CUSTOM_ELEMENT_HANDLING&&$e(e.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(f.attributeNameCheck=e.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),e.CUSTOM_ELEMENT_HANDLING&&typeof e.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements=="boolean"&&(f.allowCustomizedBuiltInElements=e.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),P&&(Ee=!1),ne&&(v=!0),k&&(m=a({},mt),d=[],k.html===!0&&(a(m,ut),a(d,pt)),k.svg===!0&&(a(m,Me),a(d,xe),a(d,fe)),k.svgFilters===!0&&(a(m,Ce),a(d,xe),a(d,fe)),k.mathMl===!0&&(a(m,we),a(d,dt),a(d,fe))),e.ADD_TAGS&&(m===Ue&&(m=C(m)),a(m,e.ADD_TAGS,p)),e.ADD_ATTR&&(d===Fe&&(d=C(d)),a(d,e.ADD_ATTR,p)),e.ADD_URI_SAFE_ATTR&&a(Se,e.ADD_URI_SAFE_ATTR,p),e.FORBID_CONTENTS&&(U===Ye&&(U=C(U)),a(U,e.FORBID_CONTENTS,p)),Ae&&(m["#text"]=!0),w&&a(m,["html","head","body"]),m.table&&(a(m,["tbody"]),delete Y.tbody),e.TRUSTED_TYPES_POLICY){if(typeof e.TRUSTED_TYPES_POLICY.createHTML!="function")throw K('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if(typeof e.TRUSTED_TYPES_POLICY.createScriptURL!="function")throw K('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');g=e.TRUSTED_TYPES_POLICY,B=g.createHTML("")}else g===void 0&&(g=fn(Q,T)),g!==null&&typeof B=="string"&&(B=g.createHTML(""));A&&A(e),H=e}},qe=a({},[...Me,...Ce,...Jt]),Ke=a({},[...we,...Qt]),Gt=function(e){let t=ee(e);(!t||!t.tagName)&&(t={namespaceURI:F,tagName:"template"});const n=ce(e.tagName),c=ce(t.tagName);return Oe[e.namespaceURI]?e.namespaceURI===ae?t.namespaceURI===b?n==="svg":t.namespaceURI===ie?n==="svg"&&(c==="annotation-xml"||re[c]):!!qe[n]:e.namespaceURI===ie?t.namespaceURI===b?n==="math":t.namespaceURI===ae?n==="math"&&se[c]:!!Ke[n]:e.namespaceURI===b?t.namespaceURI===ae&&!se[c]||t.namespaceURI===ie&&!re[c]?!1:!Ke[n]&&(Ut[n]||!qe[n]):!!(j==="application/xhtml+xml"&&Oe[e.namespaceURI]):!1},D=function(e){$(o.removed,{element:e});try{ee(e).removeChild(e)}catch{yt(e)}},z=function(e,t){try{$(o.removed,{attribute:t.getAttributeNode(e),from:t})}catch{$(o.removed,{attribute:null,from:t})}if(t.removeAttribute(e),e==="is")if(v||ne)try{D(t)}catch{}else try{t.setAttribute(e,"")}catch{}},Ze=function(e){let t=null,n=null;if(he)e=""+e;else{const u=ft(e,/^[\r\n\t ]+/);n=u&&u[0]}j==="application/xhtml+xml"&&F===b&&(e=''+e+"");const c=g?g.createHTML(e):e;if(F===b)try{t=new Rt().parseFromString(c,j)}catch{}if(!t||!t.documentElement){t=me.createDocument(F,"template",null);try{t.documentElement.innerHTML=Re?B:c}catch{}}const _=t.body||t.documentElement;return e&&n&&_.insertBefore(l.createTextNode(n),_.childNodes[0]||null),F===b?It.call(t,w?"html":"body")[0]:w?t.documentElement:_},Je=function(e){return Nt.call(e.ownerDocument||e,e,G.SHOW_ELEMENT|G.SHOW_COMMENT|G.SHOW_TEXT|G.SHOW_PROCESSING_INSTRUCTION|G.SHOW_CDATA_SECTION,null)},Le=function(e){return e instanceof St&&(typeof e.nodeName!="string"||typeof e.textContent!="string"||typeof e.removeChild!="function"||!(e.attributes instanceof At)||typeof e.removeAttribute!="function"||typeof e.setAttribute!="function"||typeof e.namespaceURI!="string"||typeof e.insertBefore!="function"||typeof e.hasChildNodes!="function")},Qe=function(e){return typeof ue=="function"&&e instanceof ue};function I(i,e,t){le(i,n=>{n.call(o,e,t,H)})}const et=function(e){let t=null;if(I(h.beforeSanitizeElements,e,null),Le(e))return D(e),!0;const n=p(e.nodeName);if(I(h.uponSanitizeElement,e,{tagName:n,allowedTags:m}),te&&e.hasChildNodes()&&!Qe(e.firstElementChild)&&S(/<[/\w!]/g,e.innerHTML)&&S(/<[/\w!]/g,e.textContent)||e.nodeType===J.progressingInstruction||te&&e.nodeType===J.comment&&S(/<[/\w]/g,e.data))return D(e),!0;if(!m[n]||Y[n]){if(!Y[n]&&nt(n)&&(f.tagNameCheck instanceof RegExp&&S(f.tagNameCheck,n)||f.tagNameCheck instanceof Function&&f.tagNameCheck(n)))return!1;if(Ae&&!U[n]){const c=ee(e)||e.parentNode,_=Dt(e)||e.childNodes;if(_&&c){const u=_.length;for(let O=u-1;O>=0;--O){const M=Ot(_[O],!0);M.__removalCount=(e.__removalCount||0)+1,c.insertBefore(M,Lt(e))}}}return D(e),!0}return e instanceof Pe&&!Gt(e)||(n==="noscript"||n==="noembed"||n==="noframes")&&S(/<\/no(script|embed|frames)/i,e.innerHTML)?(D(e),!0):(P&&e.nodeType===J.text&&(t=e.textContent,le([pe,de,Te],c=>{t=q(t,c," ")}),e.textContent!==t&&($(o.removed,{element:e.cloneNode()}),e.textContent=t)),I(h.afterSanitizeElements,e,null),!1)},tt=function(e,t,n){if(We&&(t==="id"||t==="name")&&(n in l||n in zt))return!1;if(!(Ee&&!_e[t]&&S(Ct,t))){if(!(He&&S(wt,t))){if(!d[t]||_e[t]){if(!(nt(e)&&(f.tagNameCheck instanceof RegExp&&S(f.tagNameCheck,e)||f.tagNameCheck instanceof Function&&f.tagNameCheck(e))&&(f.attributeNameCheck instanceof RegExp&&S(f.attributeNameCheck,t)||f.attributeNameCheck instanceof Function&&f.attributeNameCheck(t))||t==="is"&&f.allowCustomizedBuiltInElements&&(f.tagNameCheck instanceof RegExp&&S(f.tagNameCheck,n)||f.tagNameCheck instanceof Function&&f.tagNameCheck(n))))return!1}else if(!Se[t]){if(!S(ke,q(n,ve,""))){if(!((t==="src"||t==="xlink:href"||t==="href")&&e!=="script"&&$t(n,"data:")===0&&Xe[e])){if(!(ze&&!S(xt,q(n,ve,"")))){if(n)return!1}}}}}}return!0},nt=function(e){return e!=="annotation-xml"&&ft(e,Pt)},ot=function(e){I(h.beforeSanitizeAttributes,e,null);const{attributes:t}=e;if(!t||Le(e))return;const n={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:d,forceKeepAttr:void 0};let c=t.length;for(;c--;){const _=t[c],{name:u,namespaceURI:O,value:M}=_,V=p(u),De=M;let E=u==="value"?De:qt(De);if(n.attrName=V,n.attrValue=E,n.keepAttr=!0,n.forceKeepAttr=void 0,I(h.uponSanitizeAttribute,e,n),E=n.attrValue,Be&&(V==="id"||V==="name")&&(z(u,e),E=vt+E),te&&S(/((--!?|])>)|<\/(style|title)/i,E)){z(u,e);continue}if(n.forceKeepAttr)continue;if(!n.keepAttr){z(u,e);continue}if(!Ge&&S(/\/>/i,E)){z(u,e);continue}P&&le([pe,de,Te],at=>{E=q(E,at," ")});const it=p(e.nodeName);if(!tt(it,V,E)){z(u,e);continue}if(g&&typeof Q=="object"&&typeof Q.getAttributeType=="function"&&!O)switch(Q.getAttributeType(it,V)){case"TrustedHTML":{E=g.createHTML(E);break}case"TrustedScriptURL":{E=g.createScriptURL(E);break}}if(E!==De)try{O?e.setAttributeNS(O,u,E):e.setAttribute(u,E),Le(e)?D(e):ct(o.removed)}catch{z(u,e)}}I(h.afterSanitizeAttributes,e,null)},Wt=function i(e){let t=null;const n=Je(e);for(I(h.beforeSanitizeShadowDOM,e,null);t=n.nextNode();)I(h.uponSanitizeShadowNode,t,null),et(t),ot(t),t.content instanceof N&&i(t.content);I(h.afterSanitizeShadowDOM,e,null)};return o.sanitize=function(i){let e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},t=null,n=null,c=null,_=null;if(Re=!i,Re&&(i=""),typeof i!="string"&&!Qe(i))if(typeof i.toString=="function"){if(i=i.toString(),typeof i!="string")throw K("dirty is not a string, aborting")}else throw K("toString is not a function");if(!o.isSupported)return i;if(ge||ye(e),o.removed=[],typeof i=="string"&&(X=!1),X){if(i.nodeName){const M=p(i.nodeName);if(!m[M]||Y[M])throw K("root node is forbidden and cannot be sanitized in-place")}}else if(i instanceof ue)t=Ze(""),n=t.ownerDocument.importNode(i,!0),n.nodeType===J.element&&n.nodeName==="BODY"||n.nodeName==="HTML"?t=n:t.appendChild(n);else{if(!v&&!P&&!w&&i.indexOf("<")===-1)return g&&oe?g.createHTML(i):i;if(t=Ze(i),!t)return v?null:oe?B:""}t&&he&&D(t.firstChild);const u=Je(X?i:t);for(;c=u.nextNode();)et(c),ot(c),c.content instanceof N&&Wt(c.content);if(X)return i;if(v){if(ne)for(_=bt.call(t.ownerDocument);t.firstChild;)_.appendChild(t.firstChild);else _=t;return(d.shadowroot||d.shadowrootmode)&&(_=Mt.call(s,_,!0)),_}let O=w?t.outerHTML:t.innerHTML;return w&&m["!doctype"]&&t.ownerDocument&&t.ownerDocument.doctype&&t.ownerDocument.doctype.name&&S(_t,t.ownerDocument.doctype.name)&&(O=" +`+O),P&&le([pe,de,Te],M=>{O=q(O,M," ")}),g&&oe?g.createHTML(O):O},o.setConfig=function(){let i=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};ye(i),ge=!0},o.clearConfig=function(){H=null,ge=!1},o.isValidAttribute=function(i,e,t){H||ye({});const n=p(i),c=p(e);return tt(n,c,t)},o.addHook=function(i,e){typeof e=="function"&&$(h[i],e)},o.removeHook=function(i,e){if(e!==void 0){const t=jt(h[i],e);return t===-1?void 0:Vt(h[i],t,1)[0]}return ct(h[i])},o.removeHooks=function(i){h[i]=[]},o.removeAllHooks=function(){h=gt()},o}var un=ht();export{un as default}; +//# sourceMappingURL=/sm/caebe20dfa662a6955b27c9ab995e3d9ba6eb6af3ded07b11c6f4442df2b29e9.map \ No newline at end of file diff --git a/apps/ui/src/twfarmbot_ui/static/vendor/manifest.json b/apps/ui/src/twfarmbot_ui/static/vendor/manifest.json new file mode 100644 index 0000000..659fa17 --- /dev/null +++ b/apps/ui/src/twfarmbot_ui/static/vendor/manifest.json @@ -0,0 +1,32 @@ +[ + { + "url": "https://esm.run/@material/web@2.4.0/all.js", + "path": "@material/web/all.js", + "sha256": "07023ec48b3b495f34b485a625cc470ed07692594ccfc74d6b800f225d1a80fb", + "size": 440976 + }, + { + "url": "https://esm.run/@material/web@2.4.0/typography/md-typescale-styles.js", + "path": "@material/web/typography/md-typescale-styles.js", + "sha256": "07546a71476de34433a067774d3192900d28e88169fb7aec8831f95b0c97bc07", + "size": 5919 + }, + { + "url": "https://esm.run/chart.js@4.4.9/auto", + "path": "chart.js/auto.js", + "sha256": "e38916283b32321696a17c0acb4123f3889b4331e1859d471b195eecd4a9e497", + "size": 198386 + }, + { + "url": "https://esm.run/marked@15.0.12", + "path": "marked.js", + "sha256": "5b2f8940c0c4fd3f568aa4e08e169cbbcef8496a094eb02b579d342e5e9377e4", + "size": 39360 + }, + { + "url": "https://esm.run/dompurify@3.2.6", + "path": "dompurify.js", + "sha256": "c7cf8c441c3a0be7597d0b15c45df444e624b23a72101b68b5a96dfad8c5f2b5", + "size": 21983 + } +] diff --git a/apps/ui/src/twfarmbot_ui/static/vendor/marked.js b/apps/ui/src/twfarmbot_ui/static/vendor/marked.js new file mode 100644 index 0000000..36538c1 --- /dev/null +++ b/apps/ui/src/twfarmbot_ui/static/vendor/marked.js @@ -0,0 +1,63 @@ +/** + * Bundled by jsDelivr using Rollup v4.62.2 and esbuild v0.28.1. + * Original file: /npm/marked@15.0.12/lib/marked.esm.js + * + * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files + */ +function P(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}}var R=P();function ee(n){R=n}var $={exec:()=>null};function u(n,e=""){let t=typeof n=="string"?n:n.source;const s={replace:(r,i)=>{let l=typeof i=="string"?i:i.source;return l=l.replace(x.caret,"$1"),t=t.replace(r,l),s},getRegex:()=>new RegExp(t,e)};return s}var x={codeRemoveIndent:/^(?: {1,4}| {0,3}\t)/gm,outputLinkReplace:/\\([\[\]])/g,indentCodeCompensation:/^(\s+)(?:```)/,beginningSpace:/^\s+/,endingHash:/#$/,startingSpaceChar:/^ /,endingSpaceChar:/ $/,nonSpaceChar:/[^ ]/,newLineCharGlobal:/\n/g,tabCharGlobal:/\t/g,multipleSpaceGlobal:/\s+/g,blankLine:/^[ \t]*$/,doubleBlankLine:/\n[ \t]*\n[ \t]*$/,blockquoteStart:/^ {0,3}>/,blockquoteSetextReplace:/\n {0,3}((?:=+|-+) *)(?=\n|$)/g,blockquoteSetextReplace2:/^ {0,3}>[ \t]?/gm,listReplaceTabs:/^\t+/,listReplaceNesting:/^ {1,4}(?=( {4})*[^ ])/g,listIsTask:/^\[[ xX]\] /,listReplaceTask:/^\[[ xX]\] +/,anyLine:/\n.*\n/,hrefBrackets:/^<(.*)>$/,tableDelimiter:/[:|]/,tableAlignChars:/^\||\| *$/g,tableRowBlankLine:/\n[ \t]*$/,tableAlignRight:/^ *-+: *$/,tableAlignCenter:/^ *:-+: *$/,tableAlignLeft:/^ *:-+ *$/,startATag:/^/i,startPreScriptTag:/^<(pre|code|kbd|script)(\s|>)/i,endPreScriptTag:/^<\/(pre|code|kbd|script)(\s|>)/i,startAngleBracket:/^$/,pedanticHrefTitle:/^([^'"]*[^\s])\s+(['"])(.*)\2/,unicodeAlphaNumeric:/[\p{L}\p{N}]/u,escapeTest:/[&<>"']/,escapeReplace:/[&<>"']/g,escapeTestNoEncode:/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/,escapeReplaceNoEncode:/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/g,unescapeTest:/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig,caret:/(^|[^\[])\^/g,percentDecode:/%25/g,findPipe:/\|/g,splitPipe:/ \|/,slashPipe:/\\\|/g,carriageReturn:/\r\n|\r/g,spaceLine:/^ +$/gm,notSpaceStart:/^\S*/,endingNewline:/\n$/,listItemRegex:n=>new RegExp(`^( {0,3}${n})((?:[ ][^\\n]*)?(?:\\n|$))`),nextBulletRegex:n=>new RegExp(`^ {0,${Math.min(3,n-1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`),hrRegex:n=>new RegExp(`^ {0,${Math.min(3,n-1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`),fencesBeginRegex:n=>new RegExp(`^ {0,${Math.min(3,n-1)}}(?:\`\`\`|~~~)`),headingBeginRegex:n=>new RegExp(`^ {0,${Math.min(3,n-1)}}#`),htmlBeginRegex:n=>new RegExp(`^ {0,${Math.min(3,n-1)}}<(?:[a-z].*>|!--)`,"i")},be=/^(?:[ \t]*(?:\n|$))+/,me=/^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/,we=/^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/,v=/^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,ye=/^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,O=/(?:[*+-]|\d{1,9}[.)])/,te=/^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,ne=u(te).replace(/bull/g,O).replace(/blockCode/g,/(?: {4}| {0,3}\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\n>]+>\n/).replace(/\|table/g,"").getRegex(),Re=u(te).replace(/bull/g,O).replace(/blockCode/g,/(?: {4}| {0,3}\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\n>]+>\n/).replace(/table/g,/ {0,3}\|?(?:[:\- ]*\|)+[\:\- ]*\n/).getRegex(),G=/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,Se=/^[^\n]+/,N=/(?!\s*\])(?:\\.|[^\[\]\\])+/,Te=u(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace("label",N).replace("title",/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex(),$e=u(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g,O).getRegex(),C="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",j=/|$))/,ve=u("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|\\n*|$)|\\n*|$)|)[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$))","i").replace("comment",j).replace("tag",C).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),re=u(G).replace("hr",v).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("|lheading","").replace("|table","").replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",C).getRegex(),ze=u(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph",re).getRegex(),H={blockquote:ze,code:me,def:Te,fences:we,heading:ye,hr:v,html:ve,lheading:ne,list:$e,newline:be,paragraph:re,table:$,text:Se},se=u("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr",v).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("blockquote"," {0,3}>").replace("code","(?: {4}| {0,3} )[^\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",C).getRegex(),_e={...H,lheading:Re,table:se,paragraph:u(G).replace("hr",v).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("|lheading","").replace("table",se).replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",C).getRegex()},Ae={...H,html:u(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+? *(?:\\n{2,}|\\s*$)|\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace("comment",j).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),def:/^ *\[([^\]]+)\]: *]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,heading:/^(#{1,6})(.*)(?:\n+|$)/,fences:$,lheading:/^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,paragraph:u(G).replace("hr",v).replace("heading",` *#{1,6} *[^ +]`).replace("lheading",ne).replace("|table","").replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").replace("|tag","").getRegex()},Le=/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,Ie=/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,ie=/^( {2,}|\\)\n(?!\s*$)/,Pe=/^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\]*?>/g,oe=/^(?:\*+(?:((?!\*)punct)|[^\s*]))|^_+(?:((?!_)punct)|([^\s_]))/,Ze=u(oe,"u").replace(/punct/g,B).getRegex(),De=u(oe,"u").replace(/punct/g,ae).getRegex(),ce="^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|notPunctSpace(\\*+)(?=notPunctSpace)",Me=u(ce,"gu").replace(/notPunctSpace/g,le).replace(/punctSpace/g,Q).replace(/punct/g,B).getRegex(),Oe=u(ce,"gu").replace(/notPunctSpace/g,Ee).replace(/punctSpace/g,Be).replace(/punct/g,ae).getRegex(),Ge=u("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)","gu").replace(/notPunctSpace/g,le).replace(/punctSpace/g,Q).replace(/punct/g,B).getRegex(),Ne=u(/\\(punct)/,"gu").replace(/punct/g,B).getRegex(),je=u(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme",/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email",/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(),He=u(j).replace("(?:-->|$)","-->").getRegex(),Qe=u("^comment|^|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^|^").replace("comment",He).replace("attribute",/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex(),E=/(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/,Fe=u(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]*(?:\n[ \t]*)?)(title))?\s*\)/).replace("label",E).replace("href",/<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]*/).replace("title",/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex(),he=u(/^!?\[(label)\]\[(ref)\]/).replace("label",E).replace("ref",N).getRegex(),pe=u(/^!?\[(ref)\](?:\[\])?/).replace("ref",N).getRegex(),Ue=u("reflink|nolink(?!\\()","g").replace("reflink",he).replace("nolink",pe).getRegex(),F={_backpedal:$,anyPunctuation:Ne,autolink:je,blockSkip:qe,br:ie,code:Ie,del:$,emStrongLDelim:Ze,emStrongRDelimAst:Me,emStrongRDelimUnd:Ge,escape:Le,link:Fe,nolink:pe,punctuation:Ce,reflink:he,reflinkSearch:Ue,tag:Qe,text:Pe,url:$},Xe={...F,link:u(/^!?\[(label)\]\((.*?)\)/).replace("label",E).getRegex(),reflink:u(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label",E).getRegex()},U={...F,emStrongRDelimAst:Oe,emStrongLDelim:De,url:u(/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,"i").replace("email",/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(),_backpedal:/(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,del:/^(~~?)(?=[^\s~])((?:\\.|[^\\])*?(?:\\.|[^\s~\\]))\1(?=[^~]|$)/,text:/^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\":">",'"':""","'":"'"},ue=n=>Je[n];function m(n,e){if(e){if(x.escapeTest.test(n))return n.replace(x.escapeReplace,ue)}else if(x.escapeTestNoEncode.test(n))return n.replace(x.escapeReplaceNoEncode,ue);return n}function ge(n){try{n=encodeURI(n).replace(x.percentDecode,"%")}catch{return null}return n}function fe(n,e){const t=n.replace(x.findPipe,(i,l,a)=>{let c=!1,o=l;for(;--o>=0&&a[o]==="\\";)c=!c;return c?"|":" |"}),s=t.split(x.splitPipe);let r=0;if(s[0].trim()||s.shift(),s.length>0&&!s.at(-1)?.trim()&&s.pop(),e)if(s.length>e)s.splice(e);else for(;s.length0?-2:-1}function ke(n,e,t,s,r){const i=e.href,l=e.title||null,a=n[1].replace(r.other.outputLinkReplace,"$1");s.state.inLink=!0;const c={type:n[0].charAt(0)==="!"?"image":"link",raw:t,href:i,title:l,text:a,tokens:s.inlineTokens(a)};return s.state.inLink=!1,c}function Ve(n,e,t){const s=n.match(t.other.indentCodeCompensation);if(s===null)return e;const r=s[1];return e.split(` +`).map(i=>{const l=i.match(t.other.beginningSpace);if(l===null)return i;const[a]=l;return a.length>=r.length?i.slice(r.length):i}).join(` +`)}var A=class{options;rules;lexer;constructor(n){this.options=n||R}space(n){const e=this.rules.block.newline.exec(n);if(e&&e[0].length>0)return{type:"space",raw:e[0]}}code(n){const e=this.rules.block.code.exec(n);if(e){const t=e[0].replace(this.rules.other.codeRemoveIndent,"");return{type:"code",raw:e[0],codeBlockStyle:"indented",text:this.options.pedantic?t:_(t,` +`)}}}fences(n){const e=this.rules.block.fences.exec(n);if(e){const t=e[0],s=Ve(t,e[3]||"",this.rules);return{type:"code",raw:t,lang:e[2]?e[2].trim().replace(this.rules.inline.anyPunctuation,"$1"):e[2],text:s}}}heading(n){const e=this.rules.block.heading.exec(n);if(e){let t=e[2].trim();if(this.rules.other.endingHash.test(t)){const s=_(t,"#");(this.options.pedantic||!s||this.rules.other.endingSpaceChar.test(s))&&(t=s.trim())}return{type:"heading",raw:e[0],depth:e[1].length,text:t,tokens:this.lexer.inline(t)}}}hr(n){const e=this.rules.block.hr.exec(n);if(e)return{type:"hr",raw:_(e[0],` +`)}}blockquote(n){const e=this.rules.block.blockquote.exec(n);if(e){let t=_(e[0],` +`).split(` +`),s="",r="";const i=[];for(;t.length>0;){let l=!1;const a=[];let c;for(c=0;c1,r={type:"list",raw:"",ordered:s,start:s?+t.slice(0,-1):"",loose:!1,items:[]};t=s?`\\d{1,9}\\${t.slice(-1)}`:`\\${t}`,this.options.pedantic&&(t=s?t:"[*+-]");const i=this.rules.other.listItemRegex(t);let l=!1;for(;n;){let c=!1,o="",h="";if(!(e=i.exec(n))||this.rules.block.hr.test(n))break;o=e[0],n=n.substring(o.length);let k=e[2].split(` +`,1)[0].replace(this.rules.other.listReplaceTabs,D=>" ".repeat(3*D.length)),p=n.split(` +`,1)[0],d=!k.trim(),f=0;if(this.options.pedantic?(f=2,h=k.trimStart()):d?f=e[1].length+1:(f=e[2].search(this.rules.other.nonSpaceChar),f=f>4?1:f,h=k.slice(f),f+=e[1].length),d&&this.rules.other.blankLine.test(p)&&(o+=p+` +`,n=n.substring(p.length+1),c=!0),!c){const D=this.rules.other.nextBulletRegex(f),K=this.rules.other.hrRegex(f),V=this.rules.other.fencesBeginRegex(f),Y=this.rules.other.headingBeginRegex(f),xe=this.rules.other.htmlBeginRegex(f);for(;n;){const M=n.split(` +`,1)[0];let T;if(p=M,this.options.pedantic?(p=p.replace(this.rules.other.listReplaceNesting," "),T=p):T=p.replace(this.rules.other.tabCharGlobal," "),V.test(p)||Y.test(p)||xe.test(p)||D.test(p)||K.test(p))break;if(T.search(this.rules.other.nonSpaceChar)>=f||!p.trim())h+=` +`+T.slice(f);else{if(d||k.replace(this.rules.other.tabCharGlobal," ").search(this.rules.other.nonSpaceChar)>=4||V.test(k)||Y.test(k)||K.test(k))break;h+=` +`+p}!d&&!p.trim()&&(d=!0),o+=M+` +`,n=n.substring(M.length+1),k=T.slice(f)}}r.loose||(l?r.loose=!0:this.rules.other.doubleBlankLine.test(o)&&(l=!0));let b=null,J;this.options.gfm&&(b=this.rules.other.listIsTask.exec(h),b&&(J=b[0]!=="[ ] ",h=h.replace(this.rules.other.listReplaceTask,""))),r.items.push({type:"list_item",raw:o,task:!!b,checked:J,loose:!1,text:h,tokens:[]}),r.raw+=o}const a=r.items.at(-1);if(a)a.raw=a.raw.trimEnd(),a.text=a.text.trimEnd();else return;r.raw=r.raw.trimEnd();for(let c=0;ck.type==="space"),h=o.length>0&&o.some(k=>this.rules.other.anyLine.test(k.raw));r.loose=h}if(r.loose)for(let c=0;c({text:a,tokens:this.lexer.inline(a),header:!1,align:i.align[c]})));return i}}lheading(n){const e=this.rules.block.lheading.exec(n);if(e)return{type:"heading",raw:e[0],depth:e[2].charAt(0)==="="?1:2,text:e[1],tokens:this.lexer.inline(e[1])}}paragraph(n){const e=this.rules.block.paragraph.exec(n);if(e){const t=e[1].charAt(e[1].length-1)===` +`?e[1].slice(0,-1):e[1];return{type:"paragraph",raw:e[0],text:t,tokens:this.lexer.inline(t)}}}text(n){const e=this.rules.block.text.exec(n);if(e)return{type:"text",raw:e[0],text:e[0],tokens:this.lexer.inline(e[0])}}escape(n){const e=this.rules.inline.escape.exec(n);if(e)return{type:"escape",raw:e[0],text:e[1]}}tag(n){const e=this.rules.inline.tag.exec(n);if(e)return!this.lexer.state.inLink&&this.rules.other.startATag.test(e[0])?this.lexer.state.inLink=!0:this.lexer.state.inLink&&this.rules.other.endATag.test(e[0])&&(this.lexer.state.inLink=!1),!this.lexer.state.inRawBlock&&this.rules.other.startPreScriptTag.test(e[0])?this.lexer.state.inRawBlock=!0:this.lexer.state.inRawBlock&&this.rules.other.endPreScriptTag.test(e[0])&&(this.lexer.state.inRawBlock=!1),{type:"html",raw:e[0],inLink:this.lexer.state.inLink,inRawBlock:this.lexer.state.inRawBlock,block:!1,text:e[0]}}link(n){const e=this.rules.inline.link.exec(n);if(e){const t=e[2].trim();if(!this.options.pedantic&&this.rules.other.startAngleBracket.test(t)){if(!this.rules.other.endAngleBracket.test(t))return;const i=_(t.slice(0,-1),"\\");if((t.length-i.length)%2===0)return}else{const i=Ke(e[2],"()");if(i===-2)return;if(i>-1){const a=(e[0].indexOf("!")===0?5:4)+e[1].length+i;e[2]=e[2].substring(0,i),e[0]=e[0].substring(0,a).trim(),e[3]=""}}let s=e[2],r="";if(this.options.pedantic){const i=this.rules.other.pedanticHrefTitle.exec(s);i&&(s=i[1],r=i[3])}else r=e[3]?e[3].slice(1,-1):"";return s=s.trim(),this.rules.other.startAngleBracket.test(s)&&(this.options.pedantic&&!this.rules.other.endAngleBracket.test(t)?s=s.slice(1):s=s.slice(1,-1)),ke(e,{href:s&&s.replace(this.rules.inline.anyPunctuation,"$1"),title:r&&r.replace(this.rules.inline.anyPunctuation,"$1")},e[0],this.lexer,this.rules)}}reflink(n,e){let t;if((t=this.rules.inline.reflink.exec(n))||(t=this.rules.inline.nolink.exec(n))){const s=(t[2]||t[1]).replace(this.rules.other.multipleSpaceGlobal," "),r=e[s.toLowerCase()];if(!r){const i=t[0].charAt(0);return{type:"text",raw:i,text:i}}return ke(t,r,t[0],this.lexer,this.rules)}}emStrong(n,e,t=""){let s=this.rules.inline.emStrongLDelim.exec(n);if(!s||s[3]&&t.match(this.rules.other.unicodeAlphaNumeric))return;if(!(s[1]||s[2]||"")||!t||this.rules.inline.punctuation.exec(t)){const i=[...s[0]].length-1;let l,a,c=i,o=0;const h=s[0][0]==="*"?this.rules.inline.emStrongRDelimAst:this.rules.inline.emStrongRDelimUnd;for(h.lastIndex=0,e=e.slice(-1*n.length+i);(s=h.exec(e))!=null;){if(l=s[1]||s[2]||s[3]||s[4]||s[5]||s[6],!l)continue;if(a=[...l].length,s[3]||s[4]){c+=a;continue}else if((s[5]||s[6])&&i%3&&!((i+a)%3)){o+=a;continue}if(c-=a,c>0)continue;a=Math.min(a,a+c+o);const k=[...s[0]][0].length,p=n.slice(0,i+s.index+k+a);if(Math.min(i,a)%2){const f=p.slice(1,-1);return{type:"em",raw:p,text:f,tokens:this.lexer.inlineTokens(f)}}const d=p.slice(2,-2);return{type:"strong",raw:p,text:d,tokens:this.lexer.inlineTokens(d)}}}}codespan(n){const e=this.rules.inline.code.exec(n);if(e){let t=e[2].replace(this.rules.other.newLineCharGlobal," ");const s=this.rules.other.nonSpaceChar.test(t),r=this.rules.other.startingSpaceChar.test(t)&&this.rules.other.endingSpaceChar.test(t);return s&&r&&(t=t.substring(1,t.length-1)),{type:"codespan",raw:e[0],text:t}}}br(n){const e=this.rules.inline.br.exec(n);if(e)return{type:"br",raw:e[0]}}del(n){const e=this.rules.inline.del.exec(n);if(e)return{type:"del",raw:e[0],text:e[2],tokens:this.lexer.inlineTokens(e[2])}}autolink(n){const e=this.rules.inline.autolink.exec(n);if(e){let t,s;return e[2]==="@"?(t=e[1],s="mailto:"+t):(t=e[1],s=t),{type:"link",raw:e[0],text:t,href:s,tokens:[{type:"text",raw:t,text:t}]}}}url(n){let e;if(e=this.rules.inline.url.exec(n)){let t,s;if(e[2]==="@")t=e[0],s="mailto:"+t;else{let r;do r=e[0],e[0]=this.rules.inline._backpedal.exec(e[0])?.[0]??"";while(r!==e[0]);t=e[0],e[1]==="www."?s="http://"+e[0]:s=e[0]}return{type:"link",raw:e[0],text:t,href:s,tokens:[{type:"text",raw:t,text:t}]}}}inlineText(n){const e=this.rules.inline.text.exec(n);if(e){const t=this.lexer.state.inRawBlock;return{type:"text",raw:e[0],text:e[0],escaped:t}}}},w=class X{tokens;options;state;tokenizer;inlineQueue;constructor(e){this.tokens=[],this.tokens.links=Object.create(null),this.options=e||R,this.options.tokenizer=this.options.tokenizer||new A,this.tokenizer=this.options.tokenizer,this.tokenizer.options=this.options,this.tokenizer.lexer=this,this.inlineQueue=[],this.state={inLink:!1,inRawBlock:!1,top:!0};const t={other:x,block:q.normal,inline:z.normal};this.options.pedantic?(t.block=q.pedantic,t.inline=z.pedantic):this.options.gfm&&(t.block=q.gfm,this.options.breaks?t.inline=z.breaks:t.inline=z.gfm),this.tokenizer.rules=t}static get rules(){return{block:q,inline:z}}static lex(e,t){return new X(t).lex(e)}static lexInline(e,t){return new X(t).inlineTokens(e)}lex(e){e=e.replace(x.carriageReturn,` +`),this.blockTokens(e,this.tokens);for(let t=0;t(r=l.call({lexer:this},e,t))?(e=e.substring(r.raw.length),t.push(r),!0):!1))continue;if(r=this.tokenizer.space(e)){e=e.substring(r.raw.length);const l=t.at(-1);r.raw.length===1&&l!==void 0?l.raw+=` +`:t.push(r);continue}if(r=this.tokenizer.code(e)){e=e.substring(r.raw.length);const l=t.at(-1);l?.type==="paragraph"||l?.type==="text"?(l.raw+=` +`+r.raw,l.text+=` +`+r.text,this.inlineQueue.at(-1).src=l.text):t.push(r);continue}if(r=this.tokenizer.fences(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.heading(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.hr(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.blockquote(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.list(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.html(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.def(e)){e=e.substring(r.raw.length);const l=t.at(-1);l?.type==="paragraph"||l?.type==="text"?(l.raw+=` +`+r.raw,l.text+=` +`+r.raw,this.inlineQueue.at(-1).src=l.text):this.tokens.links[r.tag]||(this.tokens.links[r.tag]={href:r.href,title:r.title});continue}if(r=this.tokenizer.table(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.lheading(e)){e=e.substring(r.raw.length),t.push(r);continue}let i=e;if(this.options.extensions?.startBlock){let l=1/0;const a=e.slice(1);let c;this.options.extensions.startBlock.forEach(o=>{c=o.call({lexer:this},a),typeof c=="number"&&c>=0&&(l=Math.min(l,c))}),l<1/0&&l>=0&&(i=e.substring(0,l+1))}if(this.state.top&&(r=this.tokenizer.paragraph(i))){const l=t.at(-1);s&&l?.type==="paragraph"?(l.raw+=` +`+r.raw,l.text+=` +`+r.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=l.text):t.push(r),s=i.length!==e.length,e=e.substring(r.raw.length);continue}if(r=this.tokenizer.text(e)){e=e.substring(r.raw.length);const l=t.at(-1);l?.type==="text"?(l.raw+=` +`+r.raw,l.text+=` +`+r.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=l.text):t.push(r);continue}if(e){const l="Infinite loop on byte: "+e.charCodeAt(0);if(this.options.silent){console.error(l);break}else throw new Error(l)}}return this.state.top=!0,t}inline(e,t=[]){return this.inlineQueue.push({src:e,tokens:t}),t}inlineTokens(e,t=[]){let s=e,r=null;if(this.tokens.links){const a=Object.keys(this.tokens.links);if(a.length>0)for(;(r=this.tokenizer.rules.inline.reflinkSearch.exec(s))!=null;)a.includes(r[0].slice(r[0].lastIndexOf("[")+1,-1))&&(s=s.slice(0,r.index)+"["+"a".repeat(r[0].length-2)+"]"+s.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex))}for(;(r=this.tokenizer.rules.inline.anyPunctuation.exec(s))!=null;)s=s.slice(0,r.index)+"++"+s.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);for(;(r=this.tokenizer.rules.inline.blockSkip.exec(s))!=null;)s=s.slice(0,r.index)+"["+"a".repeat(r[0].length-2)+"]"+s.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);let i=!1,l="";for(;e;){i||(l=""),i=!1;let a;if(this.options.extensions?.inline?.some(o=>(a=o.call({lexer:this},e,t))?(e=e.substring(a.raw.length),t.push(a),!0):!1))continue;if(a=this.tokenizer.escape(e)){e=e.substring(a.raw.length),t.push(a);continue}if(a=this.tokenizer.tag(e)){e=e.substring(a.raw.length),t.push(a);continue}if(a=this.tokenizer.link(e)){e=e.substring(a.raw.length),t.push(a);continue}if(a=this.tokenizer.reflink(e,this.tokens.links)){e=e.substring(a.raw.length);const o=t.at(-1);a.type==="text"&&o?.type==="text"?(o.raw+=a.raw,o.text+=a.text):t.push(a);continue}if(a=this.tokenizer.emStrong(e,s,l)){e=e.substring(a.raw.length),t.push(a);continue}if(a=this.tokenizer.codespan(e)){e=e.substring(a.raw.length),t.push(a);continue}if(a=this.tokenizer.br(e)){e=e.substring(a.raw.length),t.push(a);continue}if(a=this.tokenizer.del(e)){e=e.substring(a.raw.length),t.push(a);continue}if(a=this.tokenizer.autolink(e)){e=e.substring(a.raw.length),t.push(a);continue}if(!this.state.inLink&&(a=this.tokenizer.url(e))){e=e.substring(a.raw.length),t.push(a);continue}let c=e;if(this.options.extensions?.startInline){let o=1/0;const h=e.slice(1);let k;this.options.extensions.startInline.forEach(p=>{k=p.call({lexer:this},h),typeof k=="number"&&k>=0&&(o=Math.min(o,k))}),o<1/0&&o>=0&&(c=e.substring(0,o+1))}if(a=this.tokenizer.inlineText(c)){e=e.substring(a.raw.length),a.raw.slice(-1)!=="_"&&(l=a.raw.slice(-1)),i=!0;const o=t.at(-1);o?.type==="text"?(o.raw+=a.raw,o.text+=a.text):t.push(a);continue}if(e){const o="Infinite loop on byte: "+e.charCodeAt(0);if(this.options.silent){console.error(o);break}else throw new Error(o)}}return t}},L=class{options;parser;constructor(n){this.options=n||R}space(n){return""}code({text:n,lang:e,escaped:t}){const s=(e||"").match(x.notSpaceStart)?.[0],r=n.replace(x.endingNewline,"")+` +`;return s?'
    '+(t?r:m(r,!0))+`
    +`:"
    "+(t?r:m(r,!0))+`
    +`}blockquote({tokens:n}){return`
    +${this.parser.parse(n)}
    +`}html({text:n}){return n}heading({tokens:n,depth:e}){return`${this.parser.parseInline(n)} +`}hr(n){return`
    +`}list(n){const e=n.ordered,t=n.start;let s="";for(let l=0;l +`+s+" +`}listitem(n){let e="";if(n.task){const t=this.checkbox({checked:!!n.checked});n.loose?n.tokens[0]?.type==="paragraph"?(n.tokens[0].text=t+" "+n.tokens[0].text,n.tokens[0].tokens&&n.tokens[0].tokens.length>0&&n.tokens[0].tokens[0].type==="text"&&(n.tokens[0].tokens[0].text=t+" "+m(n.tokens[0].tokens[0].text),n.tokens[0].tokens[0].escaped=!0)):n.tokens.unshift({type:"text",raw:t+" ",text:t+" ",escaped:!0}):e+=t+" "}return e+=this.parser.parse(n.tokens,!!n.loose),`
  • ${e}
  • +`}checkbox({checked:n}){return"'}paragraph({tokens:n}){return`

    ${this.parser.parseInline(n)}

    +`}table(n){let e="",t="";for(let r=0;r${s}`),` + +`+e+` +`+s+`
    +`}tablerow({text:n}){return` +${n} +`}tablecell(n){const e=this.parser.parseInline(n.tokens),t=n.header?"th":"td";return(n.align?`<${t} align="${n.align}">`:`<${t}>`)+e+` +`}strong({tokens:n}){return`${this.parser.parseInline(n)}`}em({tokens:n}){return`${this.parser.parseInline(n)}`}codespan({text:n}){return`${m(n,!0)}`}br(n){return"
    "}del({tokens:n}){return`${this.parser.parseInline(n)}`}link({href:n,title:e,tokens:t}){const s=this.parser.parseInline(t),r=ge(n);if(r===null)return s;n=r;let i='
    ",i}image({href:n,title:e,text:t,tokens:s}){s&&(t=this.parser.parseInline(s,this.parser.textRenderer));const r=ge(n);if(r===null)return m(t);n=r;let i=`${t}{const l=r[i].flat(1/0);t=t.concat(this.walkTokens(l,e))}):r.tokens&&(t=t.concat(this.walkTokens(r.tokens,e)))}}return t}use(...n){const e=this.defaults.extensions||{renderers:{},childTokens:{}};return n.forEach(t=>{const s={...t};if(s.async=this.defaults.async||s.async||!1,t.extensions&&(t.extensions.forEach(r=>{if(!r.name)throw new Error("extension name required");if("renderer"in r){const i=e.renderers[r.name];i?e.renderers[r.name]=function(...l){let a=r.renderer.apply(this,l);return a===!1&&(a=i.apply(this,l)),a}:e.renderers[r.name]=r.renderer}if("tokenizer"in r){if(!r.level||r.level!=="block"&&r.level!=="inline")throw new Error("extension level must be 'block' or 'inline'");const i=e[r.level];i?i.unshift(r.tokenizer):e[r.level]=[r.tokenizer],r.start&&(r.level==="block"?e.startBlock?e.startBlock.push(r.start):e.startBlock=[r.start]:r.level==="inline"&&(e.startInline?e.startInline.push(r.start):e.startInline=[r.start]))}"childTokens"in r&&r.childTokens&&(e.childTokens[r.name]=r.childTokens)}),s.extensions=e),t.renderer){const r=this.defaults.renderer||new L(this.defaults);for(const i in t.renderer){if(!(i in r))throw new Error(`renderer '${i}' does not exist`);if(["options","parser"].includes(i))continue;const l=i,a=t.renderer[l],c=r[l];r[l]=(...o)=>{let h=a.apply(r,o);return h===!1&&(h=c.apply(r,o)),h||""}}s.renderer=r}if(t.tokenizer){const r=this.defaults.tokenizer||new A(this.defaults);for(const i in t.tokenizer){if(!(i in r))throw new Error(`tokenizer '${i}' does not exist`);if(["options","rules","lexer"].includes(i))continue;const l=i,a=t.tokenizer[l],c=r[l];r[l]=(...o)=>{let h=a.apply(r,o);return h===!1&&(h=c.apply(r,o)),h}}s.tokenizer=r}if(t.hooks){const r=this.defaults.hooks||new I;for(const i in t.hooks){if(!(i in r))throw new Error(`hook '${i}' does not exist`);if(["options","block"].includes(i))continue;const l=i,a=t.hooks[l],c=r[l];I.passThroughHooks.has(i)?r[l]=o=>{if(this.defaults.async)return Promise.resolve(a.call(r,o)).then(k=>c.call(r,k));const h=a.call(r,o);return c.call(r,h)}:r[l]=(...o)=>{let h=a.apply(r,o);return h===!1&&(h=c.apply(r,o)),h}}s.hooks=r}if(t.walkTokens){const r=this.defaults.walkTokens,i=t.walkTokens;s.walkTokens=function(l){let a=[];return a.push(i.call(this,l)),r&&(a=a.concat(r.call(this,l))),a}}this.defaults={...this.defaults,...s}}),this}setOptions(n){return this.defaults={...this.defaults,...n},this}lexer(n,e){return w.lex(n,e??this.defaults)}parser(n,e){return y.parse(n,e??this.defaults)}parseMarkdown(n){return(t,s)=>{const r={...s},i={...this.defaults,...r},l=this.onError(!!i.silent,!!i.async);if(this.defaults.async===!0&&r.async===!1)return l(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));if(typeof t>"u"||t===null)return l(new Error("marked(): input parameter is undefined or null"));if(typeof t!="string")return l(new Error("marked(): input parameter is of type "+Object.prototype.toString.call(t)+", string expected"));i.hooks&&(i.hooks.options=i,i.hooks.block=n);const a=i.hooks?i.hooks.provideLexer():n?w.lex:w.lexInline,c=i.hooks?i.hooks.provideParser():n?y.parse:y.parseInline;if(i.async)return Promise.resolve(i.hooks?i.hooks.preprocess(t):t).then(o=>a(o,i)).then(o=>i.hooks?i.hooks.processAllTokens(o):o).then(o=>i.walkTokens?Promise.all(this.walkTokens(o,i.walkTokens)).then(()=>o):o).then(o=>c(o,i)).then(o=>i.hooks?i.hooks.postprocess(o):o).catch(l);try{i.hooks&&(t=i.hooks.preprocess(t));let o=a(t,i);i.hooks&&(o=i.hooks.processAllTokens(o)),i.walkTokens&&this.walkTokens(o,i.walkTokens);let h=c(o,i);return i.hooks&&(h=i.hooks.postprocess(h)),h}catch(o){return l(o)}}}onError(n,e){return t=>{if(t.message+=` +Please report this to https://github.com/markedjs/marked.`,n){const s="

    An error occurred:

    "+m(t.message+"",!0)+"
    ";return e?Promise.resolve(s):s}if(e)return Promise.reject(t);throw t}}},S=new de;function g(n,e){return S.parse(n,e)}g.options=g.setOptions=function(n){return S.setOptions(n),g.defaults=S.defaults,ee(g.defaults),g},g.getDefaults=P,g.defaults=R,g.use=function(...n){return S.use(...n),g.defaults=S.defaults,ee(g.defaults),g},g.walkTokens=function(n,e){return S.walkTokens(n,e)},g.parseInline=S.parseInline,g.Parser=y,g.parser=y.parse,g.Renderer=L,g.TextRenderer=Z,g.Lexer=w,g.lexer=w.lex,g.Tokenizer=A,g.Hooks=I,g.parse=g;var Ye=g.options,et=g.setOptions,tt=g.use,nt=g.walkTokens,rt=g.parseInline,st=g,it=y.parse,lt=w.lex;export{I as Hooks,w as Lexer,de as Marked,y as Parser,L as Renderer,Z as TextRenderer,A as Tokenizer,R as defaults,P as getDefaults,lt as lexer,g as marked,Ye as options,st as parse,rt as parseInline,it as parser,et as setOptions,tt as use,nt as walkTokens}; +//# sourceMappingURL=/sm/66b5932b4b2303fac670bd2b11442e2e0cc01da544e66d680f3a5ad342cf5ab6.map \ No newline at end of file diff --git a/docs/architecture.md b/docs/architecture.md index 8111924..b3004ac 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -267,9 +267,12 @@ or env-only via `os.getenv(...)`. ## 9. UI -`apps/ui` is a single-page Streamlit app (`streamlit run apps/ui/src/twfarmbot_ui/app.py`). -It contains **zero business logic** — every widget is a thin HTTP proxy -to the api_server: +`apps/ui` is a custom Material 3 single-page web app (static HTML/JS using +[Material Web Components](https://github.com/material-components/material-web)) +served by a small FastAPI server (`twfarmbot_ui/server.py`). The server +reverse-proxies `/api/*` to the api_server and `/resireg/*` to the vision +server, so the browser stays same-origin. The UI contains **zero business +logic** — every widget is a thin HTTP proxy to the api_server: **Reads (buttons/forms in the UI):** - "Check status" sidebar button → `GET /health` diff --git a/pyproject.toml b/pyproject.toml index 24d02e1..0515853 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -75,10 +75,6 @@ ignore_missing_imports = true no_warn_return_any = true warn_unused_ignores = true -[[tool.mypy.overrides]] -module = "twfarmbot_ui.app" -disable_error_code = ["union-attr", "index", "arg-type", "call-overload", "var-annotated"] - [tool.hatch.build.targets.wheel] packages = ["."] diff --git a/scripts/install_services.sh b/scripts/install_services.sh index 80b68f6..c0a0ef7 100755 --- a/scripts/install_services.sh +++ b/scripts/install_services.sh @@ -7,15 +7,6 @@ USER_SYSTEMD_DIR="${HOME}/.config/systemd/user" mkdir -p "${USER_SYSTEMD_DIR}" cp "${SCRIPT_DIR}/systemd/"*.service "${USER_SYSTEMD_DIR}/" -# Pre-accept Streamlit's email prompt so the UI service starts non-interactively. -mkdir -p "${HOME}/.streamlit" -if [[ ! -f "${HOME}/.streamlit/credentials.toml" ]]; then - cat > "${HOME}/.streamlit/credentials.toml" <<'EOF' -[general] -email = "" -EOF -fi - systemctl --user daemon-reload systemctl --user enable twfarmbot-resireg twfarmbot-api twfarmbot-ui diff --git a/scripts/systemd/twfarmbot-ui.service b/scripts/systemd/twfarmbot-ui.service index 6deeff4..95d93b9 100644 --- a/scripts/systemd/twfarmbot-ui.service +++ b/scripts/systemd/twfarmbot-ui.service @@ -1,5 +1,5 @@ [Unit] -Description=TWFarmBot Streamlit UI +Description=TWFarmBot Web UI After=network-online.target twfarmbot-api.service Wants=network-online.target twfarmbot-api.service @@ -11,8 +11,6 @@ WorkingDirectory=/home/farmbot/TWFarmBot Environment="HOME=/home/farmbot" Environment="PATH=/home/farmbot/.local/bin:/usr/local/bin:/usr/bin:/bin" Environment="PYTHONUNBUFFERED=1" -Environment="STREAMLIT_BROWSER_GATHERUSAGESTATS=false" -Environment="STREAMLIT_SERVER_HEADLESS=true" ExecStart=/home/farmbot/.local/bin/uv run --env-file=.env twfarmbot-ui Restart=on-failure RestartSec=5 diff --git a/tests/test_assistant_tab.py b/tests/test_assistant_tab.py index e0ad629..1bab5a3 100644 --- a/tests/test_assistant_tab.py +++ b/tests/test_assistant_tab.py @@ -1,6 +1,6 @@ -"""Tests for the Assistant tab in the Streamlit UI. +"""Tests for the Assistant tab's API contract. -Streamlit's renderers are hard to unit-test directly. We exercise the +The frontend renderers are browser-side. We exercise the end-to-end flow by talking to the real ``POST /plan`` endpoint with ``planning_service.plan`` stubbed, then verifying the endpoint returns the shapes the UI expects. diff --git a/tests/test_ui.py b/tests/test_ui.py index 0dae0dd..f1d0271 100644 --- a/tests/test_ui.py +++ b/tests/test_ui.py @@ -1,7 +1,7 @@ -"""Tests for the UI's API client. +"""Tests for the UI package's Python API client. -The Streamlit app itself is hard to unit-test (renders DOM), but the -``ApiClient`` it uses to talk to the API is testable in isolation. +The web frontend itself is browser-side; the ``ApiClient`` kept for +scripts/tests is testable in isolation. """ from __future__ import annotations diff --git a/tests/test_ui_server.py b/tests/test_ui_server.py new file mode 100644 index 0000000..402a895 --- /dev/null +++ b/tests/test_ui_server.py @@ -0,0 +1,212 @@ +"""Tests for the Material 3 UI server (static frontend + API proxy). + +The proxy is exercised against an in-process stub upstream via httpx's +ASGITransport, so no sockets are opened. +""" + +from __future__ import annotations + +import hashlib +import json +from pathlib import Path +from typing import Any, Iterator + +import httpx +import pytest +from fastapi import FastAPI +from fastapi.responses import StreamingResponse +from fastapi.testclient import TestClient + + +def _upstream() -> FastAPI: + app = FastAPI() + + @app.get("/health") + def health() -> dict[str, Any]: + return {"status": "ok", "actions": ["move"], "farmbot": "connected"} + + @app.get("/pin/{pin}") + def pin(pin: int, mode: str = "digital") -> dict[str, Any]: + return {"pin": pin, "mode": mode, "value": 1} + + @app.post("/actions") + def actions(payload: dict[str, Any], wait: bool = True) -> dict[str, Any]: + return {"status": "ok" if wait else "queued", "action": payload} + + @app.post("/chat/stream") + def chat_stream() -> StreamingResponse: + def events() -> Iterator[str]: + yield f"data: {json.dumps({'type': 'delta', 'content': 'hi'})}\n\n" + yield f"data: {json.dumps({'type': 'meta', 'metrics': {}})}\n\n" + + return StreamingResponse(events(), media_type="text/event-stream") + + return app + + +@pytest.fixture +def client(tmp_path, monkeypatch: pytest.MonkeyPatch) -> Iterator[TestClient]: + monkeypatch.setenv("TWFB_UI_DATA_DIR", str(tmp_path / "sessions")) + from twfarmbot_ui.server import create_app + + proxy_http = httpx.AsyncClient(transport=httpx.ASGITransport(app=_upstream())) + with TestClient(create_app(http_client=proxy_http)) as test_client: + yield test_client + + +def test_serves_material_frontend(client: TestClient) -> None: + r = client.get("/") + assert r.status_code == 200 + assert "@material/web" in r.text + + r = client.get("/js/main.js") + assert r.status_code == 200 + + +def test_proxies_api_get(client: TestClient) -> None: + r = client.get("/api/health") + assert r.status_code == 200 + assert r.json()["farmbot"] == "connected" + + +def test_proxies_query_params(client: TestClient) -> None: + r = client.get("/api/pin/13", params={"mode": "analog"}) + assert r.json() == {"pin": 13, "mode": "analog", "value": 1} + + +def test_proxies_post_body_and_wait_param(client: TestClient) -> None: + r = client.post( + "/api/actions", + params={"wait": "false"}, + json={"kind": "move", "params": {"x": 1}}, + ) + assert r.json()["status"] == "queued" + assert r.json()["action"]["kind"] == "move" + + +def test_proxies_sse_stream(client: TestClient) -> None: + with client.stream("POST", "/api/chat/stream", json={"messages": []}) as r: + assert r.status_code == 200 + assert r.headers["content-type"].startswith("text/event-stream") + body = b"".join(r.iter_bytes()).decode() + assert '"type": "delta"' in body + assert '"type": "meta"' in body + + +def test_proxy_returns_502_on_connection_failure( + tmp_path, monkeypatch: pytest.MonkeyPatch +) -> None: + monkeypatch.setenv("TWFB_UI_DATA_DIR", str(tmp_path / "sessions")) + from twfarmbot_ui.server import create_app + + class FailingTransport(httpx.AsyncBaseTransport): + async def handle_async_request(self, request: httpx.Request) -> httpx.Response: + raise httpx.ConnectError("refused") + + proxy_http = httpx.AsyncClient(transport=FailingTransport()) + with TestClient(create_app(http_client=proxy_http)) as test_client: + r = test_client.get("/api/health") + assert r.status_code == 502 + assert "ConnectError" in r.json()["detail"] + + +def test_session_crud_roundtrip(client: TestClient) -> None: + snapshot = client.post("/ui/sessions").json() + session_id = snapshot["session_id"] + + snapshot["label"] = "watering experiment" + snapshot["assistant_messages"] = [{"role": "user", "content": "water bed 1"}] + assert client.put(f"/ui/sessions/{session_id}", json=snapshot).status_code == 200 + + listed = client.get("/ui/sessions").json()["sessions"] + assert [s["session_id"] for s in listed] == [session_id] + assert listed[0]["preview"] == "water bed 1" + + loaded = client.get(f"/ui/sessions/{session_id}").json() + assert loaded["label"] == "watering experiment" + + delete_resp = client.delete(f"/ui/sessions/{session_id}") + assert delete_resp.json() == {"deleted": True} + assert client.get(f"/ui/sessions/{session_id}").status_code == 404 + + +def test_garden_entity_appended_to_yaml( + client: TestClient, tmp_path, monkeypatch: pytest.MonkeyPatch +) -> None: + config = tmp_path / "dev.yaml" + config.write_text( + "# keep this comment\nspatial:\n bounds: {x: 0, y: 0, width: 100, height: 100}\n", + encoding="utf-8", + ) + monkeypatch.setenv("TWFB_CONFIG", str(config)) + + r = client.post( + "/ui/garden/entities", + json={"x": 25.0, "y": 50.0, "kind": "plant", "name": "Tomato 1"}, + ) + assert r.status_code == 200 + assert r.json()["entity"]["id"] == "tomato_1" + + text = config.read_text(encoding="utf-8") + assert "# keep this comment" in text # round-trip preserves comments + assert "tomato_1" in text + + +def test_config_endpoint_updates_upstream(client: TestClient) -> None: + r = client.put("/ui/config", json={"api_url": "http://other:9000/"}) + assert r.json()["api_url"] == "http://other:9000" + assert client.get("/ui/config").json()["api_url"] == "http://other:9000" + + +def _static_dir() -> Path: + from twfarmbot_ui.server import STATIC_DIR + + return STATIC_DIR + + +def test_vendored_js_importmap_is_local_and_offline_capable(client: TestClient) -> None: + """Every entry in the importmap must resolve to a file under vendor/ + that the FastAPI server can serve — no esm.run / jsdelivr references.""" + html = client.get("/").text + assert "https://esm.run" not in html, ( + "importmap still points at esm.run — UI would break offline" + ) + static = _static_dir() + vendor = static / "vendor" + manifest = json.loads((vendor / "manifest.json").read_text()) + seen: set[str] = set() + for entry in manifest: + path = vendor / entry["path"] + assert path.is_file(), f"missing vendored file: {path}" + digest = hashlib.sha256(path.read_bytes()).hexdigest() + assert digest == entry["sha256"], f"hash mismatch for {path}" + served = client.get(f"/vendor/{entry['path']}") + assert served.status_code == 200 + assert served.headers["cache-control"].startswith("public") + seen.add(entry["path"]) + assert len(seen) == len(manifest) + + +def test_vendored_assets_satisfy_importmap_targets(client: TestClient) -> None: + """Each pinned importmap target must have a corresponding vendored file.""" + import re + + html = client.get("/").text + match = re.search( + r'', html, re.DOTALL + ) + assert match, "importmap block not found" + importmap = json.loads(match.group(1)) + static = _static_dir() + for specifier, target in importmap["imports"].items(): + if target.startswith(("http://", "https://")): + assert False, f"{specifier} still resolves to {target}" + prefix = target.rstrip("/") + if specifier.endswith("/"): + # Bare directory specifier: at least one file must exist beneath it. + assert any((static / prefix).rglob("*.js")), ( + f"no JS files under {static / prefix}" + ) + else: + file_path = static / target + assert file_path.is_file(), f"missing vendored file {file_path}" diff --git a/uv.lock b/uv.lock index cdbe37a..263d733 100644 --- a/uv.lock +++ b/uv.lock @@ -46,22 +46,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/30/95/f456ae7928a2f3a913f467d4fd9e662e295dd7349fc58b35f77f6c757a23/abnf-2.2.0-py3-none-any.whl", hash = "sha256:5dc2ae31a84ff454f7de46e08a2a21a442a0e21a092468420587a1590b490d1f", size = 39938, upload-time = "2023-03-17T18:26:22.608Z" }, ] -[[package]] -name = "altair" -version = "6.2.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "jinja2" }, - { name = "jsonschema" }, - { name = "narwhals" }, - { name = "packaging" }, - { name = "typing-extensions", marker = "python_full_version < '3.15'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/86/97/9a0dc61efd4f2dee29cb6d8edbbacdb789ce48cbffd98efa2b3ab145b297/altair-6.2.1.tar.gz", hash = "sha256:ca0298fa20b1a4fae22eff8847b95f74912bd90544013ad36af192119883ea64", size = 766468, upload-time = "2026-06-05T16:23:36.57Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/dc/78/b556548d92b9e29ae68a86e7b416888820900809e189e39caf308c7d44a3/altair-6.2.1-py3-none-any.whl", hash = "sha256:bf2fee3733c3a31a588e45b857a2495a88d506970deb87f74e1613f0247446b1", size = 797498, upload-time = "2026-06-05T16:23:34.799Z" }, -] - [[package]] name = "annotated-doc" version = "0.0.4" @@ -164,15 +148,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/df/73/b6e24bd22e6720ca8ee9a85a0c4a2971af8497d8f3193fa05390cbd46e09/backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8", size = 15148, upload-time = "2022-10-05T19:19:30.546Z" }, ] -[[package]] -name = "blinker" -version = "1.9.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/21/28/9b3f50ce0e048515135495f198351908d99540d69bfdc8c1d15b73dc55ce/blinker-1.9.0.tar.gz", hash = "sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf", size = 22460, upload-time = "2024-11-08T17:25:47.436Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl", hash = "sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc", size = 8458, upload-time = "2024-11-08T17:25:46.184Z" }, -] - [[package]] name = "cachetools" version = "7.1.4" @@ -930,30 +905,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e5/22/4222d7ddf3da30f363edaa98e329c2bce6c65497c9cb2810931c8b2c0fbc/fsspec-2026.6.0-py3-none-any.whl", hash = "sha256:02e0b71817df9b2169dc30a16832045764def1191b43dcff5bb85bdee212d2a1", size = 203949, upload-time = "2026-06-16T01:57:26.358Z" }, ] -[[package]] -name = "gitdb" -version = "4.0.12" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "smmap" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/72/94/63b0fc47eb32792c7ba1fe1b694daec9a63620db1e313033d18140c2320a/gitdb-4.0.12.tar.gz", hash = "sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571", size = 394684, upload-time = "2025-01-02T07:20:46.413Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl", hash = "sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf", size = 62794, upload-time = "2025-01-02T07:20:43.624Z" }, -] - -[[package]] -name = "gitpython" -version = "3.1.50" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "gitdb" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/33/f6/354ae6491228b5eb40e10d89c4d13c651fe1cf7556e35ebdded50cff57ce/gitpython-3.1.50.tar.gz", hash = "sha256:80da2d12504d52e1f998772dc5baf6e553f8d2fcfe1fcc226c9d9a2ee3372dcc", size = 219798, upload-time = "2026-05-06T04:01:26.571Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl", hash = "sha256:d352abe2908d07355014abdd21ddf798c2a961469239afec4962e9da884858f9", size = 212507, upload-time = "2026-05-06T04:01:23.799Z" }, -] - [[package]] name = "googleapis-common-protos" version = "1.75.0" @@ -1058,56 +1009,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, ] -[[package]] -name = "httptools" -version = "0.8.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/43/e5/d471fcb0e14523fe1c3f4ba58ca52480e7bd70ad7109a3846bc75892f7fb/httptools-0.8.0.tar.gz", hash = "sha256:6b2a32f18d97e16e90827d7a819ffa8dbd8cc245fc4e1fa9d1095b54ef4bd999", size = 271342, upload-time = "2026-05-25T22:17:48.841Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/40/b9/be66eb0decd730d89b9c94f930e4b8d87787b05724bb84af98bfd825f72c/httptools-0.8.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:bf3b6f807c8541503cecfbb8a8dffb385640d0d96102f3d112aa8740f9b7c826", size = 208805, upload-time = "2026-05-25T22:16:50.434Z" }, - { url = "https://files.pythonhosted.org/packages/9d/f7/b4d41eaae2869d31356bc4bbf546f44fae83ff298af0a043ca0625b06773/httptools-0.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:da684f2e1aa2ee9bdcb083f3f3a68c5956750b375bc5df864d3a5f0c42a40b77", size = 113527, upload-time = "2026-05-25T22:16:51.672Z" }, - { url = "https://files.pythonhosted.org/packages/e6/e4/77487e14fc7be47180fd0eb4267c7486d0cc59b74031839a3daf8650136b/httptools-0.8.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:a6f21e2a3b0067bbe7f67e34cfd16276af556e5e52f4c7503be0cb5f90e905e4", size = 450035, upload-time = "2026-05-25T22:16:53.313Z" }, - { url = "https://files.pythonhosted.org/packages/da/72/5a8f787e323f56fbd86c32a4be92a86776e4cfe8b4317db999f452028362/httptools-0.8.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ea897f0c729581ebf72131a438a7932d9b14efef72d75ada966700cac3caaeb", size = 451101, upload-time = "2026-05-25T22:16:54.696Z" }, - { url = "https://files.pythonhosted.org/packages/ed/41/b44a25560955197674b6744cb903664300e239235a5eaa69df0890d87054/httptools-0.8.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c0d726cc107fceb7d45f978483b4b70dd8caa836f5914d3434bb18628eb73813", size = 436140, upload-time = "2026-05-25T22:16:56.239Z" }, - { url = "https://files.pythonhosted.org/packages/74/b0/054aac84c03d7e097bf4c605fb7e74eec3d65c0276adf64ee97f3a103ff5/httptools-0.8.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9878eb2785ba5eb70631ad269b37976f73d647955e26c91d490eb8a4edfda4ba", size = 437041, upload-time = "2026-05-25T22:16:57.716Z" }, - { url = "https://files.pythonhosted.org/packages/bb/e8/86b85bbc0ac7892232f1a99ab96a9aa71936984fa06adfc0afc83ca7789e/httptools-0.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:b205e5f5523fa039679da0dfe5a10132b2a4abeae6a86fdd1ddc035f7f836557", size = 90454, upload-time = "2026-05-25T22:16:58.871Z" }, - { url = "https://files.pythonhosted.org/packages/f8/d2/c3eedaef57de65c3cc5f8dc244cf12d09c84ad258a479055aad6db23206c/httptools-0.8.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ed377e64805bdba4943c82717333f8f8603a13b09aff9cead2717c6c817fb168", size = 208428, upload-time = "2026-05-25T22:16:59.717Z" }, - { url = "https://files.pythonhosted.org/packages/f1/94/dfe435d90d0ef61ec0f2cc3d480eef78c59727c6c2ce039f433882f6131a/httptools-0.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9518c406d7b310f05adb1a37f80acabac40504a575d7c0da6d3e365c695ac20d", size = 113366, upload-time = "2026-05-25T22:17:00.795Z" }, - { url = "https://files.pythonhosted.org/packages/cc/d4/13025f1a56e615dcb331e0bbe2d9a1143212b58c263385fc5d2e558f5bac/httptools-0.8.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:57278e6fa0424c42a8a3e454828ab4f0aff27b40cddf9679579b98c6dce6a376", size = 464676, upload-time = "2026-05-25T22:17:02.014Z" }, - { url = "https://files.pythonhosted.org/packages/bf/95/4c1c26c0b985f8a3331682d802598f14e32dc41bf7509266eb2c04ad4801/httptools-0.8.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bbb8caadb2b742d293169d2b458b5c001ef70e3158704aa3d3ef9597624c5d1d", size = 464235, upload-time = "2026-05-25T22:17:03.109Z" }, - { url = "https://files.pythonhosted.org/packages/a2/82/6735be2b0ca527718c431cdb8e5f70c3862c0844a687df0f572c51e11497/httptools-0.8.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:52dd695b865fe96d9d2b16b64a895f3f57bf3cb064e8383cd3b5713a069e8085", size = 449809, upload-time = "2026-05-25T22:17:04.443Z" }, - { url = "https://files.pythonhosted.org/packages/b5/f9/5811c74f37a758c8a4aa3dc430375119d335947e883efc4664d8f3559a41/httptools-0.8.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:20b4aac66ff65f7db06a375808b78f42a94970aa22e826b3cb2b43eb09174124", size = 452174, upload-time = "2026-05-25T22:17:05.476Z" }, - { url = "https://files.pythonhosted.org/packages/cc/94/97b75870dea07b71e3ec535cebe525b08d723152e4c7d13fa887e51f4de2/httptools-0.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:a1b4c8e7a489a0d750d91894e9a8cdc295838f1924c0ca903ae993456fddec07", size = 90991, upload-time = "2026-05-25T22:17:06.75Z" }, - { url = "https://files.pythonhosted.org/packages/14/88/1d21a36da8f5cb0fa49eafd4b169eba5608d57e75bbcf61845cbc6243216/httptools-0.8.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:880490234c10f70a9830743097e8958d6e4b9f5a0ffc24515023afeef984054d", size = 208247, upload-time = "2026-05-25T22:17:07.843Z" }, - { url = "https://files.pythonhosted.org/packages/a5/42/cc4feea2945cb3051038f090c9b36bd5b8a9d7f5a894a506a8983e33fd1c/httptools-0.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5931891fb7b441b8a3853cf1b85c82c903defce084dd5f6771ca46e31bf862c5", size = 113064, upload-time = "2026-05-25T22:17:09.136Z" }, - { url = "https://files.pythonhosted.org/packages/e3/a6/febbb8b8db0f58b38e44ad6cb946e6a255ae49b55f2e8543408fb7501ccd/httptools-0.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b15fc622b0f869d19207c4089a501d9bcc63ca5e071ffdd2f03f922df882dcb2", size = 523851, upload-time = "2026-05-25T22:17:10.106Z" }, - { url = "https://files.pythonhosted.org/packages/b7/e4/f90a0df0b83beff265b7e3b65f2a4cefd95792d4be0ac3e16049f2acd3c2/httptools-0.8.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:425f83884fd6343828d8c565f046cb72b6d19063f6924093e11bcd8e1548cd09", size = 518842, upload-time = "2026-05-25T22:17:11.218Z" }, - { url = "https://files.pythonhosted.org/packages/9e/2d/0c9ac76dd2c893841fbf6498d6acec4f2442e1b7067f6e3e316a80e494e8/httptools-0.8.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ef7c3c97f4311c7be57e2986629df89d49cb434dbff78eafcd48c2bff986b15a", size = 501238, upload-time = "2026-05-25T22:17:12.728Z" }, - { url = "https://files.pythonhosted.org/packages/ca/42/906adc91ae3a5fa9c59c0a2f21c139725bd7e5b41ae6acd485cd14123ebf/httptools-0.8.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a1afd7c9fbff0d9f5d489c4ce2768bd09c84a46ddefc7161e6aa82ae35c85745", size = 509567, upload-time = "2026-05-25T22:17:13.842Z" }, - { url = "https://files.pythonhosted.org/packages/05/0b/4240efeb672751ee5b9b380cb0e3fdc050bc05f68adc7a8aefc4fcd9a69a/httptools-0.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:cd96f29b4bab1d42fa6e3d008711c75e0f79e94e06827330160e3a304227f150", size = 90918, upload-time = "2026-05-25T22:17:15.155Z" }, - { url = "https://files.pythonhosted.org/packages/5e/e5/8cfcabc5546e8022f168be28bcdaa128a240a0befdd03b59d558b4f18bd6/httptools-0.8.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:614ceea8ea606848bece2338ac03b3ce5324bcb4be8dc7d377ed708012fa4db8", size = 205148, upload-time = "2026-05-25T22:17:16.333Z" }, - { url = "https://files.pythonhosted.org/packages/2a/0e/0fb14848c19a686c8062ff9067c1a48793e3224b47bc5b201535b6036fce/httptools-0.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2d689918c15a013c65ef52d9fd495d766893ab831a2c8d89f2ac5940a5df847c", size = 111368, upload-time = "2026-05-25T22:17:17.586Z" }, - { url = "https://files.pythonhosted.org/packages/2e/1b/46f1cecf06b9bbde8e4b8c88034ac7908989e5ff7a3a388ef38392949c1f/httptools-0.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:eb3028cca2fc0a6d720e52ef61d8ebb62fcbfeb1de56874546d858d3f25a26b7", size = 486447, upload-time = "2026-05-25T22:17:18.564Z" }, - { url = "https://files.pythonhosted.org/packages/77/00/258bfc0837221f81d9725c45f9b948a6a6b2994a147a4fb66e85100c668f/httptools-0.8.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:88bdd940f2b5d487b4d032c6afa5489a7dc4694410d43de3c38c4fb3af0dc45d", size = 482448, upload-time = "2026-05-25T22:17:19.912Z" }, - { url = "https://files.pythonhosted.org/packages/04/ab/d1cef3b5523f4d272a70f42a776c3169a2dddfe3a54de4b2ce4a36341528/httptools-0.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6a43c9dd399758ccc0531acb0a3c4a6c299ee893ee9400e9c893b7bdcfae0681", size = 464460, upload-time = "2026-05-25T22:17:20.882Z" }, - { url = "https://files.pythonhosted.org/packages/ce/48/5d1d072442277bb2b3434e0e60690b8e8c23840ef7de8b6ea54040a536d3/httptools-0.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0770728beb05094c809b98e814edff5fef69d26ad7d21185f2f6d5884a0ba683", size = 471312, upload-time = "2026-05-25T22:17:22.085Z" }, - { url = "https://files.pythonhosted.org/packages/0d/66/b96623b27e51a68199ef4efdda0613cced9233fe3062ac74e50749c5ad37/httptools-0.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:7685df791fad561384bfb139e77fde27a1ffd93134e016f95a0db424ffbf77b1", size = 90117, upload-time = "2026-05-25T22:17:23.074Z" }, - { url = "https://files.pythonhosted.org/packages/1a/12/fa3fbf5f9517b273edea2dc982aa82a8c634091e67c590792b729017bc6f/httptools-0.8.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:de242a49b5d18e0a8776e654e9f6bf6d89f3875a5c35b425a0e7ce940feb3fd6", size = 206183, upload-time = "2026-05-25T22:17:24.004Z" }, - { url = "https://files.pythonhosted.org/packages/30/fc/5e7c4cb443370f2090a3aba0453a07384d29ff66b7435bb90e77e1037599/httptools-0.8.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:159e9ab5f701ccd42e555a12f1ad8ff69702910fc1c996cf2bb66e5fcb7a231b", size = 112079, upload-time = "2026-05-25T22:17:25.216Z" }, - { url = "https://files.pythonhosted.org/packages/ba/53/771bd891eb0f236f32145d6a1775777ec85745f3cc983a1f23d1a3b8ddfe/httptools-0.8.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c4a9f1707e4823d54dfec6c33fa3697d302aed536ed352a7ebb5a061ddb869d0", size = 481596, upload-time = "2026-05-25T22:17:26.186Z" }, - { url = "https://files.pythonhosted.org/packages/62/42/94e15bc68ce3d423243c45d7f1b0c7561f13844f97dc52ae23182fb65628/httptools-0.8.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d76ad7b951387e3632c8716a9bb03ac5b45c5f16119aa409db0459520887944e", size = 480865, upload-time = "2026-05-25T22:17:27.542Z" }, - { url = "https://files.pythonhosted.org/packages/1c/7c/fe2980fc03723272e30f135b62360b075f513dfe7cc73aef36c7f04012bd/httptools-0.8.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a3b7387147361c3fd47a0bde763c5c91b5b4cd4dc9989b8ece84ff436c99843b", size = 463189, upload-time = "2026-05-25T22:17:28.546Z" }, - { url = "https://files.pythonhosted.org/packages/15/1b/47fc5fff68acd1bfa20b4734059c9a06cadb88119dcd5258b5b0d21d91c8/httptools-0.8.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f256d6ce930c52ca1cb2a960b7da03548c454e7d28b06059ad41bfe789036ce0", size = 466610, upload-time = "2026-05-25T22:17:29.816Z" }, - { url = "https://files.pythonhosted.org/packages/60/bd/07b13c93ffd9bec9546e0d43f8e19378dd696dbd278511406bc07371ef1f/httptools-0.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:19d1ee275bb59ba2643ba9a3a1e51cc0c788caf2b8df506368e03f56fdd08527", size = 92705, upload-time = "2026-05-25T22:17:31.133Z" }, - { url = "https://files.pythonhosted.org/packages/fd/c4/121648f68ce066d7bd762d6b6d97e620847642d38d54f3d90ff11d947629/httptools-0.8.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:de1ed58a974e75d56560acc7e7fed01a454994429456f65209789992e41f2568", size = 215023, upload-time = "2026-05-25T22:17:32.401Z" }, - { url = "https://files.pythonhosted.org/packages/b9/b0/312a062ae741ae3e8baa8c8bf20be81b2e67337b259ab4349bebc7b6142e/httptools-0.8.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:e93c227b595c6926c1acee96891dd9da4be338cfbe82e5cd3bb9d8dd7dc4ac0b", size = 117405, upload-time = "2026-05-25T22:17:33.742Z" }, - { url = "https://files.pythonhosted.org/packages/fc/37/fccd705f795386bb05bf413012fecff2a33e5aa8c2f069096de3e9fd8702/httptools-0.8.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2a021c3a8e65cc125390d72f59b968afca3bdcaff25bd67965e0a055a14946ca", size = 558497, upload-time = "2026-05-25T22:17:34.732Z" }, - { url = "https://files.pythonhosted.org/packages/bd/39/f172e8003576de35f5ba77ff417cf0e34429d35dc014deef15afa337a72c/httptools-0.8.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:48774d39cbb70e2b1f71f88852a3087ae1d3a1eb80482bb48c13067ab080c14f", size = 571585, upload-time = "2026-05-25T22:17:35.813Z" }, - { url = "https://files.pythonhosted.org/packages/3e/b9/f5564760af99f3dbbf3f9104dc00e5da27e96cf433c6bdcf77617f70bf3f/httptools-0.8.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:88eead8ec8680a9f146c655bc88445a325bd7921cfd8194c7337e9467282427d", size = 543297, upload-time = "2026-05-25T22:17:37.08Z" }, - { url = "https://files.pythonhosted.org/packages/99/67/8d9f2c313618e161b82f3873188e7196126da1d6e29688df40eb3997c77a/httptools-0.8.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:2c032fa028f46871ec7e1fc59fc15e8023eab3e6bbe6ece786a1611719a5d081", size = 539535, upload-time = "2026-05-25T22:17:38.032Z" }, - { url = "https://files.pythonhosted.org/packages/48/63/b906c01e53f50d432c0defe43ce52764a111dc1bdd028bafbeb54dcfd008/httptools-0.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:384c17174464c8e873398b7af24f0b1f44d992c820328413951a625323155d77", size = 108209, upload-time = "2026-05-25T22:17:39.473Z" }, -] - [[package]] name = "httpx" version = "0.28.1" @@ -1183,15 +1084,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3e/95/c7c34aa53c16353c56d0b802fba48d5f5caa2cdee7958acbcb795c830416/isort-8.0.1-py3-none-any.whl", hash = "sha256:28b89bc70f751b559aeca209e6120393d43fbe2490de0559662be7a9787e3d75", size = 89733, upload-time = "2026-02-28T10:08:19.466Z" }, ] -[[package]] -name = "itsdangerous" -version = "2.2.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9c/cb/8ac0172223afbccb63986cc25049b154ecfb5e85932587206f42317be31d/itsdangerous-2.2.0.tar.gz", hash = "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173", size = 54410, upload-time = "2024-04-16T21:28:15.614Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/04/96/92447566d16df59b2a776c0fb82dbc4d9e07cd95062562af01e408583fc4/itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef", size = 16234, upload-time = "2024-04-16T21:28:14.499Z" }, -] - [[package]] name = "jinja2" version = "3.1.6" @@ -2706,144 +2598,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c4/cb/00451c3cf31790287768bb12c6bec834f5d292eaf3022afc88e14b8afc94/paho_mqtt-2.1.0-py3-none-any.whl", hash = "sha256:6db9ba9b34ed5bc6b6e3812718c7e06e2fd7444540df2455d2c51bd58808feee", size = 67219, upload-time = "2024-04-29T19:52:48.345Z" }, ] -[[package]] -name = "pandas" -version = "2.3.3" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.11'", -] -dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" } }, - { name = "python-dateutil" }, - { name = "pytz" }, - { name = "tzdata" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/33/01/d40b85317f86cf08d853a4f495195c73815fdf205eef3993821720274518/pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b", size = 4495223, upload-time = "2025-09-29T23:34:51.853Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3d/f7/f425a00df4fcc22b292c6895c6831c0c8ae1d9fac1e024d16f98a9ce8749/pandas-2.3.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:376c6446ae31770764215a6c937f72d917f214b43560603cd60da6408f183b6c", size = 11555763, upload-time = "2025-09-29T23:16:53.287Z" }, - { url = "https://files.pythonhosted.org/packages/13/4f/66d99628ff8ce7857aca52fed8f0066ce209f96be2fede6cef9f84e8d04f/pandas-2.3.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e19d192383eab2f4ceb30b412b22ea30690c9e618f78870357ae1d682912015a", size = 10801217, upload-time = "2025-09-29T23:17:04.522Z" }, - { url = "https://files.pythonhosted.org/packages/1d/03/3fc4a529a7710f890a239cc496fc6d50ad4a0995657dccc1d64695adb9f4/pandas-2.3.3-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5caf26f64126b6c7aec964f74266f435afef1c1b13da3b0636c7518a1fa3e2b1", size = 12148791, upload-time = "2025-09-29T23:17:18.444Z" }, - { url = "https://files.pythonhosted.org/packages/40/a8/4dac1f8f8235e5d25b9955d02ff6f29396191d4e665d71122c3722ca83c5/pandas-2.3.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dd7478f1463441ae4ca7308a70e90b33470fa593429f9d4c578dd00d1fa78838", size = 12769373, upload-time = "2025-09-29T23:17:35.846Z" }, - { url = "https://files.pythonhosted.org/packages/df/91/82cc5169b6b25440a7fc0ef3a694582418d875c8e3ebf796a6d6470aa578/pandas-2.3.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4793891684806ae50d1288c9bae9330293ab4e083ccd1c5e383c34549c6e4250", size = 13200444, upload-time = "2025-09-29T23:17:49.341Z" }, - { url = "https://files.pythonhosted.org/packages/10/ae/89b3283800ab58f7af2952704078555fa60c807fff764395bb57ea0b0dbd/pandas-2.3.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:28083c648d9a99a5dd035ec125d42439c6c1c525098c58af0fc38dd1a7a1b3d4", size = 13858459, upload-time = "2025-09-29T23:18:03.722Z" }, - { url = "https://files.pythonhosted.org/packages/85/72/530900610650f54a35a19476eca5104f38555afccda1aa11a92ee14cb21d/pandas-2.3.3-cp310-cp310-win_amd64.whl", hash = "sha256:503cf027cf9940d2ceaa1a93cfb5f8c8c7e6e90720a2850378f0b3f3b1e06826", size = 11346086, upload-time = "2025-09-29T23:18:18.505Z" }, - { url = "https://files.pythonhosted.org/packages/c1/fa/7ac648108144a095b4fb6aa3de1954689f7af60a14cf25583f4960ecb878/pandas-2.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:602b8615ebcc4a0c1751e71840428ddebeb142ec02c786e8ad6b1ce3c8dec523", size = 11578790, upload-time = "2025-09-29T23:18:30.065Z" }, - { url = "https://files.pythonhosted.org/packages/9b/35/74442388c6cf008882d4d4bdfc4109be87e9b8b7ccd097ad1e7f006e2e95/pandas-2.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8fe25fc7b623b0ef6b5009149627e34d2a4657e880948ec3c840e9402e5c1b45", size = 10833831, upload-time = "2025-09-29T23:38:56.071Z" }, - { url = "https://files.pythonhosted.org/packages/fe/e4/de154cbfeee13383ad58d23017da99390b91d73f8c11856f2095e813201b/pandas-2.3.3-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b468d3dad6ff947df92dcb32ede5b7bd41a9b3cceef0a30ed925f6d01fb8fa66", size = 12199267, upload-time = "2025-09-29T23:18:41.627Z" }, - { url = "https://files.pythonhosted.org/packages/bf/c9/63f8d545568d9ab91476b1818b4741f521646cbdd151c6efebf40d6de6f7/pandas-2.3.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b98560e98cb334799c0b07ca7967ac361a47326e9b4e5a7dfb5ab2b1c9d35a1b", size = 12789281, upload-time = "2025-09-29T23:18:56.834Z" }, - { url = "https://files.pythonhosted.org/packages/f2/00/a5ac8c7a0e67fd1a6059e40aa08fa1c52cc00709077d2300e210c3ce0322/pandas-2.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37b5848ba49824e5c30bedb9c830ab9b7751fd049bc7914533e01c65f79791", size = 13240453, upload-time = "2025-09-29T23:19:09.247Z" }, - { url = "https://files.pythonhosted.org/packages/27/4d/5c23a5bc7bd209231618dd9e606ce076272c9bc4f12023a70e03a86b4067/pandas-2.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:db4301b2d1f926ae677a751eb2bd0e8c5f5319c9cb3f88b0becbbb0b07b34151", size = 13890361, upload-time = "2025-09-29T23:19:25.342Z" }, - { url = "https://files.pythonhosted.org/packages/8e/59/712db1d7040520de7a4965df15b774348980e6df45c129b8c64d0dbe74ef/pandas-2.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:f086f6fe114e19d92014a1966f43a3e62285109afe874f067f5abbdcbb10e59c", size = 11348702, upload-time = "2025-09-29T23:19:38.296Z" }, - { url = "https://files.pythonhosted.org/packages/9c/fb/231d89e8637c808b997d172b18e9d4a4bc7bf31296196c260526055d1ea0/pandas-2.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d21f6d74eb1725c2efaa71a2bfc661a0689579b58e9c0ca58a739ff0b002b53", size = 11597846, upload-time = "2025-09-29T23:19:48.856Z" }, - { url = "https://files.pythonhosted.org/packages/5c/bd/bf8064d9cfa214294356c2d6702b716d3cf3bb24be59287a6a21e24cae6b/pandas-2.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3fd2f887589c7aa868e02632612ba39acb0b8948faf5cc58f0850e165bd46f35", size = 10729618, upload-time = "2025-09-29T23:39:08.659Z" }, - { url = "https://files.pythonhosted.org/packages/57/56/cf2dbe1a3f5271370669475ead12ce77c61726ffd19a35546e31aa8edf4e/pandas-2.3.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ecaf1e12bdc03c86ad4a7ea848d66c685cb6851d807a26aa245ca3d2017a1908", size = 11737212, upload-time = "2025-09-29T23:19:59.765Z" }, - { url = "https://files.pythonhosted.org/packages/e5/63/cd7d615331b328e287d8233ba9fdf191a9c2d11b6af0c7a59cfcec23de68/pandas-2.3.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b3d11d2fda7eb164ef27ffc14b4fcab16a80e1ce67e9f57e19ec0afaf715ba89", size = 12362693, upload-time = "2025-09-29T23:20:14.098Z" }, - { url = "https://files.pythonhosted.org/packages/a6/de/8b1895b107277d52f2b42d3a6806e69cfef0d5cf1d0ba343470b9d8e0a04/pandas-2.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a68e15f780eddf2b07d242e17a04aa187a7ee12b40b930bfdd78070556550e98", size = 12771002, upload-time = "2025-09-29T23:20:26.76Z" }, - { url = "https://files.pythonhosted.org/packages/87/21/84072af3187a677c5893b170ba2c8fbe450a6ff911234916da889b698220/pandas-2.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:371a4ab48e950033bcf52b6527eccb564f52dc826c02afd9a1bc0ab731bba084", size = 13450971, upload-time = "2025-09-29T23:20:41.344Z" }, - { url = "https://files.pythonhosted.org/packages/86/41/585a168330ff063014880a80d744219dbf1dd7a1c706e75ab3425a987384/pandas-2.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:a16dcec078a01eeef8ee61bf64074b4e524a2a3f4b3be9326420cabe59c4778b", size = 10992722, upload-time = "2025-09-29T23:20:54.139Z" }, - { url = "https://files.pythonhosted.org/packages/cd/4b/18b035ee18f97c1040d94debd8f2e737000ad70ccc8f5513f4eefad75f4b/pandas-2.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:56851a737e3470de7fa88e6131f41281ed440d29a9268dcbf0002da5ac366713", size = 11544671, upload-time = "2025-09-29T23:21:05.024Z" }, - { url = "https://files.pythonhosted.org/packages/31/94/72fac03573102779920099bcac1c3b05975c2cb5f01eac609faf34bed1ca/pandas-2.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bdcd9d1167f4885211e401b3036c0c8d9e274eee67ea8d0758a256d60704cfe8", size = 10680807, upload-time = "2025-09-29T23:21:15.979Z" }, - { url = "https://files.pythonhosted.org/packages/16/87/9472cf4a487d848476865321de18cc8c920b8cab98453ab79dbbc98db63a/pandas-2.3.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e32e7cc9af0f1cc15548288a51a3b681cc2a219faa838e995f7dc53dbab1062d", size = 11709872, upload-time = "2025-09-29T23:21:27.165Z" }, - { url = "https://files.pythonhosted.org/packages/15/07/284f757f63f8a8d69ed4472bfd85122bd086e637bf4ed09de572d575a693/pandas-2.3.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:318d77e0e42a628c04dc56bcef4b40de67918f7041c2b061af1da41dcff670ac", size = 12306371, upload-time = "2025-09-29T23:21:40.532Z" }, - { url = "https://files.pythonhosted.org/packages/33/81/a3afc88fca4aa925804a27d2676d22dcd2031c2ebe08aabd0ae55b9ff282/pandas-2.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e0a175408804d566144e170d0476b15d78458795bb18f1304fb94160cabf40c", size = 12765333, upload-time = "2025-09-29T23:21:55.77Z" }, - { url = "https://files.pythonhosted.org/packages/8d/0f/b4d4ae743a83742f1153464cf1a8ecfafc3ac59722a0b5c8602310cb7158/pandas-2.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93c2d9ab0fc11822b5eece72ec9587e172f63cff87c00b062f6e37448ced4493", size = 13418120, upload-time = "2025-09-29T23:22:10.109Z" }, - { url = "https://files.pythonhosted.org/packages/4f/c7/e54682c96a895d0c808453269e0b5928a07a127a15704fedb643e9b0a4c8/pandas-2.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:f8bfc0e12dc78f777f323f55c58649591b2cd0c43534e8355c51d3fede5f4dee", size = 10993991, upload-time = "2025-09-29T23:25:04.889Z" }, - { url = "https://files.pythonhosted.org/packages/f9/ca/3f8d4f49740799189e1395812f3bf23b5e8fc7c190827d55a610da72ce55/pandas-2.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:75ea25f9529fdec2d2e93a42c523962261e567d250b0013b16210e1d40d7c2e5", size = 12048227, upload-time = "2025-09-29T23:22:24.343Z" }, - { url = "https://files.pythonhosted.org/packages/0e/5a/f43efec3e8c0cc92c4663ccad372dbdff72b60bdb56b2749f04aa1d07d7e/pandas-2.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74ecdf1d301e812db96a465a525952f4dde225fdb6d8e5a521d47e1f42041e21", size = 11411056, upload-time = "2025-09-29T23:22:37.762Z" }, - { url = "https://files.pythonhosted.org/packages/46/b1/85331edfc591208c9d1a63a06baa67b21d332e63b7a591a5ba42a10bb507/pandas-2.3.3-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6435cb949cb34ec11cc9860246ccb2fdc9ecd742c12d3304989017d53f039a78", size = 11645189, upload-time = "2025-09-29T23:22:51.688Z" }, - { url = "https://files.pythonhosted.org/packages/44/23/78d645adc35d94d1ac4f2a3c4112ab6f5b8999f4898b8cdf01252f8df4a9/pandas-2.3.3-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:900f47d8f20860de523a1ac881c4c36d65efcb2eb850e6948140fa781736e110", size = 12121912, upload-time = "2025-09-29T23:23:05.042Z" }, - { url = "https://files.pythonhosted.org/packages/53/da/d10013df5e6aaef6b425aa0c32e1fc1f3e431e4bcabd420517dceadce354/pandas-2.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a45c765238e2ed7d7c608fc5bc4a6f88b642f2f01e70c0c23d2224dd21829d86", size = 12712160, upload-time = "2025-09-29T23:23:28.57Z" }, - { url = "https://files.pythonhosted.org/packages/bd/17/e756653095a083d8a37cbd816cb87148debcfcd920129b25f99dd8d04271/pandas-2.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c4fc4c21971a1a9f4bdb4c73978c7f7256caa3e62b323f70d6cb80db583350bc", size = 13199233, upload-time = "2025-09-29T23:24:24.876Z" }, - { url = "https://files.pythonhosted.org/packages/04/fd/74903979833db8390b73b3a8a7d30d146d710bd32703724dd9083950386f/pandas-2.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ee15f284898e7b246df8087fc82b87b01686f98ee67d85a17b7ab44143a3a9a0", size = 11540635, upload-time = "2025-09-29T23:25:52.486Z" }, - { url = "https://files.pythonhosted.org/packages/21/00/266d6b357ad5e6d3ad55093a7e8efc7dd245f5a842b584db9f30b0f0a287/pandas-2.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1611aedd912e1ff81ff41c745822980c49ce4a7907537be8692c8dbc31924593", size = 10759079, upload-time = "2025-09-29T23:26:33.204Z" }, - { url = "https://files.pythonhosted.org/packages/ca/05/d01ef80a7a3a12b2f8bbf16daba1e17c98a2f039cbc8e2f77a2c5a63d382/pandas-2.3.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d2cefc361461662ac48810cb14365a365ce864afe85ef1f447ff5a1e99ea81c", size = 11814049, upload-time = "2025-09-29T23:27:15.384Z" }, - { url = "https://files.pythonhosted.org/packages/15/b2/0e62f78c0c5ba7e3d2c5945a82456f4fac76c480940f805e0b97fcbc2f65/pandas-2.3.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ee67acbbf05014ea6c763beb097e03cd629961c8a632075eeb34247120abcb4b", size = 12332638, upload-time = "2025-09-29T23:27:51.625Z" }, - { url = "https://files.pythonhosted.org/packages/c5/33/dd70400631b62b9b29c3c93d2feee1d0964dc2bae2e5ad7a6c73a7f25325/pandas-2.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c46467899aaa4da076d5abc11084634e2d197e9460643dd455ac3db5856b24d6", size = 12886834, upload-time = "2025-09-29T23:28:21.289Z" }, - { url = "https://files.pythonhosted.org/packages/d3/18/b5d48f55821228d0d2692b34fd5034bb185e854bdb592e9c640f6290e012/pandas-2.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6253c72c6a1d990a410bc7de641d34053364ef8bcd3126f7e7450125887dffe3", size = 13409925, upload-time = "2025-09-29T23:28:58.261Z" }, - { url = "https://files.pythonhosted.org/packages/a6/3d/124ac75fcd0ecc09b8fdccb0246ef65e35b012030defb0e0eba2cbbbe948/pandas-2.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:1b07204a219b3b7350abaae088f451860223a52cfb8a6c53358e7948735158e5", size = 11109071, upload-time = "2025-09-29T23:32:27.484Z" }, - { url = "https://files.pythonhosted.org/packages/89/9c/0e21c895c38a157e0faa1fb64587a9226d6dd46452cac4532d80c3c4a244/pandas-2.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2462b1a365b6109d275250baaae7b760fd25c726aaca0054649286bcfbb3e8ec", size = 12048504, upload-time = "2025-09-29T23:29:31.47Z" }, - { url = "https://files.pythonhosted.org/packages/d7/82/b69a1c95df796858777b68fbe6a81d37443a33319761d7c652ce77797475/pandas-2.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0242fe9a49aa8b4d78a4fa03acb397a58833ef6199e9aa40a95f027bb3a1b6e7", size = 11410702, upload-time = "2025-09-29T23:29:54.591Z" }, - { url = "https://files.pythonhosted.org/packages/f9/88/702bde3ba0a94b8c73a0181e05144b10f13f29ebfc2150c3a79062a8195d/pandas-2.3.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a21d830e78df0a515db2b3d2f5570610f5e6bd2e27749770e8bb7b524b89b450", size = 11634535, upload-time = "2025-09-29T23:30:21.003Z" }, - { url = "https://files.pythonhosted.org/packages/a4/1e/1bac1a839d12e6a82ec6cb40cda2edde64a2013a66963293696bbf31fbbb/pandas-2.3.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e3ebdb170b5ef78f19bfb71b0dc5dc58775032361fa188e814959b74d726dd5", size = 12121582, upload-time = "2025-09-29T23:30:43.391Z" }, - { url = "https://files.pythonhosted.org/packages/44/91/483de934193e12a3b1d6ae7c8645d083ff88dec75f46e827562f1e4b4da6/pandas-2.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d051c0e065b94b7a3cea50eb1ec32e912cd96dba41647eb24104b6c6c14c5788", size = 12699963, upload-time = "2025-09-29T23:31:10.009Z" }, - { url = "https://files.pythonhosted.org/packages/70/44/5191d2e4026f86a2a109053e194d3ba7a31a2d10a9c2348368c63ed4e85a/pandas-2.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3869faf4bd07b3b66a9f462417d0ca3a9df29a9f6abd5d0d0dbab15dac7abe87", size = 13202175, upload-time = "2025-09-29T23:31:59.173Z" }, -] - -[[package]] -name = "pandas" -version = "3.0.3" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.15' and sys_platform == 'win32'", - "python_full_version == '3.14.*' and sys_platform == 'win32'", - "python_full_version >= '3.15' and sys_platform == 'emscripten'", - "python_full_version == '3.14.*' and sys_platform == 'emscripten'", - "python_full_version >= '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.14.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32'", - "python_full_version == '3.11.*' and sys_platform == 'win32'", - "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten'", - "python_full_version == '3.11.*' and sys_platform == 'emscripten'", - "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", -] -dependencies = [ - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" } }, - { name = "python-dateutil" }, - { name = "tzdata", marker = "sys_platform == 'emscripten' or sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/f8/87/4341c6252d1c47b08768c3d25ac487362bf403f0313ddae4a2a26c9b1b4c/pandas-3.0.3.tar.gz", hash = "sha256:696a4a00a2a2a35d4e5deb3fc946641b96c944f02230e4f76137fe35d806c4fc", size = 4651414, upload-time = "2026-05-11T18:54:29.21Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/42/16/b5c76b838fd9bf6ce84d3a53346b8874ec05c5f0040d75ef2c320100cd2a/pandas-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:455f6f8139d4282188f526868dbc3c828470e88a3d9d59a891bd46a455f21b98", size = 10338495, upload-time = "2026-05-11T18:52:11.558Z" }, - { url = "https://files.pythonhosted.org/packages/5a/b0/a4ffc4ae74d2d822200dcc46898987d8eb6032d1e2b219cae39da6f5cbcc/pandas-3.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4e15135e2ee5df1063313e2425ceef8ac0f4ae775893815b0923651b806a5639", size = 9938250, upload-time = "2026-05-11T18:52:17.005Z" }, - { url = "https://files.pythonhosted.org/packages/2e/b2/3323601a52caee42c019e370090ca4544b241437240ca04f786cce82b0cf/pandas-3.0.3-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:05f1f1752b8533ea03f7f39a9c15b1a058d067bb48f4748948e7a8691e0510f2", size = 10770558, upload-time = "2026-05-11T18:52:19.865Z" }, - { url = "https://files.pythonhosted.org/packages/32/f1/bbecd2f867b97abebe0f9b53d750f862251b40337e061b36676ded3d920f/pandas-3.0.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8a1e45c80cceb3b4a21bc5939d52e8cbd8d9b7305309219d59e9754d9ce09e27", size = 11274611, upload-time = "2026-05-11T18:52:22.622Z" }, - { url = "https://files.pythonhosted.org/packages/7f/4f/eafabf2d5fae5adf143b4d18d3706c5efdc368a7c4eb1ee8a3eddabbd0f6/pandas-3.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:14da8316da4d0c5a77618425996bfb1248ca87fc2c1486e6fde4652bd18b5824", size = 11784670, upload-time = "2026-05-11T18:52:25.4Z" }, - { url = "https://files.pythonhosted.org/packages/49/44/1eb20389301b57b19cc099a1c2f662501f72f08a65f912d05822613c1532/pandas-3.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a55066a0505dae0ba2b50a46637db34b46f9094c65c5d4800794ef6335010938", size = 12353708, upload-time = "2026-05-11T18:52:28.139Z" }, - { url = "https://files.pythonhosted.org/packages/eb/62/c321f13b5ba1819fc8dca456c7fce578da2dcfecff1abbf0eaddf8406c0f/pandas-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:6674ab18ad8c57802867264b00e15e7bb904700cdd9046e3b2fa1fce237439ea", size = 9907609, upload-time = "2026-05-11T18:52:30.982Z" }, - { url = "https://files.pythonhosted.org/packages/53/85/1b7f563ebc6357c27233a02a96b589bcce1fa9c6eb89fb4f0e56421d277e/pandas-3.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:5cc09a68b3120e0f54870dede8287a7bb1fa463907e4fcec1ea77cab6179bf7a", size = 9165596, upload-time = "2026-05-11T18:52:33.334Z" }, - { url = "https://files.pythonhosted.org/packages/24/f1/392f8c5bfc16f66a0d2d41561c01627c228fe7ed2a0d056ef11315042570/pandas-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fed2ff7fd9779120e388e285fc029bd5cf9490cdd2e4166a9ee22c0e49a9ab09", size = 10357846, upload-time = "2026-05-11T18:52:36.143Z" }, - { url = "https://files.pythonhosted.org/packages/cf/3d/b16412745651e855f357e5e66930248688378853a6e2698a214e331fba1f/pandas-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b168fc218fd80a6cbdbdbc1a97ddc7889ed057d7eb45f50d866ceab5f39904c4", size = 9899550, upload-time = "2026-05-11T18:52:38.976Z" }, - { url = "https://files.pythonhosted.org/packages/31/a8/fa2535168fffcedf67f4f6de28d2dd903a747ca7c8ea6989451aaeb3a92f/pandas-3.0.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0383c72c75cdcca61a9e116e611143902dbfd08bff356829c2f6d1cf40a9ca8c", size = 10412965, upload-time = "2026-05-11T18:52:41.915Z" }, - { url = "https://files.pythonhosted.org/packages/65/b6/09b01cdbc15224e2850365192d17b7bdebb8bdbd8780ed221fcdf0d9a515/pandas-3.0.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6dc0b3fd2169c9157deed50b4d519553a3655c8c6a96027136d654592be973a9", size = 10894600, upload-time = "2026-05-11T18:52:45.02Z" }, - { url = "https://files.pythonhosted.org/packages/c9/a4/2eb28f2fccb4ced4a2c79ab2a5dee9ade1ebf44922ebad6fea158c9f95d4/pandas-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7e65d5407dc0b394f509699650e4a2ec01c0514f21850f453fa60f3be79a5dbf", size = 11422824, upload-time = "2026-05-11T18:52:48.058Z" }, - { url = "https://files.pythonhosted.org/packages/f8/45/830bb57f533a4604b355e07edcb8ea18cf88b5f94e5fca92f27052d7c597/pandas-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f8894dc474d648fe7b6ff0ca9b0bd73950d19952bc1a6534540762c5d79d305c", size = 11950889, upload-time = "2026-05-11T18:52:50.905Z" }, - { url = "https://files.pythonhosted.org/packages/b9/c5/fc1b368f303087d20e8c9bf3d6ceb186263cfac0ade735cd938538bea839/pandas-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:c7be265b62cef88e253a941e4698604973736dcfe242fdb5198f0f7bc473cdcc", size = 9755463, upload-time = "2026-05-11T18:52:53.386Z" }, - { url = "https://files.pythonhosted.org/packages/86/bd/fda8f9705b1b09c6ebe14bfc0fa0e4ec8584d54ea673628f157ff55131af/pandas-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:557409bc4178e70ee8d9ddb494798e51ebf6ea59330f6be22c51bab2a7db6c49", size = 9066158, upload-time = "2026-05-11T18:52:56.038Z" }, - { url = "https://files.pythonhosted.org/packages/c5/90/62d8302883c44308c477e222c3daf7c813a34c8e96985882fbd53d964352/pandas-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:67b3b64c11910cfa29f4e94a14d3bff9ee693b6fc76055e7cad549cee0aec5fa", size = 10331071, upload-time = "2026-05-11T18:52:58.838Z" }, - { url = "https://files.pythonhosted.org/packages/7f/ae/6a6493c783a101f165e4356953ba3c74d6f77f0042fa7d753da9dfbb640c/pandas-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:39436b377d56d2a2e52d0395bdbee171f01068e99af5250509aceeb929f765c7", size = 9875690, upload-time = "2026-05-11T18:53:01.431Z" }, - { url = "https://files.pythonhosted.org/packages/62/7c/5df8e9f56c69a2769fbe9382a5ef8f2658c007e376434e1e2cbb57ad895f/pandas-3.0.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d4be06d68f9ddcfc645b87534911da79a8fbffc7573c80e0edcf42a5020624d8", size = 10381634, upload-time = "2026-05-11T18:53:04.393Z" }, - { url = "https://files.pythonhosted.org/packages/99/68/1237369725aa617bb358263d535803e3053fdbc593513ec5ed9c9896b5b6/pandas-3.0.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a4eeb6830daf35a71cc09649bd823e2b542dac246cdee9614c6e4bd65028cd6a", size = 10891243, upload-time = "2026-05-11T18:53:07.643Z" }, - { url = "https://files.pythonhosted.org/packages/25/93/77d108e8af7222b4a503ebde0e30215b1c2e4f8e53a526431890f22d5586/pandas-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1928e07221f82db493cd4af1e23c1bfca524a19a4699887975bff68f49a72bfb", size = 11388659, upload-time = "2026-05-11T18:53:10.634Z" }, - { url = "https://files.pythonhosted.org/packages/d0/bd/eff5b4399f332ac386c853f6cd2bd3fa2ca0061b9f36ecd9c4d7c4265649/pandas-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51b1fe551acb77dac643c6fda86084d8d446c10fe64b06a9cc29c4cc8540e7f2", size = 11942880, upload-time = "2026-05-11T18:53:13.536Z" }, - { url = "https://files.pythonhosted.org/packages/2c/20/559ace4200982c3887d0b86bfd0d856a2143ef8ddab63cc07934951a964c/pandas-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:a82d532a3351d435432cd913edbccaf8b8e01d4dd0e5ced5a8d2e8ecd94c7e44", size = 9757091, upload-time = "2026-05-11T18:53:16.306Z" }, - { url = "https://files.pythonhosted.org/packages/3a/66/69055a09fe200f29f922a3eeec4804611900b95f52d932ece3393c3c0c19/pandas-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:275c14e0fce14a2ec20eee474aecd305478ea3c1e6f6a9d8fe219a165542717e", size = 9057282, upload-time = "2026-05-11T18:53:18.768Z" }, - { url = "https://files.pythonhosted.org/packages/57/0e/efe801b0e6811e8e650cd21b7f2608e30f08a7067e2bf6e8752b0d56ee3c/pandas-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:46997386d528eb40376ecd6b033cf4a8a1e5282580f68f43de875b78cba2199d", size = 10767016, upload-time = "2026-05-11T18:53:21.227Z" }, - { url = "https://files.pythonhosted.org/packages/ea/dc/eb55135a1d5f0f0519f28da1f609a206d2cad1f9c35c32d51e38dd7261ae/pandas-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:261e308dfb22448384b7580cf719d2f998fe2966c92893c3e77d14008af1f066", size = 10420210, upload-time = "2026-05-11T18:53:23.982Z" }, - { url = "https://files.pythonhosted.org/packages/c6/3e/b1d5d955ce33ffecb407465a60bc32769d74fcf68224b7ae67ae11d4dea4/pandas-3.0.3-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dd1a5d1def6a46002e964510bdc67c368aa0951df5d1d9f8365336f5a1f490cd", size = 10336126, upload-time = "2026-05-11T18:53:26.731Z" }, - { url = "https://files.pythonhosted.org/packages/f5/76/a01261711ab60a22d71b862f0de20e4c504bf80457270ad8cb42110f6abc/pandas-3.0.3-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d72828c20c6d6e83e1e22a6a3b47b326b71664112fa9705dcbccfd7a39b62085", size = 10728051, upload-time = "2026-05-11T18:53:29.125Z" }, - { url = "https://files.pythonhosted.org/packages/e9/21/ea191195e587b18cf682e97f433f81b2d0fbe341380e80a3e0d6e4403c8e/pandas-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:d26cbe1fcfc12e8fd900e2454163e466b2d3af84f7c75481df7683ffc073d870", size = 11350796, upload-time = "2026-05-11T18:53:32.056Z" }, - { url = "https://files.pythonhosted.org/packages/64/69/f0eaaf54939f0e8c6768fd06be9af2cef9b36048b96dfb9e1b2c685a807e/pandas-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:3e91cec1879ada0624fc3dc9953c5cbd60208e59c0db28f540c5d6d47502422f", size = 11799741, upload-time = "2026-05-11T18:53:34.985Z" }, - { url = "https://files.pythonhosted.org/packages/45/a4/865e0e510cae5fc2194de4db28be638952de942571ba9125934fd9c01d47/pandas-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:08d789b41f87e0905880e293cedf6197ce71fe67cc081358b1e148a491b9bd13", size = 10499958, upload-time = "2026-05-11T18:53:37.857Z" }, - { url = "https://files.pythonhosted.org/packages/86/54/effdcc3c0ff7a08037889200e148ebe94c16c4f653be078c7b3675955df1/pandas-3.0.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:3650109c0f22879df8bd6179ab9ee3d7f1d1d4e7e0094a3f0032d9f51e2e64ac", size = 10336065, upload-time = "2026-05-11T18:53:41.099Z" }, - { url = "https://files.pythonhosted.org/packages/68/10/bf2d6738d72748b961a3751ab89522d58c54efc36a8e1a12161216cd45cf/pandas-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:bab900348131a7db1f69a7309ef141fd5680f1487094193bcbbb61791573bf8f", size = 9926101, upload-time = "2026-05-11T18:53:43.515Z" }, - { url = "https://files.pythonhosted.org/packages/ae/e9/e35cf11c8a136e757b956f5f0efdcaa50aecde85ea055f1898dfc68262f3/pandas-3.0.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba7e08b9ac1d54569cd1e256e3668975ed624d6826f7b68df0342b012007bddb", size = 10457553, upload-time = "2026-05-11T18:53:46.394Z" }, - { url = "https://files.pythonhosted.org/packages/58/3b/1cdec6772bdbaf7b25dab360c59f03cadf05492dd724c6540af905389b07/pandas-3.0.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d71c63ae4ebdbf70209742096f1fc46a83a0613c99d4b23766cced9ff8cd62a", size = 10914065, upload-time = "2026-05-11T18:53:49.134Z" }, - { url = "https://files.pythonhosted.org/packages/c4/c2/1ef644445fcd72e3627bceec77e3560636f87ddce4ed841afe76b83b5bf9/pandas-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e3a2ec42c98ffa2565a67e08e218d06d72576d758d90facb7c00805194d8f360", size = 11459188, upload-time = "2026-05-11T18:53:52.527Z" }, - { url = "https://files.pythonhosted.org/packages/7e/49/4d8d4f42cbc9c4adc7a1870f269c02cbd6cd40d059622c06fb298addcbad/pandas-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:335f62418ed562cfc3c49e9e196375c28b729dcef8543abf4f9438e381bf3c76", size = 11982966, upload-time = "2026-05-11T18:53:55.043Z" }, - { url = "https://files.pythonhosted.org/packages/38/55/792619469bab9882d8bbd5865d45a72f6478762d04a9af4bf0d08c503e95/pandas-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:3c20a521bbb85902f79f7270c80a59e1b5452d96d170c034f207181870f97ac5", size = 9876755, upload-time = "2026-05-11T18:53:58.067Z" }, - { url = "https://files.pythonhosted.org/packages/2a/af/33c469653b0ba03b50c3a98192d4c07f0c75c66b263ceb097fce0ee97d31/pandas-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:a2d2dff8a04f3917b55ab3910c32990f8ddf7eceba114947838cefa976a68977", size = 9198658, upload-time = "2026-05-11T18:54:00.733Z" }, - { url = "https://files.pythonhosted.org/packages/a2/fa/b8c257bd76b8bd060c3a9151c1fca05e9b9c5e3af5d0f549c0356f6d143d/pandas-3.0.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:0d589105b3c14645af1738ff279b2995102d8f7a03b0a66dc8d95550eb513e04", size = 10787242, upload-time = "2026-05-11T18:54:03.564Z" }, - { url = "https://files.pythonhosted.org/packages/54/eb/f19206ffb0bf1919002969aa448b4702c6594845156a6f8050674855aac3/pandas-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:13fc1e853d9e04743d11ba75a985ccbc2a317fe07d8af61e445a6fd24dacd6a6", size = 10436369, upload-time = "2026-05-11T18:54:06.311Z" }, - { url = "https://files.pythonhosted.org/packages/fd/24/c7c39fb4fe22b71a0c2d78bf0c585c600092d85f94f086d2b3b2f6ca27e2/pandas-3.0.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:819959dab7bbd0049c15623fbac4e29a191b9528160a61fb1032242d8ced2d9c", size = 10358306, upload-time = "2026-05-11T18:54:09.085Z" }, - { url = "https://files.pythonhosted.org/packages/16/ec/dd2a9eb7fa1204df88c0864164e35b228ac581062ac612ba0a67fd812e4c/pandas-3.0.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:60ae316d3fd75d1858d450d0db0103ea2be3e7d4a95ec2f064f7e2ae63f7b028", size = 10758394, upload-time = "2026-05-11T18:54:11.956Z" }, - { url = "https://files.pythonhosted.org/packages/95/6e/00c61ea8e85b4f6d8d35e11852a1a4998fc7fafc91c6a602d1cc9c972d64/pandas-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bd3a518890b400d32f9023722dc9a9a5c969f00b415419a3c06c043f09bb5d7d", size = 11375717, upload-time = "2026-05-11T18:54:14.539Z" }, - { url = "https://files.pythonhosted.org/packages/31/89/8fc1c268969fac43688d65fd92e67df24bd128d53cb4d2eee534cd307399/pandas-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9c39be2d709d01fa972a0cabc522389fceca4f3969332ba25a7d6c5802cf976a", size = 11828897, upload-time = "2026-05-11T18:54:17.146Z" }, - { url = "https://files.pythonhosted.org/packages/56/3b/e7d20dea247a3e6dc0bd8a6953854afbedc03951def4e7371e05e7263e25/pandas-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4db8c527972a821cf5286b40ccc57642a39bc62e62022b42f99f8a67fca8c3a1", size = 10900855, upload-time = "2026-05-11T18:54:19.72Z" }, - { url = "https://files.pythonhosted.org/packages/0f/54/68a0978d1ef8502b8492099beaa6e7a0c1b32e3b5d4f677f5810cb08711c/pandas-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b2c95f8bfc1ee412bf482605d7bfd30c12d1d26bd59fdd91efeef1d4718decb1", size = 9466464, upload-time = "2026-05-11T18:54:22.754Z" }, -] - [[package]] name = "pathspec" version = "1.1.1" @@ -3179,63 +2933,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8c/c7/7bb2e321574b10df20cbde462a94e2b71d05f9bbda251ef27d104668306a/psutil-7.2.2-cp37-abi3-win_arm64.whl", hash = "sha256:8c233660f575a5a89e6d4cb65d9f938126312bca76d8fe087b947b3a1aaac9ee", size = 134617, upload-time = "2026-01-28T18:15:36.514Z" }, ] -[[package]] -name = "pyarrow" -version = "24.0.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/91/13/13e1069b351bdc3881266e11147ffccf687505dbb0ea74036237f5d454a5/pyarrow-24.0.0.tar.gz", hash = "sha256:85fe721a14dd823aca09127acbb06c3ca723efbd436c004f16bca601b04dcc83", size = 1180261, upload-time = "2026-04-21T10:51:25.837Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a5/bf/a34fee1d624152124fa8355c42f34195ad5fe5233ce5bb87946432047d52/pyarrow-24.0.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:7c2b98645d576a0b9616892ead22b64a83a5f043c5e2ca15ebcefcb5b70c80cb", size = 35076681, upload-time = "2026-04-21T08:51:46.845Z" }, - { url = "https://files.pythonhosted.org/packages/1d/41/64180033d7027afce12dc96d0fe1f504c6fa112190582b458acea2399530/pyarrow-24.0.0-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:644a246325b8c69c595ad1dd4b463eba4b0cdb731370e4a86137d433208d6147", size = 36684260, upload-time = "2026-04-21T08:51:53.642Z" }, - { url = "https://files.pythonhosted.org/packages/57/02/9b9320e673dd8a99411fac78690f3df92f6dd6f59754c750110bca66d64e/pyarrow-24.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:3a577bd840ca83f646f0a625dbc571dba7044c43c2d1503afc378b570954345c", size = 45698566, upload-time = "2026-04-21T10:46:02.133Z" }, - { url = "https://files.pythonhosted.org/packages/67/33/f75e91b9a64c3f33c787e263c93b871ad91b8a4a68c1d5cebddd9840e835/pyarrow-24.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:e3268e43984d0b1a185c89b4cfff282a7ead12fc93f56cfd7088bdbcbe727041", size = 48835562, upload-time = "2026-04-21T10:46:10.278Z" }, - { url = "https://files.pythonhosted.org/packages/a5/63/097510448e47e4091faa41c43ba92f97cecaab8f4535b56a3d149578f634/pyarrow-24.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:2392d954fcb920f42d230284b677605e4e2fbb11f2821e823e642abd67fbb491", size = 49394997, upload-time = "2026-04-21T10:46:18.08Z" }, - { url = "https://files.pythonhosted.org/packages/60/6b/c047d6222ab279024a062742d1807e2fbaf27bba88a98637299ff47b9236/pyarrow-24.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:bec9373df11544592b0ba7ec2af0e35059e5f0e7647c6183a854dedd193298f1", size = 51911424, upload-time = "2026-04-21T10:46:25.347Z" }, - { url = "https://files.pythonhosted.org/packages/3a/ba/464cc70761c2a525d97ebd84e21c31ebd47f3ef4bdcee117009f51c46f24/pyarrow-24.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:c42ab9439498270139cc63e18847a02afe5c8b3ed9c931266533cfe378bd3591", size = 27251730, upload-time = "2026-04-21T10:46:30.913Z" }, - { url = "https://files.pythonhosted.org/packages/62/c9/a47ab7ece0d86cbe6678418a0fbd1ac4bb493b9184a3891dfa0e7f287ae0/pyarrow-24.0.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:b0e131f880cda8d04e076cee175a46fc0e8bc8b65c99c6c09dff6669335fde74", size = 35068898, upload-time = "2026-04-21T10:46:36.599Z" }, - { url = "https://files.pythonhosted.org/packages/d1/bc/8db86617a9a58008acf8913d6fed68ea2a46acb6de928db28d724c891a68/pyarrow-24.0.0-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:1b2fe7f9a5566401a0ef2571f197eb92358925c1f0c8dba305d6e43ea0871bb3", size = 36679915, upload-time = "2026-04-21T10:46:42.602Z" }, - { url = "https://files.pythonhosted.org/packages/eb/8e/fb178720400ef69db251eb4a9c3ccf4af269bc1feb5055529b8fc87170d1/pyarrow-24.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:0b3537c00fb8d384f15ac1e79b6eb6db04a16514c8c1d22e59a9b95c8ba42868", size = 45697931, upload-time = "2026-04-21T10:46:48.403Z" }, - { url = "https://files.pythonhosted.org/packages/f3/27/99c42abe8e21b44f4917f62631f3aa31404882a2c41d8a4cd5c110e13d52/pyarrow-24.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:14e31a3c9e35f1ab6356c6378f6f72830e6d2d5f1791df3774a7b097d18a6a1e", size = 48837449, upload-time = "2026-04-21T10:46:55.329Z" }, - { url = "https://files.pythonhosted.org/packages/36/b6/333749e2666e9032891125bf9c691146e92901bece62030ac1430e2e7c88/pyarrow-24.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b7d9a514e73bc42711e6a35aaccf3587c520024fe0a25d830a1a8a27c15f4f57", size = 49395949, upload-time = "2026-04-21T10:47:01.869Z" }, - { url = "https://files.pythonhosted.org/packages/17/25/c5201706a2dd374e8ba6ee3fd7a8c89fb7ffc16eed5217a91fd2bd7f7626/pyarrow-24.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b196eb3f931862af3fa84c2a253514d859c08e0d8fe020e07be12e75a5a9780c", size = 51912986, upload-time = "2026-04-21T10:47:09.872Z" }, - { url = "https://files.pythonhosted.org/packages/f8/d2/4d1bbba65320b21a49678d6fbdc6ff7c649251359fdcfc03568c4136231d/pyarrow-24.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:35405aecb474e683fb36af650618fd5340ee5471fc65a21b36076a18bbc6c981", size = 27255371, upload-time = "2026-04-21T10:47:15.943Z" }, - { url = "https://files.pythonhosted.org/packages/b4/a9/9686d9f07837f91f775e8932659192e02c74f9d8920524b480b85212cc68/pyarrow-24.0.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:6233c9ed9ab9d1db47de57d9753256d9dcffbf42db341576099f0fd9f6bf4810", size = 34981559, upload-time = "2026-04-21T10:47:22.17Z" }, - { url = "https://files.pythonhosted.org/packages/80/b6/0ddf0e9b6ead3474ab087ae598c76b031fc45532bf6a63f3a553440fb258/pyarrow-24.0.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:f7616236ec1bc2b15bfdec22a71ab38851c86f8f05ff64f379e1278cf20c634a", size = 36663654, upload-time = "2026-04-21T10:47:28.315Z" }, - { url = "https://files.pythonhosted.org/packages/7c/3b/926382efe8ce27ba729071d3566ade6dfb86bdf112f366000196b2f5780a/pyarrow-24.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:1617043b99bd33e5318ae18eb2919af09c71322ef1ca46566cdafc6e6712fb66", size = 45679394, upload-time = "2026-04-21T10:47:34.821Z" }, - { url = "https://files.pythonhosted.org/packages/b3/7a/829f7d9dfd37c207206081d6dad474d81dde29952401f07f2ba507814818/pyarrow-24.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:6165461f55ef6314f026de6638d661188e3455d3ec49834556a0ebbdbace18bb", size = 48863122, upload-time = "2026-04-21T10:47:42.056Z" }, - { url = "https://files.pythonhosted.org/packages/5f/e8/f88ce625fe8babaae64e8db2d417c7653adb3019b08aae85c5ed787dc816/pyarrow-24.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3b13dedfe76a0ad2d1d859b0811b53827a4e9d93a0bcb05cf59333ab4980cc7e", size = 49376032, upload-time = "2026-04-21T10:47:48.967Z" }, - { url = "https://files.pythonhosted.org/packages/36/7a/82c363caa145fff88fb475da50d3bf52bb024f61917be5424c3392eaf878/pyarrow-24.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:25ea65d868eb04015cd18e6df2fbe98f07e5bda2abefabcb88fce39a947716f6", size = 51929490, upload-time = "2026-04-21T10:47:55.981Z" }, - { url = "https://files.pythonhosted.org/packages/66/1c/e3e72c8014ad2743ca64a701652c733cc5cbcee15c0463a32a8c55518d9e/pyarrow-24.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:295f0a7f2e242dabd513737cf076007dc5b2d59237e3eca37b05c0c6446f3826", size = 27355660, upload-time = "2026-04-21T10:48:01.718Z" }, - { url = "https://files.pythonhosted.org/packages/6f/d3/a1abf004482026ddc17f4503db227787fa3cfe41ec5091ff20e4fea55e57/pyarrow-24.0.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:02b001b3ed4723caa44f6cd1af2d5c86aa2cf9971dacc2ffa55b21237713dfba", size = 34976759, upload-time = "2026-04-21T10:48:07.258Z" }, - { url = "https://files.pythonhosted.org/packages/4f/4a/34f0a36d28a2dd32225301b79daad44e243dc1a2bb77d43b60749be255c4/pyarrow-24.0.0-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:04920d6a71aabd08a0417709efce97d45ea8e6fb733d9ca9ecffb13c67839f68", size = 36658471, upload-time = "2026-04-21T10:48:13.347Z" }, - { url = "https://files.pythonhosted.org/packages/1f/78/543b94712ae8bb1a6023bcc1acf1a740fbff8286747c289cd9468fced2a5/pyarrow-24.0.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:a964266397740257f16f7bb2e4f08a0c81454004beab8ff59dd531b73610e9f2", size = 45675981, upload-time = "2026-04-21T10:48:20.201Z" }, - { url = "https://files.pythonhosted.org/packages/84/9f/8fb7c222b100d314137fa40ec050de56cd8c6d957d1cfff685ce72f15b17/pyarrow-24.0.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:6f066b179d68c413374294bc1735f68475457c933258df594443bb9d88ddc2a0", size = 48859172, upload-time = "2026-04-21T10:48:27.541Z" }, - { url = "https://files.pythonhosted.org/packages/a7/d3/1ea72538e6c8b3b475ed78d1049a2c518e655761ea50fe1171fc855fcab7/pyarrow-24.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1183baeb14c5f587b1ec52831e665718ce632caab84b7cd6b85fd44f96114495", size = 49385733, upload-time = "2026-04-21T10:48:34.7Z" }, - { url = "https://files.pythonhosted.org/packages/c3/be/c3d8b06a1ba35f2260f8e1f771abbee7d5e345c0937aab90675706b1690a/pyarrow-24.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:806f24b4085453c197a5078218d1ee08783ebbba271badd153d1ae22a3ee804f", size = 51934335, upload-time = "2026-04-21T10:48:42.099Z" }, - { url = "https://files.pythonhosted.org/packages/9c/62/89e07a1e7329d2cde3e3c6994ba0839a24977a2beda8be6005ea3d860b99/pyarrow-24.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:e4505fc6583f7b05ab854934896bcac8253b04ac1171a77dfb73efef92076d91", size = 27271748, upload-time = "2026-04-21T10:49:42.532Z" }, - { url = "https://files.pythonhosted.org/packages/17/1a/cff3a59f80b5b1658549d46611b67163f65e0664431c076ad728bf9d5af4/pyarrow-24.0.0-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:1a4e45017efbf115032e4475ee876d525e0e36c742214fbe405332480ecd6275", size = 35238554, upload-time = "2026-04-21T10:48:48.526Z" }, - { url = "https://files.pythonhosted.org/packages/a8/99/cce0f42a327bfef2c420fb6078a3eb834826e5d6697bf3009fe11d2ad051/pyarrow-24.0.0-cp313-cp313t-macosx_12_0_x86_64.whl", hash = "sha256:7986f1fa71cee060ad00758bcc79d3a93bab8559bf978fab9e53472a2e25a17b", size = 36782301, upload-time = "2026-04-21T10:48:55.181Z" }, - { url = "https://files.pythonhosted.org/packages/2a/66/8e560d5ff6793ca29aca213c53eec0dd482dd46cb93b2819e5aab52e4252/pyarrow-24.0.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:d3e0b61e8efb24ed38898e5cdc5fffa9124be480008d401a1f8071500494ae42", size = 45721929, upload-time = "2026-04-21T10:49:03.676Z" }, - { url = "https://files.pythonhosted.org/packages/27/0c/a26e25505d030716e078d9f16eb74973cbf0b33b672884e9f9da1c83b871/pyarrow-24.0.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:55a3bc1e3df3b5567b7d27ef551b2283f0c68a5e86f1cd56abc569da4f31335b", size = 48825365, upload-time = "2026-04-21T10:49:11.714Z" }, - { url = "https://files.pythonhosted.org/packages/5f/eb/771f9ecb0c65e73fe9dccdd1717901b9594f08c4515d000c7c62df573811/pyarrow-24.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:641f795b361874ac9da5294f8f443dfdbee355cf2bd9e3b8d97aaac2306b9b37", size = 49451819, upload-time = "2026-04-21T10:49:21.474Z" }, - { url = "https://files.pythonhosted.org/packages/48/da/61ae89a88732f5a785646f3ec6125dbb640fa98a540eb2b9889caa561403/pyarrow-24.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8adc8e6ce5fccf5dc707046ae4914fd537def529709cc0d285d37a7f9cd442ca", size = 51909252, upload-time = "2026-04-21T10:49:31.164Z" }, - { url = "https://files.pythonhosted.org/packages/cb/1a/8dd5cafab7b66573fa91c03d06d213356ad4edd71813aa75e08ce2b3a844/pyarrow-24.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:9b18371ad2f44044b81a8d23bc2d8a9b6a6226dca775e8e16cfee640473d6c5d", size = 27388127, upload-time = "2026-04-21T10:49:37.334Z" }, - { url = "https://files.pythonhosted.org/packages/ad/80/d022a34ff05d2cbedd8ccf841fc1f532ecfa9eb5ed1711b56d0e0ea71fc9/pyarrow-24.0.0-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:1cc9057f0319e26333b357e17f3c2c022f1a83739b48a88b25bfd5fa2dc18838", size = 35007997, upload-time = "2026-04-21T10:49:48.796Z" }, - { url = "https://files.pythonhosted.org/packages/1a/ff/f01485fda6f4e5d441afb8dd5e7681e4db18826c1e271852f5d3957d6a80/pyarrow-24.0.0-cp314-cp314-macosx_12_0_x86_64.whl", hash = "sha256:e6f1278ee4785b6db21229374a1c9e54ec7c549de5d1efc9630b6207de7e170b", size = 36678720, upload-time = "2026-04-21T10:49:55.858Z" }, - { url = "https://files.pythonhosted.org/packages/9e/c2/2d2d5fea814237923f71b36495211f20b43a1576f9a4d6da7e751a64ec6f/pyarrow-24.0.0-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:adbbedc55506cbdabb830890444fb856bfb0060c46c6f8026c6c2f2cf86ae795", size = 45741852, upload-time = "2026-04-21T10:50:04.624Z" }, - { url = "https://files.pythonhosted.org/packages/8e/3a/28ba9c1c1ebdbb5f1b94dfebb46f207e52e6a554b7fe4132540fde29a3a0/pyarrow-24.0.0-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:ae8a1145af31d903fa9bb166824d7abe9b4681a000b0159c9fb99c11bc11ad26", size = 48889852, upload-time = "2026-04-21T10:50:12.293Z" }, - { url = "https://files.pythonhosted.org/packages/df/51/4a389acfd31dca009f8fb82d7f510bb4130f2b3a8e18cf00194d0687d8ac/pyarrow-24.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d7027eba1df3b2069e2e8d80f644fa0918b68c46432af3d088ddd390d063ecde", size = 49445207, upload-time = "2026-04-21T10:50:20.677Z" }, - { url = "https://files.pythonhosted.org/packages/19/4b/0bab2b23d2ae901b1b9a03c0efd4b2d070256f8ce3fc43f6e58c167b2081/pyarrow-24.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e56a1ffe9bf7b727432b89104cc0849c21582949dd7bdcb34f17b2001a351a76", size = 51954117, upload-time = "2026-04-21T10:50:29.14Z" }, - { url = "https://files.pythonhosted.org/packages/29/88/f4e9145da0417b3d2c12035a8492b35ff4a3dbc653e614fcfb51d9dedb38/pyarrow-24.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:38be1808cdd068605b787e6ca9119b27eb275a0234e50212c3492331680c3b1e", size = 28001155, upload-time = "2026-04-21T10:51:22.337Z" }, - { url = "https://files.pythonhosted.org/packages/79/4f/46a49a63f43526da895b1a45bbb51d5baf8e4d77159f8528fc3e5490007f/pyarrow-24.0.0-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:418e48ce50a45a6a6c73c454677203a9c75c966cb1e92ca3370959185f197a05", size = 35250387, upload-time = "2026-04-21T10:50:35.552Z" }, - { url = "https://files.pythonhosted.org/packages/a0/da/d5e0cd5ef00796922404806d5f00325cdadc3441ce2c13fe7115f2df9a64/pyarrow-24.0.0-cp314-cp314t-macosx_12_0_x86_64.whl", hash = "sha256:2f16197705a230a78270cdd4ea8a1d57e86b2fdcbc34a1f6aebc72e65c986f9a", size = 36797102, upload-time = "2026-04-21T10:50:42.417Z" }, - { url = "https://files.pythonhosted.org/packages/34/c7/5904145b0a593a05236c882933d439b5720f0a145381179063722fbfc123/pyarrow-24.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:fb24ac194bfc5e86839d7dcd52092ee31e5fe6733fe11f5e3b06ef0812b20072", size = 45745118, upload-time = "2026-04-21T10:50:49.324Z" }, - { url = "https://files.pythonhosted.org/packages/13/d3/cca42fe166d1c6e4d5b80e530b7949104d10e17508a90ae202dac205ce2a/pyarrow-24.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:9700ebd9a51f5895ce75ff4ac4b3c47a7d4b42bc618be8e713e5d56bacf5f931", size = 48844765, upload-time = "2026-04-21T10:50:55.579Z" }, - { url = "https://files.pythonhosted.org/packages/b0/49/942c3b79878ba928324d1e17c274ed84581db8c0a749b24bcf4cbdf15bd3/pyarrow-24.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d8ddd2768da81d3ee08cfea9b597f4abb4e8e1dc8ae7e204b608d23a0d3ab699", size = 49471890, upload-time = "2026-04-21T10:51:02.439Z" }, - { url = "https://files.pythonhosted.org/packages/76/97/ff71431000a75d84135a1ace5ca4ba11726a231a8007bbb320a4c54075d5/pyarrow-24.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:61a3d7eaa97a14768b542f3d284dc6400dd2470d9f080708b13cd46b6ae18136", size = 51932250, upload-time = "2026-04-21T10:51:10.576Z" }, - { url = "https://files.pythonhosted.org/packages/51/be/6f79d55816d5c22557cf27533543d5d70dfe692adfbee4b99f2760674f38/pyarrow-24.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:c91d00057f23b8d353039520dc3a6c09d8608164c692e9f59a175a42b2ae0c19", size = 28131282, upload-time = "2026-04-21T10:51:16.815Z" }, -] - [[package]] name = "pycparser" version = "3.0" @@ -3376,20 +3073,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/4b/2d/69abac8f838090bbecd5df894befb2c2619e7996a98ddb949db9f3b93225/pydantic_core-2.46.4-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:d51026d73fcfd93610abc7b27789c26b313920fcfb20e27462d74a7f8b06e983", size = 2193071, upload-time = "2026-05-06T13:38:08.682Z" }, ] -[[package]] -name = "pydeck" -version = "0.9.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "jinja2" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/eb/df/4e9e7f20f8034a37c6571c93809f6d22388c39978c98d174d656c1a18fd2/pydeck-0.9.2.tar.gz", hash = "sha256:c10d9035e81ead6385264cac8d19402471f6866a15ca1f7df1400f52142bcf87", size = 5849672, upload-time = "2026-04-16T18:30:30.089Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/88/24/b30ee7d723100fd822de1bb4c0adea62f3419884a75a536f35f355d1e7c0/pydeck-0.9.2-py2.py3-none-any.whl", hash = "sha256:8213dfeacc5f6bfe6825f61c8ee34e3850e8a31fc43924379ec98edb34a75b25", size = 11305615, upload-time = "2026-04-16T18:30:28.133Z" }, -] - [[package]] name = "pygments" version = "2.20.0" @@ -3475,24 +3158,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl", hash = "sha256:1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a", size = 22101, upload-time = "2026-03-01T16:00:25.09Z" }, ] -[[package]] -name = "python-multipart" -version = "0.0.32" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5b/42/55c32bb9b12693c092ad250a0e82edb5b31ddeda6eb772de5f308b3804ad/python_multipart-0.0.32.tar.gz", hash = "sha256:be54b7f3fa167bb83e4fcd936b887b708f4e57fe75911c02aebf53efaf8d938e", size = 46881, upload-time = "2026-06-04T16:18:58.647Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e1/04/e8135ebd1ad02c56ec633277529b2602ff99ff634be76cdba5744cf554fd/python_multipart-0.0.32-py3-none-any.whl", hash = "sha256:ff6d3f776f16878c894e52e107296ffc890e913c611b1a4ec6c44e2821fe2e23", size = 30042, upload-time = "2026-06-04T16:18:57.319Z" }, -] - -[[package]] -name = "pytz" -version = "2026.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ff/46/dd499ec9038423421951e4fad73051febaa13d2df82b4064f87af8b8c0c3/pytz-2026.2.tar.gz", hash = "sha256:0e60b47b29f21574376f218fe21abc009894a2321ea16c6754f3cad6eb7cdd6a", size = 320861, upload-time = "2026-05-04T01:35:29.667Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/dd/96da98f892250475bdf2328112d7468abdd4acc7b902b6af23f4ed958ea0/pytz-2026.2-py2.py3-none-any.whl", hash = "sha256:04156e608bee23d3792fd45c94ae47fae1036688e75032eea2e3bf0323d1f126", size = 510141, upload-time = "2026-05-04T01:35:27.408Z" }, -] - [[package]] name = "pyyaml" version = "6.0.3" @@ -4411,15 +4076,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, ] -[[package]] -name = "smmap" -version = "5.0.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1f/ea/49c993d6dfdd7338c9b1000a0f36817ed7ec84577ae2e52f890d1a4ff909/smmap-5.0.3.tar.gz", hash = "sha256:4d9debb8b99007ae47165abc08670bd74cb74b5227dda7f643eccc4e9eb5642c", size = 22506, upload-time = "2026-03-09T03:43:26.1Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl", hash = "sha256:c106e05d5a61449cf6ba9a1e650227ecfb141590d2a98412103ff35d89fc7b2f", size = 24390, upload-time = "2026-03-09T03:43:24.361Z" }, -] - [[package]] name = "sniffio" version = "1.3.1" @@ -4451,43 +4107,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ec/bb/2799cc2ede3ed41131f8975621e7213dfc7ef4acbbaadfa440f32500c370/starlette-1.3.1-py3-none-any.whl", hash = "sha256:c7372aae11c3c3f26a42df7bd626cec2f47d03483d261d369516a615a53714c6", size = 73632, upload-time = "2026-06-12T09:23:10.017Z" }, ] -[[package]] -name = "streamlit" -version = "1.58.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "altair" }, - { name = "anyio" }, - { name = "blinker" }, - { name = "cachetools" }, - { name = "click" }, - { name = "gitpython" }, - { name = "httptools" }, - { name = "itsdangerous" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "packaging" }, - { name = "pandas", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "pandas", version = "3.0.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "pillow" }, - { name = "protobuf" }, - { name = "pyarrow" }, - { name = "pydeck" }, - { name = "python-multipart" }, - { name = "requests" }, - { name = "starlette" }, - { name = "tenacity" }, - { name = "toml" }, - { name = "typing-extensions" }, - { name = "uvicorn" }, - { name = "watchdog", marker = "sys_platform != 'darwin'" }, - { name = "websockets" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/91/74/20dac6d6200d6ec0e1c230fb8eeb6a1a423645eacb76e8d802adfc246456/streamlit-1.58.0.tar.gz", hash = "sha256:78a22e7085b053af7ce544442bf4b670771e68c509ba1bdaa056ba0708f49c3d", size = 8721149, upload-time = "2026-05-28T18:02:44.606Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/df/84/14c36a92fb24f8e1cea452f53b0744b5da69d52cdd2fe22e71e6fbf765d5/streamlit-1.58.0-py3-none-any.whl", hash = "sha256:4ca8a7afc5bd16a5f176ccf4be1e34e8121cad0240becd127fb58a103ea3178d", size = 9219185, upload-time = "2026-05-28T18:02:41.993Z" }, -] - [[package]] name = "sympy" version = "1.14.0" @@ -4609,15 +4228,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/59/8c/b1c87148aa15e099243ec9f0cf9d0e970cc2234c3257d558c25a2c5304e6/tokenizers-0.22.2-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f01a9c019878532f98927d2bacb79bbb404b43d3437455522a00a30718cdedb5", size = 3373542, upload-time = "2026-01-05T10:40:52.803Z" }, ] -[[package]] -name = "toml" -version = "0.10.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/be/ba/1f744cdc819428fc6b5084ec34d9b30660f6f9daaf70eead706e3203ec3c/toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f", size = 22253, upload-time = "2020-11-01T01:40:22.204Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", size = 16588, upload-time = "2020-11-01T01:40:20.672Z" }, -] - [[package]] name = "tomli" version = "2.4.1" @@ -5038,20 +4648,20 @@ name = "twfarmbot-ui" version = "0.1.0" source = { editable = "apps/ui" } dependencies = [ - { name = "altair" }, + { name = "fastapi" }, { name = "httpx" }, - { name = "streamlit" }, + { name = "ruamel-yaml" }, { name = "twfarmbot-core" }, - { name = "twfarmbot-ml-utils" }, + { name = "uvicorn" }, ] [package.metadata] requires-dist = [ - { name = "altair", specifier = ">=5" }, + { name = "fastapi", specifier = ">=0.110" }, { name = "httpx", specifier = ">=0.27" }, - { name = "streamlit", specifier = ">=1.30" }, + { name = "ruamel-yaml", specifier = ">=0.18" }, { name = "twfarmbot-core", editable = "core" }, - { name = "twfarmbot-ml-utils", editable = "libs/ml_utils" }, + { name = "uvicorn", specifier = ">=0.29" }, ] [[package]] @@ -5250,24 +4860,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/88/fa/e1388bbcf24ef3274f45c0c1c7b501fd14971037c1b6ee23610553307497/uvicorn-0.49.0-py3-none-any.whl", hash = "sha256:ba3d14c3ee7e41c6c654c46c9eb489d33213cdd30aa1696eab1374337c13f68f", size = 71376, upload-time = "2026-06-03T22:01:29.037Z" }, ] -[[package]] -name = "watchdog" -version = "6.0.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/db/7d/7f3d619e951c88ed75c6037b246ddcf2d322812ee8ea189be89511721d54/watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282", size = 131220, upload-time = "2024-11-01T14:07:13.037Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a9/c7/ca4bf3e518cb57a686b2feb4f55a1892fd9a3dd13f470fca14e00f80ea36/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", size = 79079, upload-time = "2024-11-01T14:06:59.472Z" }, - { url = "https://files.pythonhosted.org/packages/5c/51/d46dc9332f9a647593c947b4b88e2381c8dfc0942d15b8edc0310fa4abb1/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", size = 79078, upload-time = "2024-11-01T14:07:01.431Z" }, - { url = "https://files.pythonhosted.org/packages/d4/57/04edbf5e169cd318d5f07b4766fee38e825d64b6913ca157ca32d1a42267/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", size = 79076, upload-time = "2024-11-01T14:07:02.568Z" }, - { url = "https://files.pythonhosted.org/packages/ab/cc/da8422b300e13cb187d2203f20b9253e91058aaf7db65b74142013478e66/watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f", size = 79077, upload-time = "2024-11-01T14:07:03.893Z" }, - { url = "https://files.pythonhosted.org/packages/2c/3b/b8964e04ae1a025c44ba8e4291f86e97fac443bca31de8bd98d3263d2fcf/watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26", size = 79078, upload-time = "2024-11-01T14:07:05.189Z" }, - { url = "https://files.pythonhosted.org/packages/62/ae/a696eb424bedff7407801c257d4b1afda455fe40821a2be430e173660e81/watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c", size = 79077, upload-time = "2024-11-01T14:07:06.376Z" }, - { url = "https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2", size = 79078, upload-time = "2024-11-01T14:07:07.547Z" }, - { url = "https://files.pythonhosted.org/packages/07/f6/d0e5b343768e8bcb4cda79f0f2f55051bf26177ecd5651f84c07567461cf/watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a", size = 79065, upload-time = "2024-11-01T14:07:09.525Z" }, - { url = "https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680", size = 79070, upload-time = "2024-11-01T14:07:10.686Z" }, - { url = "https://files.pythonhosted.org/packages/33/e8/e40370e6d74ddba47f002a32919d91310d6074130fe4e17dabcafc15cbf1/watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f", size = 79067, upload-time = "2024-11-01T14:07:11.845Z" }, -] - [[package]] name = "weave" version = "0.52.43"