From 70b680d49120468849868c7f5b9344e113a0859f Mon Sep 17 00:00:00 2001 From: Schlomo Schapiro Date: Sun, 30 Aug 2026 19:14:59 +0200 Subject: [PATCH 01/35] chore(dev): hardware-free local HA harness with fabricated displays One command (dev/run.sh) brings up homeassistant/home-assistant:stable in Docker with this branch's custom_components/opendisplay mounted read-only, onboards a dev user via HA's own public onboarding HTTP API, and prints the URL + next steps. Ported from a prior-art harness (dev-ha-harness branch, PR #100's tree) onto v3.0.2 main, which has no designer panel yet -- the harness makes no assumption that one exists. New: dev/inject-displays.py writes fabricated OpenDisplay config entries (small mono 250x122, medium BWR 296x128, large BWRY 800x480 -- real py-opendisplay GlobalConfig/DisplayConfig geometries, config_to_json'd) straight into dev/ha-config/.storage/core.config_entries. No BLE, no config flow: __init__.py's async_setup_entry creates the device/entities itself from CONF_CACHED_STATE on every setup. Investigation-verified crux: this Docker container has no Bluetooth adapter, so async_ble_device_from_address() never has a discovered device to return -- it comes back None immediately, so the sleepy-cache fallback (_cache_setup_if_sleepy) is reached with no live-connect attempt at all, not even one that times out. Each fabricated entry also forces options[CONF_SLEEP_MODE]="on" so the sleepy branch is unconditional on top of a genuine battery/deep-sleep PowerOption. Idempotent: entries are matched and replaced by a title-prefix marker; --count controls how many (max 3 distinct geometries). Guards against running while the compose stack is up (storage must not be rewritten under a live HA process). Verified live end to end: onboarding, opendisplay.* services registered with zero entries, 3 fabricated devices boot with image/sensor/binary_sensor entities and no BLE hang, device registry attributes match the fabricated config exactly, and opendisplay.drawcustom dry-run against each device returns a real JPEG at that device's exact fabricated resolution (250x122, 296x128, 800x480) via entity_picture. Full account, including idempotency and re-run tests, in dev/README.md's "Verified vs UNVERIFIED". dev/snapshot.sh / dev/restore.sh / dev/verify-scripts.sh / dev/seed/fixtures ported unchanged for the real-hardware path. CONTRIBUTING.md documents the harness as an alternative to the existing symlink-into-a-live-HA workflow. pyproject.toml per-file-ignores T201 for dev/inject-displays.py (a CLI script; console output is the point). Local commit only, per instructions -- not pushed. Co-Authored-By: Claude Fable 5 --- CONTRIBUTING.md | 20 ++ dev/README.md | 286 +++++++++++++++++++ dev/docker-compose.yml | 14 + dev/ha-config/.gitignore | 6 + dev/ha-config/configuration.yaml | 19 ++ dev/inject-displays.py | 370 +++++++++++++++++++++++++ dev/internal/onboarding.sh | 112 ++++++++ dev/internal/storage-files.sh | 61 ++++ dev/restore.sh | 97 +++++++ dev/run.sh | 106 +++++++ dev/seed/.gitignore | 6 + dev/seed/fixtures/README.md | 10 + dev/seed/fixtures/config_entries.json | 31 +++ dev/seed/fixtures/device_registry.json | 28 ++ dev/seed/fixtures/entity_registry.json | 26 ++ dev/snapshot.sh | 89 ++++++ dev/verify-scripts.sh | 74 +++++ pyproject.toml | 3 + 18 files changed, 1358 insertions(+) create mode 100644 dev/README.md create mode 100644 dev/docker-compose.yml create mode 100644 dev/ha-config/.gitignore create mode 100644 dev/ha-config/configuration.yaml create mode 100755 dev/inject-displays.py create mode 100755 dev/internal/onboarding.sh create mode 100755 dev/internal/storage-files.sh create mode 100755 dev/restore.sh create mode 100755 dev/run.sh create mode 100644 dev/seed/.gitignore create mode 100644 dev/seed/fixtures/README.md create mode 100644 dev/seed/fixtures/config_entries.json create mode 100644 dev/seed/fixtures/device_registry.json create mode 100644 dev/seed/fixtures/entity_registry.json create mode 100755 dev/snapshot.sh create mode 100755 dev/verify-scripts.sh diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e34e4e72..fa49de68 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -41,6 +41,26 @@ Assistant checkout and start it from there: ln -s "$PWD/custom_components/opendisplay" /path/to/core/config/custom_components/ ``` +**No live HA? No OpenDisplay hardware?** `dev/run.sh` brings up a disposable +Home Assistant in Docker with this branch's integration mounted, and +`dev/inject-displays.py` fabricates config entries for a few realistic panels +(small mono / medium BWR / large BWRY) that set up entirely from cache — no +BLE connection, no pairing: + +```bash +dev/run.sh # bring up HA, onboard +docker compose -f dev/docker-compose.yml down # stop (storage can't be + # rewritten under a live + # process) +uv run --group dev python dev/inject-displays.py # fabricate 3 devices +dev/run.sh # bring HA back up +``` + +See [`dev/README.md`](dev/README.md) for the full workflow, why no BLE +connection ever happens in this container, and the real-hardware +snapshot/restore path (`dev/snapshot.sh`/`dev/restore.sh`) if you do have a +device. + ## Translations English is written by hand; every other language is filled in by diff --git a/dev/README.md b/dev/README.md new file mode 100644 index 00000000..cdc9b8d9 --- /dev/null +++ b/dev/README.md @@ -0,0 +1,286 @@ +# OpenDisplay local dev HA harness + +One command gives you a local Home Assistant at `http://localhost:8123` +running this branch's `custom_components/opendisplay`, for manual exploration +— **no OpenDisplay hardware required**. `dev/inject-displays.py` fabricates +config entries for a small mono / medium BWR / large BWRY panel, each set up +from cache with no BLE connection (`_cache_setup_if_sleepy` in `__init__.py`); +`opendisplay.drawcustom` dry-run rendering is all CPU-side, no BLE either. + +## Quickstart + +```bash +dev/run.sh # 1. bring up HA, onboard +docker compose -f dev/docker-compose.yml down # 2. stop (storage can't be + # rewritten under a live + # process) +uv run --group dev python dev/inject-displays.py # 3. fabricate 3 devices +dev/run.sh # 4. bring HA back up +``` + +Open `http://localhost:8123`, log in, and the three fabricated devices are +there with `image`/`sensor`/`binary_sensor` entities. Call +`opendisplay.drawcustom` (Developer Tools → Actions) against one of them with +`dry-run: true` and its image entity updates immediately. + +Re-running `dev/run.sh` is idempotent: it reuses the running container and +skips onboarding if a user already exists. Re-running `inject-displays.py` +replaces exactly the fabricated entries it created previously (matched by a +title prefix — see "Fabricated devices" below); it never touches a real +hardware-bootstrapped OpenDisplay entry or any other integration's entries. + +Stop it: `docker compose -f dev/docker-compose.yml down` +Logs: `docker compose -f dev/docker-compose.yml logs -f` +Reset everything: `rm -rf dev/ha-config` (fully disposable, gitignored) then +`dev/run.sh` again. + +## Fabricated devices (`dev/inject-displays.py`) + +```bash +uv run --group dev python dev/inject-displays.py # 3 devices (default) +uv run --group dev python dev/inject-displays.py --count 2 # fewer +``` + +Writes fabricated OpenDisplay config entries straight into +`dev/ha-config/.storage/core.config_entries` — no BLE, no config flow, no +device_registry/entity_registry seeding needed, because `__init__.py`'s own +`async_setup_entry` creates the device and platform entities itself on every +setup (see "Why no BLE connection happens" below). Each entry carries a +`CONF_CACHED_STATE` payload built from a real `opendisplay.GlobalConfig` (the +same model class the library uses for a real device), so `config_from_json` +round-trips it exactly like a real cached interrogation would: + +| Device | Panel | Color scheme | Deep-sleep interval | +|---|---|---|---| +| Fabricated Small Mono Tag | 250×122 (2.13") | mono | 15 min | +| Fabricated Medium BWR Tag | 296×128 (2.9") | BWR | 5 min | +| Fabricated Large BWRY Tag | 800×480 (7.3") | BWRY | 30 min | + +Each entry's `options` also forces `CONF_SLEEP_MODE = "on"` — redundant with +the genuine battery/deep-sleep `PowerOption` on top of it (either alone +already makes `SleepProfile.is_sleepy` resolve `True` under the default +"auto" mode), but it makes the sleepy-cache path unconditional, matching +exactly what the investigation behind this script needed to confirm. + +**Must run with the dev HA container stopped** (same rule as `restore.sh`): +storage must not be rewritten under a live process. The script checks via +`docker compose ps` and fails loudly if the container is up. + +**Idempotent by title marker**: every fabricated entry's title starts with +`OpenDisplay (dev-harness fabricated)`. A re-run finds and replaces exactly +those entries, leaving a real hardware-bootstrapped entry (titled +`OpenDisplay `, no such prefix) or any other integration's entries +untouched. + +**Fake but well-formed BLE addresses** (`AA:BB:CC:DD:EE:01`, `:02`, `:03`, +...) — never a real OUI. **Encryption key omitted** (`entry.data` carries no +`CONF_ENCRYPTION_KEY`): these are unencrypted devices, and the sleepy-cache +setup path never calls `_get_encryption_key` anyway (see below). + +## Why no BLE connection happens (the investigation this script encodes) + +`async_setup_entry` (`__init__.py`) starts with: + +```python +ble_device = async_ble_device_from_address(hass, address, connectable=True) +``` + +This is a **lookup** against Bluetooth devices HA's `bluetooth` integration +has already discovered advertising — not a connection attempt. Docker +Desktop / Rancher Desktop on macOS gives the container no Bluetooth adapter +at all (`bluetooth_adapters` reports zero adapters), so nothing is ever +discovered and this call returns `None` **immediately**, every time. There is +no live-connect attempt to time out or hang on for a fabricated (or any +other) address in this environment — the `else` branch that does the bounded +`asyncio.timeout(SETUP_DEADLINE_S)` active connect is simply never reached. + +With `ble_device is None`, setup goes straight to `_cache_setup_if_sleepy`: +cached config/firmware are loaded from `entry.data[CONF_CACHED_STATE]` and +`SleepProfile.from_entry` resolves `is_sleepy` from the entry's `options` and +the cached device's own power config (see the table above). If sleepy, setup +proceeds entirely from cache — the device registry entry, platform entities +(`image`/`sensor`/`binary_sensor`), and services all come up exactly as they +would for a real device, with the delivery manager left waiting on a wake +advertisement that, in this container, will simply never arrive (harmless: +it only sets flags and subscribes to a dispatcher signal — no reconnect +attempt happens synchronously or on a timer). + +`opendisplay.drawcustom` with `dry-run: true` never touches BLE either: it +device-registry-looks-up the target, renders via `odl_renderer.generate_image` +(pure CPU), and dispatches the resulting JPEG straight to the image entity. +**Verified live** end to end (this session, real +`homeassistant/home-assistant:stable`, no mocking): after injecting 3 +devices and rebooting, `opendisplay.drawcustom` dry-run against each fabricated +device's `device_id` (resolved via the `device_id()` Jinja function over the +REST `/api/template` endpoint — `device_registry.json` itself lags a save +debounce after boot) returned a service call with no error, the image +entity's state (`image_last_updated`) changed, and fetching +`entity_picture`'s `/api/image_proxy/...` URL returned a genuine JPEG at +**exactly** each device's fabricated resolution: 250×122, 296×128, and +800×480. + +## Onboarding: what's scripted, what isn't, and why + +Home Assistant's first-run onboarding wizard (create admin user, confirm +location, etc.) normally needs a few clicks in the browser. Two ways exist to +skip it: + +- **Pre-seed `.storage/auth` + `.storage/auth_provider.homeassistant` with a + hand-computed user record.** This is the pattern some HA devcontainer + setups use. We deliberately did **not** ship this: it means committing (or + scripting) a bcrypt hash into an internal, undocumented storage schema that + `homeassistant/home-assistant:stable` can change under us at any pull — + brittle in a way that fails silently (a stale/mismatched auth store can + leave you locked out with no error explaining why). +- **Drive the public onboarding HTTP API** (`/api/onboarding/users`, + `/auth/token`, `/api/onboarding/{core_config,analytics,integration}` — + documented at and + `homeassistant/components/onboarding/views.py`). This is the same code path + the wizard's own JS calls, so it isn't a schema hack, and it fails loudly + (curl `-f` + `set -e`) rather than silently. + +`dev/internal/onboarding.sh` (called by `run.sh`) does the latter. **Verified +live** against a real `homeassistant/home-assistant:stable` container in this +repo's dev environment: user creation, token exchange, and all four +onboarding steps completed successfully end to end. + +If a future HA release changes this API, `run.sh` treats onboarding failure +as **non-fatal** — HA is still up and reachable, you just onboard by hand: +open `http://localhost:8123`, create a user (any name/password), click +through "Next" on the remaining steps, "Finish". ~30 seconds. `run.sh` prints +a loud warning telling you to do exactly this when the script fails. + +Dev login is `dev` / `opendisplay-dev-harness` by default; override with +`HA_DEV_USERNAME` / `HA_DEV_PASSWORD` / `HA_DEV_NAME` env vars before running +`dev/run.sh`. + +## Why `opendisplay.drawcustom` and friends show up with zero devices + +`dev/ha-config/configuration.yaml` has a bare `opendisplay:` key. The +integration's `CONFIG_SCHEMA` is `cv.config_entry_only_config_schema` (no +YAML options supported), so this key doesn't configure anything and HA logs +an ERROR ("does not support YAML setup, please remove it") — but the +component's `async_setup()` still runs, which is what registers the +`opendisplay.*` services (`async_setup_services`, `__init__.py`) regardless +of whether any config entry exists yet. Once at least one config entry +exists (real or fabricated), HA calls `async_setup()`/`async_setup_entry()` +for the domain regardless of this key — so it only matters for a totally +pristine instance with zero entries. The ERROR log line is expected and +harmless — it's the mechanism, not a bug. **Verified live**: `curl` of +`/api/services` before any injection lists `opendisplay.drawcustom`, +`upload_image`, `activate_led`, `activate_buzzer`, `write_nfc`, +`play_melody`. + +## BLE-in-Docker-on-macOS caveat + +This container **cannot** reach real OpenDisplay hardware over BLE — Docker +Desktop / Rancher Desktop on macOS runs containers inside a Linux VM with no +Bluetooth passthrough, and `custom_components/opendisplay/config_flow.py` +hard-gates device creation on a live BLE connection test (no virtual/manual +path exists in this integration). `dev/inject-displays.py` sidesteps this +entirely by writing the config entry directly (see above) rather than going +through the config flow. + +For the **real-hardware** path (`dev/snapshot.sh`/`dev/restore.sh` below), +the one-time bootstrap (adding the OpenDisplay integration via the UI and +pairing a device) needs to happen somewhere with real BLE reach to the +device — a Linux box with a Bluetooth adapter running this same +`custom_components/opendisplay` (bare `hass`, this compose file with +`network_mode: host` on Linux, or a full HA install), or the panel physically +near a machine's built-in adapter on a non-Docker-Desktop setup. + +## Real-hardware snapshot / restore (`dev/snapshot.sh`, `dev/restore.sh`) + +If you have real OpenDisplay hardware and want to capture its state instead +of (or alongside) fabricated devices: + +```bash +dev/run.sh # 1. bring up HA, onboard +# 2. ONE TIME, on hardware with real BLE reach (see caveat above): +# add the OpenDisplay integration via the UI, pair your device. +dev/snapshot.sh # 3. capture that device's config/device/entity + # registry entries (opendisplay-domain only) + # into dev/seed/*.json +# ... dev/seed/*.json is gitignored (contains the device's BLE address +# and encryption key) — keep it locally, or share it out-of-band with +# a teammate who wants to skip their own hardware bootstrap. +dev/restore.sh # 4. inject dev/seed/*.json into a fresh instance + # (stops the compose stack itself first — HA + # must not have .storage rewritten under it) +dev/run.sh # 5. bring HA back up; the opendisplay config + # entry should set up from cache, no BLE + # needed +``` + +`dev/restore.sh` upserts by id (never duplicates on repeat runs) and +preserves any other integrations' entries already in `dev/ha-config` — it +only touches records in the seed. `dev/snapshot.sh` fails loudly if no +opendisplay-domain config entry exists yet (nothing to capture) rather than +writing an empty/useless seed. Unlike `dev/inject-displays.py`, this path +also seeds `device_registry`/`entity_registry` records captured from the real +device — belt and suspenders on top of `__init__.py` recreating them itself, +matching what a real one-time bootstrap actually produced. + +`dev/verify-scripts.sh` exercises `snapshot.sh`/`restore.sh`'s `jq` +filter+merge logic against synthetic fixtures in `dev/seed/fixtures/` (no +Docker, no HA, no hardware) — see "Verified vs UNVERIFIED" below for exactly +what this does and doesn't prove. + +## Iterating on the integration + +`custom_components/opendisplay` is mounted **read-only**, so nothing in the +container writes back into your checkout — edit files in your normal editor, +outside the container. Restart to pick up changes: +`docker compose -f dev/docker-compose.yml restart homeassistant`. + +## Verified vs UNVERIFIED + +**Verified live** (this session, against a real +`homeassistant/home-assistant:stable` container, no hardware, no mocking): + +- `dev/run.sh` end to end: Docker checks, `docker compose up -d`, HA became + reachable at `http://localhost:8123`; scripted onboarding + (`dev/internal/onboarding.sh`) completed all four steps. +- `opendisplay:` in `configuration.yaml` → the same two-line mechanism as + before injecting any device: the YAML-setup ERROR log line, and + `GET /api/services` listing all six `opendisplay.*` services with zero + config entries present. +- `dev/inject-displays.py` (3 devices, then re-run with `--count 2`, then + `--count 3` again): wrote/replaced the fabricated entries in + `dev/ha-config/.storage/core.config_entries`; the "must be stopped" guard + correctly refused while the compose stack was up. +- Full boot with the 3 fabricated entries present: `GET /api/states` showed + 9 entities (`image`/`sensor`/`binary_sensor` × 3 devices) with **no BLE + connection attempt, no hang, no error** — confirming the + `async_ble_device_from_address` → `None` → `_cache_setup_if_sleepy` path + described above. +- Device registry attributes for the fabricated devices (via the + `device_attr()` Jinja function): `Seeed Studio / 2.9" BWR / OpenDisplay + (dev-harness fabricated) Fabricated Medium BWR Tag (AA:BB:CC:DD:EE:02)` — + matches the fabricated `GlobalConfig` exactly. +- `opendisplay.drawcustom` dry-run against all 3 fabricated devices (real + `device_id`s, minimal payload `[{"type": "text", "value": "hi", "x": 10, + "y": 10}]`): each call succeeded, each image entity's state timestamp + updated, and each `entity_picture` URL returned a real JPEG at that + device's exact fabricated resolution (250×122, 296×128, 800×480). +- `dev/snapshot.sh` / `dev/restore.sh` / `dev/verify-scripts.sh`: full + filter → merge → idempotent-rerun cycle against the synthetic fixtures in + `dev/seed/fixtures/`, including that unrelated (non-opendisplay) registry + entries survive a restore untouched and the target files' own + `version`/`minor_version`/`key` envelope is preserved. + +**UNVERIFIED** (needs the maintainer's real OpenDisplay hardware — no +virtual/manual path exists in `config_flow.py`): + +- The one-time real-hardware device bootstrap itself (pairing over BLE, + `config_flow.py`'s connection probe). +- `dev/snapshot.sh` against a **real** device's `.storage` output — the + fixture-based test in `dev/verify-scripts.sh` proves the `jq` logic is + correct for the documented schema shape, not that a real capture matches + it byte-for-byte. +- A **live-device** (rather than fabricated) sleepy-cache setup — + `_cache_setup_if_sleepy` is the same code path either way, but this + session only exercised it against fabricated `GlobalConfig`s. +- An actual delivery (non-dry-run) send to a real panel and the wake/queue + behavior around it (`DeliveryManager`) — this harness's dry-run proof + deliberately never reaches BLE, by design. diff --git a/dev/docker-compose.yml b/dev/docker-compose.yml new file mode 100644 index 00000000..dc2dd31a --- /dev/null +++ b/dev/docker-compose.yml @@ -0,0 +1,14 @@ +services: + homeassistant: + image: homeassistant/home-assistant:stable + container_name: opendisplay-dev-ha + restart: unless-stopped + ports: + - "${HA_PORT:-8123}:8123" + volumes: + # HA's own state (onboarding, storage, logs). Read-write, gitignored. + - ./ha-config:/config + # This branch's integration code, mounted read-only so the container can + # never write into the checkout. Restart the container to pick up edits + # (see dev/README.md for what does/doesn't need a restart). + - ../custom_components/opendisplay:/config/custom_components/opendisplay:ro diff --git a/dev/ha-config/.gitignore b/dev/ha-config/.gitignore new file mode 100644 index 00000000..6c737ae4 --- /dev/null +++ b/dev/ha-config/.gitignore @@ -0,0 +1,6 @@ +# Everything here is generated by a running Home Assistant instance +# (onboarding state, .storage/, logs, tts cache, ...) — instance-specific, +# never checked in. Only the hand-written configuration.yaml is tracked. +* +!.gitignore +!configuration.yaml diff --git a/dev/ha-config/configuration.yaml b/dev/ha-config/configuration.yaml new file mode 100644 index 00000000..95faa65d --- /dev/null +++ b/dev/ha-config/configuration.yaml @@ -0,0 +1,19 @@ +# Minimal dev config for the OpenDisplay local harness (dev/README.md). +# default_config pulls in frontend/http/recorder/config/bluetooth/etc. -- +# everything custom_components/opendisplay/manifest.json depends on. +default_config: + +# opendisplay's manifest is config-entry-only (CONFIG_SCHEMA = +# cv.config_entry_only_config_schema) -- this bare key doesn't configure +# anything itself, but it's what makes HA call the domain's async_setup() +# (-> async_setup_services(), custom_components/opendisplay/__init__.py) at +# boot even with zero config entries, so opendisplay.drawcustom and friends +# show up in Developer Tools -> Actions before dev/inject-displays.py has +# ever run. Once a config entry exists (real device or fabricated), HA sets +# the domain up regardless of this key -- see dev/README.md. +opendisplay: + +logger: + default: warning + logs: + custom_components.opendisplay: debug diff --git a/dev/inject-displays.py b/dev/inject-displays.py new file mode 100755 index 00000000..464ad6db --- /dev/null +++ b/dev/inject-displays.py @@ -0,0 +1,370 @@ +#!/usr/bin/env python3 +"""Write fabricated OpenDisplay config entries into the dev harness's HA storage. + +No BLE, no real hardware: this generates N syntactically real ``GlobalConfig`` +device configs (py-opendisplay's own model classes, real geometries) and +writes them as config entries carrying ``CONF_CACHED_STATE`` straight into +``dev/ha-config/.storage/core.config_entries``. On the next ``dev/run.sh``, +``__init__.py``'s sleepy-device cache fallback (``_cache_setup_if_sleepy``) +sets each one up without ever attempting a BLE connection: this Docker +container has no Bluetooth adapter, so +``async_ble_device_from_address(..., connectable=True)`` never has a +discovered device to return and comes back ``None`` immediately -- there is +no live-connect attempt to time out or hang on. The fabricated entries force +``options[CONF_SLEEP_MODE] = SLEEP_MODE_ON`` so the sleepy branch is taken +unconditionally, on top of a genuinely battery/deep-sleep ``PowerOption`` +that would already resolve the same way under the default "auto" mode. + +Usage (uv-run via the repo's own toolchain, matching scripts/*): + + uv run --group dev python dev/inject-displays.py + uv run --group dev python dev/inject-displays.py --count 5 + +Run this only while the dev HA container is stopped -- HA must not have its +``.storage`` rewritten out from under a live process (same rule +``dev/restore.sh`` follows). Idempotent: entries whose title carries this +script's marker (see ``TITLE_PREFIX``) are replaced wholesale on every run; +any other integrations' or hand-bootstrapped OpenDisplay entries are left +alone. +""" + +from __future__ import annotations + +import argparse +import json +from pathlib import Path +import subprocess +import sys +from types import MappingProxyType + +DEV_DIR = Path(__file__).resolve().parent +REPO_ROOT = DEV_DIR.parent +STORAGE_FILE = DEV_DIR / "ha-config" / ".storage" / "core.config_entries" +COMPOSE_FILE = DEV_DIR / "docker-compose.yml" +COMPOSE_SERVICE = "homeassistant" + +# Every fabricated entry's title starts with this, and it is how a re-run +# finds (and replaces) its own previous output without touching anyone +# else's entries -- including a real hardware-bootstrapped OpenDisplay entry, +# which titles itself "OpenDisplay " with no such prefix. +TITLE_PREFIX = "OpenDisplay (dev-harness fabricated)" + +# Base MAC prefix for fabricated devices -- fake but well-formed BLE +# addresses, never a real OUI. The last octet is the 1-based device index. +FAKE_MAC_PREFIX = "AA:BB:CC:DD:EE" + + +def _fail(message: str) -> None: + print(f"ERROR: {message}", file=sys.stderr) + sys.exit(1) + + +def _compose_stack_running() -> bool: + """Return True if the dev HA container is up. + + Best-effort: if docker itself isn't on PATH there is nothing that could + be holding ha-config/.storage open, so treat that as "not running" + rather than failing -- the loud, blocking check is for the case that + actually risks corrupting storage under a live HA process. + """ + try: + result = subprocess.run( + [ + "docker", + "compose", + "-f", + str(COMPOSE_FILE), + "ps", + "--status", + "running", + "--services", + ], + capture_output=True, + text=True, + check=False, + ) + except FileNotFoundError: + return False + return COMPOSE_SERVICE in result.stdout.split() + + +def _build_device_configs(): + """Return (friendly_name, GlobalConfig) pairs for the fabricated fleet. + + Three distinct, realistic panel geometries (small mono / medium BWR / + large BWRY), each a genuine battery + deep-sleep power config so + SleepProfile resolves is_sleepy=True even under the default "auto" mode + -- the forced CONF_SLEEP_MODE=on option (see build_entries) is + belt-and-suspenders on top of that, not the only thing making it sleepy. + """ + from opendisplay import ( + BoardManufacturer, + ColorScheme, + DataExtended, + DisplayConfig, + GlobalConfig, + ManufacturerData, + PowerOption, + SystemConfig, + ) + from opendisplay.models.config import SeeedBoardType + from opendisplay.models.enums import PowerMode + + system = SystemConfig( + ic_type=0, + communication_modes=0, + device_flags=0, + pwr_pin=0xFF, + reserved=b"\x00" * 15, + ) + + def power(deep_sleep_time_seconds: int) -> PowerOption: + return PowerOption( + power_mode=PowerMode.BATTERY, + battery_capacity_mah=(2000).to_bytes(3, "little"), + sleep_timeout_ms=10_000, + tx_power=0, + sleep_flags=0, + battery_sense_pin=0xFF, + battery_sense_enable_pin=0xFF, + battery_sense_flags=0, + capacity_estimator=0, + voltage_scaling_factor=0, + deep_sleep_current_ua=0, + deep_sleep_time_seconds=deep_sleep_time_seconds, + charge_enable_pin=0xFF, + charge_state_pin=0xFF, + charger_flags=0, + min_wake_time_seconds=0, + screen_timeout_seconds=0, + reserved=b"\x00" * 4, + ) + + def data_extended(friendly_name: str, model_name: str) -> DataExtended: + return DataExtended.from_strings( + manufacturer_name="Seeed Studio", + model_name=model_name, + serial_number=f"SN-DEVHARNESS-{friendly_name.upper().replace(' ', '-')}", + friendly_name=friendly_name, + device_location="Dev Harness", + device_id=friendly_name.lower().replace(" ", "-"), + ) + + fleet = [ + ( + "Fabricated Small Mono Tag", + DisplayConfig( + instance_number=0, + display_technology=0, + panel_ic_type=0, + pixel_width=250, + pixel_height=122, + active_width_mm=49, # 2.13" panel (Waveshare-class geometry) + active_height_mm=24, + tag_type=0, + rotation=0, + reset_pin=0xFF, + busy_pin=0xFF, + dc_pin=0xFF, + cs_pin=0xFF, + data_pin=0, + partial_update_support=0, + color_scheme=ColorScheme.MONO.value, + transmission_modes=0x01, + clk_pin=0, + reserved_pins=b"\x00" * 7, + full_update_mC=0, + reserved=b"\x00" * 13, + ), + SeeedBoardType.EE04, + 900, # 15 min deep-sleep interval + '2.13" mono kit', + ), + ( + "Fabricated Medium BWR Tag", + DisplayConfig( + instance_number=0, + display_technology=0, + panel_ic_type=0, + pixel_width=296, + pixel_height=128, + active_width_mm=67, # 2.9" panel + active_height_mm=29, + tag_type=0, + rotation=0, + reset_pin=0xFF, + busy_pin=0xFF, + dc_pin=0xFF, + cs_pin=0xFF, + data_pin=0, + partial_update_support=0, + color_scheme=ColorScheme.BWR.value, + transmission_modes=0x01, + clk_pin=0, + reserved_pins=b"\x00" * 7, + full_update_mC=0, + reserved=b"\x00" * 13, + ), + SeeedBoardType.EN04, + 300, # 5 min deep-sleep interval + '2.9" BWR kit', + ), + ( + "Fabricated Large BWRY Tag", + DisplayConfig( + instance_number=0, + display_technology=0, + panel_ic_type=0, + pixel_width=800, + pixel_height=480, + active_width_mm=163, # 7.3" panel + active_height_mm=98, + tag_type=0, + rotation=0, + reset_pin=0xFF, + busy_pin=0xFF, + dc_pin=0xFF, + cs_pin=0xFF, + data_pin=0, + partial_update_support=0, + color_scheme=ColorScheme.BWRY.value, + transmission_modes=0x01, + clk_pin=0, + reserved_pins=b"\x00" * 7, + full_update_mC=0, + reserved=b"\x00" * 13, + ), + SeeedBoardType.OPENDISPLAY_73_COLOR_KIT, + 1800, # 30 min deep-sleep interval + '7.3" color kit', + ), + ] + + configs = [] + for friendly_name, display, board_type, deep_sleep_s, model_name in fleet: + config = GlobalConfig( + system=system, + manufacturer=ManufacturerData( + manufacturer_id=BoardManufacturer.SEEED, + board_type=int(board_type), + board_revision=0, + reserved=b"\x00" * 6, + ), + power=power(deep_sleep_s), + displays=[display], + data_extended=data_extended(friendly_name, model_name), + ) + configs.append((friendly_name, config)) + return configs + + +def build_entries(count: int): + """Return HA config-entry dicts (as_dict()) for `count` fabricated devices.""" + sys.path.insert(0, str(REPO_ROOT)) + from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry + from opendisplay.models.config_json import config_to_json + + from custom_components.opendisplay.const import CONF_CACHED_STATE, CONF_SLEEP_MODE + + fleet = _build_device_configs() + if count > len(fleet): + _fail( + f"--count {count} exceeds the {len(fleet)} distinct fabricated panel " + "geometries this script knows; add another entry to _build_device_configs " + "in dev/inject-displays.py, or pass a smaller --count." + ) + + entries = [] + for index in range(count): + friendly_name, device_config = fleet[index] + mac = f"{FAKE_MAC_PREFIX}:{index + 1:02X}" + firmware = {"major": 1, "minor": 0, "patch": 0, "sha": "devharness"} + cached_state = { + "config": config_to_json(device_config), + "firmware": firmware, + "is_flex": False, + "landing_url": f"https://opendisplay.org/l/?d=DEVHARNESS{index + 1:02d}", + "cached_at": 0, + } + entry = ConfigEntry( + version=1, + minor_version=1, + domain="opendisplay", + title=f"{TITLE_PREFIX} {friendly_name} ({mac})", + data={CONF_CACHED_STATE: cached_state}, + source=SOURCE_IMPORT, + unique_id=mac, + # SLEEP_MODE_ON is redundant with the battery/deep-sleep power + # config above (SleepProfile's "auto" mode would already resolve + # is_sleepy=True from it) but makes the sleepy fallback + # unconditional, matching the investigation finding this script + # exists to encode: is_sleepy must come from the fabricated + # entry, not from ever actually reaching the device. + options={CONF_SLEEP_MODE: "on"}, + discovery_keys=MappingProxyType({}), + subentries_data=None, + ) + entries.append(entry.as_dict()) + return entries + + +def main() -> None: + """Parse arguments and (re)write the fabricated config entries.""" + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument( + "--count", + type=int, + default=3, + help="number of fabricated devices to write (default: 3)", + ) + args = parser.parse_args() + if args.count < 1: + _fail("--count must be at least 1") + + if _compose_stack_running(): + _fail( + "the dev HA stack is running (docker compose -f dev/docker-compose.yml). " + "Storage must not be rewritten under a live process. Stop it first: " + "docker compose -f dev/docker-compose.yml down" + ) + + if not STORAGE_FILE.exists(): + _fail( + f"{STORAGE_FILE} not found. Run dev/run.sh at least once (through " + "onboarding) first, so HA has created its baseline config_entries store." + ) + + raw = json.loads(STORAGE_FILE.read_text()) + if raw.get("key") != "core.config_entries": + _fail( + f"{STORAGE_FILE} has key '{raw.get('key')}', expected 'core.config_entries'. " + "HA's .storage schema for this file may have changed; script needs updating." + ) + + existing = raw["data"]["entries"] + kept = [e for e in existing if not e.get("title", "").startswith(TITLE_PREFIX)] + removed = len(existing) - len(kept) + + fabricated = build_entries(args.count) + raw["data"]["entries"] = kept + fabricated + + tmp = STORAGE_FILE.with_suffix(".tmp") + tmp.write_text(json.dumps(raw, indent=2) + "\n") + tmp.replace(STORAGE_FILE) + + verb = "Replaced" if removed else "Wrote" + print( + f"inject-displays: {verb} {removed} previous fabricated entr" + f"{'y' if removed == 1 else 'ies'} with {len(fabricated)} new one(s) in " + f"{STORAGE_FILE}:" + ) + for entry in fabricated: + print( + f" - {entry['title']} (unique_id={entry['unique_id']}, entry_id={entry['entry_id']})" + ) + print("\nStart the harness with dev/run.sh -- each entry sets up from its own") + print("cache (no BLE connection) per __init__.py's sleepy-device fallback.") + + +if __name__ == "__main__": + main() diff --git a/dev/internal/onboarding.sh b/dev/internal/onboarding.sh new file mode 100755 index 00000000..f1e8922c --- /dev/null +++ b/dev/internal/onboarding.sh @@ -0,0 +1,112 @@ +#!/usr/bin/env bash +# Drive HA's own onboarding wizard through its public HTTP API +# (https://developers.home-assistant.io/docs/auth_api/, and +# homeassistant/components/onboarding/views.py) so run.sh can hand back a +# logged-in dev instance instead of the onboarding wizard. Same steps a human +# clicking through the wizard triggers ("user" -> "core_config" -> "analytics" +# -> "integration") — not a .storage/auth_provider hack. Idempotent: skips if +# the "user" step is already done, OR if /api/onboarding is already gone — +# HA's onboarding component only registers its views on a boot where +# async_is_onboarded() is still false, so on any boot *after* the one that +# completed it, GET /api/onboarding 404s. That's the normal steady state for +# a harness reused across `docker compose down`/`up` cycles, not a failure. +# Any other HTTP failure aborts loudly (set -e + curl -f); run.sh treats that +# as non-fatal (HA is still reachable, the maintainer can onboard by hand) +# but prints the failure prominently. +set -euo pipefail + +HA_URL="${HA_URL:?onboarding.sh: HA_URL must be set}" +HA_DEV_USERNAME="${HA_DEV_USERNAME:-dev}" +HA_DEV_PASSWORD="${HA_DEV_PASSWORD:-opendisplay-dev-harness}" +HA_DEV_NAME="${HA_DEV_NAME:-Dev}" +client_id="${HA_URL%/}/" + +command -v curl >/dev/null 2>&1 || { + echo "ERROR: curl is required." >&2 + exit 1 +} +command -v jq >/dev/null 2>&1 || { + echo "ERROR: jq is required (brew install jq)." >&2 + exit 1 +} + +# Fetches body + HTTP status in one request (body\nSTATUS on stdout); +# deliberately not `curl -f`, since a 404 is a meaningful, expected outcome +# (see note above), not a transport failure. Split in the caller, not inside +# a function invoked via $(...) — a function can't leak a second variable out +# of the subshell command substitution creates. +fetch_onboarding_status() { + curl -s -w '\n%{http_code}' "$HA_URL/api/onboarding" +} + +user_step_done() { + jq -e '.[] | select(.step=="user") | .done == true' <<<"$1" >/dev/null 2>&1 +} + +all_steps_done() { + jq -e 'all(.[]; .done == true)' <<<"$1" >/dev/null 2>&1 +} + +raw="$(fetch_onboarding_status)" +http_code="${raw##*$'\n'}" +status="${raw%$'\n'*}" +if [[ "$http_code" == "404" ]]; then + echo "onboarding: /api/onboarding is gone (404) — HA already finished onboarding" \ + "in a prior boot (its views only register pre-onboarding); skipping." + exit 0 +fi +[[ "$http_code" == "200" ]] || { + echo "ERROR: GET /api/onboarding returned HTTP $http_code: $status" >&2 + exit 1 +} +if user_step_done "$status"; then + echo "onboarding: already done (a user account exists) — skipping." + exit 0 +fi + +echo "onboarding: creating dev user '$HA_DEV_USERNAME'..." +users_resp="$(curl -sf -X POST "$HA_URL/api/onboarding/users" \ + -H 'Content-Type: application/json' \ + -d "$(jq -n --arg name "$HA_DEV_NAME" --arg username "$HA_DEV_USERNAME" \ + --arg password "$HA_DEV_PASSWORD" --arg client_id "$client_id" \ + '{name: $name, username: $username, password: $password, client_id: $client_id, language: "en"}')")" +auth_code="$(jq -r '.auth_code' <<<"$users_resp")" +[[ -n "$auth_code" && "$auth_code" != "null" ]] || { + echo "ERROR: onboarding/users did not return an auth_code: $users_resp" >&2 + exit 1 +} + +echo "onboarding: exchanging auth code for an access token..." +token_resp="$(curl -sf -X POST "$HA_URL/auth/token" \ + --data-urlencode "grant_type=authorization_code" \ + --data-urlencode "code=$auth_code" \ + --data-urlencode "client_id=$client_id")" +access_token="$(jq -r '.access_token' <<<"$token_resp")" +[[ -n "$access_token" && "$access_token" != "null" ]] || { + echo "ERROR: /auth/token did not return an access_token: $token_resp" >&2 + exit 1 +} + +echo "onboarding: finishing core_config / analytics / integration steps..." +curl -sf -X POST "$HA_URL/api/onboarding/core_config" \ + -H "Authorization: Bearer $access_token" -H 'Content-Type: application/json' -d '{}' >/dev/null +curl -sf -X POST "$HA_URL/api/onboarding/analytics" \ + -H "Authorization: Bearer $access_token" -H 'Content-Type: application/json' -d '{}' >/dev/null +curl -sf -X POST "$HA_URL/api/onboarding/integration" \ + -H "Authorization: Bearer $access_token" -H 'Content-Type: application/json' \ + -d "$(jq -n --arg cid "$client_id" '{client_id: $cid, redirect_uri: $cid}')" >/dev/null + +raw="$(fetch_onboarding_status)" +status="${raw%$'\n'*}" +all_steps_done "$status" || { + echo "ERROR: onboarding steps still incomplete after driving the API: $status" >&2 + exit 1 +} + +cat < on-disk filename under .storage/, the JSON array path +# holding the records, and the field that uniquely identifies a record +# (used for upsert-by-id in restore.sh). These three keys have been stable +# across HA releases for years; get_storage_key/get_array_path/get_id_field +# below assert the expected "key" field in the file so a future rename fails +# loudly here instead of silently mis-filtering. + +storage_seed_names=(config_entries device_registry entity_registry) + +storage_file_for() { + case "$1" in + config_entries) echo "core.config_entries" ;; + device_registry) echo "core.device_registry" ;; + entity_registry) echo "core.entity_registry" ;; + *) + echo "storage-files.sh: unknown seed name '$1'" >&2 + return 1 + ;; + esac +} + +storage_array_path_for() { + case "$1" in + config_entries) echo ".data.entries" ;; + device_registry) echo ".data.devices" ;; + entity_registry) echo ".data.entities" ;; + *) + echo "storage-files.sh: unknown seed name '$1'" >&2 + return 1 + ;; + esac +} + +storage_id_field_for() { + case "$1" in + config_entries) echo "entry_id" ;; + device_registry) echo "id" ;; + entity_registry) echo "entity_id" ;; + *) + echo "storage-files.sh: unknown seed name '$1'" >&2 + return 1 + ;; + esac +} + +# Fail loudly if a .storage file's own "key" field doesn't match what we +# expect, rather than silently filtering the wrong structure. +assert_storage_key() { + local seed_name="$1" file="$2" expected actual + expected="$(storage_file_for "$seed_name")" + actual="$(jq -r '.key // empty' "$file")" + if [[ "$actual" != "$expected" ]]; then + echo "ERROR: $file has key '$actual', expected '$expected'." \ + "HA's .storage schema for this file may have changed; script needs updating." >&2 + exit 1 + fi +} diff --git a/dev/restore.sh b/dev/restore.sh new file mode 100755 index 00000000..48f0fe0f --- /dev/null +++ b/dev/restore.sh @@ -0,0 +1,97 @@ +#!/usr/bin/env bash +# Inject the dev/seed/*.json snapshot (see dev/snapshot.sh) into a fresh HA +# instance's .storage, so the opendisplay config entry / device / entities +# come back without repeating the real-hardware bootstrap. Idempotent: +# upserts by id, so re-running is a no-op past the first restore. +# +# CAVEAT: HA must be stopped while its .storage is rewritten underneath it — +# this script stops the compose stack itself before touching any file. +set -euo pipefail + +DEV_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +STORAGE_DIR="$DEV_DIR/ha-config/.storage" +SEED_DIR="$DEV_DIR/seed" +COMPOSE_FILE="$DEV_DIR/docker-compose.yml" +# shellcheck source=internal/storage-files.sh +source "$DEV_DIR/internal/storage-files.sh" + +command -v jq >/dev/null 2>&1 || { + echo "ERROR: jq is required (brew install jq)." >&2 + exit 1 +} +command -v docker >/dev/null 2>&1 || { + echo "ERROR: docker not found on PATH." >&2 + exit 1 +} + +[[ -f "$SEED_DIR/config_entries.json" ]] || { + echo "ERROR: $SEED_DIR/config_entries.json not found. Run dev/snapshot.sh first" \ + "(after the one-time hardware device bootstrap), or copy a colleague's" \ + "dev/seed/ export there. For fabricated (no-hardware) devices, use" \ + "dev/inject-displays.py instead." >&2 + exit 1 +} +[[ -f "$SEED_DIR/MANIFEST.json" ]] || { + echo "ERROR: $SEED_DIR/MANIFEST.json missing — seed dir wasn't produced by snapshot.sh." >&2 + exit 1 +} + +mode="$(jq -r '.mode // "unknown"' "$SEED_DIR/MANIFEST.json")" +if [[ "$mode" != "filtered" ]]; then + echo "WARNING: seed mode is '$mode', not 'filtered' — restore will overwrite whole" \ + "registries, not just the opendisplay slice. Any other integrations' entries in" \ + "this dev instance will be replaced by the snapshot's." >&2 +fi + +echo "restore: stopping the dev HA stack (storage must not be rewritten under a live process)..." +docker compose -f "$COMPOSE_FILE" down >/dev/null 2>&1 || true + +[[ -d "$STORAGE_DIR" ]] || { + echo "ERROR: $STORAGE_DIR not found. Run dev/run.sh at least once (through onboarding)" \ + "before restoring, so HA has created its baseline registries." >&2 + exit 1 +} + +# Upsert seed/.json's records into ha-config/.storage/ by id, +# keeping every existing record whose id isn't in the seed and replacing any +# that is. Preserves the target file's own version/minor_version/key envelope. +upsert_seed() { + local seed_name="$1" + local array_path id_field seed_file target_file tmp seed_array seed_ids total + + array_path="$(storage_array_path_for "$seed_name")" # e.g. ".data.entries" + array_path="${array_path#.}" # -> "data.entries" + id_field="$(storage_id_field_for "$seed_name")" + seed_file="$SEED_DIR/$seed_name.json" + target_file="$STORAGE_DIR/$(storage_file_for "$seed_name")" + + if [[ ! -f "$seed_file" ]]; then + echo "restore: no $seed_name.json in seed (snapshot.sh warned about this) — skipping." + return 0 + fi + if [[ ! -f "$target_file" ]]; then + echo "ERROR: $target_file not found. Run dev/run.sh through onboarding first so HA" \ + "has created its baseline $seed_name store." >&2 + exit 1 + fi + assert_storage_key "$seed_name" "$target_file" + + seed_array="$(jq -c ".$array_path" "$seed_file")" + seed_ids="$(jq -c "[.[].$id_field]" <<<"$seed_array")" + + tmp="$(mktemp "$target_file.XXXXXX")" + jq --argjson seed "$seed_array" --argjson ids "$seed_ids" \ + ".$array_path |= ((. // []) | map(select((.$id_field) as \$i | (\$ids | index(\$i)) == null)) + \$seed)" \ + "$target_file" >"$tmp" + mv "$tmp" "$target_file" + + total="$(jq ".$array_path | length" "$target_file")" + echo "restore: $seed_name -> merged $(jq 'length' <<<"$seed_ids") upserted, $total total in store." +} + +for name in "${storage_seed_names[@]}"; do + upsert_seed "$name" +done + +echo "restore: done. Start the harness with dev/run.sh — the opendisplay config entry" \ + "should set up from cache (no BLE needed) per __init__.py's sleepy-cache fallback." diff --git a/dev/run.sh b/dev/run.sh new file mode 100755 index 00000000..dfcbe5c3 --- /dev/null +++ b/dev/run.sh @@ -0,0 +1,106 @@ +#!/usr/bin/env bash +# One command: bring up a local Home Assistant with this branch's OpenDisplay +# integration mounted, reachable at http://localhost:8123. See dev/README.md +# for the full workflow. +set -euo pipefail + +DEV_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +COMPOSE_FILE="$DEV_DIR/docker-compose.yml" +HA_PORT="${HA_PORT:-8123}" +HA_URL="http://localhost:${HA_PORT}" + +command -v docker >/dev/null 2>&1 || { + echo "ERROR: docker not found on PATH. Install Docker Desktop (or Rancher Desktop) first." >&2 + exit 1 +} +docker compose version >/dev/null 2>&1 || { + echo "ERROR: 'docker compose' (the plugin, not standalone docker-compose) is required." >&2 + exit 1 +} +docker info >/dev/null 2>&1 || { + echo "ERROR: Docker daemon not reachable. Start Docker Desktop / Rancher Desktop and retry." >&2 + exit 1 +} + +already_running=false +if docker compose -f "$COMPOSE_FILE" ps --status running --services 2>/dev/null | grep -qx homeassistant; then + already_running=true +fi + +if [[ "$already_running" == false ]]; then + # Port-free check: only fail if something OTHER than our own (stopped) stack + # holds it — a bare TCP probe can't tell whose process that is, so this is + # best-effort; `docker compose up` below is the authoritative check. + if (exec 3<>"/dev/tcp/127.0.0.1/$HA_PORT") 2>/dev/null; then + exec 3>&- 3<&- + echo "ERROR: port $HA_PORT is already in use by something else." \ + "Free it, or set HA_PORT= and rerun." >&2 + exit 1 + fi +fi + +echo "run: starting the dev HA stack (docker compose up -d)..." +docker compose -f "$COMPOSE_FILE" up -d + +echo "run: waiting for HA to answer at $HA_URL ..." +deadline=$((SECONDS + 120)) +until curl -sf -o /dev/null "$HA_URL/manifest.json"; do + if ((SECONDS > deadline)); then + echo "ERROR: HA did not become reachable at $HA_URL within 120s." \ + "Check logs: docker compose -f dev/docker-compose.yml logs" >&2 + exit 1 + fi + sleep 2 +done +echo "run: HA is up." + +echo "run: attempting scripted onboarding (idempotent, non-fatal if it fails)..." +if HA_URL="$HA_URL" "$DEV_DIR/internal/onboarding.sh"; then + onboarded=true +else + onboarded=false + echo + echo "WARNING: scripted onboarding failed (see error above)." \ + "HA is still up — onboard by hand in the browser (dev/README.md, ~30s)." >&2 + echo +fi + +cat </dev/null 2>&1 || { + echo "ERROR: jq is required (brew install jq)." >&2 + exit 1 +} + +[[ -d "$STORAGE_DIR" ]] || { + echo "ERROR: $STORAGE_DIR not found. Run dev/run.sh and onboard at least once first." >&2 + exit 1 +} + +ce_file="$STORAGE_DIR/$(storage_file_for config_entries)" +[[ -f "$ce_file" ]] || { + echo "ERROR: $ce_file not found — has HA started at least once?" >&2 + exit 1 +} +assert_storage_key config_entries "$ce_file" + +mkdir -p "$SEED_DIR" + +# --- config_entries: keep only domain == "opendisplay" ------------------ +entry_ids_json="$(jq -c '[.data.entries[] | select(.domain=="opendisplay") | .entry_id]' "$ce_file")" +entry_count="$(jq 'length' <<<"$entry_ids_json")" + +if [[ "$entry_count" -eq 0 ]]; then + echo "ERROR: no opendisplay-domain config entries found in $ce_file." >&2 + echo "Complete the one-time hardware device bootstrap (dev/README.md) before snapshotting," \ + "or use dev/inject-displays.py if you only need fabricated devices." >&2 + exit 1 +fi + +jq '.data.entries |= map(select(.domain=="opendisplay"))' "$ce_file" \ + >"$SEED_DIR/config_entries.json" +echo "snapshot: config_entries -> $entry_count opendisplay entr$([[ $entry_count -eq 1 ]] && echo y || echo ies)" + +# --- device_registry: keep devices referencing a retained entry_id ------ +dr_file="$STORAGE_DIR/$(storage_file_for device_registry)" +if [[ -f "$dr_file" ]]; then + assert_storage_key device_registry "$dr_file" + jq --argjson ids "$entry_ids_json" ' + .data.devices |= map( + select((.config_entries // []) as $dce | any($ids[]; . as $id | $dce | index($id) != null)) + ) + ' "$dr_file" >"$SEED_DIR/device_registry.json" + device_count="$(jq '.data.devices | length' "$SEED_DIR/device_registry.json")" + echo "snapshot: device_registry -> $device_count device(s)" +else + echo "WARNING: $dr_file not found; skipping device_registry (restore.sh will leave it untouched)." >&2 + rm -f "$SEED_DIR/device_registry.json" +fi + +# --- entity_registry: keep entities referencing a retained entry_id ----- +er_file="$STORAGE_DIR/$(storage_file_for entity_registry)" +if [[ -f "$er_file" ]]; then + assert_storage_key entity_registry "$er_file" + jq --argjson ids "$entry_ids_json" ' + .data.entities |= map( + select(.config_entry_id as $id | $ids | index($id) != null) + ) + ' "$er_file" >"$SEED_DIR/entity_registry.json" + entity_count="$(jq '.data.entities | length' "$SEED_DIR/entity_registry.json")" + echo "snapshot: entity_registry -> $entity_count entit$([[ $entity_count -eq 1 ]] && echo y || echo ies)" +else + echo "WARNING: $er_file not found; skipping entity_registry (restore.sh will leave it untouched)." >&2 + rm -f "$SEED_DIR/entity_registry.json" +fi + +jq -n --argjson ids "$entry_ids_json" --arg captured_at "$(date -u +%Y-%m-%dT%H:%M:%SZ)" ' + { + captured_at: $captured_at, + mode: "filtered", + entry_ids: $ids, + note: "Filtered to domain=opendisplay, referencing the entry_ids listed above." + } +' >"$SEED_DIR/MANIFEST.json" + +echo "snapshot: wrote dev/seed/*.json (dev/seed/MANIFEST.json records how)." diff --git a/dev/verify-scripts.sh b/dev/verify-scripts.sh new file mode 100755 index 00000000..3e0f224c --- /dev/null +++ b/dev/verify-scripts.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash +# Exercises snapshot.sh / restore.sh's jq filter+merge logic against the +# synthetic fixtures in dev/seed/fixtures/ — no Docker, no HA, no hardware. +# This is the regression test for the storage-manipulation logic: it does NOT +# prove the scripts work against a REAL opendisplay device's .storage output +# (that needs real hardware; see dev/README.md "Verified vs UNVERIFIED"). +# +# Runs entirely in a throwaway copy of dev/ under mktemp -d; never touches +# dev/ha-config or dev/seed in the real checkout. +set -euo pipefail + +DEV_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SANDBOX="$(mktemp -d)" +trap 'rm -rf "$SANDBOX"' EXIT + +fail() { + echo "FAIL: $*" >&2 + exit 1 +} + +cp -R "$DEV_DIR/." "$SANDBOX/" +STORAGE="$SANDBOX/ha-config/.storage" +mkdir -p "$STORAGE" + +# --- snapshot.sh: filters a fixture "post-bootstrap" instance down to just +# the opendisplay-domain records, leaving the unrelated "met" fixture entry +# out. ------------------------------------------------------------------ +cp "$SANDBOX/seed/fixtures/config_entries.json" "$STORAGE/core.config_entries" +cp "$SANDBOX/seed/fixtures/device_registry.json" "$STORAGE/core.device_registry" +cp "$SANDBOX/seed/fixtures/entity_registry.json" "$STORAGE/core.entity_registry" + +"$SANDBOX/snapshot.sh" + +jq -e '.data.entries | length == 1 and .[0].domain == "opendisplay"' \ + "$SANDBOX/seed/config_entries.json" >/dev/null || + fail "snapshot: config_entries.json should contain exactly the opendisplay entry" +jq -e '.data.devices | length == 1 and .[0].id == "od_fake_device_1"' \ + "$SANDBOX/seed/device_registry.json" >/dev/null || + fail "snapshot: device_registry.json should contain exactly the opendisplay device" +jq -e '.data.entities | length == 1 and .[0].entity_id == "image.opendisplay_aabbccddeeff_image"' \ + "$SANDBOX/seed/entity_registry.json" >/dev/null || + fail "snapshot: entity_registry.json should contain exactly the opendisplay entity" +jq -e '.mode == "filtered"' "$SANDBOX/seed/MANIFEST.json" >/dev/null || + fail "snapshot: MANIFEST.json should be valid JSON with mode=filtered" +echo "OK: snapshot.sh filters to the opendisplay domain only" + +# --- restore.sh: merging the snapshot into a "fresh" instance that only has +# the unrelated met.no entry must add the opendisplay records back AND leave +# met.no's alone; running it twice must not duplicate anything. ----------- +jq '.data.entries |= map(select(.domain=="met"))' \ + "$SANDBOX/seed/fixtures/config_entries.json" >"$STORAGE/core.config_entries" +jq '.data.devices |= map(select(.config_entries | index("met_fake_entry_1")))' \ + "$SANDBOX/seed/fixtures/device_registry.json" >"$STORAGE/core.device_registry" +jq '.data.entities |= map(select(.config_entry_id=="met_fake_entry_1"))' \ + "$SANDBOX/seed/fixtures/entity_registry.json" >"$STORAGE/core.entity_registry" + +"$SANDBOX/restore.sh" >/dev/null +"$SANDBOX/restore.sh" >/dev/null # idempotency: must not duplicate + +jq -e '[.data.entries[].entry_id] | sort == ["met_fake_entry_1", "od_fake_entry_1"]' \ + "$STORAGE/core.config_entries" >/dev/null || + fail "restore: config_entries should have exactly met + opendisplay, once each" +jq -e '[.data.devices[].id] | sort == ["met_fake_device_1", "od_fake_device_1"]' \ + "$STORAGE/core.device_registry" >/dev/null || + fail "restore: device_registry should have exactly met + opendisplay, once each" +jq -e '[.data.entities[].entity_id] | sort == ["image.opendisplay_aabbccddeeff_image", "weather.forecast_home"]' \ + "$STORAGE/core.entity_registry" >/dev/null || + fail "restore: entity_registry should have exactly met + opendisplay, once each" +jq -e '.version == 1 and .minor_version == 4 and .key == "core.config_entries"' \ + "$STORAGE/core.config_entries" >/dev/null || + fail "restore: config_entries envelope (version/minor_version/key) must be preserved" +echo "OK: restore.sh merges by id, preserves unrelated entries, idempotent" + +echo "verify-scripts: all checks passed." diff --git a/pyproject.toml b/pyproject.toml index f09eec10..7abd63e5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -134,6 +134,9 @@ split-on-trailing-comma = false [tool.ruff.lint.per-file-ignores] # Vendored verbatim from Home Assistant core's test helpers. "tests/bluetooth.py" = ["D"] +# CLI script for the dev/ harness (dev/README.md) -- console output to the +# maintainer running it is the point, not a logging call. +"dev/inject-displays.py" = ["T201"] [tool.ruff.lint.mccabe] max-complexity = 25 From 79b32b6479e50275f02e899f2fa5569cbaf32f88 Mon Sep 17 00:00:00 2001 From: Schlomo Schapiro Date: Sun, 30 Aug 2026 21:45:12 +0200 Subject: [PATCH 02/35] feat(designer): vendor odl-drawcustom-designer + js-yaml from npm, pinned Home Assistant custom components cannot npm install at runtime, so both the designer library and its js-yaml dependency ship vendored into the repo. scripts/update-designer-vendor.py replaces hand-dropped release blobs with a pinned, verifiable download for EACH: fetch the npm registry's declared sha512 integrity for an exact version, download the tarball, verify the actual bytes against that hash, then copy the files the panel consumes into designer/frontend/vendor/. Both packages fail loudly and write nothing to vendor/ on any network, integrity, or tarball-layout mismatch. Pinned: designer @2.6.3 (designer.lock.json's "designer" entry), js-yaml @4.1.0 ("js_yaml" entry) -- js-yaml previously shipped as an unpinned jsDelivr-rebundled blob with no integrity record and no license file of its own; it now ships the genuine npm-published dist/js-yaml.mjs, verified and licensed (LICENSE.js-yaml) the same way the designer bundle is. Re-ran both --pin and --pin-js-yaml here against the live npm registry to prove the script works. Co-Authored-By: Claude Fable 5 --- .../designer/frontend/vendor/LICENSE | 202 + .../designer/frontend/vendor/LICENSE.js-yaml | 21 + .../designer/frontend/vendor/NOTICE | 66 + .../designer/frontend/vendor/README.md | 64 + .../designer/frontend/vendor/THIRD_PARTY.md | 79 + .../frontend/vendor/designer.lock.json | 10 + .../designer/frontend/vendor/js-yaml.mjs | 3851 + .../vendor/odl-drawcustom-designer.d.ts | 702 + .../vendor/odl-drawcustom-designer.js | 77261 ++++++++++++++++ scripts/update-designer-vendor.py | 307 + 10 files changed, 82563 insertions(+) create mode 100644 custom_components/opendisplay/designer/frontend/vendor/LICENSE create mode 100644 custom_components/opendisplay/designer/frontend/vendor/LICENSE.js-yaml create mode 100644 custom_components/opendisplay/designer/frontend/vendor/NOTICE create mode 100644 custom_components/opendisplay/designer/frontend/vendor/README.md create mode 100644 custom_components/opendisplay/designer/frontend/vendor/THIRD_PARTY.md create mode 100644 custom_components/opendisplay/designer/frontend/vendor/designer.lock.json create mode 100644 custom_components/opendisplay/designer/frontend/vendor/js-yaml.mjs create mode 100644 custom_components/opendisplay/designer/frontend/vendor/odl-drawcustom-designer.d.ts create mode 100644 custom_components/opendisplay/designer/frontend/vendor/odl-drawcustom-designer.js create mode 100755 scripts/update-designer-vendor.py diff --git a/custom_components/opendisplay/designer/frontend/vendor/LICENSE b/custom_components/opendisplay/designer/frontend/vendor/LICENSE new file mode 100644 index 00000000..8a4ee770 --- /dev/null +++ b/custom_components/opendisplay/designer/frontend/vendor/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2026 Schlomo Schapiro + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/custom_components/opendisplay/designer/frontend/vendor/LICENSE.js-yaml b/custom_components/opendisplay/designer/frontend/vendor/LICENSE.js-yaml new file mode 100644 index 00000000..09d3a29e --- /dev/null +++ b/custom_components/opendisplay/designer/frontend/vendor/LICENSE.js-yaml @@ -0,0 +1,21 @@ +(The MIT License) + +Copyright (C) 2011-2015 by Vitaly Puzrin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/custom_components/opendisplay/designer/frontend/vendor/NOTICE b/custom_components/opendisplay/designer/frontend/vendor/NOTICE new file mode 100644 index 00000000..aac9a360 --- /dev/null +++ b/custom_components/opendisplay/designer/frontend/vendor/NOTICE @@ -0,0 +1,66 @@ +ODL/OEPL Drawcustom Designer (odl-drawcustom-designer) +Copyright 2026 Schlomo Schapiro + +This product includes software developed by Schlomo Schapiro and contributors, +licensed under the Apache License, Version 2.0 (see LICENSE). + +================================================================================ +Vendored documentation +================================================================================ + +docs/spec/supported_types.md + Source: OpenEPaperLink Home Assistant Integration + URL: https://github.com/OpenEPaperLink/Home_Assistant_Integration/blob/main/docs/drawcustom/supported_types.md + License: Apache License 2.0 + Copyright: OpenEPaperLink contributors + +================================================================================ +Bundled fonts +================================================================================ + +public/fonts/ppb.ttf +public/fonts/rbm.ttf + Also emitted at build time as dist-lib/assets/demo-host-font.ttf — a copy of + rbm.ttf the demo host page serves as a host-resolved asset (see + tools/demoHostAssets.ts, docs/embedding.md#resolveasset-issue-138) + Source: OpenEPaperLink Home Assistant Integration (imagegen assets) + URL: https://github.com/OpenEPaperLink/Home_Assistant_Integration/tree/main/custom_components/open_epaper_link/imagegen/assets + License: Apache License 2.0 (same repository as above) + Note: Font files are distributed with the integration; no separate font + license file was found upstream. See docs/THIRD_PARTY.md for details. + +================================================================================ +Bundled icons (runtime) +================================================================================ + +@mdi/js — Material Design Icons path data (Pictogrammers) + URL: https://github.com/Templarian/MaterialDesign-SVG + License: Apache License 2.0 + Copyright: Pictogrammers + +================================================================================ +Referenced upstream projects (not shipped as source) +================================================================================ + +OpenEPaperLink firmware — CC BY-NC-SA 4.0 + URL: https://github.com/OpenEPaperLink/OpenEPaperLink + +OpenDisplay firmware — GPL-3.0 + URL: https://github.com/OpenDisplay/Firmware + +OpenDisplay Language / Basic Standard specifications + URL: https://opendisplay.org/protocol/ + Note: Published specification pages; no explicit license stated on site. + +Home Assistant integrations (drawcustom): + OpenEPaperLink/Home_Assistant_Integration — Apache-2.0 + OpenDisplay/Home_Assistant_Integration — Apache-2.0 + home-assistant/core (opendisplay component) — Apache-2.0 + +================================================================================ +Open-source dependencies +================================================================================ + +This application is built with npm packages. Each dependency is licensed +under its own terms. Run `npx license-checker --summary` in the project +root for a full report, or see docs/THIRD_PARTY.md for key runtime libraries. diff --git a/custom_components/opendisplay/designer/frontend/vendor/README.md b/custom_components/opendisplay/designer/frontend/vendor/README.md new file mode 100644 index 00000000..d5ec69de --- /dev/null +++ b/custom_components/opendisplay/designer/frontend/vendor/README.md @@ -0,0 +1,64 @@ +# Vendored libraries + +This directory vendors two npm packages the panel needs, both pinned and +verified the same way: + +- [`@schlomo/odl-drawcustom-designer`](https://github.com/schlomo/odl-drawcustom-designer) — + the designer library itself. +- [`js-yaml`](https://github.com/nodeca/js-yaml) — the panel needs it to turn + the designer's YAML string payload back into a JS list for the + `drawcustom` service call (`CORE_SCHEMA` specifically, so a bare `y:` key + parses as the string `"y"`, not a YAML-1.1 boolean). + +Home Assistant custom components cannot `npm install` at runtime, so neither +can be a normal `package.json` dependency here. Instead both are vendored +**from** npm — a pinned, verifiable download for each — rather than the old +procedure (pre-2026-08-30) of dropping in an unlabelled release build by +hand for the designer, and an unpinned jsDelivr-rebundled blob (no +integrity record, no `THIRD_PARTY.md` entry) for `js-yaml`. + +## Files + +| File | Source | +|------|--------| +| `odl-drawcustom-designer.js` | the designer library's self-contained ESM build | +| `odl-drawcustom-designer.d.ts` | its bundled TypeScript declarations (reference only — nothing here type-checks against it at build time; useful when editing the panel by hand) | +| `LICENSE`, `NOTICE`, `THIRD_PARTY.md` | the designer library's own licensing files (Apache-2.0) — `THIRD_PARTY.md` covers the designer's *own* transitive dependencies (auto-generated by the designer's own build tooling), not `js-yaml` (a sibling dependency of this panel, not of the designer bundle — never hand-added to that file) | +| `js-yaml.mjs` | `js-yaml`'s own npm-published ESM build (`dist/js-yaml.mjs`) | +| `LICENSE.js-yaml` | `js-yaml`'s own MIT license text (kept separate from the designer's `LICENSE`, which is a different package under a different license) | +| `designer.lock.json` | **both pins** — `{"designer": {"version", "integrity"}, "js_yaml": {"version", "integrity"}}`. This one file is the entire "what version, verified how" record for both packages; every file above is fully derived from it and none are ever hand-edited | + +## Updating + +```bash +# Re-download and re-verify BOTH currently pinned packages (idempotent — +# safe to re-run any time, e.g. to recover a corrupted vendor/ checkout): +scripts/update-designer-vendor.py + +# Bump the designer library to a new released version: +scripts/update-designer-vendor.py --pin 2.7.0 + +# Bump js-yaml to a new released version: +scripts/update-designer-vendor.py --pin-js-yaml 4.1.1 + +git diff custom_components/opendisplay/designer/frontend/vendor/ +``` + +`--pin`/`--pin-js-yaml` fetch that version's metadata from the npm registry +(the registry's own declared `sha512` `dist.integrity`), download the +tarball, and verify the **actual** downloaded bytes against that declared +hash before writing anything — the registry lookup is the one place this +procedure trusts npm (the same trust boundary `npm install` itself has). +Every subsequent run (with or without a `--pin*` flag) re-verifies against +the value now pinned in `designer.lock.json`, not against the registry +again. + +A mismatch (corrupted download, tampered mirror, wrong version) exits +non-zero and writes nothing — the vendored files stay exactly as they were. +There is no silent fallback to an unverified tarball. + +After bumping the designer's pin, review the diff of +`odl-drawcustom-designer.d.ts` against the panel's own API usage in +`../panel/opendisplay-designer-panel.js` — that file is hand-written against +the 2.x host contract (`docs/embedding.md` in the designer's own repo) and is +not regenerated by this script. diff --git a/custom_components/opendisplay/designer/frontend/vendor/THIRD_PARTY.md b/custom_components/opendisplay/designer/frontend/vendor/THIRD_PARTY.md new file mode 100644 index 00000000..b030e249 --- /dev/null +++ b/custom_components/opendisplay/designer/frontend/vendor/THIRD_PARTY.md @@ -0,0 +1,79 @@ +# Third-party notices (bundled dependencies) + +Auto-generated by `tools/thirdPartyNotices.ts` for the odl-drawcustom-designer +library build — every package listed here, direct or transitive, is compiled +into the single `odl-drawcustom-designer.js` ESM. For the repository's +broader attribution (vendored docs, fonts, non-bundled upstream ecosystems) +see [`docs/THIRD_PARTY.md`](https://github.com/schlomo/odl-drawcustom-designer/blob/main/docs/THIRD_PARTY.md). + +| Package | Version | License | Link | +|---|---|---|---| +| @codemirror/autocomplete | 6.20.3 | MIT | git+https://code.haverbeke.berlin/codemirror/autocomplete.git | +| @codemirror/commands | 6.10.4 | MIT | git+https://code.haverbeke.berlin/codemirror/commands.git | +| @codemirror/lang-css | 6.3.1 | MIT | https://github.com/codemirror/lang-css.git | +| @codemirror/lang-html | 6.4.11 | MIT | https://github.com/codemirror/lang-html.git | +| @codemirror/lang-javascript | 6.2.5 | MIT | git+https://github.com/codemirror/lang-javascript.git | +| @codemirror/lang-jinja | 6.0.1 | MIT | git+https://code.haverbeke.berlin/codemirror/lang-jinja.git | +| @codemirror/lang-yaml | 6.1.3 | MIT | git+https://github.com/codemirror/lang-yaml.git | +| @codemirror/language | 6.12.4 | MIT | git+https://code.haverbeke.berlin/codemirror/language.git | +| @codemirror/lint | 6.9.7 | MIT | git+https://code.haverbeke.berlin/codemirror/lint.git | +| @codemirror/search | 6.7.1 | MIT | git+https://code.haverbeke.berlin/codemirror/search.git | +| @codemirror/state | 6.7.1 | MIT | git+https://code.haverbeke.berlin/codemirror/state.git | +| @codemirror/theme-one-dark | 6.1.3 | MIT | https://github.com/codemirror/theme-one-dark.git | +| @codemirror/view | 6.43.8 | MIT | git+https://code.haverbeke.berlin/codemirror/view.git | +| @lezer/common | 1.5.2 | MIT | https://github.com/lezer-parser/common.git | +| @lezer/css | 1.3.3 | MIT | https://github.com/lezer-parser/css.git | +| @lezer/highlight | 1.2.3 | MIT | https://github.com/lezer-parser/highlight.git | +| @lezer/html | 1.3.13 | MIT | https://github.com/lezer-parser/html.git | +| @lezer/javascript | 1.5.4 | MIT | https://github.com/lezer-parser/javascript.git | +| @lezer/lr | 1.4.10 | MIT | git+https://code.haverbeke.berlin/lezer/lr.git | +| @lezer/yaml | 1.0.4 | MIT | https://github.com/lezer-parser/yaml.git | +| @marijn/find-cluster-break | 1.0.2 | MIT | https://github.com/marijnh/find-cluster-break#readme | +| @mdi/js | 7.4.47 | Apache-2.0 | https://github.com/Templarian/MaterialDesign-JS#readme | +| @uiw/codemirror-extensions-basic-setup | 4.25.11 | MIT | https://uiwjs.github.io/react-codemirror/#/extensions/basic-setup | +| a-sync-waterfall | 1.0.1 | MIT | https://github.com/hydiak/a-sync-waterfall | +| ansi-regex | 5.0.1 | MIT | | +| ansi-styles | 4.3.0 | MIT | | +| asap | 2.0.6 | MIT | https://github.com/kriskowal/asap.git | +| bidi-js | 1.0.3 | MIT | https://github.com/lojjic/bidi-js.git | +| camelcase | 5.3.1 | MIT | | +| cliui | 6.0.0 | ISC | http://github.com/yargs/cliui.git | +| color-convert | 2.0.1 | MIT | | +| color-name | 1.1.4 | MIT | https://github.com/colorjs/color-name | +| commander | 5.1.0 | MIT | https://github.com/tj/commander.js.git | +| crelt | 1.0.6 | MIT | https://github.com/marijnh/crelt#readme | +| decamelize | 1.2.0 | MIT | | +| dexie | 4.4.5 | Apache-2.0 | https://dexie.org | +| dijkstrajs | 1.0.3 | MIT | https://github.com/tcort/dijkstrajs | +| emoji-regex | 8.0.0 | MIT | https://mths.be/emoji-regex | +| find-up | 4.1.0 | MIT | | +| get-caller-file | 2.0.5 | ISC | https://github.com/stefanpenner/get-caller-file#readme | +| is-fullwidth-code-point | 3.0.0 | MIT | | +| locate-path | 5.0.0 | MIT | | +| nunjucks | 3.2.4 | BSD-2-Clause | https://github.com/mozilla/nunjucks.git | +| opentype.js | 2.0.0 | MIT | git://github.com/opentypejs/opentype.js.git | +| p-limit | 2.3.0 | MIT | | +| p-locate | 4.1.0 | MIT | | +| p-try | 2.2.0 | MIT | | +| pako | 3.0.1 | (MIT AND Zlib) | | +| path-exists | 4.0.0 | MIT | | +| pngjs | 5.0.0 | MIT | https://github.com/lukeapage/pngjs | +| qrcode | 1.5.4 | MIT | http://github.com/soldair/node-qrcode | +| react | 19.2.8 | MIT | https://react.dev/ | +| react-dom | 19.2.8 | MIT | https://react.dev/ | +| require-directory | 2.1.1 | MIT | https://github.com/troygoode/node-require-directory/ | +| require-from-string | 2.0.2 | MIT | | +| require-main-filename | 2.0.0 | ISC | https://github.com/yargs/require-main-filename#readme | +| scheduler | 0.27.0 | MIT | https://react.dev/ | +| set-blocking | 2.0.0 | ISC | https://github.com/yargs/set-blocking#readme | +| string-width | 4.2.3 | MIT | | +| strip-ansi | 6.0.1 | MIT | | +| style-mod | 4.1.3 | MIT | git+https://github.com/marijnh/style-mod.git | +| w3c-keyname | 2.2.8 | MIT | https://github.com/marijnh/w3c-keyname#readme | +| which-module | 2.0.1 | ISC | https://github.com/nexdrew/which-module#readme | +| wrap-ansi | 6.2.0 | MIT | | +| y18n | 4.0.3 | ISC | https://github.com/yargs/y18n | +| yaml | 2.9.0 | ISC | https://eemeli.org/yaml/ | +| yargs | 15.4.1 | MIT | https://yargs.js.org/ | +| yargs-parser | 18.1.3 | ISC | https://github.com/yargs/yargs-parser.git | +| zod | 4.4.3 | MIT | https://zod.dev | diff --git a/custom_components/opendisplay/designer/frontend/vendor/designer.lock.json b/custom_components/opendisplay/designer/frontend/vendor/designer.lock.json new file mode 100644 index 00000000..19b70ff0 --- /dev/null +++ b/custom_components/opendisplay/designer/frontend/vendor/designer.lock.json @@ -0,0 +1,10 @@ +{ + "designer": { + "version": "2.6.3", + "integrity": "sha512-c5KbWpKFGCtAOI/axM8Bs5Er4a276ZbzAaHppRfKEwK0ObDTmWwkFlXlZep+Oe1pH8hol/Z6TlVsOS5F3dVZVA==" + }, + "js_yaml": { + "version": "4.1.0", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==" + } +} diff --git a/custom_components/opendisplay/designer/frontend/vendor/js-yaml.mjs b/custom_components/opendisplay/designer/frontend/vendor/js-yaml.mjs new file mode 100644 index 00000000..be71cad1 --- /dev/null +++ b/custom_components/opendisplay/designer/frontend/vendor/js-yaml.mjs @@ -0,0 +1,3851 @@ + +/*! js-yaml 4.1.0 https://github.com/nodeca/js-yaml @license MIT */ +function isNothing(subject) { + return (typeof subject === 'undefined') || (subject === null); +} + + +function isObject(subject) { + return (typeof subject === 'object') && (subject !== null); +} + + +function toArray(sequence) { + if (Array.isArray(sequence)) return sequence; + else if (isNothing(sequence)) return []; + + return [ sequence ]; +} + + +function extend(target, source) { + var index, length, key, sourceKeys; + + if (source) { + sourceKeys = Object.keys(source); + + for (index = 0, length = sourceKeys.length; index < length; index += 1) { + key = sourceKeys[index]; + target[key] = source[key]; + } + } + + return target; +} + + +function repeat(string, count) { + var result = '', cycle; + + for (cycle = 0; cycle < count; cycle += 1) { + result += string; + } + + return result; +} + + +function isNegativeZero(number) { + return (number === 0) && (Number.NEGATIVE_INFINITY === 1 / number); +} + + +var isNothing_1 = isNothing; +var isObject_1 = isObject; +var toArray_1 = toArray; +var repeat_1 = repeat; +var isNegativeZero_1 = isNegativeZero; +var extend_1 = extend; + +var common = { + isNothing: isNothing_1, + isObject: isObject_1, + toArray: toArray_1, + repeat: repeat_1, + isNegativeZero: isNegativeZero_1, + extend: extend_1 +}; + +// YAML error class. http://stackoverflow.com/questions/8458984 + + +function formatError(exception, compact) { + var where = '', message = exception.reason || '(unknown reason)'; + + if (!exception.mark) return message; + + if (exception.mark.name) { + where += 'in "' + exception.mark.name + '" '; + } + + where += '(' + (exception.mark.line + 1) + ':' + (exception.mark.column + 1) + ')'; + + if (!compact && exception.mark.snippet) { + where += '\n\n' + exception.mark.snippet; + } + + return message + ' ' + where; +} + + +function YAMLException$1(reason, mark) { + // Super constructor + Error.call(this); + + this.name = 'YAMLException'; + this.reason = reason; + this.mark = mark; + this.message = formatError(this, false); + + // Include stack trace in error object + if (Error.captureStackTrace) { + // Chrome and NodeJS + Error.captureStackTrace(this, this.constructor); + } else { + // FF, IE 10+ and Safari 6+. Fallback for others + this.stack = (new Error()).stack || ''; + } +} + + +// Inherit from Error +YAMLException$1.prototype = Object.create(Error.prototype); +YAMLException$1.prototype.constructor = YAMLException$1; + + +YAMLException$1.prototype.toString = function toString(compact) { + return this.name + ': ' + formatError(this, compact); +}; + + +var exception = YAMLException$1; + +// get snippet for a single line, respecting maxLength +function getLine(buffer, lineStart, lineEnd, position, maxLineLength) { + var head = ''; + var tail = ''; + var maxHalfLength = Math.floor(maxLineLength / 2) - 1; + + if (position - lineStart > maxHalfLength) { + head = ' ... '; + lineStart = position - maxHalfLength + head.length; + } + + if (lineEnd - position > maxHalfLength) { + tail = ' ...'; + lineEnd = position + maxHalfLength - tail.length; + } + + return { + str: head + buffer.slice(lineStart, lineEnd).replace(/\t/g, '→') + tail, + pos: position - lineStart + head.length // relative position + }; +} + + +function padStart(string, max) { + return common.repeat(' ', max - string.length) + string; +} + + +function makeSnippet(mark, options) { + options = Object.create(options || null); + + if (!mark.buffer) return null; + + if (!options.maxLength) options.maxLength = 79; + if (typeof options.indent !== 'number') options.indent = 1; + if (typeof options.linesBefore !== 'number') options.linesBefore = 3; + if (typeof options.linesAfter !== 'number') options.linesAfter = 2; + + var re = /\r?\n|\r|\0/g; + var lineStarts = [ 0 ]; + var lineEnds = []; + var match; + var foundLineNo = -1; + + while ((match = re.exec(mark.buffer))) { + lineEnds.push(match.index); + lineStarts.push(match.index + match[0].length); + + if (mark.position <= match.index && foundLineNo < 0) { + foundLineNo = lineStarts.length - 2; + } + } + + if (foundLineNo < 0) foundLineNo = lineStarts.length - 1; + + var result = '', i, line; + var lineNoLength = Math.min(mark.line + options.linesAfter, lineEnds.length).toString().length; + var maxLineLength = options.maxLength - (options.indent + lineNoLength + 3); + + for (i = 1; i <= options.linesBefore; i++) { + if (foundLineNo - i < 0) break; + line = getLine( + mark.buffer, + lineStarts[foundLineNo - i], + lineEnds[foundLineNo - i], + mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo - i]), + maxLineLength + ); + result = common.repeat(' ', options.indent) + padStart((mark.line - i + 1).toString(), lineNoLength) + + ' | ' + line.str + '\n' + result; + } + + line = getLine(mark.buffer, lineStarts[foundLineNo], lineEnds[foundLineNo], mark.position, maxLineLength); + result += common.repeat(' ', options.indent) + padStart((mark.line + 1).toString(), lineNoLength) + + ' | ' + line.str + '\n'; + result += common.repeat('-', options.indent + lineNoLength + 3 + line.pos) + '^' + '\n'; + + for (i = 1; i <= options.linesAfter; i++) { + if (foundLineNo + i >= lineEnds.length) break; + line = getLine( + mark.buffer, + lineStarts[foundLineNo + i], + lineEnds[foundLineNo + i], + mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo + i]), + maxLineLength + ); + result += common.repeat(' ', options.indent) + padStart((mark.line + i + 1).toString(), lineNoLength) + + ' | ' + line.str + '\n'; + } + + return result.replace(/\n$/, ''); +} + + +var snippet = makeSnippet; + +var TYPE_CONSTRUCTOR_OPTIONS = [ + 'kind', + 'multi', + 'resolve', + 'construct', + 'instanceOf', + 'predicate', + 'represent', + 'representName', + 'defaultStyle', + 'styleAliases' +]; + +var YAML_NODE_KINDS = [ + 'scalar', + 'sequence', + 'mapping' +]; + +function compileStyleAliases(map) { + var result = {}; + + if (map !== null) { + Object.keys(map).forEach(function (style) { + map[style].forEach(function (alias) { + result[String(alias)] = style; + }); + }); + } + + return result; +} + +function Type$1(tag, options) { + options = options || {}; + + Object.keys(options).forEach(function (name) { + if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) { + throw new exception('Unknown option "' + name + '" is met in definition of "' + tag + '" YAML type.'); + } + }); + + // TODO: Add tag format check. + this.options = options; // keep original options in case user wants to extend this type later + this.tag = tag; + this.kind = options['kind'] || null; + this.resolve = options['resolve'] || function () { return true; }; + this.construct = options['construct'] || function (data) { return data; }; + this.instanceOf = options['instanceOf'] || null; + this.predicate = options['predicate'] || null; + this.represent = options['represent'] || null; + this.representName = options['representName'] || null; + this.defaultStyle = options['defaultStyle'] || null; + this.multi = options['multi'] || false; + this.styleAliases = compileStyleAliases(options['styleAliases'] || null); + + if (YAML_NODE_KINDS.indexOf(this.kind) === -1) { + throw new exception('Unknown kind "' + this.kind + '" is specified for "' + tag + '" YAML type.'); + } +} + +var type = Type$1; + +/*eslint-disable max-len*/ + + + + + +function compileList(schema, name) { + var result = []; + + schema[name].forEach(function (currentType) { + var newIndex = result.length; + + result.forEach(function (previousType, previousIndex) { + if (previousType.tag === currentType.tag && + previousType.kind === currentType.kind && + previousType.multi === currentType.multi) { + + newIndex = previousIndex; + } + }); + + result[newIndex] = currentType; + }); + + return result; +} + + +function compileMap(/* lists... */) { + var result = { + scalar: {}, + sequence: {}, + mapping: {}, + fallback: {}, + multi: { + scalar: [], + sequence: [], + mapping: [], + fallback: [] + } + }, index, length; + + function collectType(type) { + if (type.multi) { + result.multi[type.kind].push(type); + result.multi['fallback'].push(type); + } else { + result[type.kind][type.tag] = result['fallback'][type.tag] = type; + } + } + + for (index = 0, length = arguments.length; index < length; index += 1) { + arguments[index].forEach(collectType); + } + return result; +} + + +function Schema$1(definition) { + return this.extend(definition); +} + + +Schema$1.prototype.extend = function extend(definition) { + var implicit = []; + var explicit = []; + + if (definition instanceof type) { + // Schema.extend(type) + explicit.push(definition); + + } else if (Array.isArray(definition)) { + // Schema.extend([ type1, type2, ... ]) + explicit = explicit.concat(definition); + + } else if (definition && (Array.isArray(definition.implicit) || Array.isArray(definition.explicit))) { + // Schema.extend({ explicit: [ type1, type2, ... ], implicit: [ type1, type2, ... ] }) + if (definition.implicit) implicit = implicit.concat(definition.implicit); + if (definition.explicit) explicit = explicit.concat(definition.explicit); + + } else { + throw new exception('Schema.extend argument should be a Type, [ Type ], ' + + 'or a schema definition ({ implicit: [...], explicit: [...] })'); + } + + implicit.forEach(function (type$1) { + if (!(type$1 instanceof type)) { + throw new exception('Specified list of YAML types (or a single Type object) contains a non-Type object.'); + } + + if (type$1.loadKind && type$1.loadKind !== 'scalar') { + throw new exception('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.'); + } + + if (type$1.multi) { + throw new exception('There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.'); + } + }); + + explicit.forEach(function (type$1) { + if (!(type$1 instanceof type)) { + throw new exception('Specified list of YAML types (or a single Type object) contains a non-Type object.'); + } + }); + + var result = Object.create(Schema$1.prototype); + + result.implicit = (this.implicit || []).concat(implicit); + result.explicit = (this.explicit || []).concat(explicit); + + result.compiledImplicit = compileList(result, 'implicit'); + result.compiledExplicit = compileList(result, 'explicit'); + result.compiledTypeMap = compileMap(result.compiledImplicit, result.compiledExplicit); + + return result; +}; + + +var schema = Schema$1; + +var str = new type('tag:yaml.org,2002:str', { + kind: 'scalar', + construct: function (data) { return data !== null ? data : ''; } +}); + +var seq = new type('tag:yaml.org,2002:seq', { + kind: 'sequence', + construct: function (data) { return data !== null ? data : []; } +}); + +var map = new type('tag:yaml.org,2002:map', { + kind: 'mapping', + construct: function (data) { return data !== null ? data : {}; } +}); + +var failsafe = new schema({ + explicit: [ + str, + seq, + map + ] +}); + +function resolveYamlNull(data) { + if (data === null) return true; + + var max = data.length; + + return (max === 1 && data === '~') || + (max === 4 && (data === 'null' || data === 'Null' || data === 'NULL')); +} + +function constructYamlNull() { + return null; +} + +function isNull(object) { + return object === null; +} + +var _null = new type('tag:yaml.org,2002:null', { + kind: 'scalar', + resolve: resolveYamlNull, + construct: constructYamlNull, + predicate: isNull, + represent: { + canonical: function () { return '~'; }, + lowercase: function () { return 'null'; }, + uppercase: function () { return 'NULL'; }, + camelcase: function () { return 'Null'; }, + empty: function () { return ''; } + }, + defaultStyle: 'lowercase' +}); + +function resolveYamlBoolean(data) { + if (data === null) return false; + + var max = data.length; + + return (max === 4 && (data === 'true' || data === 'True' || data === 'TRUE')) || + (max === 5 && (data === 'false' || data === 'False' || data === 'FALSE')); +} + +function constructYamlBoolean(data) { + return data === 'true' || + data === 'True' || + data === 'TRUE'; +} + +function isBoolean(object) { + return Object.prototype.toString.call(object) === '[object Boolean]'; +} + +var bool = new type('tag:yaml.org,2002:bool', { + kind: 'scalar', + resolve: resolveYamlBoolean, + construct: constructYamlBoolean, + predicate: isBoolean, + represent: { + lowercase: function (object) { return object ? 'true' : 'false'; }, + uppercase: function (object) { return object ? 'TRUE' : 'FALSE'; }, + camelcase: function (object) { return object ? 'True' : 'False'; } + }, + defaultStyle: 'lowercase' +}); + +function isHexCode(c) { + return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) || + ((0x41/* A */ <= c) && (c <= 0x46/* F */)) || + ((0x61/* a */ <= c) && (c <= 0x66/* f */)); +} + +function isOctCode(c) { + return ((0x30/* 0 */ <= c) && (c <= 0x37/* 7 */)); +} + +function isDecCode(c) { + return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)); +} + +function resolveYamlInteger(data) { + if (data === null) return false; + + var max = data.length, + index = 0, + hasDigits = false, + ch; + + if (!max) return false; + + ch = data[index]; + + // sign + if (ch === '-' || ch === '+') { + ch = data[++index]; + } + + if (ch === '0') { + // 0 + if (index + 1 === max) return true; + ch = data[++index]; + + // base 2, base 8, base 16 + + if (ch === 'b') { + // base 2 + index++; + + for (; index < max; index++) { + ch = data[index]; + if (ch === '_') continue; + if (ch !== '0' && ch !== '1') return false; + hasDigits = true; + } + return hasDigits && ch !== '_'; + } + + + if (ch === 'x') { + // base 16 + index++; + + for (; index < max; index++) { + ch = data[index]; + if (ch === '_') continue; + if (!isHexCode(data.charCodeAt(index))) return false; + hasDigits = true; + } + return hasDigits && ch !== '_'; + } + + + if (ch === 'o') { + // base 8 + index++; + + for (; index < max; index++) { + ch = data[index]; + if (ch === '_') continue; + if (!isOctCode(data.charCodeAt(index))) return false; + hasDigits = true; + } + return hasDigits && ch !== '_'; + } + } + + // base 10 (except 0) + + // value should not start with `_`; + if (ch === '_') return false; + + for (; index < max; index++) { + ch = data[index]; + if (ch === '_') continue; + if (!isDecCode(data.charCodeAt(index))) { + return false; + } + hasDigits = true; + } + + // Should have digits and should not end with `_` + if (!hasDigits || ch === '_') return false; + + return true; +} + +function constructYamlInteger(data) { + var value = data, sign = 1, ch; + + if (value.indexOf('_') !== -1) { + value = value.replace(/_/g, ''); + } + + ch = value[0]; + + if (ch === '-' || ch === '+') { + if (ch === '-') sign = -1; + value = value.slice(1); + ch = value[0]; + } + + if (value === '0') return 0; + + if (ch === '0') { + if (value[1] === 'b') return sign * parseInt(value.slice(2), 2); + if (value[1] === 'x') return sign * parseInt(value.slice(2), 16); + if (value[1] === 'o') return sign * parseInt(value.slice(2), 8); + } + + return sign * parseInt(value, 10); +} + +function isInteger(object) { + return (Object.prototype.toString.call(object)) === '[object Number]' && + (object % 1 === 0 && !common.isNegativeZero(object)); +} + +var int = new type('tag:yaml.org,2002:int', { + kind: 'scalar', + resolve: resolveYamlInteger, + construct: constructYamlInteger, + predicate: isInteger, + represent: { + binary: function (obj) { return obj >= 0 ? '0b' + obj.toString(2) : '-0b' + obj.toString(2).slice(1); }, + octal: function (obj) { return obj >= 0 ? '0o' + obj.toString(8) : '-0o' + obj.toString(8).slice(1); }, + decimal: function (obj) { return obj.toString(10); }, + /* eslint-disable max-len */ + hexadecimal: function (obj) { return obj >= 0 ? '0x' + obj.toString(16).toUpperCase() : '-0x' + obj.toString(16).toUpperCase().slice(1); } + }, + defaultStyle: 'decimal', + styleAliases: { + binary: [ 2, 'bin' ], + octal: [ 8, 'oct' ], + decimal: [ 10, 'dec' ], + hexadecimal: [ 16, 'hex' ] + } +}); + +var YAML_FLOAT_PATTERN = new RegExp( + // 2.5e4, 2.5 and integers + '^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?' + + // .2e4, .2 + // special case, seems not from spec + '|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?' + + // .inf + '|[-+]?\\.(?:inf|Inf|INF)' + + // .nan + '|\\.(?:nan|NaN|NAN))$'); + +function resolveYamlFloat(data) { + if (data === null) return false; + + if (!YAML_FLOAT_PATTERN.test(data) || + // Quick hack to not allow integers end with `_` + // Probably should update regexp & check speed + data[data.length - 1] === '_') { + return false; + } + + return true; +} + +function constructYamlFloat(data) { + var value, sign; + + value = data.replace(/_/g, '').toLowerCase(); + sign = value[0] === '-' ? -1 : 1; + + if ('+-'.indexOf(value[0]) >= 0) { + value = value.slice(1); + } + + if (value === '.inf') { + return (sign === 1) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY; + + } else if (value === '.nan') { + return NaN; + } + return sign * parseFloat(value, 10); +} + + +var SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/; + +function representYamlFloat(object, style) { + var res; + + if (isNaN(object)) { + switch (style) { + case 'lowercase': return '.nan'; + case 'uppercase': return '.NAN'; + case 'camelcase': return '.NaN'; + } + } else if (Number.POSITIVE_INFINITY === object) { + switch (style) { + case 'lowercase': return '.inf'; + case 'uppercase': return '.INF'; + case 'camelcase': return '.Inf'; + } + } else if (Number.NEGATIVE_INFINITY === object) { + switch (style) { + case 'lowercase': return '-.inf'; + case 'uppercase': return '-.INF'; + case 'camelcase': return '-.Inf'; + } + } else if (common.isNegativeZero(object)) { + return '-0.0'; + } + + res = object.toString(10); + + // JS stringifier can build scientific format without dots: 5e-100, + // while YAML requres dot: 5.e-100. Fix it with simple hack + + return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace('e', '.e') : res; +} + +function isFloat(object) { + return (Object.prototype.toString.call(object) === '[object Number]') && + (object % 1 !== 0 || common.isNegativeZero(object)); +} + +var float = new type('tag:yaml.org,2002:float', { + kind: 'scalar', + resolve: resolveYamlFloat, + construct: constructYamlFloat, + predicate: isFloat, + represent: representYamlFloat, + defaultStyle: 'lowercase' +}); + +var json = failsafe.extend({ + implicit: [ + _null, + bool, + int, + float + ] +}); + +var core = json; + +var YAML_DATE_REGEXP = new RegExp( + '^([0-9][0-9][0-9][0-9])' + // [1] year + '-([0-9][0-9])' + // [2] month + '-([0-9][0-9])$'); // [3] day + +var YAML_TIMESTAMP_REGEXP = new RegExp( + '^([0-9][0-9][0-9][0-9])' + // [1] year + '-([0-9][0-9]?)' + // [2] month + '-([0-9][0-9]?)' + // [3] day + '(?:[Tt]|[ \\t]+)' + // ... + '([0-9][0-9]?)' + // [4] hour + ':([0-9][0-9])' + // [5] minute + ':([0-9][0-9])' + // [6] second + '(?:\\.([0-9]*))?' + // [7] fraction + '(?:[ \\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tz_hour + '(?::([0-9][0-9]))?))?$'); // [11] tz_minute + +function resolveYamlTimestamp(data) { + if (data === null) return false; + if (YAML_DATE_REGEXP.exec(data) !== null) return true; + if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true; + return false; +} + +function constructYamlTimestamp(data) { + var match, year, month, day, hour, minute, second, fraction = 0, + delta = null, tz_hour, tz_minute, date; + + match = YAML_DATE_REGEXP.exec(data); + if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data); + + if (match === null) throw new Error('Date resolve error'); + + // match: [1] year [2] month [3] day + + year = +(match[1]); + month = +(match[2]) - 1; // JS month starts with 0 + day = +(match[3]); + + if (!match[4]) { // no hour + return new Date(Date.UTC(year, month, day)); + } + + // match: [4] hour [5] minute [6] second [7] fraction + + hour = +(match[4]); + minute = +(match[5]); + second = +(match[6]); + + if (match[7]) { + fraction = match[7].slice(0, 3); + while (fraction.length < 3) { // milli-seconds + fraction += '0'; + } + fraction = +fraction; + } + + // match: [8] tz [9] tz_sign [10] tz_hour [11] tz_minute + + if (match[9]) { + tz_hour = +(match[10]); + tz_minute = +(match[11] || 0); + delta = (tz_hour * 60 + tz_minute) * 60000; // delta in mili-seconds + if (match[9] === '-') delta = -delta; + } + + date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction)); + + if (delta) date.setTime(date.getTime() - delta); + + return date; +} + +function representYamlTimestamp(object /*, style*/) { + return object.toISOString(); +} + +var timestamp = new type('tag:yaml.org,2002:timestamp', { + kind: 'scalar', + resolve: resolveYamlTimestamp, + construct: constructYamlTimestamp, + instanceOf: Date, + represent: representYamlTimestamp +}); + +function resolveYamlMerge(data) { + return data === '<<' || data === null; +} + +var merge = new type('tag:yaml.org,2002:merge', { + kind: 'scalar', + resolve: resolveYamlMerge +}); + +/*eslint-disable no-bitwise*/ + + + + + +// [ 64, 65, 66 ] -> [ padding, CR, LF ] +var BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r'; + + +function resolveYamlBinary(data) { + if (data === null) return false; + + var code, idx, bitlen = 0, max = data.length, map = BASE64_MAP; + + // Convert one by one. + for (idx = 0; idx < max; idx++) { + code = map.indexOf(data.charAt(idx)); + + // Skip CR/LF + if (code > 64) continue; + + // Fail on illegal characters + if (code < 0) return false; + + bitlen += 6; + } + + // If there are any bits left, source was corrupted + return (bitlen % 8) === 0; +} + +function constructYamlBinary(data) { + var idx, tailbits, + input = data.replace(/[\r\n=]/g, ''), // remove CR/LF & padding to simplify scan + max = input.length, + map = BASE64_MAP, + bits = 0, + result = []; + + // Collect by 6*4 bits (3 bytes) + + for (idx = 0; idx < max; idx++) { + if ((idx % 4 === 0) && idx) { + result.push((bits >> 16) & 0xFF); + result.push((bits >> 8) & 0xFF); + result.push(bits & 0xFF); + } + + bits = (bits << 6) | map.indexOf(input.charAt(idx)); + } + + // Dump tail + + tailbits = (max % 4) * 6; + + if (tailbits === 0) { + result.push((bits >> 16) & 0xFF); + result.push((bits >> 8) & 0xFF); + result.push(bits & 0xFF); + } else if (tailbits === 18) { + result.push((bits >> 10) & 0xFF); + result.push((bits >> 2) & 0xFF); + } else if (tailbits === 12) { + result.push((bits >> 4) & 0xFF); + } + + return new Uint8Array(result); +} + +function representYamlBinary(object /*, style*/) { + var result = '', bits = 0, idx, tail, + max = object.length, + map = BASE64_MAP; + + // Convert every three bytes to 4 ASCII characters. + + for (idx = 0; idx < max; idx++) { + if ((idx % 3 === 0) && idx) { + result += map[(bits >> 18) & 0x3F]; + result += map[(bits >> 12) & 0x3F]; + result += map[(bits >> 6) & 0x3F]; + result += map[bits & 0x3F]; + } + + bits = (bits << 8) + object[idx]; + } + + // Dump tail + + tail = max % 3; + + if (tail === 0) { + result += map[(bits >> 18) & 0x3F]; + result += map[(bits >> 12) & 0x3F]; + result += map[(bits >> 6) & 0x3F]; + result += map[bits & 0x3F]; + } else if (tail === 2) { + result += map[(bits >> 10) & 0x3F]; + result += map[(bits >> 4) & 0x3F]; + result += map[(bits << 2) & 0x3F]; + result += map[64]; + } else if (tail === 1) { + result += map[(bits >> 2) & 0x3F]; + result += map[(bits << 4) & 0x3F]; + result += map[64]; + result += map[64]; + } + + return result; +} + +function isBinary(obj) { + return Object.prototype.toString.call(obj) === '[object Uint8Array]'; +} + +var binary = new type('tag:yaml.org,2002:binary', { + kind: 'scalar', + resolve: resolveYamlBinary, + construct: constructYamlBinary, + predicate: isBinary, + represent: representYamlBinary +}); + +var _hasOwnProperty$3 = Object.prototype.hasOwnProperty; +var _toString$2 = Object.prototype.toString; + +function resolveYamlOmap(data) { + if (data === null) return true; + + var objectKeys = [], index, length, pair, pairKey, pairHasKey, + object = data; + + for (index = 0, length = object.length; index < length; index += 1) { + pair = object[index]; + pairHasKey = false; + + if (_toString$2.call(pair) !== '[object Object]') return false; + + for (pairKey in pair) { + if (_hasOwnProperty$3.call(pair, pairKey)) { + if (!pairHasKey) pairHasKey = true; + else return false; + } + } + + if (!pairHasKey) return false; + + if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey); + else return false; + } + + return true; +} + +function constructYamlOmap(data) { + return data !== null ? data : []; +} + +var omap = new type('tag:yaml.org,2002:omap', { + kind: 'sequence', + resolve: resolveYamlOmap, + construct: constructYamlOmap +}); + +var _toString$1 = Object.prototype.toString; + +function resolveYamlPairs(data) { + if (data === null) return true; + + var index, length, pair, keys, result, + object = data; + + result = new Array(object.length); + + for (index = 0, length = object.length; index < length; index += 1) { + pair = object[index]; + + if (_toString$1.call(pair) !== '[object Object]') return false; + + keys = Object.keys(pair); + + if (keys.length !== 1) return false; + + result[index] = [ keys[0], pair[keys[0]] ]; + } + + return true; +} + +function constructYamlPairs(data) { + if (data === null) return []; + + var index, length, pair, keys, result, + object = data; + + result = new Array(object.length); + + for (index = 0, length = object.length; index < length; index += 1) { + pair = object[index]; + + keys = Object.keys(pair); + + result[index] = [ keys[0], pair[keys[0]] ]; + } + + return result; +} + +var pairs = new type('tag:yaml.org,2002:pairs', { + kind: 'sequence', + resolve: resolveYamlPairs, + construct: constructYamlPairs +}); + +var _hasOwnProperty$2 = Object.prototype.hasOwnProperty; + +function resolveYamlSet(data) { + if (data === null) return true; + + var key, object = data; + + for (key in object) { + if (_hasOwnProperty$2.call(object, key)) { + if (object[key] !== null) return false; + } + } + + return true; +} + +function constructYamlSet(data) { + return data !== null ? data : {}; +} + +var set = new type('tag:yaml.org,2002:set', { + kind: 'mapping', + resolve: resolveYamlSet, + construct: constructYamlSet +}); + +var _default = core.extend({ + implicit: [ + timestamp, + merge + ], + explicit: [ + binary, + omap, + pairs, + set + ] +}); + +/*eslint-disable max-len,no-use-before-define*/ + + + + + + + +var _hasOwnProperty$1 = Object.prototype.hasOwnProperty; + + +var CONTEXT_FLOW_IN = 1; +var CONTEXT_FLOW_OUT = 2; +var CONTEXT_BLOCK_IN = 3; +var CONTEXT_BLOCK_OUT = 4; + + +var CHOMPING_CLIP = 1; +var CHOMPING_STRIP = 2; +var CHOMPING_KEEP = 3; + + +var PATTERN_NON_PRINTABLE = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/; +var PATTERN_NON_ASCII_LINE_BREAKS = /[\x85\u2028\u2029]/; +var PATTERN_FLOW_INDICATORS = /[,\[\]\{\}]/; +var PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\-]+!)$/i; +var PATTERN_TAG_URI = /^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i; + + +function _class(obj) { return Object.prototype.toString.call(obj); } + +function is_EOL(c) { + return (c === 0x0A/* LF */) || (c === 0x0D/* CR */); +} + +function is_WHITE_SPACE(c) { + return (c === 0x09/* Tab */) || (c === 0x20/* Space */); +} + +function is_WS_OR_EOL(c) { + return (c === 0x09/* Tab */) || + (c === 0x20/* Space */) || + (c === 0x0A/* LF */) || + (c === 0x0D/* CR */); +} + +function is_FLOW_INDICATOR(c) { + return c === 0x2C/* , */ || + c === 0x5B/* [ */ || + c === 0x5D/* ] */ || + c === 0x7B/* { */ || + c === 0x7D/* } */; +} + +function fromHexCode(c) { + var lc; + + if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) { + return c - 0x30; + } + + /*eslint-disable no-bitwise*/ + lc = c | 0x20; + + if ((0x61/* a */ <= lc) && (lc <= 0x66/* f */)) { + return lc - 0x61 + 10; + } + + return -1; +} + +function escapedHexLen(c) { + if (c === 0x78/* x */) { return 2; } + if (c === 0x75/* u */) { return 4; } + if (c === 0x55/* U */) { return 8; } + return 0; +} + +function fromDecimalCode(c) { + if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) { + return c - 0x30; + } + + return -1; +} + +function simpleEscapeSequence(c) { + /* eslint-disable indent */ + return (c === 0x30/* 0 */) ? '\x00' : + (c === 0x61/* a */) ? '\x07' : + (c === 0x62/* b */) ? '\x08' : + (c === 0x74/* t */) ? '\x09' : + (c === 0x09/* Tab */) ? '\x09' : + (c === 0x6E/* n */) ? '\x0A' : + (c === 0x76/* v */) ? '\x0B' : + (c === 0x66/* f */) ? '\x0C' : + (c === 0x72/* r */) ? '\x0D' : + (c === 0x65/* e */) ? '\x1B' : + (c === 0x20/* Space */) ? ' ' : + (c === 0x22/* " */) ? '\x22' : + (c === 0x2F/* / */) ? '/' : + (c === 0x5C/* \ */) ? '\x5C' : + (c === 0x4E/* N */) ? '\x85' : + (c === 0x5F/* _ */) ? '\xA0' : + (c === 0x4C/* L */) ? '\u2028' : + (c === 0x50/* P */) ? '\u2029' : ''; +} + +function charFromCodepoint(c) { + if (c <= 0xFFFF) { + return String.fromCharCode(c); + } + // Encode UTF-16 surrogate pair + // https://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B010000_to_U.2B10FFFF + return String.fromCharCode( + ((c - 0x010000) >> 10) + 0xD800, + ((c - 0x010000) & 0x03FF) + 0xDC00 + ); +} + +var simpleEscapeCheck = new Array(256); // integer, for fast access +var simpleEscapeMap = new Array(256); +for (var i = 0; i < 256; i++) { + simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0; + simpleEscapeMap[i] = simpleEscapeSequence(i); +} + + +function State$1(input, options) { + this.input = input; + + this.filename = options['filename'] || null; + this.schema = options['schema'] || _default; + this.onWarning = options['onWarning'] || null; + // (Hidden) Remove? makes the loader to expect YAML 1.1 documents + // if such documents have no explicit %YAML directive + this.legacy = options['legacy'] || false; + + this.json = options['json'] || false; + this.listener = options['listener'] || null; + + this.implicitTypes = this.schema.compiledImplicit; + this.typeMap = this.schema.compiledTypeMap; + + this.length = input.length; + this.position = 0; + this.line = 0; + this.lineStart = 0; + this.lineIndent = 0; + + // position of first leading tab in the current line, + // used to make sure there are no tabs in the indentation + this.firstTabInLine = -1; + + this.documents = []; + + /* + this.version; + this.checkLineBreaks; + this.tagMap; + this.anchorMap; + this.tag; + this.anchor; + this.kind; + this.result;*/ + +} + + +function generateError(state, message) { + var mark = { + name: state.filename, + buffer: state.input.slice(0, -1), // omit trailing \0 + position: state.position, + line: state.line, + column: state.position - state.lineStart + }; + + mark.snippet = snippet(mark); + + return new exception(message, mark); +} + +function throwError(state, message) { + throw generateError(state, message); +} + +function throwWarning(state, message) { + if (state.onWarning) { + state.onWarning.call(null, generateError(state, message)); + } +} + + +var directiveHandlers = { + + YAML: function handleYamlDirective(state, name, args) { + + var match, major, minor; + + if (state.version !== null) { + throwError(state, 'duplication of %YAML directive'); + } + + if (args.length !== 1) { + throwError(state, 'YAML directive accepts exactly one argument'); + } + + match = /^([0-9]+)\.([0-9]+)$/.exec(args[0]); + + if (match === null) { + throwError(state, 'ill-formed argument of the YAML directive'); + } + + major = parseInt(match[1], 10); + minor = parseInt(match[2], 10); + + if (major !== 1) { + throwError(state, 'unacceptable YAML version of the document'); + } + + state.version = args[0]; + state.checkLineBreaks = (minor < 2); + + if (minor !== 1 && minor !== 2) { + throwWarning(state, 'unsupported YAML version of the document'); + } + }, + + TAG: function handleTagDirective(state, name, args) { + + var handle, prefix; + + if (args.length !== 2) { + throwError(state, 'TAG directive accepts exactly two arguments'); + } + + handle = args[0]; + prefix = args[1]; + + if (!PATTERN_TAG_HANDLE.test(handle)) { + throwError(state, 'ill-formed tag handle (first argument) of the TAG directive'); + } + + if (_hasOwnProperty$1.call(state.tagMap, handle)) { + throwError(state, 'there is a previously declared suffix for "' + handle + '" tag handle'); + } + + if (!PATTERN_TAG_URI.test(prefix)) { + throwError(state, 'ill-formed tag prefix (second argument) of the TAG directive'); + } + + try { + prefix = decodeURIComponent(prefix); + } catch (err) { + throwError(state, 'tag prefix is malformed: ' + prefix); + } + + state.tagMap[handle] = prefix; + } +}; + + +function captureSegment(state, start, end, checkJson) { + var _position, _length, _character, _result; + + if (start < end) { + _result = state.input.slice(start, end); + + if (checkJson) { + for (_position = 0, _length = _result.length; _position < _length; _position += 1) { + _character = _result.charCodeAt(_position); + if (!(_character === 0x09 || + (0x20 <= _character && _character <= 0x10FFFF))) { + throwError(state, 'expected valid JSON character'); + } + } + } else if (PATTERN_NON_PRINTABLE.test(_result)) { + throwError(state, 'the stream contains non-printable characters'); + } + + state.result += _result; + } +} + +function mergeMappings(state, destination, source, overridableKeys) { + var sourceKeys, key, index, quantity; + + if (!common.isObject(source)) { + throwError(state, 'cannot merge mappings; the provided source object is unacceptable'); + } + + sourceKeys = Object.keys(source); + + for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) { + key = sourceKeys[index]; + + if (!_hasOwnProperty$1.call(destination, key)) { + destination[key] = source[key]; + overridableKeys[key] = true; + } + } +} + +function storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, + startLine, startLineStart, startPos) { + + var index, quantity; + + // The output is a plain object here, so keys can only be strings. + // We need to convert keyNode to a string, but doing so can hang the process + // (deeply nested arrays that explode exponentially using aliases). + if (Array.isArray(keyNode)) { + keyNode = Array.prototype.slice.call(keyNode); + + for (index = 0, quantity = keyNode.length; index < quantity; index += 1) { + if (Array.isArray(keyNode[index])) { + throwError(state, 'nested arrays are not supported inside keys'); + } + + if (typeof keyNode === 'object' && _class(keyNode[index]) === '[object Object]') { + keyNode[index] = '[object Object]'; + } + } + } + + // Avoid code execution in load() via toString property + // (still use its own toString for arrays, timestamps, + // and whatever user schema extensions happen to have @@toStringTag) + if (typeof keyNode === 'object' && _class(keyNode) === '[object Object]') { + keyNode = '[object Object]'; + } + + + keyNode = String(keyNode); + + if (_result === null) { + _result = {}; + } + + if (keyTag === 'tag:yaml.org,2002:merge') { + if (Array.isArray(valueNode)) { + for (index = 0, quantity = valueNode.length; index < quantity; index += 1) { + mergeMappings(state, _result, valueNode[index], overridableKeys); + } + } else { + mergeMappings(state, _result, valueNode, overridableKeys); + } + } else { + if (!state.json && + !_hasOwnProperty$1.call(overridableKeys, keyNode) && + _hasOwnProperty$1.call(_result, keyNode)) { + state.line = startLine || state.line; + state.lineStart = startLineStart || state.lineStart; + state.position = startPos || state.position; + throwError(state, 'duplicated mapping key'); + } + + // used for this specific key only because Object.defineProperty is slow + if (keyNode === '__proto__') { + Object.defineProperty(_result, keyNode, { + configurable: true, + enumerable: true, + writable: true, + value: valueNode + }); + } else { + _result[keyNode] = valueNode; + } + delete overridableKeys[keyNode]; + } + + return _result; +} + +function readLineBreak(state) { + var ch; + + ch = state.input.charCodeAt(state.position); + + if (ch === 0x0A/* LF */) { + state.position++; + } else if (ch === 0x0D/* CR */) { + state.position++; + if (state.input.charCodeAt(state.position) === 0x0A/* LF */) { + state.position++; + } + } else { + throwError(state, 'a line break is expected'); + } + + state.line += 1; + state.lineStart = state.position; + state.firstTabInLine = -1; +} + +function skipSeparationSpace(state, allowComments, checkIndent) { + var lineBreaks = 0, + ch = state.input.charCodeAt(state.position); + + while (ch !== 0) { + while (is_WHITE_SPACE(ch)) { + if (ch === 0x09/* Tab */ && state.firstTabInLine === -1) { + state.firstTabInLine = state.position; + } + ch = state.input.charCodeAt(++state.position); + } + + if (allowComments && ch === 0x23/* # */) { + do { + ch = state.input.charCodeAt(++state.position); + } while (ch !== 0x0A/* LF */ && ch !== 0x0D/* CR */ && ch !== 0); + } + + if (is_EOL(ch)) { + readLineBreak(state); + + ch = state.input.charCodeAt(state.position); + lineBreaks++; + state.lineIndent = 0; + + while (ch === 0x20/* Space */) { + state.lineIndent++; + ch = state.input.charCodeAt(++state.position); + } + } else { + break; + } + } + + if (checkIndent !== -1 && lineBreaks !== 0 && state.lineIndent < checkIndent) { + throwWarning(state, 'deficient indentation'); + } + + return lineBreaks; +} + +function testDocumentSeparator(state) { + var _position = state.position, + ch; + + ch = state.input.charCodeAt(_position); + + // Condition state.position === state.lineStart is tested + // in parent on each call, for efficiency. No needs to test here again. + if ((ch === 0x2D/* - */ || ch === 0x2E/* . */) && + ch === state.input.charCodeAt(_position + 1) && + ch === state.input.charCodeAt(_position + 2)) { + + _position += 3; + + ch = state.input.charCodeAt(_position); + + if (ch === 0 || is_WS_OR_EOL(ch)) { + return true; + } + } + + return false; +} + +function writeFoldedLines(state, count) { + if (count === 1) { + state.result += ' '; + } else if (count > 1) { + state.result += common.repeat('\n', count - 1); + } +} + + +function readPlainScalar(state, nodeIndent, withinFlowCollection) { + var preceding, + following, + captureStart, + captureEnd, + hasPendingContent, + _line, + _lineStart, + _lineIndent, + _kind = state.kind, + _result = state.result, + ch; + + ch = state.input.charCodeAt(state.position); + + if (is_WS_OR_EOL(ch) || + is_FLOW_INDICATOR(ch) || + ch === 0x23/* # */ || + ch === 0x26/* & */ || + ch === 0x2A/* * */ || + ch === 0x21/* ! */ || + ch === 0x7C/* | */ || + ch === 0x3E/* > */ || + ch === 0x27/* ' */ || + ch === 0x22/* " */ || + ch === 0x25/* % */ || + ch === 0x40/* @ */ || + ch === 0x60/* ` */) { + return false; + } + + if (ch === 0x3F/* ? */ || ch === 0x2D/* - */) { + following = state.input.charCodeAt(state.position + 1); + + if (is_WS_OR_EOL(following) || + withinFlowCollection && is_FLOW_INDICATOR(following)) { + return false; + } + } + + state.kind = 'scalar'; + state.result = ''; + captureStart = captureEnd = state.position; + hasPendingContent = false; + + while (ch !== 0) { + if (ch === 0x3A/* : */) { + following = state.input.charCodeAt(state.position + 1); + + if (is_WS_OR_EOL(following) || + withinFlowCollection && is_FLOW_INDICATOR(following)) { + break; + } + + } else if (ch === 0x23/* # */) { + preceding = state.input.charCodeAt(state.position - 1); + + if (is_WS_OR_EOL(preceding)) { + break; + } + + } else if ((state.position === state.lineStart && testDocumentSeparator(state)) || + withinFlowCollection && is_FLOW_INDICATOR(ch)) { + break; + + } else if (is_EOL(ch)) { + _line = state.line; + _lineStart = state.lineStart; + _lineIndent = state.lineIndent; + skipSeparationSpace(state, false, -1); + + if (state.lineIndent >= nodeIndent) { + hasPendingContent = true; + ch = state.input.charCodeAt(state.position); + continue; + } else { + state.position = captureEnd; + state.line = _line; + state.lineStart = _lineStart; + state.lineIndent = _lineIndent; + break; + } + } + + if (hasPendingContent) { + captureSegment(state, captureStart, captureEnd, false); + writeFoldedLines(state, state.line - _line); + captureStart = captureEnd = state.position; + hasPendingContent = false; + } + + if (!is_WHITE_SPACE(ch)) { + captureEnd = state.position + 1; + } + + ch = state.input.charCodeAt(++state.position); + } + + captureSegment(state, captureStart, captureEnd, false); + + if (state.result) { + return true; + } + + state.kind = _kind; + state.result = _result; + return false; +} + +function readSingleQuotedScalar(state, nodeIndent) { + var ch, + captureStart, captureEnd; + + ch = state.input.charCodeAt(state.position); + + if (ch !== 0x27/* ' */) { + return false; + } + + state.kind = 'scalar'; + state.result = ''; + state.position++; + captureStart = captureEnd = state.position; + + while ((ch = state.input.charCodeAt(state.position)) !== 0) { + if (ch === 0x27/* ' */) { + captureSegment(state, captureStart, state.position, true); + ch = state.input.charCodeAt(++state.position); + + if (ch === 0x27/* ' */) { + captureStart = state.position; + state.position++; + captureEnd = state.position; + } else { + return true; + } + + } else if (is_EOL(ch)) { + captureSegment(state, captureStart, captureEnd, true); + writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent)); + captureStart = captureEnd = state.position; + + } else if (state.position === state.lineStart && testDocumentSeparator(state)) { + throwError(state, 'unexpected end of the document within a single quoted scalar'); + + } else { + state.position++; + captureEnd = state.position; + } + } + + throwError(state, 'unexpected end of the stream within a single quoted scalar'); +} + +function readDoubleQuotedScalar(state, nodeIndent) { + var captureStart, + captureEnd, + hexLength, + hexResult, + tmp, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch !== 0x22/* " */) { + return false; + } + + state.kind = 'scalar'; + state.result = ''; + state.position++; + captureStart = captureEnd = state.position; + + while ((ch = state.input.charCodeAt(state.position)) !== 0) { + if (ch === 0x22/* " */) { + captureSegment(state, captureStart, state.position, true); + state.position++; + return true; + + } else if (ch === 0x5C/* \ */) { + captureSegment(state, captureStart, state.position, true); + ch = state.input.charCodeAt(++state.position); + + if (is_EOL(ch)) { + skipSeparationSpace(state, false, nodeIndent); + + // TODO: rework to inline fn with no type cast? + } else if (ch < 256 && simpleEscapeCheck[ch]) { + state.result += simpleEscapeMap[ch]; + state.position++; + + } else if ((tmp = escapedHexLen(ch)) > 0) { + hexLength = tmp; + hexResult = 0; + + for (; hexLength > 0; hexLength--) { + ch = state.input.charCodeAt(++state.position); + + if ((tmp = fromHexCode(ch)) >= 0) { + hexResult = (hexResult << 4) + tmp; + + } else { + throwError(state, 'expected hexadecimal character'); + } + } + + state.result += charFromCodepoint(hexResult); + + state.position++; + + } else { + throwError(state, 'unknown escape sequence'); + } + + captureStart = captureEnd = state.position; + + } else if (is_EOL(ch)) { + captureSegment(state, captureStart, captureEnd, true); + writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent)); + captureStart = captureEnd = state.position; + + } else if (state.position === state.lineStart && testDocumentSeparator(state)) { + throwError(state, 'unexpected end of the document within a double quoted scalar'); + + } else { + state.position++; + captureEnd = state.position; + } + } + + throwError(state, 'unexpected end of the stream within a double quoted scalar'); +} + +function readFlowCollection(state, nodeIndent) { + var readNext = true, + _line, + _lineStart, + _pos, + _tag = state.tag, + _result, + _anchor = state.anchor, + following, + terminator, + isPair, + isExplicitPair, + isMapping, + overridableKeys = Object.create(null), + keyNode, + keyTag, + valueNode, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch === 0x5B/* [ */) { + terminator = 0x5D;/* ] */ + isMapping = false; + _result = []; + } else if (ch === 0x7B/* { */) { + terminator = 0x7D;/* } */ + isMapping = true; + _result = {}; + } else { + return false; + } + + if (state.anchor !== null) { + state.anchorMap[state.anchor] = _result; + } + + ch = state.input.charCodeAt(++state.position); + + while (ch !== 0) { + skipSeparationSpace(state, true, nodeIndent); + + ch = state.input.charCodeAt(state.position); + + if (ch === terminator) { + state.position++; + state.tag = _tag; + state.anchor = _anchor; + state.kind = isMapping ? 'mapping' : 'sequence'; + state.result = _result; + return true; + } else if (!readNext) { + throwError(state, 'missed comma between flow collection entries'); + } else if (ch === 0x2C/* , */) { + // "flow collection entries can never be completely empty", as per YAML 1.2, section 7.4 + throwError(state, "expected the node content, but found ','"); + } + + keyTag = keyNode = valueNode = null; + isPair = isExplicitPair = false; + + if (ch === 0x3F/* ? */) { + following = state.input.charCodeAt(state.position + 1); + + if (is_WS_OR_EOL(following)) { + isPair = isExplicitPair = true; + state.position++; + skipSeparationSpace(state, true, nodeIndent); + } + } + + _line = state.line; // Save the current line. + _lineStart = state.lineStart; + _pos = state.position; + composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true); + keyTag = state.tag; + keyNode = state.result; + skipSeparationSpace(state, true, nodeIndent); + + ch = state.input.charCodeAt(state.position); + + if ((isExplicitPair || state.line === _line) && ch === 0x3A/* : */) { + isPair = true; + ch = state.input.charCodeAt(++state.position); + skipSeparationSpace(state, true, nodeIndent); + composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true); + valueNode = state.result; + } + + if (isMapping) { + storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos); + } else if (isPair) { + _result.push(storeMappingPair(state, null, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos)); + } else { + _result.push(keyNode); + } + + skipSeparationSpace(state, true, nodeIndent); + + ch = state.input.charCodeAt(state.position); + + if (ch === 0x2C/* , */) { + readNext = true; + ch = state.input.charCodeAt(++state.position); + } else { + readNext = false; + } + } + + throwError(state, 'unexpected end of the stream within a flow collection'); +} + +function readBlockScalar(state, nodeIndent) { + var captureStart, + folding, + chomping = CHOMPING_CLIP, + didReadContent = false, + detectedIndent = false, + textIndent = nodeIndent, + emptyLines = 0, + atMoreIndented = false, + tmp, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch === 0x7C/* | */) { + folding = false; + } else if (ch === 0x3E/* > */) { + folding = true; + } else { + return false; + } + + state.kind = 'scalar'; + state.result = ''; + + while (ch !== 0) { + ch = state.input.charCodeAt(++state.position); + + if (ch === 0x2B/* + */ || ch === 0x2D/* - */) { + if (CHOMPING_CLIP === chomping) { + chomping = (ch === 0x2B/* + */) ? CHOMPING_KEEP : CHOMPING_STRIP; + } else { + throwError(state, 'repeat of a chomping mode identifier'); + } + + } else if ((tmp = fromDecimalCode(ch)) >= 0) { + if (tmp === 0) { + throwError(state, 'bad explicit indentation width of a block scalar; it cannot be less than one'); + } else if (!detectedIndent) { + textIndent = nodeIndent + tmp - 1; + detectedIndent = true; + } else { + throwError(state, 'repeat of an indentation width identifier'); + } + + } else { + break; + } + } + + if (is_WHITE_SPACE(ch)) { + do { ch = state.input.charCodeAt(++state.position); } + while (is_WHITE_SPACE(ch)); + + if (ch === 0x23/* # */) { + do { ch = state.input.charCodeAt(++state.position); } + while (!is_EOL(ch) && (ch !== 0)); + } + } + + while (ch !== 0) { + readLineBreak(state); + state.lineIndent = 0; + + ch = state.input.charCodeAt(state.position); + + while ((!detectedIndent || state.lineIndent < textIndent) && + (ch === 0x20/* Space */)) { + state.lineIndent++; + ch = state.input.charCodeAt(++state.position); + } + + if (!detectedIndent && state.lineIndent > textIndent) { + textIndent = state.lineIndent; + } + + if (is_EOL(ch)) { + emptyLines++; + continue; + } + + // End of the scalar. + if (state.lineIndent < textIndent) { + + // Perform the chomping. + if (chomping === CHOMPING_KEEP) { + state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines); + } else if (chomping === CHOMPING_CLIP) { + if (didReadContent) { // i.e. only if the scalar is not empty. + state.result += '\n'; + } + } + + // Break this `while` cycle and go to the funciton's epilogue. + break; + } + + // Folded style: use fancy rules to handle line breaks. + if (folding) { + + // Lines starting with white space characters (more-indented lines) are not folded. + if (is_WHITE_SPACE(ch)) { + atMoreIndented = true; + // except for the first content line (cf. Example 8.1) + state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines); + + // End of more-indented block. + } else if (atMoreIndented) { + atMoreIndented = false; + state.result += common.repeat('\n', emptyLines + 1); + + // Just one line break - perceive as the same line. + } else if (emptyLines === 0) { + if (didReadContent) { // i.e. only if we have already read some scalar content. + state.result += ' '; + } + + // Several line breaks - perceive as different lines. + } else { + state.result += common.repeat('\n', emptyLines); + } + + // Literal style: just add exact number of line breaks between content lines. + } else { + // Keep all line breaks except the header line break. + state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines); + } + + didReadContent = true; + detectedIndent = true; + emptyLines = 0; + captureStart = state.position; + + while (!is_EOL(ch) && (ch !== 0)) { + ch = state.input.charCodeAt(++state.position); + } + + captureSegment(state, captureStart, state.position, false); + } + + return true; +} + +function readBlockSequence(state, nodeIndent) { + var _line, + _tag = state.tag, + _anchor = state.anchor, + _result = [], + following, + detected = false, + ch; + + // there is a leading tab before this token, so it can't be a block sequence/mapping; + // it can still be flow sequence/mapping or a scalar + if (state.firstTabInLine !== -1) return false; + + if (state.anchor !== null) { + state.anchorMap[state.anchor] = _result; + } + + ch = state.input.charCodeAt(state.position); + + while (ch !== 0) { + if (state.firstTabInLine !== -1) { + state.position = state.firstTabInLine; + throwError(state, 'tab characters must not be used in indentation'); + } + + if (ch !== 0x2D/* - */) { + break; + } + + following = state.input.charCodeAt(state.position + 1); + + if (!is_WS_OR_EOL(following)) { + break; + } + + detected = true; + state.position++; + + if (skipSeparationSpace(state, true, -1)) { + if (state.lineIndent <= nodeIndent) { + _result.push(null); + ch = state.input.charCodeAt(state.position); + continue; + } + } + + _line = state.line; + composeNode(state, nodeIndent, CONTEXT_BLOCK_IN, false, true); + _result.push(state.result); + skipSeparationSpace(state, true, -1); + + ch = state.input.charCodeAt(state.position); + + if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) { + throwError(state, 'bad indentation of a sequence entry'); + } else if (state.lineIndent < nodeIndent) { + break; + } + } + + if (detected) { + state.tag = _tag; + state.anchor = _anchor; + state.kind = 'sequence'; + state.result = _result; + return true; + } + return false; +} + +function readBlockMapping(state, nodeIndent, flowIndent) { + var following, + allowCompact, + _line, + _keyLine, + _keyLineStart, + _keyPos, + _tag = state.tag, + _anchor = state.anchor, + _result = {}, + overridableKeys = Object.create(null), + keyTag = null, + keyNode = null, + valueNode = null, + atExplicitKey = false, + detected = false, + ch; + + // there is a leading tab before this token, so it can't be a block sequence/mapping; + // it can still be flow sequence/mapping or a scalar + if (state.firstTabInLine !== -1) return false; + + if (state.anchor !== null) { + state.anchorMap[state.anchor] = _result; + } + + ch = state.input.charCodeAt(state.position); + + while (ch !== 0) { + if (!atExplicitKey && state.firstTabInLine !== -1) { + state.position = state.firstTabInLine; + throwError(state, 'tab characters must not be used in indentation'); + } + + following = state.input.charCodeAt(state.position + 1); + _line = state.line; // Save the current line. + + // + // Explicit notation case. There are two separate blocks: + // first for the key (denoted by "?") and second for the value (denoted by ":") + // + if ((ch === 0x3F/* ? */ || ch === 0x3A/* : */) && is_WS_OR_EOL(following)) { + + if (ch === 0x3F/* ? */) { + if (atExplicitKey) { + storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos); + keyTag = keyNode = valueNode = null; + } + + detected = true; + atExplicitKey = true; + allowCompact = true; + + } else if (atExplicitKey) { + // i.e. 0x3A/* : */ === character after the explicit key. + atExplicitKey = false; + allowCompact = true; + + } else { + throwError(state, 'incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line'); + } + + state.position += 1; + ch = following; + + // + // Implicit notation case. Flow-style node as the key first, then ":", and the value. + // + } else { + _keyLine = state.line; + _keyLineStart = state.lineStart; + _keyPos = state.position; + + if (!composeNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true)) { + // Neither implicit nor explicit notation. + // Reading is done. Go to the epilogue. + break; + } + + if (state.line === _line) { + ch = state.input.charCodeAt(state.position); + + while (is_WHITE_SPACE(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + if (ch === 0x3A/* : */) { + ch = state.input.charCodeAt(++state.position); + + if (!is_WS_OR_EOL(ch)) { + throwError(state, 'a whitespace character is expected after the key-value separator within a block mapping'); + } + + if (atExplicitKey) { + storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos); + keyTag = keyNode = valueNode = null; + } + + detected = true; + atExplicitKey = false; + allowCompact = false; + keyTag = state.tag; + keyNode = state.result; + + } else if (detected) { + throwError(state, 'can not read an implicit mapping pair; a colon is missed'); + + } else { + state.tag = _tag; + state.anchor = _anchor; + return true; // Keep the result of `composeNode`. + } + + } else if (detected) { + throwError(state, 'can not read a block mapping entry; a multiline key may not be an implicit key'); + + } else { + state.tag = _tag; + state.anchor = _anchor; + return true; // Keep the result of `composeNode`. + } + } + + // + // Common reading code for both explicit and implicit notations. + // + if (state.line === _line || state.lineIndent > nodeIndent) { + if (atExplicitKey) { + _keyLine = state.line; + _keyLineStart = state.lineStart; + _keyPos = state.position; + } + + if (composeNode(state, nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) { + if (atExplicitKey) { + keyNode = state.result; + } else { + valueNode = state.result; + } + } + + if (!atExplicitKey) { + storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _keyLine, _keyLineStart, _keyPos); + keyTag = keyNode = valueNode = null; + } + + skipSeparationSpace(state, true, -1); + ch = state.input.charCodeAt(state.position); + } + + if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) { + throwError(state, 'bad indentation of a mapping entry'); + } else if (state.lineIndent < nodeIndent) { + break; + } + } + + // + // Epilogue. + // + + // Special case: last mapping's node contains only the key in explicit notation. + if (atExplicitKey) { + storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos); + } + + // Expose the resulting mapping. + if (detected) { + state.tag = _tag; + state.anchor = _anchor; + state.kind = 'mapping'; + state.result = _result; + } + + return detected; +} + +function readTagProperty(state) { + var _position, + isVerbatim = false, + isNamed = false, + tagHandle, + tagName, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch !== 0x21/* ! */) return false; + + if (state.tag !== null) { + throwError(state, 'duplication of a tag property'); + } + + ch = state.input.charCodeAt(++state.position); + + if (ch === 0x3C/* < */) { + isVerbatim = true; + ch = state.input.charCodeAt(++state.position); + + } else if (ch === 0x21/* ! */) { + isNamed = true; + tagHandle = '!!'; + ch = state.input.charCodeAt(++state.position); + + } else { + tagHandle = '!'; + } + + _position = state.position; + + if (isVerbatim) { + do { ch = state.input.charCodeAt(++state.position); } + while (ch !== 0 && ch !== 0x3E/* > */); + + if (state.position < state.length) { + tagName = state.input.slice(_position, state.position); + ch = state.input.charCodeAt(++state.position); + } else { + throwError(state, 'unexpected end of the stream within a verbatim tag'); + } + } else { + while (ch !== 0 && !is_WS_OR_EOL(ch)) { + + if (ch === 0x21/* ! */) { + if (!isNamed) { + tagHandle = state.input.slice(_position - 1, state.position + 1); + + if (!PATTERN_TAG_HANDLE.test(tagHandle)) { + throwError(state, 'named tag handle cannot contain such characters'); + } + + isNamed = true; + _position = state.position + 1; + } else { + throwError(state, 'tag suffix cannot contain exclamation marks'); + } + } + + ch = state.input.charCodeAt(++state.position); + } + + tagName = state.input.slice(_position, state.position); + + if (PATTERN_FLOW_INDICATORS.test(tagName)) { + throwError(state, 'tag suffix cannot contain flow indicator characters'); + } + } + + if (tagName && !PATTERN_TAG_URI.test(tagName)) { + throwError(state, 'tag name cannot contain such characters: ' + tagName); + } + + try { + tagName = decodeURIComponent(tagName); + } catch (err) { + throwError(state, 'tag name is malformed: ' + tagName); + } + + if (isVerbatim) { + state.tag = tagName; + + } else if (_hasOwnProperty$1.call(state.tagMap, tagHandle)) { + state.tag = state.tagMap[tagHandle] + tagName; + + } else if (tagHandle === '!') { + state.tag = '!' + tagName; + + } else if (tagHandle === '!!') { + state.tag = 'tag:yaml.org,2002:' + tagName; + + } else { + throwError(state, 'undeclared tag handle "' + tagHandle + '"'); + } + + return true; +} + +function readAnchorProperty(state) { + var _position, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch !== 0x26/* & */) return false; + + if (state.anchor !== null) { + throwError(state, 'duplication of an anchor property'); + } + + ch = state.input.charCodeAt(++state.position); + _position = state.position; + + while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + if (state.position === _position) { + throwError(state, 'name of an anchor node must contain at least one character'); + } + + state.anchor = state.input.slice(_position, state.position); + return true; +} + +function readAlias(state) { + var _position, alias, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch !== 0x2A/* * */) return false; + + ch = state.input.charCodeAt(++state.position); + _position = state.position; + + while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + if (state.position === _position) { + throwError(state, 'name of an alias node must contain at least one character'); + } + + alias = state.input.slice(_position, state.position); + + if (!_hasOwnProperty$1.call(state.anchorMap, alias)) { + throwError(state, 'unidentified alias "' + alias + '"'); + } + + state.result = state.anchorMap[alias]; + skipSeparationSpace(state, true, -1); + return true; +} + +function composeNode(state, parentIndent, nodeContext, allowToSeek, allowCompact) { + var allowBlockStyles, + allowBlockScalars, + allowBlockCollections, + indentStatus = 1, // 1: this>parent, 0: this=parent, -1: this parentIndent) { + indentStatus = 1; + } else if (state.lineIndent === parentIndent) { + indentStatus = 0; + } else if (state.lineIndent < parentIndent) { + indentStatus = -1; + } + } + } + + if (indentStatus === 1) { + while (readTagProperty(state) || readAnchorProperty(state)) { + if (skipSeparationSpace(state, true, -1)) { + atNewLine = true; + allowBlockCollections = allowBlockStyles; + + if (state.lineIndent > parentIndent) { + indentStatus = 1; + } else if (state.lineIndent === parentIndent) { + indentStatus = 0; + } else if (state.lineIndent < parentIndent) { + indentStatus = -1; + } + } else { + allowBlockCollections = false; + } + } + } + + if (allowBlockCollections) { + allowBlockCollections = atNewLine || allowCompact; + } + + if (indentStatus === 1 || CONTEXT_BLOCK_OUT === nodeContext) { + if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) { + flowIndent = parentIndent; + } else { + flowIndent = parentIndent + 1; + } + + blockIndent = state.position - state.lineStart; + + if (indentStatus === 1) { + if (allowBlockCollections && + (readBlockSequence(state, blockIndent) || + readBlockMapping(state, blockIndent, flowIndent)) || + readFlowCollection(state, flowIndent)) { + hasContent = true; + } else { + if ((allowBlockScalars && readBlockScalar(state, flowIndent)) || + readSingleQuotedScalar(state, flowIndent) || + readDoubleQuotedScalar(state, flowIndent)) { + hasContent = true; + + } else if (readAlias(state)) { + hasContent = true; + + if (state.tag !== null || state.anchor !== null) { + throwError(state, 'alias node should not have any properties'); + } + + } else if (readPlainScalar(state, flowIndent, CONTEXT_FLOW_IN === nodeContext)) { + hasContent = true; + + if (state.tag === null) { + state.tag = '?'; + } + } + + if (state.anchor !== null) { + state.anchorMap[state.anchor] = state.result; + } + } + } else if (indentStatus === 0) { + // Special case: block sequences are allowed to have same indentation level as the parent. + // http://www.yaml.org/spec/1.2/spec.html#id2799784 + hasContent = allowBlockCollections && readBlockSequence(state, blockIndent); + } + } + + if (state.tag === null) { + if (state.anchor !== null) { + state.anchorMap[state.anchor] = state.result; + } + + } else if (state.tag === '?') { + // Implicit resolving is not allowed for non-scalar types, and '?' + // non-specific tag is only automatically assigned to plain scalars. + // + // We only need to check kind conformity in case user explicitly assigns '?' + // tag, for example like this: "! [0]" + // + if (state.result !== null && state.kind !== 'scalar') { + throwError(state, 'unacceptable node kind for ! tag; it should be "scalar", not "' + state.kind + '"'); + } + + for (typeIndex = 0, typeQuantity = state.implicitTypes.length; typeIndex < typeQuantity; typeIndex += 1) { + type = state.implicitTypes[typeIndex]; + + if (type.resolve(state.result)) { // `state.result` updated in resolver if matched + state.result = type.construct(state.result); + state.tag = type.tag; + if (state.anchor !== null) { + state.anchorMap[state.anchor] = state.result; + } + break; + } + } + } else if (state.tag !== '!') { + if (_hasOwnProperty$1.call(state.typeMap[state.kind || 'fallback'], state.tag)) { + type = state.typeMap[state.kind || 'fallback'][state.tag]; + } else { + // looking for multi type + type = null; + typeList = state.typeMap.multi[state.kind || 'fallback']; + + for (typeIndex = 0, typeQuantity = typeList.length; typeIndex < typeQuantity; typeIndex += 1) { + if (state.tag.slice(0, typeList[typeIndex].tag.length) === typeList[typeIndex].tag) { + type = typeList[typeIndex]; + break; + } + } + } + + if (!type) { + throwError(state, 'unknown tag !<' + state.tag + '>'); + } + + if (state.result !== null && type.kind !== state.kind) { + throwError(state, 'unacceptable node kind for !<' + state.tag + '> tag; it should be "' + type.kind + '", not "' + state.kind + '"'); + } + + if (!type.resolve(state.result, state.tag)) { // `state.result` updated in resolver if matched + throwError(state, 'cannot resolve a node with !<' + state.tag + '> explicit tag'); + } else { + state.result = type.construct(state.result, state.tag); + if (state.anchor !== null) { + state.anchorMap[state.anchor] = state.result; + } + } + } + + if (state.listener !== null) { + state.listener('close', state); + } + return state.tag !== null || state.anchor !== null || hasContent; +} + +function readDocument(state) { + var documentStart = state.position, + _position, + directiveName, + directiveArgs, + hasDirectives = false, + ch; + + state.version = null; + state.checkLineBreaks = state.legacy; + state.tagMap = Object.create(null); + state.anchorMap = Object.create(null); + + while ((ch = state.input.charCodeAt(state.position)) !== 0) { + skipSeparationSpace(state, true, -1); + + ch = state.input.charCodeAt(state.position); + + if (state.lineIndent > 0 || ch !== 0x25/* % */) { + break; + } + + hasDirectives = true; + ch = state.input.charCodeAt(++state.position); + _position = state.position; + + while (ch !== 0 && !is_WS_OR_EOL(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + directiveName = state.input.slice(_position, state.position); + directiveArgs = []; + + if (directiveName.length < 1) { + throwError(state, 'directive name must not be less than one character in length'); + } + + while (ch !== 0) { + while (is_WHITE_SPACE(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + if (ch === 0x23/* # */) { + do { ch = state.input.charCodeAt(++state.position); } + while (ch !== 0 && !is_EOL(ch)); + break; + } + + if (is_EOL(ch)) break; + + _position = state.position; + + while (ch !== 0 && !is_WS_OR_EOL(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + directiveArgs.push(state.input.slice(_position, state.position)); + } + + if (ch !== 0) readLineBreak(state); + + if (_hasOwnProperty$1.call(directiveHandlers, directiveName)) { + directiveHandlers[directiveName](state, directiveName, directiveArgs); + } else { + throwWarning(state, 'unknown document directive "' + directiveName + '"'); + } + } + + skipSeparationSpace(state, true, -1); + + if (state.lineIndent === 0 && + state.input.charCodeAt(state.position) === 0x2D/* - */ && + state.input.charCodeAt(state.position + 1) === 0x2D/* - */ && + state.input.charCodeAt(state.position + 2) === 0x2D/* - */) { + state.position += 3; + skipSeparationSpace(state, true, -1); + + } else if (hasDirectives) { + throwError(state, 'directives end mark is expected'); + } + + composeNode(state, state.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true); + skipSeparationSpace(state, true, -1); + + if (state.checkLineBreaks && + PATTERN_NON_ASCII_LINE_BREAKS.test(state.input.slice(documentStart, state.position))) { + throwWarning(state, 'non-ASCII line breaks are interpreted as content'); + } + + state.documents.push(state.result); + + if (state.position === state.lineStart && testDocumentSeparator(state)) { + + if (state.input.charCodeAt(state.position) === 0x2E/* . */) { + state.position += 3; + skipSeparationSpace(state, true, -1); + } + return; + } + + if (state.position < (state.length - 1)) { + throwError(state, 'end of the stream or a document separator is expected'); + } else { + return; + } +} + + +function loadDocuments(input, options) { + input = String(input); + options = options || {}; + + if (input.length !== 0) { + + // Add tailing `\n` if not exists + if (input.charCodeAt(input.length - 1) !== 0x0A/* LF */ && + input.charCodeAt(input.length - 1) !== 0x0D/* CR */) { + input += '\n'; + } + + // Strip BOM + if (input.charCodeAt(0) === 0xFEFF) { + input = input.slice(1); + } + } + + var state = new State$1(input, options); + + var nullpos = input.indexOf('\0'); + + if (nullpos !== -1) { + state.position = nullpos; + throwError(state, 'null byte is not allowed in input'); + } + + // Use 0 as string terminator. That significantly simplifies bounds check. + state.input += '\0'; + + while (state.input.charCodeAt(state.position) === 0x20/* Space */) { + state.lineIndent += 1; + state.position += 1; + } + + while (state.position < (state.length - 1)) { + readDocument(state); + } + + return state.documents; +} + + +function loadAll$1(input, iterator, options) { + if (iterator !== null && typeof iterator === 'object' && typeof options === 'undefined') { + options = iterator; + iterator = null; + } + + var documents = loadDocuments(input, options); + + if (typeof iterator !== 'function') { + return documents; + } + + for (var index = 0, length = documents.length; index < length; index += 1) { + iterator(documents[index]); + } +} + + +function load$1(input, options) { + var documents = loadDocuments(input, options); + + if (documents.length === 0) { + /*eslint-disable no-undefined*/ + return undefined; + } else if (documents.length === 1) { + return documents[0]; + } + throw new exception('expected a single document in the stream, but found more'); +} + + +var loadAll_1 = loadAll$1; +var load_1 = load$1; + +var loader = { + loadAll: loadAll_1, + load: load_1 +}; + +/*eslint-disable no-use-before-define*/ + + + + + +var _toString = Object.prototype.toString; +var _hasOwnProperty = Object.prototype.hasOwnProperty; + +var CHAR_BOM = 0xFEFF; +var CHAR_TAB = 0x09; /* Tab */ +var CHAR_LINE_FEED = 0x0A; /* LF */ +var CHAR_CARRIAGE_RETURN = 0x0D; /* CR */ +var CHAR_SPACE = 0x20; /* Space */ +var CHAR_EXCLAMATION = 0x21; /* ! */ +var CHAR_DOUBLE_QUOTE = 0x22; /* " */ +var CHAR_SHARP = 0x23; /* # */ +var CHAR_PERCENT = 0x25; /* % */ +var CHAR_AMPERSAND = 0x26; /* & */ +var CHAR_SINGLE_QUOTE = 0x27; /* ' */ +var CHAR_ASTERISK = 0x2A; /* * */ +var CHAR_COMMA = 0x2C; /* , */ +var CHAR_MINUS = 0x2D; /* - */ +var CHAR_COLON = 0x3A; /* : */ +var CHAR_EQUALS = 0x3D; /* = */ +var CHAR_GREATER_THAN = 0x3E; /* > */ +var CHAR_QUESTION = 0x3F; /* ? */ +var CHAR_COMMERCIAL_AT = 0x40; /* @ */ +var CHAR_LEFT_SQUARE_BRACKET = 0x5B; /* [ */ +var CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */ +var CHAR_GRAVE_ACCENT = 0x60; /* ` */ +var CHAR_LEFT_CURLY_BRACKET = 0x7B; /* { */ +var CHAR_VERTICAL_LINE = 0x7C; /* | */ +var CHAR_RIGHT_CURLY_BRACKET = 0x7D; /* } */ + +var ESCAPE_SEQUENCES = {}; + +ESCAPE_SEQUENCES[0x00] = '\\0'; +ESCAPE_SEQUENCES[0x07] = '\\a'; +ESCAPE_SEQUENCES[0x08] = '\\b'; +ESCAPE_SEQUENCES[0x09] = '\\t'; +ESCAPE_SEQUENCES[0x0A] = '\\n'; +ESCAPE_SEQUENCES[0x0B] = '\\v'; +ESCAPE_SEQUENCES[0x0C] = '\\f'; +ESCAPE_SEQUENCES[0x0D] = '\\r'; +ESCAPE_SEQUENCES[0x1B] = '\\e'; +ESCAPE_SEQUENCES[0x22] = '\\"'; +ESCAPE_SEQUENCES[0x5C] = '\\\\'; +ESCAPE_SEQUENCES[0x85] = '\\N'; +ESCAPE_SEQUENCES[0xA0] = '\\_'; +ESCAPE_SEQUENCES[0x2028] = '\\L'; +ESCAPE_SEQUENCES[0x2029] = '\\P'; + +var DEPRECATED_BOOLEANS_SYNTAX = [ + 'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON', + 'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF' +]; + +var DEPRECATED_BASE60_SYNTAX = /^[-+]?[0-9_]+(?::[0-9_]+)+(?:\.[0-9_]*)?$/; + +function compileStyleMap(schema, map) { + var result, keys, index, length, tag, style, type; + + if (map === null) return {}; + + result = {}; + keys = Object.keys(map); + + for (index = 0, length = keys.length; index < length; index += 1) { + tag = keys[index]; + style = String(map[tag]); + + if (tag.slice(0, 2) === '!!') { + tag = 'tag:yaml.org,2002:' + tag.slice(2); + } + type = schema.compiledTypeMap['fallback'][tag]; + + if (type && _hasOwnProperty.call(type.styleAliases, style)) { + style = type.styleAliases[style]; + } + + result[tag] = style; + } + + return result; +} + +function encodeHex(character) { + var string, handle, length; + + string = character.toString(16).toUpperCase(); + + if (character <= 0xFF) { + handle = 'x'; + length = 2; + } else if (character <= 0xFFFF) { + handle = 'u'; + length = 4; + } else if (character <= 0xFFFFFFFF) { + handle = 'U'; + length = 8; + } else { + throw new exception('code point within a string may not be greater than 0xFFFFFFFF'); + } + + return '\\' + handle + common.repeat('0', length - string.length) + string; +} + + +var QUOTING_TYPE_SINGLE = 1, + QUOTING_TYPE_DOUBLE = 2; + +function State(options) { + this.schema = options['schema'] || _default; + this.indent = Math.max(1, (options['indent'] || 2)); + this.noArrayIndent = options['noArrayIndent'] || false; + this.skipInvalid = options['skipInvalid'] || false; + this.flowLevel = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']); + this.styleMap = compileStyleMap(this.schema, options['styles'] || null); + this.sortKeys = options['sortKeys'] || false; + this.lineWidth = options['lineWidth'] || 80; + this.noRefs = options['noRefs'] || false; + this.noCompatMode = options['noCompatMode'] || false; + this.condenseFlow = options['condenseFlow'] || false; + this.quotingType = options['quotingType'] === '"' ? QUOTING_TYPE_DOUBLE : QUOTING_TYPE_SINGLE; + this.forceQuotes = options['forceQuotes'] || false; + this.replacer = typeof options['replacer'] === 'function' ? options['replacer'] : null; + + this.implicitTypes = this.schema.compiledImplicit; + this.explicitTypes = this.schema.compiledExplicit; + + this.tag = null; + this.result = ''; + + this.duplicates = []; + this.usedDuplicates = null; +} + +// Indents every line in a string. Empty lines (\n only) are not indented. +function indentString(string, spaces) { + var ind = common.repeat(' ', spaces), + position = 0, + next = -1, + result = '', + line, + length = string.length; + + while (position < length) { + next = string.indexOf('\n', position); + if (next === -1) { + line = string.slice(position); + position = length; + } else { + line = string.slice(position, next + 1); + position = next + 1; + } + + if (line.length && line !== '\n') result += ind; + + result += line; + } + + return result; +} + +function generateNextLine(state, level) { + return '\n' + common.repeat(' ', state.indent * level); +} + +function testImplicitResolving(state, str) { + var index, length, type; + + for (index = 0, length = state.implicitTypes.length; index < length; index += 1) { + type = state.implicitTypes[index]; + + if (type.resolve(str)) { + return true; + } + } + + return false; +} + +// [33] s-white ::= s-space | s-tab +function isWhitespace(c) { + return c === CHAR_SPACE || c === CHAR_TAB; +} + +// Returns true if the character can be printed without escaping. +// From YAML 1.2: "any allowed characters known to be non-printable +// should also be escaped. [However,] This isn’t mandatory" +// Derived from nb-char - \t - #x85 - #xA0 - #x2028 - #x2029. +function isPrintable(c) { + return (0x00020 <= c && c <= 0x00007E) + || ((0x000A1 <= c && c <= 0x00D7FF) && c !== 0x2028 && c !== 0x2029) + || ((0x0E000 <= c && c <= 0x00FFFD) && c !== CHAR_BOM) + || (0x10000 <= c && c <= 0x10FFFF); +} + +// [34] ns-char ::= nb-char - s-white +// [27] nb-char ::= c-printable - b-char - c-byte-order-mark +// [26] b-char ::= b-line-feed | b-carriage-return +// Including s-white (for some reason, examples doesn't match specs in this aspect) +// ns-char ::= c-printable - b-line-feed - b-carriage-return - c-byte-order-mark +function isNsCharOrWhitespace(c) { + return isPrintable(c) + && c !== CHAR_BOM + // - b-char + && c !== CHAR_CARRIAGE_RETURN + && c !== CHAR_LINE_FEED; +} + +// [127] ns-plain-safe(c) ::= c = flow-out ⇒ ns-plain-safe-out +// c = flow-in ⇒ ns-plain-safe-in +// c = block-key ⇒ ns-plain-safe-out +// c = flow-key ⇒ ns-plain-safe-in +// [128] ns-plain-safe-out ::= ns-char +// [129] ns-plain-safe-in ::= ns-char - c-flow-indicator +// [130] ns-plain-char(c) ::= ( ns-plain-safe(c) - “:” - “#” ) +// | ( /* An ns-char preceding */ “#” ) +// | ( “:” /* Followed by an ns-plain-safe(c) */ ) +function isPlainSafe(c, prev, inblock) { + var cIsNsCharOrWhitespace = isNsCharOrWhitespace(c); + var cIsNsChar = cIsNsCharOrWhitespace && !isWhitespace(c); + return ( + // ns-plain-safe + inblock ? // c = flow-in + cIsNsCharOrWhitespace + : cIsNsCharOrWhitespace + // - c-flow-indicator + && c !== CHAR_COMMA + && c !== CHAR_LEFT_SQUARE_BRACKET + && c !== CHAR_RIGHT_SQUARE_BRACKET + && c !== CHAR_LEFT_CURLY_BRACKET + && c !== CHAR_RIGHT_CURLY_BRACKET + ) + // ns-plain-char + && c !== CHAR_SHARP // false on '#' + && !(prev === CHAR_COLON && !cIsNsChar) // false on ': ' + || (isNsCharOrWhitespace(prev) && !isWhitespace(prev) && c === CHAR_SHARP) // change to true on '[^ ]#' + || (prev === CHAR_COLON && cIsNsChar); // change to true on ':[^ ]' +} + +// Simplified test for values allowed as the first character in plain style. +function isPlainSafeFirst(c) { + // Uses a subset of ns-char - c-indicator + // where ns-char = nb-char - s-white. + // No support of ( ( “?” | “:” | “-” ) /* Followed by an ns-plain-safe(c)) */ ) part + return isPrintable(c) && c !== CHAR_BOM + && !isWhitespace(c) // - s-white + // - (c-indicator ::= + // “-” | “?” | “:” | “,” | “[” | “]” | “{” | “}” + && c !== CHAR_MINUS + && c !== CHAR_QUESTION + && c !== CHAR_COLON + && c !== CHAR_COMMA + && c !== CHAR_LEFT_SQUARE_BRACKET + && c !== CHAR_RIGHT_SQUARE_BRACKET + && c !== CHAR_LEFT_CURLY_BRACKET + && c !== CHAR_RIGHT_CURLY_BRACKET + // | “#” | “&” | “*” | “!” | “|” | “=” | “>” | “'” | “"” + && c !== CHAR_SHARP + && c !== CHAR_AMPERSAND + && c !== CHAR_ASTERISK + && c !== CHAR_EXCLAMATION + && c !== CHAR_VERTICAL_LINE + && c !== CHAR_EQUALS + && c !== CHAR_GREATER_THAN + && c !== CHAR_SINGLE_QUOTE + && c !== CHAR_DOUBLE_QUOTE + // | “%” | “@” | “`”) + && c !== CHAR_PERCENT + && c !== CHAR_COMMERCIAL_AT + && c !== CHAR_GRAVE_ACCENT; +} + +// Simplified test for values allowed as the last character in plain style. +function isPlainSafeLast(c) { + // just not whitespace or colon, it will be checked to be plain character later + return !isWhitespace(c) && c !== CHAR_COLON; +} + +// Same as 'string'.codePointAt(pos), but works in older browsers. +function codePointAt(string, pos) { + var first = string.charCodeAt(pos), second; + if (first >= 0xD800 && first <= 0xDBFF && pos + 1 < string.length) { + second = string.charCodeAt(pos + 1); + if (second >= 0xDC00 && second <= 0xDFFF) { + // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae + return (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000; + } + } + return first; +} + +// Determines whether block indentation indicator is required. +function needIndentIndicator(string) { + var leadingSpaceRe = /^\n* /; + return leadingSpaceRe.test(string); +} + +var STYLE_PLAIN = 1, + STYLE_SINGLE = 2, + STYLE_LITERAL = 3, + STYLE_FOLDED = 4, + STYLE_DOUBLE = 5; + +// Determines which scalar styles are possible and returns the preferred style. +// lineWidth = -1 => no limit. +// Pre-conditions: str.length > 0. +// Post-conditions: +// STYLE_PLAIN or STYLE_SINGLE => no \n are in the string. +// STYLE_LITERAL => no lines are suitable for folding (or lineWidth is -1). +// STYLE_FOLDED => a line > lineWidth and can be folded (and lineWidth != -1). +function chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth, + testAmbiguousType, quotingType, forceQuotes, inblock) { + + var i; + var char = 0; + var prevChar = null; + var hasLineBreak = false; + var hasFoldableLine = false; // only checked if shouldTrackWidth + var shouldTrackWidth = lineWidth !== -1; + var previousLineBreak = -1; // count the first line correctly + var plain = isPlainSafeFirst(codePointAt(string, 0)) + && isPlainSafeLast(codePointAt(string, string.length - 1)); + + if (singleLineOnly || forceQuotes) { + // Case: no block styles. + // Check for disallowed characters to rule out plain and single. + for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) { + char = codePointAt(string, i); + if (!isPrintable(char)) { + return STYLE_DOUBLE; + } + plain = plain && isPlainSafe(char, prevChar, inblock); + prevChar = char; + } + } else { + // Case: block styles permitted. + for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) { + char = codePointAt(string, i); + if (char === CHAR_LINE_FEED) { + hasLineBreak = true; + // Check if any line can be folded. + if (shouldTrackWidth) { + hasFoldableLine = hasFoldableLine || + // Foldable line = too long, and not more-indented. + (i - previousLineBreak - 1 > lineWidth && + string[previousLineBreak + 1] !== ' '); + previousLineBreak = i; + } + } else if (!isPrintable(char)) { + return STYLE_DOUBLE; + } + plain = plain && isPlainSafe(char, prevChar, inblock); + prevChar = char; + } + // in case the end is missing a \n + hasFoldableLine = hasFoldableLine || (shouldTrackWidth && + (i - previousLineBreak - 1 > lineWidth && + string[previousLineBreak + 1] !== ' ')); + } + // Although every style can represent \n without escaping, prefer block styles + // for multiline, since they're more readable and they don't add empty lines. + // Also prefer folding a super-long line. + if (!hasLineBreak && !hasFoldableLine) { + // Strings interpretable as another type have to be quoted; + // e.g. the string 'true' vs. the boolean true. + if (plain && !forceQuotes && !testAmbiguousType(string)) { + return STYLE_PLAIN; + } + return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE; + } + // Edge case: block indentation indicator can only have one digit. + if (indentPerLevel > 9 && needIndentIndicator(string)) { + return STYLE_DOUBLE; + } + // At this point we know block styles are valid. + // Prefer literal style unless we want to fold. + if (!forceQuotes) { + return hasFoldableLine ? STYLE_FOLDED : STYLE_LITERAL; + } + return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE; +} + +// Note: line breaking/folding is implemented for only the folded style. +// NB. We drop the last trailing newline (if any) of a returned block scalar +// since the dumper adds its own newline. This always works: +// • No ending newline => unaffected; already using strip "-" chomping. +// • Ending newline => removed then restored. +// Importantly, this keeps the "+" chomp indicator from gaining an extra line. +function writeScalar(state, string, level, iskey, inblock) { + state.dump = (function () { + if (string.length === 0) { + return state.quotingType === QUOTING_TYPE_DOUBLE ? '""' : "''"; + } + if (!state.noCompatMode) { + if (DEPRECATED_BOOLEANS_SYNTAX.indexOf(string) !== -1 || DEPRECATED_BASE60_SYNTAX.test(string)) { + return state.quotingType === QUOTING_TYPE_DOUBLE ? ('"' + string + '"') : ("'" + string + "'"); + } + } + + var indent = state.indent * Math.max(1, level); // no 0-indent scalars + // As indentation gets deeper, let the width decrease monotonically + // to the lower bound min(state.lineWidth, 40). + // Note that this implies + // state.lineWidth ≤ 40 + state.indent: width is fixed at the lower bound. + // state.lineWidth > 40 + state.indent: width decreases until the lower bound. + // This behaves better than a constant minimum width which disallows narrower options, + // or an indent threshold which causes the width to suddenly increase. + var lineWidth = state.lineWidth === -1 + ? -1 : Math.max(Math.min(state.lineWidth, 40), state.lineWidth - indent); + + // Without knowing if keys are implicit/explicit, assume implicit for safety. + var singleLineOnly = iskey + // No block styles in flow mode. + || (state.flowLevel > -1 && level >= state.flowLevel); + function testAmbiguity(string) { + return testImplicitResolving(state, string); + } + + switch (chooseScalarStyle(string, singleLineOnly, state.indent, lineWidth, + testAmbiguity, state.quotingType, state.forceQuotes && !iskey, inblock)) { + + case STYLE_PLAIN: + return string; + case STYLE_SINGLE: + return "'" + string.replace(/'/g, "''") + "'"; + case STYLE_LITERAL: + return '|' + blockHeader(string, state.indent) + + dropEndingNewline(indentString(string, indent)); + case STYLE_FOLDED: + return '>' + blockHeader(string, state.indent) + + dropEndingNewline(indentString(foldString(string, lineWidth), indent)); + case STYLE_DOUBLE: + return '"' + escapeString(string) + '"'; + default: + throw new exception('impossible error: invalid scalar style'); + } + }()); +} + +// Pre-conditions: string is valid for a block scalar, 1 <= indentPerLevel <= 9. +function blockHeader(string, indentPerLevel) { + var indentIndicator = needIndentIndicator(string) ? String(indentPerLevel) : ''; + + // note the special case: the string '\n' counts as a "trailing" empty line. + var clip = string[string.length - 1] === '\n'; + var keep = clip && (string[string.length - 2] === '\n' || string === '\n'); + var chomp = keep ? '+' : (clip ? '' : '-'); + + return indentIndicator + chomp + '\n'; +} + +// (See the note for writeScalar.) +function dropEndingNewline(string) { + return string[string.length - 1] === '\n' ? string.slice(0, -1) : string; +} + +// Note: a long line without a suitable break point will exceed the width limit. +// Pre-conditions: every char in str isPrintable, str.length > 0, width > 0. +function foldString(string, width) { + // In folded style, $k$ consecutive newlines output as $k+1$ newlines— + // unless they're before or after a more-indented line, or at the very + // beginning or end, in which case $k$ maps to $k$. + // Therefore, parse each chunk as newline(s) followed by a content line. + var lineRe = /(\n+)([^\n]*)/g; + + // first line (possibly an empty line) + var result = (function () { + var nextLF = string.indexOf('\n'); + nextLF = nextLF !== -1 ? nextLF : string.length; + lineRe.lastIndex = nextLF; + return foldLine(string.slice(0, nextLF), width); + }()); + // If we haven't reached the first content line yet, don't add an extra \n. + var prevMoreIndented = string[0] === '\n' || string[0] === ' '; + var moreIndented; + + // rest of the lines + var match; + while ((match = lineRe.exec(string))) { + var prefix = match[1], line = match[2]; + moreIndented = (line[0] === ' '); + result += prefix + + (!prevMoreIndented && !moreIndented && line !== '' + ? '\n' : '') + + foldLine(line, width); + prevMoreIndented = moreIndented; + } + + return result; +} + +// Greedy line breaking. +// Picks the longest line under the limit each time, +// otherwise settles for the shortest line over the limit. +// NB. More-indented lines *cannot* be folded, as that would add an extra \n. +function foldLine(line, width) { + if (line === '' || line[0] === ' ') return line; + + // Since a more-indented line adds a \n, breaks can't be followed by a space. + var breakRe = / [^ ]/g; // note: the match index will always be <= length-2. + var match; + // start is an inclusive index. end, curr, and next are exclusive. + var start = 0, end, curr = 0, next = 0; + var result = ''; + + // Invariants: 0 <= start <= length-1. + // 0 <= curr <= next <= max(0, length-2). curr - start <= width. + // Inside the loop: + // A match implies length >= 2, so curr and next are <= length-2. + while ((match = breakRe.exec(line))) { + next = match.index; + // maintain invariant: curr - start <= width + if (next - start > width) { + end = (curr > start) ? curr : next; // derive end <= length-2 + result += '\n' + line.slice(start, end); + // skip the space that was output as \n + start = end + 1; // derive start <= length-1 + } + curr = next; + } + + // By the invariants, start <= length-1, so there is something left over. + // It is either the whole string or a part starting from non-whitespace. + result += '\n'; + // Insert a break if the remainder is too long and there is a break available. + if (line.length - start > width && curr > start) { + result += line.slice(start, curr) + '\n' + line.slice(curr + 1); + } else { + result += line.slice(start); + } + + return result.slice(1); // drop extra \n joiner +} + +// Escapes a double-quoted string. +function escapeString(string) { + var result = ''; + var char = 0; + var escapeSeq; + + for (var i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) { + char = codePointAt(string, i); + escapeSeq = ESCAPE_SEQUENCES[char]; + + if (!escapeSeq && isPrintable(char)) { + result += string[i]; + if (char >= 0x10000) result += string[i + 1]; + } else { + result += escapeSeq || encodeHex(char); + } + } + + return result; +} + +function writeFlowSequence(state, level, object) { + var _result = '', + _tag = state.tag, + index, + length, + value; + + for (index = 0, length = object.length; index < length; index += 1) { + value = object[index]; + + if (state.replacer) { + value = state.replacer.call(object, String(index), value); + } + + // Write only valid elements, put null instead of invalid elements. + if (writeNode(state, level, value, false, false) || + (typeof value === 'undefined' && + writeNode(state, level, null, false, false))) { + + if (_result !== '') _result += ',' + (!state.condenseFlow ? ' ' : ''); + _result += state.dump; + } + } + + state.tag = _tag; + state.dump = '[' + _result + ']'; +} + +function writeBlockSequence(state, level, object, compact) { + var _result = '', + _tag = state.tag, + index, + length, + value; + + for (index = 0, length = object.length; index < length; index += 1) { + value = object[index]; + + if (state.replacer) { + value = state.replacer.call(object, String(index), value); + } + + // Write only valid elements, put null instead of invalid elements. + if (writeNode(state, level + 1, value, true, true, false, true) || + (typeof value === 'undefined' && + writeNode(state, level + 1, null, true, true, false, true))) { + + if (!compact || _result !== '') { + _result += generateNextLine(state, level); + } + + if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { + _result += '-'; + } else { + _result += '- '; + } + + _result += state.dump; + } + } + + state.tag = _tag; + state.dump = _result || '[]'; // Empty sequence if no valid values. +} + +function writeFlowMapping(state, level, object) { + var _result = '', + _tag = state.tag, + objectKeyList = Object.keys(object), + index, + length, + objectKey, + objectValue, + pairBuffer; + + for (index = 0, length = objectKeyList.length; index < length; index += 1) { + + pairBuffer = ''; + if (_result !== '') pairBuffer += ', '; + + if (state.condenseFlow) pairBuffer += '"'; + + objectKey = objectKeyList[index]; + objectValue = object[objectKey]; + + if (state.replacer) { + objectValue = state.replacer.call(object, objectKey, objectValue); + } + + if (!writeNode(state, level, objectKey, false, false)) { + continue; // Skip this pair because of invalid key; + } + + if (state.dump.length > 1024) pairBuffer += '? '; + + pairBuffer += state.dump + (state.condenseFlow ? '"' : '') + ':' + (state.condenseFlow ? '' : ' '); + + if (!writeNode(state, level, objectValue, false, false)) { + continue; // Skip this pair because of invalid value. + } + + pairBuffer += state.dump; + + // Both key and value are valid. + _result += pairBuffer; + } + + state.tag = _tag; + state.dump = '{' + _result + '}'; +} + +function writeBlockMapping(state, level, object, compact) { + var _result = '', + _tag = state.tag, + objectKeyList = Object.keys(object), + index, + length, + objectKey, + objectValue, + explicitPair, + pairBuffer; + + // Allow sorting keys so that the output file is deterministic + if (state.sortKeys === true) { + // Default sorting + objectKeyList.sort(); + } else if (typeof state.sortKeys === 'function') { + // Custom sort function + objectKeyList.sort(state.sortKeys); + } else if (state.sortKeys) { + // Something is wrong + throw new exception('sortKeys must be a boolean or a function'); + } + + for (index = 0, length = objectKeyList.length; index < length; index += 1) { + pairBuffer = ''; + + if (!compact || _result !== '') { + pairBuffer += generateNextLine(state, level); + } + + objectKey = objectKeyList[index]; + objectValue = object[objectKey]; + + if (state.replacer) { + objectValue = state.replacer.call(object, objectKey, objectValue); + } + + if (!writeNode(state, level + 1, objectKey, true, true, true)) { + continue; // Skip this pair because of invalid key. + } + + explicitPair = (state.tag !== null && state.tag !== '?') || + (state.dump && state.dump.length > 1024); + + if (explicitPair) { + if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { + pairBuffer += '?'; + } else { + pairBuffer += '? '; + } + } + + pairBuffer += state.dump; + + if (explicitPair) { + pairBuffer += generateNextLine(state, level); + } + + if (!writeNode(state, level + 1, objectValue, true, explicitPair)) { + continue; // Skip this pair because of invalid value. + } + + if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { + pairBuffer += ':'; + } else { + pairBuffer += ': '; + } + + pairBuffer += state.dump; + + // Both key and value are valid. + _result += pairBuffer; + } + + state.tag = _tag; + state.dump = _result || '{}'; // Empty mapping if no valid pairs. +} + +function detectType(state, object, explicit) { + var _result, typeList, index, length, type, style; + + typeList = explicit ? state.explicitTypes : state.implicitTypes; + + for (index = 0, length = typeList.length; index < length; index += 1) { + type = typeList[index]; + + if ((type.instanceOf || type.predicate) && + (!type.instanceOf || ((typeof object === 'object') && (object instanceof type.instanceOf))) && + (!type.predicate || type.predicate(object))) { + + if (explicit) { + if (type.multi && type.representName) { + state.tag = type.representName(object); + } else { + state.tag = type.tag; + } + } else { + state.tag = '?'; + } + + if (type.represent) { + style = state.styleMap[type.tag] || type.defaultStyle; + + if (_toString.call(type.represent) === '[object Function]') { + _result = type.represent(object, style); + } else if (_hasOwnProperty.call(type.represent, style)) { + _result = type.represent[style](object, style); + } else { + throw new exception('!<' + type.tag + '> tag resolver accepts not "' + style + '" style'); + } + + state.dump = _result; + } + + return true; + } + } + + return false; +} + +// Serializes `object` and writes it to global `result`. +// Returns true on success, or false on invalid object. +// +function writeNode(state, level, object, block, compact, iskey, isblockseq) { + state.tag = null; + state.dump = object; + + if (!detectType(state, object, false)) { + detectType(state, object, true); + } + + var type = _toString.call(state.dump); + var inblock = block; + var tagStr; + + if (block) { + block = (state.flowLevel < 0 || state.flowLevel > level); + } + + var objectOrArray = type === '[object Object]' || type === '[object Array]', + duplicateIndex, + duplicate; + + if (objectOrArray) { + duplicateIndex = state.duplicates.indexOf(object); + duplicate = duplicateIndex !== -1; + } + + if ((state.tag !== null && state.tag !== '?') || duplicate || (state.indent !== 2 && level > 0)) { + compact = false; + } + + if (duplicate && state.usedDuplicates[duplicateIndex]) { + state.dump = '*ref_' + duplicateIndex; + } else { + if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) { + state.usedDuplicates[duplicateIndex] = true; + } + if (type === '[object Object]') { + if (block && (Object.keys(state.dump).length !== 0)) { + writeBlockMapping(state, level, state.dump, compact); + if (duplicate) { + state.dump = '&ref_' + duplicateIndex + state.dump; + } + } else { + writeFlowMapping(state, level, state.dump); + if (duplicate) { + state.dump = '&ref_' + duplicateIndex + ' ' + state.dump; + } + } + } else if (type === '[object Array]') { + if (block && (state.dump.length !== 0)) { + if (state.noArrayIndent && !isblockseq && level > 0) { + writeBlockSequence(state, level - 1, state.dump, compact); + } else { + writeBlockSequence(state, level, state.dump, compact); + } + if (duplicate) { + state.dump = '&ref_' + duplicateIndex + state.dump; + } + } else { + writeFlowSequence(state, level, state.dump); + if (duplicate) { + state.dump = '&ref_' + duplicateIndex + ' ' + state.dump; + } + } + } else if (type === '[object String]') { + if (state.tag !== '?') { + writeScalar(state, state.dump, level, iskey, inblock); + } + } else if (type === '[object Undefined]') { + return false; + } else { + if (state.skipInvalid) return false; + throw new exception('unacceptable kind of an object to dump ' + type); + } + + if (state.tag !== null && state.tag !== '?') { + // Need to encode all characters except those allowed by the spec: + // + // [35] ns-dec-digit ::= [#x30-#x39] /* 0-9 */ + // [36] ns-hex-digit ::= ns-dec-digit + // | [#x41-#x46] /* A-F */ | [#x61-#x66] /* a-f */ + // [37] ns-ascii-letter ::= [#x41-#x5A] /* A-Z */ | [#x61-#x7A] /* a-z */ + // [38] ns-word-char ::= ns-dec-digit | ns-ascii-letter | “-” + // [39] ns-uri-char ::= “%” ns-hex-digit ns-hex-digit | ns-word-char | “#” + // | “;” | “/” | “?” | “:” | “@” | “&” | “=” | “+” | “$” | “,” + // | “_” | “.” | “!” | “~” | “*” | “'” | “(” | “)” | “[” | “]” + // + // Also need to encode '!' because it has special meaning (end of tag prefix). + // + tagStr = encodeURI( + state.tag[0] === '!' ? state.tag.slice(1) : state.tag + ).replace(/!/g, '%21'); + + if (state.tag[0] === '!') { + tagStr = '!' + tagStr; + } else if (tagStr.slice(0, 18) === 'tag:yaml.org,2002:') { + tagStr = '!!' + tagStr.slice(18); + } else { + tagStr = '!<' + tagStr + '>'; + } + + state.dump = tagStr + ' ' + state.dump; + } + } + + return true; +} + +function getDuplicateReferences(object, state) { + var objects = [], + duplicatesIndexes = [], + index, + length; + + inspectNode(object, objects, duplicatesIndexes); + + for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) { + state.duplicates.push(objects[duplicatesIndexes[index]]); + } + state.usedDuplicates = new Array(length); +} + +function inspectNode(object, objects, duplicatesIndexes) { + var objectKeyList, + index, + length; + + if (object !== null && typeof object === 'object') { + index = objects.indexOf(object); + if (index !== -1) { + if (duplicatesIndexes.indexOf(index) === -1) { + duplicatesIndexes.push(index); + } + } else { + objects.push(object); + + if (Array.isArray(object)) { + for (index = 0, length = object.length; index < length; index += 1) { + inspectNode(object[index], objects, duplicatesIndexes); + } + } else { + objectKeyList = Object.keys(object); + + for (index = 0, length = objectKeyList.length; index < length; index += 1) { + inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes); + } + } + } + } +} + +function dump$1(input, options) { + options = options || {}; + + var state = new State(options); + + if (!state.noRefs) getDuplicateReferences(input, state); + + var value = input; + + if (state.replacer) { + value = state.replacer.call({ '': value }, '', value); + } + + if (writeNode(state, 0, value, true, true)) return state.dump + '\n'; + + return ''; +} + +var dump_1 = dump$1; + +var dumper = { + dump: dump_1 +}; + +function renamed(from, to) { + return function () { + throw new Error('Function yaml.' + from + ' is removed in js-yaml 4. ' + + 'Use yaml.' + to + ' instead, which is now safe by default.'); + }; +} + + +var Type = type; +var Schema = schema; +var FAILSAFE_SCHEMA = failsafe; +var JSON_SCHEMA = json; +var CORE_SCHEMA = core; +var DEFAULT_SCHEMA = _default; +var load = loader.load; +var loadAll = loader.loadAll; +var dump = dumper.dump; +var YAMLException = exception; + +// Re-export all types in case user wants to create custom schema +var types = { + binary: binary, + float: float, + map: map, + null: _null, + pairs: pairs, + set: set, + timestamp: timestamp, + bool: bool, + int: int, + merge: merge, + omap: omap, + seq: seq, + str: str +}; + +// Removed functions from JS-YAML 3.0.x +var safeLoad = renamed('safeLoad', 'load'); +var safeLoadAll = renamed('safeLoadAll', 'loadAll'); +var safeDump = renamed('safeDump', 'dump'); + +var jsYaml = { + Type: Type, + Schema: Schema, + FAILSAFE_SCHEMA: FAILSAFE_SCHEMA, + JSON_SCHEMA: JSON_SCHEMA, + CORE_SCHEMA: CORE_SCHEMA, + DEFAULT_SCHEMA: DEFAULT_SCHEMA, + load: load, + loadAll: loadAll, + dump: dump, + YAMLException: YAMLException, + types: types, + safeLoad: safeLoad, + safeLoadAll: safeLoadAll, + safeDump: safeDump +}; + +export default jsYaml; +export { CORE_SCHEMA, DEFAULT_SCHEMA, FAILSAFE_SCHEMA, JSON_SCHEMA, Schema, Type, YAMLException, dump, load, loadAll, safeDump, safeLoad, safeLoadAll, types }; diff --git a/custom_components/opendisplay/designer/frontend/vendor/odl-drawcustom-designer.d.ts b/custom_components/opendisplay/designer/frontend/vendor/odl-drawcustom-designer.d.ts new file mode 100644 index 00000000..9571e43a --- /dev/null +++ b/custom_components/opendisplay/designer/frontend/vendor/odl-drawcustom-designer.d.ts @@ -0,0 +1,702 @@ +export declare type AssetKind = 'font' | 'image'; + +/** + * Read-only snapshot of designer status (issue #133, ADR-018's observability + * clause: "state flows out via a read handle plus optional change + * notification; status is derived, never authoritative, and carries no + * designer internals"). Answers "is the YAML good, what did the user just do, + * how much has changed" without exposing elements, YAML text or any other + * internal shape. + * + * Deliberately small — grow it by maintainer ruling, not speculation. + * Frozen: a later status is always a new object, never a mutation of one a + * host already holds. + */ +export declare interface DesignerStatus { + /** Whether the current YAML document parses and validates. */ + readonly yamlValid: boolean; + /** + * A one-line description of the first validation problem, truncated to its + * first `\n`-delimited line if the underlying parser error is not (a raw + * YAML syntax error's message can carry a multi-line caret diagram + * pointing at the offending column). Present only while + * {@link DesignerStatus.yamlValid} is `false` — a valid document carries no + * summary rather than an empty or stale one. + */ + readonly yamlErrorSummary?: string; + /** + * Epoch ms, in the **host's** clock domain (`Date.now()` at the moment of + * the edit) — never a designer-internal or build-time value — of the last + * user-originated change: typing committed to the canvas, a canvas drag, a + * property-panel edit, undo/redo. `null` before the user has made any edit + * during this mount. + * + * Never bumped by a host push (`setPayload()`, `setStates()`, …) — a push is + * the host acting on the designer, not the user acting on it. + */ + readonly lastEditAt: number | null; + /** + * Monotonic counter, incremented once per committed payload change — + * whether it came from the user (typing, a drag, undo/redo) or from a host + * `setPayload()` push. A host that only needs "has anything changed since I + * last looked" can diff this number instead of diffing YAML strings. + * + * Granularity, precisely: + * + * - **One drag or property-panel drag gesture is one revision**, not one + * per pointermove — coalesced the same way the gesture's undo-history + * entry is (`beginEditCoalesce`/`endEditCoalesce`), applied once when the + * gesture ends. A gesture that starts and ends without net change bumps + * nothing. + * - **A `setPayload()` push with a structurally equal payload (element-wise) + * is a no-op for the revision** — dedupe before commit, the same + * full-bail pattern the `states`/`actions` channels use for an unchanged + * re-push (issue #110): no revision bump, no reset undo history, no + * cleared selection. Formatting/comment-only YAML differences dedupe too + * (the comparison is over parsed elements, not the YAML text). **Except** + * while a pending, not-yet-committed YAML edit the user was typing before + * this push exists: `setPayload()` is authoritative over an in-flight + * draft regardless of whether the pushed payload turns out to match + * what's already committed, so the draft is **always** discarded, deduped + * or not — and when there was a real draft to discard, the dedupe is + * skipped entirely and the push takes the full apply path instead, + * which **does** bump the revision even though the committed elements + * end up structurally the same as before. This is deliberate, not an + * inconsistency: the push observably changed something (the draft the + * editor was showing is gone, replaced by a fresh sync of the pushed + * payload) — a plain content comparison alone would miss that and leave + * the editor's on-screen text uncorrected. + * - Every other committed change (a single keystroke's debounced commit, a + * click-driven property edit, undo, redo, a genuinely different + * `setPayload()` push) bumps exactly once. + */ + readonly payloadRevision: number; + /** How many elements are currently selected on the canvas. */ + readonly selectedElementCount: number; +} + +/** Theme applied to the mount container (never `document.documentElement`). */ +export declare type EmbedTheme = 'light' | 'dark'; + +/** + * One host-registered toolbar button (issue #108, ADR-018 actions seam). + * + * The host owns what the button means; the designer owns how it looks and + * reports which one fired, with the current payload (`onAction`). This is a + * typed, closed button list — deliberately not a plugin API: no host markup, + * styles or components ever enter the designer's shadow root (ADR-017). + */ +export declare interface HostAction { + /** + * Opaque, host-defined identity, echoed back by `onAction`. Also the list's + * diff key: re-pushing the same id updates that button in place rather than + * replacing it. Must be unique within a push. + */ + id: string; + /** Button text, shown as-is (surrounding whitespace trimmed). Also its accessible name. */ + label: string; + /** + * Optional [Material Design Icon](https://pictogrammer.com/library/mdi/) + * name — the same vocabulary a payload `icon` element accepts, resolved + * the same way (`mdi:` prefix optional, e.g. `send`, `mdi:home-assistant`). + * The designer bundles the full MDI set for the payload's icon element + * anyway, so every one of those names is available to a host at no added + * bundle size and with no icon dependency of its own. An unknown name is + * rejected, not ignored. + */ + icon?: string; + /** Button chrome; defaults to `'normal'`. */ + severity?: HostActionSeverity; + /** + * Whether this action reads the designer's payload; defaults to `true`. + * + * A payload-carrying action is disabled while the YAML editor is blocked by + * a parse/schema error. An action that does *not* need the payload + * (host-side settings, a reconnect, a help link) sets `false` and stays + * clickable throughout; it still receives the last valid payload, exactly + * as {@link MountHandle.getPayload} documents for a blocked document. + */ + needsPayload?: boolean; + /** + * When set, the button renders visibly disabled and this text is what the + * user gets on hover ("Display offline", "No target selected"). Clearing it + * in a later push re-enables the button — this is the field hosts re-push + * as their own state changes. + */ + disabledReason?: string; +} + +/** + * Third argument of `onAction` — the opaque ids that accompany the payload. + */ +export declare interface HostActionContext { + /** + * The selected target's opaque host id (issue #106), or `undefined` when + * the design is not pinned to one — no targets pushed, none picked yet, or + * the user switched to the virtual display. Always the same value the last + * {@link MountOptions.onTargetSelected} call reported. + */ + targetId?: string; +} + +/** + * Fired when the user clicks a host-registered action. Save and send are host + * actions — the designer has no save channel of its own (ADR-018). + * + * `payload` is the current drawcustom YAML — the exact string + * {@link MountHandle.getPayload} returns at that instant (same serializer, + * same pending-edit flush), so a host never has to reconcile two readings of + * the same design. + */ +export declare type HostActionHandler = (id: string, payload: string, context: HostActionContext) => void; + +/** + * How prominently an action's button warns before it is clicked (issue #108, + * ADR-018): + * + * - `'normal'` (default) — regular button chrome. + * - `'caution'` — orange: the action reaches beyond the designer, e.g. the + * OpenDisplay integration's Send-to-display drives physical hardware. + * - `'danger'` — red: the action destroys or overwrites something. + * + * Severity is *presentation only*. The designer never infers meaning from it + * — confirmation, auth and the actual call stay host-side. + */ +export declare type HostActionSeverity = 'normal' | 'caution' | 'danger'; + +/** + * Host asset resolver — the LAST tier of asset resolution (issue #138, + * ADR-002 amendment). + * + * A payload may reference fonts and images by bare name (`Ubuntu-R.ttf`, + * `logo.png`): that is how hand-written drawcustom payloads address the + * integration's own font/media directories. The designer cannot know those + * directories, so an embedding host supplies a resolver and the designer asks + * it for any reference it could not resolve locally: + * + * 1. local content map (uploaded via Content Manager, ADR-002) + * 2. bundled assets (`ppb.ttf`, `rbm.ttf`, the showcase image) + * 3. **this tier** — the host, by name + * + * The contract is deliberately `name -> asset`: search paths, media + * directories and integration layout are the HOST's business, so the designer + * learns no domain vocabulary (ADR-018). A `null` answer, a rejection, a + * silence past {@link HOST_ASSET_TIMEOUT_MS} or an out-of-contract value all + * settle as "not supplied" and reach the user as the existing explicit + * render-error state for the element referencing it — never a silent skip and + * never a plausible-looking wrong render (issue #10). + */ +export declare type HostAssetResolver = (kind: AssetKind, name: string) => Promise; + +/** + * What a display *is* — the description driving canvas setup, carried by every + * {@link HostTarget}. Mirrors the payload shape of the OpenDisplay HA + * integration's `capabilities.py` so a host-side adapter can pass it through + * unchanged. All fields optional; anything a display does not declare comes + * from the designer's canonical defaults, never from the display previously in + * effect. + */ +export declare interface HostCapabilities { + /** Physical panel width in pixels (before rotation). */ + pixel_width?: number; + /** Physical panel height in pixels (before rotation). */ + pixel_height?: number; + /** Mounting rotation in degrees; only quarter turns are representable. */ + rotation_degrees?: number; + /** Drawing-surface width after rotation; preferred over pixel_width. */ + render_width?: number; + /** Drawing-surface height after rotation; preferred over pixel_height. */ + render_height?: number; + /** OpenDisplay Basic Standard colour scheme (0x00 BW … 0x04 six-color). */ + color_scheme?: number; + /** Accent color name, e.g. 'red' or 'yellow'. */ + accent_color?: string; + /** Palette color names, e.g. ['black', 'white', 'red']. */ + available_colors?: string[]; + /** Palette name -> hex map, e.g. { black: '#000000', … }. */ + color_map?: Record; + /** Whether the palette hexes were measured on real hardware. */ + palette_measured?: boolean; +} + +/** + * Second argument of {@link HostPreviewRenderer} — the same + * "payload plus opaque ids" shape {@link HostActionContext} carries, extended + * with the geometry and the service options the render depends on. + */ +export declare interface HostPreviewContext { + /** + * The selected target's opaque host id (issue #106), or `undefined` when the + * design is not pinned to one — exactly the value {@link HostActionContext} + * reports at the same instant. + */ + targetId?: string; + /** + * The canvas the payload is authored against. Always present: a payload's + * coordinates are meaningless without the surface they refer to, and the + * designer always knows it — a display-config change (resolution pick, + * re-orientation) re-requests the render, so a provider that renders at its + * own idea of the size answers a changed request with an image of the wrong + * shape, which the designer letterboxes visibly rather than stretching. + */ + display: HostPreviewDisplayGeometry; + /** + * The service options this render must honour. Always present — the designer + * always knows its own dither mode, so a host never has to guard for it. + */ + service: HostPreviewServiceOptions; +} + +/** + * The **logical drawing surface** the payload is authored against — the + * coordinate space its `x`/`y` values live in, and therefore what a host has to + * render at for the image to mean anything beside the design. + * + * Already oriented: {@link HostPreviewDisplayGeometry.width}/`height` are + * swapped for a quarter turn (issue #139), exactly as upstream `imagegen` + * creates its canvas before drawing, and `rotation` says which way round the + * panel holds that surface. Never the raw physical panel size, and never a + * transform to apply to the returned image. + */ +export declare interface HostPreviewDisplayGeometry { + width: number; + height: number; + /** The orientation `width`/`height` are already expressed in. */ + rotation: 0 | 90 | 180 | 270; +} + +/** + * Renders the current payload host-side and hands the finished image back + * (issue #109, ADR-018 preview seam). + * + * When a host supplies one, the designer offers a **Display preview** toggle + * next to its canvas heading; turning it on replaces the designer's own + * client-side preview with this image — a real server-side render, not another + * client approximation, which is what makes it usable as the + * [ADR-007](../../docs/adr/ADR-007-hybrid-rendering.md) pixel-parity + * reference. Every edit affordance is inert while it shows; Copy/Download PNG, + * zoom and the dither control keep working, and dither re-requests. + * + * - Resolve with a `Blob` (`image/png`, `image/*`) or with a URL string + * (`data:`, `blob:`, `http(s):`) the designer can point an `` at. A + * URL must be readable by the host page for Copy/Download PNG to reach the + * bytes. + * - **Reject to report failure.** The designer shows an explicit error in the + * preview area — the rejection's `message` when it has one — and shows no + * image at all: a stated error beats a stale or wrong render. + * - Called again (debounced) whenever anything it was given changes while the + * preview shows: a `setPayload()` push, the display config (resolution, + * orientation), the selected target, the dither option. Responses are matched + * to their request, so a slow answer that a newer request has already + * superseded is discarded rather than painted. + * - Must be a function when supplied — anything else throws out of `mount()`, + * like a malformed action or target list does. + * + * A stable closure fixed at mount: ADR-018 pushes data, never functions. + */ +export declare type HostPreviewRenderer = (payload: string, context: HostPreviewContext) => Promise; + +/** + * The service options a host-side render must honour, carried by every + * {@link HostPreviewContext} (issue #109, ADR-018 preview seam). + * + * Deliberately minimal: the designer sends the options it actually owns a + * control for. The full drawcustom service-options seam is formalized in + * [issue #105](https://github.com/schlomo/odl-drawcustom-designer/issues/105) + * — this object is where it lands, and it grows additively (a host reads the + * fields it knows). + */ +export declare interface HostPreviewServiceOptions { + /** + * The dither mode the designer's own dither control currently holds, in the + * drawcustom `dither` service option's own domain (`src/core/schema/service.ts`): + * `0` flat, `1`, `2` ordered halftone. The designer's preview control + * produces `0` or `2` today. + * + * A provider **must** honour it: changing the control re-requests the + * preview, so a provider that ignores the value answers a changed request + * with an unchanged image and the designer shows a preview that contradicts + * its own dither setting. + */ + dither: 0 | 1 | 2; +} + +/** A pushed state value with optional attributes and an optional display name. */ +export declare interface HostState { + state: string | number | boolean; + attributes?: Record; + /** + * Human-readable label for this state key (issue #107, ADR-018 state + * catalog) — what the referenced-states panel shows instead of the raw key + * ("Living-room temperature", not `sensor.demo_temperature`). + * + * Presentation only, and re-pushable like every other field: templates never + * see it (a payload reads `states()`/`state_attr()`, which are unaffected by + * whether the host named the key), and the designer never parses meaning out + * of it. Surrounding whitespace is trimmed; a blank name counts as none, and + * an unnamed key shows as its key. + */ + name?: string; +} + +/** + * Host-pushed states: state key -> state value or {state, attributes, name}. + * The keys are the host's own identifiers, opaque to the designer — they are + * what a payload's templates name (`states('…')`, `state_attr('…', '…')`). + * + * When provided, this **replaces the State Simulator entirely** (issue #107, + * ADR-018 Simulator policy): the designer shows a read-only referenced-states + * panel instead, and the full catalog stays reachable through YAML/template + * autocomplete. + * + * Ownership contract (issue #110): treated as an **immutable snapshot** at + * the moment `setStates()` is called. Repeated pushes are diffed + * structurally against the previously applied object to keep a 4x/s + * full-registry push cheap (no re-render, no template re-evaluation when + * nothing changed) — that diff compares by value against the retained + * reference, not by cloning, so **mutate-and-repush is unsupported**: + * mutating this same object in place and calling `setStates()` again with + * that reference is invisible to the diff and silently treated as + * "unchanged". Construct a fresh object per push instead (see + * docs/embedding.md's `states` section). + */ +export declare type HostStates = Record; + +/** + * Fired on a status transition (issue #133) — a YAML validity flip or a + * {@link DesignerStatus.payloadRevision} change — debounced so a burst of + * keystrokes or drag updates yields one call, not one per commit. Not fired + * for a selection change alone, and not fired for the initial status observed + * at mount (read {@link MountHandle.getStatus} for that). Delivery is capped + * at 1 second after the first pending transition, however many times the + * debounce gets rescheduled in between — something that keeps re-triggering + * it without ever settling cannot postpone delivery indefinitely. + * + * The delivered status is always **live**: read fresh (and flushed, per + * {@link MountHandle.getStatus}) at the moment the debounce settles, never the + * value captured when the debounce was scheduled — a flip that reverts to the + * last-notified truth before the debounce settles delivers no call at all + * (there is nothing new to report), and a flip that settles on a different + * truth delivers exactly that, never an intermediate one from partway through + * the window. A host that reacts to this callback and calls + * {@link MountHandle.getStatus} inside it always sees the identical value. + * + * A stable closure fixed at mount, like `onAction`: ADR-018 pushes data, + * never functions, so there is no update channel for it. + */ +export declare type HostStatusChangeHandler = (status: DesignerStatus) => void; + +/** + * One display the host knows about (issue #106, ADR-018 targets seam) — the + * designer's single display channel. + * + * The host pushes the list, the designer renders a picker inside its own + * display-config area, and selecting an entry adopts that display's + * capabilities behind the existing lock (issue #70). A **one-element list is + * adopted and locked without a pick** (issue #121): that is how a + * single-display host says "this is the display". The id is **opaque**: it + * round-trips through `onTargetSelected` and `onAction`'s context untouched, + * and the designer never learns what it names (ADR-018: domain-neutral + * vocabulary — "target", never "entity"). + */ +export declare interface HostTarget { + /** + * Opaque, host-defined identity, echoed back by `onTargetSelected` and + * `onAction`. Also the list's diff key: re-pushing the same id keeps a + * selection on it. Must be unique within a push. + */ + id: string; + /** Picker entry text, shown as-is (surrounding whitespace trimmed). */ + label: string; + /** + * The display this target *is* ({@link HostCapabilities}) — what the canvas, + * palette and orientation are set from when this target is adopted. Only the + * documented fields are retained; the copy the designer keeps is frozen, so + * mutating the pushed object afterwards cannot change what the picker + * applies, and a re-push carrying different values is recognised as the host + * re-defining this display. + */ + capabilities: HostCapabilities; +} + +/** + * Called when the effective display target changes (issue #106). + * + * `null` means "no target": the user picked the virtual display, unlocked the + * display config, or has not picked anything yet. Fires only on a *change* — + * including the one a single-element `targets` push makes by adopting that + * display (issue #121) — and never as a side effect of a `setTargets` push + * that leaves the selection alone: a push that removes the selected display + * keeps it (marked stale) rather than switching. + * + * A stable closure fixed at mount: ADR-018 pushes data, never functions. + */ +export declare type HostTargetSelectedHandler = (targetId: string | null) => void; + +/** + * Mount the designer into an arbitrary host container (issue #20, ADR-010). + * Renders into an open shadow root on the container — created here, or + * reused when the host attached one already (issue #21) — so styles are + * isolated in both directions. + * + * The host pushes data through the returned handle; the designer never + * persists the payload itself — the host reads the current drawcustom YAML + * through `getPayload()`, or receives it with the action the user clicked + * (ADR-018). Invalid `payload` YAML throws synchronously (here and in + * `setPayload`). + * + * This is the embedded host adapter over {@link mountDesigner} (ADR-017); + * the standalone SPA is a sibling adapter over the same lifecycle. + */ +export declare function mount(container: HTMLElement, options?: MountOptions): MountHandle; + +export declare interface MountHandle { + /** + * The designer build's version (issue #23, reworked 2026-07-29: git tags + * are the sole version source, `package.json` stays pinned at `0.0.0`), + * e.g. `'1.0.0'`. A release build bakes in the tag-derived version via the + * `APP_VERSION` env var (`tools/autoRelease.ts` sets it, `tools/version.ts` + * resolves it); any other build (local dev, CI `checks`) falls back to + * `'0.0.0-dev'`, and Vitest gets the fixed string `'test'`. Same value as + * the library's `version` export (`src/embed/index.ts`); handy when a host + * only has the handle. + */ + readonly version: string; + /** Unmount the designer and remove everything from the container. */ + destroy(): void; + /** + * Push a full replacement state map for template preview. Treat the passed + * object as an immutable snapshot — see `HostStates`'s ownership contract + * above; mutating it and calling `setStates()` again with the same reference + * is unsupported and gets treated as a no-op push. + * + * Throws on a malformed map (a non-primitive or missing `state`, a + * non-object `attributes`, a non-string `name`, or a `states` argument that + * is not an object) with a message naming the offending key, and **changes + * nothing** when it does: no values, no names, no Simulator-off latch, and + * the rejected map never becomes the last-applied push the diff compares + * against — so the same bad map fails again rather than being deduped, and a + * corrected one applies normally. + */ + setStates(states: HostStates): void; + /** Replace the current payload with new drawcustom YAML (throws on invalid YAML). */ + setPayload(payload: string): void; + /** + * Replace the host action buttons (issue #108). Everything pushed at mount + * is re-pushable (ADR-018), and this is the channel hosts use to keep + * labels and `disabledReason`s live: push the full list again whenever host + * state changes (connection lost, target deselected). The designer diffs — + * an unchanged list costs no re-render — and an empty list removes all + * action chrome. + * + * Throws on a malformed list (unknown `icon` or `severity`, missing or + * duplicate `id`, missing `label`) without changing what is on screen, and + * on any non-empty list when `mount()` was given no `onAction` — the + * handler is fixed at mount, so those buttons could never fire. + */ + setActions(actions: readonly HostAction[]): void; + /** + * Replace the display targets the picker offers (issue #106). Everything + * pushed at mount is re-pushable (ADR-018), and targets are the channel a + * host uses as its own display inventory changes: a display that appears + * shows up in the picker without a reload, and the designer diffs the list + * so an unchanged re-push costs no re-render. + * + * A **one-element** push is adopted and locked straight away (issue #121) — + * a single display is not a choice — but only while the user has made no + * display choice of their own; after that, nothing but a pick moves the + * canvas. + * + * Otherwise a push never moves the canvas on its own, and never overrides + * the user: if it **removes the currently selected target**, the designer keeps that + * display's last-known capabilities and lock state and marks the selection + * stale ("display no longer available") instead of silently switching or + * unlocking. Pushing the target back clears the stale marker. + * + * Throws on a malformed list (missing or duplicate `id`, missing `label`, + * missing `capabilities`) without changing what is on screen. + */ + setTargets(targets: readonly HostTarget[]): void; + /** Switch the container-scoped theme. */ + setTheme(theme: EmbedTheme): void; + /** + * The designer's current drawcustom YAML payload (issue #104) — exactly the + * string an `onAction` callback receives at this instant. Same serializer, + * same underlying elements state; there is no second source of truth. + * + * - **Never returns `undefined`, and throws only after `destroy()`** — like + * every other method on this handle, it rejects a destroyed mount + * (`MountHandle used after destroy()`). On a live mount it always answers + * with a string, including in the brief window right after + * `mount()`/`mountStandaloneApp()` return but before React has committed + * and run its effects, when it reports the bootstrap payload the designer + * is about to render. + * - **Never lags a pending edit.** The YAML editor commits typed text to + * the canvas model on an 80ms debounce (or on blur); `getPayload()` + * forces that flush first, so a call made mid-keystroke reflects the + * text already typed — the same content an action click sends (a click + * blurs the editor, which flushes the debounce, before the payload is + * read). + * - **Never resurrects a pre-push draft.** A `setPayload()` push is + * authoritative: it discards any debounced edit typed before it, so the + * flush above can only ever commit text typed *after* the last push. + * - **While the YAML editor is blocked** by a parse/schema error (every + * payload-carrying action is disabled), returns the last valid payload — + * the canvas model is frozen there too, so this is exactly what the last + * action would have sent, and the only way to read anything at all. + * + * See [`docs/embedding.md`](../../docs/embedding.md#getpayload-issue-104) + * for the full semantics and rationale. + */ + getPayload(): string; + /** + * The designer's own rasterization of the current payload, right now — the + * exact bytes its own Copy PNG / Download PNG would produce outside + * Display preview, full font/renderer fidelity included. Exists so a host + * with no rendering backend of its own (a demo, a thin adapter) can answer + * `renderPreview` by reading this instead of writing a second renderer — + * the same "read access" fix {@link getPayload} is for reading the payload + * instead of driving the Save button. + * + * - **Independent of Display preview.** Always the client-side render, even + * while the toggle is on and a host image is showing — a `renderPreview` + * provider built on this can therefore never call itself. + * - **Rejects, never throws synchronously**, while the designer has not + * yet committed its first render (the brief window right after + * `mount()`/`mountStandaloneApp()` returns) — there is no bootstrap + * fallback for a raster the way {@link getPayload} falls back to + * serialized YAML, since fonts/assets have not loaded yet either. + * - Throws (does not reject) `MountHandle used after destroy()`, like every + * other method on this handle. + */ + getPngBlob(): Promise; + /** + * The designer's current status (issue #133, ADR-018's observability + * clause) — a small, frozen, derived snapshot; never authoritative, and it + * carries no designer internals (no elements, no YAML text). + * + * **Flushes a pending debounced YAML edit first**, exactly like + * {@link getPayload} does — the two must never disagree about whether there + * is unsaved, uncommitted text: a call made moments after typing already + * reflects the typed edit in `payloadRevision`/`lastEditAt`, not the state + * as of 80ms ago. Calling `getStatus()` before `getPayload()` or vice versa + * flushes the same way either order. + * + * Always answers synchronously, including in the brief pre-registration + * window right after `mount()`/`mountStandaloneApp()` returns — before that + * registration has run, reports a default status (`yamlValid: true`, no + * edits yet, revision `0`, nothing selected), the same "safe default before + * the shell exists" shape {@link getPayload}'s bootstrap fallback uses. + * Throws `MountHandle used after destroy()` like every other method here. + */ + getStatus(): DesignerStatus; +} + +export declare interface MountOptions { + /** Initial drawcustom YAML payload (list of draw elements). */ + payload?: string; + /** + * Initial states for template preview. A mount option *is* an initial push + * (ADR-018 seam grammar): identical to calling {@link MountHandle.setStates} + * before the first painted frame, validated the same way — a malformed map + * throws out of `mount()`, like an invalid `payload`. + */ + states?: HostStates; + /** Initial theme; defaults to 'light'. */ + theme?: EmbedTheme; + /** + * Initial host action buttons (issue #108). A mount option *is* an initial + * push (ADR-018 seam grammar): identical to calling + * {@link MountHandle.setActions} before the first painted frame, and + * re-pushable from then on. A malformed list throws out of `mount()`, like + * an invalid `payload`. + * + * Requires {@link MountOptions.onAction}: registering actions no one can + * hear about is rejected rather than rendered. + */ + actions?: readonly HostAction[]; + /** + * Called when the user clicks one of the {@link MountOptions.actions}. + * A stable closure — there is no update channel for it (ADR-018: data is + * pushed, functions are not) — which is why a mount without it can never + * take actions, at mount time or through a later `setActions()`. + */ + onAction?: HostActionHandler; + /** + * Initial display targets (issue #106) — the designer's only display + * channel. A mount option *is* an initial push (ADR-018 seam grammar): + * identical to calling {@link MountHandle.setTargets} before the first + * painted frame, and re-pushable from then on. A malformed list throws out + * of `mount()`, like an invalid `payload`. + * + * A list the user can choose between only says what they *can* pick — it + * never moves the canvas by itself. A **one-element** list says "this is the + * display": it is adopted and locked straight away, so a single-display host + * needs no pick and no seeding option (issue #121). + */ + targets?: readonly HostTarget[]; + /** + * Called when the selected display target changes, including to `null` for + * the virtual display. Optional: a host that only needs the id when + * something happens gets it from `onAction`'s context instead. Hosts that + * *react* to the selection — re-pushing `actions` with a + * `disabledReason: 'No display selected'`, say — want this. + */ + onTargetSelected?: HostTargetSelectedHandler; + /** + * Host-side render of the current payload (issue #109). Supplying one is + * what makes the designer offer its **Display preview** toggle at all — no + * provider, no toggle and no other visual trace, exactly like `actions` and + * `targets` (conditional chrome; standalone output is unchanged). + * + * A stable closure — there is no update channel for it (ADR-018: data is + * pushed, functions are not). + */ + renderPreview?: HostPreviewRenderer; + /** + * Resolve a font or image the designer could not resolve locally + * ([issue #138](https://github.com/schlomo/odl-drawcustom-designer/issues/138)). + * + * Payloads reference assets by the name the *host* understands + * (`Ubuntu-R.ttf`, `logo.png`) — for the OpenDisplay integration, a file in + * its font/media directories. The designer asks this closure for any + * reference left over after its own tiers (Content Manager uploads, bundled + * assets), and caches what comes back for the life of the mount: + * + * - a `Blob` — the asset's bytes (the safest answer: no CORS, no tainting); + * - a `string` — a URL the designer can load (data:, blob:, or same-origin); + * - `null` — "I don't have that", which surfaces as the designer's explicit + * render-error state on every element referencing the asset, naming it and + * saying the host could not supply it. A rejection reads the same way, + * with its reason. Never a silent skip, never a wrong render. + * + * Search paths, directory layout and permissions stay host-side: the + * contract is `name -> asset` and nothing else (ADR-018). A stable closure + * fixed at mount — like `onAction`, there is no update channel for it; an + * unresolvable name is retried after a short interval, so a host whose store + * comes back can answer differently without a remount. + */ + resolveAsset?: HostAssetResolver; + /** + * Called on a designer status transition (issue #133) — see + * {@link HostStatusChangeHandler}. Optional: a host that only wants status + * on demand reads {@link MountHandle.getStatus} instead and never supplies + * this. + * + * A stable closure fixed at mount — there is no update channel for it + * (ADR-018: data is pushed, functions are not). + */ + onStatusChange?: HostStatusChangeHandler; +} + +/** + * Runtime version (issue #23, reworked 2026-07-29: git tags are the sole + * version source, not package.json — see `tools/version.ts`). Baked in at + * build time (`tools/buildDefines.ts`) from the release script's + * `APP_VERSION` env var; a non-release build (local dev, CI `checks`) has + * none set and falls back to `0.0.0-dev`. Re-exported from + * `src/embed/index.ts` (`version`) and surfaced on `MountHandle.version`. + */ +export declare const version: string; + +export { } diff --git a/custom_components/opendisplay/designer/frontend/vendor/odl-drawcustom-designer.js b/custom_components/opendisplay/designer/frontend/vendor/odl-drawcustom-designer.js new file mode 100644 index 00000000..0afcefb0 --- /dev/null +++ b/custom_components/opendisplay/designer/frontend/vendor/odl-drawcustom-designer.js @@ -0,0 +1,77261 @@ +//#region \0rolldown/runtime.js +var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescriptor, r = Object.getOwnPropertyNames, i = Object.getPrototypeOf, a = Object.prototype.hasOwnProperty, o = (e, t) => () => (t || (e((t = { exports: {} }).exports, t), e = null), t.exports), s = (e, n) => { + let r = {}; + for (var i in e) t(r, i, { + get: e[i], + enumerable: !0 + }); + return n || t(r, Symbol.toStringTag, { value: "Module" }), r; +}, c = (e, i, o, s) => { + if (i && typeof i == "object" || typeof i == "function") for (var c = r(i), l = 0, u = c.length, d; l < u; l++) d = c[l], !a.call(e, d) && d !== o && t(e, d, { + get: ((e) => i[e]).bind(null, d), + enumerable: !(s = n(i, d)) || s.enumerable + }); + return e; +}, l = (n, r, o) => (o = n == null ? {} : e(i(n)), c(r || !n || !n.__esModule || !a.call(n, "default") ? t(o, "default", { + value: n, + enumerable: !0 +}) : o, n)), u = /* @__PURE__ */ o(((e) => { + var t = Symbol.for("react.transitional.element"), n = Symbol.for("react.portal"), r = Symbol.for("react.fragment"), i = Symbol.for("react.strict_mode"), a = Symbol.for("react.profiler"), o = Symbol.for("react.consumer"), s = Symbol.for("react.context"), c = Symbol.for("react.forward_ref"), l = Symbol.for("react.suspense"), u = Symbol.for("react.memo"), d = Symbol.for("react.lazy"), f = Symbol.for("react.activity"), p = Symbol.iterator; + function m(e) { + return typeof e != "object" || !e ? null : (e = p && e[p] || e["@@iterator"], typeof e == "function" ? e : null); + } + var h = { + isMounted: function() { + return !1; + }, + enqueueForceUpdate: function() {}, + enqueueReplaceState: function() {}, + enqueueSetState: function() {} + }, g = Object.assign, _ = {}; + function v(e, t, n) { + this.props = e, this.context = t, this.refs = _, this.updater = n || h; + } + v.prototype.isReactComponent = {}, v.prototype.setState = function(e, t) { + if (typeof e != "object" && typeof e != "function" && e != null) throw Error("takes an object of state variables to update or a function which returns an object of state variables."); + this.updater.enqueueSetState(this, e, t, "setState"); + }, v.prototype.forceUpdate = function(e) { + this.updater.enqueueForceUpdate(this, e, "forceUpdate"); + }; + function y() {} + y.prototype = v.prototype; + function b(e, t, n) { + this.props = e, this.context = t, this.refs = _, this.updater = n || h; + } + var x = b.prototype = new y(); + x.constructor = b, g(x, v.prototype), x.isPureReactComponent = !0; + var S = Array.isArray; + function C() {} + var w = { + H: null, + A: null, + T: null, + S: null + }, T = Object.prototype.hasOwnProperty; + function E(e, n, r) { + var i = r.ref; + return { + $$typeof: t, + type: e, + key: n, + ref: i === void 0 ? null : i, + props: r + }; + } + function ee(e, t) { + return E(e.type, t, e.props); + } + function D(e) { + return typeof e == "object" && !!e && e.$$typeof === t; + } + function te(e) { + var t = { + "=": "=0", + ":": "=2" + }; + return "$" + e.replace(/[=:]/g, function(e) { + return t[e]; + }); + } + var ne = /\/+/g; + function re(e, t) { + return typeof e == "object" && e && e.key != null ? te("" + e.key) : t.toString(36); + } + function ie(e) { + switch (e.status) { + case "fulfilled": return e.value; + case "rejected": throw e.reason; + default: switch (typeof e.status == "string" ? e.then(C, C) : (e.status = "pending", e.then(function(t) { + e.status === "pending" && (e.status = "fulfilled", e.value = t); + }, function(t) { + e.status === "pending" && (e.status = "rejected", e.reason = t); + })), e.status) { + case "fulfilled": return e.value; + case "rejected": throw e.reason; + } + } + throw e; + } + function ae(e, r, i, a, o) { + var s = typeof e; + (s === "undefined" || s === "boolean") && (e = null); + var c = !1; + if (e === null) c = !0; + else switch (s) { + case "bigint": + case "string": + case "number": + c = !0; + break; + case "object": switch (e.$$typeof) { + case t: + case n: + c = !0; + break; + case d: return c = e._init, ae(c(e._payload), r, i, a, o); + } + } + if (c) return o = o(e), c = a === "" ? "." + re(e, 0) : a, S(o) ? (i = "", c != null && (i = c.replace(ne, "$&/") + "/"), ae(o, r, i, "", function(e) { + return e; + })) : o != null && (D(o) && (o = ee(o, i + (o.key == null || e && e.key === o.key ? "" : ("" + o.key).replace(ne, "$&/") + "/") + c)), r.push(o)), 1; + c = 0; + var l = a === "" ? "." : a + ":"; + if (S(e)) for (var u = 0; u < e.length; u++) a = e[u], s = l + re(a, u), c += ae(a, r, i, s, o); + else if (u = m(e), typeof u == "function") for (e = u.call(e), u = 0; !(a = e.next()).done;) a = a.value, s = l + re(a, u++), c += ae(a, r, i, s, o); + else if (s === "object") { + if (typeof e.then == "function") return ae(ie(e), r, i, a, o); + throw r = String(e), Error("Objects are not valid as a React child (found: " + (r === "[object Object]" ? "object with keys {" + Object.keys(e).join(", ") + "}" : r) + "). If you meant to render a collection of children, use an array instead."); + } + return c; + } + function oe(e, t, n) { + if (e == null) return e; + var r = [], i = 0; + return ae(e, r, "", "", function(e) { + return t.call(n, e, i++); + }), r; + } + function se(e) { + if (e._status === -1) { + var t = e._result; + t = t(), t.then(function(t) { + (e._status === 0 || e._status === -1) && (e._status = 1, e._result = t); + }, function(t) { + (e._status === 0 || e._status === -1) && (e._status = 2, e._result = t); + }), e._status === -1 && (e._status = 0, e._result = t); + } + if (e._status === 1) return e._result.default; + throw e._result; + } + var O = typeof reportError == "function" ? reportError : function(e) { + if (typeof window == "object" && typeof window.ErrorEvent == "function") { + var t = new window.ErrorEvent("error", { + bubbles: !0, + cancelable: !0, + message: typeof e == "object" && e && typeof e.message == "string" ? String(e.message) : String(e), + error: e + }); + if (!window.dispatchEvent(t)) return; + } else if (typeof process == "object" && typeof process.emit == "function") { + process.emit("uncaughtException", e); + return; + } + console.error(e); + }, k = { + map: oe, + forEach: function(e, t, n) { + oe(e, function() { + t.apply(this, arguments); + }, n); + }, + count: function(e) { + var t = 0; + return oe(e, function() { + t++; + }), t; + }, + toArray: function(e) { + return oe(e, function(e) { + return e; + }) || []; + }, + only: function(e) { + if (!D(e)) throw Error("React.Children.only expected to receive a single React element child."); + return e; + } + }; + e.Activity = f, e.Children = k, e.Component = v, e.Fragment = r, e.Profiler = a, e.PureComponent = b, e.StrictMode = i, e.Suspense = l, e.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE = w, e.__COMPILER_RUNTIME = { + __proto__: null, + c: function(e) { + return w.H.useMemoCache(e); + } + }, e.cache = function(e) { + return function() { + return e.apply(null, arguments); + }; + }, e.cacheSignal = function() { + return null; + }, e.cloneElement = function(e, t, n) { + if (e == null) throw Error("The argument must be a React element, but you passed " + e + "."); + var r = g({}, e.props), i = e.key; + if (t != null) for (a in t.key !== void 0 && (i = "" + t.key), t) !T.call(t, a) || a === "key" || a === "__self" || a === "__source" || a === "ref" && t.ref === void 0 || (r[a] = t[a]); + var a = arguments.length - 2; + if (a === 1) r.children = n; + else if (1 < a) { + for (var o = Array(a), s = 0; s < a; s++) o[s] = arguments[s + 2]; + r.children = o; + } + return E(e.type, i, r); + }, e.createContext = function(e) { + return e = { + $$typeof: s, + _currentValue: e, + _currentValue2: e, + _threadCount: 0, + Provider: null, + Consumer: null + }, e.Provider = e, e.Consumer = { + $$typeof: o, + _context: e + }, e; + }, e.createElement = function(e, t, n) { + var r, i = {}, a = null; + if (t != null) for (r in t.key !== void 0 && (a = "" + t.key), t) T.call(t, r) && r !== "key" && r !== "__self" && r !== "__source" && (i[r] = t[r]); + var o = arguments.length - 2; + if (o === 1) i.children = n; + else if (1 < o) { + for (var s = Array(o), c = 0; c < o; c++) s[c] = arguments[c + 2]; + i.children = s; + } + if (e && e.defaultProps) for (r in o = e.defaultProps, o) i[r] === void 0 && (i[r] = o[r]); + return E(e, a, i); + }, e.createRef = function() { + return { current: null }; + }, e.forwardRef = function(e) { + return { + $$typeof: c, + render: e + }; + }, e.isValidElement = D, e.lazy = function(e) { + return { + $$typeof: d, + _payload: { + _status: -1, + _result: e + }, + _init: se + }; + }, e.memo = function(e, t) { + return { + $$typeof: u, + type: e, + compare: t === void 0 ? null : t + }; + }, e.startTransition = function(e) { + var t = w.T, n = {}; + w.T = n; + try { + var r = e(), i = w.S; + i !== null && i(n, r), typeof r == "object" && r && typeof r.then == "function" && r.then(C, O); + } catch (e) { + O(e); + } finally { + t !== null && n.types !== null && (t.types = n.types), w.T = t; + } + }, e.unstable_useCacheRefresh = function() { + return w.H.useCacheRefresh(); + }, e.use = function(e) { + return w.H.use(e); + }, e.useActionState = function(e, t, n) { + return w.H.useActionState(e, t, n); + }, e.useCallback = function(e, t) { + return w.H.useCallback(e, t); + }, e.useContext = function(e) { + return w.H.useContext(e); + }, e.useDebugValue = function() {}, e.useDeferredValue = function(e, t) { + return w.H.useDeferredValue(e, t); + }, e.useEffect = function(e, t) { + return w.H.useEffect(e, t); + }, e.useEffectEvent = function(e) { + return w.H.useEffectEvent(e); + }, e.useId = function() { + return w.H.useId(); + }, e.useImperativeHandle = function(e, t, n) { + return w.H.useImperativeHandle(e, t, n); + }, e.useInsertionEffect = function(e, t) { + return w.H.useInsertionEffect(e, t); + }, e.useLayoutEffect = function(e, t) { + return w.H.useLayoutEffect(e, t); + }, e.useMemo = function(e, t) { + return w.H.useMemo(e, t); + }, e.useOptimistic = function(e, t) { + return w.H.useOptimistic(e, t); + }, e.useReducer = function(e, t, n) { + return w.H.useReducer(e, t, n); + }, e.useRef = function(e) { + return w.H.useRef(e); + }, e.useState = function(e) { + return w.H.useState(e); + }, e.useSyncExternalStore = function(e, t, n) { + return w.H.useSyncExternalStore(e, t, n); + }, e.useTransition = function() { + return w.H.useTransition(); + }, e.version = "19.2.8"; +})), d = /* @__PURE__ */ o(((e, t) => { + t.exports = u(); +})), f = /* @__PURE__ */ o(((e) => { + function t(e, t) { + var n = e.length; + e.push(t); + a: for (; 0 < n;) { + var r = n - 1 >>> 1, a = e[r]; + if (0 < i(a, t)) e[r] = t, e[n] = a, n = r; + else break a; + } + } + function n(e) { + return e.length === 0 ? null : e[0]; + } + function r(e) { + if (e.length === 0) return null; + var t = e[0], n = e.pop(); + if (n !== t) { + e[0] = n; + a: for (var r = 0, a = e.length, o = a >>> 1; r < o;) { + var s = 2 * (r + 1) - 1, c = e[s], l = s + 1, u = e[l]; + if (0 > i(c, n)) l < a && 0 > i(u, c) ? (e[r] = u, e[l] = n, r = l) : (e[r] = c, e[s] = n, r = s); + else if (l < a && 0 > i(u, n)) e[r] = u, e[l] = n, r = l; + else break a; + } + } + return t; + } + function i(e, t) { + var n = e.sortIndex - t.sortIndex; + return n === 0 ? e.id - t.id : n; + } + if (e.unstable_now = void 0, typeof performance == "object" && typeof performance.now == "function") { + var a = performance; + e.unstable_now = function() { + return a.now(); + }; + } else { + var o = Date, s = o.now(); + e.unstable_now = function() { + return o.now() - s; + }; + } + var c = [], l = [], u = 1, d = null, f = 3, p = !1, m = !1, h = !1, g = !1, _ = typeof setTimeout == "function" ? setTimeout : null, v = typeof clearTimeout == "function" ? clearTimeout : null, y = typeof setImmediate < "u" ? setImmediate : null; + function b(e) { + for (var i = n(l); i !== null;) { + if (i.callback === null) r(l); + else if (i.startTime <= e) r(l), i.sortIndex = i.expirationTime, t(c, i); + else break; + i = n(l); + } + } + function x(e) { + if (h = !1, b(e), !m) { + if (n(c) !== null) m = !0, S || (S = !0, D()); + else { + var t = n(l); + t !== null && re(x, t.startTime - e); + } + } + } + var S = !1, C = -1, w = 5, T = -1; + function E() { + return g ? !0 : !(e.unstable_now() - T < w); + } + function ee() { + if (g = !1, S) { + var t = e.unstable_now(); + T = t; + var i = !0; + try { + a: { + m = !1, h && (h = !1, v(C), C = -1), p = !0; + var a = f; + try { + b: { + for (b(t), d = n(c); d !== null && !(d.expirationTime > t && E());) { + var o = d.callback; + if (typeof o == "function") { + d.callback = null, f = d.priorityLevel; + var s = o(d.expirationTime <= t); + if (t = e.unstable_now(), typeof s == "function") { + d.callback = s, b(t), i = !0; + break b; + } + d === n(c) && r(c), b(t); + } else r(c); + d = n(c); + } + if (d !== null) i = !0; + else { + var u = n(l); + u !== null && re(x, u.startTime - t), i = !1; + } + } + break a; + } finally { + d = null, f = a, p = !1; + } + } + } finally { + i ? D() : S = !1; + } + } + } + var D; + if (typeof y == "function") D = function() { + y(ee); + }; + else if (typeof MessageChannel < "u") { + var te = new MessageChannel(), ne = te.port2; + te.port1.onmessage = ee, D = function() { + ne.postMessage(null); + }; + } else D = function() { + _(ee, 0); + }; + function re(t, n) { + C = _(function() { + t(e.unstable_now()); + }, n); + } + e.unstable_IdlePriority = 5, e.unstable_ImmediatePriority = 1, e.unstable_LowPriority = 4, e.unstable_NormalPriority = 3, e.unstable_Profiling = null, e.unstable_UserBlockingPriority = 2, e.unstable_cancelCallback = function(e) { + e.callback = null; + }, e.unstable_forceFrameRate = function(e) { + 0 > e || 125 < e ? console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported") : w = 0 < e ? Math.floor(1e3 / e) : 5; + }, e.unstable_getCurrentPriorityLevel = function() { + return f; + }, e.unstable_next = function(e) { + switch (f) { + case 1: + case 2: + case 3: + var t = 3; + break; + default: t = f; + } + var n = f; + f = t; + try { + return e(); + } finally { + f = n; + } + }, e.unstable_requestPaint = function() { + g = !0; + }, e.unstable_runWithPriority = function(e, t) { + switch (e) { + case 1: + case 2: + case 3: + case 4: + case 5: break; + default: e = 3; + } + var n = f; + f = e; + try { + return t(); + } finally { + f = n; + } + }, e.unstable_scheduleCallback = function(r, i, a) { + var o = e.unstable_now(); + switch (typeof a == "object" && a ? (a = a.delay, a = typeof a == "number" && 0 < a ? o + a : o) : a = o, r) { + case 1: + var s = -1; + break; + case 2: + s = 250; + break; + case 5: + s = 1073741823; + break; + case 4: + s = 1e4; + break; + default: s = 5e3; + } + return s = a + s, r = { + id: u++, + callback: i, + priorityLevel: r, + startTime: a, + expirationTime: s, + sortIndex: -1 + }, a > o ? (r.sortIndex = a, t(l, r), n(c) === null && r === n(l) && (h ? (v(C), C = -1) : h = !0, re(x, a - o))) : (r.sortIndex = s, t(c, r), m || p || (m = !0, S || (S = !0, D()))), r; + }, e.unstable_shouldYield = E, e.unstable_wrapCallback = function(e) { + var t = f; + return function() { + var n = f; + f = t; + try { + return e.apply(this, arguments); + } finally { + f = n; + } + }; + }; +})), p = /* @__PURE__ */ o(((e, t) => { + t.exports = f(); +})), m = /* @__PURE__ */ o(((e) => { + var t = d(); + function n(e) { + var t = "https://react.dev/errors/" + e; + if (1 < arguments.length) { + t += "?args[]=" + encodeURIComponent(arguments[1]); + for (var n = 2; n < arguments.length; n++) t += "&args[]=" + encodeURIComponent(arguments[n]); + } + return "Minified React error #" + e + "; visit " + t + " for the full message or use the non-minified dev environment for full errors and additional helpful warnings."; + } + function r() {} + var i = { + d: { + f: r, + r: function() { + throw Error(n(522)); + }, + D: r, + C: r, + L: r, + m: r, + X: r, + S: r, + M: r + }, + p: 0, + findDOMNode: null + }, a = Symbol.for("react.portal"); + function o(e, t, n) { + var r = 3 < arguments.length && arguments[3] !== void 0 ? arguments[3] : null; + return { + $$typeof: a, + key: r == null ? null : "" + r, + children: e, + containerInfo: t, + implementation: n + }; + } + var s = t.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE; + function c(e, t) { + if (e === "font") return ""; + if (typeof t == "string") return t === "use-credentials" ? t : ""; + } + e.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE = i, e.createPortal = function(e, t) { + var r = 2 < arguments.length && arguments[2] !== void 0 ? arguments[2] : null; + if (!t || t.nodeType !== 1 && t.nodeType !== 9 && t.nodeType !== 11) throw Error(n(299)); + return o(e, t, null, r); + }, e.flushSync = function(e) { + var t = s.T, n = i.p; + try { + if (s.T = null, i.p = 2, e) return e(); + } finally { + s.T = t, i.p = n, i.d.f(); + } + }, e.preconnect = function(e, t) { + typeof e == "string" && (t ? (t = t.crossOrigin, t = typeof t == "string" ? t === "use-credentials" ? t : "" : void 0) : t = null, i.d.C(e, t)); + }, e.prefetchDNS = function(e) { + typeof e == "string" && i.d.D(e); + }, e.preinit = function(e, t) { + if (typeof e == "string" && t && typeof t.as == "string") { + var n = t.as, r = c(n, t.crossOrigin), a = typeof t.integrity == "string" ? t.integrity : void 0, o = typeof t.fetchPriority == "string" ? t.fetchPriority : void 0; + n === "style" ? i.d.S(e, typeof t.precedence == "string" ? t.precedence : void 0, { + crossOrigin: r, + integrity: a, + fetchPriority: o + }) : n === "script" && i.d.X(e, { + crossOrigin: r, + integrity: a, + fetchPriority: o, + nonce: typeof t.nonce == "string" ? t.nonce : void 0 + }); + } + }, e.preinitModule = function(e, t) { + if (typeof e == "string") { + if (typeof t == "object" && t) { + if (t.as == null || t.as === "script") { + var n = c(t.as, t.crossOrigin); + i.d.M(e, { + crossOrigin: n, + integrity: typeof t.integrity == "string" ? t.integrity : void 0, + nonce: typeof t.nonce == "string" ? t.nonce : void 0 + }); + } + } else t ?? i.d.M(e); + } + }, e.preload = function(e, t) { + if (typeof e == "string" && typeof t == "object" && t && typeof t.as == "string") { + var n = t.as, r = c(n, t.crossOrigin); + i.d.L(e, n, { + crossOrigin: r, + integrity: typeof t.integrity == "string" ? t.integrity : void 0, + nonce: typeof t.nonce == "string" ? t.nonce : void 0, + type: typeof t.type == "string" ? t.type : void 0, + fetchPriority: typeof t.fetchPriority == "string" ? t.fetchPriority : void 0, + referrerPolicy: typeof t.referrerPolicy == "string" ? t.referrerPolicy : void 0, + imageSrcSet: typeof t.imageSrcSet == "string" ? t.imageSrcSet : void 0, + imageSizes: typeof t.imageSizes == "string" ? t.imageSizes : void 0, + media: typeof t.media == "string" ? t.media : void 0 + }); + } + }, e.preloadModule = function(e, t) { + if (typeof e == "string") { + if (t) { + var n = c(t.as, t.crossOrigin); + i.d.m(e, { + as: typeof t.as == "string" && t.as !== "script" ? t.as : void 0, + crossOrigin: n, + integrity: typeof t.integrity == "string" ? t.integrity : void 0 + }); + } else i.d.m(e); + } + }, e.requestFormReset = function(e) { + i.d.r(e); + }, e.unstable_batchedUpdates = function(e, t) { + return e(t); + }, e.useFormState = function(e, t, n) { + return s.H.useFormState(e, t, n); + }, e.useFormStatus = function() { + return s.H.useHostTransitionStatus(); + }, e.version = "19.2.8"; +})), h = /* @__PURE__ */ o(((e, t) => { + function n() { + if (!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ > "u" || typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE != "function")) try { + __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n); + } catch (e) { + console.error(e); + } + } + n(), t.exports = m(); +})), g = /* @__PURE__ */ o(((e) => { + var t = p(), n = d(), r = h(); + function i(e) { + var t = "https://react.dev/errors/" + e; + if (1 < arguments.length) { + t += "?args[]=" + encodeURIComponent(arguments[1]); + for (var n = 2; n < arguments.length; n++) t += "&args[]=" + encodeURIComponent(arguments[n]); + } + return "Minified React error #" + e + "; visit " + t + " for the full message or use the non-minified dev environment for full errors and additional helpful warnings."; + } + function a(e) { + return !(!e || e.nodeType !== 1 && e.nodeType !== 9 && e.nodeType !== 11); + } + function o(e) { + var t = e, n = e; + if (e.alternate) for (; t.return;) t = t.return; + else { + e = t; + do + t = e, t.flags & 4098 && (n = t.return), e = t.return; + while (e); + } + return t.tag === 3 ? n : null; + } + function s(e) { + if (e.tag === 13) { + var t = e.memoizedState; + if (t === null && (e = e.alternate, e !== null && (t = e.memoizedState)), t !== null) return t.dehydrated; + } + return null; + } + function c(e) { + if (e.tag === 31) { + var t = e.memoizedState; + if (t === null && (e = e.alternate, e !== null && (t = e.memoizedState)), t !== null) return t.dehydrated; + } + return null; + } + function l(e) { + if (o(e) !== e) throw Error(i(188)); + } + function u(e) { + var t = e.alternate; + if (!t) { + if (t = o(e), t === null) throw Error(i(188)); + return t === e ? e : null; + } + for (var n = e, r = t;;) { + var a = n.return; + if (a === null) break; + var s = a.alternate; + if (s === null) { + if (r = a.return, r !== null) { + n = r; + continue; + } + break; + } + if (a.child === s.child) { + for (s = a.child; s;) { + if (s === n) return l(a), e; + if (s === r) return l(a), t; + s = s.sibling; + } + throw Error(i(188)); + } + if (n.return !== r.return) n = a, r = s; + else { + for (var c = !1, u = a.child; u;) { + if (u === n) { + c = !0, n = a, r = s; + break; + } + if (u === r) { + c = !0, r = a, n = s; + break; + } + u = u.sibling; + } + if (!c) { + for (u = s.child; u;) { + if (u === n) { + c = !0, n = s, r = a; + break; + } + if (u === r) { + c = !0, r = s, n = a; + break; + } + u = u.sibling; + } + if (!c) throw Error(i(189)); + } + } + if (n.alternate !== r) throw Error(i(190)); + } + if (n.tag !== 3) throw Error(i(188)); + return n.stateNode.current === n ? e : t; + } + function f(e) { + var t = e.tag; + if (t === 5 || t === 26 || t === 27 || t === 6) return e; + for (e = e.child; e !== null;) { + if (t = f(e), t !== null) return t; + e = e.sibling; + } + return null; + } + var m = Object.assign, g = Symbol.for("react.element"), _ = Symbol.for("react.transitional.element"), v = Symbol.for("react.portal"), y = Symbol.for("react.fragment"), b = Symbol.for("react.strict_mode"), x = Symbol.for("react.profiler"), S = Symbol.for("react.consumer"), C = Symbol.for("react.context"), w = Symbol.for("react.forward_ref"), T = Symbol.for("react.suspense"), E = Symbol.for("react.suspense_list"), ee = Symbol.for("react.memo"), D = Symbol.for("react.lazy"), te = Symbol.for("react.activity"), ne = Symbol.for("react.memo_cache_sentinel"), re = Symbol.iterator; + function ie(e) { + return typeof e != "object" || !e ? null : (e = re && e[re] || e["@@iterator"], typeof e == "function" ? e : null); + } + var ae = Symbol.for("react.client.reference"); + function oe(e) { + if (e == null) return null; + if (typeof e == "function") return e.$$typeof === ae ? null : e.displayName || e.name || null; + if (typeof e == "string") return e; + switch (e) { + case y: return "Fragment"; + case x: return "Profiler"; + case b: return "StrictMode"; + case T: return "Suspense"; + case E: return "SuspenseList"; + case te: return "Activity"; + } + if (typeof e == "object") switch (e.$$typeof) { + case v: return "Portal"; + case C: return e.displayName || "Context"; + case S: return (e._context.displayName || "Context") + ".Consumer"; + case w: + var t = e.render; + return e = e.displayName, e ||= (e = t.displayName || t.name || "", e === "" ? "ForwardRef" : "ForwardRef(" + e + ")"), e; + case ee: return t = e.displayName || null, t === null ? oe(e.type) || "Memo" : t; + case D: + t = e._payload, e = e._init; + try { + return oe(e(t)); + } catch {} + } + return null; + } + var se = Array.isArray, O = n.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, k = r.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, ce = { + pending: !1, + data: null, + method: null, + action: null + }, le = [], ue = -1; + function de(e) { + return { current: e }; + } + function fe(e) { + 0 > ue || (e.current = le[ue], le[ue] = null, ue--); + } + function A(e, t) { + ue++, le[ue] = e.current, e.current = t; + } + var j = de(null), M = de(null), pe = de(null), N = de(null); + function me(e, t) { + switch (A(pe, t), A(M, e), A(j, null), t.nodeType) { + case 9: + case 11: + e = (e = t.documentElement) && (e = e.namespaceURI) ? Yd(e) : 0; + break; + default: if (e = t.tagName, t = t.namespaceURI) t = Yd(t), e = Xd(t, e); + else switch (e) { + case "svg": + e = 1; + break; + case "math": + e = 2; + break; + default: e = 0; + } + } + fe(j), A(j, e); + } + function he() { + fe(j), fe(M), fe(pe); + } + function P(e) { + e.memoizedState !== null && A(N, e); + var t = j.current, n = Xd(t, e.type); + t !== n && (A(M, e), A(j, n)); + } + function F(e) { + M.current === e && (fe(j), fe(M)), N.current === e && (fe(N), op._currentValue = ce); + } + var I, L; + function ge(e) { + if (I === void 0) try { + throw Error(); + } catch (e) { + var t = e.stack.trim().match(/\n( *(at )?)/); + I = t && t[1] || "", L = -1 < e.stack.indexOf("\n at") ? " ()" : -1 < e.stack.indexOf("@") ? "@unknown:0:0" : ""; + } + return "\n" + I + e + L; + } + var _e = !1; + function ve(e, t) { + if (!e || _e) return ""; + _e = !0; + var n = Error.prepareStackTrace; + Error.prepareStackTrace = void 0; + try { + var r = { DetermineComponentFrameRoot: function() { + try { + if (t) { + var n = function() { + throw Error(); + }; + if (Object.defineProperty(n.prototype, "props", { set: function() { + throw Error(); + } }), typeof Reflect == "object" && Reflect.construct) { + try { + Reflect.construct(n, []); + } catch (e) { + var r = e; + } + Reflect.construct(e, [], n); + } else { + try { + n.call(); + } catch (e) { + r = e; + } + e.call(n.prototype); + } + } else { + try { + throw Error(); + } catch (e) { + r = e; + } + (n = e()) && typeof n.catch == "function" && n.catch(function() {}); + } + } catch (e) { + if (e && r && typeof e.stack == "string") return [e.stack, r.stack]; + } + return [null, null]; + } }; + r.DetermineComponentFrameRoot.displayName = "DetermineComponentFrameRoot"; + var i = Object.getOwnPropertyDescriptor(r.DetermineComponentFrameRoot, "name"); + i && i.configurable && Object.defineProperty(r.DetermineComponentFrameRoot, "name", { value: "DetermineComponentFrameRoot" }); + var a = r.DetermineComponentFrameRoot(), o = a[0], s = a[1]; + if (o && s) { + var c = o.split("\n"), l = s.split("\n"); + for (i = r = 0; r < c.length && !c[r].includes("DetermineComponentFrameRoot");) r++; + for (; i < l.length && !l[i].includes("DetermineComponentFrameRoot");) i++; + if (r === c.length || i === l.length) for (r = c.length - 1, i = l.length - 1; 1 <= r && 0 <= i && c[r] !== l[i];) i--; + for (; 1 <= r && 0 <= i; r--, i--) if (c[r] !== l[i]) { + if (r !== 1 || i !== 1) do + if (r--, i--, 0 > i || c[r] !== l[i]) { + var u = "\n" + c[r].replace(" at new ", " at "); + return e.displayName && u.includes("") && (u = u.replace("", e.displayName)), u; + } + while (1 <= r && 0 <= i); + break; + } + } + } finally { + _e = !1, Error.prepareStackTrace = n; + } + return (n = e ? e.displayName || e.name : "") ? ge(n) : ""; + } + function ye(e, t) { + switch (e.tag) { + case 26: + case 27: + case 5: return ge(e.type); + case 16: return ge("Lazy"); + case 13: return e.child !== t && t !== null ? ge("Suspense Fallback") : ge("Suspense"); + case 19: return ge("SuspenseList"); + case 0: + case 15: return ve(e.type, !1); + case 11: return ve(e.type.render, !1); + case 1: return ve(e.type, !0); + case 31: return ge("Activity"); + default: return ""; + } + } + function be(e) { + try { + var t = "", n = null; + do + t += ye(e, n), n = e, e = e.return; + while (e); + return t; + } catch (e) { + return "\nError generating stack: " + e.message + "\n" + e.stack; + } + } + var xe = Object.prototype.hasOwnProperty, Se = t.unstable_scheduleCallback, Ce = t.unstable_cancelCallback, we = t.unstable_shouldYield, Te = t.unstable_requestPaint, Ee = t.unstable_now, De = t.unstable_getCurrentPriorityLevel, Oe = t.unstable_ImmediatePriority, R = t.unstable_UserBlockingPriority, ke = t.unstable_NormalPriority, Ae = t.unstable_LowPriority, je = t.unstable_IdlePriority, z = t.log, Me = t.unstable_setDisableYieldValue, Ne = null, Pe = null; + function B(e) { + if (typeof z == "function" && Me(e), Pe && typeof Pe.setStrictMode == "function") try { + Pe.setStrictMode(Ne, e); + } catch {} + } + var Fe = Math.clz32 ? Math.clz32 : Re, Ie = Math.log, Le = Math.LN2; + function Re(e) { + return e >>>= 0, e === 0 ? 32 : 31 - (Ie(e) / Le | 0) | 0; + } + var ze = 256, Be = 262144, Ve = 4194304; + function He(e) { + var t = e & 42; + if (t !== 0) return t; + switch (e & -e) { + case 1: return 1; + case 2: return 2; + case 4: return 4; + case 8: return 8; + case 16: return 16; + case 32: return 32; + case 64: return 64; + case 128: return 128; + case 256: + case 512: + case 1024: + case 2048: + case 4096: + case 8192: + case 16384: + case 32768: + case 65536: + case 131072: return e & 261888; + case 262144: + case 524288: + case 1048576: + case 2097152: return e & 3932160; + case 4194304: + case 8388608: + case 16777216: + case 33554432: return e & 62914560; + case 67108864: return 67108864; + case 134217728: return 134217728; + case 268435456: return 268435456; + case 536870912: return 536870912; + case 1073741824: return 0; + default: return e; + } + } + function V(e, t, n) { + var r = e.pendingLanes; + if (r === 0) return 0; + var i = 0, a = e.suspendedLanes, o = e.pingedLanes; + e = e.warmLanes; + var s = r & 134217727; + return s === 0 ? (s = r & ~a, s === 0 ? o === 0 ? n || (n = r & ~e, n !== 0 && (i = He(n))) : i = He(o) : i = He(s)) : (r = s & ~a, r === 0 ? (o &= s, o === 0 ? n || (n = s & ~e, n !== 0 && (i = He(n))) : i = He(o)) : i = He(r)), i === 0 ? 0 : t !== 0 && t !== i && (t & a) === 0 && (a = i & -i, n = t & -t, a >= n || a === 32 && n & 4194048) ? t : i; + } + function H(e, t) { + return (e.pendingLanes & ~(e.suspendedLanes & ~e.pingedLanes) & t) === 0; + } + function Ue(e, t) { + switch (e) { + case 1: + case 2: + case 4: + case 8: + case 64: return t + 250; + case 16: + case 32: + case 128: + case 256: + case 512: + case 1024: + case 2048: + case 4096: + case 8192: + case 16384: + case 32768: + case 65536: + case 131072: + case 262144: + case 524288: + case 1048576: + case 2097152: return t + 5e3; + case 4194304: + case 8388608: + case 16777216: + case 33554432: return -1; + case 67108864: + case 134217728: + case 268435456: + case 536870912: + case 1073741824: return -1; + default: return -1; + } + } + function U() { + var e = Ve; + return Ve <<= 1, !(Ve & 62914560) && (Ve = 4194304), e; + } + function We(e) { + for (var t = [], n = 0; 31 > n; n++) t.push(e); + return t; + } + function Ge(e, t) { + e.pendingLanes |= t, t !== 268435456 && (e.suspendedLanes = 0, e.pingedLanes = 0, e.warmLanes = 0); + } + function Ke(e, t, n, r, i, a) { + var o = e.pendingLanes; + e.pendingLanes = n, e.suspendedLanes = 0, e.pingedLanes = 0, e.warmLanes = 0, e.expiredLanes &= n, e.entangledLanes &= n, e.errorRecoveryDisabledLanes &= n, e.shellSuspendCounter = 0; + var s = e.entanglements, c = e.expirationTimes, l = e.hiddenUpdates; + for (n = o & ~n; 0 < n;) { + var u = 31 - Fe(n), d = 1 << u; + s[u] = 0, c[u] = -1; + var f = l[u]; + if (f !== null) for (l[u] = null, u = 0; u < f.length; u++) { + var p = f[u]; + p !== null && (p.lane &= -536870913); + } + n &= ~d; + } + r !== 0 && qe(e, r, 0), a !== 0 && i === 0 && e.tag !== 0 && (e.suspendedLanes |= a & ~(o & ~t)); + } + function qe(e, t, n) { + e.pendingLanes |= t, e.suspendedLanes &= ~t; + var r = 31 - Fe(t); + e.entangledLanes |= t, e.entanglements[r] = e.entanglements[r] | 1073741824 | n & 261930; + } + function Je(e, t) { + var n = e.entangledLanes |= t; + for (e = e.entanglements; n;) { + var r = 31 - Fe(n), i = 1 << r; + i & t | e[r] & t && (e[r] |= t), n &= ~i; + } + } + function Ye(e, t) { + var n = t & -t; + return n = n & 42 ? 1 : Xe(n), (n & (e.suspendedLanes | t)) === 0 ? n : 0; + } + function Xe(e) { + switch (e) { + case 2: + e = 1; + break; + case 8: + e = 4; + break; + case 32: + e = 16; + break; + case 256: + case 512: + case 1024: + case 2048: + case 4096: + case 8192: + case 16384: + case 32768: + case 65536: + case 131072: + case 262144: + case 524288: + case 1048576: + case 2097152: + case 4194304: + case 8388608: + case 16777216: + case 33554432: + e = 128; + break; + case 268435456: + e = 134217728; + break; + default: e = 0; + } + return e; + } + function Ze(e) { + return e &= -e, 2 < e ? 8 < e ? e & 134217727 ? 32 : 268435456 : 8 : 2; + } + function Qe() { + var e = k.p; + return e === 0 ? (e = window.event, e === void 0 ? 32 : Sp(e.type)) : e; + } + function $e(e, t) { + var n = k.p; + try { + return k.p = e, t(); + } finally { + k.p = n; + } + } + var et = Math.random().toString(36).slice(2), tt = "__reactFiber$" + et, nt = "__reactProps$" + et, rt = "__reactContainer$" + et, it = "__reactEvents$" + et, at = "__reactListeners$" + et, ot = "__reactHandles$" + et, st = "__reactResources$" + et, ct = "__reactMarker$" + et; + function lt(e) { + delete e[tt], delete e[nt], delete e[it], delete e[at], delete e[ot]; + } + function ut(e) { + var t = e[tt]; + if (t) return t; + for (var n = e.parentNode; n;) { + if (t = n[rt] || n[tt]) { + if (n = t.alternate, t.child !== null || n !== null && n.child !== null) for (e = yf(e); e !== null;) { + if (n = e[tt]) return n; + e = yf(e); + } + return t; + } + e = n, n = e.parentNode; + } + return null; + } + function dt(e) { + if (e = e[tt] || e[rt]) { + var t = e.tag; + if (t === 5 || t === 6 || t === 13 || t === 31 || t === 26 || t === 27 || t === 3) return e; + } + return null; + } + function ft(e) { + var t = e.tag; + if (t === 5 || t === 26 || t === 27 || t === 6) return e.stateNode; + throw Error(i(33)); + } + function pt(e) { + var t = e[st]; + return t ||= e[st] = { + hoistableStyles: /* @__PURE__ */ new Map(), + hoistableScripts: /* @__PURE__ */ new Map() + }, t; + } + function mt(e) { + e[ct] = !0; + } + var ht = /* @__PURE__ */ new Set(), gt = {}; + function _t(e, t) { + vt(e, t), vt(e + "Capture", t); + } + function vt(e, t) { + for (gt[e] = t, e = 0; e < t.length; e++) ht.add(t[e]); + } + var yt = RegExp("^[:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD][:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*$"), bt = {}, xt = {}; + function St(e) { + return xe.call(xt, e) ? !0 : xe.call(bt, e) ? !1 : yt.test(e) ? xt[e] = !0 : (bt[e] = !0, !1); + } + function Ct(e, t, n) { + if (St(t)) { + if (n === null) e.removeAttribute(t); + else { + switch (typeof n) { + case "undefined": + case "function": + case "symbol": + e.removeAttribute(t); + return; + case "boolean": + var r = t.toLowerCase().slice(0, 5); + if (r !== "data-" && r !== "aria-") { + e.removeAttribute(t); + return; + } + } + e.setAttribute(t, "" + n); + } + } + } + function wt(e, t, n) { + if (n === null) e.removeAttribute(t); + else { + switch (typeof n) { + case "undefined": + case "function": + case "symbol": + case "boolean": + e.removeAttribute(t); + return; + } + e.setAttribute(t, "" + n); + } + } + function Tt(e, t, n, r) { + if (r === null) e.removeAttribute(n); + else { + switch (typeof r) { + case "undefined": + case "function": + case "symbol": + case "boolean": + e.removeAttribute(n); + return; + } + e.setAttributeNS(t, n, "" + r); + } + } + function Et(e) { + switch (typeof e) { + case "bigint": + case "boolean": + case "number": + case "string": + case "undefined": return e; + case "object": return e; + default: return ""; + } + } + function Dt(e) { + var t = e.type; + return (e = e.nodeName) && e.toLowerCase() === "input" && (t === "checkbox" || t === "radio"); + } + function Ot(e, t, n) { + var r = Object.getOwnPropertyDescriptor(e.constructor.prototype, t); + if (!e.hasOwnProperty(t) && r !== void 0 && typeof r.get == "function" && typeof r.set == "function") { + var i = r.get, a = r.set; + return Object.defineProperty(e, t, { + configurable: !0, + get: function() { + return i.call(this); + }, + set: function(e) { + n = "" + e, a.call(this, e); + } + }), Object.defineProperty(e, t, { enumerable: r.enumerable }), { + getValue: function() { + return n; + }, + setValue: function(e) { + n = "" + e; + }, + stopTracking: function() { + e._valueTracker = null, delete e[t]; + } + }; + } + } + function kt(e) { + if (!e._valueTracker) { + var t = Dt(e) ? "checked" : "value"; + e._valueTracker = Ot(e, t, "" + e[t]); + } + } + function At(e) { + if (!e) return !1; + var t = e._valueTracker; + if (!t) return !0; + var n = t.getValue(), r = ""; + return e && (r = Dt(e) ? e.checked ? "true" : "false" : e.value), e = r, e !== n && (t.setValue(e), !0); + } + function jt(e) { + if (e ||= typeof document < "u" ? document : void 0, e === void 0) return null; + try { + return e.activeElement || e.body; + } catch { + return e.body; + } + } + var Mt = /[\n"\\]/g; + function Nt(e) { + return e.replace(Mt, function(e) { + return "\\" + e.charCodeAt(0).toString(16) + " "; + }); + } + function Pt(e, t, n, r, i, a, o, s) { + e.name = "", o != null && typeof o != "function" && typeof o != "symbol" && typeof o != "boolean" ? e.type = o : e.removeAttribute("type"), t == null ? o !== "submit" && o !== "reset" || e.removeAttribute("value") : o === "number" ? (t === 0 && e.value === "" || e.value != t) && (e.value = "" + Et(t)) : e.value !== "" + Et(t) && (e.value = "" + Et(t)), t == null ? n == null ? r != null && e.removeAttribute("value") : It(e, o, Et(n)) : It(e, o, Et(t)), i == null && a != null && (e.defaultChecked = !!a), i != null && (e.checked = i && typeof i != "function" && typeof i != "symbol"), s != null && typeof s != "function" && typeof s != "symbol" && typeof s != "boolean" ? e.name = "" + Et(s) : e.removeAttribute("name"); + } + function Ft(e, t, n, r, i, a, o, s) { + if (a != null && typeof a != "function" && typeof a != "symbol" && typeof a != "boolean" && (e.type = a), t != null || n != null) { + if (!(a !== "submit" && a !== "reset" || t != null)) { + kt(e); + return; + } + n = n == null ? "" : "" + Et(n), t = t == null ? n : "" + Et(t), s || t === e.value || (e.value = t), e.defaultValue = t; + } + r ??= i, r = typeof r != "function" && typeof r != "symbol" && !!r, e.checked = s ? e.checked : !!r, e.defaultChecked = !!r, o != null && typeof o != "function" && typeof o != "symbol" && typeof o != "boolean" && (e.name = o), kt(e); + } + function It(e, t, n) { + t === "number" && jt(e.ownerDocument) === e || e.defaultValue === "" + n || (e.defaultValue = "" + n); + } + function Lt(e, t, n, r) { + if (e = e.options, t) { + t = {}; + for (var i = 0; i < n.length; i++) t["$" + n[i]] = !0; + for (n = 0; n < e.length; n++) i = t.hasOwnProperty("$" + e[n].value), e[n].selected !== i && (e[n].selected = i), i && r && (e[n].defaultSelected = !0); + } else { + for (n = "" + Et(n), t = null, i = 0; i < e.length; i++) { + if (e[i].value === n) { + e[i].selected = !0, r && (e[i].defaultSelected = !0); + return; + } + t !== null || e[i].disabled || (t = e[i]); + } + t !== null && (t.selected = !0); + } + } + function Rt(e, t, n) { + if (t != null && (t = "" + Et(t), t !== e.value && (e.value = t), n == null)) { + e.defaultValue !== t && (e.defaultValue = t); + return; + } + e.defaultValue = n == null ? "" : "" + Et(n); + } + function zt(e, t, n, r) { + if (t == null) { + if (r != null) { + if (n != null) throw Error(i(92)); + if (se(r)) { + if (1 < r.length) throw Error(i(93)); + r = r[0]; + } + n = r; + } + n ??= "", t = n; + } + n = Et(t), e.defaultValue = n, r = e.textContent, r === n && r !== "" && r !== null && (e.value = r), kt(e); + } + function Bt(e, t) { + if (t) { + var n = e.firstChild; + if (n && n === e.lastChild && n.nodeType === 3) { + n.nodeValue = t; + return; + } + } + e.textContent = t; + } + var Vt = new Set("animationIterationCount aspectRatio borderImageOutset borderImageSlice borderImageWidth boxFlex boxFlexGroup boxOrdinalGroup columnCount columns flex flexGrow flexPositive flexShrink flexNegative flexOrder gridArea gridRow gridRowEnd gridRowSpan gridRowStart gridColumn gridColumnEnd gridColumnSpan gridColumnStart fontWeight lineClamp lineHeight opacity order orphans scale tabSize widows zIndex zoom fillOpacity floodOpacity stopOpacity strokeDasharray strokeDashoffset strokeMiterlimit strokeOpacity strokeWidth MozAnimationIterationCount MozBoxFlex MozBoxFlexGroup MozLineClamp msAnimationIterationCount msFlex msZoom msFlexGrow msFlexNegative msFlexOrder msFlexPositive msFlexShrink msGridColumn msGridColumnSpan msGridRow msGridRowSpan WebkitAnimationIterationCount WebkitBoxFlex WebKitBoxFlexGroup WebkitBoxOrdinalGroup WebkitColumnCount WebkitColumns WebkitFlex WebkitFlexGrow WebkitFlexPositive WebkitFlexShrink WebkitLineClamp".split(" ")); + function Ht(e, t, n) { + var r = t.indexOf("--") === 0; + n == null || typeof n == "boolean" || n === "" ? r ? e.setProperty(t, "") : t === "float" ? e.cssFloat = "" : e[t] = "" : r ? e.setProperty(t, n) : typeof n != "number" || n === 0 || Vt.has(t) ? t === "float" ? e.cssFloat = n : e[t] = ("" + n).trim() : e[t] = n + "px"; + } + function Ut(e, t, n) { + if (t != null && typeof t != "object") throw Error(i(62)); + if (e = e.style, n != null) { + for (var r in n) !n.hasOwnProperty(r) || t != null && t.hasOwnProperty(r) || (r.indexOf("--") === 0 ? e.setProperty(r, "") : r === "float" ? e.cssFloat = "" : e[r] = ""); + for (var a in t) r = t[a], t.hasOwnProperty(a) && n[a] !== r && Ht(e, a, r); + } else for (var o in t) t.hasOwnProperty(o) && Ht(e, o, t[o]); + } + function Wt(e) { + if (e.indexOf("-") === -1) return !1; + switch (e) { + case "annotation-xml": + case "color-profile": + case "font-face": + case "font-face-src": + case "font-face-uri": + case "font-face-format": + case "font-face-name": + case "missing-glyph": return !1; + default: return !0; + } + } + var Gt = /* @__PURE__ */ new Map([ + ["acceptCharset", "accept-charset"], + ["htmlFor", "for"], + ["httpEquiv", "http-equiv"], + ["crossOrigin", "crossorigin"], + ["accentHeight", "accent-height"], + ["alignmentBaseline", "alignment-baseline"], + ["arabicForm", "arabic-form"], + ["baselineShift", "baseline-shift"], + ["capHeight", "cap-height"], + ["clipPath", "clip-path"], + ["clipRule", "clip-rule"], + ["colorInterpolation", "color-interpolation"], + ["colorInterpolationFilters", "color-interpolation-filters"], + ["colorProfile", "color-profile"], + ["colorRendering", "color-rendering"], + ["dominantBaseline", "dominant-baseline"], + ["enableBackground", "enable-background"], + ["fillOpacity", "fill-opacity"], + ["fillRule", "fill-rule"], + ["floodColor", "flood-color"], + ["floodOpacity", "flood-opacity"], + ["fontFamily", "font-family"], + ["fontSize", "font-size"], + ["fontSizeAdjust", "font-size-adjust"], + ["fontStretch", "font-stretch"], + ["fontStyle", "font-style"], + ["fontVariant", "font-variant"], + ["fontWeight", "font-weight"], + ["glyphName", "glyph-name"], + ["glyphOrientationHorizontal", "glyph-orientation-horizontal"], + ["glyphOrientationVertical", "glyph-orientation-vertical"], + ["horizAdvX", "horiz-adv-x"], + ["horizOriginX", "horiz-origin-x"], + ["imageRendering", "image-rendering"], + ["letterSpacing", "letter-spacing"], + ["lightingColor", "lighting-color"], + ["markerEnd", "marker-end"], + ["markerMid", "marker-mid"], + ["markerStart", "marker-start"], + ["overlinePosition", "overline-position"], + ["overlineThickness", "overline-thickness"], + ["paintOrder", "paint-order"], + ["panose-1", "panose-1"], + ["pointerEvents", "pointer-events"], + ["renderingIntent", "rendering-intent"], + ["shapeRendering", "shape-rendering"], + ["stopColor", "stop-color"], + ["stopOpacity", "stop-opacity"], + ["strikethroughPosition", "strikethrough-position"], + ["strikethroughThickness", "strikethrough-thickness"], + ["strokeDasharray", "stroke-dasharray"], + ["strokeDashoffset", "stroke-dashoffset"], + ["strokeLinecap", "stroke-linecap"], + ["strokeLinejoin", "stroke-linejoin"], + ["strokeMiterlimit", "stroke-miterlimit"], + ["strokeOpacity", "stroke-opacity"], + ["strokeWidth", "stroke-width"], + ["textAnchor", "text-anchor"], + ["textDecoration", "text-decoration"], + ["textRendering", "text-rendering"], + ["transformOrigin", "transform-origin"], + ["underlinePosition", "underline-position"], + ["underlineThickness", "underline-thickness"], + ["unicodeBidi", "unicode-bidi"], + ["unicodeRange", "unicode-range"], + ["unitsPerEm", "units-per-em"], + ["vAlphabetic", "v-alphabetic"], + ["vHanging", "v-hanging"], + ["vIdeographic", "v-ideographic"], + ["vMathematical", "v-mathematical"], + ["vectorEffect", "vector-effect"], + ["vertAdvY", "vert-adv-y"], + ["vertOriginX", "vert-origin-x"], + ["vertOriginY", "vert-origin-y"], + ["wordSpacing", "word-spacing"], + ["writingMode", "writing-mode"], + ["xmlnsXlink", "xmlns:xlink"], + ["xHeight", "x-height"] + ]), Kt = /^[\u0000-\u001F ]*j[\r\n\t]*a[\r\n\t]*v[\r\n\t]*a[\r\n\t]*s[\r\n\t]*c[\r\n\t]*r[\r\n\t]*i[\r\n\t]*p[\r\n\t]*t[\r\n\t]*:/i; + function qt(e) { + return Kt.test("" + e) ? "javascript:throw new Error('React has blocked a javascript: URL as a security precaution.')" : e; + } + function Jt() {} + var Yt = null; + function Xt(e) { + return e = e.target || e.srcElement || window, e.correspondingUseElement && (e = e.correspondingUseElement), e.nodeType === 3 ? e.parentNode : e; + } + var Zt = null, Qt = null; + function $t(e) { + var t = dt(e); + if (t && (e = t.stateNode)) { + var n = e[nt] || null; + a: switch (e = t.stateNode, t.type) { + case "input": + if (Pt(e, n.value, n.defaultValue, n.defaultValue, n.checked, n.defaultChecked, n.type, n.name), t = n.name, n.type === "radio" && t != null) { + for (n = e; n.parentNode;) n = n.parentNode; + for (n = n.querySelectorAll("input[name=\"" + Nt("" + t) + "\"][type=\"radio\"]"), t = 0; t < n.length; t++) { + var r = n[t]; + if (r !== e && r.form === e.form) { + var a = r[nt] || null; + if (!a) throw Error(i(90)); + Pt(r, a.value, a.defaultValue, a.defaultValue, a.checked, a.defaultChecked, a.type, a.name); + } + } + for (t = 0; t < n.length; t++) r = n[t], r.form === e.form && At(r); + } + break a; + case "textarea": + Rt(e, n.value, n.defaultValue); + break a; + case "select": t = n.value, t != null && Lt(e, !!n.multiple, t, !1); + } + } + } + var en = !1; + function tn(e, t, n) { + if (en) return e(t, n); + en = !0; + try { + return e(t); + } finally { + if (en = !1, (Zt !== null || Qt !== null) && (Eu(), Zt && (t = Zt, e = Qt, Qt = Zt = null, $t(t), e))) for (t = 0; t < e.length; t++) $t(e[t]); + } + } + function nn(e, t) { + var n = e.stateNode; + if (n === null) return null; + var r = n[nt] || null; + if (r === null) return null; + n = r[t]; + a: switch (t) { + case "onClick": + case "onClickCapture": + case "onDoubleClick": + case "onDoubleClickCapture": + case "onMouseDown": + case "onMouseDownCapture": + case "onMouseMove": + case "onMouseMoveCapture": + case "onMouseUp": + case "onMouseUpCapture": + case "onMouseEnter": + (r = !r.disabled) || (e = e.type, r = e !== "button" && e !== "input" && e !== "select" && e !== "textarea"), e = !r; + break a; + default: e = !1; + } + if (e) return null; + if (n && typeof n != "function") throw Error(i(231, t, typeof n)); + return n; + } + var rn = !(typeof window > "u" || window.document === void 0 || window.document.createElement === void 0), an = !1; + if (rn) try { + var on = {}; + Object.defineProperty(on, "passive", { get: function() { + an = !0; + } }), window.addEventListener("test", on, on), window.removeEventListener("test", on, on); + } catch { + an = !1; + } + var sn = null, cn = null, ln = null; + function un() { + if (ln) return ln; + var e, t = cn, n = t.length, r, i = "value" in sn ? sn.value : sn.textContent, a = i.length; + for (e = 0; e < n && t[e] === i[e]; e++); + var o = n - e; + for (r = 1; r <= o && t[n - r] === i[a - r]; r++); + return ln = i.slice(e, 1 < r ? 1 - r : void 0); + } + function dn(e) { + var t = e.keyCode; + return "charCode" in e ? (e = e.charCode, e === 0 && t === 13 && (e = 13)) : e = t, e === 10 && (e = 13), 32 <= e || e === 13 ? e : 0; + } + function fn() { + return !0; + } + function pn() { + return !1; + } + function mn(e) { + function t(t, n, r, i, a) { + for (var o in this._reactName = t, this._targetInst = r, this.type = n, this.nativeEvent = i, this.target = a, this.currentTarget = null, e) e.hasOwnProperty(o) && (t = e[o], this[o] = t ? t(i) : i[o]); + return this.isDefaultPrevented = (i.defaultPrevented == null ? !1 === i.returnValue : i.defaultPrevented) ? fn : pn, this.isPropagationStopped = pn, this; + } + return m(t.prototype, { + preventDefault: function() { + this.defaultPrevented = !0; + var e = this.nativeEvent; + e && (e.preventDefault ? e.preventDefault() : typeof e.returnValue != "unknown" && (e.returnValue = !1), this.isDefaultPrevented = fn); + }, + stopPropagation: function() { + var e = this.nativeEvent; + e && (e.stopPropagation ? e.stopPropagation() : typeof e.cancelBubble != "unknown" && (e.cancelBubble = !0), this.isPropagationStopped = fn); + }, + persist: function() {}, + isPersistent: fn + }), t; + } + var hn = { + eventPhase: 0, + bubbles: 0, + cancelable: 0, + timeStamp: function(e) { + return e.timeStamp || Date.now(); + }, + defaultPrevented: 0, + isTrusted: 0 + }, gn = mn(hn), _n = m({}, hn, { + view: 0, + detail: 0 + }), vn = mn(_n), yn, bn, xn, Sn = m({}, _n, { + screenX: 0, + screenY: 0, + clientX: 0, + clientY: 0, + pageX: 0, + pageY: 0, + ctrlKey: 0, + shiftKey: 0, + altKey: 0, + metaKey: 0, + getModifierState: Nn, + button: 0, + buttons: 0, + relatedTarget: function(e) { + return e.relatedTarget === void 0 ? e.fromElement === e.srcElement ? e.toElement : e.fromElement : e.relatedTarget; + }, + movementX: function(e) { + return "movementX" in e ? e.movementX : (e !== xn && (xn && e.type === "mousemove" ? (yn = e.screenX - xn.screenX, bn = e.screenY - xn.screenY) : bn = yn = 0, xn = e), yn); + }, + movementY: function(e) { + return "movementY" in e ? e.movementY : bn; + } + }), Cn = mn(Sn), wn = mn(m({}, Sn, { dataTransfer: 0 })), Tn = mn(m({}, _n, { relatedTarget: 0 })), En = mn(m({}, hn, { + animationName: 0, + elapsedTime: 0, + pseudoElement: 0 + })), Dn = mn(m({}, hn, { clipboardData: function(e) { + return "clipboardData" in e ? e.clipboardData : window.clipboardData; + } })), On = mn(m({}, hn, { data: 0 })), kn = { + Esc: "Escape", + Spacebar: " ", + Left: "ArrowLeft", + Up: "ArrowUp", + Right: "ArrowRight", + Down: "ArrowDown", + Del: "Delete", + Win: "OS", + Menu: "ContextMenu", + Apps: "ContextMenu", + Scroll: "ScrollLock", + MozPrintableKey: "Unidentified" + }, An = { + 8: "Backspace", + 9: "Tab", + 12: "Clear", + 13: "Enter", + 16: "Shift", + 17: "Control", + 18: "Alt", + 19: "Pause", + 20: "CapsLock", + 27: "Escape", + 32: " ", + 33: "PageUp", + 34: "PageDown", + 35: "End", + 36: "Home", + 37: "ArrowLeft", + 38: "ArrowUp", + 39: "ArrowRight", + 40: "ArrowDown", + 45: "Insert", + 46: "Delete", + 112: "F1", + 113: "F2", + 114: "F3", + 115: "F4", + 116: "F5", + 117: "F6", + 118: "F7", + 119: "F8", + 120: "F9", + 121: "F10", + 122: "F11", + 123: "F12", + 144: "NumLock", + 145: "ScrollLock", + 224: "Meta" + }, jn = { + Alt: "altKey", + Control: "ctrlKey", + Meta: "metaKey", + Shift: "shiftKey" + }; + function Mn(e) { + var t = this.nativeEvent; + return t.getModifierState ? t.getModifierState(e) : (e = jn[e]) ? !!t[e] : !1; + } + function Nn() { + return Mn; + } + var Pn = mn(m({}, _n, { + key: function(e) { + if (e.key) { + var t = kn[e.key] || e.key; + if (t !== "Unidentified") return t; + } + return e.type === "keypress" ? (e = dn(e), e === 13 ? "Enter" : String.fromCharCode(e)) : e.type === "keydown" || e.type === "keyup" ? An[e.keyCode] || "Unidentified" : ""; + }, + code: 0, + location: 0, + ctrlKey: 0, + shiftKey: 0, + altKey: 0, + metaKey: 0, + repeat: 0, + locale: 0, + getModifierState: Nn, + charCode: function(e) { + return e.type === "keypress" ? dn(e) : 0; + }, + keyCode: function(e) { + return e.type === "keydown" || e.type === "keyup" ? e.keyCode : 0; + }, + which: function(e) { + return e.type === "keypress" ? dn(e) : e.type === "keydown" || e.type === "keyup" ? e.keyCode : 0; + } + })), Fn = mn(m({}, Sn, { + pointerId: 0, + width: 0, + height: 0, + pressure: 0, + tangentialPressure: 0, + tiltX: 0, + tiltY: 0, + twist: 0, + pointerType: 0, + isPrimary: 0 + })), In = mn(m({}, _n, { + touches: 0, + targetTouches: 0, + changedTouches: 0, + altKey: 0, + metaKey: 0, + ctrlKey: 0, + shiftKey: 0, + getModifierState: Nn + })), Ln = mn(m({}, hn, { + propertyName: 0, + elapsedTime: 0, + pseudoElement: 0 + })), Rn = mn(m({}, Sn, { + deltaX: function(e) { + return "deltaX" in e ? e.deltaX : "wheelDeltaX" in e ? -e.wheelDeltaX : 0; + }, + deltaY: function(e) { + return "deltaY" in e ? e.deltaY : "wheelDeltaY" in e ? -e.wheelDeltaY : "wheelDelta" in e ? -e.wheelDelta : 0; + }, + deltaZ: 0, + deltaMode: 0 + })), zn = mn(m({}, hn, { + newState: 0, + oldState: 0 + })), Bn = [ + 9, + 13, + 27, + 32 + ], Vn = rn && "CompositionEvent" in window, Hn = null; + rn && "documentMode" in document && (Hn = document.documentMode); + var Un = rn && "TextEvent" in window && !Hn, Wn = rn && (!Vn || Hn && 8 < Hn && 11 >= Hn), Gn = " ", Kn = !1; + function qn(e, t) { + switch (e) { + case "keyup": return Bn.indexOf(t.keyCode) !== -1; + case "keydown": return t.keyCode !== 229; + case "keypress": + case "mousedown": + case "focusout": return !0; + default: return !1; + } + } + function Jn(e) { + return e = e.detail, typeof e == "object" && "data" in e ? e.data : null; + } + var Yn = !1; + function Xn(e, t) { + switch (e) { + case "compositionend": return Jn(t); + case "keypress": return t.which === 32 ? (Kn = !0, Gn) : null; + case "textInput": return e = t.data, e === Gn && Kn ? null : e; + default: return null; + } + } + function Zn(e, t) { + if (Yn) return e === "compositionend" || !Vn && qn(e, t) ? (e = un(), ln = cn = sn = null, Yn = !1, e) : null; + switch (e) { + case "paste": return null; + case "keypress": + if (!(t.ctrlKey || t.altKey || t.metaKey) || t.ctrlKey && t.altKey) { + if (t.char && 1 < t.char.length) return t.char; + if (t.which) return String.fromCharCode(t.which); + } + return null; + case "compositionend": return Wn && t.locale !== "ko" ? null : t.data; + default: return null; + } + } + var Qn = { + color: !0, + date: !0, + datetime: !0, + "datetime-local": !0, + email: !0, + month: !0, + number: !0, + password: !0, + range: !0, + search: !0, + tel: !0, + text: !0, + time: !0, + url: !0, + week: !0 + }; + function $n(e) { + var t = e && e.nodeName && e.nodeName.toLowerCase(); + return t === "input" ? !!Qn[e.type] : t === "textarea"; + } + function er(e, t, n, r) { + Zt ? Qt ? Qt.push(r) : Qt = [r] : Zt = r, t = Pd(t, "onChange"), 0 < t.length && (n = new gn("onChange", "change", null, n, r), e.push({ + event: n, + listeners: t + })); + } + var tr = null, nr = null; + function rr(e) { + Ed(e, 0); + } + function ir(e) { + if (At(ft(e))) return e; + } + function ar(e, t) { + if (e === "change") return t; + } + var or = !1; + if (rn) { + var sr; + if (rn) { + var cr = "oninput" in document; + if (!cr) { + var lr = document.createElement("div"); + lr.setAttribute("oninput", "return;"), cr = typeof lr.oninput == "function"; + } + sr = cr; + } else sr = !1; + or = sr && (!document.documentMode || 9 < document.documentMode); + } + function ur() { + tr && (tr.detachEvent("onpropertychange", dr), nr = tr = null); + } + function dr(e) { + if (e.propertyName === "value" && ir(nr)) { + var t = []; + er(t, nr, e, Xt(e)), tn(rr, t); + } + } + function fr(e, t, n) { + e === "focusin" ? (ur(), tr = t, nr = n, tr.attachEvent("onpropertychange", dr)) : e === "focusout" && ur(); + } + function pr(e) { + if (e === "selectionchange" || e === "keyup" || e === "keydown") return ir(nr); + } + function mr(e, t) { + if (e === "click") return ir(t); + } + function hr(e, t) { + if (e === "input" || e === "change") return ir(t); + } + function gr(e, t) { + return e === t && (e !== 0 || 1 / e == 1 / t) || e !== e && t !== t; + } + var _r = typeof Object.is == "function" ? Object.is : gr; + function vr(e, t) { + if (_r(e, t)) return !0; + if (typeof e != "object" || !e || typeof t != "object" || !t) return !1; + var n = Object.keys(e), r = Object.keys(t); + if (n.length !== r.length) return !1; + for (r = 0; r < n.length; r++) { + var i = n[r]; + if (!xe.call(t, i) || !_r(e[i], t[i])) return !1; + } + return !0; + } + function yr(e) { + for (; e && e.firstChild;) e = e.firstChild; + return e; + } + function br(e, t) { + var n = yr(e); + e = 0; + for (var r; n;) { + if (n.nodeType === 3) { + if (r = e + n.textContent.length, e <= t && r >= t) return { + node: n, + offset: t - e + }; + e = r; + } + a: { + for (; n;) { + if (n.nextSibling) { + n = n.nextSibling; + break a; + } + n = n.parentNode; + } + n = void 0; + } + n = yr(n); + } + } + function xr(e, t) { + return e && t ? e === t ? !0 : e && e.nodeType === 3 ? !1 : t && t.nodeType === 3 ? xr(e, t.parentNode) : "contains" in e ? e.contains(t) : e.compareDocumentPosition ? !!(e.compareDocumentPosition(t) & 16) : !1 : !1; + } + function Sr(e) { + e = e != null && e.ownerDocument != null && e.ownerDocument.defaultView != null ? e.ownerDocument.defaultView : window; + for (var t = jt(e.document); t instanceof e.HTMLIFrameElement;) { + try { + var n = typeof t.contentWindow.location.href == "string"; + } catch { + n = !1; + } + if (n) e = t.contentWindow; + else break; + t = jt(e.document); + } + return t; + } + function Cr(e) { + var t = e && e.nodeName && e.nodeName.toLowerCase(); + return t && (t === "input" && (e.type === "text" || e.type === "search" || e.type === "tel" || e.type === "url" || e.type === "password") || t === "textarea" || e.contentEditable === "true"); + } + var wr = rn && "documentMode" in document && 11 >= document.documentMode, Tr = null, Er = null, Dr = null, Or = !1; + function kr(e, t, n) { + var r = n.window === n ? n.document : n.nodeType === 9 ? n : n.ownerDocument; + Or || Tr == null || Tr !== jt(r) || (r = Tr, "selectionStart" in r && Cr(r) ? r = { + start: r.selectionStart, + end: r.selectionEnd + } : (r = (r.ownerDocument && r.ownerDocument.defaultView || window).getSelection(), r = { + anchorNode: r.anchorNode, + anchorOffset: r.anchorOffset, + focusNode: r.focusNode, + focusOffset: r.focusOffset + }), Dr && vr(Dr, r) || (Dr = r, r = Pd(Er, "onSelect"), 0 < r.length && (t = new gn("onSelect", "select", null, t, n), e.push({ + event: t, + listeners: r + }), t.target = Tr))); + } + function Ar(e, t) { + var n = {}; + return n[e.toLowerCase()] = t.toLowerCase(), n["Webkit" + e] = "webkit" + t, n["Moz" + e] = "moz" + t, n; + } + var jr = { + animationend: Ar("Animation", "AnimationEnd"), + animationiteration: Ar("Animation", "AnimationIteration"), + animationstart: Ar("Animation", "AnimationStart"), + transitionrun: Ar("Transition", "TransitionRun"), + transitionstart: Ar("Transition", "TransitionStart"), + transitioncancel: Ar("Transition", "TransitionCancel"), + transitionend: Ar("Transition", "TransitionEnd") + }, Mr = {}, Nr = {}; + rn && (Nr = document.createElement("div").style, "AnimationEvent" in window || (delete jr.animationend.animation, delete jr.animationiteration.animation, delete jr.animationstart.animation), "TransitionEvent" in window || delete jr.transitionend.transition); + function Pr(e) { + if (Mr[e]) return Mr[e]; + if (!jr[e]) return e; + var t = jr[e], n; + for (n in t) if (t.hasOwnProperty(n) && n in Nr) return Mr[e] = t[n]; + return e; + } + var Fr = Pr("animationend"), Ir = Pr("animationiteration"), Lr = Pr("animationstart"), Rr = Pr("transitionrun"), zr = Pr("transitionstart"), Br = Pr("transitioncancel"), Vr = Pr("transitionend"), Hr = /* @__PURE__ */ new Map(), Ur = "abort auxClick beforeToggle cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel".split(" "); + Ur.push("scrollEnd"); + function Wr(e, t) { + Hr.set(e, t), _t(t, [e]); + } + var Gr = typeof reportError == "function" ? reportError : function(e) { + if (typeof window == "object" && typeof window.ErrorEvent == "function") { + var t = new window.ErrorEvent("error", { + bubbles: !0, + cancelable: !0, + message: typeof e == "object" && e && typeof e.message == "string" ? String(e.message) : String(e), + error: e + }); + if (!window.dispatchEvent(t)) return; + } else if (typeof process == "object" && typeof process.emit == "function") { + process.emit("uncaughtException", e); + return; + } + console.error(e); + }, Kr = [], qr = 0, Jr = 0; + function Yr() { + for (var e = qr, t = Jr = qr = 0; t < e;) { + var n = Kr[t]; + Kr[t++] = null; + var r = Kr[t]; + Kr[t++] = null; + var i = Kr[t]; + Kr[t++] = null; + var a = Kr[t]; + if (Kr[t++] = null, r !== null && i !== null) { + var o = r.pending; + o === null ? i.next = i : (i.next = o.next, o.next = i), r.pending = i; + } + a !== 0 && $r(n, i, a); + } + } + function Xr(e, t, n, r) { + Kr[qr++] = e, Kr[qr++] = t, Kr[qr++] = n, Kr[qr++] = r, Jr |= r, e.lanes |= r, e = e.alternate, e !== null && (e.lanes |= r); + } + function Zr(e, t, n, r) { + return Xr(e, t, n, r), ei(e); + } + function Qr(e, t) { + return Xr(e, null, null, t), ei(e); + } + function $r(e, t, n) { + e.lanes |= n; + var r = e.alternate; + r !== null && (r.lanes |= n); + for (var i = !1, a = e.return; a !== null;) a.childLanes |= n, r = a.alternate, r !== null && (r.childLanes |= n), a.tag === 22 && (e = a.stateNode, e === null || e._visibility & 1 || (i = !0)), e = a, a = a.return; + return e.tag === 3 ? (a = e.stateNode, i && t !== null && (i = 31 - Fe(n), e = a.hiddenUpdates, r = e[i], r === null ? e[i] = [t] : r.push(t), t.lane = n | 536870912), a) : null; + } + function ei(e) { + if (50 < _u) throw _u = 0, vu = null, Error(i(185)); + for (var t = e.return; t !== null;) e = t, t = e.return; + return e.tag === 3 ? e.stateNode : null; + } + var ti = {}; + function ni(e, t, n, r) { + this.tag = e, this.key = n, this.sibling = this.child = this.return = this.stateNode = this.type = this.elementType = null, this.index = 0, this.refCleanup = this.ref = null, this.pendingProps = t, this.dependencies = this.memoizedState = this.updateQueue = this.memoizedProps = null, this.mode = r, this.subtreeFlags = this.flags = 0, this.deletions = null, this.childLanes = this.lanes = 0, this.alternate = null; + } + function ri(e, t, n, r) { + return new ni(e, t, n, r); + } + function ii(e) { + return e = e.prototype, !(!e || !e.isReactComponent); + } + function ai(e, t) { + var n = e.alternate; + return n === null ? (n = ri(e.tag, t, e.key, e.mode), n.elementType = e.elementType, n.type = e.type, n.stateNode = e.stateNode, n.alternate = e, e.alternate = n) : (n.pendingProps = t, n.type = e.type, n.flags = 0, n.subtreeFlags = 0, n.deletions = null), n.flags = e.flags & 65011712, n.childLanes = e.childLanes, n.lanes = e.lanes, n.child = e.child, n.memoizedProps = e.memoizedProps, n.memoizedState = e.memoizedState, n.updateQueue = e.updateQueue, t = e.dependencies, n.dependencies = t === null ? null : { + lanes: t.lanes, + firstContext: t.firstContext + }, n.sibling = e.sibling, n.index = e.index, n.ref = e.ref, n.refCleanup = e.refCleanup, n; + } + function oi(e, t) { + e.flags &= 65011714; + var n = e.alternate; + return n === null ? (e.childLanes = 0, e.lanes = t, e.child = null, e.subtreeFlags = 0, e.memoizedProps = null, e.memoizedState = null, e.updateQueue = null, e.dependencies = null, e.stateNode = null) : (e.childLanes = n.childLanes, e.lanes = n.lanes, e.child = n.child, e.subtreeFlags = 0, e.deletions = null, e.memoizedProps = n.memoizedProps, e.memoizedState = n.memoizedState, e.updateQueue = n.updateQueue, e.type = n.type, t = n.dependencies, e.dependencies = t === null ? null : { + lanes: t.lanes, + firstContext: t.firstContext + }), e; + } + function si(e, t, n, r, a, o) { + var s = 0; + if (r = e, typeof e == "function") ii(e) && (s = 1); + else if (typeof e == "string") s = Zf(e, n, j.current) ? 26 : e === "html" || e === "head" || e === "body" ? 27 : 5; + else a: switch (e) { + case te: return e = ri(31, n, t, a), e.elementType = te, e.lanes = o, e; + case y: return ci(n.children, a, o, t); + case b: + s = 8, a |= 24; + break; + case x: return e = ri(12, n, t, a | 2), e.elementType = x, e.lanes = o, e; + case T: return e = ri(13, n, t, a), e.elementType = T, e.lanes = o, e; + case E: return e = ri(19, n, t, a), e.elementType = E, e.lanes = o, e; + default: + if (typeof e == "object" && e) switch (e.$$typeof) { + case C: + s = 10; + break a; + case S: + s = 9; + break a; + case w: + s = 11; + break a; + case ee: + s = 14; + break a; + case D: + s = 16, r = null; + break a; + } + s = 29, n = Error(i(130, e === null ? "null" : typeof e, "")), r = null; + } + return t = ri(s, n, t, a), t.elementType = e, t.type = r, t.lanes = o, t; + } + function ci(e, t, n, r) { + return e = ri(7, e, r, t), e.lanes = n, e; + } + function li(e, t, n) { + return e = ri(6, e, null, t), e.lanes = n, e; + } + function ui(e) { + var t = ri(18, null, null, 0); + return t.stateNode = e, t; + } + function di(e, t, n) { + return t = ri(4, e.children === null ? [] : e.children, e.key, t), t.lanes = n, t.stateNode = { + containerInfo: e.containerInfo, + pendingChildren: null, + implementation: e.implementation + }, t; + } + var fi = /* @__PURE__ */ new WeakMap(); + function pi(e, t) { + if (typeof e == "object" && e) { + var n = fi.get(e); + return n === void 0 ? (t = { + value: e, + source: t, + stack: be(t) + }, fi.set(e, t), t) : n; + } + return { + value: e, + source: t, + stack: be(t) + }; + } + var mi = [], hi = 0, gi = null, _i = 0, vi = [], yi = 0, bi = null, W = 1, xi = ""; + function Si(e, t) { + mi[hi++] = _i, mi[hi++] = gi, gi = e, _i = t; + } + function Ci(e, t, n) { + vi[yi++] = W, vi[yi++] = xi, vi[yi++] = bi, bi = e; + var r = W; + e = xi; + var i = 32 - Fe(r) - 1; + r &= ~(1 << i), n += 1; + var a = 32 - Fe(t) + i; + if (30 < a) { + var o = i - i % 5; + a = (r & (1 << o) - 1).toString(32), r >>= o, i -= o, W = 1 << 32 - Fe(t) + i | n << i | r, xi = a + e; + } else W = 1 << a | n << i | r, xi = e; + } + function wi(e) { + e.return !== null && (Si(e, 1), Ci(e, 1, 0)); + } + function Ti(e) { + for (; e === gi;) gi = mi[--hi], mi[hi] = null, _i = mi[--hi], mi[hi] = null; + for (; e === bi;) bi = vi[--yi], vi[yi] = null, xi = vi[--yi], vi[yi] = null, W = vi[--yi], vi[yi] = null; + } + function Ei(e, t) { + vi[yi++] = W, vi[yi++] = xi, vi[yi++] = bi, W = t.id, xi = t.overflow, bi = e; + } + var Di = null, Oi = null, ki = !1, Ai = null, ji = !1, Mi = Error(i(519)); + function Ni(e) { + throw zi(pi(Error(i(418, 1 < arguments.length && arguments[1] !== void 0 && arguments[1] ? "text" : "HTML", "")), e)), Mi; + } + function Pi(e) { + var t = e.stateNode, n = e.type, r = e.memoizedProps; + switch (t[tt] = e, t[nt] = r, n) { + case "dialog": + Dd("cancel", t), Dd("close", t); + break; + case "iframe": + case "object": + case "embed": + Dd("load", t); + break; + case "video": + case "audio": + for (n = 0; n < wd.length; n++) Dd(wd[n], t); + break; + case "source": + Dd("error", t); + break; + case "img": + case "image": + case "link": + Dd("error", t), Dd("load", t); + break; + case "details": + Dd("toggle", t); + break; + case "input": + Dd("invalid", t), Ft(t, r.value, r.defaultValue, r.checked, r.defaultChecked, r.type, r.name, !0); + break; + case "select": + Dd("invalid", t); + break; + case "textarea": Dd("invalid", t), zt(t, r.value, r.defaultValue, r.children); + } + n = r.children, typeof n != "string" && typeof n != "number" && typeof n != "bigint" || t.textContent === "" + n || !0 === r.suppressHydrationWarning || Bd(t.textContent, n) ? (r.popover != null && (Dd("beforetoggle", t), Dd("toggle", t)), r.onScroll != null && Dd("scroll", t), r.onScrollEnd != null && Dd("scrollend", t), r.onClick != null && (t.onclick = Jt), t = !0) : t = !1, t || Ni(e, !0); + } + function Fi(e) { + for (Di = e.return; Di;) switch (Di.tag) { + case 5: + case 31: + case 13: + ji = !1; + return; + case 27: + case 3: + ji = !0; + return; + default: Di = Di.return; + } + } + function Ii(e) { + if (e !== Di) return !1; + if (!ki) return Fi(e), ki = !0, !1; + var t = e.tag, n; + if ((n = t !== 3 && t !== 27) && ((n = t === 5) && (n = e.type, n = n === "form" || n === "button" || Zd(e.type, e.memoizedProps)), n = !n), n && Oi && Ni(e), Fi(e), t === 13) { + if (e = e.memoizedState, e = e === null ? null : e.dehydrated, !e) throw Error(i(317)); + Oi = vf(e); + } else if (t === 31) { + if (e = e.memoizedState, e = e === null ? null : e.dehydrated, !e) throw Error(i(317)); + Oi = vf(e); + } else t === 27 ? (t = Oi, of(e.type) ? (e = _f, _f = null, Oi = e) : Oi = t) : Oi = Di ? gf(e.stateNode.nextSibling) : null; + return !0; + } + function Li() { + Oi = Di = null, ki = !1; + } + function Ri() { + var e = Ai; + return e !== null && (ru === null ? ru = e : ru.push.apply(ru, e), Ai = null), e; + } + function zi(e) { + Ai === null ? Ai = [e] : Ai.push(e); + } + var Bi = de(null), Vi = null, Hi = null; + function Ui(e, t, n) { + A(Bi, t._currentValue), t._currentValue = n; + } + function Wi(e) { + e._currentValue = Bi.current, fe(Bi); + } + function Gi(e, t, n) { + for (; e !== null;) { + var r = e.alternate; + if ((e.childLanes & t) === t ? r !== null && (r.childLanes & t) !== t && (r.childLanes |= t) : (e.childLanes |= t, r !== null && (r.childLanes |= t)), e === n) break; + e = e.return; + } + } + function Ki(e, t, n, r) { + var a = e.child; + for (a !== null && (a.return = e); a !== null;) { + var o = a.dependencies; + if (o !== null) { + var s = a.child; + o = o.firstContext; + a: for (; o !== null;) { + var c = o; + o = a; + for (var l = 0; l < t.length; l++) if (c.context === t[l]) { + o.lanes |= n, c = o.alternate, c !== null && (c.lanes |= n), Gi(o.return, n, e), r || (s = null); + break a; + } + o = c.next; + } + } else if (a.tag === 18) { + if (s = a.return, s === null) throw Error(i(341)); + s.lanes |= n, o = s.alternate, o !== null && (o.lanes |= n), Gi(s, n, e), s = null; + } else s = a.child; + if (s !== null) s.return = a; + else for (s = a; s !== null;) { + if (s === e) { + s = null; + break; + } + if (a = s.sibling, a !== null) { + a.return = s.return, s = a; + break; + } + s = s.return; + } + a = s; + } + } + function qi(e, t, n, r) { + e = null; + for (var a = t, o = !1; a !== null;) { + if (!o) { + if (a.flags & 524288) o = !0; + else if (a.flags & 262144) break; + } + if (a.tag === 10) { + var s = a.alternate; + if (s === null) throw Error(i(387)); + if (s = s.memoizedProps, s !== null) { + var c = a.type; + _r(a.pendingProps.value, s.value) || (e === null ? e = [c] : e.push(c)); + } + } else if (a === N.current) { + if (s = a.alternate, s === null) throw Error(i(387)); + s.memoizedState.memoizedState !== a.memoizedState.memoizedState && (e === null ? e = [op] : e.push(op)); + } + a = a.return; + } + e !== null && Ki(t, e, n, r), t.flags |= 262144; + } + function Ji(e) { + for (e = e.firstContext; e !== null;) { + if (!_r(e.context._currentValue, e.memoizedValue)) return !0; + e = e.next; + } + return !1; + } + function Yi(e) { + Vi = e, Hi = null, e = e.dependencies, e !== null && (e.firstContext = null); + } + function Xi(e) { + return Qi(Vi, e); + } + function Zi(e, t) { + return Vi === null && Yi(e), Qi(e, t); + } + function Qi(e, t) { + var n = t._currentValue; + if (t = { + context: t, + memoizedValue: n, + next: null + }, Hi === null) { + if (e === null) throw Error(i(308)); + Hi = t, e.dependencies = { + lanes: 0, + firstContext: t + }, e.flags |= 524288; + } else Hi = Hi.next = t; + return n; + } + var $i = typeof AbortController < "u" ? AbortController : function() { + var e = [], t = this.signal = { + aborted: !1, + addEventListener: function(t, n) { + e.push(n); + } + }; + this.abort = function() { + t.aborted = !0, e.forEach(function(e) { + return e(); + }); + }; + }, ea = t.unstable_scheduleCallback, ta = t.unstable_NormalPriority, na = { + $$typeof: C, + Consumer: null, + Provider: null, + _currentValue: null, + _currentValue2: null, + _threadCount: 0 + }; + function ra() { + return { + controller: new $i(), + data: /* @__PURE__ */ new Map(), + refCount: 0 + }; + } + function ia(e) { + e.refCount--, e.refCount === 0 && ea(ta, function() { + e.controller.abort(); + }); + } + var aa = null, oa = 0, sa = 0, ca = null; + function la(e, t) { + if (aa === null) { + var n = aa = []; + oa = 0, sa = vd(), ca = { + status: "pending", + value: void 0, + then: function(e) { + n.push(e); + } + }; + } + return oa++, t.then(ua, ua), t; + } + function ua() { + if (--oa === 0 && aa !== null) { + ca !== null && (ca.status = "fulfilled"); + var e = aa; + aa = null, sa = 0, ca = null; + for (var t = 0; t < e.length; t++) (0, e[t])(); + } + } + function da(e, t) { + var n = [], r = { + status: "pending", + value: null, + reason: null, + then: function(e) { + n.push(e); + } + }; + return e.then(function() { + r.status = "fulfilled", r.value = t; + for (var e = 0; e < n.length; e++) (0, n[e])(t); + }, function(e) { + for (r.status = "rejected", r.reason = e, e = 0; e < n.length; e++) (0, n[e])(void 0); + }), r; + } + var fa = O.S; + O.S = function(e, t) { + ou = Ee(), typeof t == "object" && t && typeof t.then == "function" && la(e, t), fa !== null && fa(e, t); + }; + var pa = de(null); + function ma() { + var e = pa.current; + return e === null ? Vl.pooledCache : e; + } + function ha(e, t) { + t === null ? A(pa, pa.current) : A(pa, t.pool); + } + function ga() { + var e = ma(); + return e === null ? null : { + parent: na._currentValue, + pool: e + }; + } + var _a = Error(i(460)), va = Error(i(474)), ya = Error(i(542)), ba = { then: function() {} }; + function xa(e) { + return e = e.status, e === "fulfilled" || e === "rejected"; + } + function Sa(e, t, n) { + switch (n = e[n], n === void 0 ? e.push(t) : n !== t && (t.then(Jt, Jt), t = n), t.status) { + case "fulfilled": return t.value; + case "rejected": throw e = t.reason, Ea(e), e; + default: + if (typeof t.status == "string") t.then(Jt, Jt); + else { + if (e = Vl, e !== null && 100 < e.shellSuspendCounter) throw Error(i(482)); + e = t, e.status = "pending", e.then(function(e) { + if (t.status === "pending") { + var n = t; + n.status = "fulfilled", n.value = e; + } + }, function(e) { + if (t.status === "pending") { + var n = t; + n.status = "rejected", n.reason = e; + } + }); + } + switch (t.status) { + case "fulfilled": return t.value; + case "rejected": throw e = t.reason, Ea(e), e; + } + throw wa = t, _a; + } + } + function Ca(e) { + try { + var t = e._init; + return t(e._payload); + } catch (e) { + throw typeof e == "object" && e && typeof e.then == "function" ? (wa = e, _a) : e; + } + } + var wa = null; + function Ta() { + if (wa === null) throw Error(i(459)); + var e = wa; + return wa = null, e; + } + function Ea(e) { + if (e === _a || e === ya) throw Error(i(483)); + } + var Da = null, Oa = 0; + function ka(e) { + var t = Oa; + return Oa += 1, Da === null && (Da = []), Sa(Da, e, t); + } + function Aa(e, t) { + t = t.props.ref, e.ref = t === void 0 ? null : t; + } + function ja(e, t) { + throw t.$$typeof === g ? Error(i(525)) : (e = Object.prototype.toString.call(t), Error(i(31, e === "[object Object]" ? "object with keys {" + Object.keys(t).join(", ") + "}" : e))); + } + function Ma(e) { + function t(t, n) { + if (e) { + var r = t.deletions; + r === null ? (t.deletions = [n], t.flags |= 16) : r.push(n); + } + } + function n(n, r) { + if (!e) return null; + for (; r !== null;) t(n, r), r = r.sibling; + return null; + } + function r(e) { + for (var t = /* @__PURE__ */ new Map(); e !== null;) e.key === null ? t.set(e.index, e) : t.set(e.key, e), e = e.sibling; + return t; + } + function a(e, t) { + return e = ai(e, t), e.index = 0, e.sibling = null, e; + } + function o(t, n, r) { + return t.index = r, e ? (r = t.alternate, r === null ? (t.flags |= 67108866, n) : (r = r.index, r < n ? (t.flags |= 67108866, n) : r)) : (t.flags |= 1048576, n); + } + function s(t) { + return e && t.alternate === null && (t.flags |= 67108866), t; + } + function c(e, t, n, r) { + return t === null || t.tag !== 6 ? (t = li(n, e.mode, r), t.return = e, t) : (t = a(t, n), t.return = e, t); + } + function l(e, t, n, r) { + var i = n.type; + return i === y ? d(e, t, n.props.children, r, n.key) : t !== null && (t.elementType === i || typeof i == "object" && i && i.$$typeof === D && Ca(i) === t.type) ? (t = a(t, n.props), Aa(t, n), t.return = e, t) : (t = si(n.type, n.key, n.props, null, e.mode, r), Aa(t, n), t.return = e, t); + } + function u(e, t, n, r) { + return t === null || t.tag !== 4 || t.stateNode.containerInfo !== n.containerInfo || t.stateNode.implementation !== n.implementation ? (t = di(n, e.mode, r), t.return = e, t) : (t = a(t, n.children || []), t.return = e, t); + } + function d(e, t, n, r, i) { + return t === null || t.tag !== 7 ? (t = ci(n, e.mode, r, i), t.return = e, t) : (t = a(t, n), t.return = e, t); + } + function f(e, t, n) { + if (typeof t == "string" && t !== "" || typeof t == "number" || typeof t == "bigint") return t = li("" + t, e.mode, n), t.return = e, t; + if (typeof t == "object" && t) { + switch (t.$$typeof) { + case _: return n = si(t.type, t.key, t.props, null, e.mode, n), Aa(n, t), n.return = e, n; + case v: return t = di(t, e.mode, n), t.return = e, t; + case D: return t = Ca(t), f(e, t, n); + } + if (se(t) || ie(t)) return t = ci(t, e.mode, n, null), t.return = e, t; + if (typeof t.then == "function") return f(e, ka(t), n); + if (t.$$typeof === C) return f(e, Zi(e, t), n); + ja(e, t); + } + return null; + } + function p(e, t, n, r) { + var i = t === null ? null : t.key; + if (typeof n == "string" && n !== "" || typeof n == "number" || typeof n == "bigint") return i === null ? c(e, t, "" + n, r) : null; + if (typeof n == "object" && n) { + switch (n.$$typeof) { + case _: return n.key === i ? l(e, t, n, r) : null; + case v: return n.key === i ? u(e, t, n, r) : null; + case D: return n = Ca(n), p(e, t, n, r); + } + if (se(n) || ie(n)) return i === null ? d(e, t, n, r, null) : null; + if (typeof n.then == "function") return p(e, t, ka(n), r); + if (n.$$typeof === C) return p(e, t, Zi(e, n), r); + ja(e, n); + } + return null; + } + function m(e, t, n, r, i) { + if (typeof r == "string" && r !== "" || typeof r == "number" || typeof r == "bigint") return e = e.get(n) || null, c(t, e, "" + r, i); + if (typeof r == "object" && r) { + switch (r.$$typeof) { + case _: return e = e.get(r.key === null ? n : r.key) || null, l(t, e, r, i); + case v: return e = e.get(r.key === null ? n : r.key) || null, u(t, e, r, i); + case D: return r = Ca(r), m(e, t, n, r, i); + } + if (se(r) || ie(r)) return e = e.get(n) || null, d(t, e, r, i, null); + if (typeof r.then == "function") return m(e, t, n, ka(r), i); + if (r.$$typeof === C) return m(e, t, n, Zi(t, r), i); + ja(t, r); + } + return null; + } + function h(i, a, s, c) { + for (var l = null, u = null, d = a, h = a = 0, g = null; d !== null && h < s.length; h++) { + d.index > h ? (g = d, d = null) : g = d.sibling; + var _ = p(i, d, s[h], c); + if (_ === null) { + d === null && (d = g); + break; + } + e && d && _.alternate === null && t(i, d), a = o(_, a, h), u === null ? l = _ : u.sibling = _, u = _, d = g; + } + if (h === s.length) return n(i, d), ki && Si(i, h), l; + if (d === null) { + for (; h < s.length; h++) d = f(i, s[h], c), d !== null && (a = o(d, a, h), u === null ? l = d : u.sibling = d, u = d); + return ki && Si(i, h), l; + } + for (d = r(d); h < s.length; h++) g = m(d, i, h, s[h], c), g !== null && (e && g.alternate !== null && d.delete(g.key === null ? h : g.key), a = o(g, a, h), u === null ? l = g : u.sibling = g, u = g); + return e && d.forEach(function(e) { + return t(i, e); + }), ki && Si(i, h), l; + } + function g(a, s, c, l) { + if (c == null) throw Error(i(151)); + for (var u = null, d = null, h = s, g = s = 0, _ = null, v = c.next(); h !== null && !v.done; g++, v = c.next()) { + h.index > g ? (_ = h, h = null) : _ = h.sibling; + var y = p(a, h, v.value, l); + if (y === null) { + h === null && (h = _); + break; + } + e && h && y.alternate === null && t(a, h), s = o(y, s, g), d === null ? u = y : d.sibling = y, d = y, h = _; + } + if (v.done) return n(a, h), ki && Si(a, g), u; + if (h === null) { + for (; !v.done; g++, v = c.next()) v = f(a, v.value, l), v !== null && (s = o(v, s, g), d === null ? u = v : d.sibling = v, d = v); + return ki && Si(a, g), u; + } + for (h = r(h); !v.done; g++, v = c.next()) v = m(h, a, g, v.value, l), v !== null && (e && v.alternate !== null && h.delete(v.key === null ? g : v.key), s = o(v, s, g), d === null ? u = v : d.sibling = v, d = v); + return e && h.forEach(function(e) { + return t(a, e); + }), ki && Si(a, g), u; + } + function b(e, r, o, c) { + if (typeof o == "object" && o && o.type === y && o.key === null && (o = o.props.children), typeof o == "object" && o) { + switch (o.$$typeof) { + case _: + a: { + for (var l = o.key; r !== null;) { + if (r.key === l) { + if (l = o.type, l === y) { + if (r.tag === 7) { + n(e, r.sibling), c = a(r, o.props.children), c.return = e, e = c; + break a; + } + } else if (r.elementType === l || typeof l == "object" && l && l.$$typeof === D && Ca(l) === r.type) { + n(e, r.sibling), c = a(r, o.props), Aa(c, o), c.return = e, e = c; + break a; + } + n(e, r); + break; + } + t(e, r), r = r.sibling; + } + o.type === y ? (c = ci(o.props.children, e.mode, c, o.key), c.return = e, e = c) : (c = si(o.type, o.key, o.props, null, e.mode, c), Aa(c, o), c.return = e, e = c); + } + return s(e); + case v: + a: { + for (l = o.key; r !== null;) { + if (r.key === l) { + if (r.tag === 4 && r.stateNode.containerInfo === o.containerInfo && r.stateNode.implementation === o.implementation) { + n(e, r.sibling), c = a(r, o.children || []), c.return = e, e = c; + break a; + } + n(e, r); + break; + } + t(e, r), r = r.sibling; + } + c = di(o, e.mode, c), c.return = e, e = c; + } + return s(e); + case D: return o = Ca(o), b(e, r, o, c); + } + if (se(o)) return h(e, r, o, c); + if (ie(o)) { + if (l = ie(o), typeof l != "function") throw Error(i(150)); + return o = l.call(o), g(e, r, o, c); + } + if (typeof o.then == "function") return b(e, r, ka(o), c); + if (o.$$typeof === C) return b(e, r, Zi(e, o), c); + ja(e, o); + } + return typeof o == "string" && o !== "" || typeof o == "number" || typeof o == "bigint" ? (o = "" + o, r !== null && r.tag === 6 ? (n(e, r.sibling), c = a(r, o), c.return = e, e = c) : (n(e, r), c = li(o, e.mode, c), c.return = e, e = c), s(e)) : n(e, r); + } + return function(e, t, n, r) { + try { + Oa = 0; + var i = b(e, t, n, r); + return Da = null, i; + } catch (t) { + if (t === _a || t === ya) throw t; + var a = ri(29, t, null, e.mode); + return a.lanes = r, a.return = e, a; + } + }; + } + var Na = Ma(!0), Pa = Ma(!1), Fa = !1; + function Ia(e) { + e.updateQueue = { + baseState: e.memoizedState, + firstBaseUpdate: null, + lastBaseUpdate: null, + shared: { + pending: null, + lanes: 0, + hiddenCallbacks: null + }, + callbacks: null + }; + } + function La(e, t) { + e = e.updateQueue, t.updateQueue === e && (t.updateQueue = { + baseState: e.baseState, + firstBaseUpdate: e.firstBaseUpdate, + lastBaseUpdate: e.lastBaseUpdate, + shared: e.shared, + callbacks: null + }); + } + function Ra(e) { + return { + lane: e, + tag: 0, + payload: null, + callback: null, + next: null + }; + } + function za(e, t, n) { + var r = e.updateQueue; + if (r === null) return null; + if (r = r.shared, Bl & 2) { + var i = r.pending; + return i === null ? t.next = t : (t.next = i.next, i.next = t), r.pending = t, t = ei(e), $r(e, null, n), t; + } + return Xr(e, r, t, n), ei(e); + } + function Ba(e, t, n) { + if (t = t.updateQueue, t !== null && (t = t.shared, n & 4194048)) { + var r = t.lanes; + r &= e.pendingLanes, n |= r, t.lanes = n, Je(e, n); + } + } + function Va(e, t) { + var n = e.updateQueue, r = e.alternate; + if (r !== null && (r = r.updateQueue, n === r)) { + var i = null, a = null; + if (n = n.firstBaseUpdate, n !== null) { + do { + var o = { + lane: n.lane, + tag: n.tag, + payload: n.payload, + callback: null, + next: null + }; + a === null ? i = a = o : a = a.next = o, n = n.next; + } while (n !== null); + a === null ? i = a = t : a = a.next = t; + } else i = a = t; + n = { + baseState: r.baseState, + firstBaseUpdate: i, + lastBaseUpdate: a, + shared: r.shared, + callbacks: r.callbacks + }, e.updateQueue = n; + return; + } + e = n.lastBaseUpdate, e === null ? n.firstBaseUpdate = t : e.next = t, n.lastBaseUpdate = t; + } + var Ha = !1; + function Ua() { + if (Ha) { + var e = ca; + if (e !== null) throw e; + } + } + function Wa(e, t, n, r) { + Ha = !1; + var i = e.updateQueue; + Fa = !1; + var a = i.firstBaseUpdate, o = i.lastBaseUpdate, s = i.shared.pending; + if (s !== null) { + i.shared.pending = null; + var c = s, l = c.next; + c.next = null, o === null ? a = l : o.next = l, o = c; + var u = e.alternate; + u !== null && (u = u.updateQueue, s = u.lastBaseUpdate, s !== o && (s === null ? u.firstBaseUpdate = l : s.next = l, u.lastBaseUpdate = c)); + } + if (a !== null) { + var d = i.baseState; + o = 0, u = l = c = null, s = a; + do { + var f = s.lane & -536870913, p = f !== s.lane; + if (p ? (Ul & f) === f : (r & f) === f) { + f !== 0 && f === sa && (Ha = !0), u !== null && (u = u.next = { + lane: 0, + tag: s.tag, + payload: s.payload, + callback: null, + next: null + }); + a: { + var h = e, g = s; + f = t; + var _ = n; + switch (g.tag) { + case 1: + if (h = g.payload, typeof h == "function") { + d = h.call(_, d, f); + break a; + } + d = h; + break a; + case 3: h.flags = h.flags & -65537 | 128; + case 0: + if (h = g.payload, f = typeof h == "function" ? h.call(_, d, f) : h, f == null) break a; + d = m({}, d, f); + break a; + case 2: Fa = !0; + } + } + f = s.callback, f !== null && (e.flags |= 64, p && (e.flags |= 8192), p = i.callbacks, p === null ? i.callbacks = [f] : p.push(f)); + } else p = { + lane: f, + tag: s.tag, + payload: s.payload, + callback: s.callback, + next: null + }, u === null ? (l = u = p, c = d) : u = u.next = p, o |= f; + if (s = s.next, s === null) { + if (s = i.shared.pending, s === null) break; + p = s, s = p.next, p.next = null, i.lastBaseUpdate = p, i.shared.pending = null; + } + } while (1); + u === null && (c = d), i.baseState = c, i.firstBaseUpdate = l, i.lastBaseUpdate = u, a === null && (i.shared.lanes = 0), Zl |= o, e.lanes = o, e.memoizedState = d; + } + } + function Ga(e, t) { + if (typeof e != "function") throw Error(i(191, e)); + e.call(t); + } + function Ka(e, t) { + var n = e.callbacks; + if (n !== null) for (e.callbacks = null, e = 0; e < n.length; e++) Ga(n[e], t); + } + var qa = de(null), Ja = de(0); + function Ya(e, t) { + e = Yl, A(Ja, e), A(qa, t), Yl = e | t.baseLanes; + } + function Xa() { + A(Ja, Yl), A(qa, qa.current); + } + function Za() { + Yl = Ja.current, fe(qa), fe(Ja); + } + var Qa = de(null), $a = null; + function eo(e) { + var t = e.alternate; + A(ao, ao.current & 1), A(Qa, e), $a === null && (t === null || qa.current !== null || t.memoizedState !== null) && ($a = e); + } + function to(e) { + A(ao, ao.current), A(Qa, e), $a === null && ($a = e); + } + function no(e) { + e.tag === 22 ? (A(ao, ao.current), A(Qa, e), $a === null && ($a = e)) : ro(e); + } + function ro() { + A(ao, ao.current), A(Qa, Qa.current); + } + function io(e) { + fe(Qa), $a === e && ($a = null), fe(ao); + } + var ao = de(0); + function oo(e) { + for (var t = e; t !== null;) { + if (t.tag === 13) { + var n = t.memoizedState; + if (n !== null && (n = n.dehydrated, n === null || pf(n) || mf(n))) return t; + } else if (t.tag === 19 && (t.memoizedProps.revealOrder === "forwards" || t.memoizedProps.revealOrder === "backwards" || t.memoizedProps.revealOrder === "unstable_legacy-backwards" || t.memoizedProps.revealOrder === "together")) { + if (t.flags & 128) return t; + } else if (t.child !== null) { + t.child.return = t, t = t.child; + continue; + } + if (t === e) break; + for (; t.sibling === null;) { + if (t.return === null || t.return === e) return null; + t = t.return; + } + t.sibling.return = t.return, t = t.sibling; + } + return null; + } + var so = 0, co = null, lo = null, uo = null, fo = !1, po = !1, mo = !1, ho = 0, go = 0, _o = null, vo = 0; + function yo() { + throw Error(i(321)); + } + function bo(e, t) { + if (t === null) return !1; + for (var n = 0; n < t.length && n < e.length; n++) if (!_r(e[n], t[n])) return !1; + return !0; + } + function xo(e, t, n, r, i, a) { + return so = a, co = t, t.memoizedState = null, t.updateQueue = null, t.lanes = 0, O.H = e === null || e.memoizedState === null ? Rs : zs, mo = !1, a = n(r, i), mo = !1, po && (a = Co(t, n, r, i)), So(e), a; + } + function So(e) { + O.H = Ls; + var t = lo !== null && lo.next !== null; + if (so = 0, uo = lo = co = null, fo = !1, go = 0, _o = null, t) throw Error(i(300)); + e === null || nc || (e = e.dependencies, e !== null && Ji(e) && (nc = !0)); + } + function Co(e, t, n, r) { + co = e; + var a = 0; + do { + if (po && (_o = null), go = 0, po = !1, 25 <= a) throw Error(i(301)); + if (a += 1, uo = lo = null, e.updateQueue != null) { + var o = e.updateQueue; + o.lastEffect = null, o.events = null, o.stores = null, o.memoCache != null && (o.memoCache.index = 0); + } + O.H = Bs, o = t(n, r); + } while (po); + return o; + } + function wo() { + var e = O.H, t = e.useState()[0]; + return t = typeof t.then == "function" ? jo(t) : t, e = e.useState()[0], (lo === null ? null : lo.memoizedState) !== e && (co.flags |= 1024), t; + } + function To() { + var e = ho !== 0; + return ho = 0, e; + } + function Eo(e, t, n) { + t.updateQueue = e.updateQueue, t.flags &= -2053, e.lanes &= ~n; + } + function Do(e) { + if (fo) { + for (e = e.memoizedState; e !== null;) { + var t = e.queue; + t !== null && (t.pending = null), e = e.next; + } + fo = !1; + } + so = 0, uo = lo = co = null, po = !1, go = ho = 0, _o = null; + } + function Oo() { + var e = { + memoizedState: null, + baseState: null, + baseQueue: null, + queue: null, + next: null + }; + return uo === null ? co.memoizedState = uo = e : uo = uo.next = e, uo; + } + function ko() { + if (lo === null) { + var e = co.alternate; + e = e === null ? null : e.memoizedState; + } else e = lo.next; + var t = uo === null ? co.memoizedState : uo.next; + if (t !== null) uo = t, lo = e; + else { + if (e === null) throw co.alternate === null ? Error(i(467)) : Error(i(310)); + lo = e, e = { + memoizedState: lo.memoizedState, + baseState: lo.baseState, + baseQueue: lo.baseQueue, + queue: lo.queue, + next: null + }, uo === null ? co.memoizedState = uo = e : uo = uo.next = e; + } + return uo; + } + function Ao() { + return { + lastEffect: null, + events: null, + stores: null, + memoCache: null + }; + } + function jo(e) { + var t = go; + return go += 1, _o === null && (_o = []), e = Sa(_o, e, t), t = co, (uo === null ? t.memoizedState : uo.next) === null && (t = t.alternate, O.H = t === null || t.memoizedState === null ? Rs : zs), e; + } + function Mo(e) { + if (typeof e == "object" && e) { + if (typeof e.then == "function") return jo(e); + if (e.$$typeof === C) return Xi(e); + } + throw Error(i(438, String(e))); + } + function No(e) { + var t = null, n = co.updateQueue; + if (n !== null && (t = n.memoCache), t == null) { + var r = co.alternate; + r !== null && (r = r.updateQueue, r !== null && (r = r.memoCache, r != null && (t = { + data: r.data.map(function(e) { + return e.slice(); + }), + index: 0 + }))); + } + if (t ??= { + data: [], + index: 0 + }, n === null && (n = Ao(), co.updateQueue = n), n.memoCache = t, n = t.data[t.index], n === void 0) for (n = t.data[t.index] = Array(e), r = 0; r < e; r++) n[r] = ne; + return t.index++, n; + } + function Po(e, t) { + return typeof t == "function" ? t(e) : t; + } + function Fo(e) { + return Io(ko(), lo, e); + } + function Io(e, t, n) { + var r = e.queue; + if (r === null) throw Error(i(311)); + r.lastRenderedReducer = n; + var a = e.baseQueue, o = r.pending; + if (o !== null) { + if (a !== null) { + var s = a.next; + a.next = o.next, o.next = s; + } + t.baseQueue = a = o, r.pending = null; + } + if (o = e.baseState, a === null) e.memoizedState = o; + else { + t = a.next; + var c = s = null, l = null, u = t, d = !1; + do { + var f = u.lane & -536870913; + if (f === u.lane ? (so & f) === f : (Ul & f) === f) { + var p = u.revertLane; + if (p === 0) l !== null && (l = l.next = { + lane: 0, + revertLane: 0, + gesture: null, + action: u.action, + hasEagerState: u.hasEagerState, + eagerState: u.eagerState, + next: null + }), f === sa && (d = !0); + else if ((so & p) === p) { + u = u.next, p === sa && (d = !0); + continue; + } else f = { + lane: 0, + revertLane: u.revertLane, + gesture: null, + action: u.action, + hasEagerState: u.hasEagerState, + eagerState: u.eagerState, + next: null + }, l === null ? (c = l = f, s = o) : l = l.next = f, co.lanes |= p, Zl |= p; + f = u.action, mo && n(o, f), o = u.hasEagerState ? u.eagerState : n(o, f); + } else p = { + lane: f, + revertLane: u.revertLane, + gesture: u.gesture, + action: u.action, + hasEagerState: u.hasEagerState, + eagerState: u.eagerState, + next: null + }, l === null ? (c = l = p, s = o) : l = l.next = p, co.lanes |= f, Zl |= f; + u = u.next; + } while (u !== null && u !== t); + if (l === null ? s = o : l.next = c, !_r(o, e.memoizedState) && (nc = !0, d && (n = ca, n !== null))) throw n; + e.memoizedState = o, e.baseState = s, e.baseQueue = l, r.lastRenderedState = o; + } + return a === null && (r.lanes = 0), [e.memoizedState, r.dispatch]; + } + function Lo(e) { + var t = ko(), n = t.queue; + if (n === null) throw Error(i(311)); + n.lastRenderedReducer = e; + var r = n.dispatch, a = n.pending, o = t.memoizedState; + if (a !== null) { + n.pending = null; + var s = a = a.next; + do + o = e(o, s.action), s = s.next; + while (s !== a); + _r(o, t.memoizedState) || (nc = !0), t.memoizedState = o, t.baseQueue === null && (t.baseState = o), n.lastRenderedState = o; + } + return [o, r]; + } + function Ro(e, t, n) { + var r = co, a = ko(), o = ki; + if (o) { + if (n === void 0) throw Error(i(407)); + n = n(); + } else n = t(); + var s = !_r((lo || a).memoizedState, n); + if (s && (a.memoizedState = n, nc = !0), a = a.queue, ls(Vo.bind(null, r, a, e), [e]), a.getSnapshot !== t || s || uo !== null && uo.memoizedState.tag & 1) { + if (r.flags |= 2048, is(9, { destroy: void 0 }, Bo.bind(null, r, a, n, t), null), Vl === null) throw Error(i(349)); + o || so & 127 || zo(r, t, n); + } + return n; + } + function zo(e, t, n) { + e.flags |= 16384, e = { + getSnapshot: t, + value: n + }, t = co.updateQueue, t === null ? (t = Ao(), co.updateQueue = t, t.stores = [e]) : (n = t.stores, n === null ? t.stores = [e] : n.push(e)); + } + function Bo(e, t, n, r) { + t.value = n, t.getSnapshot = r, Ho(t) && Uo(e); + } + function Vo(e, t, n) { + return n(function() { + Ho(t) && Uo(e); + }); + } + function Ho(e) { + var t = e.getSnapshot; + e = e.value; + try { + var n = t(); + return !_r(e, n); + } catch { + return !0; + } + } + function Uo(e) { + var t = Qr(e, 2); + t !== null && xu(t, e, 2); + } + function Wo(e) { + var t = Oo(); + if (typeof e == "function") { + var n = e; + if (e = n(), mo) { + B(!0); + try { + n(); + } finally { + B(!1); + } + } + } + return t.memoizedState = t.baseState = e, t.queue = { + pending: null, + lanes: 0, + dispatch: null, + lastRenderedReducer: Po, + lastRenderedState: e + }, t; + } + function Go(e, t, n, r) { + return e.baseState = n, Io(e, lo, typeof r == "function" ? r : Po); + } + function Ko(e, t, n, r, a) { + if (Ps(e)) throw Error(i(485)); + if (e = t.action, e !== null) { + var o = { + payload: a, + action: e, + next: null, + isTransition: !0, + status: "pending", + value: null, + reason: null, + listeners: [], + then: function(e) { + o.listeners.push(e); + } + }; + O.T === null ? o.isTransition = !1 : n(!0), r(o), n = t.pending, n === null ? (o.next = t.pending = o, qo(t, o)) : (o.next = n.next, t.pending = n.next = o); + } + } + function qo(e, t) { + var n = t.action, r = t.payload, i = e.state; + if (t.isTransition) { + var a = O.T, o = {}; + O.T = o; + try { + var s = n(i, r), c = O.S; + c !== null && c(o, s), Jo(e, t, s); + } catch (n) { + Xo(e, t, n); + } finally { + a !== null && o.types !== null && (a.types = o.types), O.T = a; + } + } else try { + a = n(i, r), Jo(e, t, a); + } catch (n) { + Xo(e, t, n); + } + } + function Jo(e, t, n) { + typeof n == "object" && n && typeof n.then == "function" ? n.then(function(n) { + Yo(e, t, n); + }, function(n) { + return Xo(e, t, n); + }) : Yo(e, t, n); + } + function Yo(e, t, n) { + t.status = "fulfilled", t.value = n, Zo(t), e.state = n, t = e.pending, t !== null && (n = t.next, n === t ? e.pending = null : (n = n.next, t.next = n, qo(e, n))); + } + function Xo(e, t, n) { + var r = e.pending; + if (e.pending = null, r !== null) { + r = r.next; + do + t.status = "rejected", t.reason = n, Zo(t), t = t.next; + while (t !== r); + } + e.action = null; + } + function Zo(e) { + e = e.listeners; + for (var t = 0; t < e.length; t++) (0, e[t])(); + } + function Qo(e, t) { + return t; + } + function $o(e, t) { + if (ki) { + var n = Vl.formState; + if (n !== null) { + a: { + var r = co; + if (ki) { + if (Oi) { + b: { + for (var i = Oi, a = ji; i.nodeType !== 8;) { + if (!a) { + i = null; + break b; + } + if (i = gf(i.nextSibling), i === null) { + i = null; + break b; + } + } + a = i.data, i = a === "F!" || a === "F" ? i : null; + } + if (i) { + Oi = gf(i.nextSibling), r = i.data === "F!"; + break a; + } + } + Ni(r); + } + r = !1; + } + r && (t = n[0]); + } + } + return n = Oo(), n.memoizedState = n.baseState = t, r = { + pending: null, + lanes: 0, + dispatch: null, + lastRenderedReducer: Qo, + lastRenderedState: t + }, n.queue = r, n = js.bind(null, co, r), r.dispatch = n, r = Wo(!1), a = Ns.bind(null, co, !1, r.queue), r = Oo(), i = { + state: t, + dispatch: null, + action: e, + pending: null + }, r.queue = i, n = Ko.bind(null, co, i, a, n), i.dispatch = n, r.memoizedState = e, [ + t, + n, + !1 + ]; + } + function es(e) { + return ts(ko(), lo, e); + } + function ts(e, t, n) { + if (t = Io(e, t, Qo)[0], e = Fo(Po)[0], typeof t == "object" && t && typeof t.then == "function") try { + var r = jo(t); + } catch (e) { + throw e === _a ? ya : e; + } + else r = t; + t = ko(); + var i = t.queue, a = i.dispatch; + return n !== t.memoizedState && (co.flags |= 2048, is(9, { destroy: void 0 }, ns.bind(null, i, n), null)), [ + r, + a, + e + ]; + } + function ns(e, t) { + e.action = t; + } + function rs(e) { + var t = ko(), n = lo; + if (n !== null) return ts(t, n, e); + ko(), t = t.memoizedState, n = ko(); + var r = n.queue.dispatch; + return n.memoizedState = e, [ + t, + r, + !1 + ]; + } + function is(e, t, n, r) { + return e = { + tag: e, + create: n, + deps: r, + inst: t, + next: null + }, t = co.updateQueue, t === null && (t = Ao(), co.updateQueue = t), n = t.lastEffect, n === null ? t.lastEffect = e.next = e : (r = n.next, n.next = e, e.next = r, t.lastEffect = e), e; + } + function as() { + return ko().memoizedState; + } + function os(e, t, n, r) { + var i = Oo(); + co.flags |= e, i.memoizedState = is(1 | t, { destroy: void 0 }, n, r === void 0 ? null : r); + } + function ss(e, t, n, r) { + var i = ko(); + r = r === void 0 ? null : r; + var a = i.memoizedState.inst; + lo !== null && r !== null && bo(r, lo.memoizedState.deps) ? i.memoizedState = is(t, a, n, r) : (co.flags |= e, i.memoizedState = is(1 | t, a, n, r)); + } + function cs(e, t) { + os(8390656, 8, e, t); + } + function ls(e, t) { + ss(2048, 8, e, t); + } + function us(e) { + co.flags |= 4; + var t = co.updateQueue; + if (t === null) t = Ao(), co.updateQueue = t, t.events = [e]; + else { + var n = t.events; + n === null ? t.events = [e] : n.push(e); + } + } + function ds(e) { + var t = ko().memoizedState; + return us({ + ref: t, + nextImpl: e + }), function() { + if (Bl & 2) throw Error(i(440)); + return t.impl.apply(void 0, arguments); + }; + } + function fs(e, t) { + return ss(4, 2, e, t); + } + function ps(e, t) { + return ss(4, 4, e, t); + } + function ms(e, t) { + if (typeof t == "function") { + e = e(); + var n = t(e); + return function() { + typeof n == "function" ? n() : t(null); + }; + } + if (t != null) return e = e(), t.current = e, function() { + t.current = null; + }; + } + function hs(e, t, n) { + n = n == null ? null : n.concat([e]), ss(4, 4, ms.bind(null, t, e), n); + } + function gs() {} + function _s(e, t) { + var n = ko(); + t = t === void 0 ? null : t; + var r = n.memoizedState; + return t !== null && bo(t, r[1]) ? r[0] : (n.memoizedState = [e, t], e); + } + function vs(e, t) { + var n = ko(); + t = t === void 0 ? null : t; + var r = n.memoizedState; + if (t !== null && bo(t, r[1])) return r[0]; + if (r = e(), mo) { + B(!0); + try { + e(); + } finally { + B(!1); + } + } + return n.memoizedState = [r, t], r; + } + function ys(e, t, n) { + return n === void 0 || so & 1073741824 && !(Ul & 261930) ? e.memoizedState = t : (e.memoizedState = n, e = bu(), co.lanes |= e, Zl |= e, n); + } + function bs(e, t, n, r) { + return _r(n, t) ? n : qa.current === null ? !(so & 42) || so & 1073741824 && !(Ul & 261930) ? (nc = !0, e.memoizedState = n) : (e = bu(), co.lanes |= e, Zl |= e, t) : (e = ys(e, n, r), _r(e, t) || (nc = !0), e); + } + function xs(e, t, n, r, i) { + var a = k.p; + k.p = a !== 0 && 8 > a ? a : 8; + var o = O.T, s = {}; + O.T = s, Ns(e, !1, t, n); + try { + var c = i(), l = O.S; + l !== null && l(s, c), typeof c == "object" && c && typeof c.then == "function" ? Ms(e, t, da(c, r), yu(e)) : Ms(e, t, r, yu(e)); + } catch (n) { + Ms(e, t, { + then: function() {}, + status: "rejected", + reason: n + }, yu()); + } finally { + k.p = a, o !== null && s.types !== null && (o.types = s.types), O.T = o; + } + } + function Ss() {} + function Cs(e, t, n, r) { + if (e.tag !== 5) throw Error(i(476)); + var a = ws(e).queue; + xs(e, a, t, ce, n === null ? Ss : function() { + return Ts(e), n(r); + }); + } + function ws(e) { + var t = e.memoizedState; + if (t !== null) return t; + t = { + memoizedState: ce, + baseState: ce, + baseQueue: null, + queue: { + pending: null, + lanes: 0, + dispatch: null, + lastRenderedReducer: Po, + lastRenderedState: ce + }, + next: null + }; + var n = {}; + return t.next = { + memoizedState: n, + baseState: n, + baseQueue: null, + queue: { + pending: null, + lanes: 0, + dispatch: null, + lastRenderedReducer: Po, + lastRenderedState: n + }, + next: null + }, e.memoizedState = t, e = e.alternate, e !== null && (e.memoizedState = t), t; + } + function Ts(e) { + var t = ws(e); + t.next === null && (t = e.alternate.memoizedState), Ms(e, t.next.queue, {}, yu()); + } + function Es() { + return Xi(op); + } + function Ds() { + return ko().memoizedState; + } + function Os() { + return ko().memoizedState; + } + function ks(e) { + for (var t = e.return; t !== null;) { + switch (t.tag) { + case 24: + case 3: + var n = yu(); + e = Ra(n); + var r = za(t, e, n); + r !== null && (xu(r, t, n), Ba(r, t, n)), t = { cache: ra() }, e.payload = t; + return; + } + t = t.return; + } + } + function As(e, t, n) { + var r = yu(); + n = { + lane: r, + revertLane: 0, + gesture: null, + action: n, + hasEagerState: !1, + eagerState: null, + next: null + }, Ps(e) ? Fs(t, n) : (n = Zr(e, t, n, r), n !== null && (xu(n, e, r), Is(n, t, r))); + } + function js(e, t, n) { + Ms(e, t, n, yu()); + } + function Ms(e, t, n, r) { + var i = { + lane: r, + revertLane: 0, + gesture: null, + action: n, + hasEagerState: !1, + eagerState: null, + next: null + }; + if (Ps(e)) Fs(t, i); + else { + var a = e.alternate; + if (e.lanes === 0 && (a === null || a.lanes === 0) && (a = t.lastRenderedReducer, a !== null)) try { + var o = t.lastRenderedState, s = a(o, n); + if (i.hasEagerState = !0, i.eagerState = s, _r(s, o)) return Xr(e, t, i, 0), Vl === null && Yr(), !1; + } catch {} + if (n = Zr(e, t, i, r), n !== null) return xu(n, e, r), Is(n, t, r), !0; + } + return !1; + } + function Ns(e, t, n, r) { + if (r = { + lane: 2, + revertLane: vd(), + gesture: null, + action: r, + hasEagerState: !1, + eagerState: null, + next: null + }, Ps(e)) { + if (t) throw Error(i(479)); + } else t = Zr(e, n, r, 2), t !== null && xu(t, e, 2); + } + function Ps(e) { + var t = e.alternate; + return e === co || t !== null && t === co; + } + function Fs(e, t) { + po = fo = !0; + var n = e.pending; + n === null ? t.next = t : (t.next = n.next, n.next = t), e.pending = t; + } + function Is(e, t, n) { + if (n & 4194048) { + var r = t.lanes; + r &= e.pendingLanes, n |= r, t.lanes = n, Je(e, n); + } + } + var Ls = { + readContext: Xi, + use: Mo, + useCallback: yo, + useContext: yo, + useEffect: yo, + useImperativeHandle: yo, + useLayoutEffect: yo, + useInsertionEffect: yo, + useMemo: yo, + useReducer: yo, + useRef: yo, + useState: yo, + useDebugValue: yo, + useDeferredValue: yo, + useTransition: yo, + useSyncExternalStore: yo, + useId: yo, + useHostTransitionStatus: yo, + useFormState: yo, + useActionState: yo, + useOptimistic: yo, + useMemoCache: yo, + useCacheRefresh: yo + }; + Ls.useEffectEvent = yo; + var Rs = { + readContext: Xi, + use: Mo, + useCallback: function(e, t) { + return Oo().memoizedState = [e, t === void 0 ? null : t], e; + }, + useContext: Xi, + useEffect: cs, + useImperativeHandle: function(e, t, n) { + n = n == null ? null : n.concat([e]), os(4194308, 4, ms.bind(null, t, e), n); + }, + useLayoutEffect: function(e, t) { + return os(4194308, 4, e, t); + }, + useInsertionEffect: function(e, t) { + os(4, 2, e, t); + }, + useMemo: function(e, t) { + var n = Oo(); + t = t === void 0 ? null : t; + var r = e(); + if (mo) { + B(!0); + try { + e(); + } finally { + B(!1); + } + } + return n.memoizedState = [r, t], r; + }, + useReducer: function(e, t, n) { + var r = Oo(); + if (n !== void 0) { + var i = n(t); + if (mo) { + B(!0); + try { + n(t); + } finally { + B(!1); + } + } + } else i = t; + return r.memoizedState = r.baseState = i, e = { + pending: null, + lanes: 0, + dispatch: null, + lastRenderedReducer: e, + lastRenderedState: i + }, r.queue = e, e = e.dispatch = As.bind(null, co, e), [r.memoizedState, e]; + }, + useRef: function(e) { + var t = Oo(); + return e = { current: e }, t.memoizedState = e; + }, + useState: function(e) { + e = Wo(e); + var t = e.queue, n = js.bind(null, co, t); + return t.dispatch = n, [e.memoizedState, n]; + }, + useDebugValue: gs, + useDeferredValue: function(e, t) { + return ys(Oo(), e, t); + }, + useTransition: function() { + var e = Wo(!1); + return e = xs.bind(null, co, e.queue, !0, !1), Oo().memoizedState = e, [!1, e]; + }, + useSyncExternalStore: function(e, t, n) { + var r = co, a = Oo(); + if (ki) { + if (n === void 0) throw Error(i(407)); + n = n(); + } else { + if (n = t(), Vl === null) throw Error(i(349)); + Ul & 127 || zo(r, t, n); + } + a.memoizedState = n; + var o = { + value: n, + getSnapshot: t + }; + return a.queue = o, cs(Vo.bind(null, r, o, e), [e]), r.flags |= 2048, is(9, { destroy: void 0 }, Bo.bind(null, r, o, n, t), null), n; + }, + useId: function() { + var e = Oo(), t = Vl.identifierPrefix; + if (ki) { + var n = xi, r = W; + n = (r & ~(1 << 32 - Fe(r) - 1)).toString(32) + n, t = "_" + t + "R_" + n, n = ho++, 0 < n && (t += "H" + n.toString(32)), t += "_"; + } else n = vo++, t = "_" + t + "r_" + n.toString(32) + "_"; + return e.memoizedState = t; + }, + useHostTransitionStatus: Es, + useFormState: $o, + useActionState: $o, + useOptimistic: function(e) { + var t = Oo(); + t.memoizedState = t.baseState = e; + var n = { + pending: null, + lanes: 0, + dispatch: null, + lastRenderedReducer: null, + lastRenderedState: null + }; + return t.queue = n, t = Ns.bind(null, co, !0, n), n.dispatch = t, [e, t]; + }, + useMemoCache: No, + useCacheRefresh: function() { + return Oo().memoizedState = ks.bind(null, co); + }, + useEffectEvent: function(e) { + var t = Oo(), n = { impl: e }; + return t.memoizedState = n, function() { + if (Bl & 2) throw Error(i(440)); + return n.impl.apply(void 0, arguments); + }; + } + }, zs = { + readContext: Xi, + use: Mo, + useCallback: _s, + useContext: Xi, + useEffect: ls, + useImperativeHandle: hs, + useInsertionEffect: fs, + useLayoutEffect: ps, + useMemo: vs, + useReducer: Fo, + useRef: as, + useState: function() { + return Fo(Po); + }, + useDebugValue: gs, + useDeferredValue: function(e, t) { + return bs(ko(), lo.memoizedState, e, t); + }, + useTransition: function() { + var e = Fo(Po)[0], t = ko().memoizedState; + return [typeof e == "boolean" ? e : jo(e), t]; + }, + useSyncExternalStore: Ro, + useId: Ds, + useHostTransitionStatus: Es, + useFormState: es, + useActionState: es, + useOptimistic: function(e, t) { + return Go(ko(), lo, e, t); + }, + useMemoCache: No, + useCacheRefresh: Os + }; + zs.useEffectEvent = ds; + var Bs = { + readContext: Xi, + use: Mo, + useCallback: _s, + useContext: Xi, + useEffect: ls, + useImperativeHandle: hs, + useInsertionEffect: fs, + useLayoutEffect: ps, + useMemo: vs, + useReducer: Lo, + useRef: as, + useState: function() { + return Lo(Po); + }, + useDebugValue: gs, + useDeferredValue: function(e, t) { + var n = ko(); + return lo === null ? ys(n, e, t) : bs(n, lo.memoizedState, e, t); + }, + useTransition: function() { + var e = Lo(Po)[0], t = ko().memoizedState; + return [typeof e == "boolean" ? e : jo(e), t]; + }, + useSyncExternalStore: Ro, + useId: Ds, + useHostTransitionStatus: Es, + useFormState: rs, + useActionState: rs, + useOptimistic: function(e, t) { + var n = ko(); + return lo === null ? (n.baseState = e, [e, n.queue.dispatch]) : Go(n, lo, e, t); + }, + useMemoCache: No, + useCacheRefresh: Os + }; + Bs.useEffectEvent = ds; + function Vs(e, t, n, r) { + t = e.memoizedState, n = n(r, t), n = n == null ? t : m({}, t, n), e.memoizedState = n, e.lanes === 0 && (e.updateQueue.baseState = n); + } + var Hs = { + enqueueSetState: function(e, t, n) { + e = e._reactInternals; + var r = yu(), i = Ra(r); + i.payload = t, n != null && (i.callback = n), t = za(e, i, r), t !== null && (xu(t, e, r), Ba(t, e, r)); + }, + enqueueReplaceState: function(e, t, n) { + e = e._reactInternals; + var r = yu(), i = Ra(r); + i.tag = 1, i.payload = t, n != null && (i.callback = n), t = za(e, i, r), t !== null && (xu(t, e, r), Ba(t, e, r)); + }, + enqueueForceUpdate: function(e, t) { + e = e._reactInternals; + var n = yu(), r = Ra(n); + r.tag = 2, t != null && (r.callback = t), t = za(e, r, n), t !== null && (xu(t, e, n), Ba(t, e, n)); + } + }; + function Us(e, t, n, r, i, a, o) { + return e = e.stateNode, typeof e.shouldComponentUpdate == "function" ? e.shouldComponentUpdate(r, a, o) : t.prototype && t.prototype.isPureReactComponent ? !vr(n, r) || !vr(i, a) : !0; + } + function Ws(e, t, n, r) { + e = t.state, typeof t.componentWillReceiveProps == "function" && t.componentWillReceiveProps(n, r), typeof t.UNSAFE_componentWillReceiveProps == "function" && t.UNSAFE_componentWillReceiveProps(n, r), t.state !== e && Hs.enqueueReplaceState(t, t.state, null); + } + function Gs(e, t) { + var n = t; + if ("ref" in t) for (var r in n = {}, t) r !== "ref" && (n[r] = t[r]); + if (e = e.defaultProps) for (var i in n === t && (n = m({}, n)), e) n[i] === void 0 && (n[i] = e[i]); + return n; + } + function Ks(e) { + Gr(e); + } + function qs(e) { + console.error(e); + } + function Js(e) { + Gr(e); + } + function Ys(e, t) { + try { + var n = e.onUncaughtError; + n(t.value, { componentStack: t.stack }); + } catch (e) { + setTimeout(function() { + throw e; + }); + } + } + function Xs(e, t, n) { + try { + var r = e.onCaughtError; + r(n.value, { + componentStack: n.stack, + errorBoundary: t.tag === 1 ? t.stateNode : null + }); + } catch (e) { + setTimeout(function() { + throw e; + }); + } + } + function Zs(e, t, n) { + return n = Ra(n), n.tag = 3, n.payload = { element: null }, n.callback = function() { + Ys(e, t); + }, n; + } + function Qs(e) { + return e = Ra(e), e.tag = 3, e; + } + function $s(e, t, n, r) { + var i = n.type.getDerivedStateFromError; + if (typeof i == "function") { + var a = r.value; + e.payload = function() { + return i(a); + }, e.callback = function() { + Xs(t, n, r); + }; + } + var o = n.stateNode; + o !== null && typeof o.componentDidCatch == "function" && (e.callback = function() { + Xs(t, n, r), typeof i != "function" && (lu === null ? lu = /* @__PURE__ */ new Set([this]) : lu.add(this)); + var e = r.stack; + this.componentDidCatch(r.value, { componentStack: e === null ? "" : e }); + }); + } + function ec(e, t, n, r, a) { + if (n.flags |= 32768, typeof r == "object" && r && typeof r.then == "function") { + if (t = n.alternate, t !== null && qi(t, n, a, !0), n = Qa.current, n !== null) { + switch (n.tag) { + case 31: + case 13: return $a === null ? Nu() : n.alternate === null && Xl === 0 && (Xl = 3), n.flags &= -257, n.flags |= 65536, n.lanes = a, r === ba ? n.flags |= 16384 : (t = n.updateQueue, t === null ? n.updateQueue = /* @__PURE__ */ new Set([r]) : t.add(r), Qu(e, r, a)), !1; + case 22: return n.flags |= 65536, r === ba ? n.flags |= 16384 : (t = n.updateQueue, t === null ? (t = { + transitions: null, + markerInstances: null, + retryQueue: /* @__PURE__ */ new Set([r]) + }, n.updateQueue = t) : (n = t.retryQueue, n === null ? t.retryQueue = /* @__PURE__ */ new Set([r]) : n.add(r)), Qu(e, r, a)), !1; + } + throw Error(i(435, n.tag)); + } + return Qu(e, r, a), Nu(), !1; + } + if (ki) return t = Qa.current, t === null ? (r !== Mi && (t = Error(i(423), { cause: r }), zi(pi(t, n))), e = e.current.alternate, e.flags |= 65536, a &= -a, e.lanes |= a, r = pi(r, n), a = Zs(e.stateNode, r, a), Va(e, a), Xl !== 4 && (Xl = 2)) : (!(t.flags & 65536) && (t.flags |= 256), t.flags |= 65536, t.lanes = a, r !== Mi && (e = Error(i(422), { cause: r }), zi(pi(e, n)))), !1; + var o = Error(i(520), { cause: r }); + if (o = pi(o, n), nu === null ? nu = [o] : nu.push(o), Xl !== 4 && (Xl = 2), t === null) return !0; + r = pi(r, n), n = t; + do { + switch (n.tag) { + case 3: return n.flags |= 65536, e = a & -a, n.lanes |= e, e = Zs(n.stateNode, r, e), Va(n, e), !1; + case 1: if (t = n.type, o = n.stateNode, !(n.flags & 128) && (typeof t.getDerivedStateFromError == "function" || o !== null && typeof o.componentDidCatch == "function" && (lu === null || !lu.has(o)))) return n.flags |= 65536, a &= -a, n.lanes |= a, a = Qs(a), $s(a, e, n, r), Va(n, a), !1; + } + n = n.return; + } while (n !== null); + return !1; + } + var tc = Error(i(461)), nc = !1; + function rc(e, t, n, r) { + t.child = e === null ? Pa(t, null, n, r) : Na(t, e.child, n, r); + } + function ic(e, t, n, r, i) { + n = n.render; + var a = t.ref; + if ("ref" in r) { + var o = {}; + for (var s in r) s !== "ref" && (o[s] = r[s]); + } else o = r; + return Yi(t), r = xo(e, t, n, o, a, i), s = To(), e !== null && !nc ? (Eo(e, t, i), Oc(e, t, i)) : (ki && s && wi(t), t.flags |= 1, rc(e, t, r, i), t.child); + } + function ac(e, t, n, r, i) { + if (e === null) { + var a = n.type; + return typeof a == "function" && !ii(a) && a.defaultProps === void 0 && n.compare === null ? (t.tag = 15, t.type = a, oc(e, t, a, r, i)) : (e = si(n.type, null, r, t, t.mode, i), e.ref = t.ref, e.return = t, t.child = e); + } + if (a = e.child, !kc(e, i)) { + var o = a.memoizedProps; + if (n = n.compare, n = n === null ? vr : n, n(o, r) && e.ref === t.ref) return Oc(e, t, i); + } + return t.flags |= 1, e = ai(a, r), e.ref = t.ref, e.return = t, t.child = e; + } + function oc(e, t, n, r, i) { + if (e !== null) { + var a = e.memoizedProps; + if (vr(a, r) && e.ref === t.ref) { + if (nc = !1, t.pendingProps = r = a, kc(e, i)) e.flags & 131072 && (nc = !0); + else return t.lanes = e.lanes, Oc(e, t, i); + } + } + return mc(e, t, n, r, i); + } + function sc(e, t, n, r) { + var i = r.children, a = e === null ? null : e.memoizedState; + if (e === null && t.stateNode === null && (t.stateNode = { + _visibility: 1, + _pendingMarkers: null, + _retryCache: null, + _transitions: null + }), r.mode === "hidden") { + if (t.flags & 128) { + if (a = a === null ? n : a.baseLanes | n, e !== null) { + for (r = t.child = e.child, i = 0; r !== null;) i = i | r.lanes | r.childLanes, r = r.sibling; + r = i & ~a; + } else r = 0, t.child = null; + return lc(e, t, a, n, r); + } + if (n & 536870912) t.memoizedState = { + baseLanes: 0, + cachePool: null + }, e !== null && ha(t, a === null ? null : a.cachePool), a === null ? Xa() : Ya(t, a), no(t); + else return r = t.lanes = 536870912, lc(e, t, a === null ? n : a.baseLanes | n, n, r); + } else a === null ? (e !== null && ha(t, null), Xa(), ro(t)) : (ha(t, a.cachePool), Ya(t, a), ro(t), t.memoizedState = null); + return rc(e, t, i, n), t.child; + } + function cc(e, t) { + return e !== null && e.tag === 22 || t.stateNode !== null || (t.stateNode = { + _visibility: 1, + _pendingMarkers: null, + _retryCache: null, + _transitions: null + }), t.sibling; + } + function lc(e, t, n, r, i) { + var a = ma(); + return a = a === null ? null : { + parent: na._currentValue, + pool: a + }, t.memoizedState = { + baseLanes: n, + cachePool: a + }, e !== null && ha(t, null), Xa(), no(t), e !== null && qi(e, t, r, !0), t.childLanes = i, null; + } + function uc(e, t) { + return t = Cc({ + mode: t.mode, + children: t.children + }, e.mode), t.ref = e.ref, e.child = t, t.return = e, t; + } + function dc(e, t, n) { + return Na(t, e.child, null, n), e = uc(t, t.pendingProps), e.flags |= 2, io(t), t.memoizedState = null, e; + } + function fc(e, t, n) { + var r = t.pendingProps, a = !!(t.flags & 128); + if (t.flags &= -129, e === null) { + if (ki) { + if (r.mode === "hidden") return e = uc(t, r), t.lanes = 536870912, cc(null, e); + if (to(t), (e = Oi) ? (e = ff(e, ji), e = e !== null && e.data === "&" ? e : null, e !== null && (t.memoizedState = { + dehydrated: e, + treeContext: bi === null ? null : { + id: W, + overflow: xi + }, + retryLane: 536870912, + hydrationErrors: null + }, n = ui(e), n.return = t, t.child = n, Di = t, Oi = null)) : e = null, e === null) throw Ni(t); + return t.lanes = 536870912, null; + } + return uc(t, r); + } + var o = e.memoizedState; + if (o !== null) { + var s = o.dehydrated; + if (to(t), a) { + if (t.flags & 256) t.flags &= -257, t = dc(e, t, n); + else if (t.memoizedState !== null) t.child = e.child, t.flags |= 128, t = null; + else throw Error(i(558)); + } else if (nc || qi(e, t, n, !1), a = (n & e.childLanes) !== 0, nc || a) { + if (r = Vl, r !== null && (s = Ye(r, n), s !== 0 && s !== o.retryLane)) throw o.retryLane = s, Qr(e, s), xu(r, e, s), tc; + Nu(), t = dc(e, t, n); + } else e = o.treeContext, Oi = gf(s.nextSibling), Di = t, ki = !0, Ai = null, ji = !1, e !== null && Ei(t, e), t = uc(t, r), t.flags |= 4096; + return t; + } + return e = ai(e.child, { + mode: r.mode, + children: r.children + }), e.ref = t.ref, t.child = e, e.return = t, e; + } + function pc(e, t) { + var n = t.ref; + if (n === null) e !== null && e.ref !== null && (t.flags |= 4194816); + else { + if (typeof n != "function" && typeof n != "object") throw Error(i(284)); + (e === null || e.ref !== n) && (t.flags |= 4194816); + } + } + function mc(e, t, n, r, i) { + return Yi(t), n = xo(e, t, n, r, void 0, i), r = To(), e !== null && !nc ? (Eo(e, t, i), Oc(e, t, i)) : (ki && r && wi(t), t.flags |= 1, rc(e, t, n, i), t.child); + } + function hc(e, t, n, r, i, a) { + return Yi(t), t.updateQueue = null, n = Co(t, r, n, i), So(e), r = To(), e !== null && !nc ? (Eo(e, t, a), Oc(e, t, a)) : (ki && r && wi(t), t.flags |= 1, rc(e, t, n, a), t.child); + } + function gc(e, t, n, r, i) { + if (Yi(t), t.stateNode === null) { + var a = ti, o = n.contextType; + typeof o == "object" && o && (a = Xi(o)), a = new n(r, a), t.memoizedState = a.state !== null && a.state !== void 0 ? a.state : null, a.updater = Hs, t.stateNode = a, a._reactInternals = t, a = t.stateNode, a.props = r, a.state = t.memoizedState, a.refs = {}, Ia(t), o = n.contextType, a.context = typeof o == "object" && o ? Xi(o) : ti, a.state = t.memoizedState, o = n.getDerivedStateFromProps, typeof o == "function" && (Vs(t, n, o, r), a.state = t.memoizedState), typeof n.getDerivedStateFromProps == "function" || typeof a.getSnapshotBeforeUpdate == "function" || typeof a.UNSAFE_componentWillMount != "function" && typeof a.componentWillMount != "function" || (o = a.state, typeof a.componentWillMount == "function" && a.componentWillMount(), typeof a.UNSAFE_componentWillMount == "function" && a.UNSAFE_componentWillMount(), o !== a.state && Hs.enqueueReplaceState(a, a.state, null), Wa(t, r, a, i), Ua(), a.state = t.memoizedState), typeof a.componentDidMount == "function" && (t.flags |= 4194308), r = !0; + } else if (e === null) { + a = t.stateNode; + var s = t.memoizedProps, c = Gs(n, s); + a.props = c; + var l = a.context, u = n.contextType; + o = ti, typeof u == "object" && u && (o = Xi(u)); + var d = n.getDerivedStateFromProps; + u = typeof d == "function" || typeof a.getSnapshotBeforeUpdate == "function", s = t.pendingProps !== s, u || typeof a.UNSAFE_componentWillReceiveProps != "function" && typeof a.componentWillReceiveProps != "function" || (s || l !== o) && Ws(t, a, r, o), Fa = !1; + var f = t.memoizedState; + a.state = f, Wa(t, r, a, i), Ua(), l = t.memoizedState, s || f !== l || Fa ? (typeof d == "function" && (Vs(t, n, d, r), l = t.memoizedState), (c = Fa || Us(t, n, c, r, f, l, o)) ? (u || typeof a.UNSAFE_componentWillMount != "function" && typeof a.componentWillMount != "function" || (typeof a.componentWillMount == "function" && a.componentWillMount(), typeof a.UNSAFE_componentWillMount == "function" && a.UNSAFE_componentWillMount()), typeof a.componentDidMount == "function" && (t.flags |= 4194308)) : (typeof a.componentDidMount == "function" && (t.flags |= 4194308), t.memoizedProps = r, t.memoizedState = l), a.props = r, a.state = l, a.context = o, r = c) : (typeof a.componentDidMount == "function" && (t.flags |= 4194308), r = !1); + } else { + a = t.stateNode, La(e, t), o = t.memoizedProps, u = Gs(n, o), a.props = u, d = t.pendingProps, f = a.context, l = n.contextType, c = ti, typeof l == "object" && l && (c = Xi(l)), s = n.getDerivedStateFromProps, (l = typeof s == "function" || typeof a.getSnapshotBeforeUpdate == "function") || typeof a.UNSAFE_componentWillReceiveProps != "function" && typeof a.componentWillReceiveProps != "function" || (o !== d || f !== c) && Ws(t, a, r, c), Fa = !1, f = t.memoizedState, a.state = f, Wa(t, r, a, i), Ua(); + var p = t.memoizedState; + o !== d || f !== p || Fa || e !== null && e.dependencies !== null && Ji(e.dependencies) ? (typeof s == "function" && (Vs(t, n, s, r), p = t.memoizedState), (u = Fa || Us(t, n, u, r, f, p, c) || e !== null && e.dependencies !== null && Ji(e.dependencies)) ? (l || typeof a.UNSAFE_componentWillUpdate != "function" && typeof a.componentWillUpdate != "function" || (typeof a.componentWillUpdate == "function" && a.componentWillUpdate(r, p, c), typeof a.UNSAFE_componentWillUpdate == "function" && a.UNSAFE_componentWillUpdate(r, p, c)), typeof a.componentDidUpdate == "function" && (t.flags |= 4), typeof a.getSnapshotBeforeUpdate == "function" && (t.flags |= 1024)) : (typeof a.componentDidUpdate != "function" || o === e.memoizedProps && f === e.memoizedState || (t.flags |= 4), typeof a.getSnapshotBeforeUpdate != "function" || o === e.memoizedProps && f === e.memoizedState || (t.flags |= 1024), t.memoizedProps = r, t.memoizedState = p), a.props = r, a.state = p, a.context = c, r = u) : (typeof a.componentDidUpdate != "function" || o === e.memoizedProps && f === e.memoizedState || (t.flags |= 4), typeof a.getSnapshotBeforeUpdate != "function" || o === e.memoizedProps && f === e.memoizedState || (t.flags |= 1024), r = !1); + } + return a = r, pc(e, t), r = !!(t.flags & 128), a || r ? (a = t.stateNode, n = r && typeof n.getDerivedStateFromError != "function" ? null : a.render(), t.flags |= 1, e !== null && r ? (t.child = Na(t, e.child, null, i), t.child = Na(t, null, n, i)) : rc(e, t, n, i), t.memoizedState = a.state, e = t.child) : e = Oc(e, t, i), e; + } + function _c(e, t, n, r) { + return Li(), t.flags |= 256, rc(e, t, n, r), t.child; + } + var vc = { + dehydrated: null, + treeContext: null, + retryLane: 0, + hydrationErrors: null + }; + function yc(e) { + return { + baseLanes: e, + cachePool: ga() + }; + } + function bc(e, t, n) { + return e = e === null ? 0 : e.childLanes & ~n, t && (e |= eu), e; + } + function xc(e, t, n) { + var r = t.pendingProps, a = !1, o = !!(t.flags & 128), s; + if ((s = o) || (s = e !== null && e.memoizedState === null ? !1 : !!(ao.current & 2)), s && (a = !0, t.flags &= -129), s = !!(t.flags & 32), t.flags &= -33, e === null) { + if (ki) { + if (a ? eo(t) : ro(t), (e = Oi) ? (e = ff(e, ji), e = e !== null && e.data !== "&" ? e : null, e !== null && (t.memoizedState = { + dehydrated: e, + treeContext: bi === null ? null : { + id: W, + overflow: xi + }, + retryLane: 536870912, + hydrationErrors: null + }, n = ui(e), n.return = t, t.child = n, Di = t, Oi = null)) : e = null, e === null) throw Ni(t); + return mf(e) ? t.lanes = 32 : t.lanes = 536870912, null; + } + var c = r.children; + return r = r.fallback, a ? (ro(t), a = t.mode, c = Cc({ + mode: "hidden", + children: c + }, a), r = ci(r, a, n, null), c.return = t, r.return = t, c.sibling = r, t.child = c, r = t.child, r.memoizedState = yc(n), r.childLanes = bc(e, s, n), t.memoizedState = vc, cc(null, r)) : (eo(t), Sc(t, c)); + } + var l = e.memoizedState; + if (l !== null && (c = l.dehydrated, c !== null)) { + if (o) t.flags & 256 ? (eo(t), t.flags &= -257, t = wc(e, t, n)) : t.memoizedState === null ? (ro(t), c = r.fallback, a = t.mode, r = Cc({ + mode: "visible", + children: r.children + }, a), c = ci(c, a, n, null), c.flags |= 2, r.return = t, c.return = t, r.sibling = c, t.child = r, Na(t, e.child, null, n), r = t.child, r.memoizedState = yc(n), r.childLanes = bc(e, s, n), t.memoizedState = vc, t = cc(null, r)) : (ro(t), t.child = e.child, t.flags |= 128, t = null); + else if (eo(t), mf(c)) { + if (s = c.nextSibling && c.nextSibling.dataset, s) var u = s.dgst; + s = u, r = Error(i(419)), r.stack = "", r.digest = s, zi({ + value: r, + source: null, + stack: null + }), t = wc(e, t, n); + } else if (nc || qi(e, t, n, !1), s = (n & e.childLanes) !== 0, nc || s) { + if (s = Vl, s !== null && (r = Ye(s, n), r !== 0 && r !== l.retryLane)) throw l.retryLane = r, Qr(e, r), xu(s, e, r), tc; + pf(c) || Nu(), t = wc(e, t, n); + } else pf(c) ? (t.flags |= 192, t.child = e.child, t = null) : (e = l.treeContext, Oi = gf(c.nextSibling), Di = t, ki = !0, Ai = null, ji = !1, e !== null && Ei(t, e), t = Sc(t, r.children), t.flags |= 4096); + return t; + } + return a ? (ro(t), c = r.fallback, a = t.mode, l = e.child, u = l.sibling, r = ai(l, { + mode: "hidden", + children: r.children + }), r.subtreeFlags = l.subtreeFlags & 65011712, u === null ? (c = ci(c, a, n, null), c.flags |= 2) : c = ai(u, c), c.return = t, r.return = t, r.sibling = c, t.child = r, cc(null, r), r = t.child, c = e.child.memoizedState, c === null ? c = yc(n) : (a = c.cachePool, a === null ? a = ga() : (l = na._currentValue, a = a.parent === l ? a : { + parent: l, + pool: l + }), c = { + baseLanes: c.baseLanes | n, + cachePool: a + }), r.memoizedState = c, r.childLanes = bc(e, s, n), t.memoizedState = vc, cc(e.child, r)) : (eo(t), n = e.child, e = n.sibling, n = ai(n, { + mode: "visible", + children: r.children + }), n.return = t, n.sibling = null, e !== null && (s = t.deletions, s === null ? (t.deletions = [e], t.flags |= 16) : s.push(e)), t.child = n, t.memoizedState = null, n); + } + function Sc(e, t) { + return t = Cc({ + mode: "visible", + children: t + }, e.mode), t.return = e, e.child = t; + } + function Cc(e, t) { + return e = ri(22, e, null, t), e.lanes = 0, e; + } + function wc(e, t, n) { + return Na(t, e.child, null, n), e = Sc(t, t.pendingProps.children), e.flags |= 2, t.memoizedState = null, e; + } + function Tc(e, t, n) { + e.lanes |= t; + var r = e.alternate; + r !== null && (r.lanes |= t), Gi(e.return, t, n); + } + function Ec(e, t, n, r, i, a) { + var o = e.memoizedState; + o === null ? e.memoizedState = { + isBackwards: t, + rendering: null, + renderingStartTime: 0, + last: r, + tail: n, + tailMode: i, + treeForkCount: a + } : (o.isBackwards = t, o.rendering = null, o.renderingStartTime = 0, o.last = r, o.tail = n, o.tailMode = i, o.treeForkCount = a); + } + function Dc(e, t, n) { + var r = t.pendingProps, i = r.revealOrder, a = r.tail; + r = r.children; + var o = ao.current, s = !!(o & 2); + if (s ? (o = o & 1 | 2, t.flags |= 128) : o &= 1, A(ao, o), rc(e, t, r, n), r = ki ? _i : 0, !s && e !== null && e.flags & 128) a: for (e = t.child; e !== null;) { + if (e.tag === 13) e.memoizedState !== null && Tc(e, n, t); + else if (e.tag === 19) Tc(e, n, t); + else if (e.child !== null) { + e.child.return = e, e = e.child; + continue; + } + if (e === t) break a; + for (; e.sibling === null;) { + if (e.return === null || e.return === t) break a; + e = e.return; + } + e.sibling.return = e.return, e = e.sibling; + } + switch (i) { + case "forwards": + for (n = t.child, i = null; n !== null;) e = n.alternate, e !== null && oo(e) === null && (i = n), n = n.sibling; + n = i, n === null ? (i = t.child, t.child = null) : (i = n.sibling, n.sibling = null), Ec(t, !1, i, n, a, r); + break; + case "backwards": + case "unstable_legacy-backwards": + for (n = null, i = t.child, t.child = null; i !== null;) { + if (e = i.alternate, e !== null && oo(e) === null) { + t.child = i; + break; + } + e = i.sibling, i.sibling = n, n = i, i = e; + } + Ec(t, !0, n, null, a, r); + break; + case "together": + Ec(t, !1, null, null, void 0, r); + break; + default: t.memoizedState = null; + } + return t.child; + } + function Oc(e, t, n) { + if (e !== null && (t.dependencies = e.dependencies), Zl |= t.lanes, (n & t.childLanes) === 0) { + if (e !== null) { + if (qi(e, t, n, !1), (n & t.childLanes) === 0) return null; + } else return null; + } + if (e !== null && t.child !== e.child) throw Error(i(153)); + if (t.child !== null) { + for (e = t.child, n = ai(e, e.pendingProps), t.child = n, n.return = t; e.sibling !== null;) e = e.sibling, n = n.sibling = ai(e, e.pendingProps), n.return = t; + n.sibling = null; + } + return t.child; + } + function kc(e, t) { + return (e.lanes & t) !== 0 || (e = e.dependencies, !!(e !== null && Ji(e))); + } + function Ac(e, t, n) { + switch (t.tag) { + case 3: + me(t, t.stateNode.containerInfo), Ui(t, na, e.memoizedState.cache), Li(); + break; + case 27: + case 5: + P(t); + break; + case 4: + me(t, t.stateNode.containerInfo); + break; + case 10: + Ui(t, t.type, t.memoizedProps.value); + break; + case 31: + if (t.memoizedState !== null) return t.flags |= 128, to(t), null; + break; + case 13: + var r = t.memoizedState; + if (r !== null) return r.dehydrated === null ? (n & t.child.childLanes) === 0 ? (eo(t), e = Oc(e, t, n), e === null ? null : e.sibling) : xc(e, t, n) : (eo(t), t.flags |= 128, null); + eo(t); + break; + case 19: + var i = !!(e.flags & 128); + if (r = (n & t.childLanes) !== 0, r ||= (qi(e, t, n, !1), (n & t.childLanes) !== 0), i) { + if (r) return Dc(e, t, n); + t.flags |= 128; + } + if (i = t.memoizedState, i !== null && (i.rendering = null, i.tail = null, i.lastEffect = null), A(ao, ao.current), r) break; + return null; + case 22: return t.lanes = 0, sc(e, t, n, t.pendingProps); + case 24: Ui(t, na, e.memoizedState.cache); + } + return Oc(e, t, n); + } + function jc(e, t, n) { + if (e !== null) { + if (e.memoizedProps !== t.pendingProps) nc = !0; + else { + if (!kc(e, n) && !(t.flags & 128)) return nc = !1, Ac(e, t, n); + nc = !!(e.flags & 131072); + } + } else nc = !1, ki && t.flags & 1048576 && Ci(t, _i, t.index); + switch (t.lanes = 0, t.tag) { + case 16: + a: { + var r = t.pendingProps; + if (e = Ca(t.elementType), t.type = e, typeof e == "function") ii(e) ? (r = Gs(e, r), t.tag = 1, t = gc(null, t, e, r, n)) : (t.tag = 0, t = mc(null, t, e, r, n)); + else { + if (e != null) { + var a = e.$$typeof; + if (a === w) { + t.tag = 11, t = ic(null, t, e, r, n); + break a; + } + if (a === ee) { + t.tag = 14, t = ac(null, t, e, r, n); + break a; + } + } + throw t = oe(e) || e, Error(i(306, t, "")); + } + } + return t; + case 0: return mc(e, t, t.type, t.pendingProps, n); + case 1: return r = t.type, a = Gs(r, t.pendingProps), gc(e, t, r, a, n); + case 3: + a: { + if (me(t, t.stateNode.containerInfo), e === null) throw Error(i(387)); + r = t.pendingProps; + var o = t.memoizedState; + a = o.element, La(e, t), Wa(t, r, null, n); + var s = t.memoizedState; + if (r = s.cache, Ui(t, na, r), r !== o.cache && Ki(t, [na], n, !0), Ua(), r = s.element, o.isDehydrated) { + if (o = { + element: r, + isDehydrated: !1, + cache: s.cache + }, t.updateQueue.baseState = o, t.memoizedState = o, t.flags & 256) { + t = _c(e, t, r, n); + break a; + } + if (r !== a) { + a = pi(Error(i(424)), t), zi(a), t = _c(e, t, r, n); + break a; + } + switch (e = t.stateNode.containerInfo, e.nodeType) { + case 9: + e = e.body; + break; + default: e = e.nodeName === "HTML" ? e.ownerDocument.body : e; + } + for (Oi = gf(e.firstChild), Di = t, ki = !0, Ai = null, ji = !0, n = Pa(t, null, r, n), t.child = n; n;) n.flags = n.flags & -3 | 4096, n = n.sibling; + } else { + if (Li(), r === a) { + t = Oc(e, t, n); + break a; + } + rc(e, t, r, n); + } + t = t.child; + } + return t; + case 26: return pc(e, t), e === null ? (n = Lf(t.type, null, t.pendingProps, null)) ? t.memoizedState = n : ki || (n = t.type, e = t.pendingProps, r = Jd(pe.current).createElement(n), r[tt] = t, r[nt] = e, Hd(r, n, e), mt(r), t.stateNode = r) : t.memoizedState = Lf(t.type, e.memoizedProps, t.pendingProps, e.memoizedState), null; + case 27: return P(t), e === null && ki && (r = t.stateNode = bf(t.type, t.pendingProps, pe.current), Di = t, ji = !0, a = Oi, of(t.type) ? (_f = a, Oi = gf(r.firstChild)) : Oi = a), rc(e, t, t.pendingProps.children, n), pc(e, t), e === null && (t.flags |= 4194304), t.child; + case 5: return e === null && ki && ((a = r = Oi) && (r = uf(r, t.type, t.pendingProps, ji), r === null ? a = !1 : (t.stateNode = r, Di = t, Oi = gf(r.firstChild), ji = !1, a = !0)), a || Ni(t)), P(t), a = t.type, o = t.pendingProps, s = e === null ? null : e.memoizedProps, r = o.children, Zd(a, o) ? r = null : s !== null && Zd(a, s) && (t.flags |= 32), t.memoizedState !== null && (a = xo(e, t, wo, null, null, n), op._currentValue = a), pc(e, t), rc(e, t, r, n), t.child; + case 6: return e === null && ki && ((e = n = Oi) && (n = df(n, t.pendingProps, ji), n === null ? e = !1 : (t.stateNode = n, Di = t, Oi = null, e = !0)), e || Ni(t)), null; + case 13: return xc(e, t, n); + case 4: return me(t, t.stateNode.containerInfo), r = t.pendingProps, e === null ? t.child = Na(t, null, r, n) : rc(e, t, r, n), t.child; + case 11: return ic(e, t, t.type, t.pendingProps, n); + case 7: return rc(e, t, t.pendingProps, n), t.child; + case 8: return rc(e, t, t.pendingProps.children, n), t.child; + case 12: return rc(e, t, t.pendingProps.children, n), t.child; + case 10: return r = t.pendingProps, Ui(t, t.type, r.value), rc(e, t, r.children, n), t.child; + case 9: return a = t.type._context, r = t.pendingProps.children, Yi(t), a = Xi(a), r = r(a), t.flags |= 1, rc(e, t, r, n), t.child; + case 14: return ac(e, t, t.type, t.pendingProps, n); + case 15: return oc(e, t, t.type, t.pendingProps, n); + case 19: return Dc(e, t, n); + case 31: return fc(e, t, n); + case 22: return sc(e, t, n, t.pendingProps); + case 24: return Yi(t), r = Xi(na), e === null ? (a = ma(), a === null && (a = Vl, o = ra(), a.pooledCache = o, o.refCount++, o !== null && (a.pooledCacheLanes |= n), a = o), t.memoizedState = { + parent: r, + cache: a + }, Ia(t), Ui(t, na, a)) : ((e.lanes & n) !== 0 && (La(e, t), Wa(t, null, null, n), Ua()), a = e.memoizedState, o = t.memoizedState, a.parent === r ? (r = o.cache, Ui(t, na, r), r !== a.cache && Ki(t, [na], n, !0)) : (a = { + parent: r, + cache: r + }, t.memoizedState = a, t.lanes === 0 && (t.memoizedState = t.updateQueue.baseState = a), Ui(t, na, r))), rc(e, t, t.pendingProps.children, n), t.child; + case 29: throw t.pendingProps; + } + throw Error(i(156, t.tag)); + } + function Mc(e) { + e.flags |= 4; + } + function Nc(e, t, n, r, i) { + if ((t = !!(e.mode & 32)) && (t = !1), t) { + if (e.flags |= 16777216, (i & 335544128) === i) { + if (e.stateNode.complete) e.flags |= 8192; + else if (Au()) e.flags |= 8192; + else throw wa = ba, va; + } + } else e.flags &= -16777217; + } + function Pc(e, t) { + if (t.type !== "stylesheet" || t.state.loading & 4) e.flags &= -16777217; + else if (e.flags |= 16777216, !Qf(t)) { + if (Au()) e.flags |= 8192; + else throw wa = ba, va; + } + } + function Fc(e, t) { + t !== null && (e.flags |= 4), e.flags & 16384 && (t = e.tag === 22 ? 536870912 : U(), e.lanes |= t, tu |= t); + } + function Ic(e, t) { + if (!ki) switch (e.tailMode) { + case "hidden": + t = e.tail; + for (var n = null; t !== null;) t.alternate !== null && (n = t), t = t.sibling; + n === null ? e.tail = null : n.sibling = null; + break; + case "collapsed": + n = e.tail; + for (var r = null; n !== null;) n.alternate !== null && (r = n), n = n.sibling; + r === null ? t || e.tail === null ? e.tail = null : e.tail.sibling = null : r.sibling = null; + } + } + function Lc(e) { + var t = e.alternate !== null && e.alternate.child === e.child, n = 0, r = 0; + if (t) for (var i = e.child; i !== null;) n |= i.lanes | i.childLanes, r |= i.subtreeFlags & 65011712, r |= i.flags & 65011712, i.return = e, i = i.sibling; + else for (i = e.child; i !== null;) n |= i.lanes | i.childLanes, r |= i.subtreeFlags, r |= i.flags, i.return = e, i = i.sibling; + return e.subtreeFlags |= r, e.childLanes = n, t; + } + function Rc(e, t, n) { + var r = t.pendingProps; + switch (Ti(t), t.tag) { + case 16: + case 15: + case 0: + case 11: + case 7: + case 8: + case 12: + case 9: + case 14: return Lc(t), null; + case 1: return Lc(t), null; + case 3: return n = t.stateNode, r = null, e !== null && (r = e.memoizedState.cache), t.memoizedState.cache !== r && (t.flags |= 2048), Wi(na), he(), n.pendingContext && (n.context = n.pendingContext, n.pendingContext = null), (e === null || e.child === null) && (Ii(t) ? Mc(t) : e === null || e.memoizedState.isDehydrated && !(t.flags & 256) || (t.flags |= 1024, Ri())), Lc(t), null; + case 26: + var a = t.type, o = t.memoizedState; + return e === null ? (Mc(t), o === null ? (Lc(t), Nc(t, a, null, r, n)) : (Lc(t), Pc(t, o))) : o ? o === e.memoizedState ? (Lc(t), t.flags &= -16777217) : (Mc(t), Lc(t), Pc(t, o)) : (e = e.memoizedProps, e !== r && Mc(t), Lc(t), Nc(t, a, e, r, n)), null; + case 27: + if (F(t), n = pe.current, a = t.type, e !== null && t.stateNode != null) e.memoizedProps !== r && Mc(t); + else { + if (!r) { + if (t.stateNode === null) throw Error(i(166)); + return Lc(t), null; + } + e = j.current, Ii(t) ? Pi(t, e) : (e = bf(a, r, n), t.stateNode = e, Mc(t)); + } + return Lc(t), null; + case 5: + if (F(t), a = t.type, e !== null && t.stateNode != null) e.memoizedProps !== r && Mc(t); + else { + if (!r) { + if (t.stateNode === null) throw Error(i(166)); + return Lc(t), null; + } + if (o = j.current, Ii(t)) Pi(t, o); + else { + var s = Jd(pe.current); + switch (o) { + case 1: + o = s.createElementNS("http://www.w3.org/2000/svg", a); + break; + case 2: + o = s.createElementNS("http://www.w3.org/1998/Math/MathML", a); + break; + default: switch (a) { + case "svg": + o = s.createElementNS("http://www.w3.org/2000/svg", a); + break; + case "math": + o = s.createElementNS("http://www.w3.org/1998/Math/MathML", a); + break; + case "script": + o = s.createElement("div"), o.innerHTML = "