diff --git a/automation/Common.php b/automation/Common.php index 6ea7c5e..fc84b53 100644 --- a/automation/Common.php +++ b/automation/Common.php @@ -89,13 +89,13 @@ $this -> add_sync_connection([ ["type" => "relay", "alias" => "fisrt_floor_big_relay", "channel" => 0], - ["type" => "button", "alias" => "kitchen_buttons_1", "channel" => 0], + ["type" => "button", "alias" => "kitchen_buttons_11", "channel" => 0], ["type" => "button", "alias" => "kitchen_buttons_2", "channel" => 0], ]); $this -> add_sync_connection([ ["type" => "relay", "alias" => "fisrt_floor_big_relay", "channel" => 1], - ["type" => "button", "alias" => "kitchen_buttons_1", "channel" => 1], + ["type" => "button", "alias" => "kitchen_buttons_11", "channel" => 1], ["type" => "button", "alias" => "kitchen_buttons_2", "channel" => 1], ]); diff --git a/automation/ModesRegistry.php b/automation/ModesRegistry.php new file mode 100644 index 0000000..0f35028 --- /dev/null +++ b/automation/ModesRegistry.php @@ -0,0 +1,40 @@ +mode()->is('night'), + * and an action script can flip them via $this->mode()->enable('away'). + * + * Labels and descriptions live here, in code — DB only stores runtime state. + */ +class ModesRegistry { + + public static function definitions(): array { + return [ + 'home' => [ + 'label' => 'Дома', + 'description' => 'Основной режим присутствия. Все системы работают в штатном режиме.', + ], + 'away' => [ + 'label' => 'Не дома', + 'description' => 'Никого нет дома. Активны охранные сценарии и энергосбережение.', + ], + 'night' => [ + 'label' => 'Ночь', + 'description' => 'Пониженная яркость освещения, тихие уведомления, усиленный контроль шума.', + ], + 'sleep' => [ + 'label' => 'Сон', + 'description' => 'Минимум света и звука. Датчики движения переведены в тихий режим.', + ], + 'movie' => [ + 'label' => 'Кино', + 'description' => 'Приглушённый свет в гостиной, отключены звуковые уведомления.', + ], + ]; + } +} diff --git a/automation/scopes-manifest.json b/automation/scopes-manifest.json deleted file mode 100644 index a1493eb..0000000 --- a/automation/scopes-manifest.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "scopes": [ - "LightHubScope", - "OfficeRoomScope", - "SpotlightsScope", - "TestScriptsScope" - ] -} \ No newline at end of file diff --git a/docs/android-capacitor-oauth-template.md b/docs/android-capacitor-oauth-template.md index 5df849c..62f57e0 100644 --- a/docs/android-capacitor-oauth-template.md +++ b/docs/android-capacitor-oauth-template.md @@ -336,42 +336,42 @@ ## 8. Чеклист для следующего проекта ### Capacitor setup -- [ ] `capacitor.config.json` с `"appId": "com.company.app"` — уникальный -- [ ] `androidScheme` не конфликтует с deep link scheme (shserv / https) -- [ ] `CapacitorHttp.enabled: true` если нужен native HTTP -- [ ] `adjustMarginsForEdgeToEdge: "force"` для Android 15+ +- [x] `capacitor.config.json` с `"appId": "com.company.app"` — уникальный +- [x] `androidScheme` не конфликтует с deep link scheme (shserv / https) +- [x] `CapacitorHttp.enabled: true` если нужен native HTTP +- [x] `adjustMarginsForEdgeToEdge: "force"` для Android 15+ ### Deep link (OAuth return) -- [ ] `AndroidManifest.xml` intent-filter для `scheme://host/path` -- [ ] Server bridge page с `intent://` URL -- [ ] Vue `appUrlOpen` listener + `getLaunchUrl()` для cold-start -- [ ] `window.location.reload()` после получения токена (чтобы bootstrap перезапустился) +- [x] `AndroidManifest.xml` intent-filter для `scheme://host/path` +- [x] Server bridge page с `intent://` URL +- [x] Vue `appUrlOpen` listener + `getLaunchUrl()` для cold-start +- [x] `window.location.reload()` после получения токена (чтобы bootstrap перезапустился) ### Desktop vs Native branching -- [ ] `isNativeApp()` через `Capacitor.isNativePlatform()`, НЕ `window.Capacitor` -- [ ] `initAccessToken()` и `initServerUrl()` вызывать **всегда** в bootstrap -- [ ] Storage abstraction (`storage.js`) — единая точка для Preferences/localStorage -- [ ] Navigation abstraction (`navigation.js`) — единая точка для OAuth redirect +- [x] `isNativeApp()` через `Capacitor.isNativePlatform()`, НЕ `window.Capacitor` +- [x] `initAccessToken()` и `initServerUrl()` вызывать **всегда** в bootstrap +- [x] Storage abstraction (`storage.js`) — единая точка для Preferences/localStorage +- [x] Navigation abstraction (`navigation.js`) — единая точка для OAuth redirect ### Онлайн-загрузка SPA (тонкий клиент) -- [ ] `MainActivity.onCreate()` читает `server_url` из Preferences **перед** `super.onCreate()` -- [ ] `CapConfig.Builder(this).setServerUrl(url)` если URL сохранён -- [ ] `/mobile-setup` страница — сохраняет URL и вызывает `App.exitApp()` -- [ ] Bundled `dist/` в APK как fallback для первого запуска +- [x] `MainActivity.onCreate()` читает `server_url` из Preferences **перед** `super.onCreate()` +- [x] `CapConfig.Builder(this).setServerUrl(url)` если URL сохранён +- [x] `/mobile-setup` страница — сохраняет URL и вызывает `App.exitApp()` +- [x] Bundled `dist/` в APK как fallback для первого запуска ### Android visual -- [ ] Custom `MainActivity.java` с `setTheme()` ПЕРЕД `super.onCreate()` -- [ ] Custom `capacitor_bridge_layout_main.xml` с `fitsSystemWindows="true"` -- [ ] Сброс `OnApplyWindowInsetsListener` от SystemBars plugin в `onCreate()` -- [ ] `windowOptOutEdgeToEdgeEnforcement=true` в обоих theme стилях -- [ ] Splash PNG per density в `drawable-land-*dpi/` и `drawable-port-*dpi/` -- [ ] Android 12+ splash API: `drawable-*dpi-v31/ic_splash.png` 288dp canvas -- [ ] `colors.xml` с `bg_dark`, `toolbar_bg`, `accent`, `text_primary` +- [x] Custom `MainActivity.java` с `setTheme()` ПЕРЕД `super.onCreate()` +- [x] Custom `capacitor_bridge_layout_main.xml` с `fitsSystemWindows="true"` +- [x] Сброс `OnApplyWindowInsetsListener` от SystemBars plugin в `onCreate()` +- [x] `windowOptOutEdgeToEdgeEnforcement=true` в обоих theme стилях +- [x] Splash PNG per density в `drawable-land-*dpi/` и `drawable-port-*dpi/` +- [x] Android 12+ splash API: `drawable-*dpi-v31/ic_splash.png` 288dp canvas +- [x] `colors.xml` с `bg_dark`, `toolbar_bg`, `accent`, `text_primary` ### Server (OAuth callback) -- [ ] `returnTo` читать из сессии **ДО** `handleCallback()` — state стирается -- [ ] Bridge page `/auth/mobile-bridge` с `intent://` redirect -- [ ] `sanitizeReturnTo()` разрешает `/auth/mobile-bridge` и same-origin URLs +- [x] `returnTo` читать из сессии **ДО** `handleCallback()` — state стирается +- [x] Bridge page `/auth/mobile-bridge` с `intent://` redirect +- [x] `sanitizeReturnTo()` разрешает `/auth/mobile-bridge` и same-origin URLs --- diff --git a/docs/architecture.md b/docs/architecture.md index 74e947d..e490e59 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -4,15 +4,17 @@ **Ни веб-клиент, ни сами умные устройства не имеют права напрямую управлять другими устройствами через внешний REST API.** -Всё управление устройствами — только через скрипты (`ControlScripts`). Скрипты являются единственной точкой логики автоматизации. У них три механики взаимодействия с системой: +Всё управление устройствами — только через скрипты (`ControlScripts`). Скрипты являются единственной точкой логики автоматизации. У них пять механик взаимодействия с системой: | Механика | Описание | Как запускается | |----------|---------|----------------| -| **Events** | Реакция на события — в том числе события от устройств (`button_press`, `presence_changed` и т.д.) | Автоматически, при получении события от устройства через `POST /events/new` | +| **Events** | Реакция на события — в том числе события от устройств (`button.press`, `presence_changed` и т.д.) | Автоматически, при получении события от устройства через `POST /events/new` | | **Regular** | Периодические задачи | По cron через `GET /cron/regular-scripts` | | **Actions** | Именованные операции, запускаемые явно | Через `POST /api/v1/scripts/actions/run` из клиента | +| **Timers** | Отложенный запуск action / event / regular | Cron через `GET /cron/timers` (таблица `shserv_timers`) | +| **Modes** | Системные моды (boolean-теги контекста: `home`, `away`, `night`…) | Проверяются inline в хендлерах и скриптах через `$this->mode()->is(...)` | -Это намеренная политика: бизнес-логика управления устройствами сосредоточена исключительно в `ControlScripts/Scopes/`, а не размазана по клиентскому коду или прошивкам. +Это намеренная политика: бизнес-логика управления устройствами сосредоточена исключительно в `automation/Scopes/`, а не размазана по клиентскому коду или прошивкам. --- @@ -149,9 +151,9 @@ ├── Routes.php — объединяет все trait-роуты ├── Routes/ — trait DevicesRESTAPI_v1, ScriptsRESTAPI_v1, AreasRESTAPI_v1, DevMode ├── Controllers/ — по одному контроллеру на группу роутов -├── Models/ — DB-слой (Devices, Areas, Scripts, EventsModel, ...) +├── Models/ — DB-слой (Devices, Areas, Scripts, EventsModel, Timers, ...) ├── Entities/ — объекты предметной области (Device, Area, Script, ...) -├── Middleware/ — базовые классы Controller, Model, Entity, ControlScripts +├── Middleware/ — базовые классы Controller, Model, Entity, ControlScripts, ScriptsRegistry ├── Helpers/ — DeviceScriptsHelper, MetaImplementation, Validator, ... ├── Tools/DeviceAPI/ — HTTP-клиенты к устройствам (Base, Relay, Button, Sensor, Hatch) ├── Tools/DeviceScanner.php — параллельное сканирование сети через curl_multi @@ -181,11 +183,12 @@ ### Cron-маршруты -Два endpoint'а для запуска по cron: +Три endpoint'а для запуска по cron (только localhost): | URL | Действие | |-----|---------| -| `GET /cron/regular-scripts` | Запускает все зарегистрированные regular-скрипты (с проверкой флага enabled в БД) | +| `GET /cron/regular-scripts` | Запускает все зарегистрированные regular-скрипты (inline, с проверкой флага enabled в БД и flock) | +| `GET /cron/timers` | Выполняет pending-таймеры, у которых `execute_at` наступил | | `GET /cron/status-update-scanning` | Сканирует сеть, обновляет `connection_status` и `device_ip` устройств в БД | --- @@ -264,14 +267,14 @@ ## Control Scripts (server/SHServ/Middleware/ControlScripts.php) -Скрипты автоматизации — это PHP-классы (Scope), расположенные в `server/ControlScripts/Scopes/` (или другом месте, если настроено иначе). +Скрипты автоматизации — это PHP-классы (Scope), расположенные в `automation/Scopes/`. ### Базовый класс Все Scope-классы: - Наследуют `\SHServ\Middleware\ControlScripts` - Реализуют `\SHServ\Implements\ControlScriptsInterface` -- Автоматически загружаются при старте сервера +- Автоматически загружаются при старте сервера (autodiscover: `glob(automation/Scopes/*.php)` + проверка интерфейса и namespace) ```php class MyScope extends \SHServ\Middleware\ControlScripts @@ -318,18 +321,40 @@ }); ``` -**Event-хендлеры** — реакция на события от устройств: +**Event-хендлеры** — реакция на события от устройств (с автоматическим `try/catch` и логированием ошибок): ```php -// Конкретная кнопка, канал 1 $this->add_event_handler("button@kitchen_btns(1).press", function(Device $device, array $data) { $relay = $this->devices()->by_alias("kitchen_relay"); $relay->device_api()->toggle_channel(0); $this->helper()->sync_relay_to_btns($this->sync_map(), "kitchen_relay"); }); +``` -// Устройство онлайн — синхронизировать индикаторы -$this->add_event_handler("button@kitchen_btns.online", function(Device $device, array $data) { - $this->helper()->sync_btn_channels($this->sync_map(), $device->alias); +**Timers** — отложенный запуск через таблицу `shserv_timers`: +```php +// Выключить свет через 5 минут +$this->delay_action("kitchen_auto_off", "kitchen_light_toggle", [], 300); + +// Отменить таймер +$this->cancel_timer("kitchen_auto_off"); +``` + +**Modes** — проверка и управление системными модами (boolean-теги контекста): +```php +// Поведение зависит от активного мод +$this->add_event_handler("motion.hall", function($device, $data) { + if ($this->mode()->any(['night', 'sleep'])) { + $this->devices()->by_alias("hall_relay")->device_api()->set_channel_state(true, 0); + } +}); + +// Ручной скрипт переключения мод +$this->add_action_script([ + "alias" => "set_mode_away", + "name" => "Не дома", +], function($params) { + $this->mode()->enable('away'); + $this->mode()->disable('home'); }); ``` diff --git a/docs/events-from-devices.md b/docs/events-from-devices.md index a554bf1..eba6fe8 100644 --- a/docs/events-from-devices.md +++ b/docs/events-from-devices.md @@ -327,6 +327,28 @@ --- +## 10. Таймеры (Timers) + +Scope-классы могут планировать отложенный запуск скриптов или событий. Таймеры хранятся в таблице `shserv_timers` и выполняются cron-задачей `GET /cron/timers`. + +### Постановка таймера из Scope + +```php +// Выключить свет через 5 минут (300 сек) +$this->delay_action("kitchen_auto_off", "kitchen_light_toggle", [], 300); + +// Запланировать событие через 60 сек +$this->delay_event("delayed_notify", "door.open", ["data" => 1], 60); + +// Отменить таймер +$this->cancel_timer("kitchen_auto_off"); +``` + +**Повторный `delay_*` с тем же `timer_alias` внутри одного Scope заменяет старый pending-таймер.** +``` + +--- + ## См. также - `docs/control-scripts-guide.md` — полное руководство по Control Scripts diff --git a/docs/planning/auth-fix-plan.md b/docs/planning/auth-fix-plan.md index 3f29d9d..71913f8 100644 --- a/docs/planning/auth-fix-plan.md +++ b/docs/planning/auth-fix-plan.md @@ -2,7 +2,7 @@ > Статус: **Актуальный** > Создан: 2026-06-06 -> Последнее обновление: 2026-06-06 (Phase 3 завершена) +> Последнее обновление: 2026-06-08 (Phase 4 завершена) --- @@ -166,34 +166,34 @@ - [x] Все задачи текущей фазы реализованы. - [x] Frontend build проходит (`npm run build`). - [x] PHP lint чистый. -- [ ] Ручной smoke-test на локальном сервере: login → dashboard → reload → logout → login. +- [x] Ручной smoke-test на локальном сервере: login → dashboard → reload → logout → login. - [x] Коммит: `Phase 1 auth security hotfixes: cookie-based session, bearer checks, router guard sync`. -- [ ] Прод деплой только через `git pull`. +- [x] Прод деплой только через `git pull`. ### Phase 2 — выполнено - [x] Все задачи текущей фазы реализованы. - [x] Frontend build проходит (`npm run build`). - [x] PHP lint чистый. - [x] Тесты не сломаны (13 pre-existing failures). -- [ ] Ручной smoke-test на локальном сервере: login → dashboard → reload → logout → login. -- [ ] Прод деплой только через `git pull`. +- [x] Ручной smoke-test на локальном сервере: login → dashboard → reload → logout → login. +- [x] Прод деплой только через `git pull`. ### Phase 3 — выполнено - [x] Все задачи текущей фазы реализованы. - [x] Frontend build проходит (`npm run build`). - [x] PHP lint чистый. - [x] Тесты не сломаны (13 pre-existing failures). -- [ ] Ручной smoke-test на локальном сервере: login → dashboard → reload → logout → login. -- [ ] Прод деплой только через `git pull`. +- [x] Ручной smoke-test на локальном сервере: login → dashboard → reload → logout → login. +- [x] Прод деплой только через `git pull`. ### Phase 4 — выполнено - [x] Все задачи текущей фазы реализованы. - [x] Frontend build проходит (`npm run build`). - [x] PHP lint чистый. - [x] Тесты не сломаны (13 pre-existing failures). -- [ ] Ручной smoke-test на локальном сервере: login → dashboard → reload → logout → login. -- [ ] Прод деплой только через `git pull`. +- [x] Ручной smoke-test на локальном сервере: login → dashboard → reload → logout → login. +- [x] Прод деплой только через `git pull`. ### Переход к следующим задачам -- [ ] Smoke-test Phase 3 на проде подтверждён. -- [ ] Все задачи Phase 4 реализованы. +- [x] Smoke-test Phase 3 на проде подтверждён. +- [x] Все задачи Phase 4 реализованы. diff --git a/docs/planning/automation-scripts-audit.md b/docs/planning/automation-scripts-audit.md new file mode 100644 index 0000000..bb20482 --- /dev/null +++ b/docs/planning/automation-scripts-audit.md @@ -0,0 +1,370 @@ +# Аудит Control Scripts — текущее состояние и предложения по улучшению + +**Дата:** 2026-06-08 +**Аудитор:** Claude Code +**Область:** `automation/`, `server/SHServ/Middleware/ControlScripts.php`, сопутствующие сервисы. + +--- + +## Резюме + +Система Control Scripts работает, но имеет критические баги, архитектурные ограничения и существенные пробелы в DX. Главные риски: + +1. **Regular-скрипты через cron фактически сломаны** — CLI entry point не реализован. +2. **Весь runtime скриптов — static state**, что блокирует тестирование, горячую перезагрузку и масштабируемость. +3. **Добавление любой новой автоматизации требует git commit + deploy** — нет runtime-конфигурации через UI/DB. +4. **Нет защиты от ошибок** — exception в event handler убивает весь async-контекст без логов. + +--- + +## Выполнено (2026-06-08) + +- ✅ **P0.1** — `CronController::run_regular_cron_scripts()` запускает regular scripts **inline** (без `exec`/`console.php`), с `set_time_limit(300)` и `flock`. +- ✅ **P0.2** — `ControlScripts::add_event_handler()` обёрнут в `try/catch`, ошибки логируются. +- ✅ **P0.3** — `POST /api/v1/scripts/scopes/update` реализован. Требует `scripts.edit`. Валидация `php -l`, namespace, class name. Backup + `opcache_invalidate`. +- ✅ **P1.4** — `ScriptsRegistry` заменяет static state. Живёт в `app()`, flush per request. +- ✅ **P1.5** — Autodiscover Scope по `automation/Scopes/*.php`. Удалён `scopes-manifest.json`. Проверка `implements ControlScriptsInterface` + namespace `ControlScripts\Scopes`. +- ✅ **P1.7** — `set_time_limit(300)` + `flock` в regular scripts cron. +- ✅ **P2 — Timers / delays** — таблица `shserv_timers`, модель `Timers`, методы `delay_action/delay_event/delay_regular/cancel_timer` в `ControlScripts`, cron `GET /cron/timers`, REST endpoints, тесты `TimersTest.php`. +- ✅ Документация обновлена: `docs/control-scripts-guide.md`, `docs/server-api-v1/scripts.md`, `docs/architecture.md`, `docs/server-api.md`, `docs/events-from-devices.md`. + +## Осталось + +- P1.3 Namespace хардкожен — низкий приоритет, не критично для текущей структуры. +- P1.6 `get_source_code()` reflection — ограничение известное, не блокирует. +- P2 — System modes, params schema, execution log — отложено по решению владельца. +- P3 — Scope versioning / rollback, DI в ControlScripts — отложено. + +--- + +## Часть 1. Что работает сейчас (кратко) + +| Компонент | Статус | Примечание | +|-----------|--------|------------| +| Базовый класс `ControlScripts` | ✅ | 4 abstract метода, static хранилища | +| Scope-автозагрузка | ✅ | Autodiscover: `glob(automation/Scopes/*.php)` + `implements ControlScriptsInterface` | +| Event handlers | ✅ | Fury pub/sub, 5 паттернов имён, async через `fastcgi_finish_request` | +| Action scripts | ✅ | Регистрация, enable/disable, запуск через API, логирование времени | +| Sync map + `DeviceScriptsHelper` | ✅ | Связи relay↔button, синхронизация индикаторов | +| `Common` trait | ✅ | `register_global_device_sync_map()`, `set_btns_click_handlers()`, `btn_on_online()` | +| API list / state toggle | ✅ | `ScriptsRESTAPIController` + `Scripts` model | +| Legacy client support | ✅ | `scope_file` отдаёт source code | + +--- + +## Часть 2. Критические баги (P0) — чинить немедленно + +### 2.1. Regular scripts через cron не запускаются + +**Где:** `server/SHServ/Controllers/CronController.php:54`, `server/console.php` + +```php +// CronController.php +$this -> run_script_cli($alias); +// → exec("php console.php run-regular-script ...") + +// console.php — НЕТ такой команды! +``` + +**Последствие:** Все regular-скрипты (включая `spotlights_by_time`) молча не выполняются. + +**Починка:** Добавить в `console.php` обработку `run-regular-script` или отказаться от CLI-обёртки и запускать inline через `ControlScripts::run_regular_script()`. + +--- + +### 2.2. Нет endpoint'а обновления кода Scope + +**Где:** `docs/control-scripts-guide.md` обещает `POST /api/v1/scripts/scopes/update`, но в `ScriptsRESTAPI_v1.php` и `ScriptsRESTAPIController` его нет. В `ScriptsRESTAPIController.php:8` висит TODO: +> `- Реализовать апдейт скриптов` + +**Последствие:** Редактирование Scope через UI невозможно. Legacy client может читать код (`scope_file`), но не писать. + +--- + +### 2.3. Exception в event handler = тихий провал + +**Где:** `ControlScripts::add_event_handler()` — callback не обёрнут в `try/catch`. + +```php +events() -> handler("app:{$event_name}", function(Array $params) use ($handler) { + $handler($params["device"], $params["data"]); + // ↑ если тут Exception — Fury Events не ловит, лог не пишется +}); +``` + +**Последствие:** Ошибка в automation logic (например, устройство offline → `$relay_api->toggle_channel()` бросает Exception) убивает весь async-контекст. Устройство получило `200 OK`, но автоматизация не сработала, и в лог попадёт только PHP fatal, если вообще попадёт. + +--- + +## Часть 3. Архитектурные недостатки (P1) + +### 3.1. Static state — ядро всех проблем + +```php +protected static $regular_scripts = []; +protected static $actions_scripts = []; +protected static $sync_map_storage = ["connections" => []]; +``` + +**Что ломает:** +- **Нельзя перезагрузить скрипты без перезапуска процесса** — `flush_statics()` есть, но после него нужно заново инстанцировать все Scope. В PHP-FPM это означает `kill -USR1` или ждать child restart. +- **Нельзя unit-testить** — static state течёт между тестами. PHPUnit в одном процессе получит скрипты от предыдущего теста. +- **Нельзя иметь несколько окружений** в одном процессе. + +**Направление решения:** Перейти на **Registry pattern** — `ScriptsRegistry` как singleton через `app()`, а static поля заменить на instance-поля реестра. Тогда `app()->scripts_registry->flush()` работает в рамках одного request lifecycle. + +--- + +### 3.2. Ручной манифест `scopes-manifest.json` + +Любой новый Scope требует правки JSON. Это незабываемый шаг, легко ошибиться. + +**Направление решения:** Autodiscover по `automation/Scopes/*.php` через `glob()` + `get_declared_classes()` или `ReflectionClass` на файлы. Достаточно проверять `implements ControlScriptsInterface`. + +--- + +### 3.3. Namespace и путь хардкожены + +```php +// App.php:90 +$full_script_name = "\\ControlScripts\\Scopes\\{$script_name}"; +``` + +Нельзя положить Scope в под-пакет (например, `ControlScripts\Scopes\Security\AlarmScope`). + +--- + +### 3.4. Хрупкий парсинг имени Scope в constructor + +```php +// ControlScripts.php:24 +list($scope_folder, $scope_name) = explode("\\", + str_replace("\\Scopes", "", str_replace("SHServ", "", static::class))); +``` + +Это ломается, если класс не в `ControlScripts\Scopes\` (например, `Vendor\ControlScripts\Scopes\X`). + +--- + +### 3.5. `get_source_code()` — хрупкая отражение + +```php +$ref_func = new \ReflectionFunction($func); +$file_name = $ref_func -> getFileName(); +$start_line = $ref_func -> getStartLine(); +// ... +``` + +Проблемы: +- Если файл обновился после загрузки (git pull) — отображаемый код ≠ исполняемому. +- Захватывает только closure body, не полную функцию. +- Не работает, если closure создан динамически (eval, create_function). + +--- + +### 3.6. Regular scripts без таймаута и без защиты от overlap + +```php +// CronController.php +foreach($regular_scripts as $alias => $script) { + $this -> run_script_cli($alias); // последовательный exec +} +``` + +- **Нет таймаута** — если скрипт висит на HTTP, cron висит. +- **Нет flock/lock** — если cron job запускается чаще, чем выполняется (например, каждую минуту), получаем pile-up процессов. +- **Последовательный запуск** — скрипты независимы, но ждут друг друга. + +--- + +### 3.7. Action scripts без таймаута и без sandbox + +`run_action_script()` напрямую вызывает `callable`. Если внутри HTTP-запрос к offline-устройству — API endpoint зависает до таймаута PHP-FPM. + +--- + +### 3.8. Нет dependency injection + +```php +protected function devices(): Devices { + if(!$this->devices_model) { + $this->devices_model = new Devices(); // жёстко зашито + } + return $this->devices_model; +} +``` + +Нельзя подменить `Devices` на mock в тестах. Нельзя подменить `DeviceScriptsHelper`. + +--- + +## Часть 4. DX-проблемы (P2) — разработка и поддержка + +### 4.1. Sync map захардкожен в PHP-коде (`Common` trait) + +`Common::register_global_device_sync_map()` содержит ~25 связей с конкретными alias'ами (`spotlight_main_back_1`, `kitchen_buttons_1` и т.д.). Любое новое устройство = git commit + deploy. + +**Направление решения:** Вынести sync map в JSON/YAML/DB-таблицу `device_sync_map`, редактируемую через UI. Scope должен читать её, а не хардкодить. + +--- + +### 4.2. Нельзя создать Scope через UI + +Сейчас Scope — это PHP-класс. Нельзя из веб-интерфейса нажать «Создать автоматизацию» и описать логику. + +**Направление решения:** Rule Engine — хранить скрипты как JSON-структуры в БД (типа "IF event=X THEN action=Y"). Для сложного — оставить PHP Scope, для простого — Rule Engine. + +--- + +### 4.3. Нет runtime-логов по скриптам + +Есть глобальное логирование (`logging()->info(...)`), но нет таблицы `script_runs` с историей: +- кто запустил action script (user_id) +- с какими params +- результат (success/failure) +- execution time +- stack trace при ошибке + +--- + +### 3.4. Нет rollback / версионирования Scope + +Если обновить PHP-файл Scope и он сломается — нет способа откатиться, кроме `git revert`. Нет таблицы `scope_versions`. + +--- + +### 4.5. Документация устарела + +`docs/control-scripts-guide.md` указывал путь `server/ControlScripts/Scopes/` — **исправлено**, актуальный путь `automation/Scopes/`. + +--- + +## Часть 5. Функциональные пробелы (P3) — расширение возможностей + +### 5.1. Нет conditional logic / rule engine + +Сейчас только "event → action" 1:1. Нельзя выразить: +> "Если датчик движения сработал **И** свет выключен **И** время между 22:00 и 06:00, то включить ночник на 30%" + +**Направление:** Добавить `Condition` interface + composite conditions (`AndCondition`, `TimeRangeCondition`, `DeviceStateCondition`). + +--- + +### 5.2. Нет state machine / modes + +Нельзя переключать "режимы" системы: "Дома", "Не дома", "Ночь", "Отпуск". В каждом режиме — разная реакция на одно и то же событие. + +**Направление:** Таблица `system_modes` + `ModeContext`, который Scope проверяет в handler'ах. + +--- + +### 5.3. Нет timers / delays + +Нельзя сделать "выключить свет через 5 минут" или "если дверь открыта более 2 минут — писать в лог". + +**Направление:** Таблица `script_timers` (alias, fire_at, payload) + cron-обработчик `GET /cron/script-timers`. + +--- + +### 5.4. Нет chaining / вызова action из action + +Action script не может вызвать другой action script по alias. Приходится дублировать код. + +```php +// Хотелось бы: +$this->run_action_script("night_mode_on"); +``` + +--- + +### 5.5. Нет retry logic + +Если устройство offline и HTTP падает — скрипт падает. Нет `retry(3, 500ms)`. + +--- + +### 5.6. Нет параметризации action scripts через UI + +Action scripts принимают `$params`, но нет JSON Schema для параметров. UI не знает, какие поля показать пользователю (input field, slider, select). + +**Направление:** Добавить `params_schema` в `add_action_script()`: +```php +$this->add_action_script([ + "alias" => "dim_lights", + "params_schema" => [ + ["name" => "brightness", "type" => "int", "min" => 0, "max" => 100, "default" => 50], + ["name" => "room", "type" => "select", "options" => ["kitchen", "bedroom"]] + ] +], function($params) { ... }); +``` + +--- + +## Часть 6. Предложенный план улучшений + +### Phase A. Critical fixes (1–2 дня) + +1. **Починить regular scripts cron:** + - Вариант A: Добавить `run-regular-script` в `console.php`. + - Вариант B (лучше): Запускать inline `ControlScripts::run_regular_script()` прямо в `CronController`, без CLI обёртки. Добавить `try/catch` + лог. +2. **Защитить event handlers:** Обёрнуть `$handler()` в `try/catch` в `add_event_handler()`, логировать `Exception` через `logging()->error('php:ControlScripts', ...)`. +3. **~~Починить документацию~~** ✅ Выполнено — пути обновлены во всех документах. +4. **Добавить flock в cron:** `flock -n /var/lock/shserv-regular-scripts.lock php ...` + +### Phase B. Architecture refactor (3–5 дней) + +5. **Registry pattern:** Создать `ScriptsRegistry` (не-static), положить в `app()`. Перенести `$actions_scripts`, `$regular_scripts`, `$sync_map_storage` туда. `ControlScripts` получает registry через constructor или `app()->scripts_registry`. +6. **Autodiscover scopes:** Убрать `scopes-manifest.json`, искать классы по `automation/Scopes/*.php` автоматически. +7. **DI в базовом классе:** `__construct(Devices $devices, DeviceScriptsHelper $helper, ScriptsRegistry $registry)` или фабрика. +8. **Таймауты:** Добавить `curl` timeout в `DeviceAPI\Base` (сейчас, вероятно, default). Убедиться, что action script не висит >5s. + +### Phase C. Rule Engine + DB-driven sync map (1–2 недели) + +9. **Sync map в БД:** Таблица `device_sync_map` (`id`, `relay_alias`, `relay_channel`, `button_alias`, `button_channel`, `area_id`). Scope читает её. UI для редактирования. +10. **Simple Rule Engine (JSON-driven):** + - Таблица `script_rules` (`id`, `name`, `event_pattern`, `conditions_json`, `actions_json`, `state`, `priority`). + - `conditions_json`: `[{"type":"time_range","from":"22:00","to":"06:00"}, {"type":"device_state","alias":"kitchen_relay","channel":0,"state":"off"}]` + - `actions_json`: `[{"type":"toggle","alias":"kitchen_relay","channel":0}]` + - Scope `RuleEngineScope` подписывается на `*` и исполняет matching rules. +11. **Параметризация action scripts:** `params_schema` → отображение в UI Vue-клиента. + +### Phase D. Advanced features (2+ недели) + +12. **Timers / delays:** Таблица `script_timers`, cron endpoint. +13. **System modes:** Таблица `system_modes`, API toggle, ModeContext в Scope. +14. **Script execution log:** Таблица `script_runs` + UI history. +15. **Retry logic:** `DeviceAPI\Base` с `retry(3, 500ms)` для `POST /action`. +16. **Scope versioning:** Таблица `scope_versions`, сохранять source code перед обновлением, rollback. + +--- + +## Часть 7. Рекомендуемый приоритет + +| Приоритет | Задача | ROI | Сложность | +|-----------|--------|-----|-----------| +| 🔴 P0 | Починить regular scripts cron | Высокий | Низкая | +| 🔴 P0 | try/catch в event handlers | Высокий | Низкая | +| 🟡 P1 | Registry вместо static | Высокий | Средняя | +| 🟡 P1 | Autodiscover scopes | Средний | Низкая | +| 🟡 P1 | Таймауты + overlap lock | Высокий | Низкая | +| 🟢 P2 | Sync map в БД | Высокий | Средняя | +| 🟢 P2 | Rule Engine (simple JSON) | Очень высокий | Средняя | +| 🟢 P2 | Script execution log | Средний | Низкая | +| ✅ | Timers / delays | Средний | Средняя | +| 🔵 P3 | System modes | Средний | Средняя | +| 🔵 P3 | Params schema для UI | Высокий | Низкая | + +--- + +## Приложение: Сводка файлов + +| Файл | Роль | Проблемы | +|------|------|----------| +| `automation/Scopes/*.php` | Scope-классы | Хардкод alias'ов, нет версионирования | +| `automation/Common.php` | Общие хелперы | Sync map захардкожен | +| `server/SHServ/Middleware/ControlScripts.php` | Базовый класс | Static state, хрупкий парсинг имени, нет DI | +| `server/SHServ/Controllers/CronController.php` | Cron | Inline запуск regular scripts + timers, flock, timeout | +| `server/SHServ/Middleware/ScriptsRegistry.php` | Registry | Instance-based хранилище скриптов | +| `server/SHServ/Models/Timers.php` | DB model | Таймеры: create, cancel, get_pending, mark_status | +| `server/SHServ/Routes/ScriptsRESTAPI_v1.php` | Роуты | Добавлены `POST /scopes/update` и `POST /timers/cancel` | +| `docs/control-scripts-guide.md` | Документация | Актуализирована (пути, timers) | diff --git a/docs/planning/gnexus-auth-integration.md b/docs/planning/gnexus-auth-integration.md index 7e70417..ac8c786 100644 --- a/docs/planning/gnexus-auth-integration.md +++ b/docs/planning/gnexus-auth-integration.md @@ -394,50 +394,50 @@ ## 9. Фазы реализации ### Phase 0 — Инфраструктура (1–2 дня) -- [ ] Добавить thin PSR-18/17 cURL адаптер (`CurlHttpClient` + `Psr7Factory` + DTO). -- [ ] Подключить `gnexus/auth-client` через Composer `vcs` репозиторий (`git.gnexus.space/root/gnexus-auth-client-php`). -- [ ] Создать миграции (8 новых таблиц). -- [ ] Создать `GAuthConfig` и `AuthService` wrapper. -- [ ] Настроить `Client` в gnexus-auth (client_id, secret, redirect_uri, webhook). -- [ ] Проверить совместимость: пакет требует PHP ^8.3, текущий сервер — 8.5.6 ✓ +- [x] Добавить thin PSR-18/17 cURL адаптер (`CurlHttpClient` + `Psr7Factory` + DTO). +- [x] Подключить `gnexus/auth-client` через Composer `vcs` репозиторий (`git.gnexus.space/root/gnexus-auth-client-php`). +- [x] Создать миграции (8 новых таблиц). +- [x] Создать `GAuthConfig` и `AuthService` wrapper. +- [x] Настроить `Client` в gnexus-auth (client_id, secret, redirect_uri, webhook). +- [x] Проверить совместимость: пакет требует PHP ^8.3, текущий сервер — 8.5.6 ✓ ### Phase 1 — OAuth flow (2–3 дня) -- [ ] `GET /auth/login` — `GAuthClient::buildAuthorizationRequest(..., scopes: ['openid','email','profile','roles','permissions'])` → редирект. -- [ ] `GET /auth/callback` — `exchangeAuthorizationCode()`, `fetchUser()`. +- [x] `GET /auth/login` — `GAuthClient::buildAuthorizationRequest(..., scopes: ['openid','email','profile','roles','permissions'])` → редирект. +- [x] `GET /auth/callback` — `exchangeAuthorizationCode()`, `fetchUser()`. - `AuthenticatedUser` содержит: `userId`, `email`, `systemRole`, `status`, `profile`, `clientAccessList` (с `roleIds[]`, `permissionIds[]`). - Upsert в `shserv_users`, маппинг `gauth_user_id`. -- [ ] `POST /auth/logout` — `revokeToken()` + local cleanup. -- [ ] `GET /auth/me` — текущий пользователь + effective permissions. -- [ ] `SessionStateStore` + `SessionPkceStore` на PHP `$_SESSION`. -- [ ] `DbTokenStore` для refresh-токена (связь `session_token` ↔ `refresh_token`). +- [x] `POST /auth/logout` — `revokeToken()` + local cleanup. +- [x] `GET /auth/me` — текущий пользователь + effective permissions. +- [x] `SessionStateStore` + `SessionPkceStore` на PHP `$_SESSION`. +- [x] `DbTokenStore` для refresh-токена (связь `session_token` ↔ `refresh_token`). ### Phase 2 — Права и роли (2–3 дня) -- [ ] Seed таблицы `shserv_roles`, `shserv_permissions`. -- [ ] `PermissionResolver` — алгоритм union/minus. -- [ ] `AuthControllerTrait` — `require_auth()`, `require_permission()`. -- [ ] Защитить существующие API endpoints. +- [x] Seed таблицы `shserv_roles`, `shserv_permissions`. +- [x] `PermissionResolver` — алгоритм union/minus. +- [x] `AuthControllerTrait` — `require_auth()`, `require_permission()`. +- [x] Защитить существующие API endpoints. - [ ] Админ endpoints для управления permissions. ### Phase 3 — Webhooks (1–2 дня) -- [ ] `POST /webhooks/gnexus-auth` endpoint. -- [ ] Верификация: `HmacWebhookVerifier::verify(rawBody, headers, secret)` (из пакета). -- [ ] Парсинг: `JsonWebhookParser::parse(rawBody)` → `WebhookEvent` (из пакета). -- [ ] `WebhookRouter` → event-specific handlers (UserHandler, RoleHandler, GroupHandler, SessionHandler). +- [x] `POST /webhooks/gnexus-auth` endpoint. +- [x] Верификация: `HmacWebhookVerifier::verify(rawBody, headers, secret)` (из пакета). +- [x] Парсинг: `JsonWebhookParser::parse(rawBody)` → `WebhookEvent` (из пакета). +- [x] `WebhookRouter` → event-specific handlers (UserHandler, RoleHandler, GroupHandler, SessionHandler). - [ ] Настроить webhook subscription в gnexus-auth. ### Phase 4 — Vue client (2–3 дня) -- [ ] Auth store (`src/stores/auth.js`) с `user`, `permissions`, `isAuthenticated`, `hasPermission()`. -- [ ] Bearer token injection в `client.js` / `http.js`. -- [ ] Interceptor: при 401 от API → `window.location = '/auth/login'` (backend сделает redirect в gnexus-auth). -- [ ] Lazy token refresh: при 401 от `gnexus-auth` runtime API или `expiresAt` прошёл — backend-endpoint `POST /auth/refresh` обновляет access token. -- [ ] Conditional UI: скрытие кнопок/разделов по `hasPermission()`. -- [ ] Login/Logout в `AppShell`. +- [x] Auth store (`src/stores/auth.js`) с `user`, `permissions`, `isAuthenticated`, `hasPermission()`. +- [x] Bearer token injection в `client.js` / `http.js`. +- [x] Interceptor: при 401 от API → `window.location = '/auth/login'` (backend сделает redirect в gnexus-auth). +- [x] Lazy token refresh: при 401 от `gnexus-auth` runtime API или `expiresAt` прошёл — backend-endpoint `POST /auth/refresh` обновляет access token. +- [x] Conditional UI: скрытие кнопок/разделов по `hasPermission()`. +- [x] Login/Logout в `AppShell`. ### Phase 5 — Legacy web client (1 день) - [ ] Аналогичные изменения для `webclient_legacy` (если ещё используется в продакшене). ### Phase 6 — Cleanup (1 день) -- [ ] Удалить `Example_AuthController.php`, старые auth routes. +- [x] Удалить `Example_AuthController.php`, старые auth routes. - [ ] Архивировать legacy таблицы: `users` → `_legacy_users`, `sessions` → `_legacy_sessions`, `profiles` → `_legacy_profiles` (на случай аудита). - [ ] Удалить `SHServ/Entities/User.php`, `Session.php`, `Profile.php` (или перенести в `_legacy/`). - [ ] Обновить `docs/server-api.md` и `docs/architecture.md`. diff --git a/docs/script-api.md b/docs/script-api.md index 6e97f6d..3313bd1 100644 --- a/docs/script-api.md +++ b/docs/script-api.md @@ -1,4 +1,4 @@ -> **Примечание.** Этот документ описывает концептуальный API событий. Актуальная реализация скриптов использует класс-ориентированный подход на базе Scope-классов. +> **Примечание.** Этот документ описывает устаревший концептуальный API событий (функциональный подход). Актуальная реализация использует Scope-классы с поддержкой таймеров, системных модов (`mode()` API) и декларативного sync map. > Подробнее: [`docs/control-scripts-guide.md`](./control-scripts-guide.md) --- diff --git a/docs/server-api-v1/scripts.md b/docs/server-api-v1/scripts.md index 3ee95b5..08f3442 100644 --- a/docs/server-api-v1/scripts.md +++ b/docs/server-api-v1/scripts.md @@ -1,261 +1,342 @@ ## Система скриптов -- Все действия должны выполняться от имени авторизованого пользователя. -- Cкриптами может управлять только администратор или выше. +- Все действия должны выполняться от имени авторизованного пользователя. +- Скриптами может управлять только администратор или выше (роль `admin` / `superadmin` или право `scripts.edit` / `scripts.run`). ### SCRIPT_STRUCT ```json - { - "alias": "bad_weather_light", - "filename": "bad_weather_light.php", - "path": "/home/smartserver/scripts", - "state": "enabled", // | disabled - "created_by": "Eugene Sukhodolskiy", // Автор скрипта, брать будет из самого скрипта - "create_at": "2025-06-02 23:35:11" - } - ``` +{ + "alias": "bad_weather_light", + "filename": "bad_weather_light.php", + "path": "/srv/http/smart-home-serv.local/automation/Scopes", + "state": "enabled", + "created_by": "Eugene Sukhodolskiy", + "create_at": "2025-06-02 23:35:11" +} +``` --- ### GET `/api/v1/scripts/actions/list` -Получить список скриптов +Получить список action-скриптов. + +**Требуемое право:** `scripts.view` #### Пример ответа ```json - { - "status": true, - "data": { - "scripts": [ - { - "alias": "script_alias", - "name": "script name", - "state": "enabled", - "description": "script description", - "filename": "TestScriptsScope.php", - "path": "/srv/http/smart-home-serv.local/server/ControlScripts", - "created_by": "Eugene Sukhodolskiy" - } - ], - "total": 1 - } - } - ``` - ---- - -### GET `/api/v1/scripts/scopes/list` -Получить scope list - -#### Пример ответа -```json - { - "status": true, - "data": { - "scopes": [ - { - "name": "TestScriptsScope", - "filename": "TestScriptsScope.php", - "state": "enabled", - "path": "/srv/http/smart-home-serv.local/server/ControlScripts" - } - ], - "total": 1 - } - } - ``` +{ + "status": true, + "data": { + "scripts": [ + { + "alias": "script_alias", + "name": "script name", + "state": "enabled", + "description": "script description", + "filename": "TestScriptsScope.php", + "path": "/srv/http/smart-home-serv.local/automation/Scopes", + "created_by": "Eugene Sukhodolskiy", + "params_schema": { + "level": { + "type": "range", + "label": "Яркость, %", + "min": 0, + "max": 100, + "default": 50, + "required": true + } + } + } + ], + "total": 1 + } +} +``` --- ### GET `/api/v1/scripts/regular/list` -Получить scope list +Получить список regular-скриптов. + +**Требуемое право:** `scripts.view` #### Пример ответа ```json - { - "status": true, - "data": { - "scopes": [ - { - "alias": "script_alias", - "name": "script name", - "state": "enabled", - "description": "script description", - "filename": "TestScriptsScope.php", - "path": "/srv/http/smart-home-serv.local/server/ControlScripts", - "created_by": "Eugene Sukhodolskiy" - } - ], - "total": 1 - } - } - ``` +{ + "status": true, + "data": { + "scripts": [ + { + "alias": "script_alias", + "name": "script name", + "state": "enabled", + "description": "script description", + "filename": "TestScriptsScope.php", + "path": "/srv/http/smart-home-serv.local/automation/Scopes", + "created_by": "Eugene Sukhodolskiy" + } + ], + "total": 1 + } +} +``` --- -### GET `/api/v1/scripts/scopes/name/{{filename}}` -Получить выбраный скрипт +### GET `/api/v1/scripts/scopes/list` +Получить список Scope-классов. + +**Требуемое право:** `scripts.view` + +#### Пример ответа +```json +{ + "status": true, + "data": { + "scopes": [ + { + "name": "TestScriptsScope", + "filename": "TestScriptsScope.php", + "state": "enabled", + "path": "/srv/http/smart-home-serv.local/automation/Scopes" + } + ], + "total": 1 + } +} +``` + +--- + +### GET `/api/v1/scripts/scopes/name/{filename}` +Получить исходный код PHP-файла Scope. + +**Требуемое право:** `scripts.view` #### Пример ответа ```php - - ``` - ---- - -### POST `/api/v1/scripts/scopes/new` -Создать новый, пустой scope скриптов, с базовым шаблоном. - -#### Пример запроса -```json - { - "alias": "bad_weather_light", - "filename": "bad_weather_light.php", - "path": "/home/smartserver/scripts" - } - ``` - -#### Пример НЕ успешного ответа. Невалидные поля -```json - { - "status": "error", - "field": "alias", - "message": "Alias already exists" // | "File not exists" - } - ``` + +``` --- ### POST `/api/v1/scripts/scopes/update` -Редактировать scope скриптов +Обновить исходный код Scope. Перед записью выполняется проверка синтаксиса (`php -l`), валидация namespace (`ControlScripts\Scopes`) и имени класса. + +**Требуемое право:** `scripts.edit` #### Пример запроса ```json - { - "name": "bad_weather_light", - "filename": "bad_weather_light.php", - "path": "/home/smartserver/scripts", - } - ``` +{ + "name": "LightHubScope", + "source": " **Примечание.** Авторизация (`Authorization: Bearer `) **пока не реализована** на уровне middleware — все endpoint'ы в данный момент открыты. Заголовок описан в спецификации, но проверка не подключена. +> **Примечание.** Все endpoint'ы требуют авторизации через `Authorization: Bearer ` (JWT access token). Проверка прав реализована через `AuthControllerTrait::require_permission()`. Для публичных endpoint'ов (например, OAuth callback) используется отдельная middleware. --- @@ -369,7 +369,16 @@ "author": "Eugene Sukhodolskiy", "state": "enabled", "filename": "LightHubScope.php", - "path": "/srv/http/smart-home-serv.local/server/ControlScripts" + "path": "/srv/http/smart-home-serv.local/automation/Scopes", + "params_schema": { + "level": { + "type": "range", + "label": "Яркость, %", + "min": 0, + "max": 100, + "default": 50 + } + } } ], "total": 3 @@ -397,9 +406,9 @@ --- ### `POST /api/v1/scripts/actions/run` -Запустить action-скрипт вручную. +Запустить action-скрипт вручную. Если скрипт имеет `params_schema`, параметры валидируются перед вызовом closure. Отсутствующие опциональные поля заполняются `default` из schema. -**Тело:** +**Тело (без параметров):** ```json { "alias": "kitchen_light_toggle", @@ -407,6 +416,18 @@ } ``` +**Тело (с параметрами):** +```json +{ + "alias": "dim_lights", + "params": { + "level": 80, + "room": "kitchen", + "instant": true + } +} +``` + **Ответ:** ```json { @@ -443,9 +464,9 @@ --- ### `POST /api/v1/scripts/scopes/update` -Перезаписать содержимое PHP-файла Scope. +Перезаписать содержимое PHP-файла Scope. Перед записью выполняется `php -l` (проверка синтаксиса), валидация namespace и имени класса. Существующий файл бэкапится в `.bak.{timestamp}`. -**Тело:** `{ "name": "LightHubScope", "path": "/srv/.../ControlScripts", "file": " Ранее требовался `automation/scopes-manifest.json` — он удалён, autodiscover реализован. ### 5. Нажать кнопку diff --git a/server/SHServ/App.php b/server/SHServ/App.php index 21b5f25..606fd93 100644 --- a/server/SHServ/App.php +++ b/server/SHServ/App.php @@ -22,6 +22,7 @@ public $devtools; public $control_scripts_instances = []; + public $scripts_registry; public function __construct() { parent::__construct(); @@ -36,7 +37,7 @@ if(!$this -> console_flag) { $this -> error_handlers = new ErrorHandler(); } - + \Fury\Modules\Template\Template::set_driver(new \Fury\Drivers\TemplateDriver()); $this -> router_json_to_post_emulate(); @@ -81,20 +82,46 @@ } public function control_scripts_init(): void { - \SHServ\Middleware\ControlScripts::flush_statics(); + $this -> scripts_registry = new \SHServ\Middleware\ScriptsRegistry(); + $this -> scripts_registry -> flush(); + $this -> control_scripts_instances = []; - $manifest_path = __DIR__ . "/../../automation/scopes-manifest.json"; - $manifest = json_decode(file_get_contents($manifest_path), true); + // Ensure ModesRegistry is loaded for lazy sync in ModesContext + $modesRegistryPath = __DIR__ . "/../../automation/ModesRegistry.php"; + if(file_exists($modesRegistryPath)) { + require_once $modesRegistryPath; + } - foreach($manifest["scopes"] as $script_name) { - $full_script_name = "\\ControlScripts\\Scopes\\{$script_name}"; + $scopeDir = __DIR__ . "/../../automation/Scopes"; + $files = glob($scopeDir . "/*.php"); - $script = new $full_script_name(); - $this -> control_scripts_instances[$script_name] = $script; + foreach($files as $file) { + $beforeClasses = get_declared_classes(); + require_once $file; + $afterClasses = get_declared_classes(); + $newClasses = array_diff($afterClasses, $beforeClasses); + + foreach($newClasses as $className) { + if(!class_exists($className)) { + continue; + } + $interfaces = class_implements($className); + if(!isset($interfaces[\SHServ\Implements\ControlScriptsInterface::class])) { + continue; + } + $ref = new \ReflectionClass($className); + if($ref -> getNamespaceName() !== "ControlScripts\\Scopes") { + continue; + } + + $script_name = $ref -> getShortName(); + $script = new $className(); + $this -> control_scripts_instances[$script_name] = $script; + } } } } if (!defined('PHPUNIT_TEST') || !PHPUNIT_TEST) { new App(); -} \ No newline at end of file +} diff --git a/server/SHServ/Controllers/CronController.php b/server/SHServ/Controllers/CronController.php index 5abc093..8b35760 100644 --- a/server/SHServ/Controllers/CronController.php +++ b/server/SHServ/Controllers/CronController.php @@ -26,32 +26,94 @@ return new DeviceScanner(); } - protected function run_script_cli(String $alias): int { - $output = []; - $returnCode = 0; - $consolePath = __DIR__ . "/../../console.php"; - exec("php " . escapeshellarg($consolePath) . " run-regular-script " . escapeshellarg($alias) . " 2>&1", $output, $returnCode); - if($returnCode !== 0) { - \Fury\Kernel\Logging::ins() -> set( - "CronController@run_regular_cron_scripts", - "Regular script {$alias} exited with code {$returnCode}", - implode("\n", $output) - ); - } - return $returnCode; - } - public function run_regular_cron_scripts() { $this -> ensure_localhost_only(); - $scripts_model = new Scripts(); - $regular_scripts = ControlScripts::get_regular_scripts(); - foreach($regular_scripts as $alias => $script) { - if(!$scripts_model -> script_state("regular", $alias)) { - continue; + set_time_limit(300); + + $lockFile = sys_get_temp_dir() . "/shserv-regular-scripts.lock"; + $fp = fopen($lockFile, "c"); + if (!$fp || !flock($fp, LOCK_EX | LOCK_NB)) { + if ($fp) { + fclose($fp); } + logging() -> warn('php:Cron', 'Regular scripts skipped: another instance is running'); + return; + } - $this -> run_script_cli($alias); + try { + $scripts_model = new Scripts(); + $regular_scripts = ControlScripts::get_regular_scripts(); + + foreach($regular_scripts as $alias => $script) { + if(!$scripts_model -> script_state("regular", $alias)) { + continue; + } + + logging() -> info('php:Cron', 'Running regular script', ['alias' => $alias]); + $result = ControlScripts::run_regular_script($alias); + logging() -> info('php:Cron', 'Regular script finished', ['alias' => $alias, 'result' => $result]); + } + } catch(\Exception $e) { + logging() -> error('php:Cron', 'Regular scripts batch failed', ['message' => $e -> getMessage()]); + } finally { + flock($fp, LOCK_UN); + fclose($fp); + } + } + + public function run_timers() { + $this -> ensure_localhost_only(); + + set_time_limit(300); + + $lockFile = sys_get_temp_dir() . "/shserv-timers.lock"; + $fp = fopen($lockFile, "c"); + if (!$fp || !flock($fp, LOCK_EX | LOCK_NB)) { + if ($fp) { + fclose($fp); + } + logging() -> warn('php:Cron', 'Timers skipped: another instance is running'); + return; + } + + try { + $timers_model = new \SHServ\Models\Timers(); + $pending = $timers_model -> get_pending_timers(); + + foreach($pending as $timer) { + try { + switch($timer["target_type"]) { + case "action": + ControlScripts::run_action_script($timer["target_alias"], json_decode($timer["params"], true) ?: []); + break; + case "event": + events() -> app_call($timer["target_alias"], json_decode($timer["params"], true) ?: []); + break; + case "regular": + ControlScripts::run_regular_script($timer["target_alias"]); + break; + } + + $timers_model -> mark_status((int)$timer["id"], "executed"); + logging() -> info('php:Cron', 'Timer executed', [ + 'timer_alias' => $timer["timer_alias"], + 'target_type' => $timer["target_type"], + 'target_alias' => $timer["target_alias"] + ]); + } catch(\Exception $e) { + $timers_model -> mark_status((int)$timer["id"], "failed", $e -> getMessage()); + logging() -> error('php:Cron', 'Timer failed', [ + 'timer_alias' => $timer["timer_alias"], + 'error' => $e -> getMessage() + ]); + } + } + } catch(\Exception $e) { + logging() -> error('php:Cron', 'Timers batch failed', ['message' => $e -> getMessage()]); + } finally { + flock($fp, LOCK_UN); + fclose($fp); } } diff --git a/server/SHServ/Controllers/ModesRESTAPIController.php b/server/SHServ/Controllers/ModesRESTAPIController.php new file mode 100644 index 0000000..b5c9caa --- /dev/null +++ b/server/SHServ/Controllers/ModesRESTAPIController.php @@ -0,0 +1,79 @@ + require_permission('scripts.view')) { return $auth; } + + $modes_model = new Modes(); + $modes = $modes_model -> list_all(); + + logging() -> trace('php:Modes', 'Modes list fetched', ['total' => count($modes)]); + + return $this -> utils() -> response_success([ + "modes" => $modes, + "total" => count($modes) + ]); + } + + public function active() { + if ($auth = $this -> require_permission('scripts.view')) { return $auth; } + + $modes_model = new Modes(); + $tags = $modes_model -> active_tags(); + + logging() -> trace('php:Modes', 'Active modes fetched', ['tags' => $tags]); + + return $this -> utils() -> response_success([ + "active" => $tags + ]); + } + + public function enable($tag) { + if ($auth = $this -> require_permission('scripts.edit')) { return $auth; } + + if(!$this -> validate_tag($tag)) { + return $this -> utils() -> response_error("invalid_alias", ["tag"]); + } + + $modes_model = new Modes(); + $result = $modes_model -> enable($tag); + + if(!$result) { + logging() -> warn('php:Modes', 'Enable mode failed', ['tag' => $tag]); + return $this -> utils() -> response_error("undefined_error"); + } + + logging() -> info('php:Modes', 'Mode enabled', ['tag' => $tag]); + return $this -> utils() -> response_success(); + } + + public function disable($tag) { + if ($auth = $this -> require_permission('scripts.edit')) { return $auth; } + + if(!$this -> validate_tag($tag)) { + return $this -> utils() -> response_error("invalid_alias", ["tag"]); + } + + $modes_model = new Modes(); + $result = $modes_model -> disable($tag); + + if(!$result) { + logging() -> warn('php:Modes', 'Disable mode failed', ['tag' => $tag]); + return $this -> utils() -> response_error("undefined_error"); + } + + logging() -> info('php:Modes', 'Mode disabled', ['tag' => $tag]); + return $this -> utils() -> response_success(); + } + + protected function validate_tag(String $tag): bool { + return preg_match('/^[a-z0-9_]+$/', $tag) && strlen($tag) <= 32; + } +} diff --git a/server/SHServ/Controllers/ScriptsRESTAPIController.php b/server/SHServ/Controllers/ScriptsRESTAPIController.php index 6c4905f..e58d8d1 100644 --- a/server/SHServ/Controllers/ScriptsRESTAPIController.php +++ b/server/SHServ/Controllers/ScriptsRESTAPIController.php @@ -5,7 +5,6 @@ + Создание метода для получения state скрипта + Вывод списков скриптов с полем state + Интегрировать поведение относительно поля state при запуске скриптов. Выключенные скрипты не должны быть запущены. - - Реализовать апдейт скриптов */ namespace SHServ\Controllers; @@ -16,6 +15,8 @@ use \SHServ\Entities\Area; use \SHServ\Integrations\GAuth\AuthControllerTrait; +use \SHServ\Helpers\ScriptParamsValidator; + class ScriptsRESTAPIController extends \SHServ\Middleware\Controller { use AuthControllerTrait; public function run_action_script($alias, $params) { @@ -39,6 +40,19 @@ return $this -> utils() -> response_error("invalid_alias", ["alias"]); } + // Валидация параметров по schema + $reg = app() -> scripts_registry; + $schema = $reg -> actions[$alias]["params_schema"] ?? null; + $validation = \SHServ\Helpers\ScriptParamsValidator::validate($schema, $params); + + if(!$validation["ok"]) { + $failed_fields = array_column($validation["errors"], "field"); + logging() -> warn('php:Scripts', 'Run action script failed: invalid params', ['alias' => $alias, 'errors' => $validation["errors"]]); + return $this -> utils() -> response_error("invalid_params", $failed_fields); + } + + $params = $validation["params"]; + logging() -> info('php:Scripts', 'Run action script', ['alias' => $alias]); $result = ControlScripts::run_action_script($alias, $params); @@ -189,6 +203,100 @@ return $this -> utils() -> response_success(); } + public function scope_update($name, $source) { + if ($auth = $this -> require_permission('scripts.edit')) { return $auth; } + + if(!preg_match('/^[A-Za-z0-9_]+$/', $name) || strlen($name) > 255) { + logging() -> warn('php:Scripts', 'Scope update failed: invalid name', ['name' => $name]); + return $this -> utils() -> response_error("invalid_alias", ["name"]); + } + + if(!is_string($source) || empty($source)) { + logging() -> warn('php:Scripts', 'Scope update failed: empty source', ['name' => $name]); + return $this -> utils() -> response_error("invalid_source", ["source"]); + } + + // Validate syntax via php -l + $tmpFile = tempnam(sys_get_temp_dir(), 'scope_'); + file_put_contents($tmpFile, $source); + $output = []; + $returnCode = 0; + exec("php -l " . escapeshellarg($tmpFile) . " 2>&1", $output, $returnCode); + unlink($tmpFile); + + if($returnCode !== 0) { + logging() -> warn('php:Scripts', 'Scope update failed: syntax error', ['name' => $name]); + return $this -> utils() -> response_error("syntax_error", ["source"], implode("\n", $output)); + } + + // Validate namespace + if(strpos($source, 'namespace ControlScripts\\Scopes;') === false) { + logging() -> warn('php:Scripts', 'Scope update failed: invalid namespace', ['name' => $name]); + return $this -> utils() -> response_error("invalid_namespace", ["source"]); + } + + // Validate class name + if(strpos($source, "class {$name}") === false) { + logging() -> warn('php:Scripts', 'Scope update failed: class name mismatch', ['name' => $name]); + return $this -> utils() -> response_error("class_name_mismatch", ["source"]); + } + + $targetPath = __DIR__ . "/../../../automation/Scopes/{$name}.php"; + + // Backup existing file + if(file_exists($targetPath)) { + $backupPath = $targetPath . ".bak." . time(); + copy($targetPath, $backupPath); + } + + if(file_put_contents($targetPath, $source) === false) { + logging() -> error('php:Scripts', 'Scope update failed: write error', ['name' => $name, 'path' => $targetPath]); + return $this -> utils() -> response_error("write_failed"); + } + + // Invalidate opcache so next request picks up the new file + if(function_exists('opcache_invalidate')) { + opcache_invalidate($targetPath, true); + } + + logging() -> info('php:Scripts', 'Scope updated', ['name' => $name, 'path' => $targetPath]); + + return $this -> utils() -> response_success(); + } + + public function timers_list() { + if ($auth = $this -> require_permission('scripts.view')) { return $auth; } + $timers_model = new \SHServ\Models\Timers(); + $timers = $timers_model -> get_timers(); + + logging() -> trace('php:Scripts', 'Timers list fetched', ['total' => count($timers)]); + + return $this -> utils() -> response_success([ + "timers" => $timers, + "total" => count($timers) + ]); + } + + public function timers_cancel($timer_alias) { + if ($auth = $this -> require_permission('scripts.edit')) { return $auth; } + + if(!preg_match('/^[a-z0-9_]+$/', $timer_alias) || strlen($timer_alias) > 255) { + logging() -> warn('php:Scripts', 'Timer cancel failed: invalid alias', ['timer_alias' => $timer_alias]); + return $this -> utils() -> response_error("invalid_alias", ["timer_alias"]); + } + + $timers_model = new \SHServ\Models\Timers(); + $result = $timers_model -> cancel_by_alias($timer_alias); + + if(!$result) { + logging() -> warn('php:Scripts', 'Timer cancel failed', ['timer_alias' => $timer_alias]); + return $this -> utils() -> response_error("timer_not_found"); + } + + logging() -> info('php:Scripts', 'Timer cancelled', ['timer_alias' => $timer_alias]); + return $this -> utils() -> response_success(); + } + public function unassign_from_area($target_id) { if ($auth = $this -> require_permission('scripts.edit')) { return $auth; } if($target_id != intval($target_id) or intval($target_id) < 1) { diff --git a/server/SHServ/Entities/Script.php b/server/SHServ/Entities/Script.php index b7fe808..250bed6 100644 --- a/server/SHServ/Entities/Script.php +++ b/server/SHServ/Entities/Script.php @@ -12,8 +12,8 @@ public static $table_name = "scripts"; protected static $fields = [ - "id", "area_id", "uniq_name", "type", "state", - "create_at", "update_at" + "id", "area_id", "uniq_name", "type", "state", + "params_schema", "create_at", "update_at" ]; public function __construct(Int $id, Array $data = []){ diff --git a/server/SHServ/Helpers/ScriptParamsValidator.php b/server/SHServ/Helpers/ScriptParamsValidator.php new file mode 100644 index 0000000..c62dc79 --- /dev/null +++ b/server/SHServ/Helpers/ScriptParamsValidator.php @@ -0,0 +1,108 @@ + true, "errors" => [], "params" => $params]; + } + + $errors = []; + $validated = []; + + foreach($schema as $name => $config) { + $has_value = array_key_exists($name, $params); + + if(($config["required"] ?? false) && !$has_value) { + $errors[] = ["field" => $name, "error" => "required"]; + continue; + } + + if(!$has_value) { + if(array_key_exists("default", $config)) { + $validated[$name] = $config["default"]; + } + continue; + } + + $value = $params[$name]; + $type = $config["type"] ?? "text"; + $type_error = self::validate_type($name, $type, $value, $config); + + if($type_error) { + $errors[] = $type_error; + continue; + } + + $validated[$name] = $value; + } + + return [ + "ok" => empty($errors), + "errors" => $errors, + "params" => $validated, + ]; + } + + protected static function validate_type(String $name, String $type, $value, Array $config): ?Array { + switch($type) { + case "text": + case "textarea": + if(!is_string($value)) { + return ["field" => $name, "error" => "expected_string"]; + } + return null; + + case "number": + if(!self::is_numeric_value($value)) { + return ["field" => $name, "error" => "expected_number"]; + } + $num = (float) $value; + if(isset($config["min"]) && $num < (float)$config["min"]) { + return ["field" => $name, "error" => "min", "min" => $config["min"]]; + } + if(isset($config["max"]) && $num > (float)$config["max"]) { + return ["field" => $name, "error" => "max", "max" => $config["max"]]; + } + return null; + + case "range": + if(!self::is_numeric_value($value)) { + return ["field" => $name, "error" => "expected_number"]; + } + $num = (float) $value; + if(isset($config["min"]) && $num < (float)$config["min"]) { + return ["field" => $name, "error" => "min", "min" => $config["min"]]; + } + if(isset($config["max"]) && $num > (float)$config["max"]) { + return ["field" => $name, "error" => "max", "max" => $config["max"]]; + } + return null; + + case "select": + $options = array_keys($config["options"] ?? []); + if(!in_array($value, $options, true)) { + return ["field" => $name, "error" => "invalid_option"]; + } + return null; + + case "toggle": + if(!is_bool($value)) { + return ["field" => $name, "error" => "expected_bool"]; + } + return null; + + default: + return null; + } + } + + protected static function is_numeric_value($value): Bool { + return is_int($value) || is_float($value) || (is_string($value) && is_numeric($value)); + } +} diff --git a/server/SHServ/Middleware/ControlScripts.php b/server/SHServ/Middleware/ControlScripts.php index f922312..7b94e21 100644 --- a/server/SHServ/Middleware/ControlScripts.php +++ b/server/SHServ/Middleware/ControlScripts.php @@ -125,16 +125,24 @@ return true; } + protected static function ensureRegistry(): \SHServ\Middleware\ScriptsRegistry { + $app = app(); + if(!isset($app -> scripts_registry) || $app -> scripts_registry === null) { + $app -> scripts_registry = new \SHServ\Middleware\ScriptsRegistry(); + } + return $app -> scripts_registry; + } + public static function flush_statics(): void { - app() -> scripts_registry -> flush(); + self::ensureRegistry() -> flush(); } public static function get_regular_scripts(): Array { - return app() -> scripts_registry -> getRegularScripts(); + return self::ensureRegistry() -> getRegularScripts(); } public static function get_actions_scripts(): Array { - return app() -> scripts_registry -> getActionsScripts(); + return self::ensureRegistry() -> getActionsScripts(); } public function add_action_script(Array $attributes, callable $script): bool { diff --git a/server/SHServ/Middleware/ModesContext.php b/server/SHServ/Middleware/ModesContext.php new file mode 100644 index 0000000..be2bc8d --- /dev/null +++ b/server/SHServ/Middleware/ModesContext.php @@ -0,0 +1,62 @@ + model) { + $this -> model = new Modes(); + } + + if(!$this -> synced) { + $this -> model -> sync_registry_tags(); + $this -> synced = true; + } + + return $this -> model; + } + + public function is(String $tag): bool { + return $this -> model() -> is_active($tag); + } + + public function any(Array $tags): bool { + return $this -> model() -> any_active($tags); + } + + public function all(Array $tags): bool { + return $this -> model() -> all_active($tags); + } + + public function active(): Array { + return $this -> model() -> active_tags(); + } + + public function enable(String $tag): bool { + return $this -> model() -> enable($tag); + } + + public function disable(String $tag): bool { + return $this -> model() -> disable($tag); + } + + public function toggle(String $tag): bool { + if($this -> is($tag)) { + return $this -> disable($tag); + } + + return $this -> enable($tag); + } + + public function meta(String $tag): Array { + $definitions = \ControlScripts\ModesRegistry::definitions(); + + return $definitions[$tag] ?? [ "label" => $tag, "description" => "" ]; + } +} diff --git a/server/SHServ/Middleware/ScriptsRegistry.php b/server/SHServ/Middleware/ScriptsRegistry.php new file mode 100644 index 0000000..1f76aba --- /dev/null +++ b/server/SHServ/Middleware/ScriptsRegistry.php @@ -0,0 +1,32 @@ + []]; + + public function flush(): void { + $this->actions = []; + $this->regular = []; + $this->syncMap = ["connections" => []]; + } + + public function getRegularScripts(): array { + return $this->regular; + } + + public function getActionsScripts(): array { + return $this->actions; + } + + public function getSyncMap(): array { + return $this->syncMap; + } +} diff --git a/server/SHServ/Models/Modes.php b/server/SHServ/Models/Modes.php new file mode 100644 index 0000000..29a86bd --- /dev/null +++ b/server/SHServ/Models/Modes.php @@ -0,0 +1,133 @@ + thin_builder() -> select( + self::$table_name, + [ "tag" ], + [ [ "tag", "=", $tag ] ] + ); + + if(!$exists) { + $this -> thin_builder() -> insert( + self::$table_name, + [ "tag" => $tag, "is_active" => 0 ] + ); + } + } + } + + public function enable(String $tag): bool { + return $this -> set_state($tag, 1); + } + + public function disable(String $tag): bool { + return $this -> set_state($tag, 0); + } + + protected function set_state(String $tag, int $state): bool { + $result = $this -> thin_builder() -> update( + self::$table_name, + [ "is_active" => $state ], + [ [ "tag", "=", $tag ] ] + ); + + return (bool) $result; + } + + public function is_active(String $tag): bool { + $result = $this -> thin_builder() -> select( + self::$table_name, + [ "is_active" ], + [ [ "tag", "=", $tag ] ] + ); + + return !empty($result) && (int) $result[0]["is_active"] === 1; + } + + public function any_active(Array $tags): bool { + if(empty($tags)) { + return false; + } + + $result = $this -> thin_builder() -> select( + self::$table_name, + [ "tag" ], + [ + [ "tag", "IN", $tags ], + "AND", + [ "is_active", "=", 1 ] + ] + ); + + return !empty($result); + } + + public function all_active(Array $tags): bool { + if(empty($tags)) { + return false; + } + + $result = $this -> thin_builder() -> select( + self::$table_name, + [ "tag" ], + [ + [ "tag", "IN", $tags ], + "AND", + [ "is_active", "=", 1 ] + ] + ); + + return count($result) === count($tags); + } + + public function active_tags(): Array { + $result = $this -> thin_builder() -> select( + self::$table_name, + [ "tag" ], + [ [ "is_active", "=", 1 ] ] + ); + + return array_column($result ?: [], "tag"); + } + + public function list_all(): Array { + $rows = $this -> thin_builder() -> select( + self::$table_name, + [], + [], + [ "tag" ], + "ASC" + ); + + $definitions = \ControlScripts\ModesRegistry::definitions(); + $out = []; + + foreach($rows ?: [] as $row) { + $tag = $row["tag"]; + $meta = $definitions[$tag] ?? [ "label" => $tag, "description" => "" ]; + + $out[] = [ + "tag" => $tag, + "label" => $meta["label"], + "description" => $meta["description"] ?? "", + "is_active" => (bool) $row["is_active"], + "updated_at" => $row["updated_at"] + ]; + } + + return $out; + } +} diff --git a/server/SHServ/Models/Scripts.php b/server/SHServ/Models/Scripts.php index f3df08d..abfe9e6 100644 --- a/server/SHServ/Models/Scripts.php +++ b/server/SHServ/Models/Scripts.php @@ -164,6 +164,15 @@ "scope" => isset($script_from_control["attributes"]["classname"]) ? substr(strrchr($script_from_control["attributes"]["classname"], "\\"), 1) : null, ]; + // params_schema: runtime (registry) имеет приоритет над DB + if(isset($script_from_control["params_schema"])) { + $prepared["params_schema"] = $script_from_control["params_schema"]; + } elseif($script_entity && $script_entity -> params_schema) { + $prepared["params_schema"] = json_decode($script_entity -> params_schema, true); + } else { + $prepared["params_schema"] = null; + } + if($script_entity) { $prepared = array_merge($prepared, $script_entity -> to_array()); } else { @@ -175,7 +184,7 @@ public function get_scripts_list(String $type, Array $scripts): Array { $scripts_entities = $this -> select_scripts_by_aliases_types($type, array_keys($scripts)); - + $data = []; foreach($scripts as $alias => $script_data) { @@ -184,11 +193,37 @@ })); $data[] = $this -> prepare_script_to_view($type, $script_data, $script_entity[0] ?? null); + + // Lazy sync: обновить params_schema в БД если runtime schema изменилась + if(isset($script_data["params_schema"])) { + $this -> sync_params_schema_to_db($type, $alias, $script_data["params_schema"]); + } } return $data; } + protected function sync_params_schema_to_db(String $type, String $uniq_name, ?Array $schema): void { + $result = $this -> thin_builder() -> select( + Script::$table_name, + ["id", "params_schema"], + [["type", "=", $type], "AND", ["uniq_name", '=', $uniq_name]] + ); + + if(!$result) { + return; + } + + $encoded = $schema ? json_encode($schema, JSON_UNESCAPED_UNICODE) : null; + if($result[0]["params_schema"] !== $encoded) { + $this -> thin_builder() -> update( + Script::$table_name, + ["params_schema" => $encoded], + [["id", "=", $result[0]["id"]]] + ); + } + } + public function scope_is_exists(String $name): Bool { $instances = app() -> control_scripts_instances; diff --git a/server/SHServ/Models/Timers.php b/server/SHServ/Models/Timers.php new file mode 100644 index 0000000..c682535 --- /dev/null +++ b/server/SHServ/Models/Timers.php @@ -0,0 +1,124 @@ + thin_builder() -> select( + self::$table_name, + [ "id" ], + [ + [ "timer_alias", "=", $timer_alias ], + "AND", + [ "scope_name", "=", $scope_name ], + "AND", + [ "status", "=", "pending" ] + ] + ); + + if($existing) { + $this -> thin_builder() -> update( + self::$table_name, + [ "status" => "cancelled" ], + [ [ "id", "=", $existing[0]["id"] ] ] + ); + } + + return $this -> thin_builder() -> insert( + self::$table_name, + [ + "timer_alias" => $timer_alias, + "scope_name" => $scope_name, + "target_type" => $target_type, + "target_alias" => $target_alias, + "params" => json_encode($params), + "execute_at" => date("Y-m-d H:i:s", $execute_at), + "status" => "pending", + "created_at" => date("Y-m-d H:i:s") + ] + ); + } + + public function cancel_timer(String $timer_alias, String $scope_name): bool { + return $this -> thin_builder() -> update( + self::$table_name, + [ "status" => "cancelled" ], + [ + [ "timer_alias", "=", $timer_alias ], + "AND", + [ "scope_name", "=", $scope_name ], + "AND", + [ "status", "=", "pending" ] + ] + ); + } + + public function cancel_by_alias(String $timer_alias): bool { + return $this -> thin_builder() -> update( + self::$table_name, + [ "status" => "cancelled" ], + [ + [ "timer_alias", "=", $timer_alias ], + "AND", + [ "status", "=", "pending" ] + ] + ); + } + + public function get_pending_timers(): Array { + $result = $this -> thin_builder() -> select( + self::$table_name, + [], + [ + [ "status", "=", "pending" ], + "AND", + [ "execute_at", "<=", date("Y-m-d H:i:s") ] + ], + [ "execute_at" ], + "ASC" + ); + + return $result ?: []; + } + + public function mark_status(int $id, String $status, ?String $error_message = null): bool { + $data = [ "status" => $status ]; + + if($status === "executed") { + $data["executed_at"] = date("Y-m-d H:i:s"); + } + + if($error_message !== null) { + $data["error_message"] = $error_message; + } + + return $this -> thin_builder() -> update( + self::$table_name, + $data, + [ [ "id", "=", $id ] ] + ); + } + + public function get_timers(?String $status = null, int $limit = 100): Array { + $where = []; + + if($status !== null) { + $where = [ [ "status", "=", $status ] ]; + } + + $result = $this -> thin_builder() -> select( + self::$table_name, + [], + $where, + [ "created_at" ], + "DESC", + [ 0, $limit ] + ); + + return $result ?: []; + } +} diff --git a/server/SHServ/Routes.php b/server/SHServ/Routes.php index 08f76c6..5103d32 100644 --- a/server/SHServ/Routes.php +++ b/server/SHServ/Routes.php @@ -7,6 +7,7 @@ use \SHServ\Routes\DevMode; use \SHServ\Routes\DevicesRESTAPI_v1; use \SHServ\Routes\ScriptsRESTAPI_v1; + use \SHServ\Routes\ModesRESTAPI_v1; use \SHServ\Routes\AreasRESTAPI_v1; use \SHServ\Routes\FirmwareRESTAPI_v1; @@ -44,6 +45,10 @@ $this -> scripts_restapi_get_routes(); $this -> scripts_restapi_post_routes(); + $this -> modes_restapi_uri_routes(); + $this -> modes_restapi_get_routes(); + $this -> modes_restapi_post_routes(); + $this -> areas_restapi_uri_routes(); $this -> areas_restapi_get_routes(); $this -> areas_restapi_post_routes(); diff --git a/server/SHServ/Routes/ModesRESTAPI_v1.php b/server/SHServ/Routes/ModesRESTAPI_v1.php new file mode 100644 index 0000000..77b6867 --- /dev/null +++ b/server/SHServ/Routes/ModesRESTAPI_v1.php @@ -0,0 +1,20 @@ + router -> uri("/api/v1/modes/list", "{$this -> cn}\\ModesRESTAPIController@list_all"); + $this -> router -> uri("/api/v1/modes/active", "{$this -> cn}\\ModesRESTAPIController@active"); + $this -> router -> uri('/api/v1/modes/$tag/enable', "{$this -> cn}\\ModesRESTAPIController@enable"); + $this -> router -> uri('/api/v1/modes/$tag/disable', "{$this -> cn}\\ModesRESTAPIController@disable"); + } + + protected function modes_restapi_get_routes() { + + } + + protected function modes_restapi_post_routes() { + + } +} diff --git a/server/SHServ/Routes/ScriptsRESTAPI_v1.php b/server/SHServ/Routes/ScriptsRESTAPI_v1.php index 14e91b7..b08391f 100644 --- a/server/SHServ/Routes/ScriptsRESTAPI_v1.php +++ b/server/SHServ/Routes/ScriptsRESTAPI_v1.php @@ -13,6 +13,7 @@ $this -> router -> uri('/api/v1/scripts/scopes/name/$uniq_name/$state', "{$this -> cn}\\ScriptsRESTAPIController@set_scope_state"); $this -> router -> uri('/api/v1/scripts/regular/alias/$uniq_name/$state', "{$this -> cn}\\ScriptsRESTAPIController@set_regular_script_state"); $this -> router -> uri('/api/v1/scripts/id/$target_id/unassign-from-area', "{$this -> cn}\\ScriptsRESTAPIController@unassign_from_area"); + $this -> router -> uri('/api/v1/scripts/timers/list', "{$this -> cn}\\ScriptsRESTAPIController@timers_list"); } protected function scripts_restapi_post_routes() { @@ -28,6 +29,17 @@ "/api/v1/scripts/place-in-area" ); + $this -> router -> post( + [ "name", "source" ], + "{$this -> cn}\\ScriptsRESTAPIController@scope_update", + '/api/v1/scripts/scopes/update' + ); + + $this -> router -> post( + [ "timer_alias" ], + "{$this -> cn}\\ScriptsRESTAPIController@timers_cancel", + '/api/v1/scripts/timers/cancel' + ); } protected function scripts_restapi_get_routes() { diff --git a/server/console.php b/server/console.php index 44c0d06..b265cae 100644 --- a/server/console.php +++ b/server/console.php @@ -1,5 +1,6 @@ thin_builder; + $migrationsDir = __DIR__ . "/database/migrations"; + + $tb->query(" + CREATE TABLE IF NOT EXISTS shserv_migrations ( + file_name VARCHAR(255) PRIMARY KEY, + applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci + "); + + $appliedRows = $tb->select("shserv_migrations", ["file_name"]); + $applied = array_column($appliedRows, "file_name"); + $files = glob($migrationsDir . "/*.php"); + sort($files); + + foreach($files as $file) { + $baseName = basename($file); + if(in_array($baseName, $applied)) { + echo "[SKIP] {$baseName}\n"; + continue; + } + $migration = include $file; + if(is_callable($migration)) { + $result = $migration($tb); + if($result) { + $tb->insert("shserv_migrations", ["file_name" => $baseName]); + echo "[OK] {$baseName}\n"; + } else { + echo "[FAIL] {$baseName}\n"; + } + } else { + echo "[SKIP] {$baseName} (not callable)\n"; + } + } + echo "\nDone.\n"; + break; + default: echo "\nNo command"; } diff --git a/server/database/migrations/2026_06_08_000001_script_timers.php b/server/database/migrations/2026_06_08_000001_script_timers.php new file mode 100644 index 0000000..1d69674 --- /dev/null +++ b/server/database/migrations/2026_06_08_000001_script_timers.php @@ -0,0 +1,30 @@ +query(" + CREATE TABLE IF NOT EXISTS shserv_timers ( + id INT AUTO_INCREMENT PRIMARY KEY, + timer_alias VARCHAR(100) NOT NULL, + scope_name VARCHAR(100) NOT NULL, + target_type ENUM('action', 'event', 'regular') NOT NULL, + target_alias VARCHAR(100) NOT NULL, + params JSON, + execute_at DATETIME NOT NULL, + status ENUM('pending', 'executed', 'cancelled', 'failed') NOT NULL DEFAULT 'pending', + error_message TEXT, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + executed_at TIMESTAMP NULL, + UNIQUE KEY uk_alias_scope (timer_alias, scope_name), + INDEX idx_status_execute (status, execute_at), + INDEX idx_scope (scope_name) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci + "); + + return true; +}; diff --git a/server/database/migrations/2026_06_08_000002_modes.php b/server/database/migrations/2026_06_08_000002_modes.php new file mode 100644 index 0000000..ce7fbb0 --- /dev/null +++ b/server/database/migrations/2026_06_08_000002_modes.php @@ -0,0 +1,19 @@ +query(" + CREATE TABLE IF NOT EXISTS shserv_modes ( + tag VARCHAR(32) PRIMARY KEY, + is_active TINYINT(1) NOT NULL DEFAULT 0, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci + "); + + return true; +}; diff --git a/server/database/migrations/2026_06_08_000003_script_params_schema.php b/server/database/migrations/2026_06_08_000003_script_params_schema.php new file mode 100644 index 0000000..dd75eb7 --- /dev/null +++ b/server/database/migrations/2026_06_08_000003_script_params_schema.php @@ -0,0 +1,16 @@ +query(" + ALTER TABLE scripts + ADD COLUMN params_schema TEXT NULL + "); + + return true; +}; diff --git a/server/dist/assets/NotFoundPage-B9uWKSBX.js b/server/dist/assets/NotFoundPage-B9uWKSBX.js deleted file mode 100644 index 814611a..0000000 --- a/server/dist/assets/NotFoundPage-B9uWKSBX.js +++ /dev/null @@ -1 +0,0 @@ -import{c as e,a as t,u as o,G as a,o as n}from"./index-BxlltLEk.js";const s={class:"page"},u={__name:"NotFoundPage",setup(c){return(r,_)=>(n(),e("section",s,[t(o(a),{title:"Not Found",text:"The page you are looking for does not exist.",icon:"ph-warning"})]))}};export{u as default}; diff --git a/server/dist/assets/NotFoundPage-YUIFZ53x.js b/server/dist/assets/NotFoundPage-YUIFZ53x.js new file mode 100644 index 0000000..97cf666 --- /dev/null +++ b/server/dist/assets/NotFoundPage-YUIFZ53x.js @@ -0,0 +1 @@ +import{c as e,a as t,u as o,G as a,o as n}from"./index-C4kiMKve.js";const s={class:"page"},u={__name:"NotFoundPage",setup(c){return(r,_)=>(n(),e("section",s,[t(o(a),{title:"Not Found",text:"The page you are looking for does not exist.",icon:"ph-warning"})]))}};export{u as default}; diff --git a/server/dist/assets/index-B6faREVT.css b/server/dist/assets/index-B6faREVT.css deleted file mode 100644 index 99e93ac..0000000 --- a/server/dist/assets/index-B6faREVT.css +++ /dev/null @@ -1 +0,0 @@ -@charset "UTF-8";.nav-topbar-brand img{width:50px!important;height:50px!important}.error-meta[data-v-f1e6bcb8]{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}.error-actions[data-v-f1e6bcb8]{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-top:12px}.error-boundary[data-v-1e10ea7f]{padding:24px}.area-favorites-list[data-v-f8795944]{display:grid;gap:12px;margin:0;padding:0;list-style:none}.area-favorite-card[data-v-f8795944]{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:14px;padding:14px 16px;border:1px solid rgba(192,202,245,.12);background:var(--color-panel);cursor:pointer;transition:background .15s ease}.area-favorite-card[data-v-f8795944]:hover{background:var(--color-panel-strong)}.area-favorite-icon[data-v-f8795944]{display:flex;align-items:center;justify-content:center;width:40px;height:40px;border:2px solid var(--color-primary);color:var(--color-primary);font-size:20px}.area-favorite-info[data-v-f8795944]{min-width:0}.area-favorite-title[data-v-f8795944]{margin:0 0 6px;font-size:18px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.area-favorite-meta[data-v-f8795944]{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin:0;color:var(--color-muted);font-size:13px}.area-favorite-parent[data-v-f8795944]{color:var(--color-muted)}.area-favorite-parent .parent-link[data-v-f8795944]{color:var(--color-primary);text-decoration:none}.area-favorite-parent .parent-link[data-v-f8795944]:hover{text-decoration:underline}@media(max-width:720px){.area-favorite-card[data-v-f8795944]{grid-template-columns:auto 1fr;gap:12px}.area-favorite-actions[data-v-f8795944]{grid-column:1 / -1;justify-self:end}}.form-group[data-v-5f02f384]{margin-bottom:16px}.area-link[data-v-91230b95]{text-decoration:none}.devices-panel[data-v-92cae82c]{margin-bottom:24px}.block-title[data-v-92cae82c]{font-weight:700;text-transform:uppercase;margin-bottom:12px;color:var(--color-primary)}.area-assigned[data-v-92cae82c]{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.area-card[data-v-92cae82c]{display:flex;align-items:center;gap:10px;padding:10px 14px;background:var(--color-panel);border:1px solid rgba(192,202,245,.12);color:inherit;text-decoration:none;transition:border-color .15s}.area-card[data-v-92cae82c]:hover{border-color:var(--color-primary)}.area-card-icon[data-v-92cae82c]{font-size:20px}.area-card-info[data-v-92cae82c]{display:flex;flex-direction:column;gap:2px}.area-card-info small[data-v-92cae82c]{font-size:12px}.form-group[data-v-92cae82c]{margin-bottom:16px}.device-channels-state[data-v-08541c71]{display:inline-flex;align-items:center}.channels-grid[data-v-08541c71]{display:inline-flex;flex-wrap:wrap;gap:6px;align-items:center}.unknown-type[data-v-08541c71]{font-size:12px}.raw-json[data-v-08541c71]{font-size:10px;margin:4px 0 0;max-width:400px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.device-cell[data-v-32549911]{display:flex;align-items:center;gap:10px}.device-icon[data-v-32549911]{font-size:20px}.device-info[data-v-32549911]{display:flex;flex-direction:column;gap:2px}.device-name-row[data-v-32549911]{display:inline-flex;align-items:center;gap:6px}.status-dot[data-v-32549911]{display:inline-block;width:8px;height:8px;border-radius:50%;flex-shrink:0;background:currentColor;box-shadow:0 0 4px currentColor}.device-info small[data-v-32549911]{font-size:12px}.device-link[data-v-32549911]{color:inherit;text-decoration:none}.device-link:hover strong[data-v-32549911]{color:var(--color-primary)}.script-link[data-v-1ead75a7]{color:var(--color-primary);text-decoration:none}.scope-link[data-v-1ead75a7]{display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border:1px solid var(--color-primary);color:var(--color-primary);text-decoration:none;font-size:13px;cursor:pointer;transition:background .15s,color .15s}.scope-link[data-v-1ead75a7]:hover{background:var(--color-primary);color:var(--color-bg)}.scope-label[data-v-1ead75a7]{text-transform:uppercase;font-size:11px;font-weight:700;opacity:.8}.muted[data-v-1ead75a7]{color:var(--color-muted)}.page-header:has(>.page-header-actions .page-actions-dropdown){overflow:visible}.page-actions-dropdown .btn-icon{width:44px;height:44px;font-size:24px}.page-actions-dropdown .dropdown-menu{left:auto;right:0;transform-origin:top right}.script-icon[data-v-aeab265d]{font-size:32px}.script-meta[data-v-aeab265d]{display:flex;flex-wrap:wrap;gap:8px;align-items:center}.area-meta[data-v-757a0469]{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:24px}.area-parent[data-v-757a0469]{color:var(--color-muted)}.actions-panel[data-v-757a0469],.devices-panel[data-v-757a0469],.scripts-panel[data-v-757a0469]{margin-bottom:24px}.block-title[data-v-757a0469]{font-weight:700;text-transform:uppercase;margin-bottom:12px;color:var(--color-primary)}.form-group[data-v-757a0469]{margin-bottom:16px}.devices-summary[data-v-635f3900]{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:12px}.scan-filters[data-v-1a01bb19]{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-bottom:24px}.filter-label[data-v-1a01bb19]{font-size:13px;text-transform:uppercase}.devices-summary[data-v-1a01bb19]{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:12px}.device-cell[data-v-1a01bb19]{display:flex;align-items:center;gap:10px}.device-icon[data-v-1a01bb19]{font-size:20px;color:var(--color-primary)}.device-info[data-v-1a01bb19]{display:flex;flex-direction:column;gap:2px}.device-info small[data-v-1a01bb19]{color:var(--color-muted);font-size:12px}.firmware[data-v-1a01bb19]{font-size:12px;color:var(--color-muted)}.muted[data-v-1a01bb19]{color:var(--color-muted)}.form-group[data-v-1a01bb19]{margin-bottom:16px}.device-meta[data-v-a9f83185]{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:24px}.script-info-panel[data-v-a9f83185]{display:grid;gap:8px;padding:12px;background:var(--color-panel);border:1px solid rgba(192,202,245,.12);margin-bottom:24px}.info-row[data-v-a9f83185]{display:flex;gap:8px;align-items:baseline}.info-label[data-v-a9f83185]{font-size:12px;text-transform:uppercase;min-width:48px}.info-value[data-v-a9f83185]{font-size:13px;word-break:break-all}.devices-panel[data-v-a9f83185]{margin-bottom:24px}.block-title[data-v-a9f83185]{font-weight:700;text-transform:uppercase;margin-bottom:12px;color:var(--color-primary)}.form-group[data-v-a9f83185]{margin-bottom:16px}.firmware-options[data-v-a9f83185]{display:grid;gap:8px;margin:12px 0}.firmware-option[data-v-a9f83185]{padding:10px 12px;border:1px solid rgba(192,202,245,.12);border-radius:6px;cursor:pointer;background:var(--color-panel)}.firmware-option.active[data-v-a9f83185]{border-color:var(--color-primary);background:#3b82f61a}.fw-version[data-v-a9f83185]{font-weight:600;font-size:13px}.fw-desc[data-v-a9f83185]{font-size:12px;color:var(--color-text-muted);margin-top:2px}.result-alert[data-v-f336617a]{margin-top:24px}.script-link[data-v-c8486788]{color:var(--color-primary)}.script-detail-meta[data-v-31cd836e]{display:flex;flex-direction:column;gap:16px;margin-bottom:24px}.script-icon[data-v-31cd836e]{font-size:32px}.script-meta[data-v-31cd836e]{display:flex;flex-wrap:wrap;gap:8px;align-items:center}.result-alert[data-v-31cd836e]{margin-top:24px}.devices-panel[data-v-31cd836e]{margin-bottom:24px}.block-title[data-v-31cd836e]{font-weight:700;text-transform:uppercase;margin-bottom:12px;color:var(--color-primary)}.script-link[data-v-31cd836e]{color:var(--color-primary)}.scope-link[data-v-31cd836e]{display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border:1px solid var(--color-primary);color:var(--color-primary);text-decoration:none;font-size:13px;cursor:pointer;transition:background .15s,color .15s}.scope-link[data-v-31cd836e]:hover{background:var(--color-primary);color:var(--color-bg)}.scope-label[data-v-31cd836e]{text-transform:uppercase;font-size:11px;font-weight:700;opacity:.8}.script-info-panel[data-v-31cd836e]{display:grid;gap:8px;padding:12px;background:var(--color-panel);border:1px solid rgba(192,202,245,.12)}.info-row[data-v-31cd836e]{display:flex;gap:8px;align-items:baseline}.info-label[data-v-31cd836e]{font-size:12px;text-transform:uppercase;min-width:48px}.info-value[data-v-31cd836e]{font-size:13px;word-break:break-all}.code-block[data-v-31cd836e]{margin:0;padding:14px;overflow-x:auto}.firmwares-summary[data-v-c0c73f70]{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:12px}.firmwares-list[data-v-c0c73f70]{display:grid;gap:12px}.firmware-card[data-v-c0c73f70]{background:var(--color-panel);border:1px solid rgba(192,202,245,.12);border-radius:8px;padding:12px 16px}.firmware-header[data-v-c0c73f70]{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}.firmware-id[data-v-c0c73f70]{font-family:monospace;font-size:13px;word-break:break-all}.firmware-meta[data-v-c0c73f70]{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:8px}.firmware-desc[data-v-c0c73f70]{font-size:13px;color:var(--color-text-muted);margin:0}.firmware-changelog[data-v-c0c73f70]{font-size:12px;background:#0f172a80;padding:8px;border-radius:6px;margin-top:8px;white-space:pre-wrap;word-break:break-word}.login-page[data-v-7f18a357]{display:flex;align-items:center;justify-content:center;min-height:100vh;padding:1rem}.login-card[data-v-7f18a357]{display:flex;flex-direction:column;align-items:center;gap:1.5rem;max-width:360px;width:100%;padding:2rem;text-align:center}.login-brand[data-v-7f18a357]{display:flex;flex-direction:column;align-items:center;gap:.5rem}.brand-logo[data-v-7f18a357]{width:120px;height:120px}.brand-title[data-v-7f18a357]{margin:0;font-size:1.25rem;font-weight:700}.login-hint[data-v-7f18a357]{margin:0;font-size:.875rem;line-height:1.5}.login-btn[data-v-7f18a357]{width:100%}.login-loading[data-v-7f18a357]{margin:0;font-size:.8125rem;display:flex;align-items:center;gap:.375rem}.setup-page[data-v-a50065c7]{display:flex;align-items:center;justify-content:center;min-height:100vh;padding:1rem}.setup-card[data-v-a50065c7]{display:flex;flex-direction:column;align-items:center;gap:1.5rem;max-width:360px;width:100%;padding:2rem;text-align:center}.setup-brand[data-v-a50065c7]{display:flex;flex-direction:column;align-items:center;gap:.5rem}.brand-logo[data-v-a50065c7]{width:120px;height:120px}.brand-title[data-v-a50065c7]{margin:0;font-size:1.25rem;font-weight:700}.brand-subtitle[data-v-a50065c7]{margin:0;font-size:.875rem}.setup-divider[data-v-a50065c7]{width:48px;height:2px;background:currentColor;border-radius:1px}.setup-hint[data-v-a50065c7]{margin:0;font-size:.875rem;line-height:1.5}.setup-form[data-v-a50065c7]{display:flex;flex-direction:column;gap:1rem;width:100%}.setup-btn[data-v-a50065c7]{width:100%}.setup-error[data-v-a50065c7]{margin:0;font-size:.875rem;display:flex;align-items:center;gap:.375rem}.mobile-auth-page[data-v-9c0afc74]{display:flex;align-items:center;justify-content:center;min-height:100vh;padding:1rem}.mobile-auth-card[data-v-9c0afc74]{display:flex;flex-direction:column;align-items:center;gap:1rem;text-align:center}.spinner[data-v-9c0afc74]{width:40px;height:40px;border:3px solid rgba(255,255,255,.2);border-top-color:#12b7f5;border-radius:50%;animation:spin-9c0afc74 1s linear infinite}@keyframes spin-9c0afc74{to{transform:rotate(360deg)}}@font-face{font-family:Phosphor;src:url(/assets/Phosphor-DtdjzkpE.woff2) format("woff2"),url(/assets/Phosphor-BdqudwT5.woff) format("woff"),url(/assets/Phosphor-CDxgqcPu.ttf) format("truetype"),url(/assets/Phosphor-BXRFlF4V.svg#Phosphor) format("svg");font-weight:400;font-style:normal;font-display:block}.ph{font-family:Phosphor!important;speak:never;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;letter-spacing:0;-webkit-font-feature-settings:"liga";-moz-font-feature-settings:"liga=1";-moz-font-feature-settings:"liga";-ms-font-feature-settings:"liga" 1;font-feature-settings:"liga";-webkit-font-variant-ligatures:discretionary-ligatures;font-variant-ligatures:discretionary-ligatures;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.ph.ph-acorn:before{content:""}.ph.ph-address-book:before{content:""}.ph.ph-address-book-tabs:before{content:""}.ph.ph-air-traffic-control:before{content:""}.ph.ph-airplane:before{content:""}.ph.ph-airplane-in-flight:before{content:""}.ph.ph-airplane-landing:before{content:""}.ph.ph-airplane-takeoff:before{content:""}.ph.ph-airplane-taxiing:before{content:""}.ph.ph-airplane-tilt:before{content:""}.ph.ph-airplay:before{content:""}.ph.ph-alarm:before{content:""}.ph.ph-alien:before{content:""}.ph.ph-align-bottom:before{content:""}.ph.ph-align-bottom-simple:before{content:""}.ph.ph-align-center-horizontal:before{content:""}.ph.ph-align-center-horizontal-simple:before{content:""}.ph.ph-align-center-vertical:before{content:""}.ph.ph-align-center-vertical-simple:before{content:""}.ph.ph-align-left:before{content:""}.ph.ph-align-left-simple:before{content:""}.ph.ph-align-right:before{content:""}.ph.ph-align-right-simple:before{content:""}.ph.ph-align-top:before{content:""}.ph.ph-align-top-simple:before{content:""}.ph.ph-amazon-logo:before{content:""}.ph.ph-ambulance:before{content:""}.ph.ph-anchor:before{content:""}.ph.ph-anchor-simple:before{content:""}.ph.ph-android-logo:before{content:""}.ph.ph-angle:before{content:""}.ph.ph-angular-logo:before{content:""}.ph.ph-aperture:before{content:""}.ph.ph-app-store-logo:before{content:""}.ph.ph-app-window:before{content:""}.ph.ph-apple-logo:before{content:""}.ph.ph-apple-podcasts-logo:before{content:""}.ph.ph-approximate-equals:before{content:""}.ph.ph-archive:before{content:""}.ph.ph-armchair:before{content:""}.ph.ph-arrow-arc-left:before{content:""}.ph.ph-arrow-arc-right:before{content:""}.ph.ph-arrow-bend-double-up-left:before{content:""}.ph.ph-arrow-bend-double-up-right:before{content:""}.ph.ph-arrow-bend-down-left:before{content:""}.ph.ph-arrow-bend-down-right:before{content:""}.ph.ph-arrow-bend-left-down:before{content:""}.ph.ph-arrow-bend-left-up:before{content:""}.ph.ph-arrow-bend-right-down:before{content:""}.ph.ph-arrow-bend-right-up:before{content:""}.ph.ph-arrow-bend-up-left:before{content:""}.ph.ph-arrow-bend-up-right:before{content:""}.ph.ph-arrow-circle-down:before{content:""}.ph.ph-arrow-circle-down-left:before{content:""}.ph.ph-arrow-circle-down-right:before{content:""}.ph.ph-arrow-circle-left:before{content:""}.ph.ph-arrow-circle-right:before{content:""}.ph.ph-arrow-circle-up:before{content:""}.ph.ph-arrow-circle-up-left:before{content:""}.ph.ph-arrow-circle-up-right:before{content:""}.ph.ph-arrow-clockwise:before{content:""}.ph.ph-arrow-counter-clockwise:before{content:""}.ph.ph-arrow-down:before{content:""}.ph.ph-arrow-down-left:before{content:""}.ph.ph-arrow-down-right:before{content:""}.ph.ph-arrow-elbow-down-left:before{content:""}.ph.ph-arrow-elbow-down-right:before{content:""}.ph.ph-arrow-elbow-left:before{content:""}.ph.ph-arrow-elbow-left-down:before{content:""}.ph.ph-arrow-elbow-left-up:before{content:""}.ph.ph-arrow-elbow-right:before{content:""}.ph.ph-arrow-elbow-right-down:before{content:""}.ph.ph-arrow-elbow-right-up:before{content:""}.ph.ph-arrow-elbow-up-left:before{content:""}.ph.ph-arrow-elbow-up-right:before{content:""}.ph.ph-arrow-fat-down:before{content:""}.ph.ph-arrow-fat-left:before{content:""}.ph.ph-arrow-fat-line-down:before{content:""}.ph.ph-arrow-fat-line-left:before{content:""}.ph.ph-arrow-fat-line-right:before{content:""}.ph.ph-arrow-fat-line-up:before{content:""}.ph.ph-arrow-fat-lines-down:before{content:""}.ph.ph-arrow-fat-lines-left:before{content:""}.ph.ph-arrow-fat-lines-right:before{content:""}.ph.ph-arrow-fat-lines-up:before{content:""}.ph.ph-arrow-fat-right:before{content:""}.ph.ph-arrow-fat-up:before{content:""}.ph.ph-arrow-left:before{content:""}.ph.ph-arrow-line-down:before{content:""}.ph.ph-arrow-line-down-left:before{content:""}.ph.ph-arrow-line-down-right:before{content:""}.ph.ph-arrow-line-left:before{content:""}.ph.ph-arrow-line-right:before{content:""}.ph.ph-arrow-line-up:before{content:""}.ph.ph-arrow-line-up-left:before{content:""}.ph.ph-arrow-line-up-right:before{content:""}.ph.ph-arrow-right:before{content:""}.ph.ph-arrow-square-down:before{content:""}.ph.ph-arrow-square-down-left:before{content:""}.ph.ph-arrow-square-down-right:before{content:""}.ph.ph-arrow-square-in:before{content:""}.ph.ph-arrow-square-left:before{content:""}.ph.ph-arrow-square-out:before{content:""}.ph.ph-arrow-square-right:before{content:""}.ph.ph-arrow-square-up:before{content:""}.ph.ph-arrow-square-up-left:before{content:""}.ph.ph-arrow-square-up-right:before{content:""}.ph.ph-arrow-u-down-left:before{content:""}.ph.ph-arrow-u-down-right:before{content:""}.ph.ph-arrow-u-left-down:before{content:""}.ph.ph-arrow-u-left-up:before{content:""}.ph.ph-arrow-u-right-down:before{content:""}.ph.ph-arrow-u-right-up:before{content:""}.ph.ph-arrow-u-up-left:before{content:""}.ph.ph-arrow-u-up-right:before{content:""}.ph.ph-arrow-up:before{content:""}.ph.ph-arrow-up-left:before{content:""}.ph.ph-arrow-up-right:before{content:""}.ph.ph-arrows-clockwise:before{content:""}.ph.ph-arrows-counter-clockwise:before{content:""}.ph.ph-arrows-down-up:before{content:""}.ph.ph-arrows-horizontal:before{content:""}.ph.ph-arrows-in:before{content:""}.ph.ph-arrows-in-cardinal:before{content:""}.ph.ph-arrows-in-line-horizontal:before{content:""}.ph.ph-arrows-in-line-vertical:before{content:""}.ph.ph-arrows-in-simple:before{content:""}.ph.ph-arrows-left-right:before{content:""}.ph.ph-arrows-merge:before{content:""}.ph.ph-arrows-out:before{content:""}.ph.ph-arrows-out-cardinal:before{content:""}.ph.ph-arrows-out-line-horizontal:before{content:""}.ph.ph-arrows-out-line-vertical:before{content:""}.ph.ph-arrows-out-simple:before{content:""}.ph.ph-arrows-split:before{content:""}.ph.ph-arrows-vertical:before{content:""}.ph.ph-article:before{content:""}.ph.ph-article-medium:before{content:""}.ph.ph-article-ny-times:before{content:""}.ph.ph-asclepius:before{content:""}.ph.ph-caduceus:before{content:""}.ph.ph-asterisk:before{content:""}.ph.ph-asterisk-simple:before{content:""}.ph.ph-at:before{content:""}.ph.ph-atom:before{content:""}.ph.ph-avocado:before{content:""}.ph.ph-axe:before{content:""}.ph.ph-baby:before{content:""}.ph.ph-baby-carriage:before{content:""}.ph.ph-backpack:before{content:""}.ph.ph-backspace:before{content:""}.ph.ph-bag:before{content:""}.ph.ph-bag-simple:before{content:""}.ph.ph-balloon:before{content:""}.ph.ph-bandaids:before{content:""}.ph.ph-bank:before{content:""}.ph.ph-barbell:before{content:""}.ph.ph-barcode:before{content:""}.ph.ph-barn:before{content:""}.ph.ph-barricade:before{content:""}.ph.ph-baseball:before{content:""}.ph.ph-baseball-cap:before{content:""}.ph.ph-baseball-helmet:before{content:""}.ph.ph-basket:before{content:""}.ph.ph-basketball:before{content:""}.ph.ph-bathtub:before{content:""}.ph.ph-battery-charging:before{content:""}.ph.ph-battery-charging-vertical:before{content:""}.ph.ph-battery-empty:before{content:""}.ph.ph-battery-full:before{content:""}.ph.ph-battery-high:before{content:""}.ph.ph-battery-low:before{content:""}.ph.ph-battery-medium:before{content:""}.ph.ph-battery-plus:before{content:""}.ph.ph-battery-plus-vertical:before{content:""}.ph.ph-battery-vertical-empty:before{content:""}.ph.ph-battery-vertical-full:before{content:""}.ph.ph-battery-vertical-high:before{content:""}.ph.ph-battery-vertical-low:before{content:""}.ph.ph-battery-vertical-medium:before{content:""}.ph.ph-battery-warning:before{content:""}.ph.ph-battery-warning-vertical:before{content:""}.ph.ph-beach-ball:before{content:""}.ph.ph-beanie:before{content:""}.ph.ph-bed:before{content:""}.ph.ph-beer-bottle:before{content:""}.ph.ph-beer-stein:before{content:""}.ph.ph-behance-logo:before{content:""}.ph.ph-bell:before{content:""}.ph.ph-bell-ringing:before{content:""}.ph.ph-bell-simple:before{content:""}.ph.ph-bell-simple-ringing:before{content:""}.ph.ph-bell-simple-slash:before{content:""}.ph.ph-bell-simple-z:before{content:""}.ph.ph-bell-slash:before{content:""}.ph.ph-bell-z:before{content:""}.ph.ph-belt:before{content:""}.ph.ph-bezier-curve:before{content:""}.ph.ph-bicycle:before{content:""}.ph.ph-binary:before{content:""}.ph.ph-binoculars:before{content:""}.ph.ph-biohazard:before{content:""}.ph.ph-bird:before{content:""}.ph.ph-blueprint:before{content:""}.ph.ph-bluetooth:before{content:""}.ph.ph-bluetooth-connected:before{content:""}.ph.ph-bluetooth-slash:before{content:""}.ph.ph-bluetooth-x:before{content:""}.ph.ph-boat:before{content:""}.ph.ph-bomb:before{content:""}.ph.ph-bone:before{content:""}.ph.ph-book:before{content:""}.ph.ph-book-bookmark:before{content:""}.ph.ph-book-open:before{content:""}.ph.ph-book-open-text:before{content:""}.ph.ph-book-open-user:before{content:""}.ph.ph-bookmark:before{content:""}.ph.ph-bookmark-simple:before{content:""}.ph.ph-bookmarks:before{content:""}.ph.ph-bookmarks-simple:before{content:""}.ph.ph-books:before{content:""}.ph.ph-boot:before{content:""}.ph.ph-boules:before{content:""}.ph.ph-bounding-box:before{content:""}.ph.ph-bowl-food:before{content:""}.ph.ph-bowl-steam:before{content:""}.ph.ph-bowling-ball:before{content:""}.ph.ph-box-arrow-down:before{content:""}.ph.ph-archive-box:before{content:""}.ph.ph-box-arrow-up:before{content:""}.ph.ph-boxing-glove:before{content:""}.ph.ph-brackets-angle:before{content:""}.ph.ph-brackets-curly:before{content:""}.ph.ph-brackets-round:before{content:""}.ph.ph-brackets-square:before{content:""}.ph.ph-brain:before{content:""}.ph.ph-brandy:before{content:""}.ph.ph-bread:before{content:""}.ph.ph-bridge:before{content:""}.ph.ph-briefcase:before{content:""}.ph.ph-briefcase-metal:before{content:""}.ph.ph-broadcast:before{content:""}.ph.ph-broom:before{content:""}.ph.ph-browser:before{content:""}.ph.ph-browsers:before{content:""}.ph.ph-bug:before{content:""}.ph.ph-bug-beetle:before{content:""}.ph.ph-bug-droid:before{content:""}.ph.ph-building:before{content:""}.ph.ph-building-apartment:before{content:""}.ph.ph-building-office:before{content:""}.ph.ph-buildings:before{content:""}.ph.ph-bulldozer:before{content:""}.ph.ph-bus:before{content:""}.ph.ph-butterfly:before{content:""}.ph.ph-cable-car:before{content:""}.ph.ph-cactus:before{content:""}.ph.ph-cake:before{content:""}.ph.ph-calculator:before{content:""}.ph.ph-calendar:before{content:""}.ph.ph-calendar-blank:before{content:""}.ph.ph-calendar-check:before{content:""}.ph.ph-calendar-dot:before{content:""}.ph.ph-calendar-dots:before{content:""}.ph.ph-calendar-heart:before{content:""}.ph.ph-calendar-minus:before{content:""}.ph.ph-calendar-plus:before{content:""}.ph.ph-calendar-slash:before{content:""}.ph.ph-calendar-star:before{content:""}.ph.ph-calendar-x:before{content:""}.ph.ph-call-bell:before{content:""}.ph.ph-camera:before{content:""}.ph.ph-camera-plus:before{content:""}.ph.ph-camera-rotate:before{content:""}.ph.ph-camera-slash:before{content:""}.ph.ph-campfire:before{content:""}.ph.ph-car:before{content:""}.ph.ph-car-battery:before{content:""}.ph.ph-car-profile:before{content:""}.ph.ph-car-simple:before{content:""}.ph.ph-cardholder:before{content:""}.ph.ph-cards:before{content:""}.ph.ph-cards-three:before{content:""}.ph.ph-caret-circle-double-down:before{content:""}.ph.ph-caret-circle-double-left:before{content:""}.ph.ph-caret-circle-double-right:before{content:""}.ph.ph-caret-circle-double-up:before{content:""}.ph.ph-caret-circle-down:before{content:""}.ph.ph-caret-circle-left:before{content:""}.ph.ph-caret-circle-right:before{content:""}.ph.ph-caret-circle-up:before{content:""}.ph.ph-caret-circle-up-down:before{content:""}.ph.ph-caret-double-down:before{content:""}.ph.ph-caret-double-left:before{content:""}.ph.ph-caret-double-right:before{content:""}.ph.ph-caret-double-up:before{content:""}.ph.ph-caret-down:before{content:""}.ph.ph-caret-left:before{content:""}.ph.ph-caret-line-down:before{content:""}.ph.ph-caret-line-left:before{content:""}.ph.ph-caret-line-right:before{content:""}.ph.ph-caret-line-up:before{content:""}.ph.ph-caret-right:before{content:""}.ph.ph-caret-up:before{content:""}.ph.ph-caret-up-down:before{content:""}.ph.ph-carrot:before{content:""}.ph.ph-cash-register:before{content:""}.ph.ph-cassette-tape:before{content:""}.ph.ph-castle-turret:before{content:""}.ph.ph-cat:before{content:""}.ph.ph-cell-signal-full:before{content:""}.ph.ph-cell-signal-high:before{content:""}.ph.ph-cell-signal-low:before{content:""}.ph.ph-cell-signal-medium:before{content:""}.ph.ph-cell-signal-none:before{content:""}.ph.ph-cell-signal-slash:before{content:""}.ph.ph-cell-signal-x:before{content:""}.ph.ph-cell-tower:before{content:""}.ph.ph-certificate:before{content:""}.ph.ph-chair:before{content:""}.ph.ph-chalkboard:before{content:""}.ph.ph-chalkboard-simple:before{content:""}.ph.ph-chalkboard-teacher:before{content:""}.ph.ph-champagne:before{content:""}.ph.ph-charging-station:before{content:""}.ph.ph-chart-bar:before{content:""}.ph.ph-chart-bar-horizontal:before{content:""}.ph.ph-chart-donut:before{content:""}.ph.ph-chart-line:before{content:""}.ph.ph-chart-line-down:before{content:""}.ph.ph-chart-line-up:before{content:""}.ph.ph-chart-pie:before{content:""}.ph.ph-chart-pie-slice:before{content:""}.ph.ph-chart-polar:before{content:""}.ph.ph-chart-scatter:before{content:""}.ph.ph-chat:before{content:""}.ph.ph-chat-centered:before{content:""}.ph.ph-chat-centered-dots:before{content:""}.ph.ph-chat-centered-slash:before{content:""}.ph.ph-chat-centered-text:before{content:""}.ph.ph-chat-circle:before{content:""}.ph.ph-chat-circle-dots:before{content:""}.ph.ph-chat-circle-slash:before{content:""}.ph.ph-chat-circle-text:before{content:""}.ph.ph-chat-dots:before{content:""}.ph.ph-chat-slash:before{content:""}.ph.ph-chat-teardrop:before{content:""}.ph.ph-chat-teardrop-dots:before{content:""}.ph.ph-chat-teardrop-slash:before{content:""}.ph.ph-chat-teardrop-text:before{content:""}.ph.ph-chat-text:before{content:""}.ph.ph-chats:before{content:""}.ph.ph-chats-circle:before{content:""}.ph.ph-chats-teardrop:before{content:""}.ph.ph-check:before{content:""}.ph.ph-check-circle:before{content:""}.ph.ph-check-fat:before{content:""}.ph.ph-check-square:before{content:""}.ph.ph-check-square-offset:before{content:""}.ph.ph-checkerboard:before{content:""}.ph.ph-checks:before{content:""}.ph.ph-cheers:before{content:""}.ph.ph-cheese:before{content:""}.ph.ph-chef-hat:before{content:""}.ph.ph-cherries:before{content:""}.ph.ph-church:before{content:""}.ph.ph-cigarette:before{content:""}.ph.ph-cigarette-slash:before{content:""}.ph.ph-circle:before{content:""}.ph.ph-circle-dashed:before{content:""}.ph.ph-circle-half:before{content:""}.ph.ph-circle-half-tilt:before{content:""}.ph.ph-circle-notch:before{content:""}.ph.ph-circles-four:before{content:""}.ph.ph-circles-three:before{content:""}.ph.ph-circles-three-plus:before{content:""}.ph.ph-circuitry:before{content:""}.ph.ph-city:before{content:""}.ph.ph-clipboard:before{content:""}.ph.ph-clipboard-text:before{content:""}.ph.ph-clock:before{content:""}.ph.ph-clock-afternoon:before{content:""}.ph.ph-clock-clockwise:before{content:""}.ph.ph-clock-countdown:before{content:""}.ph.ph-clock-counter-clockwise:before{content:""}.ph.ph-clock-user:before{content:""}.ph.ph-closed-captioning:before{content:""}.ph.ph-cloud:before{content:""}.ph.ph-cloud-arrow-down:before{content:""}.ph.ph-cloud-arrow-up:before{content:""}.ph.ph-cloud-check:before{content:""}.ph.ph-cloud-fog:before{content:""}.ph.ph-cloud-lightning:before{content:""}.ph.ph-cloud-moon:before{content:""}.ph.ph-cloud-rain:before{content:""}.ph.ph-cloud-slash:before{content:""}.ph.ph-cloud-snow:before{content:""}.ph.ph-cloud-sun:before{content:""}.ph.ph-cloud-warning:before{content:""}.ph.ph-cloud-x:before{content:""}.ph.ph-clover:before{content:""}.ph.ph-club:before{content:""}.ph.ph-coat-hanger:before{content:""}.ph.ph-coda-logo:before{content:""}.ph.ph-code:before{content:""}.ph.ph-code-block:before{content:""}.ph.ph-code-simple:before{content:""}.ph.ph-codepen-logo:before{content:""}.ph.ph-codesandbox-logo:before{content:""}.ph.ph-coffee:before{content:""}.ph.ph-coffee-bean:before{content:""}.ph.ph-coin:before{content:""}.ph.ph-coin-vertical:before{content:""}.ph.ph-coins:before{content:""}.ph.ph-columns:before{content:""}.ph.ph-columns-plus-left:before{content:""}.ph.ph-columns-plus-right:before{content:""}.ph.ph-command:before{content:""}.ph.ph-compass:before{content:""}.ph.ph-compass-rose:before{content:""}.ph.ph-compass-tool:before{content:""}.ph.ph-computer-tower:before{content:""}.ph.ph-confetti:before{content:""}.ph.ph-contactless-payment:before{content:""}.ph.ph-control:before{content:""}.ph.ph-cookie:before{content:""}.ph.ph-cooking-pot:before{content:""}.ph.ph-copy:before{content:""}.ph.ph-copy-simple:before{content:""}.ph.ph-copyleft:before{content:""}.ph.ph-copyright:before{content:""}.ph.ph-corners-in:before{content:""}.ph.ph-corners-out:before{content:""}.ph.ph-couch:before{content:""}.ph.ph-court-basketball:before{content:""}.ph.ph-cow:before{content:""}.ph.ph-cowboy-hat:before{content:""}.ph.ph-cpu:before{content:""}.ph.ph-crane:before{content:""}.ph.ph-crane-tower:before{content:""}.ph.ph-credit-card:before{content:""}.ph.ph-cricket:before{content:""}.ph.ph-crop:before{content:""}.ph.ph-cross:before{content:""}.ph.ph-crosshair:before{content:""}.ph.ph-crosshair-simple:before{content:""}.ph.ph-crown:before{content:""}.ph.ph-crown-cross:before{content:""}.ph.ph-crown-simple:before{content:""}.ph.ph-cube:before{content:""}.ph.ph-cube-focus:before{content:""}.ph.ph-cube-transparent:before{content:""}.ph.ph-currency-btc:before{content:""}.ph.ph-currency-circle-dollar:before{content:""}.ph.ph-currency-cny:before{content:""}.ph.ph-currency-dollar:before{content:""}.ph.ph-currency-dollar-simple:before{content:""}.ph.ph-currency-eth:before{content:""}.ph.ph-currency-eur:before{content:""}.ph.ph-currency-gbp:before{content:""}.ph.ph-currency-inr:before{content:""}.ph.ph-currency-jpy:before{content:""}.ph.ph-currency-krw:before{content:""}.ph.ph-currency-kzt:before{content:""}.ph.ph-currency-ngn:before{content:""}.ph.ph-currency-rub:before{content:""}.ph.ph-cursor:before{content:""}.ph.ph-cursor-click:before{content:""}.ph.ph-cursor-text:before{content:""}.ph.ph-cylinder:before{content:""}.ph.ph-database:before{content:""}.ph.ph-desk:before{content:""}.ph.ph-desktop:before{content:""}.ph.ph-desktop-tower:before{content:""}.ph.ph-detective:before{content:""}.ph.ph-dev-to-logo:before{content:""}.ph.ph-device-mobile:before{content:""}.ph.ph-device-mobile-camera:before{content:""}.ph.ph-device-mobile-slash:before{content:""}.ph.ph-device-mobile-speaker:before{content:""}.ph.ph-device-rotate:before{content:""}.ph.ph-device-tablet:before{content:""}.ph.ph-device-tablet-camera:before{content:""}.ph.ph-device-tablet-speaker:before{content:""}.ph.ph-devices:before{content:""}.ph.ph-diamond:before{content:""}.ph.ph-diamonds-four:before{content:""}.ph.ph-dice-five:before{content:""}.ph.ph-dice-four:before{content:""}.ph.ph-dice-one:before{content:""}.ph.ph-dice-six:before{content:""}.ph.ph-dice-three:before{content:""}.ph.ph-dice-two:before{content:""}.ph.ph-disc:before{content:""}.ph.ph-disco-ball:before{content:""}.ph.ph-discord-logo:before{content:""}.ph.ph-divide:before{content:""}.ph.ph-dna:before{content:""}.ph.ph-dog:before{content:""}.ph.ph-door:before{content:""}.ph.ph-door-open:before{content:""}.ph.ph-dot:before{content:""}.ph.ph-dot-outline:before{content:""}.ph.ph-dots-nine:before{content:""}.ph.ph-dots-six:before{content:""}.ph.ph-dots-six-vertical:before{content:""}.ph.ph-dots-three:before{content:""}.ph.ph-dots-three-circle:before{content:""}.ph.ph-dots-three-circle-vertical:before{content:""}.ph.ph-dots-three-outline:before{content:""}.ph.ph-dots-three-outline-vertical:before{content:""}.ph.ph-dots-three-vertical:before{content:""}.ph.ph-download:before{content:""}.ph.ph-download-simple:before{content:""}.ph.ph-dress:before{content:""}.ph.ph-dresser:before{content:""}.ph.ph-dribbble-logo:before{content:""}.ph.ph-drone:before{content:""}.ph.ph-drop:before{content:""}.ph.ph-drop-half:before{content:""}.ph.ph-drop-half-bottom:before{content:""}.ph.ph-drop-simple:before{content:""}.ph.ph-drop-slash:before{content:""}.ph.ph-dropbox-logo:before{content:""}.ph.ph-ear:before{content:""}.ph.ph-ear-slash:before{content:""}.ph.ph-egg:before{content:""}.ph.ph-egg-crack:before{content:""}.ph.ph-eject:before{content:""}.ph.ph-eject-simple:before{content:""}.ph.ph-elevator:before{content:""}.ph.ph-empty:before{content:""}.ph.ph-engine:before{content:""}.ph.ph-envelope:before{content:""}.ph.ph-envelope-open:before{content:""}.ph.ph-envelope-simple:before{content:""}.ph.ph-envelope-simple-open:before{content:""}.ph.ph-equalizer:before{content:""}.ph.ph-equals:before{content:""}.ph.ph-eraser:before{content:""}.ph.ph-escalator-down:before{content:""}.ph.ph-escalator-up:before{content:""}.ph.ph-exam:before{content:""}.ph.ph-exclamation-mark:before{content:""}.ph.ph-exclude:before{content:""}.ph.ph-exclude-square:before{content:""}.ph.ph-export:before{content:""}.ph.ph-eye:before{content:""}.ph.ph-eye-closed:before{content:""}.ph.ph-eye-slash:before{content:""}.ph.ph-eyedropper:before{content:""}.ph.ph-eyedropper-sample:before{content:""}.ph.ph-eyeglasses:before{content:""}.ph.ph-eyes:before{content:""}.ph.ph-face-mask:before{content:""}.ph.ph-facebook-logo:before{content:""}.ph.ph-factory:before{content:""}.ph.ph-faders:before{content:""}.ph.ph-faders-horizontal:before{content:""}.ph.ph-fallout-shelter:before{content:""}.ph.ph-fan:before{content:""}.ph.ph-farm:before{content:""}.ph.ph-fast-forward:before{content:""}.ph.ph-fast-forward-circle:before{content:""}.ph.ph-feather:before{content:""}.ph.ph-fediverse-logo:before{content:""}.ph.ph-figma-logo:before{content:""}.ph.ph-file:before{content:""}.ph.ph-file-archive:before{content:""}.ph.ph-file-arrow-down:before{content:""}.ph.ph-file-arrow-up:before{content:""}.ph.ph-file-audio:before{content:""}.ph.ph-file-c:before{content:""}.ph.ph-file-c-sharp:before{content:""}.ph.ph-file-cloud:before{content:""}.ph.ph-file-code:before{content:""}.ph.ph-file-cpp:before{content:""}.ph.ph-file-css:before{content:""}.ph.ph-file-csv:before{content:""}.ph.ph-file-dashed:before{content:""}.ph.ph-file-dotted:before{content:""}.ph.ph-file-doc:before{content:""}.ph.ph-file-html:before{content:""}.ph.ph-file-image:before{content:""}.ph.ph-file-ini:before{content:""}.ph.ph-file-jpg:before{content:""}.ph.ph-file-js:before{content:""}.ph.ph-file-jsx:before{content:""}.ph.ph-file-lock:before{content:""}.ph.ph-file-magnifying-glass:before{content:""}.ph.ph-file-search:before{content:""}.ph.ph-file-md:before{content:""}.ph.ph-file-minus:before{content:""}.ph.ph-file-pdf:before{content:""}.ph.ph-file-plus:before{content:""}.ph.ph-file-png:before{content:""}.ph.ph-file-ppt:before{content:""}.ph.ph-file-py:before{content:""}.ph.ph-file-rs:before{content:""}.ph.ph-file-sql:before{content:""}.ph.ph-file-svg:before{content:""}.ph.ph-file-text:before{content:""}.ph.ph-file-ts:before{content:""}.ph.ph-file-tsx:before{content:""}.ph.ph-file-txt:before{content:""}.ph.ph-file-video:before{content:""}.ph.ph-file-vue:before{content:""}.ph.ph-file-x:before{content:""}.ph.ph-file-xls:before{content:""}.ph.ph-file-zip:before{content:""}.ph.ph-files:before{content:""}.ph.ph-film-reel:before{content:""}.ph.ph-film-script:before{content:""}.ph.ph-film-slate:before{content:""}.ph.ph-film-strip:before{content:""}.ph.ph-fingerprint:before{content:""}.ph.ph-fingerprint-simple:before{content:""}.ph.ph-finn-the-human:before{content:""}.ph.ph-fire:before{content:""}.ph.ph-fire-extinguisher:before{content:""}.ph.ph-fire-simple:before{content:""}.ph.ph-fire-truck:before{content:""}.ph.ph-first-aid:before{content:""}.ph.ph-first-aid-kit:before{content:""}.ph.ph-fish:before{content:""}.ph.ph-fish-simple:before{content:""}.ph.ph-flag:before{content:""}.ph.ph-flag-banner:before{content:""}.ph.ph-flag-banner-fold:before{content:""}.ph.ph-flag-checkered:before{content:""}.ph.ph-flag-pennant:before{content:""}.ph.ph-flame:before{content:""}.ph.ph-flashlight:before{content:""}.ph.ph-flask:before{content:""}.ph.ph-flip-horizontal:before{content:""}.ph.ph-flip-vertical:before{content:""}.ph.ph-floppy-disk:before{content:""}.ph.ph-floppy-disk-back:before{content:""}.ph.ph-flow-arrow:before{content:""}.ph.ph-flower:before{content:""}.ph.ph-flower-lotus:before{content:""}.ph.ph-flower-tulip:before{content:""}.ph.ph-flying-saucer:before{content:""}.ph.ph-folder:before{content:""}.ph.ph-folder-notch:before{content:""}.ph.ph-folder-dashed:before{content:""}.ph.ph-folder-dotted:before{content:""}.ph.ph-folder-lock:before{content:""}.ph.ph-folder-minus:before{content:""}.ph.ph-folder-notch-minus:before{content:""}.ph.ph-folder-open:before{content:""}.ph.ph-folder-notch-open:before{content:""}.ph.ph-folder-plus:before{content:""}.ph.ph-folder-notch-plus:before{content:""}.ph.ph-folder-simple:before{content:""}.ph.ph-folder-simple-dashed:before{content:""}.ph.ph-folder-simple-dotted:before{content:""}.ph.ph-folder-simple-lock:before{content:""}.ph.ph-folder-simple-minus:before{content:""}.ph.ph-folder-simple-plus:before{content:""}.ph.ph-folder-simple-star:before{content:""}.ph.ph-folder-simple-user:before{content:""}.ph.ph-folder-star:before{content:""}.ph.ph-folder-user:before{content:""}.ph.ph-folders:before{content:""}.ph.ph-football:before{content:""}.ph.ph-football-helmet:before{content:""}.ph.ph-footprints:before{content:""}.ph.ph-fork-knife:before{content:""}.ph.ph-four-k:before{content:""}.ph.ph-frame-corners:before{content:""}.ph.ph-framer-logo:before{content:""}.ph.ph-function:before{content:""}.ph.ph-funnel:before{content:""}.ph.ph-funnel-simple:before{content:""}.ph.ph-funnel-simple-x:before{content:""}.ph.ph-funnel-x:before{content:""}.ph.ph-game-controller:before{content:""}.ph.ph-garage:before{content:""}.ph.ph-gas-can:before{content:""}.ph.ph-gas-pump:before{content:""}.ph.ph-gauge:before{content:""}.ph.ph-gavel:before{content:""}.ph.ph-gear:before{content:""}.ph.ph-gear-fine:before{content:""}.ph.ph-gear-six:before{content:""}.ph.ph-gender-female:before{content:""}.ph.ph-gender-intersex:before{content:""}.ph.ph-gender-male:before{content:""}.ph.ph-gender-neuter:before{content:""}.ph.ph-gender-nonbinary:before{content:""}.ph.ph-gender-transgender:before{content:""}.ph.ph-ghost:before{content:""}.ph.ph-gif:before{content:""}.ph.ph-gift:before{content:""}.ph.ph-git-branch:before{content:""}.ph.ph-git-commit:before{content:""}.ph.ph-git-diff:before{content:""}.ph.ph-git-fork:before{content:""}.ph.ph-git-merge:before{content:""}.ph.ph-git-pull-request:before{content:""}.ph.ph-github-logo:before{content:""}.ph.ph-gitlab-logo:before{content:""}.ph.ph-gitlab-logo-simple:before{content:""}.ph.ph-globe:before{content:""}.ph.ph-globe-hemisphere-east:before{content:""}.ph.ph-globe-hemisphere-west:before{content:""}.ph.ph-globe-simple:before{content:""}.ph.ph-globe-simple-x:before{content:""}.ph.ph-globe-stand:before{content:""}.ph.ph-globe-x:before{content:""}.ph.ph-goggles:before{content:""}.ph.ph-golf:before{content:""}.ph.ph-goodreads-logo:before{content:""}.ph.ph-google-cardboard-logo:before{content:""}.ph.ph-google-chrome-logo:before{content:""}.ph.ph-google-drive-logo:before{content:""}.ph.ph-google-logo:before{content:""}.ph.ph-google-photos-logo:before{content:""}.ph.ph-google-play-logo:before{content:""}.ph.ph-google-podcasts-logo:before{content:""}.ph.ph-gps:before{content:""}.ph.ph-gps-fix:before{content:""}.ph.ph-gps-slash:before{content:""}.ph.ph-gradient:before{content:""}.ph.ph-graduation-cap:before{content:""}.ph.ph-grains:before{content:""}.ph.ph-grains-slash:before{content:""}.ph.ph-graph:before{content:""}.ph.ph-graphics-card:before{content:""}.ph.ph-greater-than:before{content:""}.ph.ph-greater-than-or-equal:before{content:""}.ph.ph-grid-four:before{content:""}.ph.ph-grid-nine:before{content:""}.ph.ph-guitar:before{content:""}.ph.ph-hair-dryer:before{content:""}.ph.ph-hamburger:before{content:""}.ph.ph-hammer:before{content:""}.ph.ph-hand:before{content:""}.ph.ph-hand-arrow-down:before{content:""}.ph.ph-hand-arrow-up:before{content:""}.ph.ph-hand-coins:before{content:""}.ph.ph-hand-deposit:before{content:""}.ph.ph-hand-eye:before{content:""}.ph.ph-hand-fist:before{content:""}.ph.ph-hand-grabbing:before{content:""}.ph.ph-hand-heart:before{content:""}.ph.ph-hand-palm:before{content:""}.ph.ph-hand-peace:before{content:""}.ph.ph-hand-pointing:before{content:""}.ph.ph-hand-soap:before{content:""}.ph.ph-hand-swipe-left:before{content:""}.ph.ph-hand-swipe-right:before{content:""}.ph.ph-hand-tap:before{content:""}.ph.ph-hand-waving:before{content:""}.ph.ph-hand-withdraw:before{content:""}.ph.ph-handbag:before{content:""}.ph.ph-handbag-simple:before{content:""}.ph.ph-hands-clapping:before{content:""}.ph.ph-hands-praying:before{content:""}.ph.ph-handshake:before{content:""}.ph.ph-hard-drive:before{content:""}.ph.ph-hard-drives:before{content:""}.ph.ph-hard-hat:before{content:""}.ph.ph-hash:before{content:""}.ph.ph-hash-straight:before{content:""}.ph.ph-head-circuit:before{content:""}.ph.ph-headlights:before{content:""}.ph.ph-headphones:before{content:""}.ph.ph-headset:before{content:""}.ph.ph-heart:before{content:""}.ph.ph-heart-break:before{content:""}.ph.ph-heart-half:before{content:""}.ph.ph-heart-straight:before{content:""}.ph.ph-heart-straight-break:before{content:""}.ph.ph-heartbeat:before{content:""}.ph.ph-hexagon:before{content:""}.ph.ph-high-definition:before{content:""}.ph.ph-high-heel:before{content:""}.ph.ph-highlighter:before{content:""}.ph.ph-highlighter-circle:before{content:""}.ph.ph-hockey:before{content:""}.ph.ph-hoodie:before{content:""}.ph.ph-horse:before{content:""}.ph.ph-hospital:before{content:""}.ph.ph-hourglass:before{content:""}.ph.ph-hourglass-high:before{content:""}.ph.ph-hourglass-low:before{content:""}.ph.ph-hourglass-medium:before{content:""}.ph.ph-hourglass-simple:before{content:""}.ph.ph-hourglass-simple-high:before{content:""}.ph.ph-hourglass-simple-low:before{content:""}.ph.ph-hourglass-simple-medium:before{content:""}.ph.ph-house:before{content:""}.ph.ph-house-line:before{content:""}.ph.ph-house-simple:before{content:""}.ph.ph-hurricane:before{content:""}.ph.ph-ice-cream:before{content:""}.ph.ph-identification-badge:before{content:""}.ph.ph-identification-card:before{content:""}.ph.ph-image:before{content:""}.ph.ph-image-broken:before{content:""}.ph.ph-image-square:before{content:""}.ph.ph-images:before{content:""}.ph.ph-images-square:before{content:""}.ph.ph-infinity:before{content:""}.ph.ph-lemniscate:before{content:""}.ph.ph-info:before{content:""}.ph.ph-instagram-logo:before{content:""}.ph.ph-intersect:before{content:""}.ph.ph-intersect-square:before{content:""}.ph.ph-intersect-three:before{content:""}.ph.ph-intersection:before{content:""}.ph.ph-invoice:before{content:""}.ph.ph-island:before{content:""}.ph.ph-jar:before{content:""}.ph.ph-jar-label:before{content:""}.ph.ph-jeep:before{content:""}.ph.ph-joystick:before{content:""}.ph.ph-kanban:before{content:""}.ph.ph-key:before{content:""}.ph.ph-key-return:before{content:""}.ph.ph-keyboard:before{content:""}.ph.ph-keyhole:before{content:""}.ph.ph-knife:before{content:""}.ph.ph-ladder:before{content:""}.ph.ph-ladder-simple:before{content:""}.ph.ph-lamp:before{content:""}.ph.ph-lamp-pendant:before{content:""}.ph.ph-laptop:before{content:""}.ph.ph-lasso:before{content:""}.ph.ph-lastfm-logo:before{content:""}.ph.ph-layout:before{content:""}.ph.ph-leaf:before{content:""}.ph.ph-lectern:before{content:""}.ph.ph-lego:before{content:""}.ph.ph-lego-smiley:before{content:""}.ph.ph-less-than:before{content:""}.ph.ph-less-than-or-equal:before{content:""}.ph.ph-letter-circle-h:before{content:""}.ph.ph-letter-circle-p:before{content:""}.ph.ph-letter-circle-v:before{content:""}.ph.ph-lifebuoy:before{content:""}.ph.ph-lightbulb:before{content:""}.ph.ph-lightbulb-filament:before{content:""}.ph.ph-lighthouse:before{content:""}.ph.ph-lightning:before{content:""}.ph.ph-lightning-a:before{content:""}.ph.ph-lightning-slash:before{content:""}.ph.ph-line-segment:before{content:""}.ph.ph-line-segments:before{content:""}.ph.ph-line-vertical:before{content:""}.ph.ph-link:before{content:""}.ph.ph-link-break:before{content:""}.ph.ph-link-simple:before{content:""}.ph.ph-link-simple-break:before{content:""}.ph.ph-link-simple-horizontal:before{content:""}.ph.ph-link-simple-horizontal-break:before{content:""}.ph.ph-linkedin-logo:before{content:""}.ph.ph-linktree-logo:before{content:""}.ph.ph-linux-logo:before{content:""}.ph.ph-list:before{content:""}.ph.ph-list-bullets:before{content:""}.ph.ph-list-checks:before{content:""}.ph.ph-list-dashes:before{content:""}.ph.ph-list-heart:before{content:""}.ph.ph-list-magnifying-glass:before{content:""}.ph.ph-list-numbers:before{content:""}.ph.ph-list-plus:before{content:""}.ph.ph-list-star:before{content:""}.ph.ph-lock:before{content:""}.ph.ph-lock-key:before{content:""}.ph.ph-lock-key-open:before{content:""}.ph.ph-lock-laminated:before{content:""}.ph.ph-lock-laminated-open:before{content:""}.ph.ph-lock-open:before{content:""}.ph.ph-lock-simple:before{content:""}.ph.ph-lock-simple-open:before{content:""}.ph.ph-lockers:before{content:""}.ph.ph-log:before{content:""}.ph.ph-magic-wand:before{content:""}.ph.ph-magnet:before{content:""}.ph.ph-magnet-straight:before{content:""}.ph.ph-magnifying-glass:before{content:""}.ph.ph-magnifying-glass-minus:before{content:""}.ph.ph-magnifying-glass-plus:before{content:""}.ph.ph-mailbox:before{content:""}.ph.ph-map-pin:before{content:""}.ph.ph-map-pin-area:before{content:""}.ph.ph-map-pin-line:before{content:""}.ph.ph-map-pin-plus:before{content:""}.ph.ph-map-pin-simple:before{content:""}.ph.ph-map-pin-simple-area:before{content:""}.ph.ph-map-pin-simple-line:before{content:""}.ph.ph-map-trifold:before{content:""}.ph.ph-markdown-logo:before{content:""}.ph.ph-marker-circle:before{content:""}.ph.ph-martini:before{content:""}.ph.ph-mask-happy:before{content:""}.ph.ph-mask-sad:before{content:""}.ph.ph-mastodon-logo:before{content:""}.ph.ph-math-operations:before{content:""}.ph.ph-matrix-logo:before{content:""}.ph.ph-medal:before{content:""}.ph.ph-medal-military:before{content:""}.ph.ph-medium-logo:before{content:""}.ph.ph-megaphone:before{content:""}.ph.ph-megaphone-simple:before{content:""}.ph.ph-member-of:before{content:""}.ph.ph-memory:before{content:""}.ph.ph-messenger-logo:before{content:""}.ph.ph-meta-logo:before{content:""}.ph.ph-meteor:before{content:""}.ph.ph-metronome:before{content:""}.ph.ph-microphone:before{content:""}.ph.ph-microphone-slash:before{content:""}.ph.ph-microphone-stage:before{content:""}.ph.ph-microscope:before{content:""}.ph.ph-microsoft-excel-logo:before{content:""}.ph.ph-microsoft-outlook-logo:before{content:""}.ph.ph-microsoft-powerpoint-logo:before{content:""}.ph.ph-microsoft-teams-logo:before{content:""}.ph.ph-microsoft-word-logo:before{content:""}.ph.ph-minus:before{content:""}.ph.ph-minus-circle:before{content:""}.ph.ph-minus-square:before{content:""}.ph.ph-money:before{content:""}.ph.ph-money-wavy:before{content:""}.ph.ph-monitor:before{content:""}.ph.ph-monitor-arrow-up:before{content:""}.ph.ph-monitor-play:before{content:""}.ph.ph-moon:before{content:""}.ph.ph-moon-stars:before{content:""}.ph.ph-moped:before{content:""}.ph.ph-moped-front:before{content:""}.ph.ph-mosque:before{content:""}.ph.ph-motorcycle:before{content:""}.ph.ph-mountains:before{content:""}.ph.ph-mouse:before{content:""}.ph.ph-mouse-left-click:before{content:""}.ph.ph-mouse-middle-click:before{content:""}.ph.ph-mouse-right-click:before{content:""}.ph.ph-mouse-scroll:before{content:""}.ph.ph-mouse-simple:before{content:""}.ph.ph-music-note:before{content:""}.ph.ph-music-note-simple:before{content:""}.ph.ph-music-notes:before{content:""}.ph.ph-music-notes-minus:before{content:""}.ph.ph-music-notes-plus:before{content:""}.ph.ph-music-notes-simple:before{content:""}.ph.ph-navigation-arrow:before{content:""}.ph.ph-needle:before{content:""}.ph.ph-network:before{content:""}.ph.ph-network-slash:before{content:""}.ph.ph-network-x:before{content:""}.ph.ph-newspaper:before{content:""}.ph.ph-newspaper-clipping:before{content:""}.ph.ph-not-equals:before{content:""}.ph.ph-not-member-of:before{content:""}.ph.ph-not-subset-of:before{content:""}.ph.ph-not-superset-of:before{content:""}.ph.ph-notches:before{content:""}.ph.ph-note:before{content:""}.ph.ph-note-blank:before{content:""}.ph.ph-note-pencil:before{content:""}.ph.ph-notebook:before{content:""}.ph.ph-notepad:before{content:""}.ph.ph-notification:before{content:""}.ph.ph-notion-logo:before{content:""}.ph.ph-nuclear-plant:before{content:""}.ph.ph-number-circle-eight:before{content:""}.ph.ph-number-circle-five:before{content:""}.ph.ph-number-circle-four:before{content:""}.ph.ph-number-circle-nine:before{content:""}.ph.ph-number-circle-one:before{content:""}.ph.ph-number-circle-seven:before{content:""}.ph.ph-number-circle-six:before{content:""}.ph.ph-number-circle-three:before{content:""}.ph.ph-number-circle-two:before{content:""}.ph.ph-number-circle-zero:before{content:""}.ph.ph-number-eight:before{content:""}.ph.ph-number-five:before{content:""}.ph.ph-number-four:before{content:""}.ph.ph-number-nine:before{content:""}.ph.ph-number-one:before{content:""}.ph.ph-number-seven:before{content:""}.ph.ph-number-six:before{content:""}.ph.ph-number-square-eight:before{content:""}.ph.ph-number-square-five:before{content:""}.ph.ph-number-square-four:before{content:""}.ph.ph-number-square-nine:before{content:""}.ph.ph-number-square-one:before{content:""}.ph.ph-number-square-seven:before{content:""}.ph.ph-number-square-six:before{content:""}.ph.ph-number-square-three:before{content:""}.ph.ph-number-square-two:before{content:""}.ph.ph-number-square-zero:before{content:""}.ph.ph-number-three:before{content:""}.ph.ph-number-two:before{content:""}.ph.ph-number-zero:before{content:""}.ph.ph-numpad:before{content:""}.ph.ph-nut:before{content:""}.ph.ph-ny-times-logo:before{content:""}.ph.ph-octagon:before{content:""}.ph.ph-office-chair:before{content:""}.ph.ph-onigiri:before{content:""}.ph.ph-open-ai-logo:before{content:""}.ph.ph-option:before{content:""}.ph.ph-orange:before{content:""}.ph.ph-orange-slice:before{content:""}.ph.ph-oven:before{content:""}.ph.ph-package:before{content:""}.ph.ph-paint-brush:before{content:""}.ph.ph-paint-brush-broad:before{content:""}.ph.ph-paint-brush-household:before{content:""}.ph.ph-paint-bucket:before{content:""}.ph.ph-paint-roller:before{content:""}.ph.ph-palette:before{content:""}.ph.ph-panorama:before{content:""}.ph.ph-pants:before{content:""}.ph.ph-paper-plane:before{content:""}.ph.ph-paper-plane-right:before{content:""}.ph.ph-paper-plane-tilt:before{content:""}.ph.ph-paperclip:before{content:""}.ph.ph-paperclip-horizontal:before{content:""}.ph.ph-parachute:before{content:""}.ph.ph-paragraph:before{content:""}.ph.ph-parallelogram:before{content:""}.ph.ph-park:before{content:""}.ph.ph-password:before{content:""}.ph.ph-path:before{content:""}.ph.ph-patreon-logo:before{content:""}.ph.ph-pause:before{content:""}.ph.ph-pause-circle:before{content:""}.ph.ph-paw-print:before{content:""}.ph.ph-paypal-logo:before{content:""}.ph.ph-peace:before{content:""}.ph.ph-pen:before{content:""}.ph.ph-pen-nib:before{content:""}.ph.ph-pen-nib-straight:before{content:""}.ph.ph-pencil:before{content:""}.ph.ph-pencil-circle:before{content:""}.ph.ph-pencil-line:before{content:""}.ph.ph-pencil-ruler:before{content:""}.ph.ph-pencil-simple:before{content:""}.ph.ph-pencil-simple-line:before{content:""}.ph.ph-pencil-simple-slash:before{content:""}.ph.ph-pencil-slash:before{content:""}.ph.ph-pentagon:before{content:""}.ph.ph-pentagram:before{content:""}.ph.ph-pepper:before{content:""}.ph.ph-percent:before{content:""}.ph.ph-person:before{content:""}.ph.ph-person-arms-spread:before{content:""}.ph.ph-person-simple:before{content:""}.ph.ph-person-simple-bike:before{content:""}.ph.ph-person-simple-circle:before{content:""}.ph.ph-person-simple-hike:before{content:""}.ph.ph-person-simple-run:before{content:""}.ph.ph-person-simple-ski:before{content:""}.ph.ph-person-simple-snowboard:before{content:""}.ph.ph-person-simple-swim:before{content:""}.ph.ph-person-simple-tai-chi:before{content:""}.ph.ph-person-simple-throw:before{content:""}.ph.ph-person-simple-walk:before{content:""}.ph.ph-perspective:before{content:""}.ph.ph-phone:before{content:""}.ph.ph-phone-call:before{content:""}.ph.ph-phone-disconnect:before{content:""}.ph.ph-phone-incoming:before{content:""}.ph.ph-phone-list:before{content:""}.ph.ph-phone-outgoing:before{content:""}.ph.ph-phone-pause:before{content:""}.ph.ph-phone-plus:before{content:""}.ph.ph-phone-slash:before{content:""}.ph.ph-phone-transfer:before{content:""}.ph.ph-phone-x:before{content:""}.ph.ph-phosphor-logo:before{content:""}.ph.ph-pi:before{content:""}.ph.ph-piano-keys:before{content:""}.ph.ph-picnic-table:before{content:""}.ph.ph-picture-in-picture:before{content:""}.ph.ph-piggy-bank:before{content:""}.ph.ph-pill:before{content:""}.ph.ph-ping-pong:before{content:""}.ph.ph-pint-glass:before{content:""}.ph.ph-pinterest-logo:before{content:""}.ph.ph-pinwheel:before{content:""}.ph.ph-pipe:before{content:""}.ph.ph-pipe-wrench:before{content:""}.ph.ph-pix-logo:before{content:""}.ph.ph-pizza:before{content:""}.ph.ph-placeholder:before{content:""}.ph.ph-planet:before{content:""}.ph.ph-plant:before{content:""}.ph.ph-play:before{content:""}.ph.ph-play-circle:before{content:""}.ph.ph-play-pause:before{content:""}.ph.ph-playlist:before{content:""}.ph.ph-plug:before{content:""}.ph.ph-plug-charging:before{content:""}.ph.ph-plugs:before{content:""}.ph.ph-plugs-connected:before{content:""}.ph.ph-plus:before{content:""}.ph.ph-plus-circle:before{content:""}.ph.ph-plus-minus:before{content:""}.ph.ph-plus-square:before{content:""}.ph.ph-poker-chip:before{content:""}.ph.ph-police-car:before{content:""}.ph.ph-polygon:before{content:""}.ph.ph-popcorn:before{content:""}.ph.ph-popsicle:before{content:""}.ph.ph-potted-plant:before{content:""}.ph.ph-power:before{content:""}.ph.ph-prescription:before{content:""}.ph.ph-presentation:before{content:""}.ph.ph-presentation-chart:before{content:""}.ph.ph-printer:before{content:""}.ph.ph-prohibit:before{content:""}.ph.ph-prohibit-inset:before{content:""}.ph.ph-projector-screen:before{content:""}.ph.ph-projector-screen-chart:before{content:""}.ph.ph-pulse:before{content:""}.ph.ph-activity:before{content:""}.ph.ph-push-pin:before{content:""}.ph.ph-push-pin-simple:before{content:""}.ph.ph-push-pin-simple-slash:before{content:""}.ph.ph-push-pin-slash:before{content:""}.ph.ph-puzzle-piece:before{content:""}.ph.ph-qr-code:before{content:""}.ph.ph-question:before{content:""}.ph.ph-question-mark:before{content:""}.ph.ph-queue:before{content:""}.ph.ph-quotes:before{content:""}.ph.ph-rabbit:before{content:""}.ph.ph-racquet:before{content:""}.ph.ph-radical:before{content:""}.ph.ph-radio:before{content:""}.ph.ph-radio-button:before{content:""}.ph.ph-radioactive:before{content:""}.ph.ph-rainbow:before{content:""}.ph.ph-rainbow-cloud:before{content:""}.ph.ph-ranking:before{content:""}.ph.ph-read-cv-logo:before{content:""}.ph.ph-receipt:before{content:""}.ph.ph-receipt-x:before{content:""}.ph.ph-record:before{content:""}.ph.ph-rectangle:before{content:""}.ph.ph-rectangle-dashed:before{content:""}.ph.ph-recycle:before{content:""}.ph.ph-reddit-logo:before{content:""}.ph.ph-repeat:before{content:""}.ph.ph-repeat-once:before{content:""}.ph.ph-replit-logo:before{content:""}.ph.ph-resize:before{content:""}.ph.ph-rewind:before{content:""}.ph.ph-rewind-circle:before{content:""}.ph.ph-road-horizon:before{content:""}.ph.ph-robot:before{content:""}.ph.ph-rocket:before{content:""}.ph.ph-rocket-launch:before{content:""}.ph.ph-rows:before{content:""}.ph.ph-rows-plus-bottom:before{content:""}.ph.ph-rows-plus-top:before{content:""}.ph.ph-rss:before{content:""}.ph.ph-rss-simple:before{content:""}.ph.ph-rug:before{content:""}.ph.ph-ruler:before{content:""}.ph.ph-sailboat:before{content:""}.ph.ph-scales:before{content:""}.ph.ph-scan:before{content:""}.ph.ph-scan-smiley:before{content:""}.ph.ph-scissors:before{content:""}.ph.ph-scooter:before{content:""}.ph.ph-screencast:before{content:""}.ph.ph-screwdriver:before{content:""}.ph.ph-scribble:before{content:""}.ph.ph-scribble-loop:before{content:""}.ph.ph-scroll:before{content:""}.ph.ph-seal:before{content:""}.ph.ph-circle-wavy:before{content:""}.ph.ph-seal-check:before{content:""}.ph.ph-circle-wavy-check:before{content:""}.ph.ph-seal-percent:before{content:""}.ph.ph-seal-question:before{content:""}.ph.ph-circle-wavy-question:before{content:""}.ph.ph-seal-warning:before{content:""}.ph.ph-circle-wavy-warning:before{content:""}.ph.ph-seat:before{content:""}.ph.ph-seatbelt:before{content:""}.ph.ph-security-camera:before{content:""}.ph.ph-selection:before{content:""}.ph.ph-selection-all:before{content:""}.ph.ph-selection-background:before{content:""}.ph.ph-selection-foreground:before{content:""}.ph.ph-selection-inverse:before{content:""}.ph.ph-selection-plus:before{content:""}.ph.ph-selection-slash:before{content:""}.ph.ph-shapes:before{content:""}.ph.ph-share:before{content:""}.ph.ph-share-fat:before{content:""}.ph.ph-share-network:before{content:""}.ph.ph-shield:before{content:""}.ph.ph-shield-check:before{content:""}.ph.ph-shield-checkered:before{content:""}.ph.ph-shield-chevron:before{content:""}.ph.ph-shield-plus:before{content:""}.ph.ph-shield-slash:before{content:""}.ph.ph-shield-star:before{content:""}.ph.ph-shield-warning:before{content:""}.ph.ph-shipping-container:before{content:""}.ph.ph-shirt-folded:before{content:""}.ph.ph-shooting-star:before{content:""}.ph.ph-shopping-bag:before{content:""}.ph.ph-shopping-bag-open:before{content:""}.ph.ph-shopping-cart:before{content:""}.ph.ph-shopping-cart-simple:before{content:""}.ph.ph-shovel:before{content:""}.ph.ph-shower:before{content:""}.ph.ph-shrimp:before{content:""}.ph.ph-shuffle:before{content:""}.ph.ph-shuffle-angular:before{content:""}.ph.ph-shuffle-simple:before{content:""}.ph.ph-sidebar:before{content:""}.ph.ph-sidebar-simple:before{content:""}.ph.ph-sigma:before{content:""}.ph.ph-sign-in:before{content:""}.ph.ph-sign-out:before{content:""}.ph.ph-signature:before{content:""}.ph.ph-signpost:before{content:""}.ph.ph-sim-card:before{content:""}.ph.ph-siren:before{content:""}.ph.ph-sketch-logo:before{content:""}.ph.ph-skip-back:before{content:""}.ph.ph-skip-back-circle:before{content:""}.ph.ph-skip-forward:before{content:""}.ph.ph-skip-forward-circle:before{content:""}.ph.ph-skull:before{content:""}.ph.ph-skype-logo:before{content:""}.ph.ph-slack-logo:before{content:""}.ph.ph-sliders:before{content:""}.ph.ph-sliders-horizontal:before{content:""}.ph.ph-slideshow:before{content:""}.ph.ph-smiley:before{content:""}.ph.ph-smiley-angry:before{content:""}.ph.ph-smiley-blank:before{content:""}.ph.ph-smiley-meh:before{content:""}.ph.ph-smiley-melting:before{content:""}.ph.ph-smiley-nervous:before{content:""}.ph.ph-smiley-sad:before{content:""}.ph.ph-smiley-sticker:before{content:""}.ph.ph-smiley-wink:before{content:""}.ph.ph-smiley-x-eyes:before{content:""}.ph.ph-snapchat-logo:before{content:""}.ph.ph-sneaker:before{content:""}.ph.ph-sneaker-move:before{content:""}.ph.ph-snowflake:before{content:""}.ph.ph-soccer-ball:before{content:""}.ph.ph-sock:before{content:""}.ph.ph-solar-panel:before{content:""}.ph.ph-solar-roof:before{content:""}.ph.ph-sort-ascending:before{content:""}.ph.ph-sort-descending:before{content:""}.ph.ph-soundcloud-logo:before{content:""}.ph.ph-spade:before{content:""}.ph.ph-sparkle:before{content:""}.ph.ph-speaker-hifi:before{content:""}.ph.ph-speaker-high:before{content:""}.ph.ph-speaker-low:before{content:""}.ph.ph-speaker-none:before{content:""}.ph.ph-speaker-simple-high:before{content:""}.ph.ph-speaker-simple-low:before{content:""}.ph.ph-speaker-simple-none:before{content:""}.ph.ph-speaker-simple-slash:before{content:""}.ph.ph-speaker-simple-x:before{content:""}.ph.ph-speaker-slash:before{content:""}.ph.ph-speaker-x:before{content:""}.ph.ph-speedometer:before{content:""}.ph.ph-sphere:before{content:""}.ph.ph-spinner:before{content:""}.ph.ph-spinner-ball:before{content:""}.ph.ph-spinner-gap:before{content:""}.ph.ph-spiral:before{content:""}.ph.ph-split-horizontal:before{content:""}.ph.ph-split-vertical:before{content:""}.ph.ph-spotify-logo:before{content:""}.ph.ph-spray-bottle:before{content:""}.ph.ph-square:before{content:""}.ph.ph-square-half:before{content:""}.ph.ph-square-half-bottom:before{content:""}.ph.ph-square-logo:before{content:""}.ph.ph-square-split-horizontal:before{content:""}.ph.ph-square-split-vertical:before{content:""}.ph.ph-squares-four:before{content:""}.ph.ph-stack:before{content:""}.ph.ph-stack-minus:before{content:""}.ph.ph-stack-overflow-logo:before{content:""}.ph.ph-stack-plus:before{content:""}.ph.ph-stack-simple:before{content:""}.ph.ph-stairs:before{content:""}.ph.ph-stamp:before{content:""}.ph.ph-standard-definition:before{content:""}.ph.ph-star:before{content:""}.ph.ph-star-and-crescent:before{content:""}.ph.ph-star-four:before{content:""}.ph.ph-star-half:before{content:""}.ph.ph-star-of-david:before{content:""}.ph.ph-steam-logo:before{content:""}.ph.ph-steering-wheel:before{content:""}.ph.ph-steps:before{content:""}.ph.ph-stethoscope:before{content:""}.ph.ph-sticker:before{content:""}.ph.ph-stool:before{content:""}.ph.ph-stop:before{content:""}.ph.ph-stop-circle:before{content:""}.ph.ph-storefront:before{content:""}.ph.ph-strategy:before{content:""}.ph.ph-stripe-logo:before{content:""}.ph.ph-student:before{content:""}.ph.ph-subset-of:before{content:""}.ph.ph-subset-proper-of:before{content:""}.ph.ph-subtitles:before{content:""}.ph.ph-subtitles-slash:before{content:""}.ph.ph-subtract:before{content:""}.ph.ph-subtract-square:before{content:""}.ph.ph-subway:before{content:""}.ph.ph-suitcase:before{content:""}.ph.ph-suitcase-rolling:before{content:""}.ph.ph-suitcase-simple:before{content:""}.ph.ph-sun:before{content:""}.ph.ph-sun-dim:before{content:""}.ph.ph-sun-horizon:before{content:""}.ph.ph-sunglasses:before{content:""}.ph.ph-superset-of:before{content:""}.ph.ph-superset-proper-of:before{content:""}.ph.ph-swap:before{content:""}.ph.ph-swatches:before{content:""}.ph.ph-swimming-pool:before{content:""}.ph.ph-sword:before{content:""}.ph.ph-synagogue:before{content:""}.ph.ph-syringe:before{content:""}.ph.ph-t-shirt:before{content:""}.ph.ph-table:before{content:""}.ph.ph-tabs:before{content:""}.ph.ph-tag:before{content:""}.ph.ph-tag-chevron:before{content:""}.ph.ph-tag-simple:before{content:""}.ph.ph-target:before{content:""}.ph.ph-taxi:before{content:""}.ph.ph-tea-bag:before{content:""}.ph.ph-telegram-logo:before{content:""}.ph.ph-television:before{content:""}.ph.ph-television-simple:before{content:""}.ph.ph-tennis-ball:before{content:""}.ph.ph-tent:before{content:""}.ph.ph-terminal:before{content:""}.ph.ph-terminal-window:before{content:""}.ph.ph-test-tube:before{content:""}.ph.ph-text-a-underline:before{content:""}.ph.ph-text-aa:before{content:""}.ph.ph-text-align-center:before{content:""}.ph.ph-text-align-justify:before{content:""}.ph.ph-text-align-left:before{content:""}.ph.ph-text-align-right:before{content:""}.ph.ph-text-b:before{content:""}.ph.ph-text-bolder:before{content:""}.ph.ph-text-columns:before{content:""}.ph.ph-text-h:before{content:""}.ph.ph-text-h-five:before{content:""}.ph.ph-text-h-four:before{content:""}.ph.ph-text-h-one:before{content:""}.ph.ph-text-h-six:before{content:""}.ph.ph-text-h-three:before{content:""}.ph.ph-text-h-two:before{content:""}.ph.ph-text-indent:before{content:""}.ph.ph-text-italic:before{content:""}.ph.ph-text-outdent:before{content:""}.ph.ph-text-strikethrough:before{content:""}.ph.ph-text-subscript:before{content:""}.ph.ph-text-superscript:before{content:""}.ph.ph-text-t:before{content:""}.ph.ph-text-t-slash:before{content:""}.ph.ph-text-underline:before{content:""}.ph.ph-textbox:before{content:""}.ph.ph-thermometer:before{content:""}.ph.ph-thermometer-cold:before{content:""}.ph.ph-thermometer-hot:before{content:""}.ph.ph-thermometer-simple:before{content:""}.ph.ph-threads-logo:before{content:""}.ph.ph-three-d:before{content:""}.ph.ph-thumbs-down:before{content:""}.ph.ph-thumbs-up:before{content:""}.ph.ph-ticket:before{content:""}.ph.ph-tidal-logo:before{content:""}.ph.ph-tiktok-logo:before{content:""}.ph.ph-tilde:before{content:""}.ph.ph-timer:before{content:""}.ph.ph-tip-jar:before{content:""}.ph.ph-tipi:before{content:""}.ph.ph-tire:before{content:""}.ph.ph-toggle-left:before{content:""}.ph.ph-toggle-right:before{content:""}.ph.ph-toilet:before{content:""}.ph.ph-toilet-paper:before{content:""}.ph.ph-toolbox:before{content:""}.ph.ph-tooth:before{content:""}.ph.ph-tornado:before{content:""}.ph.ph-tote:before{content:""}.ph.ph-tote-simple:before{content:""}.ph.ph-towel:before{content:""}.ph.ph-tractor:before{content:""}.ph.ph-trademark:before{content:""}.ph.ph-trademark-registered:before{content:""}.ph.ph-traffic-cone:before{content:""}.ph.ph-traffic-sign:before{content:""}.ph.ph-traffic-signal:before{content:""}.ph.ph-train:before{content:""}.ph.ph-train-regional:before{content:""}.ph.ph-train-simple:before{content:""}.ph.ph-tram:before{content:""}.ph.ph-translate:before{content:""}.ph.ph-trash:before{content:""}.ph.ph-trash-simple:before{content:""}.ph.ph-tray:before{content:""}.ph.ph-tray-arrow-down:before{content:""}.ph.ph-archive-tray:before{content:""}.ph.ph-tray-arrow-up:before{content:""}.ph.ph-treasure-chest:before{content:""}.ph.ph-tree:before{content:""}.ph.ph-tree-evergreen:before{content:""}.ph.ph-tree-palm:before{content:""}.ph.ph-tree-structure:before{content:""}.ph.ph-tree-view:before{content:""}.ph.ph-trend-down:before{content:""}.ph.ph-trend-up:before{content:""}.ph.ph-triangle:before{content:""}.ph.ph-triangle-dashed:before{content:""}.ph.ph-trolley:before{content:""}.ph.ph-trolley-suitcase:before{content:""}.ph.ph-trophy:before{content:""}.ph.ph-truck:before{content:""}.ph.ph-truck-trailer:before{content:""}.ph.ph-tumblr-logo:before{content:""}.ph.ph-twitch-logo:before{content:""}.ph.ph-twitter-logo:before{content:""}.ph.ph-umbrella:before{content:""}.ph.ph-umbrella-simple:before{content:""}.ph.ph-union:before{content:""}.ph.ph-unite:before{content:""}.ph.ph-unite-square:before{content:""}.ph.ph-upload:before{content:""}.ph.ph-upload-simple:before{content:""}.ph.ph-usb:before{content:""}.ph.ph-user:before{content:""}.ph.ph-user-check:before{content:""}.ph.ph-user-circle:before{content:""}.ph.ph-user-circle-check:before{content:""}.ph.ph-user-circle-dashed:before{content:""}.ph.ph-user-circle-gear:before{content:""}.ph.ph-user-circle-minus:before{content:""}.ph.ph-user-circle-plus:before{content:""}.ph.ph-user-focus:before{content:""}.ph.ph-user-gear:before{content:""}.ph.ph-user-list:before{content:""}.ph.ph-user-minus:before{content:""}.ph.ph-user-plus:before{content:""}.ph.ph-user-rectangle:before{content:""}.ph.ph-user-sound:before{content:""}.ph.ph-user-square:before{content:""}.ph.ph-user-switch:before{content:""}.ph.ph-users:before{content:""}.ph.ph-users-four:before{content:""}.ph.ph-users-three:before{content:""}.ph.ph-van:before{content:""}.ph.ph-vault:before{content:""}.ph.ph-vector-three:before{content:""}.ph.ph-vector-two:before{content:""}.ph.ph-vibrate:before{content:""}.ph.ph-video:before{content:""}.ph.ph-video-camera:before{content:""}.ph.ph-video-camera-slash:before{content:""}.ph.ph-video-conference:before{content:""}.ph.ph-vignette:before{content:""}.ph.ph-vinyl-record:before{content:""}.ph.ph-virtual-reality:before{content:""}.ph.ph-virus:before{content:""}.ph.ph-visor:before{content:""}.ph.ph-voicemail:before{content:""}.ph.ph-volleyball:before{content:""}.ph.ph-wall:before{content:""}.ph.ph-wallet:before{content:""}.ph.ph-warehouse:before{content:""}.ph.ph-warning:before{content:""}.ph.ph-warning-circle:before{content:""}.ph.ph-warning-diamond:before{content:""}.ph.ph-warning-octagon:before{content:""}.ph.ph-washing-machine:before{content:""}.ph.ph-watch:before{content:""}.ph.ph-wave-sawtooth:before{content:""}.ph.ph-wave-sine:before{content:""}.ph.ph-wave-square:before{content:""}.ph.ph-wave-triangle:before{content:""}.ph.ph-waveform:before{content:""}.ph.ph-waveform-slash:before{content:""}.ph.ph-waves:before{content:""}.ph.ph-webcam:before{content:""}.ph.ph-webcam-slash:before{content:""}.ph.ph-webhooks-logo:before{content:""}.ph.ph-wechat-logo:before{content:""}.ph.ph-whatsapp-logo:before{content:""}.ph.ph-wheelchair:before{content:""}.ph.ph-wheelchair-motion:before{content:""}.ph.ph-wifi-high:before{content:""}.ph.ph-wifi-low:before{content:""}.ph.ph-wifi-medium:before{content:""}.ph.ph-wifi-none:before{content:""}.ph.ph-wifi-slash:before{content:""}.ph.ph-wifi-x:before{content:""}.ph.ph-wind:before{content:""}.ph.ph-windmill:before{content:""}.ph.ph-windows-logo:before{content:""}.ph.ph-wine:before{content:""}.ph.ph-wrench:before{content:""}.ph.ph-x:before{content:""}.ph.ph-x-circle:before{content:""}.ph.ph-x-logo:before{content:""}.ph.ph-x-square:before{content:""}.ph.ph-yarn:before{content:""}.ph.ph-yin-yang:before{content:""}.ph.ph-youtube-logo:before{content:""}@font-face{font-family:Phosphor-Fill;src:url(/assets/Phosphor-Fill-D4CDmGRg.woff2) format("woff2"),url(/assets/Phosphor-Fill-CS2zOYDV.woff) format("woff"),url(/assets/Phosphor-Fill-N9gYSHy0.ttf) format("truetype"),url(/assets/Phosphor-Fill-BofDnXwa.svg#Phosphor-Fill) format("svg");font-weight:400;font-style:normal;font-display:block}.ph-fill{font-family:Phosphor-Fill!important;speak:never;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;letter-spacing:0;-webkit-font-feature-settings:"liga";-moz-font-feature-settings:"liga=1";-moz-font-feature-settings:"liga";-ms-font-feature-settings:"liga" 1;font-feature-settings:"liga";-webkit-font-variant-ligatures:discretionary-ligatures;font-variant-ligatures:discretionary-ligatures;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.ph-fill.ph-acorn:before{content:""}.ph-fill.ph-address-book:before{content:""}.ph-fill.ph-address-book-tabs:before{content:""}.ph-fill.ph-air-traffic-control:before{content:""}.ph-fill.ph-airplane:before{content:""}.ph-fill.ph-airplane-in-flight:before{content:""}.ph-fill.ph-airplane-landing:before{content:""}.ph-fill.ph-airplane-takeoff:before{content:""}.ph-fill.ph-airplane-taxiing:before{content:""}.ph-fill.ph-airplane-tilt:before{content:""}.ph-fill.ph-airplay:before{content:""}.ph-fill.ph-alarm:before{content:""}.ph-fill.ph-alien:before{content:""}.ph-fill.ph-align-bottom:before{content:""}.ph-fill.ph-align-bottom-simple:before{content:""}.ph-fill.ph-align-center-horizontal:before{content:""}.ph-fill.ph-align-center-horizontal-simple:before{content:""}.ph-fill.ph-align-center-vertical:before{content:""}.ph-fill.ph-align-center-vertical-simple:before{content:""}.ph-fill.ph-align-left:before{content:""}.ph-fill.ph-align-left-simple:before{content:""}.ph-fill.ph-align-right:before{content:""}.ph-fill.ph-align-right-simple:before{content:""}.ph-fill.ph-align-top:before{content:""}.ph-fill.ph-align-top-simple:before{content:""}.ph-fill.ph-amazon-logo:before{content:""}.ph-fill.ph-ambulance:before{content:""}.ph-fill.ph-anchor:before{content:""}.ph-fill.ph-anchor-simple:before{content:""}.ph-fill.ph-android-logo:before{content:""}.ph-fill.ph-angle:before{content:""}.ph-fill.ph-angular-logo:before{content:""}.ph-fill.ph-aperture:before{content:""}.ph-fill.ph-app-store-logo:before{content:""}.ph-fill.ph-app-window:before{content:""}.ph-fill.ph-apple-logo:before{content:""}.ph-fill.ph-apple-podcasts-logo:before{content:""}.ph-fill.ph-approximate-equals:before{content:""}.ph-fill.ph-archive:before{content:""}.ph-fill.ph-armchair:before{content:""}.ph-fill.ph-arrow-arc-left:before{content:""}.ph-fill.ph-arrow-arc-right:before{content:""}.ph-fill.ph-arrow-bend-double-up-left:before{content:""}.ph-fill.ph-arrow-bend-double-up-right:before{content:""}.ph-fill.ph-arrow-bend-down-left:before{content:""}.ph-fill.ph-arrow-bend-down-right:before{content:""}.ph-fill.ph-arrow-bend-left-down:before{content:""}.ph-fill.ph-arrow-bend-left-up:before{content:""}.ph-fill.ph-arrow-bend-right-down:before{content:""}.ph-fill.ph-arrow-bend-right-up:before{content:""}.ph-fill.ph-arrow-bend-up-left:before{content:""}.ph-fill.ph-arrow-bend-up-right:before{content:""}.ph-fill.ph-arrow-circle-down:before{content:""}.ph-fill.ph-arrow-circle-down-left:before{content:""}.ph-fill.ph-arrow-circle-down-right:before{content:""}.ph-fill.ph-arrow-circle-left:before{content:""}.ph-fill.ph-arrow-circle-right:before{content:""}.ph-fill.ph-arrow-circle-up:before{content:""}.ph-fill.ph-arrow-circle-up-left:before{content:""}.ph-fill.ph-arrow-circle-up-right:before{content:""}.ph-fill.ph-arrow-clockwise:before{content:""}.ph-fill.ph-arrow-counter-clockwise:before{content:""}.ph-fill.ph-arrow-down:before{content:""}.ph-fill.ph-arrow-down-left:before{content:""}.ph-fill.ph-arrow-down-right:before{content:""}.ph-fill.ph-arrow-elbow-down-left:before{content:""}.ph-fill.ph-arrow-elbow-down-right:before{content:""}.ph-fill.ph-arrow-elbow-left:before{content:""}.ph-fill.ph-arrow-elbow-left-down:before{content:""}.ph-fill.ph-arrow-elbow-left-up:before{content:""}.ph-fill.ph-arrow-elbow-right:before{content:""}.ph-fill.ph-arrow-elbow-right-down:before{content:""}.ph-fill.ph-arrow-elbow-right-up:before{content:""}.ph-fill.ph-arrow-elbow-up-left:before{content:""}.ph-fill.ph-arrow-elbow-up-right:before{content:""}.ph-fill.ph-arrow-fat-down:before{content:""}.ph-fill.ph-arrow-fat-left:before{content:""}.ph-fill.ph-arrow-fat-line-down:before{content:""}.ph-fill.ph-arrow-fat-line-left:before{content:""}.ph-fill.ph-arrow-fat-line-right:before{content:""}.ph-fill.ph-arrow-fat-line-up:before{content:""}.ph-fill.ph-arrow-fat-lines-down:before{content:""}.ph-fill.ph-arrow-fat-lines-left:before{content:""}.ph-fill.ph-arrow-fat-lines-right:before{content:""}.ph-fill.ph-arrow-fat-lines-up:before{content:""}.ph-fill.ph-arrow-fat-right:before{content:""}.ph-fill.ph-arrow-fat-up:before{content:""}.ph-fill.ph-arrow-left:before{content:""}.ph-fill.ph-arrow-line-down:before{content:""}.ph-fill.ph-arrow-line-down-left:before{content:""}.ph-fill.ph-arrow-line-down-right:before{content:""}.ph-fill.ph-arrow-line-left:before{content:""}.ph-fill.ph-arrow-line-right:before{content:""}.ph-fill.ph-arrow-line-up:before{content:""}.ph-fill.ph-arrow-line-up-left:before{content:""}.ph-fill.ph-arrow-line-up-right:before{content:""}.ph-fill.ph-arrow-right:before{content:""}.ph-fill.ph-arrow-square-down:before{content:""}.ph-fill.ph-arrow-square-down-left:before{content:""}.ph-fill.ph-arrow-square-down-right:before{content:""}.ph-fill.ph-arrow-square-in:before{content:""}.ph-fill.ph-arrow-square-left:before{content:""}.ph-fill.ph-arrow-square-out:before{content:""}.ph-fill.ph-arrow-square-right:before{content:""}.ph-fill.ph-arrow-square-up:before{content:""}.ph-fill.ph-arrow-square-up-left:before{content:""}.ph-fill.ph-arrow-square-up-right:before{content:""}.ph-fill.ph-arrow-u-down-left:before{content:""}.ph-fill.ph-arrow-u-down-right:before{content:""}.ph-fill.ph-arrow-u-left-down:before{content:""}.ph-fill.ph-arrow-u-left-up:before{content:""}.ph-fill.ph-arrow-u-right-down:before{content:""}.ph-fill.ph-arrow-u-right-up:before{content:""}.ph-fill.ph-arrow-u-up-left:before{content:""}.ph-fill.ph-arrow-u-up-right:before{content:""}.ph-fill.ph-arrow-up:before{content:""}.ph-fill.ph-arrow-up-left:before{content:""}.ph-fill.ph-arrow-up-right:before{content:""}.ph-fill.ph-arrows-clockwise:before{content:""}.ph-fill.ph-arrows-counter-clockwise:before{content:""}.ph-fill.ph-arrows-down-up:before{content:""}.ph-fill.ph-arrows-horizontal:before{content:""}.ph-fill.ph-arrows-in:before{content:""}.ph-fill.ph-arrows-in-cardinal:before{content:""}.ph-fill.ph-arrows-in-line-horizontal:before{content:""}.ph-fill.ph-arrows-in-line-vertical:before{content:""}.ph-fill.ph-arrows-in-simple:before{content:""}.ph-fill.ph-arrows-left-right:before{content:""}.ph-fill.ph-arrows-merge:before{content:""}.ph-fill.ph-arrows-out:before{content:""}.ph-fill.ph-arrows-out-cardinal:before{content:""}.ph-fill.ph-arrows-out-line-horizontal:before{content:""}.ph-fill.ph-arrows-out-line-vertical:before{content:""}.ph-fill.ph-arrows-out-simple:before{content:""}.ph-fill.ph-arrows-split:before{content:""}.ph-fill.ph-arrows-vertical:before{content:""}.ph-fill.ph-article:before{content:""}.ph-fill.ph-article-medium:before{content:""}.ph-fill.ph-article-ny-times:before{content:""}.ph-fill.ph-asclepius:before{content:""}.ph-fill.ph-caduceus:before{content:""}.ph-fill.ph-asterisk:before{content:""}.ph-fill.ph-asterisk-simple:before{content:""}.ph-fill.ph-at:before{content:""}.ph-fill.ph-atom:before{content:""}.ph-fill.ph-avocado:before{content:""}.ph-fill.ph-axe:before{content:""}.ph-fill.ph-baby:before{content:""}.ph-fill.ph-baby-carriage:before{content:""}.ph-fill.ph-backpack:before{content:""}.ph-fill.ph-backspace:before{content:""}.ph-fill.ph-bag:before{content:""}.ph-fill.ph-bag-simple:before{content:""}.ph-fill.ph-balloon:before{content:""}.ph-fill.ph-bandaids:before{content:""}.ph-fill.ph-bank:before{content:""}.ph-fill.ph-barbell:before{content:""}.ph-fill.ph-barcode:before{content:""}.ph-fill.ph-barn:before{content:""}.ph-fill.ph-barricade:before{content:""}.ph-fill.ph-baseball:before{content:""}.ph-fill.ph-baseball-cap:before{content:""}.ph-fill.ph-baseball-helmet:before{content:""}.ph-fill.ph-basket:before{content:""}.ph-fill.ph-basketball:before{content:""}.ph-fill.ph-bathtub:before{content:""}.ph-fill.ph-battery-charging:before{content:""}.ph-fill.ph-battery-charging-vertical:before{content:""}.ph-fill.ph-battery-empty:before{content:""}.ph-fill.ph-battery-full:before{content:""}.ph-fill.ph-battery-high:before{content:""}.ph-fill.ph-battery-low:before{content:""}.ph-fill.ph-battery-medium:before{content:""}.ph-fill.ph-battery-plus:before{content:""}.ph-fill.ph-battery-plus-vertical:before{content:""}.ph-fill.ph-battery-vertical-empty:before{content:""}.ph-fill.ph-battery-vertical-full:before{content:""}.ph-fill.ph-battery-vertical-high:before{content:""}.ph-fill.ph-battery-vertical-low:before{content:""}.ph-fill.ph-battery-vertical-medium:before{content:""}.ph-fill.ph-battery-warning:before{content:""}.ph-fill.ph-battery-warning-vertical:before{content:""}.ph-fill.ph-beach-ball:before{content:""}.ph-fill.ph-beanie:before{content:""}.ph-fill.ph-bed:before{content:""}.ph-fill.ph-beer-bottle:before{content:""}.ph-fill.ph-beer-stein:before{content:""}.ph-fill.ph-behance-logo:before{content:""}.ph-fill.ph-bell:before{content:""}.ph-fill.ph-bell-ringing:before{content:""}.ph-fill.ph-bell-simple:before{content:""}.ph-fill.ph-bell-simple-ringing:before{content:""}.ph-fill.ph-bell-simple-slash:before{content:""}.ph-fill.ph-bell-simple-z:before{content:""}.ph-fill.ph-bell-slash:before{content:""}.ph-fill.ph-bell-z:before{content:""}.ph-fill.ph-belt:before{content:""}.ph-fill.ph-bezier-curve:before{content:""}.ph-fill.ph-bicycle:before{content:""}.ph-fill.ph-binary:before{content:""}.ph-fill.ph-binoculars:before{content:""}.ph-fill.ph-biohazard:before{content:""}.ph-fill.ph-bird:before{content:""}.ph-fill.ph-blueprint:before{content:""}.ph-fill.ph-bluetooth:before{content:""}.ph-fill.ph-bluetooth-connected:before{content:""}.ph-fill.ph-bluetooth-slash:before{content:""}.ph-fill.ph-bluetooth-x:before{content:""}.ph-fill.ph-boat:before{content:""}.ph-fill.ph-bomb:before{content:""}.ph-fill.ph-bone:before{content:""}.ph-fill.ph-book:before{content:""}.ph-fill.ph-book-bookmark:before{content:""}.ph-fill.ph-book-open:before{content:""}.ph-fill.ph-book-open-text:before{content:""}.ph-fill.ph-book-open-user:before{content:""}.ph-fill.ph-bookmark:before{content:""}.ph-fill.ph-bookmark-simple:before{content:""}.ph-fill.ph-bookmarks:before{content:""}.ph-fill.ph-bookmarks-simple:before{content:""}.ph-fill.ph-books:before{content:""}.ph-fill.ph-boot:before{content:""}.ph-fill.ph-boules:before{content:""}.ph-fill.ph-bounding-box:before{content:""}.ph-fill.ph-bowl-food:before{content:""}.ph-fill.ph-bowl-steam:before{content:""}.ph-fill.ph-bowling-ball:before{content:""}.ph-fill.ph-box-arrow-down:before{content:""}.ph-fill.ph-archive-box:before{content:""}.ph-fill.ph-box-arrow-up:before{content:""}.ph-fill.ph-boxing-glove:before{content:""}.ph-fill.ph-brackets-angle:before{content:""}.ph-fill.ph-brackets-curly:before{content:""}.ph-fill.ph-brackets-round:before{content:""}.ph-fill.ph-brackets-square:before{content:""}.ph-fill.ph-brain:before{content:""}.ph-fill.ph-brandy:before{content:""}.ph-fill.ph-bread:before{content:""}.ph-fill.ph-bridge:before{content:""}.ph-fill.ph-briefcase:before{content:""}.ph-fill.ph-briefcase-metal:before{content:""}.ph-fill.ph-broadcast:before{content:""}.ph-fill.ph-broom:before{content:""}.ph-fill.ph-browser:before{content:""}.ph-fill.ph-browsers:before{content:""}.ph-fill.ph-bug:before{content:""}.ph-fill.ph-bug-beetle:before{content:""}.ph-fill.ph-bug-droid:before{content:""}.ph-fill.ph-building:before{content:""}.ph-fill.ph-building-apartment:before{content:""}.ph-fill.ph-building-office:before{content:""}.ph-fill.ph-buildings:before{content:""}.ph-fill.ph-bulldozer:before{content:""}.ph-fill.ph-bus:before{content:""}.ph-fill.ph-butterfly:before{content:""}.ph-fill.ph-cable-car:before{content:""}.ph-fill.ph-cactus:before{content:""}.ph-fill.ph-cake:before{content:""}.ph-fill.ph-calculator:before{content:""}.ph-fill.ph-calendar:before{content:""}.ph-fill.ph-calendar-blank:before{content:""}.ph-fill.ph-calendar-check:before{content:""}.ph-fill.ph-calendar-dot:before{content:""}.ph-fill.ph-calendar-dots:before{content:""}.ph-fill.ph-calendar-heart:before{content:""}.ph-fill.ph-calendar-minus:before{content:""}.ph-fill.ph-calendar-plus:before{content:""}.ph-fill.ph-calendar-slash:before{content:""}.ph-fill.ph-calendar-star:before{content:""}.ph-fill.ph-calendar-x:before{content:""}.ph-fill.ph-call-bell:before{content:""}.ph-fill.ph-camera:before{content:""}.ph-fill.ph-camera-plus:before{content:""}.ph-fill.ph-camera-rotate:before{content:""}.ph-fill.ph-camera-slash:before{content:""}.ph-fill.ph-campfire:before{content:""}.ph-fill.ph-car:before{content:""}.ph-fill.ph-car-battery:before{content:""}.ph-fill.ph-car-profile:before{content:""}.ph-fill.ph-car-simple:before{content:""}.ph-fill.ph-cardholder:before{content:""}.ph-fill.ph-cards:before{content:""}.ph-fill.ph-cards-three:before{content:""}.ph-fill.ph-caret-circle-double-down:before{content:""}.ph-fill.ph-caret-circle-double-left:before{content:""}.ph-fill.ph-caret-circle-double-right:before{content:""}.ph-fill.ph-caret-circle-double-up:before{content:""}.ph-fill.ph-caret-circle-down:before{content:""}.ph-fill.ph-caret-circle-left:before{content:""}.ph-fill.ph-caret-circle-right:before{content:""}.ph-fill.ph-caret-circle-up:before{content:""}.ph-fill.ph-caret-circle-up-down:before{content:""}.ph-fill.ph-caret-double-down:before{content:""}.ph-fill.ph-caret-double-left:before{content:""}.ph-fill.ph-caret-double-right:before{content:""}.ph-fill.ph-caret-double-up:before{content:""}.ph-fill.ph-caret-down:before{content:""}.ph-fill.ph-caret-left:before{content:""}.ph-fill.ph-caret-line-down:before{content:""}.ph-fill.ph-caret-line-left:before{content:""}.ph-fill.ph-caret-line-right:before{content:""}.ph-fill.ph-caret-line-up:before{content:""}.ph-fill.ph-caret-right:before{content:""}.ph-fill.ph-caret-up:before{content:""}.ph-fill.ph-caret-up-down:before{content:""}.ph-fill.ph-carrot:before{content:""}.ph-fill.ph-cash-register:before{content:""}.ph-fill.ph-cassette-tape:before{content:""}.ph-fill.ph-castle-turret:before{content:""}.ph-fill.ph-cat:before{content:""}.ph-fill.ph-cell-signal-full:before{content:""}.ph-fill.ph-cell-signal-high:before{content:""}.ph-fill.ph-cell-signal-low:before{content:""}.ph-fill.ph-cell-signal-medium:before{content:""}.ph-fill.ph-cell-signal-none:before{content:""}.ph-fill.ph-cell-signal-slash:before{content:""}.ph-fill.ph-cell-signal-x:before{content:""}.ph-fill.ph-cell-tower:before{content:""}.ph-fill.ph-certificate:before{content:""}.ph-fill.ph-chair:before{content:""}.ph-fill.ph-chalkboard:before{content:""}.ph-fill.ph-chalkboard-simple:before{content:""}.ph-fill.ph-chalkboard-teacher:before{content:""}.ph-fill.ph-champagne:before{content:""}.ph-fill.ph-charging-station:before{content:""}.ph-fill.ph-chart-bar:before{content:""}.ph-fill.ph-chart-bar-horizontal:before{content:""}.ph-fill.ph-chart-donut:before{content:""}.ph-fill.ph-chart-line:before{content:""}.ph-fill.ph-chart-line-down:before{content:""}.ph-fill.ph-chart-line-up:before{content:""}.ph-fill.ph-chart-pie:before{content:""}.ph-fill.ph-chart-pie-slice:before{content:""}.ph-fill.ph-chart-polar:before{content:""}.ph-fill.ph-chart-scatter:before{content:""}.ph-fill.ph-chat:before{content:""}.ph-fill.ph-chat-centered:before{content:""}.ph-fill.ph-chat-centered-dots:before{content:""}.ph-fill.ph-chat-centered-slash:before{content:""}.ph-fill.ph-chat-centered-text:before{content:""}.ph-fill.ph-chat-circle:before{content:""}.ph-fill.ph-chat-circle-dots:before{content:""}.ph-fill.ph-chat-circle-slash:before{content:""}.ph-fill.ph-chat-circle-text:before{content:""}.ph-fill.ph-chat-dots:before{content:""}.ph-fill.ph-chat-slash:before{content:""}.ph-fill.ph-chat-teardrop:before{content:""}.ph-fill.ph-chat-teardrop-dots:before{content:""}.ph-fill.ph-chat-teardrop-slash:before{content:""}.ph-fill.ph-chat-teardrop-text:before{content:""}.ph-fill.ph-chat-text:before{content:""}.ph-fill.ph-chats:before{content:""}.ph-fill.ph-chats-circle:before{content:""}.ph-fill.ph-chats-teardrop:before{content:""}.ph-fill.ph-check:before{content:""}.ph-fill.ph-check-circle:before{content:""}.ph-fill.ph-check-fat:before{content:""}.ph-fill.ph-check-square:before{content:""}.ph-fill.ph-check-square-offset:before{content:""}.ph-fill.ph-checkerboard:before{content:""}.ph-fill.ph-checks:before{content:""}.ph-fill.ph-cheers:before{content:""}.ph-fill.ph-cheese:before{content:""}.ph-fill.ph-chef-hat:before{content:""}.ph-fill.ph-cherries:before{content:""}.ph-fill.ph-church:before{content:""}.ph-fill.ph-cigarette:before{content:""}.ph-fill.ph-cigarette-slash:before{content:""}.ph-fill.ph-circle:before{content:""}.ph-fill.ph-circle-dashed:before{content:""}.ph-fill.ph-circle-half:before{content:""}.ph-fill.ph-circle-half-tilt:before{content:""}.ph-fill.ph-circle-notch:before{content:""}.ph-fill.ph-circles-four:before{content:""}.ph-fill.ph-circles-three:before{content:""}.ph-fill.ph-circles-three-plus:before{content:""}.ph-fill.ph-circuitry:before{content:""}.ph-fill.ph-city:before{content:""}.ph-fill.ph-clipboard:before{content:""}.ph-fill.ph-clipboard-text:before{content:""}.ph-fill.ph-clock:before{content:""}.ph-fill.ph-clock-afternoon:before{content:""}.ph-fill.ph-clock-clockwise:before{content:""}.ph-fill.ph-clock-countdown:before{content:""}.ph-fill.ph-clock-counter-clockwise:before{content:""}.ph-fill.ph-clock-user:before{content:""}.ph-fill.ph-closed-captioning:before{content:""}.ph-fill.ph-cloud:before{content:""}.ph-fill.ph-cloud-arrow-down:before{content:""}.ph-fill.ph-cloud-arrow-up:before{content:""}.ph-fill.ph-cloud-check:before{content:""}.ph-fill.ph-cloud-fog:before{content:""}.ph-fill.ph-cloud-lightning:before{content:""}.ph-fill.ph-cloud-moon:before{content:""}.ph-fill.ph-cloud-rain:before{content:""}.ph-fill.ph-cloud-slash:before{content:""}.ph-fill.ph-cloud-snow:before{content:""}.ph-fill.ph-cloud-sun:before{content:""}.ph-fill.ph-cloud-warning:before{content:""}.ph-fill.ph-cloud-x:before{content:""}.ph-fill.ph-clover:before{content:""}.ph-fill.ph-club:before{content:""}.ph-fill.ph-coat-hanger:before{content:""}.ph-fill.ph-coda-logo:before{content:""}.ph-fill.ph-code:before{content:""}.ph-fill.ph-code-block:before{content:""}.ph-fill.ph-code-simple:before{content:""}.ph-fill.ph-codepen-logo:before{content:""}.ph-fill.ph-codesandbox-logo:before{content:""}.ph-fill.ph-coffee:before{content:""}.ph-fill.ph-coffee-bean:before{content:""}.ph-fill.ph-coin:before{content:""}.ph-fill.ph-coin-vertical:before{content:""}.ph-fill.ph-coins:before{content:""}.ph-fill.ph-columns:before{content:""}.ph-fill.ph-columns-plus-left:before{content:""}.ph-fill.ph-columns-plus-right:before{content:""}.ph-fill.ph-command:before{content:""}.ph-fill.ph-compass:before{content:""}.ph-fill.ph-compass-rose:before{content:""}.ph-fill.ph-compass-tool:before{content:""}.ph-fill.ph-computer-tower:before{content:""}.ph-fill.ph-confetti:before{content:""}.ph-fill.ph-contactless-payment:before{content:""}.ph-fill.ph-control:before{content:""}.ph-fill.ph-cookie:before{content:""}.ph-fill.ph-cooking-pot:before{content:""}.ph-fill.ph-copy:before{content:""}.ph-fill.ph-copy-simple:before{content:""}.ph-fill.ph-copyleft:before{content:""}.ph-fill.ph-copyright:before{content:""}.ph-fill.ph-corners-in:before{content:""}.ph-fill.ph-corners-out:before{content:""}.ph-fill.ph-couch:before{content:""}.ph-fill.ph-court-basketball:before{content:""}.ph-fill.ph-cow:before{content:""}.ph-fill.ph-cowboy-hat:before{content:""}.ph-fill.ph-cpu:before{content:""}.ph-fill.ph-crane:before{content:""}.ph-fill.ph-crane-tower:before{content:""}.ph-fill.ph-credit-card:before{content:""}.ph-fill.ph-cricket:before{content:""}.ph-fill.ph-crop:before{content:""}.ph-fill.ph-cross:before{content:""}.ph-fill.ph-crosshair:before{content:""}.ph-fill.ph-crosshair-simple:before{content:""}.ph-fill.ph-crown:before{content:""}.ph-fill.ph-crown-cross:before{content:""}.ph-fill.ph-crown-simple:before{content:""}.ph-fill.ph-cube:before{content:""}.ph-fill.ph-cube-focus:before{content:""}.ph-fill.ph-cube-transparent:before{content:""}.ph-fill.ph-currency-btc:before{content:""}.ph-fill.ph-currency-circle-dollar:before{content:""}.ph-fill.ph-currency-cny:before{content:""}.ph-fill.ph-currency-dollar:before{content:""}.ph-fill.ph-currency-dollar-simple:before{content:""}.ph-fill.ph-currency-eth:before{content:""}.ph-fill.ph-currency-eur:before{content:""}.ph-fill.ph-currency-gbp:before{content:""}.ph-fill.ph-currency-inr:before{content:""}.ph-fill.ph-currency-jpy:before{content:""}.ph-fill.ph-currency-krw:before{content:""}.ph-fill.ph-currency-kzt:before{content:""}.ph-fill.ph-currency-ngn:before{content:""}.ph-fill.ph-currency-rub:before{content:""}.ph-fill.ph-cursor:before{content:""}.ph-fill.ph-cursor-click:before{content:""}.ph-fill.ph-cursor-text:before{content:""}.ph-fill.ph-cylinder:before{content:""}.ph-fill.ph-database:before{content:""}.ph-fill.ph-desk:before{content:""}.ph-fill.ph-desktop:before{content:""}.ph-fill.ph-desktop-tower:before{content:""}.ph-fill.ph-detective:before{content:""}.ph-fill.ph-dev-to-logo:before{content:""}.ph-fill.ph-device-mobile:before{content:""}.ph-fill.ph-device-mobile-camera:before{content:""}.ph-fill.ph-device-mobile-slash:before{content:""}.ph-fill.ph-device-mobile-speaker:before{content:""}.ph-fill.ph-device-rotate:before{content:""}.ph-fill.ph-device-tablet:before{content:""}.ph-fill.ph-device-tablet-camera:before{content:""}.ph-fill.ph-device-tablet-speaker:before{content:""}.ph-fill.ph-devices:before{content:""}.ph-fill.ph-diamond:before{content:""}.ph-fill.ph-diamonds-four:before{content:""}.ph-fill.ph-dice-five:before{content:""}.ph-fill.ph-dice-four:before{content:""}.ph-fill.ph-dice-one:before{content:""}.ph-fill.ph-dice-six:before{content:""}.ph-fill.ph-dice-three:before{content:""}.ph-fill.ph-dice-two:before{content:""}.ph-fill.ph-disc:before{content:""}.ph-fill.ph-disco-ball:before{content:""}.ph-fill.ph-discord-logo:before{content:""}.ph-fill.ph-divide:before{content:""}.ph-fill.ph-dna:before{content:""}.ph-fill.ph-dog:before{content:""}.ph-fill.ph-door:before{content:""}.ph-fill.ph-door-open:before{content:""}.ph-fill.ph-dot:before{content:""}.ph-fill.ph-dot-outline:before{content:""}.ph-fill.ph-dots-nine:before{content:""}.ph-fill.ph-dots-six:before{content:""}.ph-fill.ph-dots-six-vertical:before{content:""}.ph-fill.ph-dots-three:before{content:""}.ph-fill.ph-dots-three-circle:before{content:""}.ph-fill.ph-dots-three-circle-vertical:before{content:""}.ph-fill.ph-dots-three-outline:before{content:""}.ph-fill.ph-dots-three-outline-vertical:before{content:""}.ph-fill.ph-dots-three-vertical:before{content:""}.ph-fill.ph-download:before{content:""}.ph-fill.ph-download-simple:before{content:""}.ph-fill.ph-dress:before{content:""}.ph-fill.ph-dresser:before{content:""}.ph-fill.ph-dribbble-logo:before{content:""}.ph-fill.ph-drone:before{content:""}.ph-fill.ph-drop:before{content:""}.ph-fill.ph-drop-half:before{content:""}.ph-fill.ph-drop-half-bottom:before{content:""}.ph-fill.ph-drop-simple:before{content:""}.ph-fill.ph-drop-slash:before{content:""}.ph-fill.ph-dropbox-logo:before{content:""}.ph-fill.ph-ear:before{content:""}.ph-fill.ph-ear-slash:before{content:""}.ph-fill.ph-egg:before{content:""}.ph-fill.ph-egg-crack:before{content:""}.ph-fill.ph-eject:before{content:""}.ph-fill.ph-eject-simple:before{content:""}.ph-fill.ph-elevator:before{content:""}.ph-fill.ph-empty:before{content:""}.ph-fill.ph-engine:before{content:""}.ph-fill.ph-envelope:before{content:""}.ph-fill.ph-envelope-open:before{content:""}.ph-fill.ph-envelope-simple:before{content:""}.ph-fill.ph-envelope-simple-open:before{content:""}.ph-fill.ph-equalizer:before{content:""}.ph-fill.ph-equals:before{content:""}.ph-fill.ph-eraser:before{content:""}.ph-fill.ph-escalator-down:before{content:""}.ph-fill.ph-escalator-up:before{content:""}.ph-fill.ph-exam:before{content:""}.ph-fill.ph-exclamation-mark:before{content:""}.ph-fill.ph-exclude:before{content:""}.ph-fill.ph-exclude-square:before{content:""}.ph-fill.ph-export:before{content:""}.ph-fill.ph-eye:before{content:""}.ph-fill.ph-eye-closed:before{content:""}.ph-fill.ph-eye-slash:before{content:""}.ph-fill.ph-eyedropper:before{content:""}.ph-fill.ph-eyedropper-sample:before{content:""}.ph-fill.ph-eyeglasses:before{content:""}.ph-fill.ph-eyes:before{content:""}.ph-fill.ph-face-mask:before{content:""}.ph-fill.ph-facebook-logo:before{content:""}.ph-fill.ph-factory:before{content:""}.ph-fill.ph-faders:before{content:""}.ph-fill.ph-faders-horizontal:before{content:""}.ph-fill.ph-fallout-shelter:before{content:""}.ph-fill.ph-fan:before{content:""}.ph-fill.ph-farm:before{content:""}.ph-fill.ph-fast-forward:before{content:""}.ph-fill.ph-fast-forward-circle:before{content:""}.ph-fill.ph-feather:before{content:""}.ph-fill.ph-fediverse-logo:before{content:""}.ph-fill.ph-figma-logo:before{content:""}.ph-fill.ph-file:before{content:""}.ph-fill.ph-file-archive:before{content:""}.ph-fill.ph-file-arrow-down:before{content:""}.ph-fill.ph-file-arrow-up:before{content:""}.ph-fill.ph-file-audio:before{content:""}.ph-fill.ph-file-c:before{content:""}.ph-fill.ph-file-c-sharp:before{content:""}.ph-fill.ph-file-cloud:before{content:""}.ph-fill.ph-file-code:before{content:""}.ph-fill.ph-file-cpp:before{content:""}.ph-fill.ph-file-css:before{content:""}.ph-fill.ph-file-csv:before{content:""}.ph-fill.ph-file-dashed:before{content:""}.ph-fill.ph-file-dotted:before{content:""}.ph-fill.ph-file-doc:before{content:""}.ph-fill.ph-file-html:before{content:""}.ph-fill.ph-file-image:before{content:""}.ph-fill.ph-file-ini:before{content:""}.ph-fill.ph-file-jpg:before{content:""}.ph-fill.ph-file-js:before{content:""}.ph-fill.ph-file-jsx:before{content:""}.ph-fill.ph-file-lock:before{content:""}.ph-fill.ph-file-magnifying-glass:before{content:""}.ph-fill.ph-file-search:before{content:""}.ph-fill.ph-file-md:before{content:""}.ph-fill.ph-file-minus:before{content:""}.ph-fill.ph-file-pdf:before{content:""}.ph-fill.ph-file-plus:before{content:""}.ph-fill.ph-file-png:before{content:""}.ph-fill.ph-file-ppt:before{content:""}.ph-fill.ph-file-py:before{content:""}.ph-fill.ph-file-rs:before{content:""}.ph-fill.ph-file-sql:before{content:""}.ph-fill.ph-file-svg:before{content:""}.ph-fill.ph-file-text:before{content:""}.ph-fill.ph-file-ts:before{content:""}.ph-fill.ph-file-tsx:before{content:""}.ph-fill.ph-file-txt:before{content:""}.ph-fill.ph-file-video:before{content:""}.ph-fill.ph-file-vue:before{content:""}.ph-fill.ph-file-x:before{content:""}.ph-fill.ph-file-xls:before{content:""}.ph-fill.ph-file-zip:before{content:""}.ph-fill.ph-files:before{content:""}.ph-fill.ph-film-reel:before{content:""}.ph-fill.ph-film-script:before{content:""}.ph-fill.ph-film-slate:before{content:""}.ph-fill.ph-film-strip:before{content:""}.ph-fill.ph-fingerprint:before{content:""}.ph-fill.ph-fingerprint-simple:before{content:""}.ph-fill.ph-finn-the-human:before{content:""}.ph-fill.ph-fire:before{content:""}.ph-fill.ph-fire-extinguisher:before{content:""}.ph-fill.ph-fire-simple:before{content:""}.ph-fill.ph-fire-truck:before{content:""}.ph-fill.ph-first-aid:before{content:""}.ph-fill.ph-first-aid-kit:before{content:""}.ph-fill.ph-fish:before{content:""}.ph-fill.ph-fish-simple:before{content:""}.ph-fill.ph-flag:before{content:""}.ph-fill.ph-flag-banner:before{content:""}.ph-fill.ph-flag-banner-fold:before{content:""}.ph-fill.ph-flag-checkered:before{content:""}.ph-fill.ph-flag-pennant:before{content:""}.ph-fill.ph-flame:before{content:""}.ph-fill.ph-flashlight:before{content:""}.ph-fill.ph-flask:before{content:""}.ph-fill.ph-flip-horizontal:before{content:""}.ph-fill.ph-flip-vertical:before{content:""}.ph-fill.ph-floppy-disk:before{content:""}.ph-fill.ph-floppy-disk-back:before{content:""}.ph-fill.ph-flow-arrow:before{content:""}.ph-fill.ph-flower:before{content:""}.ph-fill.ph-flower-lotus:before{content:""}.ph-fill.ph-flower-tulip:before{content:""}.ph-fill.ph-flying-saucer:before{content:""}.ph-fill.ph-folder:before{content:""}.ph-fill.ph-folder-notch:before{content:""}.ph-fill.ph-folder-dashed:before{content:""}.ph-fill.ph-folder-dotted:before{content:""}.ph-fill.ph-folder-lock:before{content:""}.ph-fill.ph-folder-minus:before{content:""}.ph-fill.ph-folder-notch-minus:before{content:""}.ph-fill.ph-folder-open:before{content:""}.ph-fill.ph-folder-notch-open:before{content:""}.ph-fill.ph-folder-plus:before{content:""}.ph-fill.ph-folder-notch-plus:before{content:""}.ph-fill.ph-folder-simple:before{content:""}.ph-fill.ph-folder-simple-dashed:before{content:""}.ph-fill.ph-folder-simple-dotted:before{content:""}.ph-fill.ph-folder-simple-lock:before{content:""}.ph-fill.ph-folder-simple-minus:before{content:""}.ph-fill.ph-folder-simple-plus:before{content:""}.ph-fill.ph-folder-simple-star:before{content:""}.ph-fill.ph-folder-simple-user:before{content:""}.ph-fill.ph-folder-star:before{content:""}.ph-fill.ph-folder-user:before{content:""}.ph-fill.ph-folders:before{content:""}.ph-fill.ph-football:before{content:""}.ph-fill.ph-football-helmet:before{content:""}.ph-fill.ph-footprints:before{content:""}.ph-fill.ph-fork-knife:before{content:""}.ph-fill.ph-four-k:before{content:""}.ph-fill.ph-frame-corners:before{content:""}.ph-fill.ph-framer-logo:before{content:""}.ph-fill.ph-function:before{content:""}.ph-fill.ph-funnel:before{content:""}.ph-fill.ph-funnel-simple:before{content:""}.ph-fill.ph-funnel-simple-x:before{content:""}.ph-fill.ph-funnel-x:before{content:""}.ph-fill.ph-game-controller:before{content:""}.ph-fill.ph-garage:before{content:""}.ph-fill.ph-gas-can:before{content:""}.ph-fill.ph-gas-pump:before{content:""}.ph-fill.ph-gauge:before{content:""}.ph-fill.ph-gavel:before{content:""}.ph-fill.ph-gear:before{content:""}.ph-fill.ph-gear-fine:before{content:""}.ph-fill.ph-gear-six:before{content:""}.ph-fill.ph-gender-female:before{content:""}.ph-fill.ph-gender-intersex:before{content:""}.ph-fill.ph-gender-male:before{content:""}.ph-fill.ph-gender-neuter:before{content:""}.ph-fill.ph-gender-nonbinary:before{content:""}.ph-fill.ph-gender-transgender:before{content:""}.ph-fill.ph-ghost:before{content:""}.ph-fill.ph-gif:before{content:""}.ph-fill.ph-gift:before{content:""}.ph-fill.ph-git-branch:before{content:""}.ph-fill.ph-git-commit:before{content:""}.ph-fill.ph-git-diff:before{content:""}.ph-fill.ph-git-fork:before{content:""}.ph-fill.ph-git-merge:before{content:""}.ph-fill.ph-git-pull-request:before{content:""}.ph-fill.ph-github-logo:before{content:""}.ph-fill.ph-gitlab-logo:before{content:""}.ph-fill.ph-gitlab-logo-simple:before{content:""}.ph-fill.ph-globe:before{content:""}.ph-fill.ph-globe-hemisphere-east:before{content:""}.ph-fill.ph-globe-hemisphere-west:before{content:""}.ph-fill.ph-globe-simple:before{content:""}.ph-fill.ph-globe-simple-x:before{content:""}.ph-fill.ph-globe-stand:before{content:""}.ph-fill.ph-globe-x:before{content:""}.ph-fill.ph-goggles:before{content:""}.ph-fill.ph-golf:before{content:""}.ph-fill.ph-goodreads-logo:before{content:""}.ph-fill.ph-google-cardboard-logo:before{content:""}.ph-fill.ph-google-chrome-logo:before{content:""}.ph-fill.ph-google-drive-logo:before{content:""}.ph-fill.ph-google-logo:before{content:""}.ph-fill.ph-google-photos-logo:before{content:""}.ph-fill.ph-google-play-logo:before{content:""}.ph-fill.ph-google-podcasts-logo:before{content:""}.ph-fill.ph-gps:before{content:""}.ph-fill.ph-gps-fix:before{content:""}.ph-fill.ph-gps-slash:before{content:""}.ph-fill.ph-gradient:before{content:""}.ph-fill.ph-graduation-cap:before{content:""}.ph-fill.ph-grains:before{content:""}.ph-fill.ph-grains-slash:before{content:""}.ph-fill.ph-graph:before{content:""}.ph-fill.ph-graphics-card:before{content:""}.ph-fill.ph-greater-than:before{content:""}.ph-fill.ph-greater-than-or-equal:before{content:""}.ph-fill.ph-grid-four:before{content:""}.ph-fill.ph-grid-nine:before{content:""}.ph-fill.ph-guitar:before{content:""}.ph-fill.ph-hair-dryer:before{content:""}.ph-fill.ph-hamburger:before{content:""}.ph-fill.ph-hammer:before{content:""}.ph-fill.ph-hand:before{content:""}.ph-fill.ph-hand-arrow-down:before{content:""}.ph-fill.ph-hand-arrow-up:before{content:""}.ph-fill.ph-hand-coins:before{content:""}.ph-fill.ph-hand-deposit:before{content:""}.ph-fill.ph-hand-eye:before{content:""}.ph-fill.ph-hand-fist:before{content:""}.ph-fill.ph-hand-grabbing:before{content:""}.ph-fill.ph-hand-heart:before{content:""}.ph-fill.ph-hand-palm:before{content:""}.ph-fill.ph-hand-peace:before{content:""}.ph-fill.ph-hand-pointing:before{content:""}.ph-fill.ph-hand-soap:before{content:""}.ph-fill.ph-hand-swipe-left:before{content:""}.ph-fill.ph-hand-swipe-right:before{content:""}.ph-fill.ph-hand-tap:before{content:""}.ph-fill.ph-hand-waving:before{content:""}.ph-fill.ph-hand-withdraw:before{content:""}.ph-fill.ph-handbag:before{content:""}.ph-fill.ph-handbag-simple:before{content:""}.ph-fill.ph-hands-clapping:before{content:""}.ph-fill.ph-hands-praying:before{content:""}.ph-fill.ph-handshake:before{content:""}.ph-fill.ph-hard-drive:before{content:""}.ph-fill.ph-hard-drives:before{content:""}.ph-fill.ph-hard-hat:before{content:""}.ph-fill.ph-hash:before{content:""}.ph-fill.ph-hash-straight:before{content:""}.ph-fill.ph-head-circuit:before{content:""}.ph-fill.ph-headlights:before{content:""}.ph-fill.ph-headphones:before{content:""}.ph-fill.ph-headset:before{content:""}.ph-fill.ph-heart:before{content:""}.ph-fill.ph-heart-break:before{content:""}.ph-fill.ph-heart-half:before{content:""}.ph-fill.ph-heart-straight:before{content:""}.ph-fill.ph-heart-straight-break:before{content:""}.ph-fill.ph-heartbeat:before{content:""}.ph-fill.ph-hexagon:before{content:""}.ph-fill.ph-high-definition:before{content:""}.ph-fill.ph-high-heel:before{content:""}.ph-fill.ph-highlighter:before{content:""}.ph-fill.ph-highlighter-circle:before{content:""}.ph-fill.ph-hockey:before{content:""}.ph-fill.ph-hoodie:before{content:""}.ph-fill.ph-horse:before{content:""}.ph-fill.ph-hospital:before{content:""}.ph-fill.ph-hourglass:before{content:""}.ph-fill.ph-hourglass-high:before{content:""}.ph-fill.ph-hourglass-low:before{content:""}.ph-fill.ph-hourglass-medium:before{content:""}.ph-fill.ph-hourglass-simple:before{content:""}.ph-fill.ph-hourglass-simple-high:before{content:""}.ph-fill.ph-hourglass-simple-low:before{content:""}.ph-fill.ph-hourglass-simple-medium:before{content:""}.ph-fill.ph-house:before{content:""}.ph-fill.ph-house-line:before{content:""}.ph-fill.ph-house-simple:before{content:""}.ph-fill.ph-hurricane:before{content:""}.ph-fill.ph-ice-cream:before{content:""}.ph-fill.ph-identification-badge:before{content:""}.ph-fill.ph-identification-card:before{content:""}.ph-fill.ph-image:before{content:""}.ph-fill.ph-image-broken:before{content:""}.ph-fill.ph-image-square:before{content:""}.ph-fill.ph-images:before{content:""}.ph-fill.ph-images-square:before{content:""}.ph-fill.ph-infinity:before{content:""}.ph-fill.ph-lemniscate:before{content:""}.ph-fill.ph-info:before{content:""}.ph-fill.ph-instagram-logo:before{content:""}.ph-fill.ph-intersect:before{content:""}.ph-fill.ph-intersect-square:before{content:""}.ph-fill.ph-intersect-three:before{content:""}.ph-fill.ph-intersection:before{content:""}.ph-fill.ph-invoice:before{content:""}.ph-fill.ph-island:before{content:""}.ph-fill.ph-jar:before{content:""}.ph-fill.ph-jar-label:before{content:""}.ph-fill.ph-jeep:before{content:""}.ph-fill.ph-joystick:before{content:""}.ph-fill.ph-kanban:before{content:""}.ph-fill.ph-key:before{content:""}.ph-fill.ph-key-return:before{content:""}.ph-fill.ph-keyboard:before{content:""}.ph-fill.ph-keyhole:before{content:""}.ph-fill.ph-knife:before{content:""}.ph-fill.ph-ladder:before{content:""}.ph-fill.ph-ladder-simple:before{content:""}.ph-fill.ph-lamp:before{content:""}.ph-fill.ph-lamp-pendant:before{content:""}.ph-fill.ph-laptop:before{content:""}.ph-fill.ph-lasso:before{content:""}.ph-fill.ph-lastfm-logo:before{content:""}.ph-fill.ph-layout:before{content:""}.ph-fill.ph-leaf:before{content:""}.ph-fill.ph-lectern:before{content:""}.ph-fill.ph-lego:before{content:""}.ph-fill.ph-lego-smiley:before{content:""}.ph-fill.ph-less-than:before{content:""}.ph-fill.ph-less-than-or-equal:before{content:""}.ph-fill.ph-letter-circle-h:before{content:""}.ph-fill.ph-letter-circle-p:before{content:""}.ph-fill.ph-letter-circle-v:before{content:""}.ph-fill.ph-lifebuoy:before{content:""}.ph-fill.ph-lightbulb:before{content:""}.ph-fill.ph-lightbulb-filament:before{content:""}.ph-fill.ph-lighthouse:before{content:""}.ph-fill.ph-lightning:before{content:""}.ph-fill.ph-lightning-a:before{content:""}.ph-fill.ph-lightning-slash:before{content:""}.ph-fill.ph-line-segment:before{content:""}.ph-fill.ph-line-segments:before{content:""}.ph-fill.ph-line-vertical:before{content:""}.ph-fill.ph-link:before{content:""}.ph-fill.ph-link-break:before{content:""}.ph-fill.ph-link-simple:before{content:""}.ph-fill.ph-link-simple-break:before{content:""}.ph-fill.ph-link-simple-horizontal:before{content:""}.ph-fill.ph-link-simple-horizontal-break:before{content:""}.ph-fill.ph-linkedin-logo:before{content:""}.ph-fill.ph-linktree-logo:before{content:""}.ph-fill.ph-linux-logo:before{content:""}.ph-fill.ph-list:before{content:""}.ph-fill.ph-list-bullets:before{content:""}.ph-fill.ph-list-checks:before{content:""}.ph-fill.ph-list-dashes:before{content:""}.ph-fill.ph-list-heart:before{content:""}.ph-fill.ph-list-magnifying-glass:before{content:""}.ph-fill.ph-list-numbers:before{content:""}.ph-fill.ph-list-plus:before{content:""}.ph-fill.ph-list-star:before{content:""}.ph-fill.ph-lock:before{content:""}.ph-fill.ph-lock-key:before{content:""}.ph-fill.ph-lock-key-open:before{content:""}.ph-fill.ph-lock-laminated:before{content:""}.ph-fill.ph-lock-laminated-open:before{content:""}.ph-fill.ph-lock-open:before{content:""}.ph-fill.ph-lock-simple:before{content:""}.ph-fill.ph-lock-simple-open:before{content:""}.ph-fill.ph-lockers:before{content:""}.ph-fill.ph-log:before{content:""}.ph-fill.ph-magic-wand:before{content:""}.ph-fill.ph-magnet:before{content:""}.ph-fill.ph-magnet-straight:before{content:""}.ph-fill.ph-magnifying-glass:before{content:""}.ph-fill.ph-magnifying-glass-minus:before{content:""}.ph-fill.ph-magnifying-glass-plus:before{content:""}.ph-fill.ph-mailbox:before{content:""}.ph-fill.ph-map-pin:before{content:""}.ph-fill.ph-map-pin-area:before{content:""}.ph-fill.ph-map-pin-line:before{content:""}.ph-fill.ph-map-pin-plus:before{content:""}.ph-fill.ph-map-pin-simple:before{content:""}.ph-fill.ph-map-pin-simple-area:before{content:""}.ph-fill.ph-map-pin-simple-line:before{content:""}.ph-fill.ph-map-trifold:before{content:""}.ph-fill.ph-markdown-logo:before{content:""}.ph-fill.ph-marker-circle:before{content:""}.ph-fill.ph-martini:before{content:""}.ph-fill.ph-mask-happy:before{content:""}.ph-fill.ph-mask-sad:before{content:""}.ph-fill.ph-mastodon-logo:before{content:""}.ph-fill.ph-math-operations:before{content:""}.ph-fill.ph-matrix-logo:before{content:""}.ph-fill.ph-medal:before{content:""}.ph-fill.ph-medal-military:before{content:""}.ph-fill.ph-medium-logo:before{content:""}.ph-fill.ph-megaphone:before{content:""}.ph-fill.ph-megaphone-simple:before{content:""}.ph-fill.ph-member-of:before{content:""}.ph-fill.ph-memory:before{content:""}.ph-fill.ph-messenger-logo:before{content:""}.ph-fill.ph-meta-logo:before{content:""}.ph-fill.ph-meteor:before{content:""}.ph-fill.ph-metronome:before{content:""}.ph-fill.ph-microphone:before{content:""}.ph-fill.ph-microphone-slash:before{content:""}.ph-fill.ph-microphone-stage:before{content:""}.ph-fill.ph-microscope:before{content:""}.ph-fill.ph-microsoft-excel-logo:before{content:""}.ph-fill.ph-microsoft-outlook-logo:before{content:""}.ph-fill.ph-microsoft-powerpoint-logo:before{content:""}.ph-fill.ph-microsoft-teams-logo:before{content:""}.ph-fill.ph-microsoft-word-logo:before{content:""}.ph-fill.ph-minus:before{content:""}.ph-fill.ph-minus-circle:before{content:""}.ph-fill.ph-minus-square:before{content:""}.ph-fill.ph-money:before{content:""}.ph-fill.ph-money-wavy:before{content:""}.ph-fill.ph-monitor:before{content:""}.ph-fill.ph-monitor-arrow-up:before{content:""}.ph-fill.ph-monitor-play:before{content:""}.ph-fill.ph-moon:before{content:""}.ph-fill.ph-moon-stars:before{content:""}.ph-fill.ph-moped:before{content:""}.ph-fill.ph-moped-front:before{content:""}.ph-fill.ph-mosque:before{content:""}.ph-fill.ph-motorcycle:before{content:""}.ph-fill.ph-mountains:before{content:""}.ph-fill.ph-mouse:before{content:""}.ph-fill.ph-mouse-left-click:before{content:""}.ph-fill.ph-mouse-middle-click:before{content:""}.ph-fill.ph-mouse-right-click:before{content:""}.ph-fill.ph-mouse-scroll:before{content:""}.ph-fill.ph-mouse-simple:before{content:""}.ph-fill.ph-music-note:before{content:""}.ph-fill.ph-music-note-simple:before{content:""}.ph-fill.ph-music-notes:before{content:""}.ph-fill.ph-music-notes-minus:before{content:""}.ph-fill.ph-music-notes-plus:before{content:""}.ph-fill.ph-music-notes-simple:before{content:""}.ph-fill.ph-navigation-arrow:before{content:""}.ph-fill.ph-needle:before{content:""}.ph-fill.ph-network:before{content:""}.ph-fill.ph-network-slash:before{content:""}.ph-fill.ph-network-x:before{content:""}.ph-fill.ph-newspaper:before{content:""}.ph-fill.ph-newspaper-clipping:before{content:""}.ph-fill.ph-not-equals:before{content:""}.ph-fill.ph-not-member-of:before{content:""}.ph-fill.ph-not-subset-of:before{content:""}.ph-fill.ph-not-superset-of:before{content:""}.ph-fill.ph-notches:before{content:""}.ph-fill.ph-note:before{content:""}.ph-fill.ph-note-blank:before{content:""}.ph-fill.ph-note-pencil:before{content:""}.ph-fill.ph-notebook:before{content:""}.ph-fill.ph-notepad:before{content:""}.ph-fill.ph-notification:before{content:""}.ph-fill.ph-notion-logo:before{content:""}.ph-fill.ph-nuclear-plant:before{content:""}.ph-fill.ph-number-circle-eight:before{content:""}.ph-fill.ph-number-circle-five:before{content:""}.ph-fill.ph-number-circle-four:before{content:""}.ph-fill.ph-number-circle-nine:before{content:""}.ph-fill.ph-number-circle-one:before{content:""}.ph-fill.ph-number-circle-seven:before{content:""}.ph-fill.ph-number-circle-six:before{content:""}.ph-fill.ph-number-circle-three:before{content:""}.ph-fill.ph-number-circle-two:before{content:""}.ph-fill.ph-number-circle-zero:before{content:""}.ph-fill.ph-number-eight:before{content:""}.ph-fill.ph-number-five:before{content:""}.ph-fill.ph-number-four:before{content:""}.ph-fill.ph-number-nine:before{content:""}.ph-fill.ph-number-one:before{content:""}.ph-fill.ph-number-seven:before{content:""}.ph-fill.ph-number-six:before{content:""}.ph-fill.ph-number-square-eight:before{content:""}.ph-fill.ph-number-square-five:before{content:""}.ph-fill.ph-number-square-four:before{content:""}.ph-fill.ph-number-square-nine:before{content:""}.ph-fill.ph-number-square-one:before{content:""}.ph-fill.ph-number-square-seven:before{content:""}.ph-fill.ph-number-square-six:before{content:""}.ph-fill.ph-number-square-three:before{content:""}.ph-fill.ph-number-square-two:before{content:""}.ph-fill.ph-number-square-zero:before{content:""}.ph-fill.ph-number-three:before{content:""}.ph-fill.ph-number-two:before{content:""}.ph-fill.ph-number-zero:before{content:""}.ph-fill.ph-numpad:before{content:""}.ph-fill.ph-nut:before{content:""}.ph-fill.ph-ny-times-logo:before{content:""}.ph-fill.ph-octagon:before{content:""}.ph-fill.ph-office-chair:before{content:""}.ph-fill.ph-onigiri:before{content:""}.ph-fill.ph-open-ai-logo:before{content:""}.ph-fill.ph-option:before{content:""}.ph-fill.ph-orange:before{content:""}.ph-fill.ph-orange-slice:before{content:""}.ph-fill.ph-oven:before{content:""}.ph-fill.ph-package:before{content:""}.ph-fill.ph-paint-brush:before{content:""}.ph-fill.ph-paint-brush-broad:before{content:""}.ph-fill.ph-paint-brush-household:before{content:""}.ph-fill.ph-paint-bucket:before{content:""}.ph-fill.ph-paint-roller:before{content:""}.ph-fill.ph-palette:before{content:""}.ph-fill.ph-panorama:before{content:""}.ph-fill.ph-pants:before{content:""}.ph-fill.ph-paper-plane:before{content:""}.ph-fill.ph-paper-plane-right:before{content:""}.ph-fill.ph-paper-plane-tilt:before{content:""}.ph-fill.ph-paperclip:before{content:""}.ph-fill.ph-paperclip-horizontal:before{content:""}.ph-fill.ph-parachute:before{content:""}.ph-fill.ph-paragraph:before{content:""}.ph-fill.ph-parallelogram:before{content:""}.ph-fill.ph-park:before{content:""}.ph-fill.ph-password:before{content:""}.ph-fill.ph-path:before{content:""}.ph-fill.ph-patreon-logo:before{content:""}.ph-fill.ph-pause:before{content:""}.ph-fill.ph-pause-circle:before{content:""}.ph-fill.ph-paw-print:before{content:""}.ph-fill.ph-paypal-logo:before{content:""}.ph-fill.ph-peace:before{content:""}.ph-fill.ph-pen:before{content:""}.ph-fill.ph-pen-nib:before{content:""}.ph-fill.ph-pen-nib-straight:before{content:""}.ph-fill.ph-pencil:before{content:""}.ph-fill.ph-pencil-circle:before{content:""}.ph-fill.ph-pencil-line:before{content:""}.ph-fill.ph-pencil-ruler:before{content:""}.ph-fill.ph-pencil-simple:before{content:""}.ph-fill.ph-pencil-simple-line:before{content:""}.ph-fill.ph-pencil-simple-slash:before{content:""}.ph-fill.ph-pencil-slash:before{content:""}.ph-fill.ph-pentagon:before{content:""}.ph-fill.ph-pentagram:before{content:""}.ph-fill.ph-pepper:before{content:""}.ph-fill.ph-percent:before{content:""}.ph-fill.ph-person:before{content:""}.ph-fill.ph-person-arms-spread:before{content:""}.ph-fill.ph-person-simple:before{content:""}.ph-fill.ph-person-simple-bike:before{content:""}.ph-fill.ph-person-simple-circle:before{content:""}.ph-fill.ph-person-simple-hike:before{content:""}.ph-fill.ph-person-simple-run:before{content:""}.ph-fill.ph-person-simple-ski:before{content:""}.ph-fill.ph-person-simple-snowboard:before{content:""}.ph-fill.ph-person-simple-swim:before{content:""}.ph-fill.ph-person-simple-tai-chi:before{content:""}.ph-fill.ph-person-simple-throw:before{content:""}.ph-fill.ph-person-simple-walk:before{content:""}.ph-fill.ph-perspective:before{content:""}.ph-fill.ph-phone:before{content:""}.ph-fill.ph-phone-call:before{content:""}.ph-fill.ph-phone-disconnect:before{content:""}.ph-fill.ph-phone-incoming:before{content:""}.ph-fill.ph-phone-list:before{content:""}.ph-fill.ph-phone-outgoing:before{content:""}.ph-fill.ph-phone-pause:before{content:""}.ph-fill.ph-phone-plus:before{content:""}.ph-fill.ph-phone-slash:before{content:""}.ph-fill.ph-phone-transfer:before{content:""}.ph-fill.ph-phone-x:before{content:""}.ph-fill.ph-phosphor-logo:before{content:""}.ph-fill.ph-pi:before{content:""}.ph-fill.ph-piano-keys:before{content:""}.ph-fill.ph-picnic-table:before{content:""}.ph-fill.ph-picture-in-picture:before{content:""}.ph-fill.ph-piggy-bank:before{content:""}.ph-fill.ph-pill:before{content:""}.ph-fill.ph-ping-pong:before{content:""}.ph-fill.ph-pint-glass:before{content:""}.ph-fill.ph-pinterest-logo:before{content:""}.ph-fill.ph-pinwheel:before{content:""}.ph-fill.ph-pipe:before{content:""}.ph-fill.ph-pipe-wrench:before{content:""}.ph-fill.ph-pix-logo:before{content:""}.ph-fill.ph-pizza:before{content:""}.ph-fill.ph-placeholder:before{content:""}.ph-fill.ph-planet:before{content:""}.ph-fill.ph-plant:before{content:""}.ph-fill.ph-play:before{content:""}.ph-fill.ph-play-circle:before{content:""}.ph-fill.ph-play-pause:before{content:""}.ph-fill.ph-playlist:before{content:""}.ph-fill.ph-plug:before{content:""}.ph-fill.ph-plug-charging:before{content:""}.ph-fill.ph-plugs:before{content:""}.ph-fill.ph-plugs-connected:before{content:""}.ph-fill.ph-plus:before{content:""}.ph-fill.ph-plus-circle:before{content:""}.ph-fill.ph-plus-minus:before{content:""}.ph-fill.ph-plus-square:before{content:""}.ph-fill.ph-poker-chip:before{content:""}.ph-fill.ph-police-car:before{content:""}.ph-fill.ph-polygon:before{content:""}.ph-fill.ph-popcorn:before{content:""}.ph-fill.ph-popsicle:before{content:""}.ph-fill.ph-potted-plant:before{content:""}.ph-fill.ph-power:before{content:""}.ph-fill.ph-prescription:before{content:""}.ph-fill.ph-presentation:before{content:""}.ph-fill.ph-presentation-chart:before{content:""}.ph-fill.ph-printer:before{content:""}.ph-fill.ph-prohibit:before{content:""}.ph-fill.ph-prohibit-inset:before{content:""}.ph-fill.ph-projector-screen:before{content:""}.ph-fill.ph-projector-screen-chart:before{content:""}.ph-fill.ph-pulse:before{content:""}.ph-fill.ph-activity:before{content:""}.ph-fill.ph-push-pin:before{content:""}.ph-fill.ph-push-pin-simple:before{content:""}.ph-fill.ph-push-pin-simple-slash:before{content:""}.ph-fill.ph-push-pin-slash:before{content:""}.ph-fill.ph-puzzle-piece:before{content:""}.ph-fill.ph-qr-code:before{content:""}.ph-fill.ph-question:before{content:""}.ph-fill.ph-question-mark:before{content:""}.ph-fill.ph-queue:before{content:""}.ph-fill.ph-quotes:before{content:""}.ph-fill.ph-rabbit:before{content:""}.ph-fill.ph-racquet:before{content:""}.ph-fill.ph-radical:before{content:""}.ph-fill.ph-radio:before{content:""}.ph-fill.ph-radio-button:before{content:""}.ph-fill.ph-radioactive:before{content:""}.ph-fill.ph-rainbow:before{content:""}.ph-fill.ph-rainbow-cloud:before{content:""}.ph-fill.ph-ranking:before{content:""}.ph-fill.ph-read-cv-logo:before{content:""}.ph-fill.ph-receipt:before{content:""}.ph-fill.ph-receipt-x:before{content:""}.ph-fill.ph-record:before{content:""}.ph-fill.ph-rectangle:before{content:""}.ph-fill.ph-rectangle-dashed:before{content:""}.ph-fill.ph-recycle:before{content:""}.ph-fill.ph-reddit-logo:before{content:""}.ph-fill.ph-repeat:before{content:""}.ph-fill.ph-repeat-once:before{content:""}.ph-fill.ph-replit-logo:before{content:""}.ph-fill.ph-resize:before{content:""}.ph-fill.ph-rewind:before{content:""}.ph-fill.ph-rewind-circle:before{content:""}.ph-fill.ph-road-horizon:before{content:""}.ph-fill.ph-robot:before{content:""}.ph-fill.ph-rocket:before{content:""}.ph-fill.ph-rocket-launch:before{content:""}.ph-fill.ph-rows:before{content:""}.ph-fill.ph-rows-plus-bottom:before{content:""}.ph-fill.ph-rows-plus-top:before{content:""}.ph-fill.ph-rss:before{content:""}.ph-fill.ph-rss-simple:before{content:""}.ph-fill.ph-rug:before{content:""}.ph-fill.ph-ruler:before{content:""}.ph-fill.ph-sailboat:before{content:""}.ph-fill.ph-scales:before{content:""}.ph-fill.ph-scan:before{content:""}.ph-fill.ph-scan-smiley:before{content:""}.ph-fill.ph-scissors:before{content:""}.ph-fill.ph-scooter:before{content:""}.ph-fill.ph-screencast:before{content:""}.ph-fill.ph-screwdriver:before{content:""}.ph-fill.ph-scribble:before{content:""}.ph-fill.ph-scribble-loop:before{content:""}.ph-fill.ph-scroll:before{content:""}.ph-fill.ph-seal:before{content:""}.ph-fill.ph-circle-wavy:before{content:""}.ph-fill.ph-seal-check:before{content:""}.ph-fill.ph-circle-wavy-check:before{content:""}.ph-fill.ph-seal-percent:before{content:""}.ph-fill.ph-seal-question:before{content:""}.ph-fill.ph-circle-wavy-question:before{content:""}.ph-fill.ph-seal-warning:before{content:""}.ph-fill.ph-circle-wavy-warning:before{content:""}.ph-fill.ph-seat:before{content:""}.ph-fill.ph-seatbelt:before{content:""}.ph-fill.ph-security-camera:before{content:""}.ph-fill.ph-selection:before{content:""}.ph-fill.ph-selection-all:before{content:""}.ph-fill.ph-selection-background:before{content:""}.ph-fill.ph-selection-foreground:before{content:""}.ph-fill.ph-selection-inverse:before{content:""}.ph-fill.ph-selection-plus:before{content:""}.ph-fill.ph-selection-slash:before{content:""}.ph-fill.ph-shapes:before{content:""}.ph-fill.ph-share:before{content:""}.ph-fill.ph-share-fat:before{content:""}.ph-fill.ph-share-network:before{content:""}.ph-fill.ph-shield:before{content:""}.ph-fill.ph-shield-check:before{content:""}.ph-fill.ph-shield-checkered:before{content:""}.ph-fill.ph-shield-chevron:before{content:""}.ph-fill.ph-shield-plus:before{content:""}.ph-fill.ph-shield-slash:before{content:""}.ph-fill.ph-shield-star:before{content:""}.ph-fill.ph-shield-warning:before{content:""}.ph-fill.ph-shipping-container:before{content:""}.ph-fill.ph-shirt-folded:before{content:""}.ph-fill.ph-shooting-star:before{content:""}.ph-fill.ph-shopping-bag:before{content:""}.ph-fill.ph-shopping-bag-open:before{content:""}.ph-fill.ph-shopping-cart:before{content:""}.ph-fill.ph-shopping-cart-simple:before{content:""}.ph-fill.ph-shovel:before{content:""}.ph-fill.ph-shower:before{content:""}.ph-fill.ph-shrimp:before{content:""}.ph-fill.ph-shuffle:before{content:""}.ph-fill.ph-shuffle-angular:before{content:""}.ph-fill.ph-shuffle-simple:before{content:""}.ph-fill.ph-sidebar:before{content:""}.ph-fill.ph-sidebar-simple:before{content:""}.ph-fill.ph-sigma:before{content:""}.ph-fill.ph-sign-in:before{content:""}.ph-fill.ph-sign-out:before{content:""}.ph-fill.ph-signature:before{content:""}.ph-fill.ph-signpost:before{content:""}.ph-fill.ph-sim-card:before{content:""}.ph-fill.ph-siren:before{content:""}.ph-fill.ph-sketch-logo:before{content:""}.ph-fill.ph-skip-back:before{content:""}.ph-fill.ph-skip-back-circle:before{content:""}.ph-fill.ph-skip-forward:before{content:""}.ph-fill.ph-skip-forward-circle:before{content:""}.ph-fill.ph-skull:before{content:""}.ph-fill.ph-skype-logo:before{content:""}.ph-fill.ph-slack-logo:before{content:""}.ph-fill.ph-sliders:before{content:""}.ph-fill.ph-sliders-horizontal:before{content:""}.ph-fill.ph-slideshow:before{content:""}.ph-fill.ph-smiley:before{content:""}.ph-fill.ph-smiley-angry:before{content:""}.ph-fill.ph-smiley-blank:before{content:""}.ph-fill.ph-smiley-meh:before{content:""}.ph-fill.ph-smiley-melting:before{content:""}.ph-fill.ph-smiley-nervous:before{content:""}.ph-fill.ph-smiley-sad:before{content:""}.ph-fill.ph-smiley-sticker:before{content:""}.ph-fill.ph-smiley-wink:before{content:""}.ph-fill.ph-smiley-x-eyes:before{content:""}.ph-fill.ph-snapchat-logo:before{content:""}.ph-fill.ph-sneaker:before{content:""}.ph-fill.ph-sneaker-move:before{content:""}.ph-fill.ph-snowflake:before{content:""}.ph-fill.ph-soccer-ball:before{content:""}.ph-fill.ph-sock:before{content:""}.ph-fill.ph-solar-panel:before{content:""}.ph-fill.ph-solar-roof:before{content:""}.ph-fill.ph-sort-ascending:before{content:""}.ph-fill.ph-sort-descending:before{content:""}.ph-fill.ph-soundcloud-logo:before{content:""}.ph-fill.ph-spade:before{content:""}.ph-fill.ph-sparkle:before{content:""}.ph-fill.ph-speaker-hifi:before{content:""}.ph-fill.ph-speaker-high:before{content:""}.ph-fill.ph-speaker-low:before{content:""}.ph-fill.ph-speaker-none:before{content:""}.ph-fill.ph-speaker-simple-high:before{content:""}.ph-fill.ph-speaker-simple-low:before{content:""}.ph-fill.ph-speaker-simple-none:before{content:""}.ph-fill.ph-speaker-simple-slash:before{content:""}.ph-fill.ph-speaker-simple-x:before{content:""}.ph-fill.ph-speaker-slash:before{content:""}.ph-fill.ph-speaker-x:before{content:""}.ph-fill.ph-speedometer:before{content:""}.ph-fill.ph-sphere:before{content:""}.ph-fill.ph-spinner:before{content:""}.ph-fill.ph-spinner-ball:before{content:""}.ph-fill.ph-spinner-gap:before{content:""}.ph-fill.ph-spiral:before{content:""}.ph-fill.ph-split-horizontal:before{content:""}.ph-fill.ph-split-vertical:before{content:""}.ph-fill.ph-spotify-logo:before{content:""}.ph-fill.ph-spray-bottle:before{content:""}.ph-fill.ph-square:before{content:""}.ph-fill.ph-square-half:before{content:""}.ph-fill.ph-square-half-bottom:before{content:""}.ph-fill.ph-square-logo:before{content:""}.ph-fill.ph-square-split-horizontal:before{content:""}.ph-fill.ph-square-split-vertical:before{content:""}.ph-fill.ph-squares-four:before{content:""}.ph-fill.ph-stack:before{content:""}.ph-fill.ph-stack-minus:before{content:""}.ph-fill.ph-stack-overflow-logo:before{content:""}.ph-fill.ph-stack-plus:before{content:""}.ph-fill.ph-stack-simple:before{content:""}.ph-fill.ph-stairs:before{content:""}.ph-fill.ph-stamp:before{content:""}.ph-fill.ph-standard-definition:before{content:""}.ph-fill.ph-star:before{content:""}.ph-fill.ph-star-and-crescent:before{content:""}.ph-fill.ph-star-four:before{content:""}.ph-fill.ph-star-half:before{content:""}.ph-fill.ph-star-of-david:before{content:""}.ph-fill.ph-steam-logo:before{content:""}.ph-fill.ph-steering-wheel:before{content:""}.ph-fill.ph-steps:before{content:""}.ph-fill.ph-stethoscope:before{content:""}.ph-fill.ph-sticker:before{content:""}.ph-fill.ph-stool:before{content:""}.ph-fill.ph-stop:before{content:""}.ph-fill.ph-stop-circle:before{content:""}.ph-fill.ph-storefront:before{content:""}.ph-fill.ph-strategy:before{content:""}.ph-fill.ph-stripe-logo:before{content:""}.ph-fill.ph-student:before{content:""}.ph-fill.ph-subset-of:before{content:""}.ph-fill.ph-subset-proper-of:before{content:""}.ph-fill.ph-subtitles:before{content:""}.ph-fill.ph-subtitles-slash:before{content:""}.ph-fill.ph-subtract:before{content:""}.ph-fill.ph-subtract-square:before{content:""}.ph-fill.ph-subway:before{content:""}.ph-fill.ph-suitcase:before{content:""}.ph-fill.ph-suitcase-rolling:before{content:""}.ph-fill.ph-suitcase-simple:before{content:""}.ph-fill.ph-sun:before{content:""}.ph-fill.ph-sun-dim:before{content:""}.ph-fill.ph-sun-horizon:before{content:""}.ph-fill.ph-sunglasses:before{content:""}.ph-fill.ph-superset-of:before{content:""}.ph-fill.ph-superset-proper-of:before{content:""}.ph-fill.ph-swap:before{content:""}.ph-fill.ph-swatches:before{content:""}.ph-fill.ph-swimming-pool:before{content:""}.ph-fill.ph-sword:before{content:""}.ph-fill.ph-synagogue:before{content:""}.ph-fill.ph-syringe:before{content:""}.ph-fill.ph-t-shirt:before{content:""}.ph-fill.ph-table:before{content:""}.ph-fill.ph-tabs:before{content:""}.ph-fill.ph-tag:before{content:""}.ph-fill.ph-tag-chevron:before{content:""}.ph-fill.ph-tag-simple:before{content:""}.ph-fill.ph-target:before{content:""}.ph-fill.ph-taxi:before{content:""}.ph-fill.ph-tea-bag:before{content:""}.ph-fill.ph-telegram-logo:before{content:""}.ph-fill.ph-television:before{content:""}.ph-fill.ph-television-simple:before{content:""}.ph-fill.ph-tennis-ball:before{content:""}.ph-fill.ph-tent:before{content:""}.ph-fill.ph-terminal:before{content:""}.ph-fill.ph-terminal-window:before{content:""}.ph-fill.ph-test-tube:before{content:""}.ph-fill.ph-text-a-underline:before{content:""}.ph-fill.ph-text-aa:before{content:""}.ph-fill.ph-text-align-center:before{content:""}.ph-fill.ph-text-align-justify:before{content:""}.ph-fill.ph-text-align-left:before{content:""}.ph-fill.ph-text-align-right:before{content:""}.ph-fill.ph-text-b:before{content:""}.ph-fill.ph-text-bolder:before{content:""}.ph-fill.ph-text-columns:before{content:""}.ph-fill.ph-text-h:before{content:""}.ph-fill.ph-text-h-five:before{content:""}.ph-fill.ph-text-h-four:before{content:""}.ph-fill.ph-text-h-one:before{content:""}.ph-fill.ph-text-h-six:before{content:""}.ph-fill.ph-text-h-three:before{content:""}.ph-fill.ph-text-h-two:before{content:""}.ph-fill.ph-text-indent:before{content:""}.ph-fill.ph-text-italic:before{content:""}.ph-fill.ph-text-outdent:before{content:""}.ph-fill.ph-text-strikethrough:before{content:""}.ph-fill.ph-text-subscript:before{content:""}.ph-fill.ph-text-superscript:before{content:""}.ph-fill.ph-text-t:before{content:""}.ph-fill.ph-text-t-slash:before{content:""}.ph-fill.ph-text-underline:before{content:""}.ph-fill.ph-textbox:before{content:""}.ph-fill.ph-thermometer:before{content:""}.ph-fill.ph-thermometer-cold:before{content:""}.ph-fill.ph-thermometer-hot:before{content:""}.ph-fill.ph-thermometer-simple:before{content:""}.ph-fill.ph-threads-logo:before{content:""}.ph-fill.ph-three-d:before{content:""}.ph-fill.ph-thumbs-down:before{content:""}.ph-fill.ph-thumbs-up:before{content:""}.ph-fill.ph-ticket:before{content:""}.ph-fill.ph-tidal-logo:before{content:""}.ph-fill.ph-tiktok-logo:before{content:""}.ph-fill.ph-tilde:before{content:""}.ph-fill.ph-timer:before{content:""}.ph-fill.ph-tip-jar:before{content:""}.ph-fill.ph-tipi:before{content:""}.ph-fill.ph-tire:before{content:""}.ph-fill.ph-toggle-left:before{content:""}.ph-fill.ph-toggle-right:before{content:""}.ph-fill.ph-toilet:before{content:""}.ph-fill.ph-toilet-paper:before{content:""}.ph-fill.ph-toolbox:before{content:""}.ph-fill.ph-tooth:before{content:""}.ph-fill.ph-tornado:before{content:""}.ph-fill.ph-tote:before{content:""}.ph-fill.ph-tote-simple:before{content:""}.ph-fill.ph-towel:before{content:""}.ph-fill.ph-tractor:before{content:""}.ph-fill.ph-trademark:before{content:""}.ph-fill.ph-trademark-registered:before{content:""}.ph-fill.ph-traffic-cone:before{content:""}.ph-fill.ph-traffic-sign:before{content:""}.ph-fill.ph-traffic-signal:before{content:""}.ph-fill.ph-train:before{content:""}.ph-fill.ph-train-regional:before{content:""}.ph-fill.ph-train-simple:before{content:""}.ph-fill.ph-tram:before{content:""}.ph-fill.ph-translate:before{content:""}.ph-fill.ph-trash:before{content:""}.ph-fill.ph-trash-simple:before{content:""}.ph-fill.ph-tray:before{content:""}.ph-fill.ph-tray-arrow-down:before{content:""}.ph-fill.ph-archive-tray:before{content:""}.ph-fill.ph-tray-arrow-up:before{content:""}.ph-fill.ph-treasure-chest:before{content:""}.ph-fill.ph-tree:before{content:""}.ph-fill.ph-tree-evergreen:before{content:""}.ph-fill.ph-tree-palm:before{content:""}.ph-fill.ph-tree-structure:before{content:""}.ph-fill.ph-tree-view:before{content:""}.ph-fill.ph-trend-down:before{content:""}.ph-fill.ph-trend-up:before{content:""}.ph-fill.ph-triangle:before{content:""}.ph-fill.ph-triangle-dashed:before{content:""}.ph-fill.ph-trolley:before{content:""}.ph-fill.ph-trolley-suitcase:before{content:""}.ph-fill.ph-trophy:before{content:""}.ph-fill.ph-truck:before{content:""}.ph-fill.ph-truck-trailer:before{content:""}.ph-fill.ph-tumblr-logo:before{content:""}.ph-fill.ph-twitch-logo:before{content:""}.ph-fill.ph-twitter-logo:before{content:""}.ph-fill.ph-umbrella:before{content:""}.ph-fill.ph-umbrella-simple:before{content:""}.ph-fill.ph-union:before{content:""}.ph-fill.ph-unite:before{content:""}.ph-fill.ph-unite-square:before{content:""}.ph-fill.ph-upload:before{content:""}.ph-fill.ph-upload-simple:before{content:""}.ph-fill.ph-usb:before{content:""}.ph-fill.ph-user:before{content:""}.ph-fill.ph-user-check:before{content:""}.ph-fill.ph-user-circle:before{content:""}.ph-fill.ph-user-circle-check:before{content:""}.ph-fill.ph-user-circle-dashed:before{content:""}.ph-fill.ph-user-circle-gear:before{content:""}.ph-fill.ph-user-circle-minus:before{content:""}.ph-fill.ph-user-circle-plus:before{content:""}.ph-fill.ph-user-focus:before{content:""}.ph-fill.ph-user-gear:before{content:""}.ph-fill.ph-user-list:before{content:""}.ph-fill.ph-user-minus:before{content:""}.ph-fill.ph-user-plus:before{content:""}.ph-fill.ph-user-rectangle:before{content:""}.ph-fill.ph-user-sound:before{content:""}.ph-fill.ph-user-square:before{content:""}.ph-fill.ph-user-switch:before{content:""}.ph-fill.ph-users:before{content:""}.ph-fill.ph-users-four:before{content:""}.ph-fill.ph-users-three:before{content:""}.ph-fill.ph-van:before{content:""}.ph-fill.ph-vault:before{content:""}.ph-fill.ph-vector-three:before{content:""}.ph-fill.ph-vector-two:before{content:""}.ph-fill.ph-vibrate:before{content:""}.ph-fill.ph-video:before{content:""}.ph-fill.ph-video-camera:before{content:""}.ph-fill.ph-video-camera-slash:before{content:""}.ph-fill.ph-video-conference:before{content:""}.ph-fill.ph-vignette:before{content:""}.ph-fill.ph-vinyl-record:before{content:""}.ph-fill.ph-virtual-reality:before{content:""}.ph-fill.ph-virus:before{content:""}.ph-fill.ph-visor:before{content:""}.ph-fill.ph-voicemail:before{content:""}.ph-fill.ph-volleyball:before{content:""}.ph-fill.ph-wall:before{content:""}.ph-fill.ph-wallet:before{content:""}.ph-fill.ph-warehouse:before{content:""}.ph-fill.ph-warning:before{content:""}.ph-fill.ph-warning-circle:before{content:""}.ph-fill.ph-warning-diamond:before{content:""}.ph-fill.ph-warning-octagon:before{content:""}.ph-fill.ph-washing-machine:before{content:""}.ph-fill.ph-watch:before{content:""}.ph-fill.ph-wave-sawtooth:before{content:""}.ph-fill.ph-wave-sine:before{content:""}.ph-fill.ph-wave-square:before{content:""}.ph-fill.ph-wave-triangle:before{content:""}.ph-fill.ph-waveform:before{content:""}.ph-fill.ph-waveform-slash:before{content:""}.ph-fill.ph-waves:before{content:""}.ph-fill.ph-webcam:before{content:""}.ph-fill.ph-webcam-slash:before{content:""}.ph-fill.ph-webhooks-logo:before{content:""}.ph-fill.ph-wechat-logo:before{content:""}.ph-fill.ph-whatsapp-logo:before{content:""}.ph-fill.ph-wheelchair:before{content:""}.ph-fill.ph-wheelchair-motion:before{content:""}.ph-fill.ph-wifi-high:before{content:""}.ph-fill.ph-wifi-low:before{content:""}.ph-fill.ph-wifi-medium:before{content:""}.ph-fill.ph-wifi-none:before{content:""}.ph-fill.ph-wifi-slash:before{content:""}.ph-fill.ph-wifi-x:before{content:""}.ph-fill.ph-wind:before{content:""}.ph-fill.ph-windmill:before{content:""}.ph-fill.ph-windows-logo:before{content:""}.ph-fill.ph-wine:before{content:""}.ph-fill.ph-wrench:before{content:""}.ph-fill.ph-x:before{content:""}.ph-fill.ph-x-circle:before{content:""}.ph-fill.ph-x-logo:before{content:""}.ph-fill.ph-x-square:before{content:""}.ph-fill.ph-yarn:before{content:""}.ph-fill.ph-yin-yang:before{content:""}.ph-fill.ph-youtube-logo:before{content:""}@font-face{font-family:IBM Plex Mono;src:url(/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Regular.ttf) format("truetype");font-weight:400;font-style:normal;font-display:swap}@font-face{font-family:IBM Plex Mono;src:url(/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Medium.ttf) format("truetype");font-weight:500;font-style:normal;font-display:swap}@font-face{font-family:IBM Plex Mono;src:url(/assets/fonts/IBM_Plex_Mono/IBMPlexMono-SemiBold.ttf) format("truetype");font-weight:600;font-style:normal;font-display:swap}@font-face{font-family:IBM Plex Mono;src:url(/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Bold.ttf) format("truetype");font-weight:700;font-style:normal;font-display:swap}@font-face{font-family:IBM Plex Mono;src:url(/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Italic.ttf) format("truetype");font-weight:400;font-style:italic;font-display:swap}.container{padding:18px}.section{margin-bottom:48px}.section-title,.block{margin-bottom:34px}.block-title{margin-bottom:22px}.text,p{margin-bottom:15px}.hint{margin-top:8px}.list{padding-left:22px;margin-bottom:15px}.list-item{margin-bottom:8px}.list-nested{margin-top:8px}.table{margin-bottom:22px}.table-caption{margin-bottom:8px}.form-group{margin-bottom:15px}.label{margin-bottom:5px;display:block}.input,.select,.textarea{margin-top:5px}.toast{padding:15px}.toast-stack{gap:8px}@keyframes terminal_scan_x{0%{transform:translate(-120%)}to{transform:translate(220%)}}@keyframes terminal_scan_y{0%{transform:translateY(-120%)}to{transform:translateY(220%)}}@keyframes terminal_pulse{0%,to{box-shadow:0 0 #c0caf500}50%{box-shadow:0 0 0 4px #c0caf52e}}@keyframes panel_boot{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}@keyframes overlay_reveal{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}@keyframes tooltip_reveal{0%{opacity:0;transform:translate(-50%) translateY(5px)}to{opacity:1;transform:translate(-50%) translateY(0)}}@media(prefers-reduced-motion:reduce){*,:after,:before{animation-duration:0s!important;animation-iteration-count:1!important;scroll-behavior:auto!important;transition-duration:0s!important}}html{font-size:100%}body{font-family:IBM Plex Mono,monospace;font-size:15px;font-weight:400;line-height:1.6;letter-spacing:0;color:#c0caf5}h1,h2,h3,h4,h5,h6{font-family:IBM Plex Mono,monospace;font-weight:600;line-height:1.25;margin:0}h1.contrast,h2.contrast,h3.contrast,h4.contrast,h5.contrast,h6.contrast{background:#c0caf5;color:#16161e;display:inline;padding:0 8px}h1{font-size:34px;letter-spacing:0}h2{font-size:26px}h3{font-size:22px}h4{font-size:20px}h5{font-size:18px}h6{font-size:16px;font-weight:500}.text,p{font-size:15px;line-height:1.6}.text-sm{font-size:13px;line-height:1.4}.text-lg{font-size:16px;line-height:1.6}.text-lead{max-width:760px;color:#c0caf5;font-size:16px;font-weight:500;line-height:1.6}.text-muted{font-size:13px;color:#787c99}.text-strong,strong{font-weight:600}.text-bold{font-weight:700}.text-italic,em{font-style:italic}.text-success{color:#9ece6a}.text-warning{color:#e0af68}.text-danger,.text-error{color:#f7768e}.text-info{color:#bb9af7}.eyebrow{display:inline-flex;width:-moz-max-content;width:max-content;max-width:100%;padding:5px 8px;color:#16161e;background:#7aa2f7;font-size:12px;font-weight:700;line-height:1;text-transform:uppercase}.caption{color:#787c99;font-size:12px;line-height:1.4}.code,code,pre{font-family:IBM Plex Mono,monospace;font-size:15px;line-height:1.4;background-color:#1f2335}.text-primary{color:#c0caf5}.text-secondary{color:#a9b1d6}pre{font-size:15px;line-height:1.6;white-space:pre-wrap}.code,pre code{-o-tab-size:2;tab-size:2;-moz-tab-size:2}.code{display:inline-flex;padding:0 5px;color:#7aa2f7;border:2px solid rgba(122,162,247,.24)}.kbd{display:inline-flex;align-items:center;min-height:24px;padding:0 8px;border:2px solid rgba(192,202,245,.24);border-bottom-color:#7aa2f7;color:#c0caf5;background:#1f2335;font-family:IBM Plex Mono,monospace;font-size:12px;font-weight:700;line-height:1;text-transform:uppercase}.quote{max-width:760px;margin:0;padding:15px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;color:#a9b1d6;background:#1f2335;font-size:15px;line-height:1.6}.quote cite{display:block;margin-top:12px;color:#7aa2f7;font-size:13px;font-style:normal;text-transform:uppercase}a{font-weight:500;text-decoration:none;color:#7aa2f7}@media(hover:hover)and (pointer:fine){a:hover{color:#e0af68}}@media(hover:none)and (pointer:coarse){a:active{color:#e0af68}}.link{font-size:inherit;font-weight:500}.label{font-size:13px;font-weight:500;line-height:1.4}.hint,.meta{font-size:12px;line-height:1.4}.table{font-size:13px;line-height:1.4}.table th{font-weight:600}.table td{font-weight:400}.list{font-size:15px;line-height:1.6}.list-item{font-size:inherit}.modal-title{font-size:20px;font-weight:600}.modal-body{font-size:15px}.toast-title{font-size:14px;font-weight:600}.toast-text{font-size:13px;line-height:1.4}.palette{display:flex;flex-direction:row;flex-wrap:wrap;gap:8px}.palette .color .color-box{width:92px;height:68px}body .bg-primary{background:#c0caf5}body .bg-secondary{background:#7aa2f7}body .bg-success{background:#9ece6a}body .bg-accent{background:#ff9e64}body .bg-info{background:#bb9af7}body .bg-warning{background:#e0af68}body .bg-error{background:#f7768e}body .text-color-primary{color:#c0caf5}body .text-color-secondary{color:#7aa2f7}body .text-color-success{color:#9ece6a}body .text-color-accent{color:#ff9e64}body .text-color-info{color:#bb9af7}body .text-color-warning{color:#e0af68}body .text-color-error{color:#f7768e}.loader{width:32px;aspect-ratio:1;--c:no-repeat linear-gradient(#FF3C00 0 0);background:var(--c) 0 0,var(--c) 0 100%,var(--c) 50% 0,var(--c) 50% 100%,var(--c) 100% 0,var(--c) 100% 100%;animation:l12 1s infinite}@keyframes l12{0%,to{background-size:20% 50%}16.67%{background-size:20% 30%,20% 30%,20% 50%,20% 50%,20% 50%,20% 50%}33.33%{background-size:20% 30%,20% 30%,20% 30%,20% 30%,20% 50%,20% 50%}50%{background-size:20% 30%,20% 30%,20% 30%,20% 30%,20% 30%,20% 30%}66.67%{background-size:20% 50%,20% 50%,20% 30%,20% 30%,20% 30%,20% 30%}83.33%{background-size:20% 50%,20% 50%,20% 50%,20% 50%,20% 30%,20% 30%}}.circle-loader{display:flex;flex-direction:row;align-items:center;gap:8px}.circle-loader .ph,.circle-loader .ph-bold{font-size:26px;transform-origin:50% 50%;animation:icon_spin 1.2s linear infinite}.progress{display:flex;flex-direction:column;gap:8px;width:100%;max-width:640px}.progress .progress-header{display:flex;align-items:center;justify-content:space-between;gap:12px;color:#a9b1d6;font-size:13px;font-weight:600;text-transform:uppercase}.progress .progress-value{color:#c0caf5;font-family:IBM Plex Mono,monospace}.progress .progress-track{position:relative;width:100%;height:18px;overflow:hidden;border:2px solid rgba(192,202,245,.24);background:#1f2335}.progress .progress-bar{display:block;position:relative;overflow:hidden;width:var(--progress-value,0%);height:100%;background:#7aa2f7;transition:width .28s ease}.progress.progress-success .progress-bar{background:#9ece6a}.progress.progress-warning .progress-bar{background:#e0af68}.progress.progress-danger .progress-bar,.progress.progress-error .progress-bar{background:#f7768e}.progress.progress-striped .progress-bar{background-image:repeating-linear-gradient(90deg,transparent 0,transparent 14px,rgba(22,22,30,.2) 14px,rgba(22,22,30,.2) 16px)}.progress.progress-animated .progress-bar:after{content:"";position:absolute;top:0;right:0;bottom:0;left:0;width:48%;background:linear-gradient(90deg,transparent,rgba(192,202,245,.28),transparent);transform:translate(-120%);animation:progress_scan 1.4s ease infinite}.usage-meter{display:grid;gap:12px;width:100%;max-width:420px;padding:15px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#1f2335}.usage-meter .usage-meter-title{display:flex;align-items:center;justify-content:space-between;gap:12px;margin:0;font-size:16px;font-weight:700;line-height:1;text-transform:uppercase}.usage-meter .usage-meter-value{color:#7aa2f7;font-family:IBM Plex Mono,monospace;font-size:13px}.usage-meter .usage-meter-meta{margin:0;color:#a9b1d6;font-size:13px;line-height:1.4}.progress-stages{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;width:100%;max-width:720px}.progress-stages .progress-stage{min-height:42px;padding:8px 12px;border:2px solid rgba(192,202,245,.24);color:#787c99;background:#1f2335;font-size:13px;font-weight:600;line-height:1.4;text-transform:uppercase}.progress-stages .progress-stage-complete{color:#16161e;background:#9ece6a;border-color:#9ece6a}.progress-stages .progress-stage-current{color:#16161e;background:#e0af68;border-color:#e0af68}@media(max-width:767px){.progress-stages{grid-template-columns:1fr 1fr}}@media(max-width:479px){.progress-stages{grid-template-columns:1fr}}@keyframes progress_scan{0%{transform:translate(-120%)}to{transform:translate(220%)}}@keyframes icon_spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.btn{display:inline-flex;align-items:center;justify-content:center;min-height:46px;font-family:IBM Plex Mono,monospace;font-size:15px;font-weight:600;line-height:1;letter-spacing:.04em;padding:12px 22px;border-radius:0;border-width:2px;border-left-width:6px;border-style:solid;border-color:#c0caf5;text-transform:uppercase;background-color:transparent;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:background-color,border-color,color,opacity}.btn:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}.btn.with-icon{border-left-width:46px;position:relative}.btn.with-icon .ph,.btn.with-icon .ph-bold{position:absolute;color:#16161e;left:-46px;top:1px;font-size:26px;height:100%;display:inline-flex;align-items:center;width:46px;justify-content:center;transition-duration:.2s;transition-property:color,left}@media(hover:hover)and (pointer:fine){.btn:hover.with-icon:not(.loading-state):not(.btn-small) .ph,.btn:hover.with-icon:not(.loading-state):not(.btn-small) .ph-bold{left:-28px}}@media(hover:none)and (pointer:coarse){.btn:active.with-icon:not(.loading-state):not(.btn-small) .ph,.btn:active.with-icon:not(.loading-state):not(.btn-small) .ph-bold{left:-28px}}.btn.btn-primary{color:#c0caf5;border-color:#c0caf5}@media(hover:hover)and (pointer:fine){.btn.btn-primary:hover{background-color:#c0caf5;color:#16161e}}@media(hover:none)and (pointer:coarse){.btn.btn-primary:active{background-color:#c0caf5;color:#16161e}}.btn.btn-secondary{color:#7aa2f7;border-color:#7aa2f7}@media(hover:hover)and (pointer:fine){.btn.btn-secondary:hover{background-color:#7aa2f7;color:#16161e}.btn.btn-secondary:hover.with-icon .ph,.btn.btn-secondary:hover.with-icon .ph-bold{color:#16161e}}@media(hover:none)and (pointer:coarse){.btn.btn-secondary:active{background-color:#7aa2f7;color:#16161e}.btn.btn-secondary:active.with-icon .ph,.btn.btn-secondary:active.with-icon .ph-bold{color:#16161e}}.btn.btn-accent{color:#ff9e64;border-color:#ff9e64}@media(hover:hover)and (pointer:fine){.btn.btn-accent:hover{background-color:#ff9e64;color:#16161e}.btn.btn-accent:hover.with-icon .ph,.btn.btn-accent:hover.with-icon .ph-bold{color:#16161e}}@media(hover:none)and (pointer:coarse){.btn.btn-accent:active{background-color:#ff9e64;color:#16161e}.btn.btn-accent:active.with-icon .ph,.btn.btn-accent:active.with-icon .ph-bold{color:#16161e}}.btn.btn-danger{color:#f7768e;border-color:#f7768e}@media(hover:hover)and (pointer:fine){.btn.btn-danger:hover{background-color:#f7768e;color:#16161e}}@media(hover:none)and (pointer:coarse){.btn.btn-danger:active{background-color:#f7768e;color:#16161e}}.btn.btn-warning{color:#e0af68;border-color:#e0af68}@media(hover:hover)and (pointer:fine){.btn.btn-warning:hover{background-color:#e0af68;color:#16161e}}@media(hover:none)and (pointer:coarse){.btn.btn-warning:active{background-color:#e0af68;color:#16161e}}.btn.btn-success{color:#9ece6a;border-color:#9ece6a}@media(hover:hover)and (pointer:fine){.btn.btn-success:hover{background-color:#9ece6a;color:#16161e}}@media(hover:none)and (pointer:coarse){.btn.btn-success:active{background-color:#9ece6a;color:#16161e}}.btn.btn-info{color:#bb9af7;border-color:#bb9af7}@media(hover:hover)and (pointer:fine){.btn.btn-info:hover{background-color:#bb9af7;color:#16161e}.btn.btn-info:hover.with-icon .ph,.btn.btn-info:hover.with-icon .ph-bold{color:#16161e}}@media(hover:none)and (pointer:coarse){.btn.btn-info:active{background-color:#bb9af7;color:#16161e}.btn.btn-info:active.with-icon .ph,.btn.btn-info:active.with-icon .ph-bold{color:#16161e}}.btn[disabled]:not(.loading-state){color:#787c99;border-color:#c0caf53d;background-color:#1f2335;cursor:not-allowed;opacity:.72}.btn[disabled]:not(.loading-state).with-icon .ph,.btn[disabled]:not(.loading-state).with-icon .ph-bold{color:#787c99}@media(hover:hover)and (pointer:fine){.btn[disabled]:not(.loading-state):hover{background-color:#1f2335;color:#787c99}.btn[disabled]:not(.loading-state):hover.with-icon .ph,.btn[disabled]:not(.loading-state):hover.with-icon .ph-bold{color:#787c99}}@media(hover:none)and (pointer:coarse){.btn[disabled]:not(.loading-state):active{background-color:#1f2335;color:#787c99}.btn[disabled]:not(.loading-state):active.with-icon .ph,.btn[disabled]:not(.loading-state):active.with-icon .ph-bold{color:#787c99}}.btn[disabled]:not(.loading-state).with-icon:not(.btn-small) .ph,.btn[disabled]:not(.loading-state).with-icon:not(.btn-small) .ph-bold{left:-28px}.btn.btn-small{font-size:13px;font-weight:500;min-height:38px;padding:8px}.btn.btn-small.with-icon{border-left-width:32px}.btn.btn-small.with-icon .ph,.btn.btn-small.with-icon .ph-bold{top:0;left:-40px;font-size:22px}.btn.btn-small.with-icon.loading-state .ph,.btn.btn-small.with-icon.loading-state .ph-bold{font-size:26px}.btn.btn-large{font-size:16px;font-weight:700;min-height:54px;padding:15px 48px}.btn.loading-state{color:#16161e!important;border-color:#c0caf5!important;background-color:#c0caf5!important}.btn.loading-state .ph,.btn.loading-state .ph-bold{font-size:26px;transform-origin:50% 50%;animation:icon_spin 1.2s linear infinite}.btn-icon{display:flex;justify-content:center;align-items:center;width:38px;height:38px;background:0 0;color:#c0caf5;font-size:22px;border:2px solid transparent;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background,border-color}.btn-icon:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}@media(hover:hover)and (pointer:fine){.btn-icon:not(.without-hover):hover{color:#e0af68;border-color:#e0af68}}@media(hover:none)and (pointer:coarse){.btn-icon:not(.without-hover):active{color:#e0af68;border-color:#e0af68}}.btn-icon:disabled,.btn-icon[disabled]{color:#787c99;border-color:transparent;background-color:transparent;cursor:not-allowed;opacity:.72}@media(hover:hover)and (pointer:fine){.btn-icon:disabled:not(.without-hover):hover,.btn-icon[disabled]:not(.without-hover):hover{color:#787c99;border-color:transparent}}@media(hover:none)and (pointer:coarse){.btn-icon:disabled:not(.without-hover):active,.btn-icon[disabled]:not(.without-hover):active{color:#787c99;border-color:transparent}}.btn-icon-sm{width:28px;height:28px;font-size:18px}.form-group{width:100%;max-width:600px}.form-group .label{display:flex;flex-direction:column;font-size:15px;width:100%;position:relative;color:#c0caf5}.form-group .label>.ph{position:absolute;color:#c0caf5;left:0;bottom:1px;font-size:26px;height:54px;display:inline-flex;align-items:center;width:46px;justify-content:center;transition-duration:.2s;transition-property:color,left}.form-group .label .input{min-height:54px;font-family:IBM Plex Mono,monospace;font-size:15px;font-weight:500;line-height:1;letter-spacing:.04em;padding:12px 22px;margin-top:8px;border-radius:0;border-width:2px;border-bottom-width:6px;border-style:solid;border-color:#c0caf5;color:#c0caf5;background-color:#1f2335;transition-duration:.2s;transition-timing-function:ease;transition-property:background-color,border-color,color}@media(hover:hover)and (pointer:fine){.form-group .label .input:hover{border-bottom-color:#787c99}}@media(hover:none)and (pointer:coarse){.form-group .label .input:active{border-bottom-color:#787c99}}.form-group .label .input:focus{outline:2px solid #E0AF68;outline-offset:3px;border-color:#7aa2f7;background-color:transparent}.form-group .label .input:disabled{color:#787c99;border-color:#c0caf53d;background:#1f2335;cursor:not-allowed;opacity:.72}.form-group .label .input[readonly]{color:#a9b1d6;border-color:#c0caf53d;background:#c0caf508}.form-group .label .input::-moz-placeholder{color:#787c99}.form-group .label .input::placeholder{color:#787c99}.form-group .label .input::-webkit-search-cancel-button,.form-group .label .input::-webkit-search-decoration,.form-group .label .input::-webkit-search-results-button,.form-group .label .input::-webkit-search-results-decoration{display:none;-webkit-appearance:none}.form-group .label .input[type=date],.form-group .label .input[type=datetime-local],.form-group .label .input[type=month],.form-group .label .input[type=time]{color-scheme:dark;cursor:pointer;min-width:0;padding-right:46px;text-transform:uppercase}.form-group .label .input[type=date]::-webkit-calendar-picker-indicator,.form-group .label .input[type=datetime-local]::-webkit-calendar-picker-indicator,.form-group .label .input[type=month]::-webkit-calendar-picker-indicator,.form-group .label .input[type=time]::-webkit-calendar-picker-indicator{width:46px;height:100%;margin:0;padding:0;background:0 0;cursor:pointer;opacity:0}.form-group .label .input[type=date]::-webkit-datetime-edit,.form-group .label .input[type=datetime-local]::-webkit-datetime-edit,.form-group .label .input[type=month]::-webkit-datetime-edit,.form-group .label .input[type=time]::-webkit-datetime-edit{padding:0}.form-group .label .input[type=date]::-webkit-datetime-edit-fields-wrapper,.form-group .label .input[type=datetime-local]::-webkit-datetime-edit-fields-wrapper,.form-group .label .input[type=month]::-webkit-datetime-edit-fields-wrapper,.form-group .label .input[type=time]::-webkit-datetime-edit-fields-wrapper{color:#c0caf5}.form-group .label textarea.input{height:108px;line-height:1.25;resize:none}.form-group .label .ph+.input,.form-group .label .ph+.select-wrap .select{padding-left:46px}.form-group .label .select-wrap{margin-top:8px}.form-group .label .select{width:100%;height:54px;margin-top:0;appearance:none;-webkit-appearance:none;-moz-appearance:none}.form-group .label .select:focus{outline:0}.form-group .label .select option{color:#c0caf5;background:#1f2335}.form-group .label .select-wrap:after{content:"";position:absolute;right:22px;bottom:18px;transform:translateY(-50%);width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-top:10px solid #c0caf5;pointer-events:none}.form-group .label.error .input:not(:focus){border-color:#f7768e}.form-group .label.error+.input-info{color:#e0af68}.form-group .label.success .input:not(:focus){border-color:#9ece6a}.form-group .label.success+.input-info{color:#9ece6a}.form-group .label.warning .input:not(:focus){border-color:#e0af68}.form-group .label.warning+.input-info{color:#e0af68}.form-group .input-info{font-size:14px;margin-top:8px}.form-group .input-info .ph{position:relative;top:1px}.form-group .input-info.error{color:#e0af68}.form-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:15px;width:100%;max-width:760px}.fieldset{width:100%;max-width:760px;margin:0;padding:18px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#1f2335}.legend{padding:5px 8px;color:#16161e;background:#c0caf5;font-size:13px;font-weight:700;line-height:1;text-transform:uppercase}.file-upload{display:inline-flex;align-items:center;gap:8px;min-height:46px;padding:8px 12px;border:2px solid #7aa2f7;border-left-width:6px;color:#7aa2f7;background:#1f2335;font-size:13px;font-weight:700;text-transform:uppercase;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background,border-color}.file-upload input[type=file]{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}@media(hover:hover)and (pointer:fine){.file-upload:hover{color:#16161e;background:#7aa2f7}}@media(hover:none)and (pointer:coarse){.file-upload:active{color:#16161e;background:#7aa2f7}}.file-upload:focus-within{outline:2px solid #E0AF68;outline-offset:3px}.file-upload-panel{width:100%;max-width:760px;background:#1f2335;border:2px solid rgba(192,202,245,.24);border-left-width:6px}.file-upload-form{display:flex;flex-direction:column;gap:15px;margin:0}.file-upload-header{display:flex;align-items:flex-start;justify-content:space-between;gap:15px;padding:15px 15px 0}.file-upload-heading{display:flex;flex-direction:column;gap:5px;min-width:0}.file-upload-title{margin:0;color:#c0caf5;font-size:16px;font-weight:700;line-height:1.25;text-transform:uppercase}.file-upload-description{margin:0;color:#a9b1d6;font-size:13px;line-height:1.6}.file-upload-dropzone{display:grid;grid-template-columns:auto minmax(0,1fr);align-items:center;gap:15px;margin:0 15px;padding:18px;border:2px dashed #7aa2f7;background:#7aa2f714;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:background,border-color}.file-upload-dropzone input[type=file]{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}@media(hover:hover)and (pointer:fine){.file-upload-dropzone:hover{border-color:#c0caf5;background:#c0caf51a}}@media(hover:none)and (pointer:coarse){.file-upload-dropzone:active{border-color:#c0caf5;background:#c0caf51a}}.file-upload-dropzone:focus-within{outline:2px solid #E0AF68;outline-offset:3px}.file-upload-icon{display:inline-flex;align-items:center;justify-content:center;width:54px;height:54px;color:#16161e;background:#7aa2f7;font-size:26px}.file-upload-body{display:flex;flex-direction:column;gap:5px;min-width:0}.file-upload-primary{color:#c0caf5;font-size:15px;font-weight:700;line-height:1.25;text-transform:uppercase}.file-upload-secondary{color:#a9b1d6;font-size:13px;line-height:1.4}.file-upload-preview{display:grid;grid-template-columns:repeat(auto-fill,minmax(148px,1fr));gap:12px;margin:0 15px}.file-upload-preview[hidden]{display:none}.file-upload-preview-item{position:relative;min-width:0;margin:0;border:2px solid rgba(192,202,245,.24);background:#1f2335}.file-upload-preview-remove{position:absolute;top:8px;right:8px;z-index:1;display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;border:2px solid #f7768e;color:#f7768e;background:#1f2335;font-size:18px;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background,border-color}@media(hover:hover)and (pointer:fine){.file-upload-preview-remove:hover{color:#16161e;background:#f7768e}}@media(hover:none)and (pointer:coarse){.file-upload-preview-remove:active{color:#16161e;background:#f7768e}}.file-upload-preview-remove:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}.file-upload-preview-visual{display:flex;align-items:center;justify-content:center;aspect-ratio:1;background:#1f2335}.file-upload-preview-visual img{display:block;width:100%;height:100%;-o-object-fit:cover;object-fit:cover}.file-upload-preview-type{display:inline-flex;align-items:center;justify-content:center;min-width:54px;min-height:54px;padding:8px;color:#16161e;background:#7aa2f7;font-size:13px;font-weight:700;line-height:1;text-transform:uppercase}.file-upload-preview-item figcaption{display:flex;flex-direction:column;gap:5px;overflow:hidden;padding:8px}.file-upload-preview-name{overflow:hidden;color:#c0caf5;font-size:12px;font-weight:700;line-height:1.25;text-overflow:ellipsis;white-space:nowrap}.file-upload-preview-meta{color:#a9b1d6;font-size:12px;font-weight:700;line-height:1.25;text-transform:uppercase}.file-upload-actions{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:8px;padding:0 15px 15px}.range{width:100%;max-width:600px;accent-color:#7AA2F7}.range input[type=range]{-webkit-appearance:none;-moz-appearance:none;appearance:none;width:100%;height:46px;margin:0;background:0 0;cursor:pointer}.range input[type=range]::-webkit-slider-runnable-track{height:6px;background:#c0caf516;border:2px solid rgba(192,202,245,.24)}.range input[type=range]::-webkit-slider-thumb{width:22px;height:38px;margin-top:-19px;border:2px solid #7aa2f7;background:#7aa2f7;-webkit-appearance:none}.range input[type=range]::-moz-range-track{height:6px;background:#c0caf516;border:2px solid rgba(192,202,245,.24)}.range input[type=range]::-moz-range-thumb{width:22px;height:38px;border:2px solid #7aa2f7;border-radius:0;background:#7aa2f7}@media(max-width:767px){.form-grid{grid-template-columns:1fr}.file-upload-header{flex-direction:column;align-items:stretch}.file-upload-dropzone{grid-template-columns:1fr}.file-upload-actions{justify-content:stretch}.file-upload-actions .btn{width:100%}}.radio{display:inline-flex;flex-direction:row;gap:8px;align-items:center;cursor:pointer}.radio input[type=radio]{display:none}.radio .radio-control{width:22px;height:22px;border-radius:100%;border:3px solid #c0caf5;background:#1f2335;position:relative;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition-duration:.2s;transition-property:border-color,background}.radio .radio-control:before{content:"";display:block;width:10px;height:10px;border-radius:100%;background:#c0caf5;transform:scale(0);transition-duration:.2s;transition-property:transform,background}@media(hover:hover)and (pointer:fine){.radio:hover .radio-control{border-color:#c0caf5}}@media(hover:none)and (pointer:coarse){.radio:active .radio-control{border-color:#c0caf5}}.radio input[type=radio]:checked+.radio-control{border-color:#c0caf5;background:#c0caf52e}.radio input[type=radio]:checked+.radio-control:before{transform:scale(1)}.radio input[type=radio]:disabled+.radio-control{border-color:#414868;background:#4148681f;opacity:.5}.radio input[type=radio]:disabled:checked+.radio-control:before{background:#414868}.radio input[type=radio]:focus-visible+.radio-control{outline:2px solid #E0AF68;outline-offset:3px}.radio .radio-label{font-size:15px}.radio-group{display:flex;flex-wrap:wrap;gap:12px;align-items:center}.switch{display:inline-flex;flex-direction:row;gap:8px;align-items:center}.switch input[type=checkbox]{display:none}.switch .switch-control{height:16px;width:32px;border:2px solid #c0caf5;position:relative;background:0 0;transition-duration:.2s;transition-property:border-color,background;display:block}.switch .switch-control:before{content:"";display:block;height:20px;width:20px;background:#c0caf5;position:absolute;left:-5px;top:-5px;transition-duration:.2s;transition-property:left,background}@media(hover:hover)and (pointer:fine){.switch:hover .switch-control{background:#414868}}@media(hover:none)and (pointer:coarse){.switch:active .switch-control{background:#414868}}.switch input[type=checkbox]:checked:not(:disabled)+.switch-control{background:#7aa2f7;border-color:#7aa2f7}.switch input[type=checkbox]:checked+.switch-control:before{left:17px}.switch input[type=checkbox]:disabled+.switch-control{border-color:#414868}.switch input[type=checkbox]:focus-visible+.switch-control{outline:2px solid #E0AF68;outline-offset:3px}.switch input[type=checkbox]:disabled+.switch-control:before{background:#414868}.checkbox{display:inline-flex;flex-direction:row;gap:8px;align-items:center;cursor:pointer}.checkbox input[type=checkbox]{display:none}.checkbox .checkbox-control{width:22px;height:22px;border:2px solid #c0caf5;border-bottom-width:6px;background:#1f2335;position:relative;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition-duration:.2s;transition-property:border-color,background}.checkbox .checkbox-control:before{content:"";display:block;width:10px;height:5px;border-left:2px solid #c0caf5;border-bottom:2px solid #c0caf5;transform:rotate(-45deg) scale(0);opacity:0;margin-top:-2px;transition-duration:.2s;transition-property:transform,opacity,border-color}@media(hover:hover)and (pointer:fine){.checkbox:hover .checkbox-control{border-color:#c0caf5}}@media(hover:none)and (pointer:coarse){.checkbox:active .checkbox-control{border-color:#c0caf5}}.checkbox input[type=checkbox]:checked+.checkbox-control{border-color:#c0caf5;background:#c0caf52e}.checkbox input[type=checkbox]:checked+.checkbox-control:before{transform:rotate(-45deg) scale(1);opacity:1;border-color:#c0caf5}.checkbox input[type=checkbox]:disabled+.checkbox-control{border-color:#414868;background:#4148681f;opacity:.5}.checkbox input[type=checkbox]:disabled:checked+.checkbox-control:before{border-color:#414868}.checkbox input[type=checkbox]:focus-visible+.checkbox-control{outline:2px solid #E0AF68;outline-offset:3px}.checkbox .checkbox-label{font-size:15px}.input-group{display:flex;align-items:stretch;width:100%;max-width:600px;min-height:54px;border:2px solid #c0caf5;border-bottom-width:6px;background:#1f2335;transition-duration:.2s;transition-timing-function:ease;transition-property:border-color,background}.input-group:focus-within{outline:2px solid #E0AF68;outline-offset:3px;border-color:#7aa2f7;background:0 0}.input-group .input-group-action,.input-group .input-group-addon{display:inline-flex;align-items:center;justify-content:center;min-width:54px;padding:0 12px;color:#a9b1d6;background:#c0caf50b;border:0;font-family:IBM Plex Mono,monospace;font-size:13px;font-weight:600;text-transform:uppercase}.input-group .input-group-action{color:#c0caf5;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background}.input-group .input-group-input{flex:1 1 auto;min-width:0;border:0;padding:12px 15px;color:#c0caf5;background:0 0;font-family:IBM Plex Mono,monospace;font-size:15px;font-weight:500;letter-spacing:.04em}.input-group .input-group-input:focus{outline:0}.input-group .input-group-input::-moz-placeholder{color:#787c99}.input-group .input-group-input::placeholder{color:#787c99}.input-group .input-group-input::-webkit-search-cancel-button,.input-group .input-group-input::-webkit-search-decoration,.input-group .input-group-input::-webkit-search-results-button,.input-group .input-group-input::-webkit-search-results-decoration{display:none;-webkit-appearance:none}.input-group .ph,.input-group .ph-bold{font-size:22px}.input-group.input-group-compact{min-height:46px}.input-group.input-group-compact .input-group-action,.input-group.input-group-compact .input-group-addon{min-width:46px}.input-group.input-group-compact .input-group-input{padding:8px 12px;font-size:13px}.search-field{max-width:420px}.repeater .repeater-header{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:12px}.repeater .repeater-title{font-size:15px;font-weight:600;color:#c0caf5}.repeater .repeater-list{display:grid;gap:8px}.repeater .repeater-item{background:#1f2335;border:2px solid rgba(192,202,245,.24);padding:12px;display:grid;grid-template-columns:1fr auto;gap:12px;align-items:start}.repeater .repeater-item-body{width:100%}.repeater .repeater-item-actions{display:flex;align-items:center;gap:8px;padding-top:22px}.repeater.repeater-disabled{opacity:.6;pointer-events:none}.list{display:flex;flex-direction:column;gap:5px;list-style-type:none;padding-left:0}.list .list-item{display:flex;flex-direction:row;align-items:center;gap:8px;margin-left:0}.list.list-ordered{list-style-type:decimal;display:list-item;margin-left:30px}.list.list-ordered .list-item{display:list-item}.list.list-definition{width:100%;max-width:620px;gap:0;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#1f2335}.list.list-definition .list-row{display:grid;grid-template-columns:minmax(120px,.32fr) minmax(0,1fr);gap:15px;align-items:start;padding:12px 15px;border-bottom:2px solid rgba(192,202,245,.08);transition-duration:.2s;transition-timing-function:ease;transition-property:background,border-color}.list.list-definition .list-row .list-term{display:inline-flex;width:-moz-max-content;width:max-content;max-width:100%;margin:0;padding:5px 8px;color:#16161e;background:#c0caf5;font-size:13px;font-weight:700;line-height:1;text-transform:uppercase;transition-duration:.2s;transition-timing-function:ease;transition-property:background,transform}.list.list-definition .list-row .list-desc{margin:0;color:#a9b1d6;font-size:13px;line-height:1.6;transition-duration:.2s;transition-timing-function:ease;transition-property:color,transform}.list.list-definition .list-row:last-child{border-bottom:0}@media(hover:hover)and (pointer:fine){.list.list-definition .list-row:hover{background:#c0caf516}.list.list-definition .list-row:hover .list-term{background:#7aa2f7;transform:translate(5px)}.list.list-definition .list-row:hover .list-desc{color:#c0caf5;transform:translate(5px)}}@media(hover:none)and (pointer:coarse){.list.list-definition .list-row:active{background:#c0caf516}.list.list-definition .list-row:active .list-term{background:#7aa2f7;transform:translate(5px)}.list.list-definition .list-row:active .list-desc{color:#c0caf5;transform:translate(5px)}}.list.list-nav{max-width:420px;width:100%;gap:0}.list.list-nav .list-item{display:flex;flex-direction:column;align-items:flex-start;height:50px;margin:0}.list.list-nav .list-item .list-action{display:flex;justify-content:space-between;align-items:center;width:100%;height:100%;padding:8px 12px;border:2px solid transparent;font-size:15px;background:#1f2335;color:inherit;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:background,border-color,color}.list.list-nav .list-item .list-action:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}@media(hover:hover)and (pointer:fine){.list.list-nav .list-item .list-action:hover{background:#7aa2f7;color:#16161e}}@media(hover:none)and (pointer:coarse){.list.list-nav .list-item .list-action:active{background:#7aa2f7;color:#16161e}}.list.list-nav .list-item .list-action .list-label{display:flex;flex-direction:row;gap:8px;align-items:center;letter-spacing:0;font-weight:400}.list.list-nav .list-item .list-action .list-meta{padding:8px;background:#9ece6a;color:#16161e;display:flex}.list.list-nav .list-item.list-item-active .list-action{background:#7aa2f7;color:#16161e;border-color:#7aa2f7}.list.list-actions{width:100%;max-width:420px;gap:22px}.list.list-actions .list-item{justify-content:space-between;align-items:flex-start;padding:12px 0;border-bottom:2px solid rgba(192,202,245,.08)}.list.list-actions .list-item .list-content{display:flex;flex-direction:column;gap:8px}.list.list-actions .list-item .list-content .list-title{font-size:16px;line-height:1}.list.list-actions .list-item .list-content .list-subtitle{color:#787c99}@media(hover:hover)and (pointer:fine){.list.list-actions .list-item:hover .list-title{color:#7aa2f7}}@media(hover:none)and (pointer:coarse){.list.list-actions .list-item:active .list-title{color:#7aa2f7}}@media(max-width:479px){.list.list-definition .list-row{grid-template-columns:1fr;gap:8px}}.badge{position:relative;overflow:hidden;background:#c0caf5;color:#16161e;padding:5px 8px;font-size:13px;font-weight:600;line-height:1;letter-spacing:.04em;text-transform:uppercase;display:inline-flex;align-items:center;min-height:24px;transition-duration:.2s;transition-timing-function:ease;transition-property:filter,transform,border-color,color,background}.badge:after{content:"";position:absolute;inset:0 auto 0 0;width:40%;background:linear-gradient(90deg,transparent,rgba(22,22,30,.16),transparent);opacity:0;pointer-events:none;transform:translate(-120%)}@media(hover:hover)and (pointer:fine){.badge:hover{filter:saturate(1.12);transform:translateY(-1px)}.badge:hover:after{opacity:1;animation:terminal_scan_x .7s ease}}@media(hover:none)and (pointer:coarse){.badge:active{filter:saturate(1.12);transform:translateY(-1px)}.badge:active:after{opacity:1;animation:terminal_scan_x .7s ease}}.badge.badge-success{background:#9ece6a}.badge.badge-warning{background:#e0af68}.badge.badge-danger,.badge.badge-error{background:#f7768e}.badge.badge-info{background:#bb9af7;color:#16161e}.badge.badge-secondary{background:#7aa2f7;color:#16161e}.badge.badge-primary-outline{color:#c0caf5;border:2px solid #c0caf5;background:0 0;padding:3px 8px}.chip-group{display:flex;flex-wrap:wrap;gap:8px;align-items:center}.chip{display:inline-flex;align-items:center;gap:8px;min-height:30px;padding:5px 12px;border:2px solid rgba(192,202,245,.24);color:#a9b1d6;background:#1f2335;font-family:IBM Plex Mono,monospace;font-size:12px;font-weight:600;line-height:1;text-transform:uppercase;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background,border-color,opacity}.chip .ph,.chip .ph-bold{font-size:18px}.chip:before{content:"";display:inline-block;width:7px;height:7px;flex:0 0 auto;background:#787c99;transition-duration:.2s;transition-timing-function:ease;transition-property:background,box-shadow,transform}.chip:has(.ph):before,.chip:has(.ph-bold):before{display:none}.chip .chip-remove{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;margin-right:-5px;border:0;color:inherit;background:0 0;font:inherit;cursor:pointer}.chip .chip-remove:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}.chip.chip-primary{color:#c0caf5;background:#c0caf514;border-color:#c0caf5}.chip.chip-primary:before{background:#c0caf5}.chip.chip-secondary{color:#7aa2f7;background:#7aa2f714;border-color:#7aa2f7}.chip.chip-secondary:before{background:#7aa2f7}.chip.chip-success{color:#9ece6a;background:#9ece6a14;border-color:#9ece6a}.chip.chip-success:before{background:#9ece6a}.chip.chip-warning{color:#e0af68;background:#e0af6814;border-color:#e0af68}.chip.chip-warning:before{background:#e0af68}.chip.chip-danger,.chip.chip-error{color:#f7768e;background:#f7768e14;border-color:#f7768e}.chip.chip-danger:before,.chip.chip-error:before{background:#f7768e}.chip.chip-selected,.chip[aria-pressed=true],.chip[aria-selected=true]{color:#16161e;background:#c0caf5;border-color:#c0caf5}.chip.chip-selected:before,.chip[aria-pressed=true]:before,.chip[aria-selected=true]:before{background:#16161e}.chip.chip-secondary[aria-pressed=true],.chip.chip-secondary[aria-selected=true],.chip.chip-selected.chip-secondary{background:#7aa2f7;border-color:#7aa2f7}.chip.chip-disabled,.chip:disabled{color:#787c99;background:#1f2335;border-color:#c0caf53d;cursor:not-allowed;opacity:.7}.chip.chip-disabled:before,.chip:disabled:before{background:#414868}a.chip,button.chip{cursor:pointer}a.chip:focus-visible,button.chip:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}@media(hover:hover)and (pointer:fine){a.chip:hover,button.chip:hover{color:#c0caf5;background:#c0caf516;border-color:#7aa2f7}a.chip:hover:before,button.chip:hover:before{background:#7aa2f7;animation:terminal_pulse .7s ease;transform:scale(1.12)}}@media(hover:none)and (pointer:coarse){a.chip:active,button.chip:active{color:#c0caf5;background:#c0caf516;border-color:#7aa2f7}a.chip:active:before,button.chip:active:before{background:#7aa2f7;animation:terminal_pulse .7s ease;transform:scale(1.12)}}.tag-input{background:#1f2335;border:2px solid rgba(192,202,245,.24);position:relative}.tag-input .tag-input-wrap{display:flex;flex-wrap:wrap;align-items:center;gap:8px;padding:8px 12px;min-height:46px;cursor:text}.tag-input .tag-input-field{flex:1 1 auto;min-width:80px;padding:5px 0;border:0;color:#c0caf5;background:0 0;font-family:IBM Plex Mono,monospace;font-size:13px;line-height:1;outline:0}.tag-input .tag-input-field::-moz-placeholder{color:#787c99;opacity:1}.tag-input .tag-input-field::placeholder{color:#787c99;opacity:1}.tag-input.tag-input-focused{border-color:#c0caf5}.tag-input .tag-input-meta{padding:0 12px 8px;color:#787c99;font-size:12px;line-height:1}.avatar{position:relative;display:inline-flex;align-items:center;justify-content:center;width:46px;height:46px;flex:0 0 auto;overflow:hidden;border:2px solid rgba(192,202,245,.24);color:#16161e;background:#c0caf5;font-family:IBM Plex Mono,monospace;font-size:13px;font-weight:700;line-height:1;text-transform:uppercase}.avatar img{width:100%;height:100%;-o-object-fit:cover;object-fit:cover}.avatar .ph,.avatar .ph-bold{font-size:22px}.avatar .avatar-status{position:absolute;right:-2px;bottom:-2px;width:13px;height:13px;border:2px solid #16161e;background:#787c99;transition-duration:.2s;transition-timing-function:ease;transition-property:background,box-shadow}.avatar.avatar-sm{width:38px;height:38px;font-size:12px}.avatar.avatar-sm .ph,.avatar.avatar-sm .ph-bold{font-size:18px}.avatar.avatar-lg{width:54px;height:54px;font-size:14px}.avatar.avatar-lg .ph,.avatar.avatar-lg .ph-bold{font-size:26px}.avatar.avatar-secondary{background:#7aa2f7}.avatar.avatar-success{background:#9ece6a}.avatar.avatar-warning{background:#e0af68}.avatar.avatar-danger,.avatar.avatar-error{background:#f7768e}.avatar.avatar-outline{color:#c0caf5;background:#1f2335;border-color:#c0caf5}.avatar.is-online .avatar-status{background:#9ece6a;animation:terminal_pulse 1.8s ease infinite}.avatar.is-busy .avatar-status{background:#e0af68}.avatar.is-offline .avatar-status{background:#787c99}.identity{display:inline-flex;align-items:center;gap:12px;min-width:0}.identity-content{display:flex;flex-direction:column;gap:5px;min-width:0}.identity-title{color:#c0caf5;font-size:15px;font-weight:600;line-height:1}.identity-meta{color:#787c99;font-size:13px;line-height:1.4}.avatar-stack{display:inline-flex;align-items:center}.avatar-stack .avatar{margin-right:-8px;border-color:#16161e}.avatar-stack .avatar-stack-count{display:inline-flex;align-items:center;justify-content:center;min-width:46px;height:46px;padding:0 8px;border:2px solid #16161e;color:#16161e;background:#e0af68;font-size:13px;font-weight:700}.table{width:100%;text-align:left;border:2px solid rgba(192,202,245,.24);border-collapse:collapse;background:#1f2335}.table .table-caption{text-align:left;font-size:16px;background:#c0caf5;width:-moz-max-content;width:max-content;color:#16161e;padding:5px 12px;margin-bottom:0;font-weight:700;text-transform:uppercase}.table.table-empty{width:100%}.table.table-empty .is-empty{width:100%;padding:15px;font-size:13px;color:#787c99;text-align:left}.table .table-row td,.table .table-row th{padding:12px 18px;font-size:13px;vertical-align:middle;border-bottom:2px solid rgba(192,202,245,.08)}.table .table-row th{color:#c0caf5;background:#c0caf50a;text-transform:uppercase;letter-spacing:.04em}.table .table-head{border-bottom:2px solid #c0caf5}.table .table-body .table-row{transition-duration:.2s;transition-timing-function:ease;transition-property:background,color}.table .table-body .table-row td{transition-duration:.2s;transition-timing-function:ease;transition-property:color,background}@media(hover:hover)and (pointer:fine){.table .table-body .table-row:hover{background:#7aa2f714}.table .table-body .table-row:hover td:first-child{color:#7aa2f7}}@media(hover:none)and (pointer:coarse){.table .table-body .table-row:active{background:#7aa2f714}.table .table-body .table-row:active td:first-child{color:#7aa2f7}}.table .table-foot td,.table .table-foot th{padding-top:15px}.table.table-compact .table-caption{font-size:14px}.table.table-compact .table-row td,.table.table-compact .table-row th{padding:8px 12px;font-size:12px}.table.table-compact .table-cell-mono{color:#a9b1d6;font-family:IBM Plex Mono,monospace;letter-spacing:0}.table.table-compact .table-cell-actions{width:1%;white-space:nowrap}.table-wrapper{width:100%;overflow-x:auto}.toolbar{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px;width:100%;padding:12px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#1f2335}.toolbar .toolbar-group{display:flex;flex-wrap:wrap;align-items:center;gap:8px;min-width:0}.toolbar .toolbar-title{margin:0;font-size:16px;font-weight:700;line-height:1;text-transform:uppercase}.toolbar .toolbar-meta{color:#787c99;font-size:13px}.pagination{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.pagination .pagination-item{display:inline-flex;align-items:center;justify-content:center;min-width:38px;height:38px;padding:0 12px;border:2px solid rgba(192,202,245,.24);color:#a9b1d6;background:#1f2335;font-family:IBM Plex Mono,monospace;font-size:13px;font-weight:600;line-height:1;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background,border-color,opacity}.pagination .pagination-item:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}@media(hover:hover)and (pointer:fine){.pagination .pagination-item:hover{color:#16161e;background:#7aa2f7;border-color:#7aa2f7}}@media(hover:none)and (pointer:coarse){.pagination .pagination-item:active{color:#16161e;background:#7aa2f7;border-color:#7aa2f7}}.pagination .pagination-item.pagination-item-active,.pagination .pagination-item[aria-current=page]{color:#16161e;background:#c0caf5;border-color:#c0caf5}.pagination .pagination-item.pagination-item-disabled,.pagination .pagination-item:disabled{color:#787c99;background:#1f2335;border-color:#c0caf53d;cursor:not-allowed;opacity:.72}.pagination .pagination-ellipsis{color:#787c99;padding:0 5px}.empty-state{max-width:560px;padding:22px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#1f2335}.empty-state .empty-state-icon{display:inline-flex;align-items:center;justify-content:center;width:54px;height:54px;margin-bottom:15px;color:#16161e;background:#c0caf5;font-size:26px}.empty-state .empty-state-title{margin:0 0 8px;font-size:20px;font-weight:700;text-transform:uppercase}.empty-state .empty-state-text{max-width:440px;margin:0 0 18px;color:#a9b1d6;line-height:1.6}.empty-state .empty-state-actions{display:flex;flex-wrap:wrap;gap:8px}.empty-state.empty-state-error{border-color:#f7768e}.empty-state.empty-state-error .empty-state-icon{background:#f7768e}.skeleton{display:block;position:relative;overflow:hidden;background:#c0caf516}.skeleton:after{content:"";position:absolute;top:0;right:0;bottom:0;left:0;transform:translate(-100%);background:linear-gradient(90deg,transparent,rgba(192,202,245,.12),transparent);animation:skeleton_shimmer 1.6s infinite}.skeleton.skeleton-line{width:100%;height:14px}.skeleton.skeleton-title{width:60%;height:22px}.skeleton.skeleton-block{width:100%;height:120px}.skeleton.skeleton-square{width:54px;height:54px}.skeleton-stack{display:flex;flex-direction:column;gap:12px;max-width:520px;padding:15px;border:2px solid rgba(192,202,245,.24);background:#1f2335}@keyframes skeleton_shimmer{to{transform:translate(100%)}}.page-header{position:relative;display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;gap:18px;width:100%;padding:18px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#1f2335;overflow:hidden;animation:panel_boot .28s ease both}.page-header:after{content:"";position:absolute;top:0;left:0;width:34%;height:2px;background:linear-gradient(90deg,transparent,#7aa2f7,transparent);opacity:.72;pointer-events:none;transform:translate(-120%)}@media(hover:hover)and (pointer:fine){.page-header:hover:after{animation:terminal_scan_x .9s ease}}@media(hover:none)and (pointer:coarse){.page-header:active:after{animation:terminal_scan_x .9s ease}}.page-header .page-header-content{display:flex;flex-direction:column;gap:8px;min-width:min(100%,320px)}.page-header .page-header-kicker{color:#7aa2f7;font-size:13px;font-weight:700;line-height:1;text-transform:uppercase;transition-duration:.2s;transition-timing-function:ease;transition-property:color}.page-header .page-header-title{margin:0;color:#c0caf5;font-size:26px;font-weight:700;line-height:1.15}.page-header .page-header-subtitle{max-width:720px;margin:0;color:#a9b1d6;font-size:15px;line-height:1.6}.page-header .page-header-meta{display:flex;flex-wrap:wrap;align-items:center;gap:8px;color:#787c99;font-size:13px}.page-header .page-header-actions{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:8px}.page-header.page-header-compact{align-items:center;padding:15px}.page-header.page-header-compact .page-header-title{font-size:20px}.page-header.page-header-accent{border-color:#7aa2f7;background:#7aa2f70e}.description-list{display:grid;width:100%;max-width:760px;margin:0;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#1f2335}.description-list .description-list-row{display:grid;grid-template-columns:minmax(140px,.36fr) minmax(0,1fr);gap:15px;padding:12px 15px;border-bottom:2px solid rgba(192,202,245,.08);transition-duration:.2s;transition-timing-function:ease;transition-property:background}.description-list .description-list-row:last-child{border-bottom:0}@media(hover:hover)and (pointer:fine){.description-list .description-list-row:hover{background:#c0caf516}.description-list .description-list-row:hover .description-list-term{color:#7aa2f7}.description-list .description-list-row:hover .description-list-value{transform:translate(5px)}}@media(hover:none)and (pointer:coarse){.description-list .description-list-row:active{background:#c0caf516}.description-list .description-list-row:active .description-list-term{color:#7aa2f7}.description-list .description-list-row:active .description-list-value{transform:translate(5px)}}.description-list .description-list-term{margin:0;color:#787c99;font-size:13px;font-weight:600;line-height:1.4;text-transform:uppercase;transition-duration:.2s;transition-timing-function:ease;transition-property:color}.description-list .description-list-value{display:flex;flex-wrap:wrap;align-items:center;gap:8px;min-width:0;margin:0;color:#c0caf5;font-size:15px;line-height:1.4;transition-duration:.2s;transition-timing-function:ease;transition-property:transform}.description-list .description-list-value-muted{color:#a9b1d6}.description-list.description-list-compact{max-width:520px}.description-list.description-list-compact .description-list-row{grid-template-columns:minmax(112px,.42fr) minmax(0,1fr);gap:12px;padding:8px 12px}.description-list.description-list-compact .description-list-term,.description-list.description-list-compact .description-list-value{font-size:13px}@media(max-width:479px){.description-list .description-list-row{grid-template-columns:1fr;gap:5px}}.steps{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;width:100%;max-width:900px;margin:0;padding:0;list-style:none}.steps .step{position:relative;display:flex;flex-direction:column;gap:8px;min-height:120px;padding:15px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#1f2335}.steps .step-marker{display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;color:#c0caf5;border:2px solid rgba(192,202,245,.24);font-size:13px;font-weight:700;line-height:1}.steps .step-title{margin:0;font-size:14px;font-weight:700;line-height:1.25;text-transform:uppercase}.steps .step-text{margin:0;color:#a9b1d6;font-size:13px;line-height:1.4}.steps .step-complete{border-color:#9ece6a}.steps .step-complete .step-marker{color:#16161e;background:#9ece6a;border-color:#9ece6a}.steps .step-current{border-color:#7aa2f7}.steps .step-current .step-marker{color:#16161e;background:#7aa2f7;border-color:#7aa2f7}.steps .step-disabled{opacity:.62}.steps.steps-vertical{grid-template-columns:1fr;max-width:520px;gap:0}.steps.steps-vertical .step{min-height:auto;border-bottom-width:0}.steps.steps-vertical .step:last-child{border-bottom-width:2px}@media(max-width:1023px){.steps{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(max-width:479px){.steps{grid-template-columns:1fr}}.timeline{display:grid;gap:0;width:100%;max-width:760px;margin:0;padding:0;list-style:none}.timeline .timeline-item{position:relative;display:grid;grid-template-columns:46px minmax(0,1fr);gap:12px;min-height:88px}.timeline .timeline-item:before{content:"";position:absolute;top:46px;bottom:0;left:22px;width:2px;background:#c0caf53d}.timeline .timeline-item:last-child:before{display:none}.timeline .timeline-marker{position:relative;z-index:1;display:inline-flex;align-items:center;justify-content:center;width:46px;height:46px;border:2px solid rgba(192,202,245,.24);color:#a9b1d6;background:#16161e;font-size:18px;transition-duration:.2s;transition-timing-function:ease;transition-property:border-color,background,color,box-shadow,transform}.timeline .timeline-content{min-width:0;padding:0 0 18px}.timeline .timeline-card{padding:15px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#1f2335;transition-duration:.2s;transition-timing-function:ease;transition-property:border-color,background,transform}.timeline .timeline-header{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:8px;margin-bottom:8px}.timeline .timeline-title{margin:0;font-size:14px;font-weight:700;line-height:1.25;text-transform:uppercase}.timeline .timeline-time{color:#787c99;font-size:12px;font-family:IBM Plex Mono,monospace;line-height:1.4}.timeline .timeline-text{margin:0;color:#a9b1d6;font-size:13px;line-height:1.4}.timeline .timeline-meta{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}.timeline .timeline-item-success .timeline-card,.timeline .timeline-item-success .timeline-marker{border-color:#9ece6a}.timeline .timeline-item-success .timeline-marker{color:#16161e;background:#9ece6a}.timeline .timeline-item-warning .timeline-card,.timeline .timeline-item-warning .timeline-marker{border-color:#e0af68}.timeline .timeline-item-warning .timeline-marker{color:#16161e;background:#e0af68}.timeline .timeline-item-danger .timeline-card,.timeline .timeline-item-danger .timeline-marker,.timeline .timeline-item-error .timeline-card,.timeline .timeline-item-error .timeline-marker{border-color:#f7768e}.timeline .timeline-item-danger .timeline-marker,.timeline .timeline-item-error .timeline-marker{color:#16161e;background:#f7768e}@media(hover:hover)and (pointer:fine){.timeline .timeline-item:hover .timeline-marker{box-shadow:0 0 0 4px #7aa2f724;transform:scale(1.04)}.timeline .timeline-item:hover .timeline-card{background:#c0caf516;transform:translate(5px)}}@media(hover:none)and (pointer:coarse){.timeline .timeline-item:active .timeline-marker{box-shadow:0 0 0 4px #7aa2f724;transform:scale(1.04)}.timeline .timeline-item:active .timeline-card{background:#c0caf516;transform:translate(5px)}}.activity-log{display:grid;width:100%;max-width:720px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#1f2335}.activity-log .activity-log-row{display:grid;grid-template-columns:minmax(120px,.24fr) minmax(0,1fr) auto;gap:12px;align-items:center;padding:12px 15px;border-bottom:2px solid rgba(192,202,245,.08);transition-duration:.2s;transition-timing-function:ease;transition-property:background}.activity-log .activity-log-row:last-child{border-bottom:0}@media(hover:hover)and (pointer:fine){.activity-log .activity-log-row:hover{background:#c0caf516}}@media(hover:none)and (pointer:coarse){.activity-log .activity-log-row:active{background:#c0caf516}}.activity-log .activity-log-time{color:#787c99;font-family:IBM Plex Mono,monospace;font-size:12px}.activity-log .activity-log-title{color:#c0caf5;font-size:13px;font-weight:600;line-height:1.4}@media(max-width:479px){.activity-log .activity-log-row{grid-template-columns:1fr;gap:8px}}.accordion{display:grid;width:100%;max-width:760px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#1f2335}.accordion-item{border-bottom:2px solid rgba(192,202,245,.08);overflow:hidden}.accordion-item:last-child{border-bottom:0}.accordion-item[open] .accordion-summary{color:#16161e;background:#c0caf5}.accordion-item[open] .accordion-icon{transform:rotate(180deg)}.accordion-summary{display:flex;width:100%;align-items:center;justify-content:space-between;gap:12px;min-height:46px;padding:12px 15px;border:0;color:#c0caf5;background:0 0;cursor:pointer;font-size:13px;font-weight:700;line-height:1;text-transform:uppercase;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background}.accordion-summary::-webkit-details-marker{display:none}.accordion-summary::marker{content:""}.accordion-summary:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}@media(hover:hover)and (pointer:fine){.accordion-summary:hover{color:#16161e;background:#7aa2f7}}@media(hover:none)and (pointer:coarse){.accordion-summary:active{color:#16161e;background:#7aa2f7}}.accordion-summary-content{display:flex;align-items:center;gap:8px;min-width:0}.accordion-icon{flex:0 0 auto;font-size:18px;transition-duration:.2s;transition-property:transform}.accordion-panel{overflow:hidden;padding:15px;color:#a9b1d6;font-size:13px;line-height:1.6;transition-duration:.28s;transition-timing-function:ease;transition-property:height,opacity,transform}.accordion-panel p{margin-top:0}.accordion-panel p:last-child{margin-bottom:0}.disclosure{max-width:520px;border:2px solid rgba(192,202,245,.24);background:#1f2335}.disclosure .accordion-summary{min-height:38px;padding:8px 12px}.disclosure .accordion-panel{padding:12px}.tabs{width:100%;max-width:900px}.tabs-list{display:flex;align-items:stretch;gap:0;max-width:100%;overflow-x:auto;scrollbar-width:thin}.tab{position:relative;display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:46px;padding:12px 15px;border:0;border-right:2px solid rgba(192,202,245,.08);border-radius:0;color:#a9b1d6;background:0 0;font-family:IBM Plex Mono,monospace;font-size:13px;font-weight:700;line-height:1;text-transform:uppercase;white-space:nowrap;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background,opacity}.tab .ph,.tab .ph-bold{font-size:18px}.tab:focus-visible{outline:2px solid #E0AF68;outline-offset:3px;z-index:1}@media(hover:hover)and (pointer:fine){.tab:hover{color:#16161e;background:#7aa2f7}}@media(hover:none)and (pointer:coarse){.tab:active{color:#16161e;background:#7aa2f7}}.tab:disabled,.tab[aria-disabled=true]{color:#787c99;cursor:not-allowed;opacity:.62}@media(hover:hover)and (pointer:fine){.tab:disabled:hover,.tab[aria-disabled=true]:hover{color:#787c99;background:0 0}}@media(hover:none)and (pointer:coarse){.tab:disabled:active,.tab[aria-disabled=true]:active{color:#787c99;background:0 0}}.tab-active,.tab[aria-selected=true]{color:#16161e;background:#c0caf5}.tab-panel{display:none}.tab-panel p{margin-top:0}.tab-panel p:last-child{margin-bottom:0}.tab-panel-active{display:block}.tabs-compact{max-width:620px}.tabs-compact .tabs-list{border-left-width:2px}.tabs-compact .tab{min-height:38px;padding:8px 12px}.tabs-vertical{grid-template-columns:minmax(180px,240px) minmax(0,1fr);align-items:start}.tabs-vertical .tabs-list{flex-direction:column;overflow-x:visible}.tabs-vertical .tab{justify-content:flex-start;border-right:0;border-bottom:2px solid rgba(192,202,245,.08);text-align:left}@media(max-width:767px){.tabs-vertical{grid-template-columns:1fr}.tabs-vertical .tabs-list{flex-direction:row;overflow-x:auto}.tabs-vertical .tab{justify-content:center;border-right:2px solid rgba(192,202,245,.08);border-bottom:0;text-align:center}}.drawer{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1000;display:flex;justify-content:flex-end;pointer-events:none}.drawer .drawer-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1010;background:#16161e;opacity:0;transition-duration:.28s;transition-timing-function:ease;transition-property:opacity;pointer-events:auto}.drawer .drawer-panel{position:relative;z-index:1020;width:min(460px,100vw - 18px);min-height:100vh;display:flex;flex-direction:column;gap:15px;background:#16161e;border-left:2px solid #c0caf5;box-shadow:-18px 0 42px #16161e61;opacity:0;transform:translate(100%);transition-duration:.28s;transition-timing-function:ease;transition-property:opacity,transform;pointer-events:auto}.drawer .drawer-header{display:flex;align-items:center;justify-content:space-between;padding-right:15px;border-bottom:2px solid rgba(192,202,245,.24)}.drawer .drawer-title{margin:0;padding:12px 15px;background:#c0caf5;color:#16161e;text-transform:uppercase;letter-spacing:.04em}.drawer .drawer-body{flex:1;overflow-y:auto;padding:18px}.drawer .drawer-footer{padding:18px;border-top:2px solid rgba(192,202,245,.24)}.drawer .drawer-footer .actions{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:12px;width:100%}.drawer.drawer-left{justify-content:flex-start}.drawer.drawer-left .drawer-panel{border-left:0;border-right:2px solid #c0caf5;box-shadow:18px 0 42px #16161e61;transform:translate(-100%)}.drawer.a-show .drawer-backdrop{opacity:.82}.drawer.a-show .drawer-panel{opacity:1;transform:translate(0)}.drawer.a-hide .drawer-backdrop{opacity:0}.drawer.a-hide .drawer-panel{opacity:0;transform:translate(100%)}.drawer.a-hide.drawer-left .drawer-panel{transform:translate(-100%)}.drawer-preview{display:grid;grid-template-columns:minmax(0,1fr) minmax(180px,280px);gap:18px;align-items:stretch;padding:18px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#1f2335}.drawer-preview .drawer-preview-content{display:flex;flex-direction:column;gap:12px}.drawer-preview .drawer-preview-panel{display:flex;flex-direction:column;gap:12px;padding:15px;border:2px solid #7aa2f7;background:#1f2335}.drawer-preview .drawer-preview-title{margin:0;color:#7aa2f7;font-size:14px;text-transform:uppercase}.drawer-preview .drawer-preview-text{margin:0;color:#a9b1d6;font-size:13px;line-height:1.6}@media(max-width:720px){.drawer-preview{grid-template-columns:1fr}}.nav-topbar{position:sticky;top:0;z-index:900;display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;min-height:58px;border-bottom:2px solid rgba(192,202,245,.24);background:#16161ef5;box-shadow:0 10px 28px #16161e42}.nav-topbar-toggle{display:inline-flex;align-items:center;align-self:stretch;gap:8px;min-width:150px;padding:0 15px;border:0;border-right:2px solid rgba(192,202,245,.24);color:#c0caf5;background:#1f2335;font-family:IBM Plex Mono,monospace;font-size:13px;font-weight:700;text-transform:uppercase;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background}.nav-topbar-toggle .ph{color:#7aa2f7;font-size:22px}.nav-topbar-toggle:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}@media(hover:hover)and (pointer:fine){.nav-topbar-toggle:hover{color:#16161e;background:#7aa2f7}.nav-topbar-toggle:hover .ph{color:#16161e}}@media(hover:none)and (pointer:coarse){.nav-topbar-toggle:active{color:#16161e;background:#7aa2f7}.nav-topbar-toggle:active .ph{color:#16161e}}.nav-topbar-brand{display:inline-flex;align-items:center;gap:8px;min-width:0;padding:0 15px;color:#c0caf5;font-size:13px;font-weight:700;text-transform:uppercase}.nav-topbar-brand img{width:22px;height:22px}.nav-topbar-current{min-width:160px;margin-right:15px;padding:5px 8px;border:2px solid rgba(192,202,245,.24);color:#a9b1d6;background:#1f2335;font-size:12px;font-weight:700;text-align:center;text-transform:uppercase}.nav-drawer-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:910;background:#16161e;opacity:0;pointer-events:none;transition-duration:.28s;transition-timing-function:ease;transition-property:opacity}.nav-drawer{position:fixed;inset:0 auto 0 0;z-index:920;display:flex;flex-direction:column;width:min(380px,100vw);max-height:100vh;border-right:2px solid #c0caf5;background:#1f2335;box-shadow:18px 0 42px #16161e61;opacity:0;overflow:hidden;pointer-events:none;transform:translate(-100%);transition-duration:.28s;transition-timing-function:ease;transition-property:opacity,transform}.nav-drawer.is-open{opacity:1;pointer-events:auto;transform:translate(0)}.nav-drawer-header{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px;border-bottom:2px solid rgba(192,202,245,.24)}.nav-drawer-title{display:inline-flex;padding:8px 12px;color:#16161e;background:#c0caf5;font-size:13px;font-weight:700;text-transform:uppercase}.nav-drawer-subtitle{margin-top:8px;color:#787c99;font-size:12px;font-weight:700;text-transform:uppercase}.nav-drawer-close{display:inline-flex;align-items:center;justify-content:center;width:46px;height:46px;padding:0;border:2px solid rgba(192,202,245,.24);color:#c0caf5;background:0 0;font-size:22px;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background,border-color}.nav-drawer-close:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}@media(hover:hover)and (pointer:fine){.nav-drawer-close:hover{color:#16161e;background:#f7768e;border-color:#f7768e}}@media(hover:none)and (pointer:coarse){.nav-drawer-close:active{color:#16161e;background:#f7768e;border-color:#f7768e}}.nav-drawer-body{flex:1;overflow-y:auto;overscroll-behavior:contain;padding:12px;scrollbar-width:thin;scrollbar-color:#7AA2F7 #1F2335}.nav-drawer-body::-webkit-scrollbar{width:8px}.nav-drawer-body::-webkit-scrollbar-track{background:#1f2335}.nav-drawer-body::-webkit-scrollbar-thumb{background:#7aa2f7}.nav-drawer-body .list.list-nav{max-width:none}.nav-drawer-footer{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px;border-top:2px solid rgba(192,202,245,.24);color:#787c99;background:#1f2335;font-size:12px;font-weight:700;text-transform:uppercase}.nav-drawer-footer .profile-identity{display:block;text-decoration:none;color:inherit;min-width:0;flex:1 1 auto;overflow:hidden}@media(hover:hover)and (pointer:fine){.nav-drawer-footer .profile-identity:hover{color:inherit}}@media(hover:none)and (pointer:coarse){.nav-drawer-footer .profile-identity:active{color:inherit}}.nav-drawer-open{overflow:hidden}.nav-drawer-open .nav-drawer-backdrop{opacity:.82;pointer-events:auto}@media(max-width:767px){.nav-topbar-toggle{min-width:54px;padding:0 12px}.nav-topbar-brand{padding-right:12px;padding-left:12px}.nav-topbar-current{max-width:38vw;min-width:0;margin-right:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nav-drawer{width:100vw;border-right:0}}.nav-shell-preview{width:100%;max-width:900px;overflow:hidden;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#16161e}.nav-shell-preview-topbar{position:relative;z-index:0;min-height:52px;box-shadow:none}.nav-shell-preview-body{display:grid;grid-template-columns:280px minmax(0,1fr);min-height:320px}.nav-shell-preview-drawer{position:relative;z-index:0;inset:auto;width:auto;max-height:none;opacity:1;pointer-events:auto;transform:none;box-shadow:none}.nav-shell-preview-content{display:flex;flex-direction:column;justify-content:center;gap:12px;min-width:0;padding:18px;border-left:2px solid rgba(192,202,245,.24);background:#1f2335}.nav-shell-preview-content h3{margin:0;color:#c0caf5;font-size:20px;text-transform:uppercase}.nav-shell-preview-content p{max-width:360px;margin:0;color:#a9b1d6;font-size:13px;line-height:1.6}@media(max-width:767px){.nav-shell-preview-body{grid-template-columns:1fr}.nav-shell-preview-content{min-height:180px;border-top:2px solid rgba(192,202,245,.24);border-left:0}}.toast{position:fixed;z-index:1100;bottom:-100px;right:15px;max-width:420px;background:#1f2335;border:2px solid #c0caf5;border-left-width:6px;padding:0;opacity:0;overflow:hidden;transition-duration:.28s;transition-timing-function:ease;transition-property:opacity,bottom}.toast.a-show{bottom:15px;opacity:1}.toast.a-hide{bottom:-45px;opacity:0}.toast .toast-content{display:flex;flex-direction:column;gap:0;padding:12px 48px 12px 15px}.toast .toast-content .toast-header{display:flex;align-items:center;gap:8px;font-size:13px;font-weight:700;text-transform:uppercase;color:#c0caf5;line-height:1}.toast .toast-content .toast-header .ph{font-size:22px;flex-shrink:0}.toast .toast-content .toast-text{font-size:13px;padding:8px 0 0;margin:0;color:#a9b1d6;line-height:1.4}.toast .toast-close{position:absolute;top:5px;right:8px;color:#c0caf5;width:38px;height:38px;border-color:transparent;background:0 0}.toast .toast-progress{height:3px;width:100%;background:#16161e;overflow:hidden;margin-top:1px}.toast .toast-progress .toast-progress-bar{height:100%;width:100%;transform-origin:left;animation:toast-progress linear forwards;background:#c0caf5}.toast.toast-info{border-color:#bb9af7;background:#bb9af72e}.toast.toast-info .toast-header .ph{color:#bb9af7}.toast.toast-info .toast-progress-bar{background:#bb9af7}.toast.toast-success{border-color:#9ece6a;background:#9ece6a2e}.toast.toast-success .toast-header .ph{color:#9ece6a}.toast.toast-success .toast-progress-bar{background:#9ece6a}.toast.toast-warning{border-color:#e0af68;background:#e0af682e}.toast.toast-warning .toast-header .ph{color:#e0af68}.toast.toast-warning .toast-progress-bar{background:#e0af68}.toast.toast-danger{border-color:#f7768e;background:#f7768e2e}.toast.toast-danger .toast-header .ph{color:#f7768e}.toast.toast-danger .toast-progress-bar{background:#f7768e}@keyframes toast-progress{0%{transform:scaleX(1)}to{transform:scaleX(0)}}.card{position:relative;max-width:340px;width:-moz-max-content;width:max-content;overflow:hidden;background:#1f2335;border:2px solid #c0caf5}.card .card-title{color:#16161e;background:#c0caf5;padding:8px 12px;font-weight:700;text-transform:uppercase}.card .card-content{padding:15px;height:100%}.card .card-content .card-thumb{display:block;width:min(68%,190px);margin:18px auto 22px}.card .card-content p{margin-top:8px;margin-bottom:0}.card .card-footer{padding:8px 15px 15px}.card.status-card{max-width:220px;overflow:hidden}.card.status-card .status-icon-container{position:relative}.card.status-card .status-icon-container .status-indicator{position:absolute;top:-15px;left:-5px;font-size:22px;color:#f7768e}.card.status-card .status-icon-container .status-indicator.status-online{color:#9ece6a}.card.status-card .status-icon-container .status-icon{display:flex;flex-direction:row;align-items:center;justify-content:flex-start;font-size:56px;height:108px;width:100%}.card.status-card .card-title{display:flex;width:100%;font-size:14px;font-weight:700;align-items:center;flex-direction:row;flex-wrap:nowrap;justify-content:space-between}.card.status-card .status-name{font-size:13px;line-height:1.4}.card.status-card.card-success{border-color:#9ece6a}.card.status-card.card-success .card-title,.card.status-card.card-success .modal-title,.card.status-card.card-success .toast-title{color:#16161e;background:#9ece6a}.card.status-card.card-success .status-icon{color:#9ece6a}.card.status-card.card-warning{border-color:#e0af68}.card.status-card.card-warning .card-title,.card.status-card.card-warning .modal-title,.card.status-card.card-warning .toast-title{color:#16161e;background:#e0af68}.card.status-card.card-warning .status-icon{color:#e0af68}.card.status-card.card-info{border-color:#bb9af7}.card.status-card.card-info .card-title,.card.status-card.card-info .modal-title,.card.status-card.card-info .toast-title{color:#16161e;background:#bb9af7}.card.status-card.card-info .status-icon{color:#bb9af7}.card.status-card.card-secondary{border-color:#7aa2f7}.card.status-card.card-secondary .card-title,.card.status-card.card-secondary .modal-title,.card.status-card.card-secondary .toast-title{color:#16161e;background:#7aa2f7}.card.status-card.card-secondary .status-icon{color:#7aa2f7}.card.status-card.card-danger,.card.status-card.card-error{border-color:#f7768e}.card.status-card.card-danger .card-title,.card.status-card.card-danger .modal-title,.card.status-card.card-danger .toast-title,.card.status-card.card-error .card-title,.card.status-card.card-error .modal-title,.card.status-card.card-error .toast-title{color:#16161e;background:#f7768e}.card.status-card.card-danger .status-icon,.card.status-card.card-error .status-icon{color:#f7768e}.card.metric-card{max-width:320px;border-color:#c0caf53d}.card.metric-card .card-content{display:flex;flex-direction:column;gap:15px}.card.metric-card .metric-card-header{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.card.metric-card .metric-card-label{margin:0;color:#a9b1d6;font-size:13px;font-weight:600;text-transform:uppercase}.card.metric-card .metric-card-icon{display:inline-flex;align-items:center;justify-content:center;width:46px;height:46px;color:#16161e;background:#7aa2f7;font-size:22px}.card.metric-card .metric-card-value{margin:0;color:#c0caf5;font-size:34px;font-weight:700;line-height:1.15}.card.metric-card .metric-card-meta{display:flex;flex-wrap:wrap;align-items:center;gap:8px;color:#787c99;font-size:13px}.card.metric-card .metric-card-delta{color:#9ece6a;font-weight:700}.card.metric-card .metric-card-delta.metric-card-delta-negative{color:#f7768e}.card.card-horizontal{max-width:none;display:flex;flex-direction:row;align-items:stretch;overflow:hidden}.card.card-horizontal .card-media{flex:0 0 20%;min-width:80px;max-width:160px;max-height:160px;overflow:hidden;position:relative;aspect-ratio:1;align-self:start}.card.card-horizontal .card-media img{width:100%;height:100%;-o-object-fit:cover;object-fit:cover;display:block}.card.card-horizontal .card-body{flex:1 1 auto;display:flex;flex-direction:column;padding:15px;gap:12px}.card.card-horizontal .card-title{padding:0;background:0 0;color:#c0caf5;font-size:16px;font-weight:700;text-transform:none;line-height:1.25}.card.card-horizontal .card-title a{color:inherit;text-decoration:none}.card.card-horizontal .card-content{padding:0;height:auto}.card.card-horizontal .card-content p{margin:0}.card.card-horizontal .card-footer{padding:0;display:flex;flex-wrap:wrap;align-items:center;gap:12px;color:#a9b1d6;font-size:13px}.card.action-card{max-width:360px;border-color:#7aa2f7}.card.action-card .card-content{display:flex;flex-direction:column;gap:15px}.card.action-card .action-card-kicker{display:inline-flex;width:-moz-max-content;width:max-content;padding:5px 8px;color:#16161e;background:#7aa2f7;font-size:12px;font-weight:700;line-height:1;text-transform:uppercase}.card.action-card .action-card-title{margin:0;font-size:20px;font-weight:700;line-height:1.25;text-transform:uppercase}.card.action-card .action-card-text{margin:0;color:#a9b1d6;font-size:13px;line-height:1.6}.card.action-card .action-card-actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:8px}.card.login-card{max-width:100%;width:460px;border-color:#c0caf5}.card.login-card .login-card-header{display:flex;align-items:center;justify-content:flex-start;gap:12px;padding:12px}.card.login-card .login-card-logo{display:block;width:auto;max-height:40px}.card.login-card .login-card-logo-icon{font-size:56px;color:#c0caf5}.card.login-card .login-card-title{font-size:20px;font-weight:700;text-transform:uppercase}.card.login-card .login-card-form{display:flex;flex-direction:column;gap:15px}.card.login-card .login-card-submit{width:-moz-max-content;width:max-content;margin-top:8px}.card.login-card .form-group{margin-bottom:0}.card.login-card .login-card-links{display:flex;justify-content:space-between;gap:12px;margin-top:8px;font-size:13px}.card.login-card .login-card-link{color:#a9b1d6;text-decoration:none}@media(hover:hover)and (pointer:fine){.card.login-card .login-card-link:hover{color:#c0caf5;text-decoration:underline}}@media(hover:none)and (pointer:coarse){.card.login-card .login-card-link:active{color:#c0caf5;text-decoration:underline}}.card.login-card .login-card-error{margin-bottom:8px}.card.user-card{max-width:320px}.card.user-card .user-card-body{display:flex;flex-direction:column;align-items:center;gap:15px;padding:18px;text-align:center}.card.user-card .identity{flex-direction:column;align-items:center;gap:15px}.card.user-card .identity .avatar{width:64px;height:64px;font-size:20px}.card.user-card .identity .identity-content{align-items:center;text-align:center}.card.user-card .user-card-role{color:#a9b1d6;font-size:13px;margin-top:5px}.card.user-card .user-card-actions{display:flex;gap:8px}.card.user-card-compact{max-width:none}.card.user-card-compact .user-card-body{flex-direction:row;justify-content:space-between;align-items:center;padding:12px 15px;text-align:left}.card.user-card-compact .identity{flex-direction:row;gap:12px}.card.user-card-compact .identity .avatar{width:38px;height:38px;font-size:13px}.card.user-card-compact .identity .identity-content{align-items:flex-start}.card.user-card-compact .user-card-actions{display:flex;gap:5px}.modal{position:fixed;top:0;bottom:0;left:0;right:0;z-index:1000;display:flex;flex-direction:column;align-items:center;justify-content:center}.modal .modal-backdrop{position:fixed;z-index:1010;top:0;bottom:0;left:0;right:0;background:#16161e;opacity:0;transition-duration:.25s;transition-property:opacity}.modal .modal-dialog{position:relative;z-index:1020;width:100%;max-width:960px;margin:200px 18px 18px;height:auto;max-height:calc(100vh - 48px);padding:0;display:flex;flex-direction:column;gap:0;opacity:0;transition-duration:.28s;transition-timing-function:ease;transition-property:opacity,margin-top}.modal .modal-dialog .modal-header{display:flex;flex-direction:row;justify-content:space-between;align-items:center;gap:15px}.modal .modal-dialog .modal-header .modal-title{padding:12px 15px;background:#c0caf5;color:#16161e;text-transform:uppercase;letter-spacing:.04em}.modal .modal-dialog .modal-header .modal-close{flex:0 0 auto;color:#c0caf5;border-color:#c0caf53d;background:#16161e}.modal .modal-dialog .modal-panel{min-height:200px;display:flex;flex-direction:column;gap:15px;overflow:hidden;background:#16161e;border:2px solid #c0caf5;border-left-width:6px}.modal .modal-dialog .modal-body{max-height:700px;overflow-y:auto;padding:18px}.modal .modal-dialog .modal-footer{padding:18px}.modal .modal-dialog .modal-footer .actions{display:flex;flex-direction:row;justify-content:flex-end;gap:15px;width:100%}.modal.a-show .modal-backdrop{opacity:1}.modal.a-show .modal-dialog{opacity:1;margin-top:0}.modal.a-hide .modal-backdrop{opacity:0}.modal.a-hide .modal-dialog{opacity:0;margin-top:-200px}.alert{position:relative;overflow:hidden;margin-bottom:12px;padding:12px 15px;border:2px solid transparent;border-left-style:solid;border-left-width:6px;background:#1f2335;color:#c0caf5;font-weight:500;line-height:1.4;transition-duration:.2s;transition-timing-function:ease;transition-property:background,color,border-color}.alert:after{content:"";position:absolute;inset:0 auto 0 0;width:36%;background:linear-gradient(90deg,transparent,rgba(192,202,245,.12),transparent);opacity:0;pointer-events:none;transform:translate(-120%)}@media(hover:hover)and (pointer:fine){.alert:hover:after{opacity:1;animation:terminal_scan_x .8s ease}}@media(hover:none)and (pointer:coarse){.alert:active:after{opacity:1;animation:terminal_scan_x .8s ease}}.alert.alert-primary{border-color:#c0caf5;background:#c0caf51a;color:#c0caf5}.alert.alert-success{border-color:#9ece6a;background:#9ece6a1a;color:#9ece6a}.alert.alert-secondary{border-color:#7aa2f7;background:#7aa2f71a;color:#7aa2f7}.alert.alert-info{border-color:#bb9af7;background:#bb9af71a;color:#c0caf5}.alert.alert-warning{border-color:#e0af68;background:#e0af681a;color:#e0af68}.alert.alert-danger,.alert.alert-error{border-color:#f7768e;background:#f7768e1a;color:#f7768e}.advanced-select-container{position:relative;height:0}.advanced-select{position:absolute;z-index:100;top:6px;width:100%;height:auto;max-height:200px;overflow-y:auto;background:#16161e;border:2px solid #c0caf5;border-left-width:6px;margin-top:20px;opacity:0;visibility:hidden;transition-property:opacity,margin-top,visibility;transition-duration:.2s;transition-timing-function:ease}.advanced-select.a-show{opacity:1;margin-top:0;visibility:visible}.advanced-select .popup-options-container .not-found{width:100%;padding:15px;text-align:center;display:none}.advanced-select .popup-options-container .not-found.show{display:block}.advanced-select .popup-options-container .options{width:100%;display:none}.advanced-select .popup-options-container .options.show{display:block}.advanced-select .popup-options-container .options .option{padding:8px 15px;transition-property:color,background;transition-duration:.15s}.advanced-select .popup-options-container .options .option.hide{display:none}.advanced-select .popup-options-container .options .option.focus,.advanced-select .popup-options-container .options .option:hover{color:#16161e;background:#e0af68}.component.editable-string-component .editable-string-content{display:flex;flex-direction:row;align-items:center;gap:8px;font-size:inherit}.component.editable-string-component .editable-string-content .editable-string{font-size:inherit;border-bottom:2px solid rgba(192,202,245,.24)}@media(hover:hover)and (pointer:fine){.component.editable-string-component .apply-changes-btn:hover,.component.editable-string-component .cancel-changes-btn:hover,.component.editable-string-component .edit-text-btn:hover{color:#16161e;background:#e0af68}}@media(hover:none)and (pointer:coarse){.component.editable-string-component .apply-changes-btn:active,.component.editable-string-component .cancel-changes-btn:active,.component.editable-string-component .edit-text-btn:active{color:#16161e;background:#e0af68}}.component.editable-string-component .apply-changes-btn{color:#e0af68}.component.editable-string-component .editable-string-form{display:flex;flex-direction:row;align-items:center;gap:8px}.component.editable-string-component .editable-string-form .form-group{max-width:260px;margin:0}.component.editable-string-component .editable-string-form .form-group .input{padding:8px 15px}.tabs{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:15px}.tabs .tab{display:inline-flex;align-items:center;min-height:38px;padding:8px 12px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;color:#a9b1d6;background:#1f2335;font-family:IBM Plex Mono,monospace;font-size:13px;font-weight:600;line-height:1;text-transform:uppercase;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background,border-color}.tabs .tab:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}@media(hover:hover)and (pointer:fine){.tabs .tab:hover{color:#16161e;background:#7aa2f7;border-color:#7aa2f7}}@media(hover:none)and (pointer:coarse){.tabs .tab:active{color:#16161e;background:#7aa2f7;border-color:#7aa2f7}}.tabs .tab.tab-active,.tabs .tab[aria-selected=true]{color:#16161e;background:#c0caf5;border-color:#c0caf5}.dropdown,.popover{position:relative;display:inline-flex}.dropdown-menu,.popover-panel,.tooltip-panel{z-index:40;background:#1f2335;border:2px solid rgba(192,202,245,.24);border-left-width:6px;box-shadow:0 14px 36px #16161e5c}.dropdown-menu,.popover-panel{position:absolute;top:calc(100% + 8px);left:0;min-width:220px;display:none;transform-origin:top left}.dropdown.is-open .dropdown-menu,.popover.is-open .popover-panel{display:block;animation:overlay_reveal .2s ease both}.dropdown-menu{padding:5px}.dropdown-menu .dropdown-item{display:flex;align-items:center;gap:8px;width:100%;min-height:38px;padding:8px 12px;border:0;color:#c0caf5;background:0 0;font-family:IBM Plex Mono,monospace;font-size:13px;text-align:left;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background}.dropdown-menu .dropdown-item .ph,.dropdown-menu .dropdown-item .ph-bold{font-size:18px}.dropdown-menu .dropdown-item:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}@media(hover:hover)and (pointer:fine){.dropdown-menu .dropdown-item:hover{color:#16161e;background:#7aa2f7}}@media(hover:none)and (pointer:coarse){.dropdown-menu .dropdown-item:active{color:#16161e;background:#7aa2f7}}.dropdown-menu .dropdown-item.dropdown-item-danger{color:#f7768e}@media(hover:hover)and (pointer:fine){.dropdown-menu .dropdown-item.dropdown-item-danger:hover{color:#16161e;background:#f7768e}}@media(hover:none)and (pointer:coarse){.dropdown-menu .dropdown-item.dropdown-item-danger:active{color:#16161e;background:#f7768e}}.popover-panel{width:min(320px,100vw - 22px);padding:15px}.popover-panel .popover-title{margin:0 0 8px;font-size:14px;font-weight:700;text-transform:uppercase}.popover-panel .popover-text{margin:0;color:#a9b1d6;font-size:13px;line-height:1.6}.tooltip{position:relative;display:inline-flex}.tooltip-panel{position:absolute;left:50%;bottom:calc(100% + 8px);width:-moz-max-content;width:max-content;max-width:260px;padding:8px 12px;color:#c0caf5;font-size:12px;line-height:1.4;transform:translate(-50%);opacity:0;visibility:hidden;pointer-events:none;transition-duration:.15s;transition-timing-function:ease;transition-property:opacity,visibility}.tooltip.is-open .tooltip-panel,.tooltip:focus-within .tooltip-panel,.tooltip:hover .tooltip-panel{opacity:1;visibility:visible;animation:tooltip_reveal .15s ease both}.m-0{margin:0!important}.mt-0{margin-top:0!important}.mr-0{margin-right:0!important}.mb-0{margin-bottom:0!important}.ml-0{margin-left:0!important}.mx-0{margin-left:0!important;margin-right:0!important}.my-0{margin-top:0!important;margin-bottom:0!important}.p-0{padding:0!important}.pt-0{padding-top:0!important}.pr-0{padding-right:0!important}.pb-0{padding-bottom:0!important}.pl-0{padding-left:0!important}.px-0{padding-left:0!important;padding-right:0!important}.py-0{padding-top:0!important;padding-bottom:0!important}.g-0{gap:0!important}.gx-0{-moz-column-gap:0!important;column-gap:0!important}.gy-0{row-gap:0!important}.m-1{margin:5px!important}.mt-1{margin-top:5px!important}.mr-1{margin-right:5px!important}.mb-1{margin-bottom:5px!important}.ml-1{margin-left:5px!important}.mx-1{margin-left:5px!important;margin-right:5px!important}.my-1{margin-top:5px!important;margin-bottom:5px!important}.p-1{padding:5px!important}.pt-1{padding-top:5px!important}.pr-1{padding-right:5px!important}.pb-1{padding-bottom:5px!important}.pl-1{padding-left:5px!important}.px-1{padding-left:5px!important;padding-right:5px!important}.py-1{padding-top:5px!important;padding-bottom:5px!important}.g-1{gap:5px!important}.gx-1{-moz-column-gap:5px!important;column-gap:5px!important}.gy-1{row-gap:5px!important}.m-2{margin:8px!important}.mt-2{margin-top:8px!important}.mr-2{margin-right:8px!important}.mb-2{margin-bottom:8px!important}.ml-2{margin-left:8px!important}.mx-2{margin-left:8px!important;margin-right:8px!important}.my-2{margin-top:8px!important;margin-bottom:8px!important}.p-2{padding:8px!important}.pt-2{padding-top:8px!important}.pr-2{padding-right:8px!important}.pb-2{padding-bottom:8px!important}.pl-2{padding-left:8px!important}.px-2{padding-left:8px!important;padding-right:8px!important}.py-2{padding-top:8px!important;padding-bottom:8px!important}.g-2{gap:8px!important}.gx-2{-moz-column-gap:8px!important;column-gap:8px!important}.gy-2{row-gap:8px!important}.m-3{margin:12px!important}.mt-3{margin-top:12px!important}.mr-3{margin-right:12px!important}.mb-3{margin-bottom:12px!important}.ml-3{margin-left:12px!important}.mx-3{margin-left:12px!important;margin-right:12px!important}.my-3{margin-top:12px!important;margin-bottom:12px!important}.p-3{padding:12px!important}.pt-3{padding-top:12px!important}.pr-3{padding-right:12px!important}.pb-3{padding-bottom:12px!important}.pl-3{padding-left:12px!important}.px-3{padding-left:12px!important;padding-right:12px!important}.py-3{padding-top:12px!important;padding-bottom:12px!important}.g-3{gap:12px!important}.gx-3{-moz-column-gap:12px!important;column-gap:12px!important}.gy-3{row-gap:12px!important}.m-4{margin:15px!important}.mt-4{margin-top:15px!important}.mr-4{margin-right:15px!important}.mb-4{margin-bottom:15px!important}.ml-4{margin-left:15px!important}.mx-4{margin-left:15px!important;margin-right:15px!important}.my-4{margin-top:15px!important;margin-bottom:15px!important}.p-4{padding:15px!important}.pt-4{padding-top:15px!important}.pr-4{padding-right:15px!important}.pb-4{padding-bottom:15px!important}.pl-4{padding-left:15px!important}.px-4{padding-left:15px!important;padding-right:15px!important}.py-4{padding-top:15px!important;padding-bottom:15px!important}.g-4{gap:15px!important}.gx-4{-moz-column-gap:15px!important;column-gap:15px!important}.gy-4{row-gap:15px!important}.m-5{margin:18px!important}.mt-5{margin-top:18px!important}.mr-5{margin-right:18px!important}.mb-5{margin-bottom:18px!important}.ml-5{margin-left:18px!important}.mx-5{margin-left:18px!important;margin-right:18px!important}.my-5{margin-top:18px!important;margin-bottom:18px!important}.p-5{padding:18px!important}.pt-5{padding-top:18px!important}.pr-5{padding-right:18px!important}.pb-5{padding-bottom:18px!important}.pl-5{padding-left:18px!important}.px-5{padding-left:18px!important;padding-right:18px!important}.py-5{padding-top:18px!important;padding-bottom:18px!important}.g-5{gap:18px!important}.gx-5{-moz-column-gap:18px!important;column-gap:18px!important}.gy-5{row-gap:18px!important}.m-6{margin:22px!important}.mt-6{margin-top:22px!important}.mr-6{margin-right:22px!important}.mb-6{margin-bottom:22px!important}.ml-6{margin-left:22px!important}.mx-6{margin-left:22px!important;margin-right:22px!important}.my-6{margin-top:22px!important;margin-bottom:22px!important}.p-6{padding:22px!important}.pt-6{padding-top:22px!important}.pr-6{padding-right:22px!important}.pb-6{padding-bottom:22px!important}.pl-6{padding-left:22px!important}.px-6{padding-left:22px!important;padding-right:22px!important}.py-6{padding-top:22px!important;padding-bottom:22px!important}.g-6{gap:22px!important}.gx-6{-moz-column-gap:22px!important;column-gap:22px!important}.gy-6{row-gap:22px!important}.m-7{margin:26px!important}.mt-7{margin-top:26px!important}.mr-7{margin-right:26px!important}.mb-7{margin-bottom:26px!important}.ml-7{margin-left:26px!important}.mx-7{margin-left:26px!important;margin-right:26px!important}.my-7{margin-top:26px!important;margin-bottom:26px!important}.p-7{padding:26px!important}.pt-7{padding-top:26px!important}.pr-7{padding-right:26px!important}.pb-7{padding-bottom:26px!important}.pl-7{padding-left:26px!important}.px-7{padding-left:26px!important;padding-right:26px!important}.py-7{padding-top:26px!important;padding-bottom:26px!important}.g-7{gap:26px!important}.gx-7{-moz-column-gap:26px!important;column-gap:26px!important}.gy-7{row-gap:26px!important}.m-8{margin:34px!important}.mt-8{margin-top:34px!important}.mr-8{margin-right:34px!important}.mb-8{margin-bottom:34px!important}.ml-8{margin-left:34px!important}.mx-8{margin-left:34px!important;margin-right:34px!important}.my-8{margin-top:34px!important;margin-bottom:34px!important}.p-8{padding:34px!important}.pt-8{padding-top:34px!important}.pr-8{padding-right:34px!important}.pb-8{padding-bottom:34px!important}.pl-8{padding-left:34px!important}.px-8{padding-left:34px!important;padding-right:34px!important}.py-8{padding-top:34px!important;padding-bottom:34px!important}.g-8{gap:34px!important}.gx-8{-moz-column-gap:34px!important;column-gap:34px!important}.gy-8{row-gap:34px!important}.m-9{margin:42px!important}.mt-9{margin-top:42px!important}.mr-9{margin-right:42px!important}.mb-9{margin-bottom:42px!important}.ml-9{margin-left:42px!important}.mx-9{margin-left:42px!important;margin-right:42px!important}.my-9{margin-top:42px!important;margin-bottom:42px!important}.p-9{padding:42px!important}.pt-9{padding-top:42px!important}.pr-9{padding-right:42px!important}.pb-9{padding-bottom:42px!important}.pl-9{padding-left:42px!important}.px-9{padding-left:42px!important;padding-right:42px!important}.py-9{padding-top:42px!important;padding-bottom:42px!important}.g-9{gap:42px!important}.gx-9{-moz-column-gap:42px!important;column-gap:42px!important}.gy-9{row-gap:42px!important}.m-10{margin:48px!important}.mt-10{margin-top:48px!important}.mr-10{margin-right:48px!important}.mb-10{margin-bottom:48px!important}.ml-10{margin-left:48px!important}.mx-10{margin-left:48px!important;margin-right:48px!important}.my-10{margin-top:48px!important;margin-bottom:48px!important}.p-10{padding:48px!important}.pt-10{padding-top:48px!important}.pr-10{padding-right:48px!important}.pb-10{padding-bottom:48px!important}.pl-10{padding-left:48px!important}.px-10{padding-left:48px!important;padding-right:48px!important}.py-10{padding-top:48px!important;padding-bottom:48px!important}.g-10{gap:48px!important}.gx-10{-moz-column-gap:48px!important;column-gap:48px!important}.gy-10{row-gap:48px!important}.m-11{margin:64px!important}.mt-11{margin-top:64px!important}.mr-11{margin-right:64px!important}.mb-11{margin-bottom:64px!important}.ml-11{margin-left:64px!important}.mx-11{margin-left:64px!important;margin-right:64px!important}.my-11{margin-top:64px!important;margin-bottom:64px!important}.p-11{padding:64px!important}.pt-11{padding-top:64px!important}.pr-11{padding-right:64px!important}.pb-11{padding-bottom:64px!important}.pl-11{padding-left:64px!important}.px-11{padding-left:64px!important;padding-right:64px!important}.py-11{padding-top:64px!important;padding-bottom:64px!important}.g-11{gap:64px!important}.gx-11{-moz-column-gap:64px!important;column-gap:64px!important}.gy-11{row-gap:64px!important}.m-12{margin:80px!important}.mt-12{margin-top:80px!important}.mr-12{margin-right:80px!important}.mb-12{margin-bottom:80px!important}.ml-12{margin-left:80px!important}.mx-12{margin-left:80px!important;margin-right:80px!important}.my-12{margin-top:80px!important;margin-bottom:80px!important}.p-12{padding:80px!important}.pt-12{padding-top:80px!important}.pr-12{padding-right:80px!important}.pb-12{padding-bottom:80px!important}.pl-12{padding-left:80px!important}.px-12{padding-left:80px!important;padding-right:80px!important}.py-12{padding-top:80px!important;padding-bottom:80px!important}.g-12{gap:80px!important}.gx-12{-moz-column-gap:80px!important;column-gap:80px!important}.gy-12{row-gap:80px!important}.row{display:flex;flex-direction:row}@media(max-width:1279px){.row.adaptive{flex-direction:column}}.column{display:flex;flex-direction:column}.f-grid{display:flex;flex-direction:row;flex-wrap:wrap}.grid{display:grid}.grid-2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr))}.grid-3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr))}.items-start{align-items:flex-start!important}.items-center{align-items:center!important}.items-end{align-items:flex-end!important}.justify-start{justify-content:flex-start!important}.justify-center{justify-content:center!important}.justify-between{justify-content:space-between!important}.justify-end{justify-content:flex-end!important}.w-100{width:100%}.w-auto{width:auto!important}.w-fit{width:-moz-fit-content!important;width:fit-content!important}.w-200{width:200%}.h-100{height:100%}.min-w-0{min-width:0!important}.overflow-hidden{overflow:hidden!important}.overflow-auto{overflow:auto!important}.fs-xs{font-size:12px}.fs-sm{font-size:13px}.fs-md{font-size:14px}.fs-base{font-size:15px}.fs-lg{font-size:16px}.fs-xl{font-size:20px}.text-left{text-align:left!important}.text-center{text-align:center!important}.text-right{text-align:right!important}.text-uppercase{text-transform:uppercase!important}.text-nowrap{white-space:nowrap!important}.d-none{display:none!important}.d-block{display:block!important}.d-inline-flex{display:inline-flex!important}.d-flex{display:flex!important}.d-grid{display:grid!important}@media(max-width:767px){.grid-2,.grid-3{grid-template-columns:1fr}}*{box-sizing:border-box}body,html{padding:0;margin:0}body{background-color:#16161e;color:#c0caf5}::-webkit-scrollbar{width:10px}::-webkit-scrollbar-track{width:10px;background:#16161e;cursor:pointer}::-webkit-scrollbar-thumb{width:10px;background:#414868;cursor:default}::-webkit-scrollbar-corner{background:0 0;height:1px}::-webkit-scrollbar-button{display:none}.ph.normalize{position:relative;top:.15em}code[class*=language-],pre[class*=language-]{color:#000;background:none;text-shadow:0 1px white;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,code[class*=language-] ::-moz-selection{text-shadow:none;background:#b3d4fc}pre[class*=language-]::selection,pre[class*=language-] ::selection,code[class*=language-]::selection,code[class*=language-] ::selection{text-shadow:none;background:#b3d4fc}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#f5f2f0}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.comment,.token.prolog,.token.doctype,.token.cdata{color:#708090}.token.punctuation{color:#999}.token.property,.token.tag,.token.boolean,.token.number,.token.constant,.token.symbol,.token.deleted{color:#905}.token.selector,.token.attr-name,.token.string,.token.char,.token.builtin,.token.inserted{color:#690}.token.operator,.token.entity,.token.url,.language-css .token.string,.style .token.string{color:#9a6e3a;background:#ffffff80}.token.atrule,.token.attr-value,.token.keyword{color:#07a}.token.function,.token.class-name{color:#dd4a68}.token.regex,.token.important,.token.variable{color:#e90}pre[class*=language-],code[class*=language-]{color:#c0caf5;background:none;font-family:IBM Plex Mono,Courier New,monospace;font-size:12px;line-height:1.6;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;-moz-tab-size:2;tab-size:2;-webkit-hyphens:none;hyphens:none}pre[class*=language-]{padding:14px;margin:0;overflow:auto;background:#11131a;border:1px solid rgba(192,202,245,.12)}.token.comment,.token.prolog,.token.doctype,.token.cdata{color:#565f89}.token.punctuation{color:#7aa2f7}.token.namespace{opacity:.7}.token.property,.token.tag,.token.boolean,.token.number,.token.constant,.token.symbol,.token.deleted{color:#ff9e64}.token.selector,.token.attr-name,.token.string,.token.char,.token.builtin,.token.inserted{color:#9ece6a}.token.operator,.token.entity,.token.url,.language-css .token.string,.style .token.string{color:#89ddff;background:none}.token.atrule,.token.attr-value,.token.keyword{color:#bb9af7}.token.function,.token.class-name{color:#0db9d7}.token.regex,.token.important,.token.variable{color:#e0af68}.token.important,.token.bold{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}:root{color-scheme:dark;font-family:IBM Plex Mono,Courier New,monospace;background:#07080b;color:#f4f4f5;--color-bg: #07080b;--color-panel: #11131a;--color-panel-strong: #171a24;--color-text: #f4f4f5;--color-muted: #9ca3af;--color-primary: #12b7f5;--color-accent: #00f5a0;--color-warning: #ffe500;--color-danger: #ff3d00;--border: 1px solid #f4f4f5}*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}html,body{overscroll-behavior-y:none;-webkit-overflow-scrolling:touch}body{margin:0;min-width:320px;min-height:100vh;background:radial-gradient(circle at 20% 0%,rgba(18,183,245,.12),transparent 30%),var(--color-bg)}a{color:inherit}button,input,textarea{font:inherit}.page{width:min(1200px,100%);margin:0 auto;padding:36px 14px}.page .page-header{margin-bottom:24px;animation:none}.page .page-header:after,.page .page-header:hover:after{display:none}.area-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:16px;align-items:stretch}.area-grid .card{width:100%;max-width:none;display:flex;flex-direction:column}.area-grid .card .card-content{flex:1;display:flex;flex-direction:column;gap:12px}.area-grid .card .card-footer{margin-top:auto}.area-grid .card-content p,.area-grid .card-content .text{margin-bottom:0}.area-tree,.area-tree-children{display:grid;gap:12px;margin:0;padding:0;list-style:none}.area-tree-children{margin-top:12px;padding-left:28px}.area-tree-card{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:14px;padding:14px;border:var(--border);background:var(--color-panel);cursor:pointer}.area-tree-card:hover{background:var(--color-panel-strong)}.tree-toggle{width:36px;height:36px;border:2px solid currentColor;background:transparent;cursor:pointer;font-weight:800}.tree-toggle:disabled{cursor:default}.area-tree-info h2{margin:0 0 8px;font-size:20px}.area-tree-info p,.area-tree-actions{display:flex;flex-wrap:wrap;gap:8px;margin:0}.devices-panel{display:grid;gap:16px}.devices-summary,.devices-actions{display:flex;flex-wrap:wrap;gap:8px}.modal-footer{display:flex;justify-content:flex-end;gap:12px}.nav-drawer-footer .card.user-card-compact{border:0;width:100%}.nav-drawer-footer .card.user-card-compact .user-card-body{padding:0}.toast.toast-info,.toast.toast-success,.toast.toast-warning,.toast.toast-danger{background:var(--color-panel-strong)}@media(max-width:720px){.area-tree-card{grid-template-columns:1fr}.area-tree-children{padding-left:14px}} diff --git a/server/dist/assets/index-BxlltLEk.js b/server/dist/assets/index-BxlltLEk.js deleted file mode 100644 index 104ad3d..0000000 --- a/server/dist/assets/index-BxlltLEk.js +++ /dev/null @@ -1,37 +0,0 @@ -(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const a of document.querySelectorAll('link[rel="modulepreload"]'))s(a);new MutationObserver(a=>{for(const r of a)if(r.type==="childList")for(const o of r.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&s(o)}).observe(document,{childList:!0,subtree:!0});function n(a){const r={};return a.integrity&&(r.integrity=a.integrity),a.referrerPolicy&&(r.referrerPolicy=a.referrerPolicy),a.crossOrigin==="use-credentials"?r.credentials="include":a.crossOrigin==="anonymous"?r.credentials="omit":r.credentials="same-origin",r}function s(a){if(a.ep)return;a.ep=!0;const r=n(a);fetch(a.href,r)}})();/** -* @vue/shared v3.5.33 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/function Ja(e){const t=Object.create(null);for(const n of e.split(","))t[n]=1;return n=>n in t}const Ne={},Rn=[],Ft=()=>{},zi=()=>!1,Ms=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),Us=e=>e.startsWith("onUpdate:"),tt=Object.assign,Ya=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},Vl=Object.prototype.hasOwnProperty,Ce=(e,t)=>Vl.call(e,t),ye=Array.isArray,$n=e=>vs(e)==="[object Map]",Ki=e=>vs(e)==="[object Set]",Pr=e=>vs(e)==="[object Date]",be=e=>typeof e=="function",He=e=>typeof e=="string",yt=e=>typeof e=="symbol",$e=e=>e!==null&&typeof e=="object",Wi=e=>($e(e)||be(e))&&be(e.then)&&be(e.catch),Ji=Object.prototype.toString,vs=e=>Ji.call(e),Hl=e=>vs(e).slice(8,-1),Yi=e=>vs(e)==="[object Object]",Bs=e=>He(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,Zn=Ja(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),js=e=>{const t=Object.create(null);return(n=>t[n]||(t[n]=e(n)))},Gl=/-\w/g,ft=js(e=>e.replace(Gl,t=>t.slice(1).toUpperCase())),ql=/\B([A-Z])/g,un=js(e=>e.replace(ql,"-$1").toLowerCase()),Vs=js(e=>e.charAt(0).toUpperCase()+e.slice(1)),ia=js(e=>e?`on${Vs(e)}`:""),Ot=(e,t)=>!Object.is(e,t),oa=(e,...t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:s,value:n})},zl=e=>{const t=parseFloat(e);return isNaN(t)?e:t};let Lr;const Hs=()=>Lr||(Lr=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function Xa(e){if(ye(e)){const t={};for(let n=0;n{if(n){const s=n.split(Wl);s.length>1&&(t[s[0].trim()]=s[1].trim())}}),t}function Mt(e){let t="";if(He(e))t=e;else if(ye(e))for(let n=0;n!!(e&&e.__v_isRef===!0),N=e=>He(e)?e:e==null?"":ye(e)||$e(e)&&(e.toString===Ji||!be(e.toString))?Qi(e)?N(e.value):JSON.stringify(e,eo,2):String(e),eo=(e,t)=>Qi(t)?eo(e,t.value):$n(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[s,a],r)=>(n[la(s,r)+" =>"]=a,n),{})}:Ki(t)?{[`Set(${t.size})`]:[...t.values()].map(n=>la(n))}:yt(t)?la(t):$e(t)&&!ye(t)&&!Yi(t)?String(t):t,la=(e,t="")=>{var n;return yt(e)?`Symbol(${(n=e.description)!=null?n:t})`:e};/** -* @vue/reactivity v3.5.33 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/let Xe;class to{constructor(t=!1){this.detached=t,this._active=!0,this._on=0,this.effects=[],this.cleanups=[],this._isPaused=!1,this.__v_skip=!0,this.parent=Xe,!t&&Xe&&(this.index=(Xe.scopes||(Xe.scopes=[])).push(this)-1)}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let t,n;if(this.scopes)for(t=0,n=this.scopes.length;t0&&--this._on===0){if(Xe===this)Xe=this.prevScope;else{let t=Xe;for(;t;){if(t.prevScope===this){t.prevScope=this.prevScope;break}t=t.prevScope}}this.prevScope=void 0}}stop(t){if(this._active){this._active=!1;let n,s;for(n=0,s=this.effects.length;n0)return;if(es){let t=es;for(es=void 0;t;){const n=t.next;t.next=void 0,t.flags&=-9,t=n}}let e;for(;Qn;){let t=Qn;for(Qn=void 0;t;){const n=t.next;if(t.next=void 0,t.flags&=-9,t.flags&1)try{t.trigger()}catch(s){e||(e=s)}t=n}}if(e)throw e}function oo(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function lo(e){let t,n=e.depsTail,s=n;for(;s;){const a=s.prevDep;s.version===-1?(s===n&&(n=a),tr(s),tu(s)):t=s,s.dep.activeLink=s.prevActiveLink,s.prevActiveLink=void 0,s=a}e.deps=t,e.depsTail=n}function Ea(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&(uo(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function uo(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===os)||(e.globalVersion=os,!e.isSSR&&e.flags&128&&(!e.deps&&!e._dirty||!Ea(e))))return;e.flags|=2;const t=e.dep,n=Fe,s=kt;Fe=e,kt=!0;try{oo(e);const a=e.fn(e._value);(t.version===0||Ot(a,e._value))&&(e.flags|=128,e._value=a,t.version++)}catch(a){throw t.version++,a}finally{Fe=n,kt=s,lo(e),e.flags&=-3}}function tr(e,t=!1){const{dep:n,prevSub:s,nextSub:a}=e;if(s&&(s.nextSub=a,e.prevSub=void 0),a&&(a.prevSub=s,e.nextSub=void 0),n.subs===e&&(n.subs=s,!s&&n.computed)){n.computed.flags&=-5;for(let r=n.computed.deps;r;r=r.nextDep)tr(r,!0)}!t&&!--n.sc&&n.map&&n.map.delete(n.key)}function tu(e){const{prevDep:t,nextDep:n}=e;t&&(t.nextDep=n,e.prevDep=void 0),n&&(n.prevDep=t,e.nextDep=void 0)}let kt=!0;const co=[];function Kt(){co.push(kt),kt=!1}function Wt(){const e=co.pop();kt=e===void 0?!0:e}function Ir(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const n=Fe;Fe=void 0;try{t()}finally{Fe=n}}}let os=0;class nu{constructor(t,n){this.sub=t,this.dep=n,this.version=n.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class nr{constructor(t){this.computed=t,this.version=0,this.activeLink=void 0,this.subs=void 0,this.map=void 0,this.key=void 0,this.sc=0,this.__v_skip=!0}track(t){if(!Fe||!kt||Fe===this.computed)return;let n=this.activeLink;if(n===void 0||n.sub!==Fe)n=this.activeLink=new nu(Fe,this),Fe.deps?(n.prevDep=Fe.depsTail,Fe.depsTail.nextDep=n,Fe.depsTail=n):Fe.deps=Fe.depsTail=n,fo(n);else if(n.version===-1&&(n.version=this.version,n.nextDep)){const s=n.nextDep;s.prevDep=n.prevDep,n.prevDep&&(n.prevDep.nextDep=s),n.prevDep=Fe.depsTail,n.nextDep=void 0,Fe.depsTail.nextDep=n,Fe.depsTail=n,Fe.deps===n&&(Fe.deps=s)}return n}trigger(t){this.version++,os++,this.notify(t)}notify(t){Qa();try{for(let n=this.subs;n;n=n.prevSub)n.sub.notify()&&n.sub.dep.notify()}finally{er()}}}function fo(e){if(e.dep.sc++,e.sub.flags&4){const t=e.dep.computed;if(t&&!e.dep.subs){t.flags|=20;for(let s=t.deps;s;s=s.nextDep)fo(s)}const n=e.dep.subs;n!==e&&(e.prevSub=n,n&&(n.nextSub=e)),e.dep.subs=e}}const Cs=new WeakMap,hn=Symbol(""),Ra=Symbol(""),ls=Symbol("");function st(e,t,n){if(kt&&Fe){let s=Cs.get(e);s||Cs.set(e,s=new Map);let a=s.get(n);a||(s.set(n,a=new nr),a.map=s,a.key=n),a.track()}}function qt(e,t,n,s,a,r){const o=Cs.get(e);if(!o){os++;return}const i=l=>{l&&l.trigger()};if(Qa(),t==="clear")o.forEach(i);else{const l=ye(e),u=l&&Bs(n);if(l&&n==="length"){const c=Number(s);o.forEach((d,f)=>{(f==="length"||f===ls||!yt(f)&&f>=c)&&i(d)})}else switch((n!==void 0||o.has(void 0))&&i(o.get(n)),u&&i(o.get(ls)),t){case"add":l?u&&i(o.get("length")):(i(o.get(hn)),$n(e)&&i(o.get(Ra)));break;case"delete":l||(i(o.get(hn)),$n(e)&&i(o.get(Ra)));break;case"set":$n(e)&&i(o.get(hn));break}}er()}function su(e,t){const n=Cs.get(e);return n&&n.get(t)}function kn(e){const t=Ae(e);return t===e?t:(st(t,"iterate",ls),ht(e)?t:t.map(Ct))}function Gs(e){return st(e=Ae(e),"iterate",ls),e}function It(e,t){return Jt(e)?Ln(zt(e)?Ct(t):t):Ct(t)}const au={__proto__:null,[Symbol.iterator](){return ca(this,Symbol.iterator,e=>It(this,e))},concat(...e){return kn(this).concat(...e.map(t=>ye(t)?kn(t):t))},entries(){return ca(this,"entries",e=>(e[1]=It(this,e[1]),e))},every(e,t){return jt(this,"every",e,t,void 0,arguments)},filter(e,t){return jt(this,"filter",e,t,n=>n.map(s=>It(this,s)),arguments)},find(e,t){return jt(this,"find",e,t,n=>It(this,n),arguments)},findIndex(e,t){return jt(this,"findIndex",e,t,void 0,arguments)},findLast(e,t){return jt(this,"findLast",e,t,n=>It(this,n),arguments)},findLastIndex(e,t){return jt(this,"findLastIndex",e,t,void 0,arguments)},forEach(e,t){return jt(this,"forEach",e,t,void 0,arguments)},includes(...e){return da(this,"includes",e)},indexOf(...e){return da(this,"indexOf",e)},join(e){return kn(this).join(e)},lastIndexOf(...e){return da(this,"lastIndexOf",e)},map(e,t){return jt(this,"map",e,t,void 0,arguments)},pop(){return jn(this,"pop")},push(...e){return jn(this,"push",e)},reduce(e,...t){return Dr(this,"reduce",e,t)},reduceRight(e,...t){return Dr(this,"reduceRight",e,t)},shift(){return jn(this,"shift")},some(e,t){return jt(this,"some",e,t,void 0,arguments)},splice(...e){return jn(this,"splice",e)},toReversed(){return kn(this).toReversed()},toSorted(e){return kn(this).toSorted(e)},toSpliced(...e){return kn(this).toSpliced(...e)},unshift(...e){return jn(this,"unshift",e)},values(){return ca(this,"values",e=>It(this,e))}};function ca(e,t,n){const s=Gs(e),a=s[t]();return s!==e&&!ht(e)&&(a._next=a.next,a.next=()=>{const r=a._next();return r.done||(r.value=n(r.value)),r}),a}const ru=Array.prototype;function jt(e,t,n,s,a,r){const o=Gs(e),i=o!==e&&!ht(e),l=o[t];if(l!==ru[t]){const d=l.apply(e,r);return i?Ct(d):d}let u=n;o!==e&&(i?u=function(d,f){return n.call(this,It(e,d),f,e)}:n.length>2&&(u=function(d,f){return n.call(this,d,f,e)}));const c=l.call(o,u,s);return i&&a?a(c):c}function Dr(e,t,n,s){const a=Gs(e),r=a!==e&&!ht(e);let o=n,i=!1;a!==e&&(r?(i=s.length===0,o=function(u,c,d){return i&&(i=!1,u=It(e,u)),n.call(this,u,It(e,c),d,e)}):n.length>3&&(o=function(u,c,d){return n.call(this,u,c,d,e)}));const l=a[t](o,...s);return i?It(e,l):l}function da(e,t,n){const s=Ae(e);st(s,"iterate",ls);const a=s[t](...n);return(a===-1||a===!1)&&qs(n[0])?(n[0]=Ae(n[0]),s[t](...n)):a}function jn(e,t,n=[]){Kt(),Qa();const s=Ae(e)[t].apply(e,n);return er(),Wt(),s}const iu=Ja("__proto__,__v_isRef,__isVue"),po=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(yt));function ou(e){yt(e)||(e=String(e));const t=Ae(this);return st(t,"has",e),t.hasOwnProperty(e)}class vo{constructor(t=!1,n=!1){this._isReadonly=t,this._isShallow=n}get(t,n,s){if(n==="__v_skip")return t.__v_skip;const a=this._isReadonly,r=this._isShallow;if(n==="__v_isReactive")return!a;if(n==="__v_isReadonly")return a;if(n==="__v_isShallow")return r;if(n==="__v_raw")return s===(a?r?mu:yo:r?mo:ho).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(s)?t:void 0;const o=ye(t);if(!a){let l;if(o&&(l=au[n]))return l;if(n==="hasOwnProperty")return ou}const i=Reflect.get(t,n,Ue(t)?t:s);if((yt(n)?po.has(n):iu(n))||(a||st(t,"get",n),r))return i;if(Ue(i)){const l=o&&Bs(n)?i:i.value;return a&&$e(l)?Ta(l):l}return $e(i)?a?Ta(i):Zt(i):i}}class go extends vo{constructor(t=!1){super(!1,t)}set(t,n,s,a){let r=t[n];const o=ye(t)&&Bs(n);if(!this._isShallow){const u=Jt(r);if(!ht(s)&&!Jt(s)&&(r=Ae(r),s=Ae(s)),!o&&Ue(r)&&!Ue(s))return u||(r.value=s),!0}const i=o?Number(n)e,_s=e=>Reflect.getPrototypeOf(e);function fu(e,t,n){return function(...s){const a=this.__v_raw,r=Ae(a),o=$n(r),i=e==="entries"||e===Symbol.iterator&&o,l=e==="keys"&&o,u=a[e](...s),c=n?$a:t?Ln:Ct;return!t&&st(r,"iterate",l?Ra:hn),tt(Object.create(u),{next(){const{value:d,done:f}=u.next();return f?{value:d,done:f}:{value:i?[c(d[0]),c(d[1])]:c(d),done:f}}})}}function bs(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function pu(e,t){const n={get(a){const r=this.__v_raw,o=Ae(r),i=Ae(a);e||(Ot(a,i)&&st(o,"get",a),st(o,"get",i));const{has:l}=_s(o),u=t?$a:e?Ln:Ct;if(l.call(o,a))return u(r.get(a));if(l.call(o,i))return u(r.get(i));r!==o&&r.get(a)},get size(){const a=this.__v_raw;return!e&&st(Ae(a),"iterate",hn),a.size},has(a){const r=this.__v_raw,o=Ae(r),i=Ae(a);return e||(Ot(a,i)&&st(o,"has",a),st(o,"has",i)),a===i?r.has(a):r.has(a)||r.has(i)},forEach(a,r){const o=this,i=o.__v_raw,l=Ae(i),u=t?$a:e?Ln:Ct;return!e&&st(l,"iterate",hn),i.forEach((c,d)=>a.call(r,u(c),u(d),o))}};return tt(n,e?{add:bs("add"),set:bs("set"),delete:bs("delete"),clear:bs("clear")}:{add(a){const r=Ae(this),o=_s(r),i=Ae(a),l=!t&&!ht(a)&&!Jt(a)?i:a;return o.has.call(r,l)||Ot(a,l)&&o.has.call(r,a)||Ot(i,l)&&o.has.call(r,i)||(r.add(l),qt(r,"add",l,l)),this},set(a,r){!t&&!ht(r)&&!Jt(r)&&(r=Ae(r));const o=Ae(this),{has:i,get:l}=_s(o);let u=i.call(o,a);u||(a=Ae(a),u=i.call(o,a));const c=l.call(o,a);return o.set(a,r),u?Ot(r,c)&&qt(o,"set",a,r):qt(o,"add",a,r),this},delete(a){const r=Ae(this),{has:o,get:i}=_s(r);let l=o.call(r,a);l||(a=Ae(a),l=o.call(r,a)),i&&i.call(r,a);const u=r.delete(a);return l&&qt(r,"delete",a,void 0),u},clear(){const a=Ae(this),r=a.size!==0,o=a.clear();return r&&qt(a,"clear",void 0,void 0),o}}),["keys","values","entries",Symbol.iterator].forEach(a=>{n[a]=fu(a,e,t)}),n}function sr(e,t){const n=pu(e,t);return(s,a,r)=>a==="__v_isReactive"?!e:a==="__v_isReadonly"?e:a==="__v_raw"?s:Reflect.get(Ce(n,a)&&a in s?n:s,a,r)}const vu={get:sr(!1,!1)},gu={get:sr(!1,!0)},hu={get:sr(!0,!1)};const ho=new WeakMap,mo=new WeakMap,yo=new WeakMap,mu=new WeakMap;function yu(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function _u(e){return e.__v_skip||!Object.isExtensible(e)?0:yu(Hl(e))}function Zt(e){return Jt(e)?e:ar(e,!1,uu,vu,ho)}function _o(e){return ar(e,!1,du,gu,mo)}function Ta(e){return ar(e,!0,cu,hu,yo)}function ar(e,t,n,s,a){if(!$e(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const r=_u(e);if(r===0)return e;const o=a.get(e);if(o)return o;const i=new Proxy(e,r===2?s:n);return a.set(e,i),i}function zt(e){return Jt(e)?zt(e.__v_raw):!!(e&&e.__v_isReactive)}function Jt(e){return!!(e&&e.__v_isReadonly)}function ht(e){return!!(e&&e.__v_isShallow)}function qs(e){return e?!!e.__v_raw:!1}function Ae(e){const t=e&&e.__v_raw;return t?Ae(t):e}function rr(e){return!Ce(e,"__v_skip")&&Object.isExtensible(e)&&Xi(e,"__v_skip",!0),e}const Ct=e=>$e(e)?Zt(e):e,Ln=e=>$e(e)?Ta(e):e;function Ue(e){return e?e.__v_isRef===!0:!1}function J(e){return bo(e,!1)}function bu(e){return bo(e,!0)}function bo(e,t){return Ue(e)?e:new wu(e,t)}class wu{constructor(t,n){this.dep=new nr,this.__v_isRef=!0,this.__v_isShallow=!1,this._rawValue=n?t:Ae(t),this._value=n?t:Ct(t),this.__v_isShallow=n}get value(){return this.dep.track(),this._value}set value(t){const n=this._rawValue,s=this.__v_isShallow||ht(t)||Jt(t);t=s?t:Ae(t),Ot(t,n)&&(this._rawValue=t,this._value=s?t:Ct(t),this.dep.trigger())}}function p(e){return Ue(e)?e.value:e}const Su={get:(e,t,n)=>t==="__v_raw"?e:p(Reflect.get(e,t,n)),set:(e,t,n,s)=>{const a=e[t];return Ue(a)&&!Ue(n)?(a.value=n,!0):Reflect.set(e,t,n,s)}};function wo(e){return zt(e)?e:new Proxy(e,Su)}function ku(e){const t=ye(e)?new Array(e.length):{};for(const n in e)t[n]=xu(e,n);return t}class Au{constructor(t,n,s){this._object=t,this._defaultValue=s,this.__v_isRef=!0,this._value=void 0,this._key=yt(n)?n:String(n),this._raw=Ae(t);let a=!0,r=t;if(!ye(t)||yt(this._key)||!Bs(this._key))do a=!qs(r)||ht(r);while(a&&(r=r.__v_raw));this._shallow=a}get value(){let t=this._object[this._key];return this._shallow&&(t=p(t)),this._value=t===void 0?this._defaultValue:t}set value(t){if(this._shallow&&Ue(this._raw[this._key])){const n=this._object[this._key];if(Ue(n)){n.value=t;return}}this._object[this._key]=t}get dep(){return su(this._raw,this._key)}}function xu(e,t,n){return new Au(e,t,n)}class Cu{constructor(t,n,s){this.fn=t,this.setter=n,this._value=void 0,this.dep=new nr(this),this.__v_isRef=!0,this.deps=void 0,this.depsTail=void 0,this.flags=16,this.globalVersion=os-1,this.next=void 0,this.effect=this,this.__v_isReadonly=!n,this.isSSR=s}notify(){if(this.flags|=16,!(this.flags&8)&&Fe!==this)return io(this,!0),!0}get value(){const t=this.dep.track();return uo(this),t&&(t.version=this.dep.version),this._value}set value(t){this.setter&&this.setter(t)}}function Eu(e,t,n=!1){let s,a;return be(e)?s=e:(s=e.get,a=e.set),new Cu(s,a,n)}const ws={},Es=new WeakMap;let pn;function Ru(e,t=!1,n=pn){if(n){let s=Es.get(n);s||Es.set(n,s=[]),s.push(e)}}function $u(e,t,n=Ne){const{immediate:s,deep:a,once:r,scheduler:o,augmentJob:i,call:l}=n,u=E=>a?E:ht(E)||a===!1||a===0?on(E,1):on(E);let c,d,f,h,g=!1,y=!1;if(Ue(e)?(d=()=>e.value,g=ht(e)):zt(e)?(d=()=>u(e),g=!0):ye(e)?(y=!0,g=e.some(E=>zt(E)||ht(E)),d=()=>e.map(E=>{if(Ue(E))return E.value;if(zt(E))return u(E);if(be(E))return l?l(E,2):E()})):be(e)?t?d=l?()=>l(e,2):e:d=()=>{if(f){Kt();try{f()}finally{Wt()}}const E=pn;pn=c;try{return l?l(e,3,[h]):e(h)}finally{pn=E}}:d=Ft,t&&a){const E=d,F=a===!0?1/0:a;d=()=>on(E(),F)}const m=so(),P=()=>{c.stop(),m&&m.active&&Ya(m.effects,c)};if(r&&t){const E=t;t=(...F)=>{E(...F),P()}}let _=y?new Array(e.length).fill(ws):ws;const S=E=>{if(!(!(c.flags&1)||!c.dirty&&!E))if(t){const F=c.run();if(a||g||(y?F.some((I,T)=>Ot(I,_[T])):Ot(F,_))){f&&f();const I=pn;pn=c;try{const T=[F,_===ws?void 0:y&&_[0]===ws?[]:_,h];_=F,l?l(t,3,T):t(...T)}finally{pn=I}}}else c.run()};return i&&i(S),c=new ao(d),c.scheduler=o?()=>o(S,!1):S,h=E=>Ru(E,!1,c),f=c.onStop=()=>{const E=Es.get(c);if(E){if(l)l(E,4);else for(const F of E)F();Es.delete(c)}},t?s?S(!0):_=c.run():o?o(S.bind(null,!0),!0):c.run(),P.pause=c.pause.bind(c),P.resume=c.resume.bind(c),P.stop=P,P}function on(e,t=1/0,n){if(t<=0||!$e(e)||e.__v_skip||(n=n||new Map,(n.get(e)||0)>=t))return e;if(n.set(e,t),t--,Ue(e))on(e.value,t,n);else if(ye(e))for(let s=0;s{on(s,t,n)});else if(Yi(e)){for(const s in e)on(e[s],t,n);for(const s of Object.getOwnPropertySymbols(e))Object.prototype.propertyIsEnumerable.call(e,s)&&on(e[s],t,n)}return e}/** -* @vue/runtime-core v3.5.33 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/function gs(e,t,n,s){try{return s?e(...s):e()}catch(a){zs(a,t,n)}}function Ut(e,t,n,s){if(be(e)){const a=gs(e,t,n,s);return a&&Wi(a)&&a.catch(r=>{zs(r,t,n)}),a}if(ye(e)){const a=[];for(let r=0;r>>1,a=ct[s],r=us(a);r=us(n)?ct.push(e):ct.splice(Pu(t),0,e),e.flags|=1,ko()}}function ko(){Rs||(Rs=So.then(xo))}function Lu(e){ye(e)?Tn.push(...e):an&&e.id===-1?an.splice(xn+1,0,e):e.flags&1||(Tn.push(e),e.flags|=1),ko()}function Or(e,t,n=Lt+1){for(;nus(n)-us(s));if(Tn.length=0,an){an.push(...t);return}for(an=t,xn=0;xne.id==null?e.flags&2?-1:1/0:e.id;function xo(e){try{for(Lt=0;Lt{s._d&&Ls(-1);const r=$s(t);let o;try{o=e(...a)}finally{$s(r),s._d&&Ls(1)}return o};return s._n=!0,s._c=!0,s._d=!0,s}function dn(e,t,n,s){const a=e.dirs,r=t&&t.dirs;for(let o=0;o1)return n&&be(t)?t.call(s&&s.proxy):t}}function Iu(){return!!(Zs()||mn)}const Du=Symbol.for("v-scx"),Ou=()=>mt(Du);function At(e,t,n){return Eo(e,t,n)}function Eo(e,t,n=Ne){const{immediate:s,deep:a,flush:r,once:o}=n,i=tt({},n),l=t&&s||!t&&r!=="post";let u;if(fs){if(r==="sync"){const h=Ou();u=h.__watcherHandles||(h.__watcherHandles=[])}else if(!l){const h=()=>{};return h.stop=Ft,h.resume=Ft,h.pause=Ft,h}}const c=at;i.call=(h,g,y)=>Ut(h,c,g,y);let d=!1;r==="post"?i.scheduler=h=>{ot(h,c&&c.suspense)}:r!=="sync"&&(d=!0,i.scheduler=(h,g)=>{g?h():ir(h)}),i.augmentJob=h=>{t&&(h.flags|=4),d&&(h.flags|=2,c&&(h.id=c.uid,h.i=c))};const f=$u(e,t,i);return fs&&(u?u.push(f):l&&f()),f}function Fu(e,t,n){const s=this.proxy,a=He(e)?e.includes(".")?Ro(s,e):()=>s[e]:e.bind(s,s);let r;be(t)?r=t:(r=t.handler,n=t);const o=ms(this),i=Eo(a,r.bind(s),n);return o(),i}function Ro(e,t){const n=t.split(".");return()=>{let s=e;for(let a=0;ae.__isTeleport,vn=e=>e&&(e.disabled||e.disabled===""),Mu=e=>e&&(e.defer||e.defer===""),Fr=e=>typeof SVGElement<"u"&&e instanceof SVGElement,Nr=e=>typeof MathMLElement=="function"&&e instanceof MathMLElement,Pa=(e,t)=>{const n=e&&e.to;return He(n)?t?t(n):null:n},Uu={name:"Teleport",__isTeleport:!0,process(e,t,n,s,a,r,o,i,l,u){const{mc:c,pc:d,pbc:f,o:{insert:h,querySelector:g,createText:y,createComment:m,parentNode:P}}=u,_=vn(t.props);let{dynamicChildren:S}=t;const E=(T,A,R)=>{T.shapeFlag&16&&c(T.children,A,R,a,r,o,i,l)},F=(T=t)=>{const A=vn(T.props),R=T.target=Pa(T.props,g),Z=La(R,T,y,h);R&&(o!=="svg"&&Fr(R)?o="svg":o!=="mathml"&&Nr(R)&&(o="mathml"),a&&a.isCE&&(a.ce._teleportTargets||(a.ce._teleportTargets=new Set)).add(R),A||(E(T,R,Z),Jn(T,!1)))},I=T=>{const A=()=>{if(nn.get(T)===A){if(nn.delete(T),vn(T.props)){const R=P(T.el)||n;E(T,R,T.anchor),Jn(T,!0)}F(T)}};nn.set(T,A),ot(A,r)};if(e==null){const T=t.el=y(""),A=t.anchor=y("");if(h(T,n,s),h(A,n,s),Mu(t.props)||r&&r.pendingBranch){I(t);return}_&&(E(t,n,A),Jn(t,!0)),F()}else{t.el=e.el;const T=t.anchor=e.anchor,A=nn.get(e);if(A){A.flags|=8,nn.delete(e),I(t);return}t.targetStart=e.targetStart;const R=t.target=e.target,Z=t.targetAnchor=e.targetAnchor,ue=vn(e.props),de=ue?n:R,pe=ue?T:Z;if(o==="svg"||Fr(R)?o="svg":(o==="mathml"||Nr(R))&&(o="mathml"),S?(f(e.dynamicChildren,S,de,a,r,o,i),cr(e,t,!0)):l||d(e,t,de,pe,a,r,o,i,!1),_)ue?t.props&&e.props&&t.props.to!==e.props.to&&(t.props.to=e.props.to):Ss(t,n,T,u,1);else if((t.props&&t.props.to)!==(e.props&&e.props.to)){const B=t.target=Pa(t.props,g);B&&Ss(t,B,null,u,0)}else ue&&Ss(t,R,Z,u,1);Jn(t,_)}},remove(e,t,n,{um:s,o:{remove:a}},r){const{shapeFlag:o,children:i,anchor:l,targetStart:u,targetAnchor:c,target:d,props:f}=e;let h=r||!vn(f);const g=nn.get(e);if(g&&(g.flags|=8,nn.delete(e),h=!1),d&&(a(u),a(c)),r&&a(l),o&16)for(let y=0;yns(y,t&&(ye(t)?t[m]:t),n,s,a));return}if(Pn(s)&&!a){s.shapeFlag&512&&s.type.__asyncResolved&&s.component.subTree.component&&ns(e,t,n,s.component.subTree);return}const r=s.shapeFlag&4?fr(s.component):s.el,o=a?null:r,{i,r:l}=e,u=t&&t.r,c=i.refs===Ne?i.refs={}:i.refs,d=i.setupState,f=Ae(d),h=d===Ne?zi:y=>Mr(c,y)?!1:Ce(f,y),g=(y,m)=>!(m&&Mr(c,m));if(u!=null&&u!==l){if(Ur(t),He(u))c[u]=null,h(u)&&(d[u]=null);else if(Ue(u)){const y=t;g(u,y.k)&&(u.value=null),y.k&&(c[y.k]=null)}}if(be(l))gs(l,i,12,[o,c]);else{const y=He(l),m=Ue(l);if(y||m){const P=()=>{if(e.f){const _=y?h(l)?d[l]:c[l]:g()||!e.k?l.value:c[e.k];if(a)ye(_)&&Ya(_,r);else if(ye(_))_.includes(r)||_.push(r);else if(y)c[l]=[r],h(l)&&(d[l]=c[l]);else{const S=[r];g(l,e.k)&&(l.value=S),e.k&&(c[e.k]=S)}}else y?(c[l]=o,h(l)&&(d[l]=o)):m&&(g(l,e.k)&&(l.value=o),e.k&&(c[e.k]=o))};if(o){const _=()=>{P(),Ts.delete(e)};_.id=-1,Ts.set(e,_),ot(_,n)}else Ur(e),P()}}}function Ur(e){const t=Ts.get(e);t&&(t.flags|=8,Ts.delete(e))}Hs().requestIdleCallback;Hs().cancelIdleCallback;const Pn=e=>!!e.type.__asyncLoader,Po=e=>e.type.__isKeepAlive;function Hu(e,t){Lo(e,"a",t)}function Gu(e,t){Lo(e,"da",t)}function Lo(e,t,n=at){const s=e.__wdc||(e.__wdc=()=>{let a=n;for(;a;){if(a.isDeactivated)return;a=a.parent}return e()});if(Ks(t,s,n),n){let a=n.parent;for(;a&&a.parent;)Po(a.parent.vnode)&&qu(s,t,n,a),a=a.parent}}function qu(e,t,n,s){const a=Ks(t,e,s,!0);hs(()=>{Ya(s[t],a)},n)}function Ks(e,t,n=at,s=!1){if(n){const a=n[e]||(n[e]=[]),r=t.__weh||(t.__weh=(...o)=>{Kt();const i=ms(n),l=Ut(t,n,e,o);return i(),Wt(),l});return s?a.unshift(r):a.push(r),r}}const Qt=e=>(t,n=at)=>{(!fs||e==="sp")&&Ks(e,(...s)=>t(...s),n)},zu=Qt("bm"),_t=Qt("m"),Ku=Qt("bu"),Wu=Qt("u"),Ws=Qt("bum"),hs=Qt("um"),Ju=Qt("sp"),Yu=Qt("rtg"),Xu=Qt("rtc");function Io(e,t=at){Ks("ec",e,t)}const Zu="components";function cn(e,t){return ec(Zu,e,!0,t)||e}const Qu=Symbol.for("v-ndc");function ec(e,t,n=!0,s=!1){const a=dt||at;if(a){const r=a.type;{const i=Mc(r,!1);if(i&&(i===t||i===ft(t)||i===Vs(ft(t))))return r}const o=Br(a[e]||r[e],t)||Br(a.appContext[e],t);return!o&&s?r:o}}function Br(e,t){return e&&(e[t]||e[ft(t)]||e[Vs(ft(t))])}function Yt(e,t,n,s){let a;const r=n,o=ye(e);if(o||He(e)){const i=o&&zt(e);let l=!1,u=!1;i&&(l=!ht(e),u=Jt(e),e=Gs(e)),a=new Array(e.length);for(let c=0,d=e.length;ct(i,l,void 0,r));else{const i=Object.keys(e);a=new Array(i.length);for(let l=0,u=i.length;l{const r=s.fn(...a);return r&&(r.key=s.key),r}:s.fn)}return e}function Js(e,t,n={},s,a){if(dt.ce||dt.parent&&Pn(dt.parent)&&dt.parent.ce){const u=Object.keys(n).length>0;return t!=="default"&&(n.name=t),w(),K(Ie,null,[L("slot",n,s&&s())],u?-2:64)}let r=e[t];r&&r._c&&(r._d=!1),w();const o=r&&Oo(r(n)),i=n.key||o&&o.key,l=K(Ie,{key:(i&&!yt(i)?i:`_${t}`)+(!o&&s?"_fb":"")},o||(s?s():[]),o&&e._===1?64:-2);return!a&&l.scopeId&&(l.slotScopeIds=[l.scopeId+"-s"]),r&&r._c&&(r._d=!0),l}function Oo(e){return e.some(t=>ds(t)?!(t.type===Xt||t.type===Ie&&!Oo(t.children)):!0)?e:null}const Ia=e=>e?tl(e)?fr(e):Ia(e.parent):null,ss=tt(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>Ia(e.parent),$root:e=>Ia(e.root),$host:e=>e.ce,$emit:e=>e.emit,$options:e=>No(e),$forceUpdate:e=>e.f||(e.f=()=>{ir(e.update)}),$nextTick:e=>e.n||(e.n=_n.bind(e.proxy)),$watch:e=>Fu.bind(e)}),fa=(e,t)=>e!==Ne&&!e.__isScriptSetup&&Ce(e,t),tc={get({_:e},t){if(t==="__v_skip")return!0;const{ctx:n,setupState:s,data:a,props:r,accessCache:o,type:i,appContext:l}=e;if(t[0]!=="$"){const f=o[t];if(f!==void 0)switch(f){case 1:return s[t];case 2:return a[t];case 4:return n[t];case 3:return r[t]}else{if(fa(s,t))return o[t]=1,s[t];if(a!==Ne&&Ce(a,t))return o[t]=2,a[t];if(Ce(r,t))return o[t]=3,r[t];if(n!==Ne&&Ce(n,t))return o[t]=4,n[t];Da&&(o[t]=0)}}const u=ss[t];let c,d;if(u)return t==="$attrs"&&st(e.attrs,"get",""),u(e);if((c=i.__cssModules)&&(c=c[t]))return c;if(n!==Ne&&Ce(n,t))return o[t]=4,n[t];if(d=l.config.globalProperties,Ce(d,t))return d[t]},set({_:e},t,n){const{data:s,setupState:a,ctx:r}=e;return fa(a,t)?(a[t]=n,!0):s!==Ne&&Ce(s,t)?(s[t]=n,!0):Ce(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(r[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:s,appContext:a,props:r,type:o}},i){let l;return!!(n[i]||e!==Ne&&i[0]!=="$"&&Ce(e,i)||fa(t,i)||Ce(r,i)||Ce(s,i)||Ce(ss,i)||Ce(a.config.globalProperties,i)||(l=o.__cssModules)&&l[i])},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:Ce(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};function jr(e){return ye(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}let Da=!0;function nc(e){const t=No(e),n=e.proxy,s=e.ctx;Da=!1,t.beforeCreate&&Vr(t.beforeCreate,e,"bc");const{data:a,computed:r,methods:o,watch:i,provide:l,inject:u,created:c,beforeMount:d,mounted:f,beforeUpdate:h,updated:g,activated:y,deactivated:m,beforeDestroy:P,beforeUnmount:_,destroyed:S,unmounted:E,render:F,renderTracked:I,renderTriggered:T,errorCaptured:A,serverPrefetch:R,expose:Z,inheritAttrs:ue,components:de,directives:pe,filters:B}=t;if(u&&sc(u,s,null),o)for(const W in o){const te=o[W];be(te)&&(s[W]=te.bind(n))}if(a){const W=a.call(n,n);$e(W)&&(e.data=Zt(W))}if(Da=!0,r)for(const W in r){const te=r[W],ve=be(te)?te.bind(n,n):be(te.get)?te.get.bind(n,n):Ft,Se=!be(te)&&be(te.set)?te.set.bind(n):Ft,Ee=Q({get:ve,set:Se});Object.defineProperty(s,W,{enumerable:!0,configurable:!0,get:()=>Ee.value,set:we=>Ee.value=we})}if(i)for(const W in i)Fo(i[W],s,n,W);if(l){const W=be(l)?l.call(n):l;Reflect.ownKeys(W).forEach(te=>{ts(te,W[te])})}c&&Vr(c,e,"c");function X(W,te){ye(te)?te.forEach(ve=>W(ve.bind(n))):te&&W(te.bind(n))}if(X(zu,d),X(_t,f),X(Ku,h),X(Wu,g),X(Hu,y),X(Gu,m),X(Io,A),X(Xu,I),X(Yu,T),X(Ws,_),X(hs,E),X(Ju,R),ye(Z))if(Z.length){const W=e.exposed||(e.exposed={});Z.forEach(te=>{Object.defineProperty(W,te,{get:()=>n[te],set:ve=>n[te]=ve,enumerable:!0})})}else e.exposed||(e.exposed={});F&&e.render===Ft&&(e.render=F),ue!=null&&(e.inheritAttrs=ue),de&&(e.components=de),pe&&(e.directives=pe),R&&To(e)}function sc(e,t,n=Ft){ye(e)&&(e=Oa(e));for(const s in e){const a=e[s];let r;$e(a)?"default"in a?r=mt(a.from||s,a.default,!0):r=mt(a.from||s):r=mt(a),Ue(r)?Object.defineProperty(t,s,{enumerable:!0,configurable:!0,get:()=>r.value,set:o=>r.value=o}):t[s]=r}}function Vr(e,t,n){Ut(ye(e)?e.map(s=>s.bind(t.proxy)):e.bind(t.proxy),t,n)}function Fo(e,t,n,s){let a=s.includes(".")?Ro(n,s):()=>n[s];if(He(e)){const r=t[e];be(r)&&At(a,r)}else if(be(e))At(a,e.bind(n));else if($e(e))if(ye(e))e.forEach(r=>Fo(r,t,n,s));else{const r=be(e.handler)?e.handler.bind(n):t[e.handler];be(r)&&At(a,r,e)}}function No(e){const t=e.type,{mixins:n,extends:s}=t,{mixins:a,optionsCache:r,config:{optionMergeStrategies:o}}=e.appContext,i=r.get(t);let l;return i?l=i:!a.length&&!n&&!s?l=t:(l={},a.length&&a.forEach(u=>Ps(l,u,o,!0)),Ps(l,t,o)),$e(t)&&r.set(t,l),l}function Ps(e,t,n,s=!1){const{mixins:a,extends:r}=t;r&&Ps(e,r,n,!0),a&&a.forEach(o=>Ps(e,o,n,!0));for(const o in t)if(!(s&&o==="expose")){const i=ac[o]||n&&n[o];e[o]=i?i(e[o],t[o]):t[o]}return e}const ac={data:Hr,props:Gr,emits:Gr,methods:Yn,computed:Yn,beforeCreate:it,created:it,beforeMount:it,mounted:it,beforeUpdate:it,updated:it,beforeDestroy:it,beforeUnmount:it,destroyed:it,unmounted:it,activated:it,deactivated:it,errorCaptured:it,serverPrefetch:it,components:Yn,directives:Yn,watch:ic,provide:Hr,inject:rc};function Hr(e,t){return t?e?function(){return tt(be(e)?e.call(this,this):e,be(t)?t.call(this,this):t)}:t:e}function rc(e,t){return Yn(Oa(e),Oa(t))}function Oa(e){if(ye(e)){const t={};for(let n=0;nt==="modelValue"||t==="model-value"?e.modelModifiers:e[`${t}Modifiers`]||e[`${ft(t)}Modifiers`]||e[`${un(t)}Modifiers`];function cc(e,t,...n){if(e.isUnmounted)return;const s=e.vnode.props||Ne;let a=n;const r=t.startsWith("update:"),o=r&&uc(s,t.slice(7));o&&(o.trim&&(a=n.map(c=>He(c)?c.trim():c)),o.number&&(a=n.map(zl)));let i,l=s[i=ia(t)]||s[i=ia(ft(t))];!l&&r&&(l=s[i=ia(un(t))]),l&&Ut(l,e,6,a);const u=s[i+"Once"];if(u){if(!e.emitted)e.emitted={};else if(e.emitted[i])return;e.emitted[i]=!0,Ut(u,e,6,a)}}const dc=new WeakMap;function Uo(e,t,n=!1){const s=n?dc:t.emitsCache,a=s.get(e);if(a!==void 0)return a;const r=e.emits;let o={},i=!1;if(!be(e)){const l=u=>{const c=Uo(u,t,!0);c&&(i=!0,tt(o,c))};!n&&t.mixins.length&&t.mixins.forEach(l),e.extends&&l(e.extends),e.mixins&&e.mixins.forEach(l)}return!r&&!i?($e(e)&&s.set(e,null),null):(ye(r)?r.forEach(l=>o[l]=null):tt(o,r),$e(e)&&s.set(e,o),o)}function Ys(e,t){return!e||!Ms(t)?!1:(t=t.slice(2).replace(/Once$/,""),Ce(e,t[0].toLowerCase()+t.slice(1))||Ce(e,un(t))||Ce(e,t))}function qr(e){const{type:t,vnode:n,proxy:s,withProxy:a,propsOptions:[r],slots:o,attrs:i,emit:l,render:u,renderCache:c,props:d,data:f,setupState:h,ctx:g,inheritAttrs:y}=e,m=$s(e);let P,_;try{if(n.shapeFlag&4){const E=a||s,F=E;P=Dt(u.call(F,E,c,d,h,f,g)),_=i}else{const E=t;P=Dt(E.length>1?E(d,{attrs:i,slots:o,emit:l}):E(d,null)),_=t.props?i:fc(i)}}catch(E){as.length=0,zs(E,e,1),P=L(Xt)}let S=P;if(_&&y!==!1){const E=Object.keys(_),{shapeFlag:F}=S;E.length&&F&7&&(r&&E.some(Us)&&(_=pc(_,r)),S=In(S,_,!1,!0))}return n.dirs&&(S=In(S,null,!1,!0),S.dirs=S.dirs?S.dirs.concat(n.dirs):n.dirs),n.transition&&or(S,n.transition),P=S,$s(m),P}const fc=e=>{let t;for(const n in e)(n==="class"||n==="style"||Ms(n))&&((t||(t={}))[n]=e[n]);return t},pc=(e,t)=>{const n={};for(const s in e)(!Us(s)||!(s.slice(9)in t))&&(n[s]=e[s]);return n};function vc(e,t,n){const{props:s,children:a,component:r}=e,{props:o,children:i,patchFlag:l}=t,u=r.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&l>=0){if(l&1024)return!0;if(l&16)return s?zr(s,o,u):!!o;if(l&8){const c=t.dynamicProps;for(let d=0;dObject.create(jo),Ho=e=>Object.getPrototypeOf(e)===jo;function hc(e,t,n,s=!1){const a={},r=Vo();e.propsDefaults=Object.create(null),Go(e,t,a,r);for(const o in e.propsOptions[0])o in a||(a[o]=void 0);n?e.props=s?a:_o(a):e.type.props?e.props=a:e.props=r,e.attrs=r}function mc(e,t,n,s){const{props:a,attrs:r,vnode:{patchFlag:o}}=e,i=Ae(a),[l]=e.propsOptions;let u=!1;if((s||o>0)&&!(o&16)){if(o&8){const c=e.vnode.dynamicProps;for(let d=0;d{l=!0;const[f,h]=qo(d,t,!0);tt(o,f),h&&i.push(...h)};!n&&t.mixins.length&&t.mixins.forEach(c),e.extends&&c(e.extends),e.mixins&&e.mixins.forEach(c)}if(!r&&!l)return $e(e)&&s.set(e,Rn),Rn;if(ye(r))for(let c=0;ce==="_"||e==="_ctx"||e==="$stable",ur=e=>ye(e)?e.map(Dt):[Dt(e)],_c=(e,t,n)=>{if(t._n)return t;const s=k((...a)=>ur(t(...a)),n);return s._c=!1,s},zo=(e,t,n)=>{const s=e._ctx;for(const a in e){if(lr(a))continue;const r=e[a];if(be(r))t[a]=_c(a,r,s);else if(r!=null){const o=ur(r);t[a]=()=>o}}},Ko=(e,t)=>{const n=ur(t);e.slots.default=()=>n},Wo=(e,t,n)=>{for(const s in t)(n||!lr(s))&&(e[s]=t[s])},bc=(e,t,n)=>{const s=e.slots=Vo();if(e.vnode.shapeFlag&32){const a=t._;a?(Wo(s,t,n),n&&Xi(s,"_",a,!0)):zo(t,s)}else t&&Ko(e,t)},wc=(e,t,n)=>{const{vnode:s,slots:a}=e;let r=!0,o=Ne;if(s.shapeFlag&32){const i=t._;i?n&&i===1?r=!1:Wo(a,t,n):(r=!t.$stable,zo(t,a)),o=t}else t&&(Ko(e,t),o={default:1});if(r)for(const i in a)!lr(i)&&o[i]==null&&delete a[i]},ot=Cc;function Sc(e){return kc(e)}function kc(e,t){const n=Hs();n.__VUE__=!0;const{insert:s,remove:a,patchProp:r,createElement:o,createText:i,createComment:l,setText:u,setElementText:c,parentNode:d,nextSibling:f,setScopeId:h=Ft,insertStaticContent:g}=e,y=(v,b,C,j=null,z=null,H=null,oe=void 0,re=null,ne=!!b.dynamicChildren)=>{if(v===b)return;v&&!Vn(v,b)&&(j=M(v),we(v,z,H,!0),v=null),b.patchFlag===-2&&(ne=!1,b.dynamicChildren=null);const{type:Y,ref:fe,shapeFlag:le}=b;switch(Y){case Xs:m(v,b,C,j);break;case Xt:P(v,b,C,j);break;case ks:v==null&&_(b,C,j,oe);break;case Ie:de(v,b,C,j,z,H,oe,re,ne);break;default:le&1?F(v,b,C,j,z,H,oe,re,ne):le&6?pe(v,b,C,j,z,H,oe,re,ne):(le&64||le&128)&&Y.process(v,b,C,j,z,H,oe,re,ne,x)}fe!=null&&z?ns(fe,v&&v.ref,H,b||v,!b):fe==null&&v&&v.ref!=null&&ns(v.ref,null,H,v,!0)},m=(v,b,C,j)=>{if(v==null)s(b.el=i(b.children),C,j);else{const z=b.el=v.el;b.children!==v.children&&u(z,b.children)}},P=(v,b,C,j)=>{v==null?s(b.el=l(b.children||""),C,j):b.el=v.el},_=(v,b,C,j)=>{[v.el,v.anchor]=g(v.children,b,C,j,v.el,v.anchor)},S=({el:v,anchor:b},C,j)=>{let z;for(;v&&v!==b;)z=f(v),s(v,C,j),v=z;s(b,C,j)},E=({el:v,anchor:b})=>{let C;for(;v&&v!==b;)C=f(v),a(v),v=C;a(b)},F=(v,b,C,j,z,H,oe,re,ne)=>{if(b.type==="svg"?oe="svg":b.type==="math"&&(oe="mathml"),v==null)I(b,C,j,z,H,oe,re,ne);else{const Y=v.el&&v.el._isVueCE?v.el:null;try{Y&&Y._beginPatch(),R(v,b,z,H,oe,re,ne)}finally{Y&&Y._endPatch()}}},I=(v,b,C,j,z,H,oe,re)=>{let ne,Y;const{props:fe,shapeFlag:le,transition:ce,dirs:me}=v;if(ne=v.el=o(v.type,H,fe&&fe.is,fe),le&8?c(ne,v.children):le&16&&A(v.children,ne,null,j,z,pa(v,H),oe,re),me&&dn(v,null,j,"created"),T(ne,v,v.scopeId,oe,j),fe){for(const Re in fe)Re!=="value"&&!Zn(Re)&&r(ne,Re,null,fe[Re],H,j);"value"in fe&&r(ne,"value",null,fe.value,H),(Y=fe.onVnodeBeforeMount)&&$t(Y,j,v)}me&&dn(v,null,j,"beforeMount");const ke=Ac(z,ce);ke&&ce.beforeEnter(ne),s(ne,b,C),((Y=fe&&fe.onVnodeMounted)||ke||me)&&ot(()=>{try{Y&&$t(Y,j,v),ke&&ce.enter(ne),me&&dn(v,null,j,"mounted")}finally{}},z)},T=(v,b,C,j,z)=>{if(C&&h(v,C),j)for(let H=0;H{for(let Y=ne;Y{const re=b.el=v.el;let{patchFlag:ne,dynamicChildren:Y,dirs:fe}=b;ne|=v.patchFlag&16;const le=v.props||Ne,ce=b.props||Ne;let me;if(C&&fn(C,!1),(me=ce.onVnodeBeforeUpdate)&&$t(me,C,b,v),fe&&dn(b,v,C,"beforeUpdate"),C&&fn(C,!0),(le.innerHTML&&ce.innerHTML==null||le.textContent&&ce.textContent==null)&&c(re,""),Y?Z(v.dynamicChildren,Y,re,C,j,pa(b,z),H):oe||te(v,b,re,null,C,j,pa(b,z),H,!1),ne>0){if(ne&16)ue(re,le,ce,C,z);else if(ne&2&&le.class!==ce.class&&r(re,"class",null,ce.class,z),ne&4&&r(re,"style",le.style,ce.style,z),ne&8){const ke=b.dynamicProps;for(let Re=0;Re{me&&$t(me,C,b,v),fe&&dn(b,v,C,"updated")},j)},Z=(v,b,C,j,z,H,oe)=>{for(let re=0;re{if(b!==C){if(b!==Ne)for(const H in b)!Zn(H)&&!(H in C)&&r(v,H,b[H],null,z,j);for(const H in C){if(Zn(H))continue;const oe=C[H],re=b[H];oe!==re&&H!=="value"&&r(v,H,re,oe,z,j)}"value"in C&&r(v,"value",b.value,C.value,z)}},de=(v,b,C,j,z,H,oe,re,ne)=>{const Y=b.el=v?v.el:i(""),fe=b.anchor=v?v.anchor:i("");let{patchFlag:le,dynamicChildren:ce,slotScopeIds:me}=b;me&&(re=re?re.concat(me):me),v==null?(s(Y,C,j),s(fe,C,j),A(b.children||[],C,fe,z,H,oe,re,ne)):le>0&&le&64&&ce&&v.dynamicChildren&&v.dynamicChildren.length===ce.length?(Z(v.dynamicChildren,ce,C,z,H,oe,re),(b.key!=null||z&&b===z.subTree)&&cr(v,b,!0)):te(v,b,C,fe,z,H,oe,re,ne)},pe=(v,b,C,j,z,H,oe,re,ne)=>{b.slotScopeIds=re,v==null?b.shapeFlag&512?z.ctx.activate(b,C,j,oe,ne):B(b,C,j,z,H,oe,ne):q(v,b,ne)},B=(v,b,C,j,z,H,oe)=>{const re=v.component=Ic(v,j,z);if(Po(v)&&(re.ctx.renderer=x),Dc(re,!1,oe),re.asyncDep){if(z&&z.registerDep(re,X,oe),!v.el){const ne=re.subTree=L(Xt);P(null,ne,b,C),v.placeholder=ne.el}}else X(re,v,b,C,z,H,oe)},q=(v,b,C)=>{const j=b.component=v.component;if(vc(v,b,C))if(j.asyncDep&&!j.asyncResolved){W(j,b,C);return}else j.next=b,j.update();else b.el=v.el,j.vnode=b},X=(v,b,C,j,z,H,oe)=>{const re=()=>{if(v.isMounted){let{next:le,bu:ce,u:me,parent:ke,vnode:Re}=v;{const Le=Jo(v);if(Le){le&&(le.el=Re.el,W(v,le,oe)),Le.asyncDep.then(()=>{ot(()=>{v.isUnmounted||Y()},z)});return}}let Pe=le,Be;fn(v,!1),le?(le.el=Re.el,W(v,le,oe)):le=Re,ce&&oa(ce),(Be=le.props&&le.props.onVnodeBeforeUpdate)&&$t(Be,ke,le,Re),fn(v,!0);const ie=qr(v),O=v.subTree;v.subTree=ie,y(O,ie,d(O.el),M(O),v,z,H),le.el=ie.el,Pe===null&&gc(v,ie.el),me&&ot(me,z),(Be=le.props&&le.props.onVnodeUpdated)&&ot(()=>$t(Be,ke,le,Re),z)}else{let le;const{el:ce,props:me}=b,{bm:ke,m:Re,parent:Pe,root:Be,type:ie}=v,O=Pn(b);fn(v,!1),ke&&oa(ke),!O&&(le=me&&me.onVnodeBeforeMount)&&$t(le,Pe,b),fn(v,!0);{Be.ce&&Be.ce._hasShadowRoot()&&Be.ce._injectChildStyle(ie,v.parent?v.parent.type:void 0);const Le=v.subTree=qr(v);y(null,Le,C,j,v,z,H),b.el=Le.el}if(Re&&ot(Re,z),!O&&(le=me&&me.onVnodeMounted)){const Le=b;ot(()=>$t(le,Pe,Le),z)}(b.shapeFlag&256||Pe&&Pn(Pe.vnode)&&Pe.vnode.shapeFlag&256)&&v.a&&ot(v.a,z),v.isMounted=!0,b=C=j=null}};v.scope.on();const ne=v.effect=new ao(re);v.scope.off();const Y=v.update=ne.run.bind(ne),fe=v.job=ne.runIfDirty.bind(ne);fe.i=v,fe.id=v.uid,ne.scheduler=()=>ir(fe),fn(v,!0),Y()},W=(v,b,C)=>{b.component=v;const j=v.vnode.props;v.vnode=b,v.next=null,mc(v,b.props,j,C),wc(v,b.children,C),Kt(),Or(v),Wt()},te=(v,b,C,j,z,H,oe,re,ne=!1)=>{const Y=v&&v.children,fe=v?v.shapeFlag:0,le=b.children,{patchFlag:ce,shapeFlag:me}=b;if(ce>0){if(ce&128){Se(Y,le,C,j,z,H,oe,re,ne);return}else if(ce&256){ve(Y,le,C,j,z,H,oe,re,ne);return}}me&8?(fe&16&&Te(Y,z,H),le!==Y&&c(C,le)):fe&16?me&16?Se(Y,le,C,j,z,H,oe,re,ne):Te(Y,z,H,!0):(fe&8&&c(C,""),me&16&&A(le,C,j,z,H,oe,re,ne))},ve=(v,b,C,j,z,H,oe,re,ne)=>{v=v||Rn,b=b||Rn;const Y=v.length,fe=b.length,le=Math.min(Y,fe);let ce;for(ce=0;cefe?Te(v,z,H,!0,!1,le):A(b,C,j,z,H,oe,re,ne,le)},Se=(v,b,C,j,z,H,oe,re,ne)=>{let Y=0;const fe=b.length;let le=v.length-1,ce=fe-1;for(;Y<=le&&Y<=ce;){const me=v[Y],ke=b[Y]=ne?Gt(b[Y]):Dt(b[Y]);if(Vn(me,ke))y(me,ke,C,null,z,H,oe,re,ne);else break;Y++}for(;Y<=le&&Y<=ce;){const me=v[le],ke=b[ce]=ne?Gt(b[ce]):Dt(b[ce]);if(Vn(me,ke))y(me,ke,C,null,z,H,oe,re,ne);else break;le--,ce--}if(Y>le){if(Y<=ce){const me=ce+1,ke=mece)for(;Y<=le;)we(v[Y],z,H,!0),Y++;else{const me=Y,ke=Y,Re=new Map;for(Y=ke;Y<=ce;Y++){const We=b[Y]=ne?Gt(b[Y]):Dt(b[Y]);We.key!=null&&Re.set(We.key,Y)}let Pe,Be=0;const ie=ce-ke+1;let O=!1,Le=0;const et=new Array(ie);for(Y=0;Y=ie){we(We,z,H,!0);continue}let Ke;if(We.key!=null)Ke=Re.get(We.key);else for(Pe=ke;Pe<=ce;Pe++)if(et[Pe-ke]===0&&Vn(We,b[Pe])){Ke=Pe;break}Ke===void 0?we(We,z,H,!0):(et[Ke-ke]=Y+1,Ke>=Le?Le=Ke:O=!0,y(We,b[Ke],C,null,z,H,oe,re,ne),Be++)}const he=O?xc(et):Rn;for(Pe=he.length-1,Y=ie-1;Y>=0;Y--){const We=ke+Y,Ke=b[We],Bn=b[We+1],Tr=We+1{const{el:H,type:oe,transition:re,children:ne,shapeFlag:Y}=v;if(Y&6){Ee(v.component.subTree,b,C,j);return}if(Y&128){v.suspense.move(b,C,j);return}if(Y&64){oe.move(v,b,C,x);return}if(oe===Ie){s(H,b,C);for(let le=0;lere.enter(H),z);else{const{leave:le,delayLeave:ce,afterLeave:me}=re,ke=()=>{v.ctx.isUnmounted?a(H):s(H,b,C)},Re=()=>{H._isLeaving&&H[Vu](!0),le(H,()=>{ke(),me&&me()})};ce?ce(H,ke,Re):Re()}else s(H,b,C)},we=(v,b,C,j=!1,z=!1)=>{const{type:H,props:oe,ref:re,children:ne,dynamicChildren:Y,shapeFlag:fe,patchFlag:le,dirs:ce,cacheIndex:me,memo:ke}=v;if(le===-2&&(z=!1),re!=null&&(Kt(),ns(re,null,C,v,!0),Wt()),me!=null&&(b.renderCache[me]=void 0),fe&256){b.ctx.deactivate(v);return}const Re=fe&1&&ce,Pe=!Pn(v);let Be;if(Pe&&(Be=oe&&oe.onVnodeBeforeUnmount)&&$t(Be,b,v),fe&6)Ve(v.component,C,j);else{if(fe&128){v.suspense.unmount(C,j);return}Re&&dn(v,null,b,"beforeUnmount"),fe&64?v.type.remove(v,b,C,x,j):Y&&!Y.hasOnce&&(H!==Ie||le>0&&le&64)?Te(Y,b,C,!1,!0):(H===Ie&&le&384||!z&&fe&16)&&Te(ne,b,C),j&&Me(v)}const ie=ke!=null&&me==null;(Pe&&(Be=oe&&oe.onVnodeUnmounted)||Re||ie)&&ot(()=>{Be&&$t(Be,b,v),Re&&dn(v,null,b,"unmounted"),ie&&(v.el=null)},C)},Me=v=>{const{type:b,el:C,anchor:j,transition:z}=v;if(b===Ie){je(C,j);return}if(b===ks){E(v);return}const H=()=>{a(C),z&&!z.persisted&&z.afterLeave&&z.afterLeave()};if(v.shapeFlag&1&&z&&!z.persisted){const{leave:oe,delayLeave:re}=z,ne=()=>oe(C,H);re?re(v.el,H,ne):ne()}else H()},je=(v,b)=>{let C;for(;v!==b;)C=f(v),a(v),v=C;a(b)},Ve=(v,b,C)=>{const{bum:j,scope:z,job:H,subTree:oe,um:re,m:ne,a:Y}=v;Wr(ne),Wr(Y),j&&oa(j),z.stop(),H&&(H.flags|=8,we(oe,v,b,C)),re&&ot(re,b),ot(()=>{v.isUnmounted=!0},b)},Te=(v,b,C,j=!1,z=!1,H=0)=>{for(let oe=H;oe{if(v.shapeFlag&6)return M(v.component.subTree);if(v.shapeFlag&128)return v.suspense.next();const b=f(v.anchor||v.el),C=b&&b[$o];return C?f(C):b};let se=!1;const $=(v,b,C)=>{let j;v==null?b._vnode&&(we(b._vnode,null,null,!0),j=b._vnode.component):y(b._vnode||null,v,b,null,null,null,C),b._vnode=v,se||(se=!0,Or(j),Ao(),se=!1)},x={p:y,um:we,m:Ee,r:Me,mt:B,mc:A,pc:te,pbc:Z,n:M,o:e};return{render:$,hydrate:void 0,createApp:lc($)}}function pa({type:e,props:t},n){return n==="svg"&&e==="foreignObject"||n==="mathml"&&e==="annotation-xml"&&t&&t.encoding&&t.encoding.includes("html")?void 0:n}function fn({effect:e,job:t},n){n?(e.flags|=32,t.flags|=4):(e.flags&=-33,t.flags&=-5)}function Ac(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function cr(e,t,n=!1){const s=e.children,a=t.children;if(ye(s)&&ye(a))for(let r=0;r>1,e[n[i]]0&&(t[s]=n[r-1]),n[r]=s)}}for(r=n.length,o=n[r-1];r-- >0;)n[r]=o,o=t[o];return n}function Jo(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:Jo(t)}function Wr(e){if(e)for(let t=0;te.__isSuspense;function Cc(e,t){t&&t.pendingBranch?ye(e)?t.effects.push(...e):t.effects.push(e):Lu(e)}const Ie=Symbol.for("v-fgt"),Xs=Symbol.for("v-txt"),Xt=Symbol.for("v-cmt"),ks=Symbol.for("v-stc"),as=[];let vt=null;function w(e=!1){as.push(vt=e?null:[])}function Ec(){as.pop(),vt=as[as.length-1]||null}let cs=1;function Ls(e,t=!1){cs+=e,e<0&&vt&&t&&(vt.hasOnce=!0)}function Zo(e){return e.dynamicChildren=cs>0?vt||Rn:null,Ec(),cs>0&&vt&&vt.push(e),e}function G(e,t,n,s,a,r){return Zo(D(e,t,n,s,a,r,!0))}function K(e,t,n,s,a){return Zo(L(e,t,n,s,a,!0))}function ds(e){return e?e.__v_isVNode===!0:!1}function Vn(e,t){return e.type===t.type&&e.key===t.key}const Qo=({key:e})=>e??null,As=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?He(e)||Ue(e)||be(e)?{i:dt,r:e,k:t,f:!!n}:e:null);function D(e,t=null,n=null,s=0,a=null,r=e===Ie?0:1,o=!1,i=!1){const l={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&Qo(t),ref:t&&As(t),scopeId:Co,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetStart:null,targetAnchor:null,staticCount:0,shapeFlag:r,patchFlag:s,dynamicProps:a,dynamicChildren:null,appContext:null,ctx:dt};return i?(dr(l,n),r&128&&e.normalize(l)):n&&(l.shapeFlag|=He(n)?8:16),cs>0&&!o&&vt&&(l.patchFlag>0||r&6)&&l.patchFlag!==32&&vt.push(l),l}const L=Rc;function Rc(e,t=null,n=null,s=0,a=null,r=!1){if((!e||e===Qu)&&(e=Xt),ds(e)){const i=In(e,t,!0);return n&&dr(i,n),cs>0&&!r&&vt&&(i.shapeFlag&6?vt[vt.indexOf(e)]=i:vt.push(i)),i.patchFlag=-2,i}if(Uc(e)&&(e=e.__vccOpts),t){t=$c(t);let{class:i,style:l}=t;i&&!He(i)&&(t.class=Mt(i)),$e(l)&&(qs(l)&&!ye(l)&&(l=tt({},l)),t.style=Xa(l))}const o=He(e)?1:Xo(e)?128:Nu(e)?64:$e(e)?4:be(e)?2:0;return D(e,t,n,s,a,o,r,!0)}function $c(e){return e?qs(e)||Ho(e)?tt({},e):e:null}function In(e,t,n=!1,s=!1){const{props:a,ref:r,patchFlag:o,children:i,transition:l}=e,u=t?el(a||{},t):a,c={__v_isVNode:!0,__v_skip:!0,type:e.type,props:u,key:u&&Qo(u),ref:t&&t.ref?n&&r?ye(r)?r.concat(As(t)):[r,As(t)]:As(t):r,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:i,target:e.target,targetStart:e.targetStart,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==Ie?o===-1?16:o|16:o,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:l,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&In(e.ssContent),ssFallback:e.ssFallback&&In(e.ssFallback),placeholder:e.placeholder,el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce};return l&&s&&or(c,l.clone(c)),c}function U(e=" ",t=0){return L(Xs,null,e,t)}function Tc(e,t){const n=L(ks,null,e);return n.staticCount=t,n}function ae(e="",t=!1){return t?(w(),K(Xt,null,e)):L(Xt,null,e)}function Dt(e){return e==null||typeof e=="boolean"?L(Xt):ye(e)?L(Ie,null,e.slice()):ds(e)?Gt(e):L(Xs,null,String(e))}function Gt(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:In(e)}function dr(e,t){let n=0;const{shapeFlag:s}=e;if(t==null)t=null;else if(ye(t))n=16;else if(typeof t=="object")if(s&65){const a=t.default;a&&(a._c&&(a._d=!1),dr(e,a()),a._c&&(a._d=!0));return}else{n=32;const a=t._;!a&&!Ho(t)?t._ctx=dt:a===3&&dt&&(dt.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else be(t)?(t={default:t,_ctx:dt},n=32):(t=String(t),s&64?(n=16,t=[U(t)]):n=8);e.children=t,e.shapeFlag|=n}function el(...e){const t={};for(let n=0;nat||dt;let Is,Na;{const e=Hs(),t=(n,s)=>{let a;return(a=e[n])||(a=e[n]=[]),a.push(s),r=>{a.length>1?a.forEach(o=>o(r)):a[0](r)}};Is=t("__VUE_INSTANCE_SETTERS__",n=>at=n),Na=t("__VUE_SSR_SETTERS__",n=>fs=n)}const ms=e=>{const t=at;return Is(e),e.scope.on(),()=>{e.scope.off(),Is(t)}},Jr=()=>{at&&at.scope.off(),Is(null)};function tl(e){return e.vnode.shapeFlag&4}let fs=!1;function Dc(e,t=!1,n=!1){t&&Na(t);const{props:s,children:a}=e.vnode,r=tl(e);hc(e,s,r,t),bc(e,a,n||t);const o=r?Oc(e,t):void 0;return t&&Na(!1),o}function Oc(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=new Proxy(e.ctx,tc);const{setup:s}=n;if(s){Kt();const a=e.setupContext=s.length>1?Nc(e):null,r=ms(e),o=gs(s,e,0,[e.props,a]),i=Wi(o);if(Wt(),r(),(i||e.sp)&&!Pn(e)&&To(e),i){if(o.then(Jr,Jr),t)return o.then(l=>{Yr(e,l)}).catch(l=>{zs(l,e,0)});e.asyncDep=o}else Yr(e,o)}else nl(e)}function Yr(e,t,n){be(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:$e(t)&&(e.setupState=wo(t)),nl(e)}function nl(e,t,n){const s=e.type;e.render||(e.render=s.render||Ft);{const a=ms(e);Kt();try{nc(e)}finally{Wt(),a()}}}const Fc={get(e,t){return st(e,"get",""),e[t]}};function Nc(e){const t=n=>{e.exposed=n||{}};return{attrs:new Proxy(e.attrs,Fc),slots:e.slots,emit:e.emit,expose:t}}function fr(e){return e.exposed?e.exposeProxy||(e.exposeProxy=new Proxy(wo(rr(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in ss)return ss[n](e)},has(t,n){return n in t||n in ss}})):e.proxy}function Mc(e,t=!0){return be(e)?e.displayName||e.name:e.name||t&&e.__name}function Uc(e){return be(e)&&"__vccOpts"in e}const Q=(e,t)=>Eu(e,t,fs);function V(e,t,n){try{Ls(-1);const s=arguments.length;return s===2?$e(t)&&!ye(t)?ds(t)?L(e,null,[t]):L(e,t):L(e,null,t):(s>3?n=Array.prototype.slice.call(arguments,2):s===3&&ds(n)&&(n=[n]),L(e,t,n))}finally{Ls(1)}}const Bc="3.5.33";/** -* @vue/runtime-dom v3.5.33 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/let Ma;const Xr=typeof window<"u"&&window.trustedTypes;if(Xr)try{Ma=Xr.createPolicy("vue",{createHTML:e=>e})}catch{}const sl=Ma?e=>Ma.createHTML(e):e=>e,jc="http://www.w3.org/2000/svg",Vc="http://www.w3.org/1998/Math/MathML",Ht=typeof document<"u"?document:null,Zr=Ht&&Ht.createElement("template"),Hc={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,s)=>{const a=t==="svg"?Ht.createElementNS(jc,e):t==="mathml"?Ht.createElementNS(Vc,e):n?Ht.createElement(e,{is:n}):Ht.createElement(e);return e==="select"&&s&&s.multiple!=null&&a.setAttribute("multiple",s.multiple),a},createText:e=>Ht.createTextNode(e),createComment:e=>Ht.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>Ht.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,s,a,r){const o=n?n.previousSibling:t.lastChild;if(a&&(a===r||a.nextSibling))for(;t.insertBefore(a.cloneNode(!0),n),!(a===r||!(a=a.nextSibling)););else{Zr.innerHTML=sl(s==="svg"?`${e}`:s==="mathml"?`${e}`:e);const i=Zr.content;if(s==="svg"||s==="mathml"){const l=i.firstChild;for(;l.firstChild;)i.appendChild(l.firstChild);i.removeChild(l)}t.insertBefore(i,n)}return[o?o.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},Gc=Symbol("_vtc");function qc(e,t,n){const s=e[Gc];s&&(t=(t?[t,...s]:[...s]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const Qr=Symbol("_vod"),zc=Symbol("_vsh"),Kc=Symbol(""),Wc=/(?:^|;)\s*display\s*:/;function Jc(e,t,n){const s=e.style,a=He(n);let r=!1;if(n&&!a){if(t)if(He(t))for(const o of t.split(";")){const i=o.slice(0,o.indexOf(":")).trim();n[i]==null&&Xn(s,i,"")}else for(const o in t)n[o]==null&&Xn(s,o,"");for(const o in n){o==="display"&&(r=!0);const i=n[o];i!=null?Xc(e,o,!He(t)&&t?t[o]:void 0,i)||Xn(s,o,i):Xn(s,o,"")}}else if(a){if(t!==n){const o=s[Kc];o&&(n+=";"+o),s.cssText=n,r=Wc.test(n)}}else t&&e.removeAttribute("style");Qr in e&&(e[Qr]=r?s.display:"",e[zc]&&(s.display="none"))}const ei=/\s*!important$/;function Xn(e,t,n){if(ye(n))n.forEach(s=>Xn(e,t,s));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const s=Yc(e,t);ei.test(n)?e.setProperty(un(s),n.replace(ei,""),"important"):e[s]=n}}const ti=["Webkit","Moz","ms"],va={};function Yc(e,t){const n=va[t];if(n)return n;let s=ft(t);if(s!=="filter"&&s in e)return va[t]=s;s=Vs(s);for(let a=0;aga||(nd.then(()=>ga=0),ga=Date.now());function ad(e,t){const n=s=>{if(!s._vts)s._vts=Date.now();else if(s._vts<=n.attached)return;Ut(rd(s,n.value),t,5,[s])};return n.value=e,n.attached=sd(),n}function rd(e,t){if(ye(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(s=>a=>!a._stopped&&s&&s(a))}else return t}const oi=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,id=(e,t,n,s,a,r)=>{const o=a==="svg";t==="class"?qc(e,s,o):t==="style"?Jc(e,n,s):Ms(t)?Us(t)||ed(e,t,n,s,r):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):od(e,t,s,o))?(ai(e,t,s),!e.tagName.includes("-")&&(t==="value"||t==="checked"||t==="selected")&&si(e,t,s,o,r,t!=="value")):e._isVueCE&&(ld(e,t)||e._def.__asyncLoader&&(/[A-Z]/.test(t)||!He(s)))?ai(e,ft(t),s,r,t):(t==="true-value"?e._trueValue=s:t==="false-value"&&(e._falseValue=s),si(e,t,s,o))};function od(e,t,n,s){if(s)return!!(t==="innerHTML"||t==="textContent"||t in e&&oi(t)&&be(n));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="autocorrect"||t==="sandbox"&&e.tagName==="IFRAME"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const a=e.tagName;if(a==="IMG"||a==="VIDEO"||a==="CANVAS"||a==="SOURCE")return!1}return oi(t)&&He(n)?!1:t in e}function ld(e,t){const n=e._def.props;if(!n)return!1;const s=ft(t);return Array.isArray(n)?n.some(a=>ft(a)===s):Object.keys(n).some(a=>ft(a)===s)}const ud=["ctrl","shift","alt","meta"],cd={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&e.button!==0,middle:e=>"button"in e&&e.button!==1,right:e=>"button"in e&&e.button!==2,exact:(e,t)=>ud.some(n=>e[`${n}Key`]&&!t.includes(n))},Qs=(e,t)=>{if(!e)return e;const n=e._withMods||(e._withMods={}),s=t.join(".");return n[s]||(n[s]=((a,...r)=>{for(let o=0;o{const n=e._withKeys||(e._withKeys={}),s=t.join(".");return n[s]||(n[s]=(a=>{if(!("key"in a))return;const r=un(a.key);if(t.some(o=>o===r||dd[o]===r))return e(a)}))},pd=tt({patchProp:id},Hc);let li;function vd(){return li||(li=Sc(pd))}const gd=((...e)=>{const t=vd().createApp(...e),{mount:n}=t;return t.mount=s=>{const a=md(s);if(!a)return;const r=t._component;!be(r)&&!r.render&&!r.template&&(r.template=a.innerHTML),a.nodeType===1&&(a.textContent="");const o=n(a,!1,hd(a));return a instanceof Element&&(a.removeAttribute("v-cloak"),a.setAttribute("data-v-app","")),o},t});function hd(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function md(e){return He(e)?document.querySelector(e):e}/*! - * pinia v2.3.1 - * (c) 2025 Eduardo San Martin Morote - * @license MIT - */let al;const ea=e=>al=e,rl=Symbol();function Ua(e){return e&&typeof e=="object"&&Object.prototype.toString.call(e)==="[object Object]"&&typeof e.toJSON!="function"}var rs;(function(e){e.direct="direct",e.patchObject="patch object",e.patchFunction="patch function"})(rs||(rs={}));function yd(){const e=no(!0),t=e.run(()=>J({}));let n=[],s=[];const a=rr({install(r){ea(a),a._a=r,r.provide(rl,a),r.config.globalProperties.$pinia=a,s.forEach(o=>n.push(o)),s=[]},use(r){return this._a?n.push(r):s.push(r),this},_p:n,_a:null,_e:e,_s:new Map,state:t});return a}const il=()=>{};function ui(e,t,n,s=il){e.push(t);const a=()=>{const r=e.indexOf(t);r>-1&&(e.splice(r,1),s())};return!n&&so()&&eu(a),a}function An(e,...t){e.slice().forEach(n=>{n(...t)})}const _d=e=>e(),ci=Symbol(),ha=Symbol();function Ba(e,t){e instanceof Map&&t instanceof Map?t.forEach((n,s)=>e.set(s,n)):e instanceof Set&&t instanceof Set&&t.forEach(e.add,e);for(const n in t){if(!t.hasOwnProperty(n))continue;const s=t[n],a=e[n];Ua(a)&&Ua(s)&&e.hasOwnProperty(n)&&!Ue(s)&&!zt(s)?e[n]=Ba(a,s):e[n]=s}return e}const bd=Symbol();function wd(e){return!Ua(e)||!e.hasOwnProperty(bd)}const{assign:sn}=Object;function Sd(e){return!!(Ue(e)&&e.effect)}function kd(e,t,n,s){const{state:a,actions:r,getters:o}=t,i=n.state.value[e];let l;function u(){i||(n.state.value[e]=a?a():{});const c=ku(n.state.value[e]);return sn(c,r,Object.keys(o||{}).reduce((d,f)=>(d[f]=rr(Q(()=>{ea(n);const h=n._s.get(e);return o[f].call(h,h)})),d),{}))}return l=ol(e,u,t,n,s,!0),l}function ol(e,t,n={},s,a,r){let o;const i=sn({actions:{}},n),l={deep:!0};let u,c,d=[],f=[],h;const g=s.state.value[e];!r&&!g&&(s.state.value[e]={});let y;function m(A){let R;u=c=!1,typeof A=="function"?(A(s.state.value[e]),R={type:rs.patchFunction,storeId:e,events:h}):(Ba(s.state.value[e],A),R={type:rs.patchObject,payload:A,storeId:e,events:h});const Z=y=Symbol();_n().then(()=>{y===Z&&(u=!0)}),c=!0,An(d,R,s.state.value[e])}const P=r?function(){const{state:R}=n,Z=R?R():{};this.$patch(ue=>{sn(ue,Z)})}:il;function _(){o.stop(),d=[],f=[],s._s.delete(e)}const S=(A,R="")=>{if(ci in A)return A[ha]=R,A;const Z=function(){ea(s);const ue=Array.from(arguments),de=[],pe=[];function B(W){de.push(W)}function q(W){pe.push(W)}An(f,{args:ue,name:Z[ha],store:F,after:B,onError:q});let X;try{X=A.apply(this&&this.$id===e?this:F,ue)}catch(W){throw An(pe,W),W}return X instanceof Promise?X.then(W=>(An(de,W),W)).catch(W=>(An(pe,W),Promise.reject(W))):(An(de,X),X)};return Z[ci]=!0,Z[ha]=R,Z},E={_p:s,$id:e,$onAction:ui.bind(null,f),$patch:m,$reset:P,$subscribe(A,R={}){const Z=ui(d,A,R.detached,()=>ue()),ue=o.run(()=>At(()=>s.state.value[e],de=>{(R.flush==="sync"?c:u)&&A({storeId:e,type:rs.direct,events:h},de)},sn({},l,R)));return Z},$dispose:_},F=Zt(E);s._s.set(e,F);const T=(s._a&&s._a.runWithContext||_d)(()=>s._e.run(()=>(o=no()).run(()=>t({action:S}))));for(const A in T){const R=T[A];if(Ue(R)&&!Sd(R)||zt(R))r||(g&&wd(R)&&(Ue(R)?R.value=g[A]:Ba(R,g[A])),s.state.value[e][A]=R);else if(typeof R=="function"){const Z=S(R,A);T[A]=Z,i.actions[A]=R}}return sn(F,T),sn(Ae(F),T),Object.defineProperty(F,"$state",{get:()=>s.state.value[e],set:A=>{m(R=>{sn(R,A)})}}),s._p.forEach(A=>{sn(F,o.run(()=>A({store:F,app:s._a,pinia:s,options:i})))}),g&&r&&n.hydrate&&n.hydrate(F.$state,g),u=!0,c=!0,F}/*! #__NO_SIDE_EFFECTS__ */function bn(e,t,n){let s,a;const r=typeof t=="function";typeof e=="string"?(s=e,a=r?n:t):(a=e,s=e.id);function o(i,l){const u=Iu();return i=i||(u?mt(rl,null):null),i&&ea(i),i=al,i._s.has(s)||(r?ol(s,t,a,i):kd(s,a,i)),i._s.get(s)}return o.$id=s,o}const Ad="modulepreload",xd=function(e){return"/"+e},di={},pr=function(t,n,s){let a=Promise.resolve();if(n&&n.length>0){let o=function(u){return Promise.all(u.map(c=>Promise.resolve(c).then(d=>({status:"fulfilled",value:d}),d=>({status:"rejected",reason:d}))))};document.getElementsByTagName("link");const i=document.querySelector("meta[property=csp-nonce]"),l=(i==null?void 0:i.nonce)||(i==null?void 0:i.getAttribute("nonce"));a=o(n.map(u=>{if(u=xd(u),u in di)return;di[u]=!0;const c=u.endsWith(".css"),d=c?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${u}"]${d}`))return;const f=document.createElement("link");if(f.rel=c?"stylesheet":Ad,c||(f.as="script"),f.crossOrigin="",f.href=u,l&&f.setAttribute("nonce",l),document.head.appendChild(f),c)return new Promise((h,g)=>{f.addEventListener("load",h),f.addEventListener("error",()=>g(new Error(`Unable to preload CSS for ${u}`)))})}))}function r(o){const i=new Event("vite:preloadError",{cancelable:!0});if(i.payload=o,window.dispatchEvent(i),!i.defaultPrevented)throw o}return a.then(o=>{for(const i of o||[])i.status==="rejected"&&r(i.reason);return t().catch(r)})};/*! Capacitor: https://capacitorjs.com/ - MIT License */var Dn;(function(e){e.Unimplemented="UNIMPLEMENTED",e.Unavailable="UNAVAILABLE"})(Dn||(Dn={}));class ma extends Error{constructor(t,n,s){super(t),this.message=t,this.code=n,this.data=s}}const Cd=e=>{var t,n;return e!=null&&e.androidBridge?"android":!((n=(t=e==null?void 0:e.webkit)===null||t===void 0?void 0:t.messageHandlers)===null||n===void 0)&&n.bridge?"ios":"web"},Ed=e=>{const t=e.CapacitorCustomPlatform||null,n=e.Capacitor||{},s=n.Plugins=n.Plugins||{},a=()=>t!==null?t.name:Cd(e),r=()=>a()!=="web",o=d=>{const f=u.get(d);return!!(f!=null&&f.platforms.has(a())||i(d))},i=d=>{var f;return(f=n.PluginHeaders)===null||f===void 0?void 0:f.find(h=>h.name===d)},l=d=>e.console.error(d),u=new Map,c=(d,f={})=>{const h=u.get(d);if(h)return console.warn(`Capacitor plugin "${d}" already registered. Cannot register plugins twice.`),h.proxy;const g=a(),y=i(d);let m;const P=async()=>(!m&&g in f?m=typeof f[g]=="function"?m=await f[g]():m=f[g]:t!==null&&!m&&"web"in f&&(m=typeof f.web=="function"?m=await f.web():m=f.web),m),_=(A,R)=>{var Z,ue;if(y){const de=y==null?void 0:y.methods.find(pe=>R===pe.name);if(de)return de.rtype==="promise"?pe=>n.nativePromise(d,R.toString(),pe):(pe,B)=>n.nativeCallback(d,R.toString(),pe,B);if(A)return(Z=A[R])===null||Z===void 0?void 0:Z.bind(A)}else{if(A)return(ue=A[R])===null||ue===void 0?void 0:ue.bind(A);throw new ma(`"${d}" plugin is not implemented on ${g}`,Dn.Unimplemented)}},S=A=>{let R;const Z=(...ue)=>{const de=P().then(pe=>{const B=_(pe,A);if(B){const q=B(...ue);return R=q==null?void 0:q.remove,q}else throw new ma(`"${d}.${A}()" is not implemented on ${g}`,Dn.Unimplemented)});return A==="addListener"&&(de.remove=async()=>R()),de};return Z.toString=()=>`${A.toString()}() { [capacitor code] }`,Object.defineProperty(Z,"name",{value:A,writable:!1,configurable:!1}),Z},E=S("addListener"),F=S("removeListener"),I=(A,R)=>{const Z=E({eventName:A},R),ue=async()=>{const pe=await Z;F({eventName:A,callbackId:pe},R)},de=new Promise(pe=>Z.then(()=>pe({remove:ue})));return de.remove=async()=>{console.warn("Using addListener() without 'await' is deprecated."),await ue()},de},T=new Proxy({},{get(A,R){switch(R){case"$$typeof":return;case"toJSON":return()=>({});case"addListener":return y?I:E;case"removeListener":return F;default:return S(R)}}});return s[d]=T,u.set(d,{name:d,proxy:T,platforms:new Set([...Object.keys(f),...y?[g]:[]])}),T};return n.convertFileSrc||(n.convertFileSrc=d=>d),n.getPlatform=a,n.handleError=l,n.isNativePlatform=r,n.isPluginAvailable=o,n.registerPlugin=c,n.Exception=ma,n.DEBUG=!!n.DEBUG,n.isLoggingEnabled=!!n.isLoggingEnabled,n},Rd=e=>e.Capacitor=Ed(e),Ds=Rd(typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{}),ys=Ds.registerPlugin;class vr{constructor(){this.listeners={},this.retainedEventArguments={},this.windowListeners={}}addListener(t,n){let s=!1;this.listeners[t]||(this.listeners[t]=[],s=!0),this.listeners[t].push(n);const r=this.windowListeners[t];r&&!r.registered&&this.addWindowListener(r),s&&this.sendRetainedArgumentsForEvent(t);const o=async()=>this.removeListener(t,n);return Promise.resolve({remove:o})}async removeAllListeners(){this.listeners={};for(const t in this.windowListeners)this.removeWindowListener(this.windowListeners[t]);this.windowListeners={}}notifyListeners(t,n,s){const a=this.listeners[t];if(!a){if(s){let r=this.retainedEventArguments[t];r||(r=[]),r.push(n),this.retainedEventArguments[t]=r}return}a.forEach(r=>r(n))}hasListeners(t){var n;return!!(!((n=this.listeners[t])===null||n===void 0)&&n.length)}registerWindowListener(t,n){this.windowListeners[n]={registered:!1,windowEventName:t,pluginEventName:n,handler:s=>{this.notifyListeners(n,s)}}}unimplemented(t="not implemented"){return new Ds.Exception(t,Dn.Unimplemented)}unavailable(t="not available"){return new Ds.Exception(t,Dn.Unavailable)}async removeListener(t,n){const s=this.listeners[t];if(!s)return;const a=s.indexOf(n);this.listeners[t].splice(a,1),this.listeners[t].length||this.removeWindowListener(this.windowListeners[t])}addWindowListener(t){window.addEventListener(t.windowEventName,t.handler),t.registered=!0}removeWindowListener(t){t&&(window.removeEventListener(t.windowEventName,t.handler),t.registered=!1)}sendRetainedArgumentsForEvent(t){const n=this.retainedEventArguments[t];n&&(delete this.retainedEventArguments[t],n.forEach(s=>{this.notifyListeners(t,s)}))}}const fi=e=>encodeURIComponent(e).replace(/%(2[346B]|5E|60|7C)/g,decodeURIComponent).replace(/[()]/g,escape),pi=e=>e.replace(/(%[\dA-F]{2})+/gi,decodeURIComponent);class $d extends vr{async getCookies(){const t=document.cookie,n={};return t.split(";").forEach(s=>{if(s.length<=0)return;let[a,r]=s.replace(/=/,"CAP_COOKIE").split("CAP_COOKIE");a=pi(a).trim(),r=pi(r).trim(),n[a]=r}),n}async setCookie(t){try{const n=fi(t.key),s=fi(t.value),a=t.expires?`; expires=${t.expires.replace("expires=","")}`:"",r=(t.path||"/").replace("path=",""),o=t.url!=null&&t.url.length>0?`domain=${t.url}`:"";document.cookie=`${n}=${s||""}${a}; path=${r}; ${o};`}catch(n){return Promise.reject(n)}}async deleteCookie(t){try{document.cookie=`${t.key}=; Max-Age=0`}catch(n){return Promise.reject(n)}}async clearCookies(){try{const t=document.cookie.split(";")||[];for(const n of t)document.cookie=n.replace(/^ +/,"").replace(/=.*/,`=;expires=${new Date().toUTCString()};path=/`)}catch(t){return Promise.reject(t)}}async clearAllCookies(){try{await this.clearCookies()}catch(t){return Promise.reject(t)}}}ys("CapacitorCookies",{web:()=>new $d});const Td=async e=>new Promise((t,n)=>{const s=new FileReader;s.onload=()=>{const a=s.result;t(a.indexOf(",")>=0?a.split(",")[1]:a)},s.onerror=a=>n(a),s.readAsDataURL(e)}),Pd=(e={})=>{const t=Object.keys(e);return Object.keys(e).map(a=>a.toLocaleLowerCase()).reduce((a,r,o)=>(a[r]=e[t[o]],a),{})},Ld=(e,t=!0)=>e?Object.entries(e).reduce((s,a)=>{const[r,o]=a;let i,l;return Array.isArray(o)?(l="",o.forEach(u=>{i=t?encodeURIComponent(u):u,l+=`${r}=${i}&`}),l.slice(0,-1)):(i=t?encodeURIComponent(o):o,l=`${r}=${i}`),`${s}&${l}`},"").substr(1):null,Id=(e,t={})=>{const n=Object.assign({method:e.method||"GET",headers:e.headers},t),a=Pd(e.headers)["content-type"]||"";if(typeof e.data=="string")n.body=e.data;else if(a.includes("application/x-www-form-urlencoded")){const r=new URLSearchParams;for(const[o,i]of Object.entries(e.data||{}))r.set(o,i);n.body=r.toString()}else if(a.includes("multipart/form-data")||e.data instanceof FormData){const r=new FormData;if(e.data instanceof FormData)e.data.forEach((i,l)=>{r.append(l,i)});else for(const i of Object.keys(e.data))r.append(i,e.data[i]);n.body=r;const o=new Headers(n.headers);o.delete("content-type"),n.headers=o}else(a.includes("application/json")||typeof e.data=="object")&&(n.body=JSON.stringify(e.data));return n};class Dd extends vr{async request(t){const n=Id(t,t.webFetchExtra),s=Ld(t.params,t.shouldEncodeUrlParams),a=s?`${t.url}?${s}`:t.url,r=await fetch(a,n),o=r.headers.get("content-type")||"";let{responseType:i="text"}=r.ok?t:{};o.includes("application/json")&&(i="json");let l,u;switch(i){case"arraybuffer":case"blob":u=await r.blob(),l=await Td(u);break;case"json":l=await r.json();break;case"document":case"text":default:l=await r.text()}const c={};return r.headers.forEach((d,f)=>{c[f]=d}),{data:l,headers:c,status:r.status,url:r.url}}async get(t){return this.request(Object.assign(Object.assign({},t),{method:"GET"}))}async post(t){return this.request(Object.assign(Object.assign({},t),{method:"POST"}))}async put(t){return this.request(Object.assign(Object.assign({},t),{method:"PUT"}))}async patch(t){return this.request(Object.assign(Object.assign({},t),{method:"PATCH"}))}async delete(t){return this.request(Object.assign(Object.assign({},t),{method:"DELETE"}))}}ys("CapacitorHttp",{web:()=>new Dd});var vi;(function(e){e.Dark="DARK",e.Light="LIGHT",e.Default="DEFAULT"})(vi||(vi={}));var gi;(function(e){e.StatusBar="StatusBar",e.NavigationBar="NavigationBar"})(gi||(gi={}));class Od extends vr{async setStyle(){this.unavailable("not available for web")}async setAnimation(){this.unavailable("not available for web")}async show(){this.unavailable("not available for web")}async hide(){this.unavailable("not available for web")}}ys("SystemBars",{web:()=>new Od});const ja=ys("App",{web:()=>pr(()=>import("./web-f7iCgAY0.js"),[]).then(e=>new e.AppWeb)});/*! - * vue-router v4.6.4 - * (c) 2025 Eduardo San Martin Morote - * @license MIT - */const Cn=typeof document<"u";function ll(e){return typeof e=="object"||"displayName"in e||"props"in e||"__vccOpts"in e}function Fd(e){return e.__esModule||e[Symbol.toStringTag]==="Module"||e.default&&ll(e.default)}const xe=Object.assign;function ya(e,t){const n={};for(const s in t){const a=t[s];n[s]=Et(a)?a.map(e):e(a)}return n}const is=()=>{},Et=Array.isArray;function hi(e,t){const n={};for(const s in e)n[s]=s in t?t[s]:e[s];return n}const ul=/#/g,Nd=/&/g,Md=/\//g,Ud=/=/g,Bd=/\?/g,cl=/\+/g,jd=/%5B/g,Vd=/%5D/g,dl=/%5E/g,Hd=/%60/g,fl=/%7B/g,Gd=/%7C/g,pl=/%7D/g,qd=/%20/g;function gr(e){return e==null?"":encodeURI(""+e).replace(Gd,"|").replace(jd,"[").replace(Vd,"]")}function zd(e){return gr(e).replace(fl,"{").replace(pl,"}").replace(dl,"^")}function Va(e){return gr(e).replace(cl,"%2B").replace(qd,"+").replace(ul,"%23").replace(Nd,"%26").replace(Hd,"`").replace(fl,"{").replace(pl,"}").replace(dl,"^")}function Kd(e){return Va(e).replace(Ud,"%3D")}function Wd(e){return gr(e).replace(ul,"%23").replace(Bd,"%3F")}function Jd(e){return Wd(e).replace(Md,"%2F")}function ps(e){if(e==null)return null;try{return decodeURIComponent(""+e)}catch{}return""+e}const Yd=/\/$/,Xd=e=>e.replace(Yd,"");function _a(e,t,n="/"){let s,a={},r="",o="";const i=t.indexOf("#");let l=t.indexOf("?");return l=i>=0&&l>i?-1:l,l>=0&&(s=t.slice(0,l),r=t.slice(l,i>0?i:t.length),a=e(r.slice(1))),i>=0&&(s=s||t.slice(0,i),o=t.slice(i,t.length)),s=tf(s??t,n),{fullPath:s+r+o,path:s,query:a,hash:ps(o)}}function Zd(e,t){const n=t.query?e(t.query):"";return t.path+(n&&"?")+n+(t.hash||"")}function mi(e,t){return!t||!e.toLowerCase().startsWith(t.toLowerCase())?e:e.slice(t.length)||"/"}function Qd(e,t,n){const s=t.matched.length-1,a=n.matched.length-1;return s>-1&&s===a&&On(t.matched[s],n.matched[a])&&vl(t.params,n.params)&&e(t.query)===e(n.query)&&t.hash===n.hash}function On(e,t){return(e.aliasOf||e)===(t.aliasOf||t)}function vl(e,t){if(Object.keys(e).length!==Object.keys(t).length)return!1;for(var n in e)if(!ef(e[n],t[n]))return!1;return!0}function ef(e,t){return Et(e)?yi(e,t):Et(t)?yi(t,e):(e==null?void 0:e.valueOf())===(t==null?void 0:t.valueOf())}function yi(e,t){return Et(t)?e.length===t.length&&e.every((n,s)=>n===t[s]):e.length===1&&e[0]===t}function tf(e,t){if(e.startsWith("/"))return e;if(!e)return t;const n=t.split("/"),s=e.split("/"),a=s[s.length-1];(a===".."||a===".")&&s.push("");let r=n.length-1,o,i;for(o=0;o1&&r--;else break;return n.slice(0,r).join("/")+"/"+s.slice(o).join("/")}const tn={path:"/",name:void 0,params:{},query:{},hash:"",fullPath:"/",matched:[],meta:{},redirectedFrom:void 0};let Ha=(function(e){return e.pop="pop",e.push="push",e})({}),ba=(function(e){return e.back="back",e.forward="forward",e.unknown="",e})({});function nf(e){if(!e)if(Cn){const t=document.querySelector("base");e=t&&t.getAttribute("href")||"/",e=e.replace(/^\w+:\/\/[^\/]+/,"")}else e="/";return e[0]!=="/"&&e[0]!=="#"&&(e="/"+e),Xd(e)}const sf=/^[^#]+#/;function af(e,t){return e.replace(sf,"#")+t}function rf(e,t){const n=document.documentElement.getBoundingClientRect(),s=e.getBoundingClientRect();return{behavior:t.behavior,left:s.left-n.left-(t.left||0),top:s.top-n.top-(t.top||0)}}const ta=()=>({left:window.scrollX,top:window.scrollY});function of(e){let t;if("el"in e){const n=e.el,s=typeof n=="string"&&n.startsWith("#"),a=typeof n=="string"?s?document.getElementById(n.slice(1)):document.querySelector(n):n;if(!a)return;t=rf(a,e)}else t=e;"scrollBehavior"in document.documentElement.style?window.scrollTo(t):window.scrollTo(t.left!=null?t.left:window.scrollX,t.top!=null?t.top:window.scrollY)}function _i(e,t){return(history.state?history.state.position-t:-1)+e}const Ga=new Map;function lf(e,t){Ga.set(e,t)}function uf(e){const t=Ga.get(e);return Ga.delete(e),t}function cf(e){return typeof e=="string"||e&&typeof e=="object"}function gl(e){return typeof e=="string"||typeof e=="symbol"}let Ge=(function(e){return e[e.MATCHER_NOT_FOUND=1]="MATCHER_NOT_FOUND",e[e.NAVIGATION_GUARD_REDIRECT=2]="NAVIGATION_GUARD_REDIRECT",e[e.NAVIGATION_ABORTED=4]="NAVIGATION_ABORTED",e[e.NAVIGATION_CANCELLED=8]="NAVIGATION_CANCELLED",e[e.NAVIGATION_DUPLICATED=16]="NAVIGATION_DUPLICATED",e})({});const hl=Symbol("");Ge.MATCHER_NOT_FOUND+"",Ge.NAVIGATION_GUARD_REDIRECT+"",Ge.NAVIGATION_ABORTED+"",Ge.NAVIGATION_CANCELLED+"",Ge.NAVIGATION_DUPLICATED+"";function Fn(e,t){return xe(new Error,{type:e,[hl]:!0},t)}function Vt(e,t){return e instanceof Error&&hl in e&&(t==null||!!(e.type&t))}const df=["params","query","hash"];function ff(e){if(typeof e=="string")return e;if(e.path!=null)return e.path;const t={};for(const n of df)n in e&&(t[n]=e[n]);return JSON.stringify(t,null,2)}function pf(e){const t={};if(e===""||e==="?")return t;const n=(e[0]==="?"?e.slice(1):e).split("&");for(let s=0;sa&&Va(a)):[s&&Va(s)]).forEach(a=>{a!==void 0&&(t+=(t.length?"&":"")+n,a!=null&&(t+="="+a))})}return t}function vf(e){const t={};for(const n in e){const s=e[n];s!==void 0&&(t[n]=Et(s)?s.map(a=>a==null?null:""+a):s==null?s:""+s)}return t}const gf=Symbol(""),wi=Symbol(""),na=Symbol(""),hr=Symbol(""),qa=Symbol("");function Hn(){let e=[];function t(s){return e.push(s),()=>{const a=e.indexOf(s);a>-1&&e.splice(a,1)}}function n(){e=[]}return{add:t,list:()=>e.slice(),reset:n}}function rn(e,t,n,s,a,r=o=>o()){const o=s&&(s.enterCallbacks[a]=s.enterCallbacks[a]||[]);return()=>new Promise((i,l)=>{const u=f=>{f===!1?l(Fn(Ge.NAVIGATION_ABORTED,{from:n,to:t})):f instanceof Error?l(f):cf(f)?l(Fn(Ge.NAVIGATION_GUARD_REDIRECT,{from:t,to:f})):(o&&s.enterCallbacks[a]===o&&typeof f=="function"&&o.push(f),i())},c=r(()=>e.call(s&&s.instances[a],t,n,u));let d=Promise.resolve(c);e.length<3&&(d=d.then(u)),d.catch(f=>l(f))})}function wa(e,t,n,s,a=r=>r()){const r=[];for(const o of e)for(const i in o.components){let l=o.components[i];if(!(t!=="beforeRouteEnter"&&!o.instances[i]))if(ll(l)){const u=(l.__vccOpts||l)[t];u&&r.push(rn(u,n,s,o,i,a))}else{let u=l();r.push(()=>u.then(c=>{if(!c)throw new Error(`Couldn't resolve component "${i}" at "${o.path}"`);const d=Fd(c)?c.default:c;o.mods[i]=c,o.components[i]=d;const f=(d.__vccOpts||d)[t];return f&&rn(f,n,s,o,i,a)()}))}}return r}function hf(e,t){const n=[],s=[],a=[],r=Math.max(t.matched.length,e.matched.length);for(let o=0;oOn(u,i))?s.push(i):n.push(i));const l=e.matched[o];l&&(t.matched.find(u=>On(u,l))||a.push(l))}return[n,s,a]}/*! - * vue-router v4.6.4 - * (c) 2025 Eduardo San Martin Morote - * @license MIT - */let mf=()=>location.protocol+"//"+location.host;function ml(e,t){const{pathname:n,search:s,hash:a}=t,r=e.indexOf("#");if(r>-1){let o=a.includes(e.slice(r))?e.slice(r).length:1,i=a.slice(o);return i[0]!=="/"&&(i="/"+i),mi(i,"")}return mi(n,e)+s+a}function yf(e,t,n,s){let a=[],r=[],o=null;const i=({state:f})=>{const h=ml(e,location),g=n.value,y=t.value;let m=0;if(f){if(n.value=h,t.value=f,o&&o===g){o=null;return}m=y?f.position-y.position:0}else s(h);a.forEach(P=>{P(n.value,g,{delta:m,type:Ha.pop,direction:m?m>0?ba.forward:ba.back:ba.unknown})})};function l(){o=n.value}function u(f){a.push(f);const h=()=>{const g=a.indexOf(f);g>-1&&a.splice(g,1)};return r.push(h),h}function c(){if(document.visibilityState==="hidden"){const{history:f}=window;if(!f.state)return;f.replaceState(xe({},f.state,{scroll:ta()}),"")}}function d(){for(const f of r)f();r=[],window.removeEventListener("popstate",i),window.removeEventListener("pagehide",c),document.removeEventListener("visibilitychange",c)}return window.addEventListener("popstate",i),window.addEventListener("pagehide",c),document.addEventListener("visibilitychange",c),{pauseListeners:l,listen:u,destroy:d}}function Si(e,t,n,s=!1,a=!1){return{back:e,current:t,forward:n,replaced:s,position:window.history.length,scroll:a?ta():null}}function _f(e){const{history:t,location:n}=window,s={value:ml(e,n)},a={value:t.state};a.value||r(s.value,{back:null,current:s.value,forward:null,position:t.length-1,replaced:!0,scroll:null},!0);function r(l,u,c){const d=e.indexOf("#"),f=d>-1?(n.host&&document.querySelector("base")?e:e.slice(d))+l:mf()+e+l;try{t[c?"replaceState":"pushState"](u,"",f),a.value=u}catch(h){console.error(h),n[c?"replace":"assign"](f)}}function o(l,u){r(l,xe({},t.state,Si(a.value.back,l,a.value.forward,!0),u,{position:a.value.position}),!0),s.value=l}function i(l,u){const c=xe({},a.value,t.state,{forward:l,scroll:ta()});r(c.current,c,!0),r(l,xe({},Si(s.value,l,null),{position:c.position+1},u),!1),s.value=l}return{location:s,state:a,push:i,replace:o}}function bf(e){e=nf(e);const t=_f(e),n=yf(e,t.state,t.location,t.replace);function s(r,o=!0){o||n.pauseListeners(),history.go(r)}const a=xe({location:"",base:e,go:s,createHref:af.bind(null,e)},t,n);return Object.defineProperty(a,"location",{enumerable:!0,get:()=>t.location.value}),Object.defineProperty(a,"state",{enumerable:!0,get:()=>t.state.value}),a}function wf(e){return e=location.host?e||location.pathname+location.search:"",e.includes("#")||(e+="#"),bf(e)}let gn=(function(e){return e[e.Static=0]="Static",e[e.Param=1]="Param",e[e.Group=2]="Group",e})({});var Je=(function(e){return e[e.Static=0]="Static",e[e.Param=1]="Param",e[e.ParamRegExp=2]="ParamRegExp",e[e.ParamRegExpEnd=3]="ParamRegExpEnd",e[e.EscapeNext=4]="EscapeNext",e})(Je||{});const Sf={type:gn.Static,value:""},kf=/[a-zA-Z0-9_]/;function Af(e){if(!e)return[[]];if(e==="/")return[[Sf]];if(!e.startsWith("/"))throw new Error(`Invalid path "${e}"`);function t(h){throw new Error(`ERR (${n})/"${u}": ${h}`)}let n=Je.Static,s=n;const a=[];let r;function o(){r&&a.push(r),r=[]}let i=0,l,u="",c="";function d(){u&&(n===Je.Static?r.push({type:gn.Static,value:u}):n===Je.Param||n===Je.ParamRegExp||n===Je.ParamRegExpEnd?(r.length>1&&(l==="*"||l==="+")&&t(`A repeatable param (${u}) must be alone in its segment. eg: '/:ids+.`),r.push({type:gn.Param,value:u,regexp:c,repeatable:l==="*"||l==="+",optional:l==="*"||l==="?"})):t("Invalid state to consume buffer"),u="")}function f(){u+=l}for(;it.length?t.length===1&&t[0]===lt.Static+lt.Segment?1:-1:0}function yl(e,t){let n=0;const s=e.score,a=t.score;for(;n0&&t[t.length-1]<0}const $f={strict:!1,end:!0,sensitive:!1};function Tf(e,t,n){const s=Ef(Af(e.path),n),a=xe(s,{record:e,parent:t,children:[],alias:[]});return t&&!a.record.aliasOf==!t.record.aliasOf&&t.children.push(a),a}function Pf(e,t){const n=[],s=new Map;t=hi($f,t);function a(d){return s.get(d)}function r(d,f,h){const g=!h,y=Ci(d);y.aliasOf=h&&h.record;const m=hi(t,d),P=[y];if("alias"in d){const E=typeof d.alias=="string"?[d.alias]:d.alias;for(const F of E)P.push(Ci(xe({},y,{components:h?h.record.components:y.components,path:F,aliasOf:h?h.record:y})))}let _,S;for(const E of P){const{path:F}=E;if(f&&F[0]!=="/"){const I=f.record.path,T=I[I.length-1]==="/"?"":"/";E.path=f.record.path+(F&&T+F)}if(_=Tf(E,f,m),h?h.alias.push(_):(S=S||_,S!==_&&S.alias.push(_),g&&d.name&&!Ei(_)&&o(d.name)),_l(_)&&l(_),y.children){const I=y.children;for(let T=0;T{o(S)}:is}function o(d){if(gl(d)){const f=s.get(d);f&&(s.delete(d),n.splice(n.indexOf(f),1),f.children.forEach(o),f.alias.forEach(o))}else{const f=n.indexOf(d);f>-1&&(n.splice(f,1),d.record.name&&s.delete(d.record.name),d.children.forEach(o),d.alias.forEach(o))}}function i(){return n}function l(d){const f=Df(d,n);n.splice(f,0,d),d.record.name&&!Ei(d)&&s.set(d.record.name,d)}function u(d,f){let h,g={},y,m;if("name"in d&&d.name){if(h=s.get(d.name),!h)throw Fn(Ge.MATCHER_NOT_FOUND,{location:d});m=h.record.name,g=xe(xi(f.params,h.keys.filter(S=>!S.optional).concat(h.parent?h.parent.keys.filter(S=>S.optional):[]).map(S=>S.name)),d.params&&xi(d.params,h.keys.map(S=>S.name))),y=h.stringify(g)}else if(d.path!=null)y=d.path,h=n.find(S=>S.re.test(y)),h&&(g=h.parse(y),m=h.record.name);else{if(h=f.name?s.get(f.name):n.find(S=>S.re.test(f.path)),!h)throw Fn(Ge.MATCHER_NOT_FOUND,{location:d,currentLocation:f});m=h.record.name,g=xe({},f.params,d.params),y=h.stringify(g)}const P=[];let _=h;for(;_;)P.unshift(_.record),_=_.parent;return{name:m,path:y,params:g,matched:P,meta:If(P)}}e.forEach(d=>r(d));function c(){n.length=0,s.clear()}return{addRoute:r,resolve:u,removeRoute:o,clearRoutes:c,getRoutes:i,getRecordMatcher:a}}function xi(e,t){const n={};for(const s of t)s in e&&(n[s]=e[s]);return n}function Ci(e){const t={path:e.path,redirect:e.redirect,name:e.name,meta:e.meta||{},aliasOf:e.aliasOf,beforeEnter:e.beforeEnter,props:Lf(e),children:e.children||[],instances:{},leaveGuards:new Set,updateGuards:new Set,enterCallbacks:{},components:"components"in e?e.components||null:e.component&&{default:e.component}};return Object.defineProperty(t,"mods",{value:{}}),t}function Lf(e){const t={},n=e.props||!1;if("component"in e)t.default=n;else for(const s in e.components)t[s]=typeof n=="object"?n[s]:n;return t}function Ei(e){for(;e;){if(e.record.aliasOf)return!0;e=e.parent}return!1}function If(e){return e.reduce((t,n)=>xe(t,n.meta),{})}function Df(e,t){let n=0,s=t.length;for(;n!==s;){const r=n+s>>1;yl(e,t[r])<0?s=r:n=r+1}const a=Of(e);return a&&(s=t.lastIndexOf(a,s-1)),s}function Of(e){let t=e;for(;t=t.parent;)if(_l(t)&&yl(e,t)===0)return t}function _l({record:e}){return!!(e.name||e.components&&Object.keys(e.components).length||e.redirect)}function Ri(e){const t=mt(na),n=mt(hr),s=Q(()=>{const l=p(e.to);return t.resolve(l)}),a=Q(()=>{const{matched:l}=s.value,{length:u}=l,c=l[u-1],d=n.matched;if(!c||!d.length)return-1;const f=d.findIndex(On.bind(null,c));if(f>-1)return f;const h=$i(l[u-2]);return u>1&&$i(c)===h&&d[d.length-1].path!==h?d.findIndex(On.bind(null,l[u-2])):f}),r=Q(()=>a.value>-1&&Bf(n.params,s.value.params)),o=Q(()=>a.value>-1&&a.value===n.matched.length-1&&vl(n.params,s.value.params));function i(l={}){if(Uf(l)){const u=t[p(e.replace)?"replace":"push"](p(e.to)).catch(is);return e.viewTransition&&typeof document<"u"&&"startViewTransition"in document&&document.startViewTransition(()=>u),u}return Promise.resolve()}return{route:s,href:Q(()=>s.value.href),isActive:r,isExactActive:o,navigate:i}}function Ff(e){return e.length===1?e[0]:e}const Nf=qe({name:"RouterLink",compatConfig:{MODE:3},props:{to:{type:[String,Object],required:!0},replace:Boolean,activeClass:String,exactActiveClass:String,custom:Boolean,ariaCurrentValue:{type:String,default:"page"},viewTransition:Boolean},useLink:Ri,setup(e,{slots:t}){const n=Zt(Ri(e)),{options:s}=mt(na),a=Q(()=>({[Ti(e.activeClass,s.linkActiveClass,"router-link-active")]:n.isActive,[Ti(e.exactActiveClass,s.linkExactActiveClass,"router-link-exact-active")]:n.isExactActive}));return()=>{const r=t.default&&Ff(t.default(n));return e.custom?r:V("a",{"aria-current":n.isExactActive?e.ariaCurrentValue:null,href:n.href,onClick:n.navigate,class:a.value},r)}}}),Mf=Nf;function Uf(e){if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)&&!e.defaultPrevented&&!(e.button!==void 0&&e.button!==0)){if(e.currentTarget&&e.currentTarget.getAttribute){const t=e.currentTarget.getAttribute("target");if(/\b_blank\b/i.test(t))return}return e.preventDefault&&e.preventDefault(),!0}}function Bf(e,t){for(const n in t){const s=t[n],a=e[n];if(typeof s=="string"){if(s!==a)return!1}else if(!Et(a)||a.length!==s.length||s.some((r,o)=>r.valueOf()!==a[o].valueOf()))return!1}return!0}function $i(e){return e?e.aliasOf?e.aliasOf.path:e.path:""}const Ti=(e,t,n)=>e??t??n,jf=qe({name:"RouterView",inheritAttrs:!1,props:{name:{type:String,default:"default"},route:Object},compatConfig:{MODE:3},setup(e,{attrs:t,slots:n}){const s=mt(qa),a=Q(()=>e.route||s.value),r=mt(wi,0),o=Q(()=>{let u=p(r);const{matched:c}=a.value;let d;for(;(d=c[u])&&!d.components;)u++;return u}),i=Q(()=>a.value.matched[o.value]);ts(wi,Q(()=>o.value+1)),ts(gf,i),ts(qa,a);const l=J();return At(()=>[l.value,i.value,e.name],([u,c,d],[f,h,g])=>{c&&(c.instances[d]=u,h&&h!==c&&u&&u===f&&(c.leaveGuards.size||(c.leaveGuards=h.leaveGuards),c.updateGuards.size||(c.updateGuards=h.updateGuards))),u&&c&&(!h||!On(c,h)||!f)&&(c.enterCallbacks[d]||[]).forEach(y=>y(u))},{flush:"post"}),()=>{const u=a.value,c=e.name,d=i.value,f=d&&d.components[c];if(!f)return Pi(n.default,{Component:f,route:u});const h=d.props[c],g=h?h===!0?u.params:typeof h=="function"?h(u):h:null,m=V(f,xe({},g,t,{onVnodeUnmounted:P=>{P.component.isUnmounted&&(d.instances[c]=null)},ref:l}));return Pi(n.default,{Component:m,route:u})||m}}});function Pi(e,t){if(!e)return null;const n=e(t);return n.length===1?n[0]:n}const bl=jf;function Vf(e){const t=Pf(e.routes,e),n=e.parseQuery||pf,s=e.stringifyQuery||bi,a=e.history,r=Hn(),o=Hn(),i=Hn(),l=bu(tn);let u=tn;Cn&&e.scrollBehavior&&"scrollRestoration"in history&&(history.scrollRestoration="manual");const c=ya.bind(null,M=>""+M),d=ya.bind(null,Jd),f=ya.bind(null,ps);function h(M,se){let $,x;return gl(M)?($=t.getRecordMatcher(M),x=se):x=M,t.addRoute(x,$)}function g(M){const se=t.getRecordMatcher(M);se&&t.removeRoute(se)}function y(){return t.getRoutes().map(M=>M.record)}function m(M){return!!t.getRecordMatcher(M)}function P(M,se){if(se=xe({},se||l.value),typeof M=="string"){const C=_a(n,M,se.path),j=t.resolve({path:C.path},se),z=a.createHref(C.fullPath);return xe(C,j,{params:f(j.params),hash:ps(C.hash),redirectedFrom:void 0,href:z})}let $;if(M.path!=null)$=xe({},M,{path:_a(n,M.path,se.path).path});else{const C=xe({},M.params);for(const j in C)C[j]==null&&delete C[j];$=xe({},M,{params:d(C)}),se.params=d(se.params)}const x=t.resolve($,se),ee=M.hash||"";x.params=c(f(x.params));const v=Zd(s,xe({},M,{hash:zd(ee),path:x.path})),b=a.createHref(v);return xe({fullPath:v,hash:ee,query:s===bi?vf(M.query):M.query||{}},x,{redirectedFrom:void 0,href:b})}function _(M){return typeof M=="string"?_a(n,M,l.value.path):xe({},M)}function S(M,se){if(u!==M)return Fn(Ge.NAVIGATION_CANCELLED,{from:se,to:M})}function E(M){return T(M)}function F(M){return E(xe(_(M),{replace:!0}))}function I(M,se){const $=M.matched[M.matched.length-1];if($&&$.redirect){const{redirect:x}=$;let ee=typeof x=="function"?x(M,se):x;return typeof ee=="string"&&(ee=ee.includes("?")||ee.includes("#")?ee=_(ee):{path:ee},ee.params={}),xe({query:M.query,hash:M.hash,params:ee.path!=null?{}:M.params},ee)}}function T(M,se){const $=u=P(M),x=l.value,ee=M.state,v=M.force,b=M.replace===!0,C=I($,x);if(C)return T(xe(_(C),{state:typeof C=="object"?xe({},ee,C.state):ee,force:v,replace:b}),se||$);const j=$;j.redirectedFrom=se;let z;return!v&&Qd(s,x,$)&&(z=Fn(Ge.NAVIGATION_DUPLICATED,{to:j,from:x}),Ee(x,x,!0,!1)),(z?Promise.resolve(z):Z(j,x)).catch(H=>Vt(H)?Vt(H,Ge.NAVIGATION_GUARD_REDIRECT)?H:Se(H):te(H,j,x)).then(H=>{if(H){if(Vt(H,Ge.NAVIGATION_GUARD_REDIRECT))return T(xe({replace:b},_(H.to),{state:typeof H.to=="object"?xe({},ee,H.to.state):ee,force:v}),se||j)}else H=de(j,x,!0,b,ee);return ue(j,x,H),H})}function A(M,se){const $=S(M,se);return $?Promise.reject($):Promise.resolve()}function R(M){const se=je.values().next().value;return se&&typeof se.runWithContext=="function"?se.runWithContext(M):M()}function Z(M,se){let $;const[x,ee,v]=hf(M,se);$=wa(x.reverse(),"beforeRouteLeave",M,se);for(const C of x)C.leaveGuards.forEach(j=>{$.push(rn(j,M,se))});const b=A.bind(null,M,se);return $.push(b),Te($).then(()=>{$=[];for(const C of r.list())$.push(rn(C,M,se));return $.push(b),Te($)}).then(()=>{$=wa(ee,"beforeRouteUpdate",M,se);for(const C of ee)C.updateGuards.forEach(j=>{$.push(rn(j,M,se))});return $.push(b),Te($)}).then(()=>{$=[];for(const C of v)if(C.beforeEnter)if(Et(C.beforeEnter))for(const j of C.beforeEnter)$.push(rn(j,M,se));else $.push(rn(C.beforeEnter,M,se));return $.push(b),Te($)}).then(()=>(M.matched.forEach(C=>C.enterCallbacks={}),$=wa(v,"beforeRouteEnter",M,se,R),$.push(b),Te($))).then(()=>{$=[];for(const C of o.list())$.push(rn(C,M,se));return $.push(b),Te($)}).catch(C=>Vt(C,Ge.NAVIGATION_CANCELLED)?C:Promise.reject(C))}function ue(M,se,$){i.list().forEach(x=>R(()=>x(M,se,$)))}function de(M,se,$,x,ee){const v=S(M,se);if(v)return v;const b=se===tn,C=Cn?history.state:{};$&&(x||b?a.replace(M.fullPath,xe({scroll:b&&C&&C.scroll},ee)):a.push(M.fullPath,ee)),l.value=M,Ee(M,se,$,b),Se()}let pe;function B(){pe||(pe=a.listen((M,se,$)=>{if(!Ve.listening)return;const x=P(M),ee=I(x,Ve.currentRoute.value);if(ee){T(xe(ee,{replace:!0,force:!0}),x).catch(is);return}u=x;const v=l.value;Cn&&lf(_i(v.fullPath,$.delta),ta()),Z(x,v).catch(b=>Vt(b,Ge.NAVIGATION_ABORTED|Ge.NAVIGATION_CANCELLED)?b:Vt(b,Ge.NAVIGATION_GUARD_REDIRECT)?(T(xe(_(b.to),{force:!0}),x).then(C=>{Vt(C,Ge.NAVIGATION_ABORTED|Ge.NAVIGATION_DUPLICATED)&&!$.delta&&$.type===Ha.pop&&a.go(-1,!1)}).catch(is),Promise.reject()):($.delta&&a.go(-$.delta,!1),te(b,x,v))).then(b=>{b=b||de(x,v,!1),b&&($.delta&&!Vt(b,Ge.NAVIGATION_CANCELLED)?a.go(-$.delta,!1):$.type===Ha.pop&&Vt(b,Ge.NAVIGATION_ABORTED|Ge.NAVIGATION_DUPLICATED)&&a.go(-1,!1)),ue(x,v,b)}).catch(is)}))}let q=Hn(),X=Hn(),W;function te(M,se,$){Se(M);const x=X.list();return x.length?x.forEach(ee=>ee(M,se,$)):console.error(M),Promise.reject(M)}function ve(){return W&&l.value!==tn?Promise.resolve():new Promise((M,se)=>{q.add([M,se])})}function Se(M){return W||(W=!M,B(),q.list().forEach(([se,$])=>M?$(M):se()),q.reset()),M}function Ee(M,se,$,x){const{scrollBehavior:ee}=e;if(!Cn||!ee)return Promise.resolve();const v=!$&&uf(_i(M.fullPath,0))||(x||!$)&&history.state&&history.state.scroll||null;return _n().then(()=>ee(M,se,v)).then(b=>b&&of(b)).catch(b=>te(b,M,se))}const we=M=>a.go(M);let Me;const je=new Set,Ve={currentRoute:l,listening:!0,addRoute:h,removeRoute:g,clearRoutes:t.clearRoutes,hasRoute:m,getRoutes:y,resolve:P,options:e,push:E,replace:F,go:we,back:()=>we(-1),forward:()=>we(1),beforeEach:r.add,beforeResolve:o.add,afterEach:i.add,onError:X.add,isReady:ve,install(M){M.component("RouterLink",Mf),M.component("RouterView",bl),M.config.globalProperties.$router=Ve,Object.defineProperty(M.config.globalProperties,"$route",{enumerable:!0,get:()=>p(l)}),Cn&&!Me&&l.value===tn&&(Me=!0,E(a.location).catch(x=>{}));const se={};for(const x in tn)Object.defineProperty(se,x,{get:()=>l.value[x],enumerable:!0});M.provide(na,Ve),M.provide(hr,_o(se)),M.provide(qa,l);const $=M.unmount;je.add(M),M.unmount=function(){je.delete(M),je.size<1&&(u=tn,pe&&pe(),pe=null,l.value=tn,Me=!1,W=!1),$()}}};function Te(M){return M.reduce((se,$)=>se.then(()=>R($)),Promise.resolve())}return Ve}function en(){return mt(na)}function sa(e){return mt(hr)}var Hf={},Gf=new Set(["primary","secondary","accent","success","warning","danger","error","info"]);function Oe(...e){return e.flatMap(t=>t?Array.isArray(t)?t:typeof t=="object"?Object.entries(t).filter(([,n])=>n).map(([n])=>n):[t]:[]).filter(Boolean).join(" ")}function Mn(e,t="primary"){return Gf.has(e)?e:t}function Ye(e,t=""){if(!e)return null;const n=e.includes("ph ")||e.startsWith("ph-");n||typeof process<"u"&&Hf&&console.warn(`[gnexus-ui-kit] Icon "${e}" is missing the required "ph-" prefix. Use "ph-${e}" instead.`);const s=n?e:`ph-${e}`;return V("i",{class:Oe("ph",s,t),"aria-hidden":"true"})}function wl(e){const t=e.target;return t.type==="checkbox"?t.checked:t.value}var qf=["a[href]","button:not([disabled])","input:not([disabled])","select:not([disabled])","textarea:not([disabled])","[tabindex]:not([tabindex='-1'])"].join(",");function zf(e,t){if(e.key!=="Tab"||!t)return;const n=[...t.querySelectorAll(qf)].filter(r=>!r.hasAttribute("disabled")&&r.offsetParent!==null);if(!n.length){e.preventDefault(),t.focus();return}const s=n[0],a=n[n.length-1];e.shiftKey&&document.activeElement===s?(e.preventDefault(),a.focus()):!e.shiftKey&&document.activeElement===a&&(e.preventDefault(),s.focus())}var Kf=qe({name:"GnActionCard",props:{kicker:{type:String,default:""},title:{type:String,required:!0},text:{type:String,default:""}},setup(e,{slots:t}){return()=>{var n,s,a;return V("article",{class:"card action-card"},[V("div",{class:"card-content"},[(e.kicker||t.kicker)&&V("span",{class:"action-card-kicker"},((n=t.kicker)==null?void 0:n.call(t))||e.kicker),V("h3",{class:"action-card-title"},((s=t.title)==null?void 0:s.call(t))||e.title),(e.text||t.default)&&V("p",{class:"action-card-text"},((a=t.default)==null?void 0:a.call(t))||e.text),t.actions&&V("div",{class:"action-card-actions"},t.actions())])])}}}),Ze=qe({name:"GnAlert",inheritAttrs:!1,props:{variant:{type:String,default:"primary"},role:{type:String,default:"status"}},setup(e,{attrs:t,slots:n}){return()=>{var s;const a=Mn(e.variant);return V("div",{...t,role:e.role,class:Oe("alert",`alert-${a}`,t.class)},(s=n.default)==null?void 0:s.call(n))}}}),Wf=qe({name:"GnAvatar",inheritAttrs:!1,props:{src:{type:String,default:""},alt:{type:String,default:""},initials:{type:String,default:""},icon:{type:String,default:""},size:{type:String,default:"md"},variant:{type:String,default:"primary"},outline:{type:Boolean,default:!1},status:{type:String,default:""}},setup(e,{attrs:t}){return()=>{const n=Mn(e.variant);return V("span",{...t,class:Oe("avatar",`avatar-${n}`,{"avatar-sm":e.size==="sm","avatar-lg":e.size==="lg","avatar-outline":e.outline,"is-online":e.status==="online","is-busy":e.status==="busy","is-offline":e.status==="offline"},t.class)},[e.src?V("img",{src:e.src,alt:e.alt}):Ye(e.icon)||e.initials,e.status&&V("span",{class:"avatar-status","aria-hidden":"true"})])}}}),_e=qe({name:"GnBadge",inheritAttrs:!1,props:{variant:{type:String,default:"primary"},outline:{type:Boolean,default:!1}},setup(e,{attrs:t,slots:n}){return()=>{var s;const a=Mn(e.variant);return V("span",{...t,class:Oe("badge",e.outline&&a==="primary"?"badge-primary-outline":`badge-${a}`,t.class)},(s=n.default)==null?void 0:s.call(n))}}}),ge=qe({name:"GnButton",inheritAttrs:!1,props:{variant:{type:String,default:"primary"},size:{type:String,default:"md"},icon:{type:String,default:""},loading:{type:Boolean,default:!1},disabled:{type:Boolean,default:!1},type:{type:String,default:"button"}},setup(e,{attrs:t,slots:n}){return()=>{var s;const a=!!(e.icon||e.loading),r=Mn(e.variant);return V("button",{...t,type:e.type,disabled:e.disabled||e.loading,class:Oe("btn",`btn-${r}`,{"btn-small":e.size==="sm","btn-large":e.size==="lg","with-icon":a,"loading-state":e.loading},t.class)},[e.loading?Ye("ph-bold ph-spinner"):Ye(e.icon),(s=n.default)==null?void 0:s.call(n)])}}}),Li=qe({name:"GnChip",inheritAttrs:!1,props:{variant:{type:String,default:""},icon:{type:String,default:""},selected:{type:Boolean,default:!1},disabled:{type:Boolean,default:!1},removable:{type:Boolean,default:!1},clickable:{type:Boolean,default:!1}},emits:["remove"],setup(e,{attrs:t,emit:n,slots:s}){return()=>{var a,r,o,i;const l=e.clickable?"button":"span",u=e.variant?Mn(e.variant):"",c=(o=(r=(a=s.default)==null?void 0:a.call(s))==null?void 0:r[0])==null?void 0:o.children;return V(l,{...t,type:l==="button"?"button":void 0,disabled:l==="button"?e.disabled:void 0,"aria-pressed":l==="button"?String(e.selected):void 0,class:Oe("chip",u&&`chip-${u}`,{"chip-selected":e.selected,"chip-disabled":e.disabled},t.class)},[Ye(e.icon),(i=s.default)==null?void 0:i.call(s),e.removable&&V("button",{class:"chip-remove",type:"button","aria-label":c?`Remove ${c}`:"Remove",onClick:d=>{d.stopPropagation(),n("remove")}},[Ye("ph-x")])])}}}),Jf=0,ut=qe({name:"GnModal",props:{open:{type:Boolean,default:!1},title:{type:String,default:""},closeOnBackdrop:{type:Boolean,default:!0}},emits:["update:open","close"],setup(e,{emit:t,slots:n}){const s=`gn-modal-title-${++Jf}`,a=J(null),r=J(!1),o=J(!1);let i=null,l=null;const u=()=>{t("update:open",!1),t("close")},c=f=>{f.key==="Escape"?(f.preventDefault(),u()):zf(f,a.value)},d=()=>{_n(()=>{var f;(f=a.value)==null||f.focus()})};return At(()=>e.open,f=>{var h;f?(o.value=!0,r.value=!0,_n(()=>{requestAnimationFrame(()=>{o.value=!1})}),i=document.activeElement,document.addEventListener("keydown",c),d()):(o.value=!0,document.removeEventListener("keydown",c),(h=i==null?void 0:i.focus)==null||h.call(i),i=null,l=window.setTimeout(()=>{r.value=!1,o.value=!1},300))},{flush:"post"}),Ws(()=>{document.removeEventListener("keydown",c),window.clearTimeout(l)}),()=>{var f,h,g;return r.value?V(ju,{to:"body"},[V("div",{class:Oe("modal",o.value?"a-hide":"a-show"),"aria-hidden":"false"},[V("div",{class:"modal-backdrop",onClick:()=>e.closeOnBackdrop&&u()}),V("div",{ref:a,class:"modal-dialog",role:"dialog","aria-modal":"true","aria-labelledby":s,tabindex:"-1"},[V("header",{class:"modal-header"},[V("h4",{class:"modal-title",id:s},((f=n.title)==null?void 0:f.call(n))||e.title),V("button",{class:"btn-icon modal-close",type:"button","aria-label":"Close",onClick:u},[Ye("ph-x")])]),V("div",{class:"modal-panel"},[V("div",{class:"modal-body"},(h=n.default)==null?void 0:h.call(n)),(n.footer||n.actions)&&V("footer",{class:"modal-footer"},[(g=n.footer)==null?void 0:g.call(n),n.actions&&V("div",{class:"actions"},n.actions({close:u}))])])])])]):null}}}),Yf=qe({name:"GnCopyButton",props:{text:{type:String,required:!0},icon:{type:String,default:"ph-copy"},successIcon:{type:String,default:"ph-check"},duration:{type:Number,default:3e3},label:{type:String,default:"Copy"},size:{type:String,default:null}},emits:["copy"],setup(e,{emit:t}){const n=J(!1);let s=null;const a=async()=>{try{await navigator.clipboard.writeText(e.text)}catch{const o=document.createElement("textarea");o.value=e.text,o.style.position="fixed",o.style.opacity="0",document.body.appendChild(o),o.select(),document.execCommand("copy"),document.body.removeChild(o)}n.value=!0,window.clearTimeout(s),s=window.setTimeout(()=>{n.value=!1},e.duration),t("copy",e.text)};return()=>V("button",{class:Oe("btn-icon",{"btn-icon-sm":e.size==="sm"}),type:"button","aria-label":e.label,onClick:a},[Ye(n.value?e.successIcon:e.icon)])}}),Xf=qe({name:"GnDropdown",props:{label:{type:String,default:"Actions"},icon:{type:String,default:"ph-dots-three-outline"},variant:{type:String,default:"secondary"},items:{type:Array,default:()=>[]}},emits:["select"],setup(e,{emit:t,slots:n}){const s=J(!1),a=J(null),r=()=>{s.value=!1,document.removeEventListener("click",o),document.removeEventListener("keydown",i)},o=c=>{a.value&&!a.value.contains(c.target)&&r()},i=c=>{c.key==="Escape"&&(c.preventDefault(),r())},l=()=>{s.value=!s.value,s.value?(setTimeout(()=>document.addEventListener("click",o),0),document.addEventListener("keydown",i)):r()},u=c=>{var d;c.disabled||((d=c.onSelect)==null||d.call(c,c),t("select",c),r())};return Ws(r),()=>{var c,d;return V("div",{ref:a,class:Oe("dropdown",{"is-open":s.value})},[((c=n.trigger)==null?void 0:c.call(n,{open:s.value,toggle:l}))||V(ge,{variant:e.variant,icon:e.icon,"aria-expanded":s.value?"true":"false",onClick:l},()=>e.label),V("div",{class:"dropdown-menu",role:"menu"},((d=n.default)==null?void 0:d.call(n,{close:r}))||e.items.map(f=>V("button",{class:Oe("dropdown-item",f.danger&&"dropdown-item-danger"),type:"button",role:"menuitem",disabled:f.disabled,onClick:()=>u(f)},[Ye(f.icon),f.label])))])}}}),Zf=qe({name:"GnEmptyState",inheritAttrs:!1,props:{title:{type:String,required:!0},text:{type:String,default:""},icon:{type:String,default:"ph-package"},variant:{type:String,default:""}},setup(e,{attrs:t,slots:n}){return()=>{var s,a;return V("div",{...t,class:Oe("empty-state",e.variant&&`empty-state-${e.variant}`,t.class)},[V("div",{class:"empty-state-icon"},[Ye(e.icon)]),V("h3",{class:"empty-state-title"},((s=n.title)==null?void 0:s.call(n))||e.title),(e.text||n.default)&&V("p",{class:"empty-state-text"},((a=n.default)==null?void 0:a.call(n))||e.text),n.actions&&V("div",{class:"empty-state-actions"},n.actions())])}}}),xt=qe({name:"GnInput",inheritAttrs:!1,props:{modelValue:{type:[String,Number],default:""},label:{type:String,default:""},type:{type:String,default:"text"},icon:{type:String,default:""},state:{type:String,default:""},help:{type:String,default:""},bare:{type:Boolean,default:!1}},emits:["update:modelValue"],setup(e,{attrs:t,emit:n}){return()=>{const s=V("input",{...t,type:e.type,value:e.modelValue,class:Oe(e.bare?"":"input",t.class),onInput:a=>n("update:modelValue",wl(a))});return e.bare?s:V("div",{class:"form-group"},[V("label",{class:Oe("label",e.state)},[e.label,Ye(e.icon),s]),e.help&&V("div",{class:Oe("input-info",e.state==="error"&&"error")},e.help)])}}}),Sl=qe({name:"GnLoader",inheritAttrs:!1,props:{circle:{type:Boolean,default:!1},label:{type:String,default:"Loading"}},setup(e,{attrs:t}){return()=>e.circle?V("div",{...t,class:Oe("circle-loader",t.class)},[Ye("ph-bold ph-spinner normalize"),e.label]):V("div",{...t,class:Oe("loader",t.class),role:"status","aria-label":e.label})}});function Qf(){var e;const t=Zs();return((e=t==null?void 0:t.proxy)==null?void 0:e.$router)||null}function ep(){var e;const t=Zs();return((e=t==null?void 0:t.proxy)==null?void 0:e.$route)||null}function tp(e,t,n="prefix"){if(!e)return!1;const s=e.value||e;return typeof t=="string"?n==="exact"?s.path===t:s.path===t||s.path.startsWith(t+"/"):t.path?n==="exact"?s.path===t.path:s.path===t.path||s.path.startsWith(t.path+"/"):t.name?s.name===t.name:!1}var np=qe({name:"GnNavList",inheritAttrs:!1,props:{items:{type:Array,default:()=>[]},activeMatch:{type:String,default:"prefix"}},emits:["select"],setup(e,{attrs:t,emit:n,slots:s}){const a=Qf(),r=ep(),o=!!(a&&r),i=u=>{if(u){if(typeof u=="string")return u;if(u.path)return u.path}},l=Q(()=>e.items.map(u=>{const c=!!u.to,d=c?o?a.resolve(u.to).href:i(u.to):u.href,f=c&&o?tp(r,u.to,e.activeMatch):!!u.active;return{...u,resolvedHref:d,isActive:f,hasTo:c}}));return()=>V("ul",{...t,class:Oe("list list-nav",t.class)},l.value.map(u=>{var c,d;return V("li",{class:Oe("list-item",{"list-item-active":u.isActive})},[V(u.resolvedHref?"a":"button",{class:"list-action",href:u.resolvedHref,type:u.resolvedHref?void 0:"button",onClick:f=>{var h;u.hasTo&&o&&(f.preventDefault(),a.push(u.to)),(h=u.onSelect)==null||h.call(u,u,f),n("select",u)}},[V("span",{class:"list-label"},[Ye(u.icon),((c=s.label)==null?void 0:c.call(s,{item:u}))||u.label]),(u.meta||s.meta)&&V("span",{class:"list-meta"},((d=s.meta)==null?void 0:d.call(s,{item:u}))||u.meta)])])}))}}),sp=0,ap=qe({name:"GnNavigationShell",props:{brand:{type:String,default:"GNexus UI Kit"},logoSrc:{type:String,default:"/assets/imgs/gnexus-mark.svg"},current:{type:String,default:""},title:{type:String,default:"Sections"},subtitle:{type:String,default:"Navigation"},footerLeft:{type:String,default:""},footerRight:{type:String,default:""},items:{type:Array,default:()=>[]},activeMatch:{type:String,default:"prefix"}},emits:["select"],setup(e,{emit:t,slots:n}){const s=J(!1),a=`gn-nav-drawer-${++sp}`,r=J(null);let o=null;const i=()=>{s.value=!1},l=()=>{s.value=!s.value},u=c=>{c.key==="Escape"&&(c.preventDefault(),i())};return At(s,c=>{var d;c?(o=document.activeElement,document.body.classList.add("nav-drawer-open"),document.addEventListener("keydown",u),_n(()=>{var f;return(f=r.value)==null?void 0:f.focus()})):(document.body.classList.remove("nav-drawer-open"),document.removeEventListener("keydown",u),(d=o==null?void 0:o.focus)==null||d.call(o),o=null)}),Ws(()=>{document.body.classList.remove("nav-drawer-open"),document.removeEventListener("keydown",u)}),()=>{var c,d,f,h,g,y,m;return[V("header",{class:"nav-topbar"},[V("button",{class:"nav-topbar-toggle",type:"button","aria-controls":a,"aria-expanded":s.value?"true":"false",onClick:l},[Ye("ph-sidebar-simple"),V("span",{},"Menu")]),V("div",{class:"nav-topbar-brand"},[e.logoSrc&&V("img",{src:e.logoSrc,alt:"","aria-hidden":"true"}),V("span",{},((c=n.brand)==null?void 0:c.call(n))||e.brand)]),V("div",{class:"nav-topbar-current"},((d=n.current)==null?void 0:d.call(n))||e.current)]),V("div",{class:"nav-drawer-backdrop",onClick:i}),V("aside",{ref:r,class:["nav-drawer",{"is-open":s.value}],id:a,"aria-label":"Navigation","aria-hidden":s.value?"false":"true",tabindex:"-1"},[V("header",{class:"nav-drawer-header"},[V("div",{},[V("div",{class:"nav-drawer-title"},((f=n.title)==null?void 0:f.call(n))||e.title),V("div",{class:"nav-drawer-subtitle"},((h=n.subtitle)==null?void 0:h.call(n))||e.subtitle)]),V("button",{class:"nav-drawer-close",type:"button","aria-label":"Close navigation",onClick:i},[Ye("ph-x")])]),V("nav",{class:"nav-drawer-body"},[((g=n.default)==null?void 0:g.call(n,{close:i}))||V(np,{items:e.items,activeMatch:e.activeMatch,onSelect:P=>{t("select",P),i()}})]),(n.footer||e.footerLeft||e.footerRight)&&V("footer",{class:"nav-drawer-footer"},((y=n.footer)==null?void 0:y.call(n))||[V("span",{},e.footerLeft),V("span",{},e.footerRight)])]),(m=n.content)==null?void 0:m.call(n)]}}}),Rt=qe({name:"GnPageHeader",inheritAttrs:!1,props:{title:{type:String,required:!0},subtitle:{type:String,default:""},kicker:{type:String,default:""},compact:{type:Boolean,default:!1},accent:{type:Boolean,default:!1}},setup(e,{attrs:t,slots:n}){return()=>{var s,a,r;return V("header",{...t,class:Oe("page-header",{"page-header-compact":e.compact,"page-header-accent":e.accent},t.class)},[V("div",{class:"page-header-content"},[(e.kicker||n.kicker)&&V("div",{class:"page-header-kicker"},((s=n.kicker)==null?void 0:s.call(n))||e.kicker),V("h1",{class:"page-header-title"},((a=n.title)==null?void 0:a.call(n))||e.title),(e.subtitle||n.subtitle)&&V("p",{class:"page-header-subtitle"},((r=n.subtitle)==null?void 0:r.call(n))||e.subtitle),n.meta&&V("div",{class:"page-header-meta"},n.meta())]),n.actions&&V("div",{class:"page-header-actions"},n.actions())])}}}),mr=qe({name:"GnSelect",inheritAttrs:!1,props:{modelValue:{type:[String,Number],default:""},label:{type:String,default:""},icon:{type:String,default:""},state:{type:String,default:""},help:{type:String,default:""},options:{type:Array,default:()=>[]}},emits:["update:modelValue"],setup(e,{attrs:t,emit:n,slots:s}){const a=()=>e.options.map(r=>{const o=typeof r=="object"?r.value:r,i=typeof r=="object"?r.label:r;return V("option",{value:o},i)});return()=>{var r;return V("div",{class:"form-group"},[V("label",{class:Oe("label",e.state)},[e.label,Ye(e.icon),V("div",{class:"select-wrap"},[V("select",{...t,value:e.modelValue,class:Oe("input select",t.class),onChange:o=>n("update:modelValue",wl(o))},((r=s.default)==null?void 0:r.call(s))||a())])]),e.help&&V("div",{class:Oe("input-info",e.state==="error"&&"error")},e.help)])}}}),rp=qe({name:"GnSwitch",inheritAttrs:!1,props:{modelValue:{type:Boolean,default:!1},label:{type:String,default:""},disabled:{type:Boolean,default:!1}},emits:["update:modelValue"],setup(e,{attrs:t,emit:n,slots:s}){return()=>{var a;return V("label",{class:Oe("switch",t.class)},[V("input",{...t,type:"checkbox",checked:e.modelValue,disabled:e.disabled,onChange:r=>n("update:modelValue",r.target.checked)}),V("span",{class:"switch-control","aria-hidden":"true"}),V("span",{class:"switch-label"},((a=s.default)==null?void 0:a.call(s))||e.label)])}}}),Nn=qe({name:"GnTable",props:{columns:{type:Array,required:!0},rows:{type:Array,default:()=>[]},caption:{type:String,default:""},emptyText:{type:String,default:"Empty"}},setup(e,{attrs:t,slots:n}){return()=>{var s;return V("div",{class:"table-wrapper"},[V("table",{class:Oe("table data-list",{"table-empty":!e.rows.length},t.class)},[e.caption&&V("caption",{class:"table-caption"},e.caption),V("thead",{class:"table-head"},[V("tr",{class:"table-row"},e.columns.map(a=>V("th",{scope:"col"},a.label)))]),V("tbody",{class:"table-body"},e.rows.length?e.rows.map(a=>V("tr",{class:"table-row"},e.columns.map(r=>{var o;const i=`cell-${r.key}`;return V("td",{},((o=n[i])==null?void 0:o.call(n,{row:a,column:r,value:a[r.key]}))||a[r.key])}))):V("tr",{},[V("td",{class:"is-empty",colspan:e.columns.length},((s=n.empty)==null?void 0:s.call(n))||e.emptyText)]))])])}}}),kl=Symbol("gnexus-ui-kit-toast"),Ii={info:"ph-info",success:"ph-check-circle",warning:"ph-warning",danger:"ph-warning-octagon",error:"ph-warning-octagon",primary:"ph-info",secondary:"ph-info"},ip=qe({name:"GnToastProvider",props:{lifetime:{type:Number,default:4e3}},setup(e,{slots:t,expose:n}){const s=J(null),a=J(!1),r=J(!1);let o=null,i=null,l=null;const u=J(100),c=()=>{window.clearTimeout(i),window.clearInterval(l),a.value=!0,r.value=!1,i=window.setTimeout(()=>{s.value=null,a.value=!1,u.value=100,window.clearTimeout(o),o=null},300)},d=()=>{window.clearTimeout(i),window.clearTimeout(o),window.clearInterval(l),a.value=!1,r.value=!1,u.value=100,s.value=null},f=y=>{window.clearTimeout(i),window.clearInterval(l),a.value=!1,r.value=!1,u.value=100;const m=Mn(y.variant||y.type||"info","info"),P=y.lifetime!==void 0?y.lifetime:e.lifetime;if(s.value={id:Date.now(),variant:m==="error"?"danger":m,title:y.title||"",text:y.text||y.message||"",icon:y.icon||Ii[m]||Ii.info,lifetime:P},window.clearTimeout(o),P!==0){const S=P/100;u.value=100,l=window.setInterval(()=>{u.value-=100/S,u.value<=0&&window.clearInterval(l)},100),o=window.setTimeout(c,P)}_n(()=>{requestAnimationFrame(()=>{r.value=!0})})},h={show:f,close:d,info:y=>f({...y,variant:"info"}),success:y=>f({...y,variant:"success"}),warning:y=>f({...y,variant:"warning"}),danger:y=>f({...y,variant:"danger"}),error:y=>f({...y,variant:"danger"})};ts(kl,h),n(h);const g=()=>a.value?"a-hide":r.value?"a-show":"";return()=>{var y;return[(y=t.default)==null?void 0:y.call(t),s.value&&V("div",{class:Oe("toast",g(),`toast-${s.value.variant}`),role:"alert"},[V("div",{class:"toast-content"},[V("div",{class:"toast-header"},[Ye(s.value.icon),s.value.title]),s.value.text&&V("p",{class:"toast-text"},s.value.text)]),V("button",{class:"btn-icon toast-close",type:"button","aria-label":"Close",onClick:c},[Ye("ph-x")]),s.value.lifetime!==0&&V("div",{class:"toast-progress"},[V("div",{class:"toast-progress-bar",style:{transform:`scaleX(${Math.max(0,u.value/100)})`}})])])]}}}),op=qe({name:"GnUserCard",props:{name:{type:String,required:!0},email:{type:String,default:""},role:{type:String,default:""},avatar:{type:Object,default:()=>({})},href:{type:String,default:""},compact:{type:Boolean,default:!1},actions:{type:Array,default:()=>[]}},setup(e,{slots:t}){const n=()=>{var r;return((r=t.avatar)==null?void 0:r.call(t))||V(Wf,{...e.avatar,size:e.compact?"sm":"md"})},s=()=>V("span",{class:"identity"},[n(),V("span",{class:"identity-content"},[V("span",{class:"identity-title"},e.name),e.email&&V("span",{class:"identity-meta"},e.email)])]),a=()=>t.actions?t.actions():e.actions.length?V("div",{class:"user-card-actions"},e.actions.map(r=>{if(e.compact)return V("button",{class:"btn-icon",type:"button","aria-label":r.label,onClick:r.onClick},[Ye(r.icon)]);const o=!!r.icon,i=Oe("btn","btn-small",{[`btn-${r.variant}`]:r.variant,"btn-secondary":!r.variant,"with-icon":o});return V("button",{class:i,type:"button",onClick:r.onClick},[o&&Ye(r.icon),r.label])})):null;return()=>{const r=Oe("card","user-card",{"user-card-compact":e.compact}),o=[];e.href?o.push(V("a",{class:"profile-identity",href:e.href,target:"_blank",rel:"noopener noreferrer"},[s()])):o.push(s()),!e.compact&&e.role&&o.push(V("span",{class:"user-card-role"},e.role)),t.default&&!e.compact&&o.push(V("div",{class:"user-card-extra"},t.default()));const i=a();return i&&o.push(i),V("article",{class:r},[V("div",{class:"user-card-body"},o)])}}});function wn(){const e=mt(kl,null);if(e)return e;const t=()=>{throw new Error("GNexus UI Kit: useToast() requires near the app root.")};return{show:t,info:t,success:t,warning:t,danger:t,error:t,close:t}}const Sa=ys("Preferences",{web:()=>pr(()=>import("./web-DxttIM6a.js"),[]).then(e=>new e.PreferencesWeb)}),yr="shserv_server_url";let _r="";function Nt(){return Ds.isNativePlatform()}function Al(){return _r}function xs(e){_r=String(e||"").replace(/\/+$/,"")}async function lp(){if(!Nt()){xs("");return}try{const e=await St.get(yr);xs(e||"")}catch{xs("")}}async function up(e){const t=String(e||"").replace(/\/+$/,"");if(xs(t),!!Nt())try{await St.set(yr,t)}catch{}}function cp(e){const t=Al();if(!t)return e;const n=String(e||"").replace(/^\/+/,"");return n?`${t}/${n}`:t}async function dp(){return!Nt()||_r?!0:!!await St.get(yr)}const St={async get(e){if(Nt())try{const{value:t}=await Sa.get({key:e});return t}catch{return null}try{return localStorage.getItem(e)}catch{return null}},async set(e,t){if(Nt()){try{await Sa.set({key:e,value:t})}catch{}return}try{localStorage.setItem(e,t)}catch{}},async remove(e){if(Nt()){try{await Sa.remove({key:e})}catch{}return}try{localStorage.removeItem(e)}catch{}}},Os="shserv_access_token",Fs="shserv_expires_at";let yn=null,ln=null;async function fp(){try{yn=await St.get(Os)||null;const t=await St.get(Fs);ln=t?Number(t):null}catch{yn=null,ln=null}}function aa(e,t=null){yn=e||null,t!=null&&t>0?ln=Date.now()+t*1e3:ln=null,yn?(St.set(Os,yn),ln&&St.set(Fs,String(ln))):(St.remove(Os),St.remove(Fs))}function xl(){return yn}function pp(){return ln}function En(){yn=null,ln=null,St.remove(Os),St.remove(Fs)}const Ns={DEBUG:0,INFO:1,WARN:2,ERROR:3};function Cl(){return Ns[void 0]??Ns.INFO}function br(){return Cl()<=Ns.DEBUG}function Di(e){return Ns[e]>=Cl()}function Oi(e){return e<10?`${e.toFixed(1)}ms`:`${Math.round(e)}ms`}function El(e,t=500){if(!e)return"";const n=String(e);return n.length>t?n.slice(0,t)+"…":n}function Rl(e,t){try{const n=JSON.stringify(e);return t?El(n,t):n}catch{return"[Circular]"}}const vp=1e4,ka="[vue:http]";function gp(e){const t=new URLSearchParams;for(const[s,a]of Object.entries(e||{}))a!=null&&t.append(s,String(a));const n=t.toString();return n?`?${n}`:""}function hp(e,t){const n=String(e||"").replace(/\/+$/,""),s=String(t||"").replace(/^\/+/,"");return n?`${n}/${s}`:`/${s}`}function mp(e,t){return`${e}${gp(t)}`}async function Fi(e,t,n,s={}){const a=Number(s.timeoutMs||vp),r=new AbortController,o=setTimeout(()=>r.abort(),a),i=Al(),l=hp(i,mp(t,s.query)),u={Accept:"application/json",...s.headers||{}},c=xl();c&&(u.Authorization=`Bearer ${c}`);const d={method:e,headers:u,signal:r.signal,credentials:"include"};s.signal&&s.signal.addEventListener("abort",()=>r.abort(),{once:!0}),n!=null&&(u["Content-Type"]="application/json",d.body=JSON.stringify(n)),br()&&console.debug(ka,e,l,n?Rl(n,500):"");const f=performance.now();try{const h=await fetch(l,d),g=await h.text();let y=g;if(g)try{y=JSON.parse(g)}catch{y=g}const m=performance.now()-f,P=h.status>=500?"ERROR":h.status>=400?"WARN":"INFO";return Di(P)&&console[P.toLowerCase()](ka,`${e} ${l} — ${h.status} in ${Oi(m)}`,El(g||"",200)),{response:h,data:y,meta:{url:l,method:e,statusCode:h.status,headers:h.headers}}}catch(h){const g=performance.now()-f;throw Di("ERROR")&&console.error(ka,`${e} ${l} — FAILED in ${Oi(g)}`,(h==null?void 0:h.message)||h),h}finally{clearTimeout(o)}}function wr(e){const t=cp(`/auth/login?return_to=${encodeURIComponent(e)}`);window.location.href=t}function $l(){window.location.href="/#/login"}function Sr(){return Nt()?"/auth/mobile-bridge":window.location.href}let Aa=!1,za=[];function yp(e){za.push(e)}function Ni(e){za.forEach(t=>t(e)),za=[]}function Gn(e,t,n={}){return{type:e,message:t,...n}}async function kr(e,t,n,s){var a,r;try{const{response:o,data:i,meta:l}=await Fi(e,t,n,s);if(!o.ok){if(o.status===401&&!(s!=null&&s._retryOnce)){if(Aa)await new Promise(c=>{yp(d=>c(d))});else{Aa=!0;try{const c=await Fi("POST","/auth/refresh",null);if(c.response.ok){const d=(r=(a=c.data)==null?void 0:a.data)==null?void 0:r.access_token;if(d)aa(d),Ni(d);else throw new Error("No token in refresh response")}else throw new Error("Refresh failed")}catch{return Ni(null),En(),window.location.hash.includes("/login")||$l(),{ok:!1,error:Gn("http_error","HTTP 401",{statusCode:401,raw:i}),meta:l}}finally{Aa=!1}}return xl()?kr(e,t,n,{...s,_retryOnce:!0}):{ok:!1,error:Gn("http_error","HTTP 401",{statusCode:401,raw:i}),meta:l}}return{ok:!1,error:Gn("http_error",`HTTP ${o.status}`,{statusCode:o.status,raw:i}),meta:l}}return i&&typeof i=="object"&&(i.status===!1||i.status==="error")?{ok:!1,error:Gn("api_error",i.msg||i.message||"API error",{errorAlias:i.error_alias,failedFields:i.failed_fields||[],raw:i}),meta:l}:{ok:!0,data:i,meta:l}}catch(o){const i=(o==null?void 0:o.name)==="AbortError";return{ok:!1,error:Gn(i?"timeout":"network_error",(o==null?void 0:o.message)||"Network error",{details:o}),meta:{url:t,method:e,statusCode:0,headers:null}}}}function De(e,t){return kr("GET",e,null,t)}function Qe(e,t,n){return kr("POST",e,t,n)}const Un=bn("auth",()=>{const e=J(null),t=J([]),n=J(!1),s=J(null),a=Q(()=>!!e.value),r=Q(()=>new Set(t.value));function o(y){return r.value.has(y)}function i(y){return Array.isArray(y)?y.some(m=>r.value.has(m)):!1}function l(){s.value&&(clearTimeout(s.value),s.value=null);const y=pp();if(!y)return;const m=y-Date.now()-6e4;m>0?s.value=setTimeout(()=>{f().then(()=>{l()})},m):f().then(()=>{l()})}function u(){s.value&&(clearTimeout(s.value),s.value=null)}let c=null;async function d(){return c||(n.value=!0,c=De("/auth/me").then(async y=>{var m,P,_;if(y.ok){const S=((m=y.data)==null?void 0:m.data)||{};e.value=S.user||null,t.value=S.permissions||[],l()}else if(((P=y.error)==null?void 0:P.statusCode)===401){await f();const S=await De("/auth/me");if(S.ok){const E=((_=S.data)==null?void 0:_.data)||{};e.value=E.user||null,t.value=E.permissions||[],l()}else e.value=null,t.value=[],En(),u()}else e.value=null,t.value=[],En(),u()}).catch(()=>{e.value=null,t.value=[],En(),u()}).finally(()=>{n.value=!1}),c)}async function f(){var m,P,_,S;const y=await Qe("/auth/refresh");if(y.ok){const E=((P=(m=y.data)==null?void 0:m.data)==null?void 0:P.access_token)||null,F=((S=(_=y.data)==null?void 0:_.data)==null?void 0:S.expires_in)||null;aa(E,F),l()}else En(),u()}async function h(){try{await Qe("/auth/logout")}catch{}e.value=null,t.value=[],En(),u(),window.location.href="/#/login"}function g(){if(Nt()){$l();return}wr(Sr())}return{user:e,permissions:t,isLoading:n,isAuthenticated:a,hasPermission:o,hasAnyPermission:i,init:d,refreshToken:f,logout:h,redirectToLogin:g}}),_p={__name:"AppShell",setup(e){const t=sa(),n=Un(),s={login:"Login","areas-favorites":"Favorites","areas-tree":"Areas","area-detail":"Area",devices:"Devices","device-detail":"Device","devices-scanning":"Scanning","scripts-actions":"Actions","scripts-regular":"Regular","scripts-scopes":"Scopes","script-detail":"Script",firmwares:"Firmwares"},a=Q(()=>{const f=t==null?void 0:t.name;return f&&s[f]?s[f]:""}),r=[{label:"Favorites",to:"/areas/favorites",icon:"ph-bookmarks",permission:"areas.view"},{label:"Areas",to:"/areas/tree",icon:"ph-map-trifold",permission:"areas.view"},{label:"Devices",to:"/devices",icon:"ph-cpu",permission:"devices.view"},{label:"Scanning",to:"/devices/scanning",icon:"ph-magnifying-glass",permission:"devices.scan"},{label:"Actions",to:"/scripts/actions",icon:"ph-play",permission:"scripts.run"},{label:"Regular",to:"/scripts/regular",icon:"ph-clock",permission:"scripts.view"},{label:"Scopes",to:"/scripts/scopes",icon:"ph-brackets-curly",permission:"scripts.view"},{label:"Firmwares",to:"/firmwares",icon:"ph-cloud-arrow-down",permission:"firmware.view"}],o=Q(()=>r.filter(f=>f.permission?n.hasPermission(f.permission):!0));function i(f){return f?f.split(/\s+/).slice(0,2).map(h=>{var g;return(g=h[0])==null?void 0:g.toUpperCase()}).join(""):""}function l(f){return f?f.charAt(0).toUpperCase()+f.slice(1):""}function u(){wr(Sr())}function c(){const f=document.querySelector(".nav-drawer-backdrop");f&&f.click()}function d(){c(),n.logout()}return(f,h)=>(w(),K(p(ap),{brand:"SHSERV","logo-src":"/logo-cube-square.svg",title:"Navigation",subtitle:"Smart Home",items:o.value,"active-match":"prefix",current:a.value},{content:k(()=>[Js(f.$slots,"default")]),footer:k(()=>{var g,y,m,P,_,S;return[p(n).isAuthenticated?(w(),K(p(op),{key:0,name:((g=p(n).user)==null?void 0:g.display_name)||"User",email:((y=p(n).user)==null?void 0:y.email)||"",role:l((m=p(n).user)==null?void 0:m.system_role),avatar:{src:((P=p(n).user)==null?void 0:P.avatar_url)||"",initials:i((_=p(n).user)==null?void 0:_.display_name),size:"sm"},href:((S=p(n).user)==null?void 0:S.gauth_profile_url)||"",compact:"",actions:[{label:"Logout",icon:"ph-sign-out",variant:"ghost",onClick:d}]},null,8,["name","email","role","avatar","href","actions"])):(w(),K(p(ge),{key:1,variant:"primary",size:"sm",onClick:u},{icon:k(()=>[...h[0]||(h[0]=[D("i",{class:"ph ph-sign-in"},null,-1)])]),default:k(()=>[h[1]||(h[1]=U(" Sign in ",-1))]),_:1}))]}),_:3},8,["items","current"]))}},ze=(e,t)=>{const n=e.__vccOpts||e;for(const[s,a]of t)n[s]=a;return n},bp={key:0},wp={key:1,class:"error-meta"},Sp={class:"error-actions"},kp={__name:"AppErrorState",props:{title:{type:String,default:"Request failed"},message:{type:String,default:""},retry:{type:Function,default:null},error:{type:Object,default:null}},setup(e){const t=e,n=Q(()=>{var a;return t.message||((a=t.error)==null?void 0:a.message)||""}),s=Q(()=>{if(!t.error)return"";try{return JSON.stringify(t.error,null,2)}catch{return String(t.error)}});return(a,r)=>(w(),K(p(Ze),{variant:"danger",role:"alert"},{default:k(()=>[D("strong",null,N(e.title),1),n.value?(w(),G("p",bp,N(n.value),1)):ae("",!0),e.error?(w(),G("div",wp,[e.error.type?(w(),K(p(_e),{key:0,variant:"secondary"},{default:k(()=>[U(N(e.error.type),1)]),_:1})):ae("",!0),e.error.statusCode?(w(),K(p(_e),{key:1,variant:"secondary"},{default:k(()=>[U("HTTP "+N(e.error.statusCode),1)]),_:1})):ae("",!0),e.error.errorAlias?(w(),K(p(_e),{key:2,variant:"warning"},{default:k(()=>[U(N(e.error.errorAlias),1)]),_:1})):ae("",!0)])):ae("",!0),D("div",Sp,[e.error?(w(),K(p(Yf),{key:0,text:s.value,label:"Copy error details",size:"sm"},null,8,["text"])):ae("",!0),e.retry?(w(),K(p(ge),{key:1,variant:"danger",onClick:e.retry},{default:k(()=>[...r[0]||(r[0]=[U("Retry",-1)])]),_:1},8,["onClick"])):ae("",!0)])]),_:1}))}},pt=ze(kp,[["__scopeId","data-v-f1e6bcb8"]]),Ap={key:0,class:"error-boundary",role:"alert"},xp={__name:"AppErrorBoundary",setup(e){const t=J(!1),n=J("");Io((a,r,o)=>{const i=(a==null?void 0:a.message)||String(a);return console.error("[AppErrorBoundary] Caught Vue error:",i,"| info:",o,a),t.value=!0,n.value=i,!1});function s(){t.value=!1,n.value=""}return(a,r)=>t.value?(w(),G("div",Ap,[L(pt,{title:"Something went wrong",message:n.value,retry:s},null,8,["message"])])):Js(a.$slots,"default",{key:1},void 0,!0)}},Cp=ze(xp,[["__scopeId","data-v-1e10ea7f"]]),Ep={__name:"App",setup(e){return(t,n)=>(w(),K(_p,null,{default:k(()=>[L(p(ip),null,{default:k(()=>[L(Cp,null,{default:k(()=>[L(p(bl))]),_:1})]),_:1})]),_:1}))}},Tt={list(e){return De("/api/v1/areas/list",e)},innerList(e,t){return De(`/api/v1/areas/id/${encodeURIComponent(String(e))}/list`,t)},newArea(e){return Qe("/api/v1/areas/new-area",e)},remove(e){return De(`/api/v1/areas/id/${encodeURIComponent(String(e))}/remove`)},devices(e,t){return De(`/api/v1/areas/id/${encodeURIComponent(String(e))}/devices`,t)},scripts(e,t){return De(`/api/v1/areas/id/${encodeURIComponent(String(e))}/scripts`,t)},updateDisplayName(e){return Qe("/api/v1/areas/update-display-name",e)},updateAlias(e){return Qe("/api/v1/areas/update-alias",e)},placeInArea(e){return Qe("/api/v1/areas/place-in-area",e)},unassign(e){return De(`/api/v1/areas/id/${encodeURIComponent(String(e))}/unassign-from-area`)}};function gt(e={}){const t=J(null),n=J(!1),s=J(null);async function a(i){var u,c;(u=t.value)==null||u.abort();const l=new AbortController;t.value=l,n.value=!0,s.value=null;try{const d=await i(l.signal);return t.value=null,n.value=!1,d.ok||e.ignoreTimeout!==!1&&((c=d.error)==null?void 0:c.type)==="timeout"||(s.value=d.error),d}catch(d){return t.value=null,n.value=!1,s.value={type:"network_error",message:(d==null?void 0:d.message)||"Network error"},{ok:!1,error:s.value}}}function r(){var i;(i=t.value)==null||i.abort(),t.value=null}function o(){s.value=null,r()}return{abortController:t,isLoading:n,error:s,execute:a,abort:r,clear:o}}const Tl="sh:areas:expandedNodes";function Rp(){try{const e=localStorage.getItem(Tl);if(e){const t=JSON.parse(e);if(Array.isArray(t))return new Set(t)}}catch{}return new Set}function $p(e){try{localStorage.setItem(Tl,JSON.stringify([...e]))}catch{}}function Tp(e){const t={},n=[];for(const s of e)t[s.id]={...s,children:[]};for(const s of e){const a=t[s.id],r=s.parent_id&&s.parent_id==s.id,o=s.parent_id&&t[s.parent_id];!r&&o?t[s.parent_id].children.push(a):n.push(a)}return n.length===0&&e.length>0?Object.values(t):n}const wt=bn("areas",()=>{const e=J([]),t=J(null),n=J([]),s=J([]),a=gt(),r=gt(),o=Q(()=>Object.fromEntries(e.value.map(I=>[String(I.id),I]))),i=Q(()=>Tp(e.value)),l=J(Rp());At(l,I=>{$p(I)},{deep:!0});function u(I){const T=new Set(l.value);T.has(I)?T.delete(I):T.add(I),l.value=T}function c(I){return l.value.has(I)}async function d(){return a.execute(async I=>{var A,R;const T=await Tt.list({signal:I});return T.ok&&(e.value=((R=(A=T.data)==null?void 0:A.data)==null?void 0:R.areas)||[]),T})}async function f(I){var A,R,Z,ue,de,pe;r.abort();const T=new AbortController;r.abortController.value=T,r.isLoading.value=!0,r.error.value=null,t.value=o.value[String(I)]||null,n.value=[],s.value=[];try{const[B,q]=await Promise.all([Tt.devices(I,{signal:T.signal}),Tt.scripts(I,{signal:T.signal})]);return r.abortController.value=null,r.isLoading.value=!1,B.ok?q.ok?(n.value=((ue=(Z=B.data)==null?void 0:Z.data)==null?void 0:ue.devices)||[],s.value=((pe=(de=q.data)==null?void 0:de.data)==null?void 0:pe.scripts)||[],{ok:!0}):(((R=q.error)==null?void 0:R.type)!=="timeout"&&(r.error.value=q.error),{ok:!1,error:r.error.value}):(((A=B.error)==null?void 0:A.type)!=="timeout"&&(r.error.value=B.error),{ok:!1,error:r.error.value})}catch(B){return r.abortController.value=null,r.isLoading.value=!1,r.error.value={type:"network_error",message:(B==null?void 0:B.message)||"Network error"},{ok:!1,error:r.error.value}}}function h(){t.value=null,n.value=[],s.value=[],r.clear()}async function g(I){var A,R;const T=await Tt.devices(I);return T.ok&&(n.value=((R=(A=T.data)==null?void 0:A.data)==null?void 0:R.devices)||[]),T}async function y(I){var A,R;const T=await Tt.scripts(I);return T.ok&&(s.value=((R=(A=T.data)==null?void 0:A.data)==null?void 0:R.scripts)||[]),T}async function m(I){var A,R;const T=await Tt.newArea(I);if(T.ok){const Z=(R=(A=T.data)==null?void 0:A.data)==null?void 0:R.area;Z&&e.value.push(Z)}return T}async function P(I,T){const A=await Tt.updateDisplayName({area_id:I,display_name:T});if(A.ok){const R=e.value.findIndex(Z=>Z.id===I);R!==-1&&(e.value[R]={...e.value[R],display_name:T})}return A}async function _(I){const T=await Tt.remove(I);return T.ok&&(e.value=e.value.filter(A=>A.id!==I)),T}function S(I){return!(I!=null&&I.parent_id)||I.parent_id<=0}async function E(I,T){const A=e.value.find(ue=>ue.id===I),R=e.value.filter(S).length;if(A&&S(A)&&R===1)return{ok:!1,error:{message:"Cannot assign the last root area as a child."}};const Z=await Tt.placeInArea({target_id:I,place_in_area_id:T});if(Z.ok){const ue=e.value.findIndex(de=>de.id===I);ue!==-1&&e.value.splice(ue,1,{...e.value[ue],parent_id:Number(T)})}return Z}async function F(I){const T=await Tt.unassign(I);if(T.ok){const A=e.value.findIndex(R=>R.id===I);A!==-1&&e.value.splice(A,1,{...e.value[A],parent_id:0})}return T}return{areas:e,isLoading:a.isLoading,error:a.error,currentArea:t,currentAreaDevices:n,currentAreaScripts:s,isLoadingAreaDetail:r.isLoading,errorAreaDetail:r.error,areasById:o,areaTree:i,expandedNodeIds:l,toggleNode:u,isNodeExpanded:c,loadAreas:d,loadAreaDetail:f,clearAreaDetail:h,loadAreaDevices:g,loadAreaScripts:y,createArea:m,renameArea:P,removeArea:_,assignToArea:E,unassignArea:F}}),Pl="sh_fav_areas";function Pp(){try{return JSON.parse(localStorage.getItem(Pl)||"[]").map(String)}catch{return[]}}function Mi(e){localStorage.setItem(Pl,JSON.stringify(e.map(String)))}const Ar=bn("favorites",()=>{const e=J(Pp());function t(r){return e.value.includes(String(r))}function n(r){const o=String(r);e.value.includes(o)||(e.value.push(o),Mi(e.value))}function s(r){e.value=e.value.filter(o=>o!==String(r)),Mi(e.value)}function a(r){return t(r)?(s(r),!1):(n(r),!0)}return{ids:e,has:t,add:n,remove:s,toggle:a}}),Lp=["aria-label"],Ll={__name:"AreaFavoriteButton",props:{areaId:{type:[String,Number],required:!0}},setup(e){const t=e,n=Ar(),s=Q(()=>n.has(t.areaId));return(a,r)=>(w(),G("button",{class:Mt(["btn-icon area-favorite-btn",{"is-active":s.value,"text-muted":!s.value,"text-warning":s.value}]),type:"button","aria-label":s.value?"Remove bookmark":"Bookmark",onClick:r[0]||(r[0]=Qs(o=>p(n).toggle(e.areaId),["stop"]))},[D("i",{class:Mt(["ph",s.value?"ph-fill ph-bookmark-simple":"ph-bookmark-simple"])},null,2)],10,Lp))}},bt={__name:"AppLoadingState",props:{text:{type:String,default:"Loading"}},setup(e){return(t,n)=>(w(),K(p(Sl),{circle:"",label:e.text},null,8,["label"]))}},rt={__name:"AppEmptyState",props:{title:{type:String,default:"Nothing here"},message:{type:String,default:""}},setup(e){return(t,n)=>(w(),K(p(Zf),{title:e.title,text:e.message,icon:"ph-package"},{actions:k(()=>[Js(t.$slots,"action")]),_:3},8,["title","text"]))}},Ip={class:"page"},Dp={key:3,class:"area-favorites-list"},Op=["onClick"],Fp={class:"area-favorite-info"},Np={class:"area-favorite-title"},Mp={class:"area-favorite-meta"},Up={key:0,class:"area-favorite-parent"},Bp={class:"area-favorite-actions"},jp={__name:"AreaFavoritesPage",setup(e){const t=wt(),n=Ar(),s=en(),a=Q(()=>{const i=new Set(n.ids.map(String));return t.areas.filter(l=>i.has(String(l.id)))});function r(i){if(!i.parent_id)return null;const l=t.areasById[String(i.parent_id)];return(l==null?void 0:l.display_name)||null}function o(i){s.push({name:"area-detail",params:{id:String(i.id)}})}return _t(()=>{t.areas.length===0&&t.loadAreas()}),(i,l)=>{const u=cn("router-link");return w(),G("section",Ip,[L(p(Rt),{title:"Favorites",kicker:"Areas"},{actions:k(()=>[L(p(_e),{variant:"primary"},{default:k(()=>[U(N(a.value.length)+" favorite areas",1)]),_:1})]),_:1}),p(t).isLoading?(w(),K(bt,{key:0,text:"Loading areas"})):p(t).error?(w(),K(pt,{key:1,title:"Areas loading failed",error:p(t).error,retry:p(t).loadAreas},null,8,["error","retry"])):a.value.length===0?(w(),K(rt,{key:2,title:"No favorite areas",message:"Favorite areas from the current client are preserved through localStorage."})):(w(),G("ul",Dp,[(w(!0),G(Ie,null,Yt(a.value,c=>(w(),G("li",{key:c.id,class:"area-favorite-item"},[D("article",{class:"area-favorite-card",onClick:d=>o(c)},[l[2]||(l[2]=D("div",{class:"area-favorite-icon"},[D("i",{class:"ph ph-fill ph-bookmark-simple"})],-1)),D("div",Fp,[D("h2",Np,N(c.display_name),1),D("p",Mp,[L(p(_e),{variant:"secondary"},{default:k(()=>[U(N(c.type),1)]),_:2},1024),D("code",null,N(c.alias),1),r(c)?(w(),G("span",Up,[l[1]||(l[1]=U(" in ",-1)),L(u,{to:{name:"area-detail",params:{id:String(c.parent_id)}},class:"parent-link",onClick:l[0]||(l[0]=Qs(()=>{},["stop"]))},{default:k(()=>[U(N(r(c)),1)]),_:2},1032,["to"])])):ae("",!0)])]),D("div",Bp,[L(Ll,{"area-id":c.id},null,8,["area-id"])])],8,Op)]))),128))]))])}}},Vp=ze(jp,[["__scopeId","data-v-f8795944"]]);function Bt(){const e=Un();return{has:t=>e.hasPermission(t),hasAny:t=>e.hasAnyPermission(t),permissions:e.permissions}}const Hp=["disabled","aria-expanded"],Gp={class:"area-tree-info"},qp={class:"text-muted"},zp={class:"area-tree-actions"},Kp={key:0,class:"area-tree-children"},Wp={key:1,class:"area-tree-node"},Jp={class:"area-tree-card area-tree-cycle text-danger"},Yp={__name:"AreaTreeNode",props:{area:{type:Object,required:!0},ancestors:{type:Array,default:()=>[]}},setup(e){const t=e,n=en(),s=wt(),a=Q(()=>s.isNodeExpanded(t.area.id)),r=Q(()=>{var c;return!((c=t.area.children)!=null&&c.length)}),o=Q(()=>t.ancestors.includes(String(t.area.id))),i=Q(()=>[...t.ancestors,String(t.area.id)]);function l(){s.toggleNode(t.area.id)}function u(){n.push({name:"area-detail",params:{id:String(t.area.id)}})}return(c,d)=>{var h;const f=cn("AreaTreeNode",!0);return o.value?(w(),G("li",Wp,[D("article",Jp," Cycle skipped for area ID "+N(e.area.id),1)])):(w(),G("li",{key:0,class:Mt(["area-tree-node",{"is-open":a.value,"is-leaf":r.value}])},[D("article",{class:"area-tree-card",onClick:u},[D("button",{class:Mt(["tree-toggle",{"text-primary":!r.value,"text-muted":r.value}]),type:"button",disabled:r.value,"aria-expanded":a.value,onClick:Qs(l,["stop"])},N(r.value?"·":a.value?"−":"+"),11,Hp),D("div",Gp,[D("h2",null,N(e.area.display_name),1),D("p",qp,[L(p(_e),{variant:"secondary"},{default:k(()=>[U(N(e.area.type),1)]),_:1}),D("code",null,N(e.area.alias),1)])]),D("div",zp,[L(Ll,{"area-id":e.area.id},null,8,["area-id"])])]),(h=e.area.children)!=null&&h.length&&a.value?(w(),G("ul",Kp,[(w(!0),G(Ie,null,Yt(e.area.children,g=>(w(),K(f,{key:g.id,area:g,ancestors:i.value},null,8,["area","ancestors"]))),128))])):ae("",!0)],2))}}},Xp={class:"page"},Zp={key:3,class:"area-tree"},Qp={class:"form-group"},ev={class:"form-group"},tv={class:"form-group"},nv={key:0,class:"form-group"},sv={__name:"AreaTreePage",setup(e){const t=wt(),n=wn(),s=Bt(),a=J(!1),r=J(!1),o=J(""),i=Zt({type:"",alias:"",display_name:""});function l(){i.type="",i.alias="",i.display_name="",o.value="",a.value=!0}async function u(){var d;r.value=!0,o.value="";const c=await t.createArea({...i});if(r.value=!1,!c.ok){o.value=((d=c.error)==null?void 0:d.message)||"Failed to create area";return}a.value=!1,n.success({title:"Created",text:"Area created successfully"})}return _t(()=>{t.loadAreas()}),(c,d)=>(w(),G("section",Xp,[L(p(Rt),{title:"Tree",kicker:"Areas"},{actions:k(()=>[p(s).has("areas.manage")?(w(),K(p(ge),{key:0,variant:"primary",icon:"ph-plus",onClick:l},{default:k(()=>[...d[5]||(d[5]=[U("Create area",-1)])]),_:1})):ae("",!0)]),_:1}),p(t).isLoading?(w(),K(bt,{key:0,text:"Loading areas tree"})):p(t).error?(w(),K(pt,{key:1,title:"Areas loading failed",error:p(t).error,retry:p(t).loadAreas},null,8,["error","retry"])):p(t).areaTree.length===0?(w(),K(rt,{key:2,title:"No areas",message:"No areas found. Create one to get started."})):(w(),G("ul",Zp,[(w(!0),G(Ie,null,Yt(p(t).areaTree,f=>(w(),K(Yp,{key:f.id,area:f},null,8,["area"]))),128))])),L(p(ut),{open:a.value,title:"Create area","onUpdate:open":d[4]||(d[4]=f=>a.value=f)},{footer:k(()=>[L(p(ge),{variant:"secondary",onClick:d[3]||(d[3]=f=>a.value=!1)},{default:k(()=>[...d[6]||(d[6]=[U("Cancel",-1)])]),_:1}),L(p(ge),{variant:"primary",icon:"ph-plus",loading:r.value,onClick:u},{default:k(()=>[...d[7]||(d[7]=[U("Create",-1)])]),_:1},8,["loading"])]),default:k(()=>[D("div",Qp,[L(p(xt),{modelValue:i.type,"onUpdate:modelValue":d[0]||(d[0]=f=>i.type=f),label:"Type",placeholder:"room"},null,8,["modelValue"])]),D("div",ev,[L(p(xt),{modelValue:i.alias,"onUpdate:modelValue":d[1]||(d[1]=f=>i.alias=f),label:"Alias",placeholder:"kitchen"},null,8,["modelValue"])]),D("div",tv,[L(p(xt),{modelValue:i.display_name,"onUpdate:modelValue":d[2]||(d[2]=f=>i.display_name=f),label:"Display name",placeholder:"Kitchen"},null,8,["modelValue"])]),o.value?(w(),G("div",nv,[L(p(Ze),{variant:"danger"},{default:k(()=>[U(N(o.value),1)]),_:1})])):ae("",!0)]),_:1},8,["open"])]))}},av=ze(sv,[["__scopeId","data-v-5f02f384"]]),rv={device_name:"name",device_hard_id:"device_id",device_ip:"ip",ip_address:"ip",mac_address:"mac",device_mac:"mac",core_version:"firmware_core_version",type:"device_type"};function iv(e){const t={};for(const[n,s]of Object.entries(e||{}))t[rv[n]||n]=s;return t}function qn(e){return encodeURIComponent(String(e))}function ov(e){var n,s,a;if(!e.ok)return e;const t=((s=(n=e.data)==null?void 0:n.data)==null?void 0:s.devices)||[];return{...e,data:{...e.data,data:{...(a=e.data)==null?void 0:a.data,devices:t.map(iv)}}}}const nt={async list(){return ov(await De("/api/v1/devices/list"))},status(e,t){return De(`/api/v1/devices/id/${qn(e)}/status`,t)},reboot(e){return De(`/api/v1/devices/id/${qn(e)}/reboot`)},action(e){return Qe("/api/v1/devices/action",e)},scanningSetup(e){return De("/api/v1/devices/scanning/setup",{timeoutMs:12e4,...e})},scanningAll(e){return De("/api/v1/devices/scanning/all",{timeoutMs:12e4,...e})},setupNewDevice(e){return Qe("/api/v1/devices/setup/new-device",e)},detail(e,t){return De(`/api/v1/devices/id/${qn(e)}`,t)},updateName(e,t){return Qe("/api/v1/devices/update-name",{device_id:e,name:t})},updateDescription(e,t){return Qe("/api/v1/devices/update-description",{device_id:e,description:t})},updateAlias(e,t){return Qe("/api/v1/devices/update-alias",{device_id:e,new_alias:t})},remove(e){return De(`/api/v1/devices/id/${qn(e)}/remove`)},resetup(e){return Qe("/api/v1/devices/resetup",{device_id:e})},reset(e){return Qe("/api/v1/devices/reset",{device_id:e})},unassign(e){return De(`/api/v1/devices/id/${qn(e)}/unassign-from-area`)},placeInArea(e){return Qe("/api/v1/devices/place-in-area",e)}},lv=4;function Ka(e){return String((e==null?void 0:e.id)||"")}function xr(e,t){return{deviceId:Ka(e),status:"idle",message:"",response:null,connectionStatus:(e==null?void 0:e.connection_status)||"unknown",updatedAt:null,...t}}function uv(e,t){var a,r;const s=(((r=(a=t.data)==null?void 0:a.data)==null?void 0:r.device)||{}).device_response||{};return xr(e,{status:"ready",message:s.status||"ok",response:s,connectionStatus:"active",updatedAt:new Date().toISOString()})}function cv(e,t){var a,r,o;const n=((a=t.error)==null?void 0:a.raw)||{},s=((r=n==null?void 0:n.data)==null?void 0:r.connection_status)||(e==null?void 0:e.connection_status)||"unknown";return xr(e,{status:"error",message:((o=t.error)==null?void 0:o.message)||"Device state is unavailable",response:n,connectionStatus:s,updatedAt:new Date().toISOString()})}async function dv(e,t,n){let s=0;const a=Math.max(1,Math.min(t,e.length));async function r(){for(;s{const e=J([]),t=J({}),n=J(0),s=J(new Set),a=J(null),r=J(null),o=J(null),i=J(!1),l=J(null),u=gt(),c=gt(),d=Q(()=>e.value.length),f=Q(()=>B=>s.value.has(String(B)));async function h(){return u.execute(async B=>{var X,W;const q=await nt.list({signal:B});return q.ok&&(e.value=((W=(X=q.data)==null?void 0:X.data)==null?void 0:W.devices)||[],o.value=new Date().toISOString()),q})}function g(B,q){const X=Ka(B);X&&(t.value={...t.value,[X]:xr(B,q)})}async function y(B,q,X){const W=n.value+1;n.value=W,i.value=!0,l.value=null,X&&(t.value={});const te=[];for(const ve of B)ve.connection_status==="lost"?g(ve,{status:"skipped",message:"Connection lost",connectionStatus:"lost"}):(g(ve,{status:"loading",message:"Loading"}),te.push(ve));try{await dv(te,q.concurrency||lv,async ve=>{const Se=await nt.status(ve.id);n.value===W&&(t.value={...t.value,[Ka(ve)]:Se.ok?uv(ve,Se):cv(ve,Se)})})}catch(ve){n.value===W&&(l.value={type:"state_loader_error",message:(ve==null?void 0:ve.message)||"Device states loader failed"})}finally{n.value===W&&(i.value=!1)}}async function m(B,q={}){return y(B,q,!1)}async function P(B={}){return y(e.value,B,!0)}async function _(B){const q=String(B);s.value=new Set(s.value).add(q);const X=await nt.reboot(B),W=new Set(s.value);return W.delete(q),s.value=W,X}async function S(B){return c.execute(async q=>{var W,te;const X=await nt.detail(B,{signal:q});return X.ok&&(a.value=((te=(W=X.data)==null?void 0:W.data)==null?void 0:te.device)||null),X})}async function E(B){var te,ve;const q=await nt.status(B);if(!q.ok)return r.value={ok:!1,error:q.error,channels:[]},q;const W=(((ve=(te=q.data)==null?void 0:te.data)==null?void 0:ve.device)||{}).device_response||{};return r.value={ok:!0,channels:W.channels||[],raw:W},q}async function F(B,q){const X=await nt.updateName(B,q);return X.ok&&a.value&&(a.value={...a.value,name:q}),X}async function I(B,q){const X=await nt.updateDescription(B,q);return X.ok&&a.value&&(a.value={...a.value,description:q}),X}async function T(B,q){const X=await nt.updateAlias(B,q);return X.ok&&a.value&&(a.value={...a.value,alias:q}),X}async function A(B){return nt.remove(B)}async function R(B){return nt.resetup(B)}async function Z(B){return nt.reset(B)}async function ue(B){const q=await nt.unassign(B);return q.ok&&a.value&&(a.value={...a.value,area_id:null}),q}async function de(B,q){const X=await nt.placeInArea({target_id:B,place_in_area_id:q});return X.ok&&a.value&&(a.value={...a.value,area_id:q}),X}function pe(){a.value=null,r.value=null,c.clear()}return{devices:e,isLoading:u.isLoading,error:u.error,isLoadingStates:i,stateError:l,stateByDeviceId:t,stateRunId:n,rebootingIds:s,lastLoadedAt:o,currentDevice:a,currentDeviceStatus:r,isLoadingDetail:c.isLoading,errorDetail:c.error,total:d,isRebooting:f,loadDevices:h,setDeviceState:g,loadDeviceStates:P,loadStatesFor:m,rebootDevice:_,loadDeviceDetail:S,loadDeviceStatus:E,updateDeviceName:F,updateDeviceDescription:I,updateDeviceAlias:T,removeDevice:A,unassignDevice:ue,assignToArea:de,resetupDevice:R,resetDevice:Z,clearDeviceDetail:pe}}),Pt={actionsList(e){return De("/api/v1/scripts/actions/list",e)},regularList(e){return De("/api/v1/scripts/regular/list",e)},scopesList(e){return De("/api/v1/scripts/scopes/list",e)},runAction(e,t={}){return Qe("/api/v1/scripts/actions/run",{alias:e,params:t})},setActionState(e,t){return De(`/api/v1/scripts/actions/alias/${encodeURIComponent(e)}/${t?"enable":"disable"}`)},setRegularState(e,t){return De(`/api/v1/scripts/regular/alias/${encodeURIComponent(e)}/${t?"enable":"disable"}`)},setScopeState(e,t){return De(`/api/v1/scripts/scopes/name/${encodeURIComponent(e)}/${t?"enable":"disable"}`)},scopeCode(e,t){return De(`/api/v1/scripts/scopes/name/${encodeURIComponent(e)}`,t)},placeInArea(e){return Qe("/api/v1/scripts/place-in-area",e)},unassign(e){return De(`/api/v1/scripts/id/${encodeURIComponent(String(e))}/unassign-from-area`)}},Sn=bn("scripts",()=>{const e=J([]),t=J([]),n=J([]),s=J(new Set),a=J(null),r=J(""),o=gt(),i=gt(),l=gt(),u=gt(),c=Q(()=>e.value.length),d=Q(()=>t.value.length),f=Q(()=>n.value.length),h=Q(()=>B=>s.value.has(B)),g=Q(()=>B=>e.value.find(q=>q.alias===B)||null),y=Q(()=>B=>t.value.find(q=>q.alias===B)||null),m=Q(()=>B=>n.value.find(q=>q.name===B)||null),P=Q(()=>B=>e.value.filter(q=>q.scope===B)),_=Q(()=>B=>t.value.filter(q=>q.scope===B));async function S(){return o.execute(async B=>{var X,W;const q=await Pt.actionsList({signal:B});return q.ok&&(e.value=((W=(X=q.data)==null?void 0:X.data)==null?void 0:W.scripts)||[]),q})}async function E(){return i.execute(async B=>{var X,W;const q=await Pt.regularList({signal:B});return q.ok&&(t.value=((W=(X=q.data)==null?void 0:X.data)==null?void 0:W.scripts)||[]),q})}async function F(){return l.execute(async B=>{var X,W;const q=await Pt.scopesList({signal:B});return q.ok&&(n.value=((W=(X=q.data)==null?void 0:X.data)==null?void 0:W.scopes)||[]),q})}async function I(B,q={}){var te,ve,Se,Ee,we,Me;s.value=new Set(s.value).add(B),a.value=null;const X=await Pt.runAction(B,q),W=new Set(s.value);return W.delete(B),s.value=W,X.ok?(a.value={alias:B,ok:!0,data:(Se=(ve=(te=X.data)==null?void 0:te.data)==null?void 0:ve.return)==null?void 0:Se.result,execTime:(Me=(we=(Ee=X.data)==null?void 0:Ee.data)==null?void 0:we.return)==null?void 0:Me.exec_time},X):(a.value={alias:B,ok:!1,error:X.error},X)}async function T(B,q){const X=await Pt.setActionState(B,q);if(X.ok){const W=e.value.findIndex(te=>te.alias===B);W!==-1&&(e.value[W]={...e.value[W],state:q?"enabled":"disabled"})}return X}async function A(B,q){const X=await Pt.setRegularState(B,q);if(X.ok){const W=t.value.findIndex(te=>te.alias===B);W!==-1&&(t.value[W]={...t.value[W],state:q?"enabled":"disabled"})}return X}async function R(B,q){const X=await Pt.setScopeState(B,q);if(X.ok){const W=n.value.findIndex(te=>te.name===B);W!==-1&&(n.value[W]={...n.value[W],state:q?"enabled":"disabled"})}return X}async function Z(B,q){const X=await Pt.placeInArea({target_id:B,place_in_area_id:q});if(X.ok){const W=e.value.findIndex(ve=>ve.id===B);W!==-1&&e.value.splice(W,1,{...e.value[W],area_id:q});const te=t.value.findIndex(ve=>ve.id===B);te!==-1&&t.value.splice(te,1,{...t.value[te],area_id:q})}return X}async function ue(B){const q=await Pt.unassign(B);if(q.ok){const X=e.value.findIndex(te=>te.id===B);X!==-1&&e.value.splice(X,1,{...e.value[X],area_id:null});const W=t.value.findIndex(te=>te.id===B);W!==-1&&t.value.splice(W,1,{...t.value[W],area_id:null})}return q}async function de(B){return u.execute(async q=>{const X=await Pt.scopeCode(B,{signal:q});return X.ok&&(r.value=typeof X.data=="string"?X.data:""),X})}function pe(){r.value="",u.clear()}return{actions:e,regular:t,scopes:n,isLoadingActions:o.isLoading,isLoadingRegular:i.isLoading,isLoadingScopes:l.isLoading,errorActions:o.error,errorRegular:i.error,errorScopes:l.error,runningAliases:s,lastRunResult:a,currentScopeCode:r,isLoadingScopeCode:u.isLoading,errorScopeCode:u.error,totalActions:c,totalRegular:d,totalScopes:f,isRunning:h,actionByAlias:g,regularByAlias:y,scopeByName:m,actionsByScope:P,regularByScope:_,loadActions:S,loadRegular:E,loadScopes:F,runScript:I,setActionState:T,setRegularState:A,setScopeState:R,assignToArea:Z,unassignFromArea:ue,loadScopeCode:de,clearScopeCode:pe}});function Cr(){const e=wt(),t=J(""),n=Q(()=>e.areas.filter(u=>String(u.id)!==String(t.value)).map(u=>({value:String(u.id),label:`${u.display_name} (${u.type})`}))),s=J(!1),a=J(""),r=J(!1),o=J("");function i(u){a.value=u?String(u):"",t.value=u?String(u):"",o.value="",s.value=!0}async function l(u,c){var f;if(!u||!c)return;r.value=!0,o.value="";const d=await c(u,a.value);return r.value=!1,d.ok?(s.value=!1,d):(o.value=((f=d.error)==null?void 0:f.message)||"Failed to assign area",d)}return{areaOptions:n,showAssignModal:s,selectedAreaId:a,assignLoading:r,assignError:o,openAssign:i,submitAssignCore:l}}const fv={key:1,class:"text-muted",style:{"font-size":"13px"}},pv={__name:"AreaBadgeLink",props:{area:{type:Object,default:null},areaId:{type:[Number,String],default:null}},setup(e){return(t,n)=>{const s=cn("router-link");return e.area?(w(),K(s,{key:0,to:{name:"area-detail",params:{id:e.area.id}},class:"area-link"},{default:k(()=>[L(p(_e),{variant:"info"},{default:k(()=>[U(N(e.area.display_name),1)]),_:1})]),_:1},8,["to"])):e.areaId?(w(),G("span",fv,"Area ID: "+N(e.areaId),1)):ae("",!0)}}},Er=ze(pv,[["__scopeId","data-v-91230b95"]]),vv={class:"devices-panel"},gv={class:"block-title"},hv={key:0,class:"area-assigned"},mv={class:"area-card-info"},yv={class:"text-muted"},_v={__name:"AreaAssignSection",props:{item:{type:Object,default:null},areaId:{type:[Number,String],default:null},title:{type:String,default:"Area"},emptyMessage:{type:String,default:"This item is not assigned to any area."}},emits:["assign"],setup(e,{emit:t}){const n=e,s=t,a=wt(),r=Q(()=>{var i;const o=n.areaId!=null?n.areaId:(i=n.item)==null?void 0:i.area_id;return o&&a.areasById[String(o)]||null});return(o,i)=>{const l=cn("router-link");return w(),G("div",vv,[D("div",gv,N(e.title),1),r.value?(w(),G("div",hv,[L(l,{to:{name:"area-detail",params:{id:r.value.id}},class:"area-card"},{default:k(()=>[i[1]||(i[1]=D("div",{class:"area-card-icon text-primary"},[D("i",{class:"ph ph-map-trifold"})],-1)),D("div",mv,[D("strong",null,N(r.value.display_name),1),D("small",yv,N(r.value.type)+" — "+N(r.value.alias),1)])]),_:1},8,["to"])])):(w(),K(rt,{key:1,title:"Not assigned",message:e.emptyMessage},{action:k(()=>[Js(o.$slots,"action",{},()=>[L(p(ge),{variant:"primary",icon:"ph-map-pin",onClick:i[0]||(i[0]=u=>s("assign"))},{default:k(()=>[...i[2]||(i[2]=[U("Assign to area",-1)])]),_:1})],!0)]),_:3},8,["message"]))])}}},Rr=ze(_v,[["__scopeId","data-v-92cae82c"]]);function Il(e){if(!e)return"";const t=Dl(e);if(!t)return e;const s=new Date-t,a=Math.floor(s/1e3),r=Math.floor(a/60),o=Math.floor(r/60),i=Math.floor(o/24),l=Math.floor(i/7),u=Math.floor(i/30);if(a<10)return"just now";if(a<60)return`${a} sec ago`;if(r<60)return`${r} min ago`;if(o<24){const d=r%60;return d>0?`${o} hour${o>1?"s":""} ${d} min ago`:`${o} hour${o>1?"s":""} ago`}if(i<7)return`${i} day${i>1?"s":""} ago`;if(l<4)return`${l} week${l>1?"s":""} ago`;if(u<12)return`${u} month${u>1?"s":""} ago`;const c=Math.floor(i/365);return`${c} year${c>1?"s":""} ago`}function Wa(e){if(!e)return"";const t=Dl(e);if(!t)return e;const s=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"][t.getMonth()],a=t.getDate(),r=t.getFullYear(),o=String(t.getHours()).padStart(2,"0"),i=String(t.getMinutes()).padStart(2,"0");return`${s} ${a}, ${r} ${o}:${i}`}function Dl(e){if(!e)return null;const t=/^(\d{4})-(\d{2})-(\d{2})\s+(\d{2}):(\d{2}):(\d{2})$/,n=e.match(t);if(n){const[,a,r,o,i,l,u]=n;return new Date(a,parseInt(r)-1,o,i,l,u)}const s=new Date(e);return isNaN(s.getTime())?null:s}const bv={class:"device-channels-state"},wv={key:3,class:"channels-grid"},Sv={key:0,class:"ph ph-caret-up"},kv={key:1,class:"ph ph-caret-down"},Av={key:0,class:"ph ph-caret-up"},xv={key:1,class:"ph ph-caret-down"},Cv={key:0,class:"ph ph-caret-up"},Ev={key:1,class:"ph ph-caret-down"},Rv={key:0,class:"ph ph-caret-up"},$v={key:1,class:"ph ph-caret-down"},Tv={key:0,class:"ph ph-caret-up"},Pv={key:1,class:"ph ph-caret-down"},Lv={key:0,class:"raw-json text-muted"},Iv={__name:"DeviceChannelsState",props:{deviceType:{type:String,default:""},response:{type:Object,default:null},loading:{type:Boolean,default:!1},error:{type:[String,Object],default:null},connectionStatus:{type:String,default:"unknown"}},setup(e){const t=e,n=Q(()=>t.connectionStatus==="lost"),s=Q(()=>{var g;return((g=t.response)==null?void 0:g.channels)||[]}),a=Q(()=>{var g;return((g=t.response)==null?void 0:g.sensors)||{}}),r=Q(()=>{var g,y;return((y=(g=t.response)==null?void 0:g.hatch)==null?void 0:y.state)||"—"}),o=Q(()=>{var g,y;return((y=(g=t.response)==null?void 0:g.hatch)==null?void 0:y.position_pct)??"—"}),i=Q(()=>String(r.value).includes("open")?"warning":"primary"),l=Q(()=>String(r.value).includes("open")),u=Q(()=>{var g;return((g=t.response)==null?void 0:g.status)==="ok"}),c=Q(()=>{if(!t.response)return"";try{return JSON.stringify(t.response).slice(0,200)}catch{return""}}),d=Q(()=>{var g;return u.value?t.deviceType==="relay"||t.deviceType==="button"?s.value.length>0:t.deviceType==="sensor"?Object.keys(a.value).length>0:t.deviceType==="hatch"?!!((g=t.response)!=null&&g.hatch):!1:!1});function f(g){return g.id??g.channel}function h(g){return{enabled:"success",disabled:"secondary",mute:"primary",waiting:"warning",error:"danger"}[g]||"secondary"}return(g,y)=>(w(),G("div",bv,[e.loading?(w(),K(p(Sl),{key:0,circle:"",size:"sm",label:"Loading state"})):n.value?(w(),K(p(_e),{key:1,variant:"danger",size:"sm"},{default:k(()=>[...y[0]||(y[0]=[D("i",{class:"ph ph-wifi-slash"},null,-1),U(" Offline ",-1)])]),_:1})):e.error||!u.value?(w(),K(p(_e),{key:2,variant:"danger",size:"sm"},{default:k(()=>[y[1]||(y[1]=D("i",{class:"ph ph-warning-octagon"},null,-1)),typeof e.error=="string"?(w(),G(Ie,{key:0},[U(N(e.error),1)],64)):(w(),G(Ie,{key:1},[U("Error")],64))]),_:1})):d.value?(w(),G("div",wv,[e.deviceType==="relay"?(w(!0),G(Ie,{key:0},Yt(s.value,m=>(w(),K(p(_e),{key:f(m),variant:m.state==="on"||m.state===!0?"success":"secondary",size:"sm"},{default:k(()=>[s.value.length>1?(w(),G(Ie,{key:0},[U(N(f(m))+": ",1)],64)):ae("",!0),D("b",null,N(m.state=="off"?"OFF":"ON"),1)]),_:2},1032,["variant"]))),128)):e.deviceType==="button"?(w(!0),G(Ie,{key:1},Yt(s.value,m=>(w(),K(p(_e),{key:f(m),variant:h(m.indicator),size:"sm"},{default:k(()=>[U(N(f(m))+": ",1),D("b",null,N(m.indicator),1)]),_:2},1032,["variant"]))),128)):e.deviceType==="sensor"?(w(),G(Ie,{key:2},[a.value.radar?(w(),K(p(_e),{key:0,variant:"primary",size:"sm"},{default:k(()=>[D("i",{class:Mt(["ph",a.value.radar.presence?"ph-user-square":"ph-square"])},null,2),a.value.radar.presence?(w(),G(Ie,{key:0},[U(N(a.value.radar.activity_score)+" ",1),a.value.radar.activity_score_dynamics==="increasing"?(w(),G("i",Sv)):a.value.radar.activity_score_dynamics==="decreasing"?(w(),G("i",kv)):ae("",!0)],64)):ae("",!0)]),_:1})):ae("",!0),a.value.temperature?(w(),K(p(_e),{key:1,variant:"primary",size:"sm"},{default:k(()=>[y[2]||(y[2]=D("i",{class:"ph ph-thermometer"},null,-1)),U(" "+N(a.value.temperature.current)+"°C ",1),a.value.temperature.dynamics==="increasing"?(w(),G("i",Av)):a.value.temperature.dynamics==="decreasing"?(w(),G("i",xv)):ae("",!0)]),_:1})):ae("",!0),a.value.humidity?(w(),K(p(_e),{key:2,variant:"primary",size:"sm"},{default:k(()=>[y[3]||(y[3]=D("i",{class:"ph ph-drop-half-bottom"},null,-1)),U(" "+N(a.value.humidity.current)+"% ",1),a.value.humidity.dynamics==="increasing"?(w(),G("i",Cv)):a.value.humidity.dynamics==="decreasing"?(w(),G("i",Ev)):ae("",!0)]),_:1})):ae("",!0),a.value.pressure?(w(),K(p(_e),{key:3,variant:"primary",size:"sm"},{default:k(()=>[U(N(a.value.pressure.current)+"hpa ",1),a.value.pressure.dynamics==="increasing"?(w(),G("i",Rv)):a.value.pressure.dynamics==="decreasing"?(w(),G("i",$v)):ae("",!0)]),_:1})):ae("",!0),a.value.light?(w(),K(p(_e),{key:4,variant:"primary",size:"sm"},{default:k(()=>[y[4]||(y[4]=D("i",{class:"ph ph-lightbulb"},null,-1)),U(" "+N(a.value.light.percent)+"% ",1)]),_:1})):ae("",!0),a.value.microphone?(w(),K(p(_e),{key:5,variant:"primary",size:"sm"},{default:k(()=>[y[5]||(y[5]=D("i",{class:"ph ph-ear"},null,-1)),U(" "+N(a.value.microphone.current_noise)+"dBi ",1),a.value.microphone.noise_dynamics==="increasing"?(w(),G("i",Tv)):a.value.microphone.noise_dynamics==="decreasing"?(w(),G("i",Pv)):ae("",!0)]),_:1})):ae("",!0)],64)):e.deviceType==="hatch"?(w(),K(p(_e),{key:3,variant:i.value,size:"sm"},{default:k(()=>[U(N(r.value)+" ",1),l.value?(w(),G(Ie,{key:0},[U(" - "+N(o.value)+"%",1)],64)):ae("",!0)]),_:1},8,["variant"])):(w(),G(Ie,{key:4},[y[6]||(y[6]=D("span",{class:"unknown-type text-muted"},"Unknown type",-1)),c.value?(w(),G("pre",Lv,N(c.value),1)):ae("",!0)],64))])):(w(),K(p(_e),{key:4,variant:"secondary",size:"sm"},{default:k(()=>[...y[7]||(y[7]=[U("No data",-1)])]),_:1}))]))}},Ol=ze(Iv,[["__scopeId","data-v-08541c71"]]),Dv={class:"device-cell"},Ov=["innerHTML"],Fv={class:"device-info"},Nv={class:"device-name-row"},Mv=["title"],Uv={class:"text-muted"},Bv=["title"],jv={key:1,class:"text-muted"},Vv={__name:"DeviceTable",props:{devices:{type:Array,required:!0},showActions:{type:Boolean,default:!0},showLastContact:{type:Boolean,default:!0},caption:{type:String,default:"Devices"}},setup(e){const t=e,n=ra(),s=wn(),a=Bt(),r={relay:'',button:'',sensor:''},o=Q(()=>{const d=[{key:"device",label:"Device"},{key:"state",label:"State"}];return t.showLastContact&&d.push({key:"lastContact",label:"Last Contact"}),t.showActions&&d.push({key:"actions",label:"Actions"}),d});function i(d){return r[d]||r.relay}function l(d){return{active:"success",removed:"danger",freezed:"warning",setup:"primary"}[d]||"secondary"}function u(d){return n.stateByDeviceId[String(d.id)]||{status:"idle",message:"Not loaded",connectionStatus:d.connection_status||"unknown"}}async function c(d){var g;const f=t.devices.find(y=>String(y.id)===String(d)),h=await n.rebootDevice(d);h.ok?s.success({title:"Rebooting",text:`Device ${(f==null?void 0:f.name)||(f==null?void 0:f.alias)||"#"+d} is rebooting`}):s.error({title:"Reboot failed",text:((g=h.error)==null?void 0:g.message)||"Failed to reboot device"})}return(d,f)=>{const h=cn("router-link");return w(),K(p(Nn),{columns:o.value,rows:e.devices,caption:e.caption},Do({"cell-device":k(({row:g})=>[L(h,{to:{name:"device-detail",params:{id:String(g.id)}},class:"device-link"},{default:k(()=>[D("div",Dv,[D("div",{class:"device-icon text-primary",innerHTML:i(g.device_type)},null,8,Ov),D("div",Fv,[D("div",Nv,[D("strong",null,N(g.name||g.alias||`Device #${g.id}`),1),g.status&&g.status!=="active"?(w(),K(p(_e),{key:0,variant:l(g.status),size:"sm"},{default:k(()=>[U(N(g.status),1)]),_:2},1032,["variant"])):ae("",!0),D("span",{class:Mt(["status-dot",{"text-success":g.connection_status==="active","text-danger":g.connection_status!=="active"}]),"aria-hidden":"true",title:g.connection_status==="active"?"Online":"Offline"},null,10,Mv)]),D("small",Uv,N(g.alias)+" — "+N(g.device_ip||"—"),1)])])]),_:2},1032,["to"])]),"cell-state":k(({row:g})=>[L(Ol,{"device-type":g.device_type,response:u(g).response,loading:u(g).status==="loading",error:u(g).status==="error"?u(g).message:null,"connection-status":g.connection_status||"unknown"},null,8,["device-type","response","loading","error","connection-status"])]),"cell-lastContact":k(({row:g})=>[g.last_contact?(w(),G("span",{key:0,title:p(Wa)(g.last_contact)},N(p(Il)(g.last_contact)),9,Bv)):(w(),G("span",jv,"—"))]),_:2},[e.showActions&&p(a).has("devices.control")?{name:"cell-actions",fn:k(({row:g})=>[L(p(ge),{variant:"warning",icon:"ph-arrow-clockwise",size:"sm",loading:p(n).isRebooting(g.id),onClick:y=>c(g.id)},{default:k(()=>[...f[0]||(f[0]=[U(" Reboot ",-1)])]),_:1},8,["loading","onClick"])]),key:"0"}:void 0]),1032,["columns","rows","caption"])}}},Fl=ze(Vv,[["__scopeId","data-v-32549911"]]),Hv={class:"scope-name"},Gv={key:1,class:"muted"},qv={key:1,class:"muted"},zv={__name:"ScriptTable",props:{scripts:{type:Array,required:!0},scriptType:{type:String,default:"regular"},showArea:{type:Boolean,default:!1},showScope:{type:Boolean,default:!0},showFilename:{type:Boolean,default:!0},showActions:{type:Boolean,default:!0},caption:{type:String,default:"Scripts"}},setup(e){const t=e,n=Sn(),s=wt(),a=Bt(),r=Q(()=>{const c={};for(const d of s.areas)c[d.id]=d;return c});function o(c){var d;return c.area_id?((d=r.value[c.area_id])==null?void 0:d.display_name)||`Area ${c.area_id}`:null}function i(c){const d=c.type||t.scriptType;return d==="action"?"actions":d==="scope"?"scopes":d}const l=Q(()=>{const c=[{key:"alias",label:"Alias"},{key:"name",label:"Name"}];return t.showScope&&c.push({key:"scope",label:"Scope"}),t.showArea&&c.push({key:"area",label:"Area"}),c.push({key:"state",label:"State"}),t.showFilename&&c.push({key:"filename",label:"File"}),t.showActions&&c.push({key:"actions",label:"Actions"}),c});function u(c,d,f){const h=f.type||t.scriptType;h==="action"?n.setActionState(c,d):h==="regular"&&n.setRegularState(c,d)}return(c,d)=>{const f=cn("router-link");return w(),K(p(Nn),{columns:l.value,rows:e.scripts,caption:e.caption},Do({"cell-alias":k(({row:h})=>[L(f,{to:{name:"script-detail",params:{type:i(h),id:h.alias}},class:"script-link"},{default:k(()=>[U(N(h.alias),1)]),_:2},1032,["to"])]),"cell-scope":k(({row:h})=>[h.scope?(w(),K(f,{key:0,to:{name:"script-detail",params:{type:"scopes",id:h.scope}},class:"scope-link"},{default:k(()=>[d[0]||(d[0]=D("span",{class:"scope-label"},"Scope",-1)),D("span",Hv,N(h.scope),1),d[1]||(d[1]=D("i",{class:"ph ph-arrow-right"},null,-1))]),_:2},1032,["to"])):(w(),G("span",Gv,"—"))]),"cell-area":k(({row:h})=>[h.area_id?(w(),K(p(_e),{key:0,variant:"primary"},{default:k(()=>[U(N(o(h)),1)]),_:2},1024)):(w(),G("span",qv,"—"))]),"cell-state":k(({row:h})=>[L(p(_e),{variant:h.state==="enabled"?"success":"secondary"},{default:k(()=>[U(N(h.state),1)]),_:2},1032,["variant"])]),_:2},[e.showActions&&p(a).has("scripts.edit")?{name:"cell-actions",fn:k(({row:h})=>[h.state==="enabled"?(w(),K(p(ge),{key:0,variant:"secondary",icon:"ph-pause",onClick:g=>u(h.alias,!1,h)},{default:k(()=>[...d[2]||(d[2]=[U(" Disable ",-1)])]),_:1},8,["onClick"])):(w(),K(p(ge),{key:1,variant:"primary",icon:"ph-play",onClick:g=>u(h.alias,!0,h)},{default:k(()=>[...d[3]||(d[3]=[U(" Enable ",-1)])]),_:1},8,["onClick"]))]),key:"0"}:void 0]),1032,["columns","rows","caption"])}}},Nl=ze(zv,[["__scopeId","data-v-1ead75a7"]]),Kv={class:"page-actions-dropdown"},Wv=["aria-expanded","onClick"],$r={__name:"PageActionsDropdown",props:{items:{type:Array,required:!0}},setup(e){return(t,n)=>(w(),G("div",Kv,[L(p(Xf),el({items:e.items},t.$attrs),{trigger:k(({toggle:s,open:a})=>[D("button",{class:"btn-icon",type:"button","aria-label":"Actions","aria-expanded":a?"true":"false",onClick:s},[...n[0]||(n[0]=[D("i",{class:"ph ph-dots-three-vertical"},null,-1)])],8,Wv)]),_:1},16,["items"])]))}},Jv={class:"area-grid"},Yv=["innerHTML"],Xv={key:1},Zv={class:"script-meta"},Qv={key:2},eg={__name:"ActionScriptsGrid",props:{scripts:{type:Array,required:!0},showAreaBadge:{type:Boolean,default:!1}},emits:["run-success"],setup(e,{emit:t}){const n=e,s=t,a=en(),r=Sn(),o=wt(),i=wn(),l=Bt();function u(f){return!f.area_id||!n.showAreaBadge?null:o.areas.find(h=>h.id===f.area_id)||null}async function c(f){var g,y;const h=await r.runScript(f);h!=null&&h.ok?(i.success({title:`Ran ${f}`,text:(g=r.lastRunResult)!=null&&g.execTime?`Exec time: ${r.lastRunResult.execTime}`:void 0}),s("run-success",{alias:f})):i.error({title:`Failed ${f}`,text:((y=h==null?void 0:h.error)==null?void 0:y.message)||"Unknown error"})}function d(f){a.push({name:"script-detail",params:{type:"actions",id:f}})}return(f,h)=>(w(),G("div",Jv,[(w(!0),G(Ie,null,Yt(e.scripts,g=>(w(),K(p(Kf),{key:g.alias,title:g.name,onClick:y=>d(g.alias)},{default:k(()=>[g.icon?(w(),G("div",{key:0,innerHTML:g.icon,class:"script-icon"},null,8,Yv)):ae("",!0),g.description?(w(),G("p",Xv,N(g.description),1)):ae("",!0),D("div",Zv,[L(p(_e),{variant:g.state==="enabled"?"success":"secondary"},{default:k(()=>[U(N(g.state),1)]),_:2},1032,["variant"]),g.scope?(w(),K(p(_e),{key:0,variant:"primary"},{default:k(()=>[U(N(g.scope),1)]),_:2},1024)):ae("",!0),e.showAreaBadge&&u(g)?(w(),K(p(_e),{key:1,variant:"primary"},{default:k(()=>[U(N(u(g).display_name),1)]),_:2},1024)):ae("",!0)]),g.created_by||g.author?(w(),G("small",Qv,N(g.created_by||g.author),1)):ae("",!0)]),actions:k(()=>[p(l).has("scripts.run")?(w(),K(p(ge),{key:0,variant:"primary",icon:"ph-play",loading:p(r).isRunning(g.alias),disabled:g.state!=="enabled",onClick:Qs(y=>c(g.alias),["stop"])},{default:k(()=>[...h[0]||(h[0]=[U(" Run ",-1)])]),_:1},8,["loading","disabled","onClick"])):ae("",!0)]),_:2},1032,["title","onClick"]))),128))]))}},Ml=ze(eg,[["__scopeId","data-v-aeab265d"]]),tg={class:"page"},ng={key:3},sg={class:"area-meta"},ag={class:"actions-panel"},rg={class:"block-title"},ig={class:"devices-panel"},og={class:"block-title"},lg={class:"scripts-panel"},ug={class:"block-title"},cg={class:"form-group"},dg={key:0,class:"form-group"},fg={key:1,class:"form-group"},pg={key:2,class:"form-group"},vg={key:0,class:"form-group"},gg={key:0,class:"form-group"},hg={__name:"AreaDetailPage",setup(e){const t=sa(),n=en(),s=wt(),a=ra(),r=Ar();Sn();const o=wn(),i=Bt(),{showAssignModal:l,selectedAreaId:u,assignLoading:c,assignError:d,openAssign:f,submitAssignCore:h}=Cr(),g=Q(()=>s.areasById[String(t.params.id)]||null),y=Q(()=>g.value?r.has(g.value.id):!1),m=Q(()=>{var x;const $=[];return i.has("areas.manage")&&($.push({label:"Rename",icon:"ph-pencil",onSelect:ve}),((x=g.value)==null?void 0:x.parent_id)>0?$.push({label:"Change parent area",icon:"ph-map-pin",onSelect:Me},{label:"Unassign from parent",icon:"ph-x-circle",onSelect:Ve}):$.push({label:"Assign to area",icon:"ph-map-pin",onSelect:Me})),$.push({label:y.value?"Remove bookmark":"Bookmark",icon:y.value?"ph-fill ph-bookmark-simple":"ph-bookmark-simple",onSelect:()=>{var ee;return r.toggle((ee=g.value)==null?void 0:ee.id)}}),i.has("areas.manage")&&$.push({label:"Remove",icon:"ph-trash",danger:!0,onSelect:Ee}),$}),P=Q(()=>!g.value||g.value.parent_id<=0?null:s.areasById[String(g.value.parent_id)]||null),_=Q(()=>s.currentAreaScripts.filter($=>$.type==="action")),S=Q(()=>s.currentAreaScripts.filter($=>$.type!=="action")),E=Q(()=>{if(!g.value)return!1;const $=!g.value.parent_id||g.value.parent_id<=0,x=s.areas.filter(ee=>!ee.parent_id||ee.parent_id<=0).length;return $&&x===1});function F($){const x=new Set,ee=[$];for(;ee.length;){const v=ee.shift(),b=s.areas.filter(C=>C.parent_id===v);for(const C of b)x.add(C.id),ee.push(C.id)}return x}const I=Q(()=>{if(!g.value)return[];const $=new Set([g.value.id,...F(g.value.id)]);return s.areas.filter(x=>!$.has(x.id)).map(x=>({value:String(x.id),label:`${x.display_name} (${x.type})`}))}),T=J(!1),A=J(!1),R=J(""),Z=Zt({areaId:null,display_name:""}),ue=J(!1),de=J(""),pe=J(!1),B=J(""),q=J(!1),X=J(""),W=J(!1),te=J("");function ve(){g.value&&(Z.areaId=g.value.id,Z.display_name=g.value.display_name,R.value="",T.value=!0)}async function Se(){var x;A.value=!0,R.value="";const $=await s.renameArea(Z.areaId,Z.display_name);if(A.value=!1,!$.ok){R.value=((x=$.error)==null?void 0:x.message)||"Failed to rename area";return}T.value=!1,o.success({title:"Renamed",text:"Area renamed successfully"})}function Ee(){g.value&&(de.value=`Are you sure you want to remove area "${g.value.display_name}"?`,B.value="",ue.value=!0)}async function we(){var x;if(!g.value)return;pe.value=!0,B.value="";const $=await s.removeArea(g.value.id);if(pe.value=!1,!$.ok){B.value=((x=$.error)==null?void 0:x.message)||"Failed to remove area";return}ue.value=!1,o.success({title:"Removed",text:"Area removed successfully"}),n.push({name:"areas-tree"})}function Me(){var $;f((($=g.value)==null?void 0:$.parent_id)>0?g.value.parent_id:"")}async function je(){var ee;const $=(ee=g.value)==null?void 0:ee.id,x=await h($,(v,b)=>s.assignToArea(v,b));x!=null&&x.ok&&o.success({title:"Assigned",text:"Area assigned successfully"})}function Ve(){g.value&&(X.value=`Are you sure you want to unassign area "${g.value.display_name}" from its parent?`,te.value="",q.value=!0)}async function Te(){var x;if(!g.value)return;W.value=!0,te.value="";const $=await s.unassignArea(g.value.id);if(W.value=!1,!$.ok){te.value=((x=$.error)==null?void 0:x.message)||"Failed to unassign area";return}q.value=!1,o.success({title:"Unassigned",text:"Area unassigned from parent successfully"})}async function M(){s.currentAreaDevices.length>0&&await a.loadStatesFor(s.currentAreaDevices)}async function se(){const $=t.params.id;$&&(s.areas.length===0&&await s.loadAreas(),s.areasById[String($)]&&(await s.loadAreaDetail($),await M()))}return At(()=>t.params.id,async($,x)=>{$&&$!==x&&await se()},{immediate:!1}),_t(()=>{se()}),hs(()=>{s.clearAreaDetail()}),($,x)=>(w(),G("section",tg,[p(s).isLoading||p(s).isLoadingAreaDetail?(w(),K(bt,{key:0,text:"Loading area"})):p(s).error&&!p(s).areas.length?(w(),K(pt,{key:1,title:"Areas loading failed",error:p(s).error,retry:se},null,8,["error"])):p(s).errorAreaDetail?(w(),K(pt,{key:2,title:"Area loading failed",error:p(s).errorAreaDetail,retry:se},null,8,["error"])):g.value?(w(),G("div",ng,[L(p(Rt),{title:g.value.display_name,kicker:"Area"},{actions:k(()=>[L($r,{items:m.value},null,8,["items"])]),_:1},8,["title"]),D("div",sg,[L(p(_e),{variant:"secondary"},{default:k(()=>[U(N(g.value.type),1)]),_:1}),D("code",null,N(g.value.alias),1),L(Er,{area:P.value,areaId:g.value.parent_id},null,8,["area","areaId"])]),D("div",ag,[D("div",rg,"Actions ("+N(_.value.length)+")",1),_.value.length===0?(w(),K(rt,{key:0,title:"No actions",message:"No action scripts assigned to this area."})):(w(),K(Ml,{key:1,scripts:_.value,onRunSuccess:M},null,8,["scripts"]))]),D("div",ig,[D("div",og,"Devices ("+N(p(s).currentAreaDevices.length)+")",1),p(s).currentAreaDevices.length===0?(w(),K(rt,{key:0,title:"No devices",message:"No devices assigned to this area."})):(w(),K(Fl,{key:1,devices:p(s).currentAreaDevices,caption:"Area devices"},null,8,["devices"]))]),L(Rr,{areaId:g.value.parent_id>0?g.value.parent_id:null,title:"Parent area",emptyMessage:"This area is not assigned to any parent area.",onAssign:Me},{action:k(()=>[p(i).has("areas.manage")?(w(),K(p(ge),{key:0,variant:"primary",icon:"ph-map-pin",onClick:Me},{default:k(()=>[U(N(g.value.parent_id>0?"Change parent area":"Assign to area"),1)]),_:1})):ae("",!0)]),_:1},8,["areaId"]),D("div",lg,[D("div",ug,"Regular scripts ("+N(S.value.length)+")",1),S.value.length===0?(w(),K(rt,{key:0,title:"No regular scripts",message:"No regular scripts assigned to this area."})):(w(),K(Nl,{key:1,scripts:S.value,scriptType:"regular",showArea:!1,showActions:!1,showFilename:!1,caption:"Area regular scripts"},null,8,["scripts"]))])])):(w(),K(rt,{key:4,title:"Area not found",message:"The requested area does not exist."})),L(p(ut),{open:T.value,title:"Rename area","onUpdate:open":x[2]||(x[2]=ee=>T.value=ee)},{footer:k(()=>[L(p(ge),{variant:"secondary",onClick:x[1]||(x[1]=ee=>T.value=!1)},{default:k(()=>[...x[10]||(x[10]=[U("Cancel",-1)])]),_:1}),L(p(ge),{variant:"primary",icon:"ph-check",loading:A.value,onClick:Se},{default:k(()=>[...x[11]||(x[11]=[U("Rename",-1)])]),_:1},8,["loading"])]),default:k(()=>[D("div",cg,[L(p(xt),{modelValue:Z.display_name,"onUpdate:modelValue":x[0]||(x[0]=ee=>Z.display_name=ee),label:"Display name"},null,8,["modelValue"])]),R.value?(w(),G("div",dg,[L(p(Ze),{variant:"danger"},{default:k(()=>[U(N(R.value),1)]),_:1})])):ae("",!0)]),_:1},8,["open"]),L(p(ut),{open:p(l),title:"Assign to parent area","onUpdate:open":x[5]||(x[5]=ee=>l.value=ee)},{footer:k(()=>[L(p(ge),{variant:"secondary",onClick:x[4]||(x[4]=ee=>l.value=!1)},{default:k(()=>[...x[13]||(x[13]=[U("Cancel",-1)])]),_:1}),E.value?ae("",!0):(w(),K(p(ge),{key:0,variant:"primary",icon:"ph-check",loading:p(c),onClick:je},{default:k(()=>[...x[14]||(x[14]=[U(" Assign ",-1)])]),_:1},8,["loading"]))]),default:k(()=>[E.value?ae("",!0):(w(),K(p(mr),{key:0,modelValue:p(u),"onUpdate:modelValue":x[3]||(x[3]=ee=>Ue(u)?u.value=ee:null),label:"Parent area",options:I.value,icon:"ph-map-trifold"},null,8,["modelValue","options"])),E.value?(w(),G("div",fg,[L(p(Ze),{variant:"warning"},{default:k(()=>[...x[12]||(x[12]=[U(" This is the last root area and cannot be assigned as a child. At least one root area must remain. ",-1)])]),_:1})])):ae("",!0),p(d)?(w(),G("div",pg,[L(p(Ze),{variant:"danger"},{default:k(()=>[U(N(p(d)),1)]),_:1})])):ae("",!0)]),_:1},8,["open"]),L(p(ut),{open:q.value,title:"Unassign from parent","onUpdate:open":x[7]||(x[7]=ee=>q.value=ee)},{footer:k(()=>[L(p(ge),{variant:"secondary",onClick:x[6]||(x[6]=ee=>q.value=!1)},{default:k(()=>[...x[15]||(x[15]=[U("Cancel",-1)])]),_:1}),L(p(ge),{variant:"warning",icon:"ph-x-circle",loading:W.value,onClick:Te},{default:k(()=>[...x[16]||(x[16]=[U(" Unassign ",-1)])]),_:1},8,["loading"])]),default:k(()=>[D("p",null,N(X.value),1),te.value?(w(),G("div",vg,[L(p(Ze),{variant:"danger"},{default:k(()=>[U(N(te.value),1)]),_:1})])):ae("",!0)]),_:1},8,["open"]),L(p(ut),{open:ue.value,title:"Remove area","onUpdate:open":x[9]||(x[9]=ee=>ue.value=ee)},{footer:k(()=>[L(p(ge),{variant:"secondary",onClick:x[8]||(x[8]=ee=>ue.value=!1)},{default:k(()=>[...x[17]||(x[17]=[U("Cancel",-1)])]),_:1}),L(p(ge),{variant:"danger",icon:"ph-trash",loading:pe.value,onClick:we},{default:k(()=>[...x[18]||(x[18]=[U(" Remove ",-1)])]),_:1},8,["loading"])]),default:k(()=>[D("p",null,N(de.value),1),B.value?(w(),G("div",gg,[L(p(Ze),{variant:"danger"},{default:k(()=>[U(N(B.value),1)]),_:1})])):ae("",!0)]),_:1},8,["open"])]))}},mg=ze(hg,[["__scopeId","data-v-757a0469"]]),yg={class:"page"},_g={key:3,class:"devices-panel"},bg={class:"devices-summary"},wg=300*1e3,Sg={__name:"DevicesListPage",setup(e){const t=ra(),n=Q(()=>{if(!t.lastLoadedAt)return!1;const a=new Date(t.lastLoadedAt).getTime();return Date.now()-a>wg});async function s(){(await t.loadDevices()).ok&&await t.loadDeviceStates()}return _t(s),(a,r)=>(w(),G("section",yg,[L(p(Rt),{title:"Device Matrix",kicker:"Devices"},{actions:k(()=>[L(p(ge),{loading:p(t).isLoading||p(t).isLoadingStates,icon:"ph-arrow-clockwise",onClick:s},{default:k(()=>[...r[0]||(r[0]=[U(" Refresh ",-1)])]),_:1},8,["loading"])]),_:1}),p(t).isLoading?(w(),K(bt,{key:0,text:"Loading devices"})):p(t).error?(w(),K(pt,{key:1,title:"Devices loading failed",error:p(t).error,retry:s},null,8,["error"])):p(t).devices.length===0?(w(),K(rt,{key:2,title:"No active devices",message:"No active devices found."})):(w(),G("div",_g,[D("div",bg,[L(p(_e),{variant:"primary"},{default:k(()=>[U("Total: "+N(p(t).total),1)]),_:1}),p(t).isLoadingStates?(w(),K(p(_e),{key:0,variant:"secondary"},{default:k(()=>[...r[1]||(r[1]=[U("States loading",-1)])]),_:1})):(w(),K(p(_e),{key:1,variant:"success"},{default:k(()=>[...r[2]||(r[2]=[U("States settled",-1)])]),_:1})),n.value?(w(),K(p(_e),{key:2,variant:"warning"},{default:k(()=>[...r[3]||(r[3]=[U("Stale data",-1)])]),_:1})):ae("",!0)]),p(t).stateError?(w(),K(pt,{key:0,title:"Device states loading failed",error:p(t).stateError},null,8,["error"])):ae("",!0),L(Fl,{devices:p(t).devices,caption:"Registered devices"},null,8,["devices"])]))]))}},kg=ze(Sg,[["__scopeId","data-v-635f3900"]]),Ag=bn("scanning",()=>{const e=J("setup"),t=J([]),n=gt(),s=Q(()=>t.value.length);async function a(){return n.execute(async i=>{var u,c;const l=e.value==="setup"?await nt.scanningSetup({signal:i}):await nt.scanningAll({signal:i});return l.ok&&(t.value=((c=(u=l.data)==null?void 0:u.data)==null?void 0:c.devices)||[]),l})}function r(i){e.value=i,t.value=[],n.clear()}async function o(i){return nt.setupNewDevice(i)}return{mode:e,devices:t,isLoading:n.isLoading,error:n.error,total:s,scan:a,setMode:r,setupDevice:o}}),xg={class:"page"},Cg={class:"scan-filters"},Eg={key:3,class:"devices-panel"},Rg={class:"devices-summary"},$g={class:"device-cell"},Tg=["innerHTML"],Pg={class:"device-info"},Lg={class:"firmware"},Ig={key:1,class:"muted"},Dg={class:"form-group"},Og={class:"form-group"},Fg={class:"form-group"},Ng={key:0,class:"form-group"},Mg={__name:"DevicesScanningPage",setup(e){const t=Ag(),n=wn(),s=Bt(),a=J(!1),r=J(!1),o=J(""),i=Zt({device_ip:"",alias:"",name:"",description:""}),l={relay:'',button:'',sensor:''},u=[{key:"device",label:"Device"},{key:"status",label:"Status"},{key:"firmware",label:"Firmware"},{key:"actions",label:"Actions"}];function c(y){return l[y]||l.relay}function d(y){t.setMode(y)}function f(){t.scan()}function h(y){i.device_ip=y.ip_address,i.alias="",i.name="",i.description="",o.value="",a.value=!0}async function g(){var m;r.value=!0,o.value="";const y=await t.setupDevice({...i});if(r.value=!1,!y.ok){o.value=((m=y.error)==null?void 0:m.message)||"Failed to setup device";return}a.value=!1,n.success({title:"Device added",text:`Device ${i.alias||i.name||""} added successfully`})}return(y,m)=>(w(),G("section",xg,[L(p(Rt),{title:"Scanning",kicker:"Devices"},{actions:k(()=>[L(p(ge),{loading:p(t).isLoading,icon:"ph-magnifying-glass",onClick:f},{default:k(()=>[...m[7]||(m[7]=[U(" Scan ",-1)])]),_:1},8,["loading"])]),_:1}),D("div",Cg,[m[10]||(m[10]=D("span",{class:"filter-label text-muted"},"Mode:",-1)),L(p(Li),{selected:p(t).mode==="setup",clickable:"",icon:"ph-plug",onClick:m[0]||(m[0]=P=>d("setup"))},{default:k(()=>[...m[8]||(m[8]=[U(" Setup ",-1)])]),_:1},8,["selected"]),L(p(Li),{selected:p(t).mode==="all",clickable:"",icon:"ph-scan",onClick:m[1]||(m[1]=P=>d("all"))},{default:k(()=>[...m[9]||(m[9]=[U(" All ",-1)])]),_:1},8,["selected"])]),p(t).isLoading?(w(),K(bt,{key:0,text:"Scanning network"})):p(t).error?(w(),K(pt,{key:1,title:"Scan failed",error:p(t).error,retry:f},null,8,["error"])):p(t).devices.length===0?(w(),K(rt,{key:2,title:"No devices found",message:"Choose scan mode and click Scan to discover devices."})):(w(),G("div",Eg,[D("div",Rg,[L(p(_e),{variant:"primary"},{default:k(()=>[U(N(p(t).total)+" found",1)]),_:1})]),L(p(Nn),{columns:u,rows:p(t).devices,caption:"Discovered devices"},{"cell-device":k(({row:P})=>[D("div",$g,[D("div",{class:"device-icon",innerHTML:c(P.device_type)},null,8,Tg),D("div",Pg,[D("strong",null,N(P.device_name||"Unknown"),1),D("small",null,N(P.device_type||"unknown")+" — "+N(P.ip_address||"—"),1)])])]),"cell-status":k(({row:P})=>[L(p(_e),{variant:P.status==="setup"?"warning":"success"},{default:k(()=>[U(N(P.status||"unknown"),1)]),_:2},1032,["variant"])]),"cell-firmware":k(({row:P})=>[D("span",Lg,N(P.firmware_version||"—"),1)]),"cell-actions":k(({row:P})=>[P.status==="setup"&&p(s).has("devices.setup")?(w(),K(p(ge),{key:0,variant:"primary",icon:"ph-plus",size:"sm",onClick:_=>h(P)},{default:k(()=>[...m[11]||(m[11]=[U(" Add ",-1)])]),_:1},8,["onClick"])):(w(),G("span",Ig,"—"))]),_:1},8,["rows"])])),L(p(ut),{open:a.value,title:"Setup new device","onUpdate:open":m[6]||(m[6]=P=>a.value=P)},{footer:k(()=>[L(p(ge),{variant:"secondary",onClick:m[5]||(m[5]=P=>a.value=!1)},{default:k(()=>[...m[12]||(m[12]=[U("Cancel",-1)])]),_:1}),L(p(ge),{variant:"primary",icon:"ph-plus",loading:r.value,onClick:g},{default:k(()=>[...m[13]||(m[13]=[U(" Add device ",-1)])]),_:1},8,["loading"])]),default:k(()=>[D("div",Dg,[L(p(xt),{modelValue:i.alias,"onUpdate:modelValue":m[2]||(m[2]=P=>i.alias=P),label:"Alias",placeholder:"kitchen_relay"},null,8,["modelValue"])]),D("div",Og,[L(p(xt),{modelValue:i.name,"onUpdate:modelValue":m[3]||(m[3]=P=>i.name=P),label:"Name",placeholder:"Kitchen Relay"},null,8,["modelValue"])]),D("div",Fg,[L(p(xt),{modelValue:i.description,"onUpdate:modelValue":m[4]||(m[4]=P=>i.description=P),label:"Description"},null,8,["modelValue"])]),o.value?(w(),G("div",Ng,[L(p(Ze),{variant:"danger"},{default:k(()=>[U(N(o.value),1)]),_:1})])):ae("",!0)]),_:1},8,["open"])]))}},Ug=ze(Mg,[["__scopeId","data-v-1a01bb19"]]);function Ui(e){return encodeURIComponent(String(e))}const zn={async list(){return De("/api/v1/firmwares")},async detail(e){return De(`/api/v1/firmwares/id/${Ui(e)}`)},async refresh(){return Qe("/api/v1/firmwares/refresh")},async deviceCompatibility(e){return De(`/api/v1/devices/id/${Ui(e)}/firmware-compatibility`)},async updateDeviceFirmware(e,t){return Qe("/api/v1/devices/update-firmware",{device_id:e,firmware_id:t})}},Ul=bn("firmwares",()=>{const e=J([]),t=J(null),n=J(null),s=gt(),a=gt(),r=gt(),o=gt(),i=Q(()=>s.isLoading.value),l=Q(()=>a.isLoading.value),u=Q(()=>r.isLoading.value),c=Q(()=>o.isLoading.value);async function d(){return s.execute(async P=>{var S,E;const _=await zn.list({signal:P});return _.ok&&(e.value=((E=(S=_.data)==null?void 0:S.data)==null?void 0:E.firmwares)||[]),_})}async function f(){return r.execute(async()=>{const P=await zn.refresh();return P.ok&&await d(),P})}async function h(P){return a.execute(async _=>{var E,F;const S=await zn.detail(P,{signal:_});return S.ok&&(t.value=((F=(E=S.data)==null?void 0:E.data)==null?void 0:F.firmware)||null),S})}async function g(P){return o.execute(async _=>{var E,F,I,T;const S=await zn.deviceCompatibility(P,{signal:_});return S.ok&&(n.value={compatible:((F=(E=S.data)==null?void 0:E.data)==null?void 0:F.compatible)||[],currentVersion:((T=(I=S.data)==null?void 0:I.data)==null?void 0:T.current_version)||"unknown"}),S})}async function y(P,_){return r.execute(async()=>zn.updateDeviceFirmware(P,_))}function m(){n.value=null}return{firmwares:e,current:t,compatibility:n,isLoadingList:i,isLoadingDetail:l,isUpdating:u,isLoadingCompatibility:c,loadFirmwares:d,refreshFirmwares:f,loadFirmwareDetail:h,loadDeviceCompatibility:g,updateDeviceFirmware:y,clearCompatibility:m}}),Bg={class:"page"},jg={key:2},Vg={class:"device-meta"},Hg={class:"script-info-panel"},Gg={class:"info-row"},qg={class:"info-value"},zg={class:"info-row"},Kg={class:"info-value"},Wg={class:"info-row"},Jg={class:"info-value"},Yg={class:"info-row"},Xg={class:"info-value"},Zg={class:"info-row"},Qg={class:"info-value"},eh={class:"info-row"},th={class:"info-value"},nh={class:"info-row"},sh={class:"info-value"},ah={key:0,class:"info-row"},rh=["title"],ih={key:1,class:"info-row"},oh={class:"info-value"},lh={key:0,class:"devices-panel"},uh={key:1,class:"devices-panel"},ch={class:"form-group"},dh={class:"form-group"},fh={class:"form-group"},ph={key:0,class:"form-group"},vh={key:0,class:"form-group"},gh={key:0,class:"form-group"},hh={key:0,class:"form-group"},mh={key:0,class:"form-group"},yh={key:0,class:"form-group"},_h={class:"firmware-options"},bh=["onClick"],wh={class:"fw-version"},Sh={key:0,class:"fw-desc"},kh={key:0,class:"form-group"},Ah={__name:"DeviceDetailPage",setup(e){const t=sa(),n=en(),s=ra(),a=wt(),r=Ul(),o=wn(),i=Bt(),{areaOptions:l,showAssignModal:u,selectedAreaId:c,assignLoading:d,assignError:f,openAssign:h,submitAssignCore:g}=Cr(),y=Q(()=>t.params.id),m=Q(()=>s.currentDevice),P=Q(()=>s.isLoadingDetail),_=Q(()=>s.errorDetail),S=J(!1),E=J(null),F=Q(()=>{var O;const ie=(O=m.value)==null?void 0:O.area_id;return ie&&a.areasById[String(ie)]||null}),I=J(!1),T=J(!1),A=J(""),R=Zt({name:"",description:"",alias:""}),Z=J(!1),ue=J(""),de=J(!1),pe=J(""),B=J(!1),q=J(""),X=J(!1),W=J(""),te=J(!1),ve=J(""),Se=J(!1),Ee=J(""),we=J(!1),Me=J(""),je=J(!1),Ve=J(""),Te=J(!1),M=J(null),se=J(""),$=Q(()=>{var ie,O;return(((O=(ie=r.compatibility)==null?void 0:ie.compatible)==null?void 0:O.length)||0)>0}),x=Q(()=>{var ie;return((ie=r.compatibility)==null?void 0:ie.compatible)||[]}),ee=Q(()=>{var O,Le;const ie=[];return i.has("devices.edit")&&(ie.push({label:"Edit",icon:"ph-pencil",onSelect:v}),(O=m.value)!=null&&O.area_id?ie.push({label:"Change area",icon:"ph-map-pin",onSelect:C},{label:"Unassign from area",icon:"ph-x-circle",onSelect:z}):ie.push({label:"Assign to area",icon:"ph-map-pin",onSelect:C})),i.has("devices.setup")&&ie.push({label:"ReSetup",icon:"ph-gear",onSelect:Y}),i.has("devices.control")&&ie.push({label:"Reboot",icon:"ph-arrow-clockwise",disabled:s.isRebooting((Le=m.value)==null?void 0:Le.id),onSelect:ne}),i.has("devices.edit")&&ie.push({label:"Reset",icon:"ph-x",danger:!0,onSelect:le}),i.has("devices.delete")&&ie.push({label:"Remove",icon:"ph-trash",danger:!0,onSelect:oe}),ie});function v(){m.value&&(R.name=m.value.name||"",R.description=m.value.description||"",R.alias=m.value.alias||"",A.value="",I.value=!0)}async function b(){var et,he,We,Ke;T.value=!0,A.value="";const ie=y.value,O=await Promise.all([R.name!==((et=m.value)==null?void 0:et.name)?s.updateDeviceName(ie,R.name):{ok:!0},R.description!==((he=m.value)==null?void 0:he.description)?s.updateDeviceDescription(ie,R.description):{ok:!0},R.alias!==((We=m.value)==null?void 0:We.alias)?s.updateDeviceAlias(ie,R.alias):{ok:!0}]);T.value=!1;const Le=O.find(Bn=>!Bn.ok);if(Le){A.value=((Ke=Le.error)==null?void 0:Ke.message)||"Failed to update device";return}I.value=!1,o.success({title:"Updated",text:"Device updated successfully"})}function C(){var ie;h((ie=m.value)==null?void 0:ie.area_id)}async function j(){const ie=await g(y.value,s.assignToArea.bind(s));ie!=null&&ie.ok&&o.success({title:"Assigned",text:"Device assigned to area successfully"})}function z(){m.value&&(q.value=`Are you sure you want to unassign device "${m.value.name||m.value.alias}" from its area?`,W.value="",B.value=!0)}async function H(){var O;if(!m.value)return;X.value=!0,W.value="";const ie=await s.unassignDevice(y.value);if(X.value=!1,!ie.ok){W.value=((O=ie.error)==null?void 0:O.message)||"Failed to unassign device";return}B.value=!1,o.success({title:"Unassigned",text:"Device unassigned from area successfully"})}function oe(){m.value&&(ue.value=`Are you sure you want to remove device "${m.value.name||m.value.alias}"?`,pe.value="",Z.value=!0)}async function re(){var Le;const ie=y.value;de.value=!0,pe.value="";const O=await s.removeDevice(ie);if(de.value=!1,!O.ok){pe.value=((Le=O.error)==null?void 0:Le.message)||"Failed to remove device";return}Z.value=!1,o.success({title:"Removed",text:"Device removed successfully"}),n.push({name:"devices"})}async function ne(){var O;if(!m.value)return;const ie=await s.rebootDevice(m.value.id);ie.ok?o.success({title:"Rebooting",text:`Device ${m.value.name||m.value.alias||"#"+m.value.id} is rebooting`}):o.error({title:"Reboot failed",text:((O=ie.error)==null?void 0:O.message)||"Failed to reboot device"})}function Y(){m.value&&(ve.value=`Are you sure you want to repeat setup for device "${m.value.name||m.value.alias}"?`,Ee.value="",te.value=!0)}async function fe(){var Le,et,he;const ie=y.value;Se.value=!0,Ee.value="";const O=await s.resetupDevice(ie);if(Se.value=!1,!O.ok){Ee.value=((Le=O.error)==null?void 0:Le.message)||"Failed to repeat device setup";return}te.value=!1,o.success({title:"Success",text:`Device ${((et=m.value)==null?void 0:et.name)||((he=m.value)==null?void 0:he.alias)||"#"+ie} setup repeated`}),n.push({name:"devices"})}function le(){m.value&&(Me.value=`Are you sure you want to reset device "${m.value.name||m.value.alias}"?`,Ve.value="",we.value=!0)}async function ce(){var Le,et,he;const ie=y.value;je.value=!0,Ve.value="";const O=await s.resetDevice(ie);if(je.value=!1,!O.ok){Ve.value=((Le=O.error)==null?void 0:Le.message)||"Failed to reset device";return}we.value=!1,o.success({title:"Success",text:`Device ${((et=m.value)==null?void 0:et.name)||((he=m.value)==null?void 0:he.alias)||"#"+ie} reset`}),n.push({name:"devices"})}function me(){var ie;M.value=((ie=x.value[0])==null?void 0:ie.id)||null,se.value="",Te.value=!0}async function ke(){var O;if(!M.value||!m.value)return;const ie=await r.updateDeviceFirmware(m.value.id,M.value);if(!ie.ok){se.value=((O=ie.error)==null?void 0:O.message)||"Firmware update failed";return}Te.value=!1,o.success({title:"Updated",text:"Firmware update pushed successfully"}),await s.loadDeviceDetail(y.value)}function Re(ie){return{active:"success",removed:"danger",freezed:"warning",setup:"primary"}[ie]||"secondary"}async function Pe(){const ie=y.value;if(!ie||!m.value||m.value.connection_status!=="active")return;S.value=!0,E.value=null;const O=await s.loadDeviceStatus(ie);S.value=!1,O.ok||(E.value=O.error)}async function Be(){var O;const ie=y.value;ie&&(a.areas.length===0&&await a.loadAreas(),await s.loadDeviceDetail(ie),((O=m.value)==null?void 0:O.connection_status)==="active"&&(await Pe(),await r.loadDeviceCompatibility(ie)))}return _t(()=>{Be()}),hs(()=>{s.clearDeviceDetail(),r.clearCompatibility()}),At(()=>t.params.id,(ie,O)=>{ie!==O&&(s.clearDeviceDetail(),Be())}),(ie,O)=>{var Le,et;return w(),G("section",Bg,[P.value?(w(),K(bt,{key:0,text:"Loading device details"})):_.value?(w(),K(pt,{key:1,title:"Device loading failed",error:_.value,retry:Be},null,8,["error"])):m.value?(w(),G("div",jg,[L(p(Rt),{title:m.value.name||m.value.alias||`Device #${m.value.id}`,kicker:"Device"},{actions:k(()=>[L($r,{items:ee.value},null,8,["items"])]),_:1},8,["title"]),D("div",Vg,[L(p(_e),{variant:m.value.connection_status==="active"?"success":"danger"},{default:k(()=>[U(N(m.value.connection_status==="active"?"Online":"Offline"),1)]),_:1},8,["variant"]),D("code",null,N(m.value.alias),1),L(Er,{area:F.value,areaId:m.value.area_id},null,8,["area","areaId"])]),D("div",Hg,[D("div",Gg,[O[18]||(O[18]=D("span",{class:"info-label text-muted"},"System status:",-1)),D("span",qg,[L(p(_e),{variant:Re(m.value.status)},{default:k(()=>[U(N(m.value.status),1)]),_:1},8,["variant"])])]),D("div",zg,[O[19]||(O[19]=D("span",{class:"info-label text-muted"},"Type:",-1)),D("span",Kg,N(m.value.device_type),1)]),D("div",Wg,[O[20]||(O[20]=D("span",{class:"info-label text-muted"},"State:",-1)),D("span",Jg,[L(Ol,{"device-type":m.value.device_type,response:(Le=p(s).currentDeviceStatus)==null?void 0:Le.raw,loading:S.value,error:(et=E.value)==null?void 0:et.message,"connection-status":m.value.connection_status},null,8,["device-type","response","loading","error","connection-status"])])]),D("div",Yg,[O[21]||(O[21]=D("span",{class:"info-label text-muted"},"IP:",-1)),D("span",Xg,N(m.value.device_ip),1)]),D("div",Zg,[O[22]||(O[22]=D("span",{class:"info-label text-muted"},"MAC:",-1)),D("span",Qg,N(m.value.device_mac),1)]),D("div",eh,[O[23]||(O[23]=D("span",{class:"info-label text-muted"},"Hard ID:",-1)),D("span",th,N(m.value.device_hard_id),1)]),D("div",nh,[O[24]||(O[24]=D("span",{class:"info-label text-muted"},"Firmware:",-1)),D("span",sh,N(m.value.firmware_version),1)]),m.value.last_contact?(w(),G("div",ah,[O[25]||(O[25]=D("span",{class:"info-label text-muted"},"Last contact:",-1)),D("span",{class:"info-value",title:p(Wa)(m.value.last_contact)},N(p(Il)(m.value.last_contact)),9,rh)])):ae("",!0),m.value.create_at?(w(),G("div",ih,[O[26]||(O[26]=D("span",{class:"info-label text-muted"},"Created:",-1)),D("span",oh,N(p(Wa)(m.value.create_at)),1)])):ae("",!0)]),L(Rr,{item:m.value,emptyMessage:"This device is not assigned to any area.",onAssign:C},{action:k(()=>[p(i).has("devices.edit")?(w(),K(p(ge),{key:0,variant:"primary",icon:"ph-map-pin",onClick:C},{default:k(()=>{var he;return[U(N((he=m.value)!=null&&he.area_id?"Change area":"Assign to area"),1)]}),_:1})):ae("",!0)]),_:1},8,["item"]),$.value&&p(i).has("firmware.upload")?(w(),G("div",lh,[O[29]||(O[29]=D("div",{class:"block-title"},"Firmware Update",-1)),L(p(Ze),{variant:"info"},{default:k(()=>[O[27]||(O[27]=U(" New firmware available: ",-1)),(w(!0),G(Ie,null,Yt(x.value,he=>(w(),K(p(_e),{key:he.id,variant:"success"},{default:k(()=>[U(N(he.version),1)]),_:2},1024))),128))]),_:1}),L(p(ge),{variant:"primary",icon:"ph-cloud-arrow-down",onClick:me},{default:k(()=>[...O[28]||(O[28]=[U(" Update Firmware ",-1)])]),_:1})])):ae("",!0),m.value.description?(w(),G("div",uh,[O[30]||(O[30]=D("div",{class:"block-title"},"Description",-1)),D("p",null,N(m.value.description),1)])):ae("",!0)])):(w(),K(rt,{key:3,title:"Device not found",message:"The requested device does not exist."})),L(p(ut),{open:I.value,title:"Edit device","onUpdate:open":O[4]||(O[4]=he=>I.value=he)},{footer:k(()=>[L(p(ge),{variant:"secondary",onClick:O[3]||(O[3]=he=>I.value=!1)},{default:k(()=>[...O[31]||(O[31]=[U("Cancel",-1)])]),_:1}),L(p(ge),{variant:"primary",icon:"ph-check",loading:T.value,onClick:b},{default:k(()=>[...O[32]||(O[32]=[U(" Save ",-1)])]),_:1},8,["loading"])]),default:k(()=>[D("div",ch,[L(p(xt),{modelValue:R.name,"onUpdate:modelValue":O[0]||(O[0]=he=>R.name=he),label:"Name"},null,8,["modelValue"])]),D("div",dh,[L(p(xt),{modelValue:R.description,"onUpdate:modelValue":O[1]||(O[1]=he=>R.description=he),label:"Description"},null,8,["modelValue"])]),D("div",fh,[L(p(xt),{modelValue:R.alias,"onUpdate:modelValue":O[2]||(O[2]=he=>R.alias=he),label:"Alias"},null,8,["modelValue"])]),A.value?(w(),G("div",ph,[L(p(Ze),{variant:"danger"},{default:k(()=>[U(N(A.value),1)]),_:1})])):ae("",!0)]),_:1},8,["open"]),L(p(ut),{open:p(u),title:"Assign to area","onUpdate:open":O[7]||(O[7]=he=>u.value=he)},{footer:k(()=>[L(p(ge),{variant:"secondary",onClick:O[6]||(O[6]=he=>u.value=!1)},{default:k(()=>[...O[33]||(O[33]=[U("Cancel",-1)])]),_:1}),L(p(ge),{variant:"primary",icon:"ph-check",loading:p(d),onClick:j},{default:k(()=>[...O[34]||(O[34]=[U(" Assign ",-1)])]),_:1},8,["loading"])]),default:k(()=>[L(p(mr),{modelValue:p(c),"onUpdate:modelValue":O[5]||(O[5]=he=>Ue(c)?c.value=he:null),label:"Area",options:p(l),icon:"ph-map-trifold"},null,8,["modelValue","options"]),p(f)?(w(),G("div",vh,[L(p(Ze),{variant:"danger"},{default:k(()=>[U(N(p(f)),1)]),_:1})])):ae("",!0)]),_:1},8,["open"]),L(p(ut),{open:B.value,title:"Unassign from area","onUpdate:open":O[9]||(O[9]=he=>B.value=he)},{footer:k(()=>[L(p(ge),{variant:"secondary",onClick:O[8]||(O[8]=he=>B.value=!1)},{default:k(()=>[...O[35]||(O[35]=[U("Cancel",-1)])]),_:1}),L(p(ge),{variant:"warning",icon:"ph-x-circle",loading:X.value,onClick:H},{default:k(()=>[...O[36]||(O[36]=[U(" Unassign ",-1)])]),_:1},8,["loading"])]),default:k(()=>[D("p",null,N(q.value),1),W.value?(w(),G("div",gh,[L(p(Ze),{variant:"danger"},{default:k(()=>[U(N(W.value),1)]),_:1})])):ae("",!0)]),_:1},8,["open"]),L(p(ut),{open:Z.value,title:"Remove device","onUpdate:open":O[11]||(O[11]=he=>Z.value=he)},{footer:k(()=>[L(p(ge),{variant:"secondary",onClick:O[10]||(O[10]=he=>Z.value=!1)},{default:k(()=>[...O[37]||(O[37]=[U("Cancel",-1)])]),_:1}),L(p(ge),{variant:"danger",icon:"ph-trash",loading:de.value,onClick:re},{default:k(()=>[...O[38]||(O[38]=[U(" Remove ",-1)])]),_:1},8,["loading"])]),default:k(()=>[D("p",null,N(ue.value),1),pe.value?(w(),G("div",hh,[L(p(Ze),{variant:"danger"},{default:k(()=>[U(N(pe.value),1)]),_:1})])):ae("",!0)]),_:1},8,["open"]),L(p(ut),{open:te.value,title:"Repeat device setup","onUpdate:open":O[13]||(O[13]=he=>te.value=he)},{footer:k(()=>[L(p(ge),{variant:"secondary",onClick:O[12]||(O[12]=he=>te.value=!1)},{default:k(()=>[...O[39]||(O[39]=[U("Cancel",-1)])]),_:1}),L(p(ge),{variant:"primary",icon:"ph-gear",loading:Se.value,onClick:fe},{default:k(()=>[...O[40]||(O[40]=[U(" ReSetup ",-1)])]),_:1},8,["loading"])]),default:k(()=>[D("p",null,N(ve.value),1),Ee.value?(w(),G("div",mh,[L(p(Ze),{variant:"danger"},{default:k(()=>[U(N(Ee.value),1)]),_:1})])):ae("",!0)]),_:1},8,["open"]),L(p(ut),{open:we.value,title:"Reset device","onUpdate:open":O[15]||(O[15]=he=>we.value=he)},{footer:k(()=>[L(p(ge),{variant:"secondary",onClick:O[14]||(O[14]=he=>we.value=!1)},{default:k(()=>[...O[41]||(O[41]=[U("Cancel",-1)])]),_:1}),L(p(ge),{variant:"danger",icon:"ph-x",loading:je.value,onClick:ce},{default:k(()=>[...O[42]||(O[42]=[U(" Reset ",-1)])]),_:1},8,["loading"])]),default:k(()=>[D("p",null,N(Me.value),1),Ve.value?(w(),G("div",yh,[L(p(Ze),{variant:"danger"},{default:k(()=>[U(N(Ve.value),1)]),_:1})])):ae("",!0)]),_:1},8,["open"]),L(p(ut),{open:Te.value,title:"Update Firmware","onUpdate:open":O[17]||(O[17]=he=>Te.value=he)},{footer:k(()=>[L(p(ge),{variant:"secondary",onClick:O[16]||(O[16]=he=>Te.value=!1)},{default:k(()=>[...O[45]||(O[45]=[U("Cancel",-1)])]),_:1}),L(p(ge),{variant:"primary",icon:"ph-check",loading:p(r).isUpdating,disabled:!M.value,onClick:ke},{default:k(()=>[...O[46]||(O[46]=[U(" Update ",-1)])]),_:1},8,["loading","disabled"])]),default:k(()=>{var he,We;return[D("p",null,[O[43]||(O[43]=U("Select firmware to install on ",-1)),D("strong",null,N(((he=m.value)==null?void 0:he.name)||((We=m.value)==null?void 0:We.alias)),1),O[44]||(O[44]=U(":",-1))]),D("div",_h,[(w(!0),G(Ie,null,Yt(x.value,Ke=>(w(),G("div",{key:Ke.id,class:Mt(["firmware-option",{active:M.value===Ke.id}]),onClick:Bn=>M.value=Ke.id},[D("div",wh,N(Ke.version),1),Ke.description?(w(),G("div",Sh,N(Ke.description),1)):ae("",!0)],10,bh))),128))]),se.value?(w(),G("div",kh,[L(p(Ze),{variant:"danger"},{default:k(()=>[U(N(se.value),1)]),_:1})])):ae("",!0)]}),_:1},8,["open"])])}}},xh=ze(Ah,[["__scopeId","data-v-a9f83185"]]),Ch={class:"page"},Eh={__name:"ScriptsActionsPage",setup(e){const t=Sn(),n=wt();return _t(()=>{t.loadActions(),n.areas.length===0&&n.loadAreas()}),(s,a)=>(w(),G("section",Ch,[L(p(Rt),{title:"Actions",kicker:"Scripts"},{actions:k(()=>[L(p(_e),{variant:"primary"},{default:k(()=>[U(N(p(t).totalActions)+" scripts",1)]),_:1})]),_:1}),p(t).isLoadingActions?(w(),K(bt,{key:0,text:"Loading actions"})):p(t).errorActions?(w(),K(pt,{key:1,title:"Actions loading failed",error:p(t).errorActions,retry:p(t).loadActions},null,8,["error","retry"])):p(t).actions.length===0?(w(),K(rt,{key:2,title:"No action scripts",message:"No action scripts registered."})):(w(),K(Ml,{key:3,scripts:p(t).actions,"show-area-badge":""},null,8,["scripts"]))]))}},Rh=ze(Eh,[["__scopeId","data-v-f336617a"]]),$h={class:"page"},Th={key:3,class:"devices-panel"},Ph={__name:"ScriptsRegularPage",setup(e){const t=Sn(),n=wt();return _t(()=>{t.loadRegular(),n.areas.length===0&&n.loadAreas()}),(s,a)=>(w(),G("section",$h,[L(p(Rt),{title:"Regular",kicker:"Scripts"},{actions:k(()=>[L(p(_e),{variant:"primary"},{default:k(()=>[U(N(p(t).totalRegular)+" scripts",1)]),_:1})]),_:1}),p(t).isLoadingRegular?(w(),K(bt,{key:0,text:"Loading regular scripts"})):p(t).errorRegular?(w(),K(pt,{key:1,title:"Regular scripts loading failed",error:p(t).errorRegular,retry:p(t).loadRegular},null,8,["error","retry"])):p(t).regular.length===0?(w(),K(rt,{key:2,title:"No regular scripts",message:"No regular scripts registered."})):(w(),G("div",Th,[L(Nl,{scripts:p(t).regular,scriptType:"regular",showArea:!0,showScope:!0,showFilename:!0,showActions:!0,caption:"Regular scripts"},null,8,["scripts"])]))]))}},Lh={class:"page"},Ih={key:3,class:"devices-panel"},Dh={__name:"ScriptsScopesPage",setup(e){en();const t=Sn(),n=Bt(),s=[{key:"name",label:"Name"},{key:"filename",label:"File"},{key:"state",label:"State"},{key:"path",label:"Path"},{key:"actions",label:"Actions"}];function a(r,o){t.setScopeState(r,o)}return _t(()=>{t.loadScopes()}),(r,o)=>{const i=cn("router-link");return w(),G("section",Lh,[L(p(Rt),{title:"Scopes",kicker:"Scripts"},{actions:k(()=>[L(p(_e),{variant:"primary"},{default:k(()=>[U(N(p(t).totalScopes)+" scopes",1)]),_:1})]),_:1}),p(t).isLoadingScopes?(w(),K(bt,{key:0,text:"Loading scopes"})):p(t).errorScopes?(w(),K(pt,{key:1,title:"Scopes loading failed",error:p(t).errorScopes,retry:p(t).loadScopes},null,8,["error","retry"])):p(t).scopes.length===0?(w(),K(rt,{key:2,title:"No scopes",message:"No script scopes registered."})):(w(),G("div",Ih,[L(p(Nn),{columns:s,rows:p(t).scopes,caption:"Script scopes"},{"cell-name":k(({row:l})=>[L(i,{to:{name:"script-detail",params:{type:"scopes",id:l.name}},class:"script-link"},{default:k(()=>[U(N(l.name),1)]),_:2},1032,["to"])]),"cell-state":k(({row:l})=>[L(p(_e),{variant:l.state==="enabled"?"success":"secondary"},{default:k(()=>[U(N(l.state),1)]),_:2},1032,["variant"])]),"cell-actions":k(({row:l})=>[l.state==="enabled"&&p(n).has("scripts.edit")?(w(),K(p(ge),{key:0,variant:"secondary",icon:"ph-pause",onClick:u=>a(l.name,!1)},{default:k(()=>[...o[0]||(o[0]=[U(" Disable ",-1)])]),_:1},8,["onClick"])):p(n).has("scripts.edit")?(w(),K(p(ge),{key:1,variant:"primary",icon:"ph-play",onClick:u=>a(l.name,!0)},{default:k(()=>[...o[1]||(o[1]=[U(" Enable ",-1)])]),_:1},8,["onClick"])):ae("",!0)]),_:1},8,["rows"])]))])}}},Oh=ze(Dh,[["__scopeId","data-v-c8486788"]]);var Bi=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function Fh(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var xa={exports:{}},ji;function Nh(){return ji||(ji=1,(function(e){var t=typeof window<"u"?window:typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope?self:{};/** - * Prism: Lightweight, robust, elegant syntax highlighting - * - * @license MIT - * @author Lea Verou - * @namespace - * @public - */var n=(function(s){var a=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,r=0,o={},i={manual:s.Prism&&s.Prism.manual,disableWorkerMessageHandler:s.Prism&&s.Prism.disableWorkerMessageHandler,util:{encode:function _(S){return S instanceof l?new l(S.type,_(S.content),S.alias):Array.isArray(S)?S.map(_):S.replace(/&/g,"&").replace(/"u")return null;if(document.currentScript&&document.currentScript.tagName==="SCRIPT")return document.currentScript;try{throw new Error}catch(F){var _=(/at [^(\r\n]*\((.*):[^:]+:[^:]+\)$/i.exec(F.stack)||[])[1];if(_){var S=document.getElementsByTagName("script");for(var E in S)if(S[E].src==_)return S[E]}return null}},isActive:function(_,S,E){for(var F="no-"+S;_;){var I=_.classList;if(I.contains(S))return!0;if(I.contains(F))return!1;_=_.parentElement}return!!E}},languages:{plain:o,plaintext:o,text:o,txt:o,extend:function(_,S){var E=i.util.clone(i.languages[_]);for(var F in S)E[F]=S[F];return E},insertBefore:function(_,S,E,F){F=F||i.languages;var I=F[_],T={};for(var A in I)if(I.hasOwnProperty(A)){if(A==S)for(var R in E)E.hasOwnProperty(R)&&(T[R]=E[R]);E.hasOwnProperty(A)||(T[A]=I[A])}var Z=F[_];return F[_]=T,i.languages.DFS(i.languages,function(ue,de){de===Z&&ue!=_&&(this[ue]=T)}),T},DFS:function _(S,E,F,I){I=I||{};var T=i.util.objId;for(var A in S)if(S.hasOwnProperty(A)){E.call(S,A,S[A],F||A);var R=S[A],Z=i.util.type(R);Z==="Object"&&!I[T(R)]?(I[T(R)]=!0,_(R,E,null,I)):Z==="Array"&&!I[T(R)]&&(I[T(R)]=!0,_(R,E,A,I))}}},plugins:{},highlightAll:function(_,S){i.highlightAllUnder(document,_,S)},highlightAllUnder:function(_,S,E){var F={callback:E,container:_,selector:'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'};i.hooks.run("before-highlightall",F),F.elements=Array.prototype.slice.apply(F.container.querySelectorAll(F.selector)),i.hooks.run("before-all-elements-highlight",F);for(var I=0,T;T=F.elements[I++];)i.highlightElement(T,S===!0,F.callback)},highlightElement:function(_,S,E){var F=i.util.getLanguage(_),I=i.languages[F];i.util.setLanguage(_,F);var T=_.parentElement;T&&T.nodeName.toLowerCase()==="pre"&&i.util.setLanguage(T,F);var A=_.textContent,R={element:_,language:F,grammar:I,code:A};function Z(de){R.highlightedCode=de,i.hooks.run("before-insert",R),R.element.innerHTML=R.highlightedCode,i.hooks.run("after-highlight",R),i.hooks.run("complete",R),E&&E.call(R.element)}if(i.hooks.run("before-sanity-check",R),T=R.element.parentElement,T&&T.nodeName.toLowerCase()==="pre"&&!T.hasAttribute("tabindex")&&T.setAttribute("tabindex","0"),!R.code){i.hooks.run("complete",R),E&&E.call(R.element);return}if(i.hooks.run("before-highlight",R),!R.grammar){Z(i.util.encode(R.code));return}if(S&&s.Worker){var ue=new Worker(i.filename);ue.onmessage=function(de){Z(de.data)},ue.postMessage(JSON.stringify({language:R.language,code:R.code,immediateClose:!0}))}else Z(i.highlight(R.code,R.grammar,R.language))},highlight:function(_,S,E){var F={code:_,grammar:S,language:E};if(i.hooks.run("before-tokenize",F),!F.grammar)throw new Error('The language "'+F.language+'" has no grammar.');return F.tokens=i.tokenize(F.code,F.grammar),i.hooks.run("after-tokenize",F),l.stringify(i.util.encode(F.tokens),F.language)},tokenize:function(_,S){var E=S.rest;if(E){for(var F in E)S[F]=E[F];delete S.rest}var I=new d;return f(I,I.head,_),c(_,I,S,I.head,0),g(I)},hooks:{all:{},add:function(_,S){var E=i.hooks.all;E[_]=E[_]||[],E[_].push(S)},run:function(_,S){var E=i.hooks.all[_];if(!(!E||!E.length))for(var F=0,I;I=E[F++];)I(S)}},Token:l};s.Prism=i;function l(_,S,E,F){this.type=_,this.content=S,this.alias=E,this.length=(F||"").length|0}l.stringify=function _(S,E){if(typeof S=="string")return S;if(Array.isArray(S)){var F="";return S.forEach(function(Z){F+=_(Z,E)}),F}var I={type:S.type,content:_(S.content,E),tag:"span",classes:["token",S.type],attributes:{},language:E},T=S.alias;T&&(Array.isArray(T)?Array.prototype.push.apply(I.classes,T):I.classes.push(T)),i.hooks.run("wrap",I);var A="";for(var R in I.attributes)A+=" "+R+'="'+(I.attributes[R]||"").replace(/"/g,""")+'"';return"<"+I.tag+' class="'+I.classes.join(" ")+'"'+A+">"+I.content+""};function u(_,S,E,F){_.lastIndex=S;var I=_.exec(E);if(I&&F&&I[1]){var T=I[1].length;I.index+=T,I[0]=I[0].slice(T)}return I}function c(_,S,E,F,I,T){for(var A in E)if(!(!E.hasOwnProperty(A)||!E[A])){var R=E[A];R=Array.isArray(R)?R:[R];for(var Z=0;Z=T.reach);ve+=te.value.length,te=te.next){var Se=te.value;if(S.length>_.length)return;if(!(Se instanceof l)){var Ee=1,we;if(B){if(we=u(W,ve,_,pe),!we||we.index>=_.length)break;var Te=we.index,Me=we.index+we[0].length,je=ve;for(je+=te.value.length;Te>=je;)te=te.next,je+=te.value.length;if(je-=te.value.length,ve=je,te.value instanceof l)continue;for(var Ve=te;Ve!==S.tail&&(jeT.reach&&(T.reach=x);var ee=te.prev;se&&(ee=f(S,ee,se),ve+=se.length),h(S,ee,Ee);var v=new l(A,de?i.tokenize(M,de):M,q,M);if(te=f(S,ee,v),$&&f(S,te,$),Ee>1){var b={cause:A+","+Z,reach:x};c(_,S,E,te.prev,ve,b),T&&b.reach>T.reach&&(T.reach=b.reach)}}}}}}function d(){var _={value:null,prev:null,next:null},S={value:null,prev:_,next:null};_.next=S,this.head=_,this.tail=S,this.length=0}function f(_,S,E){var F=S.next,I={value:E,prev:S,next:F};return S.next=I,F.prev=I,_.length++,I}function h(_,S,E){for(var F=S.next,I=0;I/,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},{pattern:/^(\s*)["']|["']$/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},n.languages.markup.tag.inside["attr-value"].inside.entity=n.languages.markup.entity,n.languages.markup.doctype.inside["internal-subset"].inside=n.languages.markup,n.hooks.add("wrap",function(s){s.type==="entity"&&(s.attributes.title=s.content.replace(/&/,"&"))}),Object.defineProperty(n.languages.markup.tag,"addInlined",{value:function(a,r){var o={};o["language-"+r]={pattern:/(^$)/i,lookbehind:!0,inside:n.languages[r]},o.cdata=/^$/i;var i={"included-cdata":{pattern://i,inside:o}};i["language-"+r]={pattern:/[\s\S]+/,inside:n.languages[r]};var l={};l[a]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,function(){return a}),"i"),lookbehind:!0,greedy:!0,inside:i},n.languages.insertBefore("markup","cdata",l)}}),Object.defineProperty(n.languages.markup.tag,"addAttribute",{value:function(s,a){n.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+s+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[a,"language-"+a],inside:n.languages[a]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),n.languages.html=n.languages.markup,n.languages.mathml=n.languages.markup,n.languages.svg=n.languages.markup,n.languages.xml=n.languages.extend("markup",{}),n.languages.ssml=n.languages.xml,n.languages.atom=n.languages.xml,n.languages.rss=n.languages.xml,(function(s){var a=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;s.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:RegExp("@[\\w-](?:"+/[^;{\s"']|\s+(?!\s)/.source+"|"+a.source+")*?"+/(?:;|(?=\s*\{))/.source),inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+a.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+a.source+"$"),alias:"url"}}},selector:{pattern:RegExp(`(^|[{}\\s])[^{}\\s](?:[^{};"'\\s]|\\s+(?![\\s{])|`+a.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:a,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},s.languages.css.atrule.inside.rest=s.languages.css;var r=s.languages.markup;r&&(r.tag.addInlined("style","css"),r.tag.addAttribute("style","css"))})(n),n.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},n.languages.javascript=n.languages.extend("clike",{"class-name":[n.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+(/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source)+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),n.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,n.languages.insertBefore("javascript","keyword",{regex:{pattern:RegExp(/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source+/\//.source+"(?:"+/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/.source+"|"+/(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/.source+")"+/(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source),lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:n.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:n.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:n.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:n.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:n.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),n.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:n.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),n.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),n.languages.markup&&(n.languages.markup.tag.addInlined("script","javascript"),n.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),n.languages.js=n.languages.javascript,(function(){if(typeof n>"u"||typeof document>"u")return;Element.prototype.matches||(Element.prototype.matches=Element.prototype.msMatchesSelector||Element.prototype.webkitMatchesSelector);var s="Loading…",a=function(y,m){return"✖ Error "+y+" while fetching file: "+m},r="✖ Error: File does not exist or is empty",o={js:"javascript",py:"python",rb:"ruby",ps1:"powershell",psm1:"powershell",sh:"bash",bat:"batch",h:"c",tex:"latex"},i="data-src-status",l="loading",u="loaded",c="failed",d="pre[data-src]:not(["+i+'="'+u+'"]):not(['+i+'="'+l+'"])';function f(y,m,P){var _=new XMLHttpRequest;_.open("GET",y,!0),_.onreadystatechange=function(){_.readyState==4&&(_.status<400&&_.responseText?m(_.responseText):_.status>=400?P(a(_.status,_.statusText)):P(r))},_.send(null)}function h(y){var m=/^\s*(\d+)\s*(?:(,)\s*(?:(\d+)\s*)?)?$/.exec(y||"");if(m){var P=Number(m[1]),_=m[2],S=m[3];return _?S?[P,Number(S)]:[P,void 0]:[P,P]}}n.hooks.add("before-highlightall",function(y){y.selector+=", "+d}),n.hooks.add("before-sanity-check",function(y){var m=y.element;if(m.matches(d)){y.code="",m.setAttribute(i,l);var P=m.appendChild(document.createElement("CODE"));P.textContent=s;var _=m.getAttribute("data-src"),S=y.language;if(S==="none"){var E=(/\.(\w+)$/.exec(_)||[,"none"])[1];S=o[E]||E}n.util.setLanguage(P,S),n.util.setLanguage(m,S);var F=n.plugins.autoloader;F&&F.loadLanguages(S),f(_,function(I){m.setAttribute(i,u);var T=h(m.getAttribute("data-range"));if(T){var A=I.split(/\r\n?|\n/g),R=T[0],Z=T[1]==null?A.length:T[1];R<0&&(R+=A.length),R=Math.max(0,Math.min(R-1,A.length)),Z<0&&(Z+=A.length),Z=Math.max(0,Math.min(Z,A.length)),I=A.slice(R,Z).join(` -`),m.hasAttribute("data-start")||m.setAttribute("data-start",String(R+1))}P.textContent=I,n.highlightElement(P)},function(I){m.setAttribute(i,c),P.textContent=I})}}),n.plugins.fileHighlight={highlight:function(m){for(var P=(m||document).querySelectorAll(d),_=0,S;S=P[_++];)n.highlightElement(S)}};var g=!1;n.fileHighlight=function(){g||(console.warn("Prism.fileHighlight is deprecated. Use `Prism.plugins.fileHighlight.highlight` instead."),g=!0),n.plugins.fileHighlight.highlight.apply(this,arguments)}})()})(xa)),xa.exports}var Mh=Nh();const Vi=Fh(Mh);(function(e){function t(n,s){return"___"+n.toUpperCase()+s+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,s,a,r){if(n.language===s){var o=n.tokenStack=[];n.code=n.code.replace(a,function(i){if(typeof r=="function"&&!r(i))return i;for(var l=o.length,u;n.code.indexOf(u=t(s,l))!==-1;)++l;return o[l]=i,u}),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,s){if(n.language!==s||!n.tokenStack)return;n.grammar=e.languages[s];var a=0,r=Object.keys(n.tokenStack);function o(i){for(var l=0;l=r.length);l++){var u=i[l];if(typeof u=="string"||u.content&&typeof u.content=="string"){var c=r[a],d=n.tokenStack[c],f=typeof u=="string"?u:u.content,h=t(s,c),g=f.indexOf(h);if(g>-1){++a;var y=f.substring(0,g),m=new e.Token(s,e.tokenize(d,n.grammar),"language-"+s,d),P=f.substring(g+h.length),_=[];y&&_.push.apply(_,o([y])),_.push(m),P&&_.push.apply(_,o([P])),typeof u=="string"?i.splice.apply(i,[l,1].concat(_)):u.content=_}}else u.content&&o(u.content)}return i}o(n.tokens)}}})})(Prism);var Hi={},Gi;function Uh(){return Gi||(Gi=1,(function(e){var t=/\/\*[\s\S]*?\*\/|\/\/.*|#(?!\[).*/,n=[{pattern:/\b(?:false|true)\b/i,alias:"boolean"},{pattern:/(::\s*)\b[a-z_]\w*\b(?!\s*\()/i,greedy:!0,lookbehind:!0},{pattern:/(\b(?:case|const)\s+)\b[a-z_]\w*(?=\s*[;=])/i,greedy:!0,lookbehind:!0},/\b(?:null)\b/i,/\b[A-Z_][A-Z0-9_]*\b(?!\s*\()/],s=/\b0b[01]+(?:_[01]+)*\b|\b0o[0-7]+(?:_[0-7]+)*\b|\b0x[\da-f]+(?:_[\da-f]+)*\b|(?:\b\d+(?:_\d+)*\.?(?:\d+(?:_\d+)*)?|\B\.\d+)(?:e[+-]?\d+)?/i,a=/|\?\?=?|\.{3}|\??->|[!=]=?=?|::|\*\*=?|--|\+\+|&&|\|\||<<|>>|[?~]|[/^|%*&<>.+-]=?/,r=/[{}\[\](),:;]/;e.languages.php={delimiter:{pattern:/\?>$|^<\?(?:php(?=\s)|=)?/i,alias:"important"},comment:t,variable:/\$+(?:\w+\b|(?=\{))/,package:{pattern:/(namespace\s+|use\s+(?:function\s+)?)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,lookbehind:!0,inside:{punctuation:/\\/}},"class-name-definition":{pattern:/(\b(?:class|enum|interface|trait)\s+)\b[a-z_]\w*(?!\\)\b/i,lookbehind:!0,alias:"class-name"},"function-definition":{pattern:/(\bfunction\s+)[a-z_]\w*(?=\s*\()/i,lookbehind:!0,alias:"function"},keyword:[{pattern:/(\(\s*)\b(?:array|bool|boolean|float|int|integer|object|string)\b(?=\s*\))/i,alias:"type-casting",greedy:!0,lookbehind:!0},{pattern:/([(,?]\s*)\b(?:array(?!\s*\()|bool|callable|(?:false|null)(?=\s*\|)|float|int|iterable|mixed|object|self|static|string)\b(?=\s*\$)/i,alias:"type-hint",greedy:!0,lookbehind:!0},{pattern:/(\)\s*:\s*(?:\?\s*)?)\b(?:array(?!\s*\()|bool|callable|(?:false|null)(?=\s*\|)|float|int|iterable|mixed|never|object|self|static|string|void)\b/i,alias:"return-type",greedy:!0,lookbehind:!0},{pattern:/\b(?:array(?!\s*\()|bool|float|int|iterable|mixed|object|string|void)\b/i,alias:"type-declaration",greedy:!0},{pattern:/(\|\s*)(?:false|null)\b|\b(?:false|null)(?=\s*\|)/i,alias:"type-declaration",greedy:!0,lookbehind:!0},{pattern:/\b(?:parent|self|static)(?=\s*::)/i,alias:"static-context",greedy:!0},{pattern:/(\byield\s+)from\b/i,lookbehind:!0},/\bclass\b/i,{pattern:/((?:^|[^\s>:]|(?:^|[^-])>|(?:^|[^:]):)\s*)\b(?:abstract|and|array|as|break|callable|case|catch|clone|const|continue|declare|default|die|do|echo|else|elseif|empty|enddeclare|endfor|endforeach|endif|endswitch|endwhile|enum|eval|exit|extends|final|finally|fn|for|foreach|function|global|goto|if|implements|include|include_once|instanceof|insteadof|interface|isset|list|match|namespace|never|new|or|parent|print|private|protected|public|readonly|require|require_once|return|self|static|switch|throw|trait|try|unset|use|var|while|xor|yield|__halt_compiler)\b/i,lookbehind:!0}],"argument-name":{pattern:/([(,]\s*)\b[a-z_]\w*(?=\s*:(?!:))/i,lookbehind:!0},"class-name":[{pattern:/(\b(?:extends|implements|instanceof|new(?!\s+self|\s+static))\s+|\bcatch\s*\()\b[a-z_]\w*(?!\\)\b/i,greedy:!0,lookbehind:!0},{pattern:/(\|\s*)\b[a-z_]\w*(?!\\)\b/i,greedy:!0,lookbehind:!0},{pattern:/\b[a-z_]\w*(?!\\)\b(?=\s*\|)/i,greedy:!0},{pattern:/(\|\s*)(?:\\?\b[a-z_]\w*)+\b/i,alias:"class-name-fully-qualified",greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/(?:\\?\b[a-z_]\w*)+\b(?=\s*\|)/i,alias:"class-name-fully-qualified",greedy:!0,inside:{punctuation:/\\/}},{pattern:/(\b(?:extends|implements|instanceof|new(?!\s+self\b|\s+static\b))\s+|\bcatch\s*\()(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,alias:"class-name-fully-qualified",greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/\b[a-z_]\w*(?=\s*\$)/i,alias:"type-declaration",greedy:!0},{pattern:/(?:\\?\b[a-z_]\w*)+(?=\s*\$)/i,alias:["class-name-fully-qualified","type-declaration"],greedy:!0,inside:{punctuation:/\\/}},{pattern:/\b[a-z_]\w*(?=\s*::)/i,alias:"static-context",greedy:!0},{pattern:/(?:\\?\b[a-z_]\w*)+(?=\s*::)/i,alias:["class-name-fully-qualified","static-context"],greedy:!0,inside:{punctuation:/\\/}},{pattern:/([(,?]\s*)[a-z_]\w*(?=\s*\$)/i,alias:"type-hint",greedy:!0,lookbehind:!0},{pattern:/([(,?]\s*)(?:\\?\b[a-z_]\w*)+(?=\s*\$)/i,alias:["class-name-fully-qualified","type-hint"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/(\)\s*:\s*(?:\?\s*)?)\b[a-z_]\w*(?!\\)\b/i,alias:"return-type",greedy:!0,lookbehind:!0},{pattern:/(\)\s*:\s*(?:\?\s*)?)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,alias:["class-name-fully-qualified","return-type"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}}],constant:n,function:{pattern:/(^|[^\\\w])\\?[a-z_](?:[\w\\]*\w)?(?=\s*\()/i,lookbehind:!0,inside:{punctuation:/\\/}},property:{pattern:/(->\s*)\w+/,lookbehind:!0},number:s,operator:a,punctuation:r};var o={pattern:/\{\$(?:\{(?:\{[^{}]+\}|[^{}]+)\}|[^{}])+\}|(^|[^\\{])\$+(?:\w+(?:\[[^\r\n\[\]]+\]|->\w+)?)/,lookbehind:!0,inside:e.languages.php},i=[{pattern:/<<<'([^']+)'[\r\n](?:.*[\r\n])*?\1;/,alias:"nowdoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<<'[^']+'|[a-z_]\w*;$/i,alias:"symbol",inside:{punctuation:/^<<<'?|[';]$/}}}},{pattern:/<<<(?:"([^"]+)"[\r\n](?:.*[\r\n])*?\1;|([a-z_]\w*)[\r\n](?:.*[\r\n])*?\2;)/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<<(?:"[^"]+"|[a-z_]\w*)|[a-z_]\w*;$/i,alias:"symbol",inside:{punctuation:/^<<<"?|[";]$/}},interpolation:o}},{pattern:/`(?:\\[\s\S]|[^\\`])*`/,alias:"backtick-quoted-string",greedy:!0},{pattern:/'(?:\\[\s\S]|[^\\'])*'/,alias:"single-quoted-string",greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,alias:"double-quoted-string",greedy:!0,inside:{interpolation:o}}];e.languages.insertBefore("php","variable",{string:i,attribute:{pattern:/#\[(?:[^"'\/#]|\/(?![*/])|\/\/.*$|#(?!\[).*$|\/\*(?:[^*]|\*(?!\/))*\*\/|"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*')+\](?=\s*[a-z$#])/im,greedy:!0,inside:{"attribute-content":{pattern:/^(#\[)[\s\S]+(?=\]$)/,lookbehind:!0,inside:{comment:t,string:i,"attribute-class-name":[{pattern:/([^:]|^)\b[a-z_]\w*(?!\\)\b/i,alias:"class-name",greedy:!0,lookbehind:!0},{pattern:/([^:]|^)(?:\\?\b[a-z_]\w*)+/i,alias:["class-name","class-name-fully-qualified"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}}],constant:n,number:s,operator:a,punctuation:r}},delimiter:{pattern:/^#\[|\]$/,alias:"punctuation"}}}}),e.hooks.add("before-tokenize",function(l){if(/<\?/.test(l.code)){var u=/<\?(?:[^"'/#]|\/(?![*/])|("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|(?:\/\/|#(?!\[))(?:[^?\n\r]|\?(?!>))*(?=$|\?>|[\r\n])|#\[|\/\*(?:[^*]|\*(?!\/))*(?:\*\/|$))*?(?:\?>|$)/g;e.languages["markup-templating"].buildPlaceholders(l,"php",u)}}),e.hooks.add("after-tokenize",function(l){e.languages["markup-templating"].tokenizePlaceholders(l,"php")})})(Prism)),Hi}Uh();const Bh={class:"page"},jh={key:2},Vh={class:"script-detail-meta"},Hh=["innerHTML"],Gh={key:1},qh={class:"script-meta"},zh={key:0},Kh={class:"scope-name"},Wh={class:"script-info-panel"},Jh={key:0,class:"info-row"},Yh={class:"info-value"},Xh={key:1,class:"info-row"},Zh={class:"info-value"},Qh={key:2,class:"info-row"},em={class:"info-value"},tm={key:1,class:"devices-panel"},nm={class:"block-title"},sm={key:2,class:"devices-panel"},am={class:"block-title"},rm={key:3,class:"devices-panel"},im={key:2,class:"code-block"},om=["innerHTML"],lm={key:0,class:"form-group"},um={key:0,class:"form-group"},cm={__name:"ScriptDetailPage",setup(e){const t=sa(),n=Sn(),s=wt(),a=wn(),r=Bt(),{areaOptions:o,showAssignModal:i,selectedAreaId:l,assignLoading:u,assignError:c,openAssign:d,submitAssignCore:f}=Cr(),h=Q(()=>t.params.type),g=Q(()=>t.params.id),y=Q(()=>h.value==="actions"),m=Q(()=>h.value==="regular"),P=Q(()=>h.value==="scopes"),_=Q(()=>{var x,ee,v;const $=[];return!P.value&&r.has("scripts.edit")&&((x=A.value)!=null&&x.area_id?$.push({label:"Change area",icon:"ph-map-pin",onSelect:te},{label:"Unassign from area",icon:"ph-x-circle",onSelect:je}):$.push({label:"Assign to area",icon:"ph-map-pin",onSelect:te})),y.value&&r.has("scripts.run")&&$.push({label:"Run",icon:"ph-play",disabled:((ee=A.value)==null?void 0:ee.state)!=="enabled"||n.isRunning((v=A.value)==null?void 0:v.alias),onSelect:X}),$}),S=Q(()=>y.value?"Actions":m.value?"Regular":P.value?"Scope":"Script"),E=Q(()=>`Loading ${S.value.toLowerCase()} details`),F=Q(()=>y.value?n.isLoadingActions:m.value?n.isLoadingRegular:P.value?n.isLoadingScopes||n.isLoadingActions||n.isLoadingRegular:!1),I=Q(()=>y.value?n.errorActions:m.value?n.errorRegular:P.value?n.errorScopes:null),T=Q(()=>y.value?n.actions.length>0:m.value?n.regular.length>0:P.value?n.scopes.length>0:!1),A=Q(()=>{const $=g.value;return $?y.value?n.actionByAlias($):m.value?n.regularByAlias($):P.value?n.scopeByName($):null:null}),R=Q(()=>{const $=g.value;return!$||!P.value?[]:n.actionsByScope($)}),Z=Q(()=>{const $=g.value;return!$||!P.value?[]:n.regularByScope($)}),ue=Q(()=>{var x;const $=(x=A.value)==null?void 0:x.area_id;return $&&s.areasById[String($)]||null}),de=Q(()=>P.value?n.isLoadingScopeCode:!1),pe=Q(()=>P.value?n.errorScopeCode:null),B=Q(()=>{var $;return y.value||m.value?(($=A.value)==null?void 0:$.code)||"":P.value?n.currentScopeCode:""}),q=Q(()=>{const $=B.value;return $?Vi.highlight($,Vi.languages.php,"php"):""});async function X(){var x,ee,v;if(!((x=A.value)!=null&&x.alias))return;const $=await n.runScript(A.value.alias);$!=null&&$.ok?a.success({title:`Ran ${A.value.alias}`,text:(ee=n.lastRunResult)!=null&&ee.execTime?`Exec time: ${n.lastRunResult.execTime}`:void 0}):a.error({title:`Failed ${A.value.alias}`,text:((v=$==null?void 0:$.error)==null?void 0:v.message)||"Unknown error"})}async function W($){var b,C;const x=g.value;if(!x)return;let ee;y.value?ee=await n.setActionState(x,$):m.value?ee=await n.setRegularState(x,$):P.value&&(ee=await n.setScopeState(x,$));const v=((b=A.value)==null?void 0:b.alias)||x;ee&&!ee.ok?a.error({title:`Failed to ${$?"enable":"disable"} ${v}`,text:((C=ee.error)==null?void 0:C.message)||"Unknown error"}):ee&&a.success({title:`${$?"Enabled":"Disabled"} ${v}`})}function te(){var $;d(($=A.value)==null?void 0:$.area_id)}async function ve(){var ee;const $=(ee=A.value)==null?void 0:ee.id,x=await f($,n.assignToArea.bind(n));x!=null&&x.ok&&a.success({title:"Assigned",text:"Script assigned to area successfully"})}const Se=J(!1),Ee=J(""),we=J(!1),Me=J("");function je(){A.value&&(Ee.value=`Are you sure you want to unassign script "${A.value.name||A.value.alias}" from its area?`,Me.value="",Se.value=!0)}async function Ve(){var x;if(!A.value)return;we.value=!0,Me.value="";const $=await n.unassignFromArea(A.value.id);if(we.value=!1,!$.ok){Me.value=((x=$.error)==null?void 0:x.message)||"Failed to unassign script";return}Se.value=!1,a.success({title:"Unassigned",text:"Script unassigned from area successfully"})}async function Te(){const $=g.value;!$||!P.value||await n.loadScopeCode($)}async function M(){g.value&&(y.value&&n.actions.length===0?await n.loadActions():m.value&&n.regular.length===0?await n.loadRegular():P.value&&n.scopes.length===0&&await n.loadScopes(),P.value&&(n.actions.length===0&&await n.loadActions(),n.regular.length===0&&await n.loadRegular(),await Te()),s.areas.length===0&&await s.loadAreas())}const se=[{key:"alias",label:"Alias"},{key:"name",label:"Name"},{key:"state",label:"State"}];return _t(()=>{M()}),hs(()=>{n.clearScopeCode()}),At(()=>[t.params.type,t.params.id],([$,x],[ee,v])=>{($!==ee||x!==v)&&(n.clearScopeCode(),M())}),($,x)=>{const ee=cn("router-link");return w(),G("section",Bh,[F.value?(w(),K(bt,{key:0,text:E.value},null,8,["text"])):I.value&&!T.value?(w(),K(pt,{key:1,title:`${S.value} loading failed`,error:I.value,retry:M},null,8,["title","error"])):A.value?(w(),G("div",jh,[L(p(Rt),{title:A.value.name||A.value.alias||A.value.name,kicker:S.value},{actions:k(()=>[p(r).has("scripts.edit")?(w(),K(p(rp),{key:0,"model-value":A.value.state==="enabled",label:"Enabled","onUpdate:modelValue":x[0]||(x[0]=v=>W(v))},null,8,["model-value"])):ae("",!0),L($r,{items:_.value},null,8,["items"])]),_:1},8,["title","kicker"]),D("div",Vh,[A.value.icon?(w(),G("div",{key:0,innerHTML:A.value.icon,class:"script-icon"},null,8,Hh)):ae("",!0),A.value.description?(w(),G("p",Gh,N(A.value.description),1)):ae("",!0),D("div",qh,[L(p(_e),{variant:A.value.state==="enabled"?"success":"secondary"},{default:k(()=>[U(N(A.value.state),1)]),_:1},8,["variant"]),D("code",null,N(A.value.alias||A.value.name),1),A.value.author?(w(),G("small",zh,N(A.value.author),1)):ae("",!0),L(Er,{area:ue.value,areaId:A.value.area_id},null,8,["area","areaId"]),A.value.scope?(w(),K(ee,{key:1,to:{name:"script-detail",params:{type:"scopes",id:A.value.scope}},class:"scope-link"},{default:k(()=>[x[6]||(x[6]=D("span",{class:"scope-label"},"Scope",-1)),D("span",Kh,N(A.value.scope),1),x[7]||(x[7]=D("i",{class:"ph ph-arrow-right"},null,-1))]),_:1},8,["to"])):ae("",!0)]),D("div",Wh,[A.value.filename?(w(),G("div",Jh,[x[8]||(x[8]=D("span",{class:"info-label text-muted"},"File:",-1)),D("span",Yh,N(A.value.filename),1)])):ae("",!0),A.value.path?(w(),G("div",Xh,[x[9]||(x[9]=D("span",{class:"info-label text-muted"},"Path:",-1)),D("span",Zh,N(A.value.path),1)])):ae("",!0),A.value.created_by?(w(),G("div",Qh,[x[10]||(x[10]=D("span",{class:"info-label text-muted"},"Author:",-1)),D("span",em,N(A.value.created_by),1)])):ae("",!0)])]),P.value?ae("",!0):(w(),K(Rr,{key:0,item:A.value,emptyMessage:"This script is not assigned to any area.",onAssign:te},{action:k(()=>[p(r).has("scripts.edit")?(w(),K(p(ge),{key:0,variant:"primary",icon:"ph-map-pin",onClick:te},{default:k(()=>{var v;return[U(N((v=A.value)!=null&&v.area_id?"Change area":"Assign to area"),1)]}),_:1})):ae("",!0)]),_:1},8,["item"])),P.value&&R.value.length>0?(w(),G("div",tm,[D("div",nm,"Action scripts ("+N(R.value.length)+")",1),L(p(Nn),{rows:R.value,columns:se},{"cell-state":k(({row:v})=>[L(p(_e),{variant:v.state==="enabled"?"success":"secondary"},{default:k(()=>[U(N(v.state),1)]),_:2},1032,["variant"])]),"cell-alias":k(({row:v})=>[L(ee,{to:{name:"script-detail",params:{type:"actions",id:v.alias}},class:"script-link"},{default:k(()=>[U(N(v.alias),1)]),_:2},1032,["to"])]),_:1},8,["rows"])])):ae("",!0),P.value&&Z.value.length>0?(w(),G("div",sm,[D("div",am,"Regular scripts ("+N(Z.value.length)+")",1),L(p(Nn),{rows:Z.value,columns:se},{"cell-state":k(({row:v})=>[L(p(_e),{variant:v.state==="enabled"?"success":"secondary"},{default:k(()=>[U(N(v.state),1)]),_:2},1032,["variant"])]),"cell-alias":k(({row:v})=>[L(ee,{to:{name:"script-detail",params:{type:"regular",id:v.alias}},class:"script-link"},{default:k(()=>[U(N(v.alias),1)]),_:2},1032,["to"])]),_:1},8,["rows"])])):ae("",!0),A.value.code||P.value?(w(),G("div",rm,[x[11]||(x[11]=D("div",{class:"block-title"},"Source code",-1)),de.value?(w(),K(bt,{key:0,text:"Loading source code"})):pe.value?(w(),K(pt,{key:1,title:"Code loading failed",error:pe.value,retry:Te},null,8,["error"])):B.value?(w(),G("pre",im,[D("code",{class:"language-php",innerHTML:q.value},null,8,om)])):(w(),K(rt,{key:3,title:"No code",message:"Source code is not available."}))])):ae("",!0)])):(w(),K(rt,{key:3,title:"Not found",message:"The requested script does not exist."})),L(p(ut),{open:p(i),title:"Assign to area","onUpdate:open":x[3]||(x[3]=v=>i.value=v)},{footer:k(()=>[L(p(ge),{variant:"secondary",onClick:x[2]||(x[2]=v=>i.value=!1)},{default:k(()=>[...x[12]||(x[12]=[U("Cancel",-1)])]),_:1}),L(p(ge),{variant:"primary",icon:"ph-check",loading:p(u),onClick:ve},{default:k(()=>[...x[13]||(x[13]=[U(" Assign ",-1)])]),_:1},8,["loading"])]),default:k(()=>[L(p(mr),{modelValue:p(l),"onUpdate:modelValue":x[1]||(x[1]=v=>Ue(l)?l.value=v:null),label:"Area",options:p(o),icon:"ph-map-trifold"},null,8,["modelValue","options"]),p(c)?(w(),G("div",lm,[L(p(Ze),{variant:"danger"},{default:k(()=>[U(N(p(c)),1)]),_:1})])):ae("",!0)]),_:1},8,["open"]),L(p(ut),{open:Se.value,title:"Unassign from area","onUpdate:open":x[5]||(x[5]=v=>Se.value=v)},{footer:k(()=>[L(p(ge),{variant:"secondary",onClick:x[4]||(x[4]=v=>Se.value=!1)},{default:k(()=>[...x[14]||(x[14]=[U("Cancel",-1)])]),_:1}),L(p(ge),{variant:"warning",icon:"ph-x-circle",loading:we.value,onClick:Ve},{default:k(()=>[...x[15]||(x[15]=[U(" Unassign ",-1)])]),_:1},8,["loading"])]),default:k(()=>[D("p",null,N(Ee.value),1),Me.value?(w(),G("div",um,[L(p(Ze),{variant:"danger"},{default:k(()=>[U(N(Me.value),1)]),_:1})])):ae("",!0)]),_:1},8,["open"])])}}},dm=ze(cm,[["__scopeId","data-v-31cd836e"]]),fm={class:"page"},pm={key:3,class:"firmwares-panel"},vm={class:"firmwares-summary"},gm={class:"firmwares-list"},hm={class:"firmware-header"},mm={class:"firmware-id"},ym={class:"firmware-meta"},_m={key:0,class:"firmware-desc"},bm={key:1,class:"firmware-changelog"},wm={__name:"FirmwaresListPage",setup(e){const t=Ul(),n=Bt(),s=J(null);async function a(){var i;s.value=null;const o=await t.loadFirmwares();o.ok||(s.value=((i=o.error)==null?void 0:i.message)||"Failed to load catalog")}async function r(){var i;s.value=null;const o=await t.refreshFirmwares();o.ok||(s.value=((i=o.error)==null?void 0:i.message)||"Failed to refresh catalog")}return _t(a),(o,i)=>(w(),G("section",fm,[L(p(Rt),{title:"Firmware Catalog",kicker:"Firmwares"},{actions:k(()=>[p(n).has("firmware.upload")?(w(),K(p(ge),{key:0,loading:p(t).isUpdating,icon:"ph-arrow-clockwise",onClick:r},{default:k(()=>[...i[0]||(i[0]=[U(" Refresh Catalog ",-1)])]),_:1},8,["loading"])):ae("",!0)]),_:1}),p(t).isLoadingList?(w(),K(bt,{key:0,text:"Loading firmware catalog"})):s.value?(w(),K(pt,{key:1,title:"Catalog loading failed",error:s.value,retry:a},null,8,["error"])):p(t).firmwares.length===0?(w(),K(rt,{key:2,title:"No firmwares found",message:"No firmware packages detected in the firmwares directory."})):(w(),G("div",pm,[D("div",vm,[L(p(_e),{variant:"primary"},{default:k(()=>[U("Total: "+N(p(t).firmwares.length),1)]),_:1})]),D("div",gm,[(w(!0),G(Ie,null,Yt(p(t).firmwares,l=>(w(),G("div",{key:l.id,class:"firmware-card"},[D("div",hm,[D("span",mm,N(l.id),1),L(p(_e),{variant:"success"},{default:k(()=>[U(N(l.version),1)]),_:2},1024)]),D("div",ym,[L(p(_e),{variant:"secondary"},{default:k(()=>[U(N(l.device_type),1)]),_:2},1024),l.platform?(w(),K(p(_e),{key:0,variant:"info"},{default:k(()=>[U(N(l.platform),1)]),_:2},1024)):ae("",!0),l.channels?(w(),K(p(_e),{key:1,variant:"warning"},{default:k(()=>[U(N(l.channels)+" ch",1)]),_:2},1024)):ae("",!0)]),l.description?(w(),G("p",_m,N(l.description),1)):ae("",!0),l.changelog?(w(),G("pre",bm,N(l.changelog),1)):ae("",!0)]))),128))])]))]))}},Sm=ze(wm,[["__scopeId","data-v-c0c73f70"]]),Bl="/logo-cube-square.svg",km={class:"login-page"},Am={class:"login-card"},xm={key:0,class:"login-loading text-muted"},Cm={__name:"LoginPage",setup(e){const t=en(),n=Un();_t(()=>{n.isAuthenticated&&t.replace({name:"areas-favorites"})});function s(){wr(Sr())}return(a,r)=>(w(),G("div",km,[D("div",Am,[r[2]||(r[2]=D("div",{class:"login-brand"},[D("img",{src:Bl,alt:"Smart Home",class:"brand-logo"}),D("h1",{class:"brand-title"},"Smart Home Server")],-1)),r[3]||(r[3]=D("p",{class:"login-hint text-muted"}," You need to sign in to access the smart home dashboard. ",-1)),L(p(ge),{variant:"primary",class:"login-btn",icon:"ph-sign-in",onClick:s},{default:k(()=>[...r[0]||(r[0]=[U(" LOGIN WITH GNEXUS ",-1)])]),_:1}),p(n).isLoading?(w(),G("p",xm,[...r[1]||(r[1]=[D("i",{class:"ph ph-spinner ph-spin"},null,-1),U(" Checking session… ",-1)])])):ae("",!0)])]))}},Em=ze(Cm,[["__scopeId","data-v-7f18a357"]]),Rm={class:"setup-page"},$m={class:"setup-card"},Tm={class:"setup-form"},Pm={key:0,class:"setup-error text-danger"},Lm={__name:"MobileSetupPage",setup(e){en();const t=J(""),n=J(""),s=J(!1),a=J("");async function r(){n.value="",a.value="";const o=t.value.trim();if(!o){n.value="Server URL is required";return}let i=o;/^https?:\/\//i.test(i)||(i="http://"+i);try{new URL(i)}catch{n.value="Invalid URL format";return}s.value=!0;try{const l=[`${i}/api/v1/about`,`${i}/about`];let u=!1;for(const c of l)try{const d=new AbortController,f=setTimeout(()=>d.abort(),5e3),h=await fetch(c,{method:"GET",signal:d.signal});if(clearTimeout(f),h.ok||h.status===401){u=!0;break}}catch{}if(!u){a.value="Could not connect to server. Please check the address.",s.value=!1;return}await up(i),alert("Server address saved. Please restart the app to continue."),ja.exitApp();return}catch{a.value="Connection check failed. Please try again.",s.value=!1}}return(o,i)=>(w(),G("div",Rm,[D("div",$m,[i[3]||(i[3]=Tc('

Smart Home

Mobile App Setup

Enter the address of your Smart Home server. Example: https://shserv.home or http://192.168.1.10

',3)),D("div",Tm,[L(p(xt),{modelValue:t.value,"onUpdate:modelValue":i[0]||(i[0]=l=>t.value=l),label:"Server URL",placeholder:"https://your-server.com",error:n.value,onKeyup:fd(r,["enter"])},null,8,["modelValue","error"]),L(p(ge),{variant:"primary",size:"lg",class:"setup-btn",loading:s.value,onClick:r},{icon:k(()=>[...i[1]||(i[1]=[D("i",{class:"ph ph-check"},null,-1)])]),default:k(()=>[U(" "+N(s.value?"Checking connection…":"Save and continue"),1)]),_:1},8,["loading"])]),a.value?(w(),G("p",Pm,[i[2]||(i[2]=D("i",{class:"ph ph-warning-circle"},null,-1)),U(" "+N(a.value),1)])):ae("",!0)])]))}},Im=ze(Lm,[["__scopeId","data-v-a50065c7"]]),Dm={class:"mobile-auth-page"},Om={class:"mobile-auth-card"},Fm={class:"text-muted"},Nm={__name:"MobileAuthPage",setup(e){const t=en(),n=Un(),s=J("Authenticating…");return _t(async()=>{const a=window.location.hash,r=a.indexOf("?");if(r===-1){s.value="Invalid login link. Redirecting…",setTimeout(()=>t.replace({name:"login"}),1500);return}const o=new URLSearchParams(a.slice(r+1)),i=o.get("token"),l=o.get("expires_in");if(!i){s.value="No token received. Redirecting…",setTimeout(()=>t.replace({name:"login"}),1500);return}aa(i,l?parseInt(l,10):null);const u=a.slice(0,r);window.history.replaceState(null,"",u||"#/"),s.value="Loading profile…";try{await n.init(),n.isAuthenticated?t.replace({name:"areas-favorites"}):(s.value="Session invalid. Redirecting…",setTimeout(()=>t.replace({name:"login"}),1500))}catch{s.value="Failed to load profile. Redirecting…",setTimeout(()=>t.replace({name:"login"}),1500)}}),(a,r)=>(w(),G("div",Dm,[D("div",Om,[r[0]||(r[0]=D("div",{class:"spinner"},null,-1)),D("p",Fm,N(s.value),1)])]))}},Mm=ze(Nm,[["__scopeId","data-v-9c0afc74"]]),Um=[{path:"/",redirect:"/areas/favorites"},{path:"/login",name:"login",component:Em,meta:{public:!0}},{path:"/mobile-setup",name:"mobile-setup",component:Im,meta:{public:!0}},{path:"/mobile-auth",name:"mobile-auth",component:Mm,meta:{public:!0}},{path:"/areas/favorites",name:"areas-favorites",component:Vp,meta:{permission:"areas.view"}},{path:"/areas/tree",name:"areas-tree",component:av,meta:{permission:"areas.view"}},{path:"/areas/:id",name:"area-detail",component:mg,meta:{permission:"areas.view"}},{path:"/devices",name:"devices",component:kg,meta:{permission:"devices.view"}},{path:"/devices/scanning",name:"devices-scanning",component:Ug,meta:{permission:"devices.scan"}},{path:"/devices/:id",name:"device-detail",component:xh,meta:{permission:"devices.view"}},{path:"/scripts/actions",name:"scripts-actions",component:Rh,meta:{permission:"scripts.run"}},{path:"/scripts/regular",name:"scripts-regular",component:Ph,meta:{permission:"scripts.view"}},{path:"/scripts/scopes",name:"scripts-scopes",component:Oh,meta:{permission:"scripts.view"}},{path:"/scripts/:type(actions|regular|scopes)/:id",name:"script-detail",component:dm,meta:{permission:"scripts.view"}},{path:"/firmwares",name:"firmwares",component:Sm,meta:{permission:"firmware.view"}},{path:"/:pathMatch(.*)*",name:"not-found",component:()=>pr(()=>import("./NotFoundPage-B9uWKSBX.js"),[])}],Kn="[vue:router]",Wn=br(),jl=Vf({history:wf(),routes:Um});jl.beforeEach(async(e,t,n)=>{var r,o;if(Nt()&&e.name!=="mobile-setup")try{if(!await dp()){Wn&&console.debug(Kn,"Redirect: native app missing server URL → mobile-setup"),n({name:"mobile-setup"});return}}catch{if(e.name!=="mobile-setup"){n({name:"mobile-setup"});return}}const s=Un();if(Wn&&console.debug(Kn,`Navigate: ${t.fullPath||"init"} → ${e.fullPath}`),await s.init(),(r=e.meta)!=null&&r.public){if(e.name==="login"&&s.isAuthenticated){Wn&&console.debug(Kn,"Redirect: authenticated user at login → areas-favorites"),n({name:"areas-favorites"});return}n();return}if(!s.isAuthenticated){Wn&&console.debug(Kn,"Redirect: unauthenticated → login"),n({name:"login"});return}const a=(o=e.meta)==null?void 0:o.permission;if(a&&!s.hasPermission(a)){Wn&&console.warn(Kn,`Forbidden: ${e.fullPath} requires ${a}`),n({name:"areas-favorites"});return}n()});function Bm(e){const t="[vue:error]";e.config.errorHandler=(n,s,a)=>{const r=(n==null?void 0:n.message)||String(n);console.error(t,`Vue ${a}`,r,(n==null?void 0:n.stack)||"")},window.addEventListener("unhandledrejection",n=>{var r;const s=n.reason,a=(s==null?void 0:s.message)||((r=s==null?void 0:s.error)==null?void 0:r.message)||String(s);console.error(t,"Unhandled rejection:",a,(s==null?void 0:s.stack)||""),n.preventDefault()}),window.addEventListener("error",n=>{const s=n.error,a=(s==null?void 0:s.message)||n.message||"Unknown error";console.error(t,`Global error: ${a}`,`at ${n.filename}:${n.lineno}:${n.colno}`,(s==null?void 0:s.stack)||"")})}const Ca="[vue:pinia]",jm=e=>{if(!br())return;const{store:t,options:n}=e,s=n.id,a=Object.keys(n.actions||{});for(const r of a){const o=t[r];t[r]=async function(...i){console.debug(Ca,`${s}.${r}(${i.map(u=>Rl(u)).join(", ")})`);const l=performance.now();try{const u=await o.apply(this,i);return console.debug(Ca,`${s}.${r} completed in ${(performance.now()-l).toFixed(1)}ms`),u}catch(u){throw console.error(Ca,`${s}.${r} failed: ${(u==null?void 0:u.message)||u}`),u}}}};function qi(e){try{const t=new URL(e);if(t.host==="auth"&&t.pathname==="/callback"){const n=t.searchParams.get("token"),s=t.searchParams.get("expires_in");n&&(aa(n,s?parseInt(s,10):null),window.location.reload())}}catch{}}async function Vm(){if(await lp(),await fp(),Nt()){try{const s=await ja.getLaunchUrl();if(s!=null&&s.url){qi(s.url);return}}catch{}ja.addListener("appUrlOpen",s=>{qi(s.url)})}const e=gd(Ep);Bm(e);const t=yd();t.use(jm),e.use(t).use(jl),await Un().init(),e.mount("#app")}Vm();export{Zf as G,vr as W,L as a,G as c,w as o,p as u}; diff --git a/server/dist/assets/index-C4kiMKve.js b/server/dist/assets/index-C4kiMKve.js new file mode 100644 index 0000000..a1cd466 --- /dev/null +++ b/server/dist/assets/index-C4kiMKve.js @@ -0,0 +1,37 @@ +(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const s of document.querySelectorAll('link[rel="modulepreload"]'))a(s);new MutationObserver(s=>{for(const r of s)if(r.type==="childList")for(const o of r.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&a(o)}).observe(document,{childList:!0,subtree:!0});function n(s){const r={};return s.integrity&&(r.integrity=s.integrity),s.referrerPolicy&&(r.referrerPolicy=s.referrerPolicy),s.crossOrigin==="use-credentials"?r.credentials="include":s.crossOrigin==="anonymous"?r.credentials="omit":r.credentials="same-origin",r}function a(s){if(s.ep)return;s.ep=!0;const r=n(s);fetch(s.href,r)}})();/** +* @vue/shared v3.5.33 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/function Xs(e){const t=Object.create(null);for(const n of e.split(","))t[n]=1;return n=>n in t}const Me={},Rn=[],Ft=()=>{},Ki=()=>!1,Ma=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),Ua=e=>e.startsWith("onUpdate:"),tt=Object.assign,Zs=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},Gl=Object.prototype.hasOwnProperty,Ce=(e,t)=>Gl.call(e,t),ye=Array.isArray,$n=e=>va(e)==="[object Map]",Wi=e=>va(e)==="[object Set]",Ir=e=>va(e)==="[object Date]",we=e=>typeof e=="function",He=e=>typeof e=="string",_t=e=>typeof e=="symbol",Te=e=>e!==null&&typeof e=="object",Ji=e=>(Te(e)||we(e))&&we(e.then)&&we(e.catch),Yi=Object.prototype.toString,va=e=>Yi.call(e),ql=e=>va(e).slice(8,-1),Xi=e=>va(e)==="[object Object]",Va=e=>He(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,Zn=Xs(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),ja=e=>{const t=Object.create(null);return(n=>t[n]||(t[n]=e(n)))},zl=/-\w/g,ft=ja(e=>e.replace(zl,t=>t.slice(1).toUpperCase())),Kl=/\B([A-Z])/g,un=ja(e=>e.replace(Kl,"-$1").toLowerCase()),Ba=ja(e=>e.charAt(0).toUpperCase()+e.slice(1)),ls=ja(e=>e?`on${Ba(e)}`:""),Ot=(e,t)=>!Object.is(e,t),us=(e,...t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:a,value:n})},Wl=e=>{const t=parseFloat(e);return isNaN(t)?e:t};let Lr;const Ha=()=>Lr||(Lr=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function Qs(e){if(ye(e)){const t={};for(let n=0;n{if(n){const a=n.split(Yl);a.length>1&&(t[a[0].trim()]=a[1].trim())}}),t}function Mt(e){let t="";if(He(e))t=e;else if(ye(e))for(let n=0;n!!(e&&e.__v_isRef===!0),O=e=>He(e)?e:e==null?"":ye(e)||Te(e)&&(e.toString===Yi||!we(e.toString))?eo(e)?O(e.value):JSON.stringify(e,to,2):String(e),to=(e,t)=>eo(t)?to(e,t.value):$n(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[a,s],r)=>(n[cs(a,r)+" =>"]=s,n),{})}:Wi(t)?{[`Set(${t.size})`]:[...t.values()].map(n=>cs(n))}:_t(t)?cs(t):Te(t)&&!ye(t)&&!Xi(t)?String(t):t,cs=(e,t="")=>{var n;return _t(e)?`Symbol(${(n=e.description)!=null?n:t})`:e};/** +* @vue/reactivity v3.5.33 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/let Xe;class no{constructor(t=!1){this.detached=t,this._active=!0,this._on=0,this.effects=[],this.cleanups=[],this._isPaused=!1,this.__v_skip=!0,this.parent=Xe,!t&&Xe&&(this.index=(Xe.scopes||(Xe.scopes=[])).push(this)-1)}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let t,n;if(this.scopes)for(t=0,n=this.scopes.length;t0&&--this._on===0){if(Xe===this)Xe=this.prevScope;else{let t=Xe;for(;t;){if(t.prevScope===this){t.prevScope=this.prevScope;break}t=t.prevScope}}this.prevScope=void 0}}stop(t){if(this._active){this._active=!1;let n,a;for(n=0,a=this.effects.length;n0)return;if(ea){let t=ea;for(ea=void 0;t;){const n=t.next;t.next=void 0,t.flags&=-9,t=n}}let e;for(;Qn;){let t=Qn;for(Qn=void 0;t;){const n=t.next;if(t.next=void 0,t.flags&=-9,t.flags&1)try{t.trigger()}catch(a){e||(e=a)}t=n}}if(e)throw e}function lo(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function uo(e){let t,n=e.depsTail,a=n;for(;a;){const s=a.prevDep;a.version===-1?(a===n&&(n=s),ar(a),au(a)):t=a,a.dep.activeLink=a.prevActiveLink,a.prevActiveLink=void 0,a=s}e.deps=t,e.depsTail=n}function $s(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&(co(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function co(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===oa)||(e.globalVersion=oa,!e.isSSR&&e.flags&128&&(!e.deps&&!e._dirty||!$s(e))))return;e.flags|=2;const t=e.dep,n=Ne,a=xt;Ne=e,xt=!0;try{lo(e);const s=e.fn(e._value);(t.version===0||Ot(s,e._value))&&(e.flags|=128,e._value=s,t.version++)}catch(s){throw t.version++,s}finally{Ne=n,xt=a,uo(e),e.flags&=-3}}function ar(e,t=!1){const{dep:n,prevSub:a,nextSub:s}=e;if(a&&(a.nextSub=s,e.prevSub=void 0),s&&(s.prevSub=a,e.nextSub=void 0),n.subs===e&&(n.subs=a,!a&&n.computed)){n.computed.flags&=-5;for(let r=n.computed.deps;r;r=r.nextDep)ar(r,!0)}!t&&!--n.sc&&n.map&&n.map.delete(n.key)}function au(e){const{prevDep:t,nextDep:n}=e;t&&(t.nextDep=n,e.prevDep=void 0),n&&(n.prevDep=t,e.nextDep=void 0)}let xt=!0;const fo=[];function Wt(){fo.push(xt),xt=!1}function Jt(){const e=fo.pop();xt=e===void 0?!0:e}function Dr(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const n=Ne;Ne=void 0;try{t()}finally{Ne=n}}}let oa=0;class su{constructor(t,n){this.sub=t,this.dep=n,this.version=n.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class sr{constructor(t){this.computed=t,this.version=0,this.activeLink=void 0,this.subs=void 0,this.map=void 0,this.key=void 0,this.sc=0,this.__v_skip=!0}track(t){if(!Ne||!xt||Ne===this.computed)return;let n=this.activeLink;if(n===void 0||n.sub!==Ne)n=this.activeLink=new su(Ne,this),Ne.deps?(n.prevDep=Ne.depsTail,Ne.depsTail.nextDep=n,Ne.depsTail=n):Ne.deps=Ne.depsTail=n,po(n);else if(n.version===-1&&(n.version=this.version,n.nextDep)){const a=n.nextDep;a.prevDep=n.prevDep,n.prevDep&&(n.prevDep.nextDep=a),n.prevDep=Ne.depsTail,n.nextDep=void 0,Ne.depsTail.nextDep=n,Ne.depsTail=n,Ne.deps===n&&(Ne.deps=a)}return n}trigger(t){this.version++,oa++,this.notify(t)}notify(t){tr();try{for(let n=this.subs;n;n=n.prevSub)n.sub.notify()&&n.sub.dep.notify()}finally{nr()}}}function po(e){if(e.dep.sc++,e.sub.flags&4){const t=e.dep.computed;if(t&&!e.dep.subs){t.flags|=20;for(let a=t.deps;a;a=a.nextDep)po(a)}const n=e.dep.subs;n!==e&&(e.prevSub=n,n&&(n.nextSub=e)),e.dep.subs=e}}const Ca=new WeakMap,hn=Symbol(""),Ts=Symbol(""),la=Symbol("");function st(e,t,n){if(xt&&Ne){let a=Ca.get(e);a||Ca.set(e,a=new Map);let s=a.get(n);s||(a.set(n,s=new sr),s.map=a,s.key=n),s.track()}}function zt(e,t,n,a,s,r){const o=Ca.get(e);if(!o){oa++;return}const i=l=>{l&&l.trigger()};if(tr(),t==="clear")o.forEach(i);else{const l=ye(e),u=l&&Va(n);if(l&&n==="length"){const c=Number(a);o.forEach((d,f)=>{(f==="length"||f===la||!_t(f)&&f>=c)&&i(d)})}else switch((n!==void 0||o.has(void 0))&&i(o.get(n)),u&&i(o.get(la)),t){case"add":l?u&&i(o.get("length")):(i(o.get(hn)),$n(e)&&i(o.get(Ts)));break;case"delete":l||(i(o.get(hn)),$n(e)&&i(o.get(Ts)));break;case"set":$n(e)&&i(o.get(hn));break}}nr()}function ru(e,t){const n=Ca.get(e);return n&&n.get(t)}function kn(e){const t=Ae(e);return t===e?t:(st(t,"iterate",la),ht(e)?t:t.map(Ct))}function Ga(e){return st(e=Ae(e),"iterate",la),e}function Lt(e,t){return Yt(e)?In(Kt(e)?Ct(t):t):Ct(t)}const iu={__proto__:null,[Symbol.iterator](){return fs(this,Symbol.iterator,e=>Lt(this,e))},concat(...e){return kn(this).concat(...e.map(t=>ye(t)?kn(t):t))},entries(){return fs(this,"entries",e=>(e[1]=Lt(this,e[1]),e))},every(e,t){return Bt(this,"every",e,t,void 0,arguments)},filter(e,t){return Bt(this,"filter",e,t,n=>n.map(a=>Lt(this,a)),arguments)},find(e,t){return Bt(this,"find",e,t,n=>Lt(this,n),arguments)},findIndex(e,t){return Bt(this,"findIndex",e,t,void 0,arguments)},findLast(e,t){return Bt(this,"findLast",e,t,n=>Lt(this,n),arguments)},findLastIndex(e,t){return Bt(this,"findLastIndex",e,t,void 0,arguments)},forEach(e,t){return Bt(this,"forEach",e,t,void 0,arguments)},includes(...e){return ps(this,"includes",e)},indexOf(...e){return ps(this,"indexOf",e)},join(e){return kn(this).join(e)},lastIndexOf(...e){return ps(this,"lastIndexOf",e)},map(e,t){return Bt(this,"map",e,t,void 0,arguments)},pop(){return jn(this,"pop")},push(...e){return jn(this,"push",e)},reduce(e,...t){return Or(this,"reduce",e,t)},reduceRight(e,...t){return Or(this,"reduceRight",e,t)},shift(){return jn(this,"shift")},some(e,t){return Bt(this,"some",e,t,void 0,arguments)},splice(...e){return jn(this,"splice",e)},toReversed(){return kn(this).toReversed()},toSorted(e){return kn(this).toSorted(e)},toSpliced(...e){return kn(this).toSpliced(...e)},unshift(...e){return jn(this,"unshift",e)},values(){return fs(this,"values",e=>Lt(this,e))}};function fs(e,t,n){const a=Ga(e),s=a[t]();return a!==e&&!ht(e)&&(s._next=s.next,s.next=()=>{const r=s._next();return r.done||(r.value=n(r.value)),r}),s}const ou=Array.prototype;function Bt(e,t,n,a,s,r){const o=Ga(e),i=o!==e&&!ht(e),l=o[t];if(l!==ou[t]){const d=l.apply(e,r);return i?Ct(d):d}let u=n;o!==e&&(i?u=function(d,f){return n.call(this,Lt(e,d),f,e)}:n.length>2&&(u=function(d,f){return n.call(this,d,f,e)}));const c=l.call(o,u,a);return i&&s?s(c):c}function Or(e,t,n,a){const s=Ga(e),r=s!==e&&!ht(e);let o=n,i=!1;s!==e&&(r?(i=a.length===0,o=function(u,c,d){return i&&(i=!1,u=Lt(e,u)),n.call(this,u,Lt(e,c),d,e)}):n.length>3&&(o=function(u,c,d){return n.call(this,u,c,d,e)}));const l=s[t](o,...a);return i?Lt(e,l):l}function ps(e,t,n){const a=Ae(e);st(a,"iterate",la);const s=a[t](...n);return(s===-1||s===!1)&&qa(n[0])?(n[0]=Ae(n[0]),a[t](...n)):s}function jn(e,t,n=[]){Wt(),tr();const a=Ae(e)[t].apply(e,n);return nr(),Jt(),a}const lu=Xs("__proto__,__v_isRef,__isVue"),vo=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(_t));function uu(e){_t(e)||(e=String(e));const t=Ae(this);return st(t,"has",e),t.hasOwnProperty(e)}class go{constructor(t=!1,n=!1){this._isReadonly=t,this._isShallow=n}get(t,n,a){if(n==="__v_skip")return t.__v_skip;const s=this._isReadonly,r=this._isShallow;if(n==="__v_isReactive")return!s;if(n==="__v_isReadonly")return s;if(n==="__v_isShallow")return r;if(n==="__v_raw")return a===(s?r?_u:_o:r?yo:mo).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(a)?t:void 0;const o=ye(t);if(!s){let l;if(o&&(l=iu[n]))return l;if(n==="hasOwnProperty")return uu}const i=Reflect.get(t,n,Ve(t)?t:a);if((_t(n)?vo.has(n):lu(n))||(s||st(t,"get",n),r))return i;if(Ve(i)){const l=o&&Va(n)?i:i.value;return s&&Te(l)?Is(l):l}return Te(i)?s?Is(i):Zt(i):i}}class ho extends go{constructor(t=!1){super(!1,t)}set(t,n,a,s){let r=t[n];const o=ye(t)&&Va(n);if(!this._isShallow){const u=Yt(r);if(!ht(a)&&!Yt(a)&&(r=Ae(r),a=Ae(a)),!o&&Ve(r)&&!Ve(a))return u||(r.value=a),!0}const i=o?Number(n)e,_a=e=>Reflect.getPrototypeOf(e);function vu(e,t,n){return function(...a){const s=this.__v_raw,r=Ae(s),o=$n(r),i=e==="entries"||e===Symbol.iterator&&o,l=e==="keys"&&o,u=s[e](...a),c=n?Ps:t?In:Ct;return!t&&st(r,"iterate",l?Ts:hn),tt(Object.create(u),{next(){const{value:d,done:f}=u.next();return f?{value:d,done:f}:{value:i?[c(d[0]),c(d[1])]:c(d),done:f}}})}}function ba(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function gu(e,t){const n={get(s){const r=this.__v_raw,o=Ae(r),i=Ae(s);e||(Ot(s,i)&&st(o,"get",s),st(o,"get",i));const{has:l}=_a(o),u=t?Ps:e?In:Ct;if(l.call(o,s))return u(r.get(s));if(l.call(o,i))return u(r.get(i));r!==o&&r.get(s)},get size(){const s=this.__v_raw;return!e&&st(Ae(s),"iterate",hn),s.size},has(s){const r=this.__v_raw,o=Ae(r),i=Ae(s);return e||(Ot(s,i)&&st(o,"has",s),st(o,"has",i)),s===i?r.has(s):r.has(s)||r.has(i)},forEach(s,r){const o=this,i=o.__v_raw,l=Ae(i),u=t?Ps:e?In:Ct;return!e&&st(l,"iterate",hn),i.forEach((c,d)=>s.call(r,u(c),u(d),o))}};return tt(n,e?{add:ba("add"),set:ba("set"),delete:ba("delete"),clear:ba("clear")}:{add(s){const r=Ae(this),o=_a(r),i=Ae(s),l=!t&&!ht(s)&&!Yt(s)?i:s;return o.has.call(r,l)||Ot(s,l)&&o.has.call(r,s)||Ot(i,l)&&o.has.call(r,i)||(r.add(l),zt(r,"add",l,l)),this},set(s,r){!t&&!ht(r)&&!Yt(r)&&(r=Ae(r));const o=Ae(this),{has:i,get:l}=_a(o);let u=i.call(o,s);u||(s=Ae(s),u=i.call(o,s));const c=l.call(o,s);return o.set(s,r),u?Ot(r,c)&&zt(o,"set",s,r):zt(o,"add",s,r),this},delete(s){const r=Ae(this),{has:o,get:i}=_a(r);let l=o.call(r,s);l||(s=Ae(s),l=o.call(r,s)),i&&i.call(r,s);const u=r.delete(s);return l&&zt(r,"delete",s,void 0),u},clear(){const s=Ae(this),r=s.size!==0,o=s.clear();return r&&zt(s,"clear",void 0,void 0),o}}),["keys","values","entries",Symbol.iterator].forEach(s=>{n[s]=vu(s,e,t)}),n}function rr(e,t){const n=gu(e,t);return(a,s,r)=>s==="__v_isReactive"?!e:s==="__v_isReadonly"?e:s==="__v_raw"?a:Reflect.get(Ce(n,s)&&s in a?n:a,s,r)}const hu={get:rr(!1,!1)},mu={get:rr(!1,!0)},yu={get:rr(!0,!1)};const mo=new WeakMap,yo=new WeakMap,_o=new WeakMap,_u=new WeakMap;function bu(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function wu(e){return e.__v_skip||!Object.isExtensible(e)?0:bu(ql(e))}function Zt(e){return Yt(e)?e:ir(e,!1,du,hu,mo)}function bo(e){return ir(e,!1,pu,mu,yo)}function Is(e){return ir(e,!0,fu,yu,_o)}function ir(e,t,n,a,s){if(!Te(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const r=wu(e);if(r===0)return e;const o=s.get(e);if(o)return o;const i=new Proxy(e,r===2?a:n);return s.set(e,i),i}function Kt(e){return Yt(e)?Kt(e.__v_raw):!!(e&&e.__v_isReactive)}function Yt(e){return!!(e&&e.__v_isReadonly)}function ht(e){return!!(e&&e.__v_isShallow)}function qa(e){return e?!!e.__v_raw:!1}function Ae(e){const t=e&&e.__v_raw;return t?Ae(t):e}function or(e){return!Ce(e,"__v_skip")&&Object.isExtensible(e)&&Zi(e,"__v_skip",!0),e}const Ct=e=>Te(e)?Zt(e):e,In=e=>Te(e)?Is(e):e;function Ve(e){return e?e.__v_isRef===!0:!1}function J(e){return wo(e,!1)}function Su(e){return wo(e,!0)}function wo(e,t){return Ve(e)?e:new ku(e,t)}class ku{constructor(t,n){this.dep=new sr,this.__v_isRef=!0,this.__v_isShallow=!1,this._rawValue=n?t:Ae(t),this._value=n?t:Ct(t),this.__v_isShallow=n}get value(){return this.dep.track(),this._value}set value(t){const n=this._rawValue,a=this.__v_isShallow||ht(t)||Yt(t);t=a?t:Ae(t),Ot(t,n)&&(this._rawValue=t,this._value=a?t:Ct(t),this.dep.trigger())}}function v(e){return Ve(e)?e.value:e}const Au={get:(e,t,n)=>t==="__v_raw"?e:v(Reflect.get(e,t,n)),set:(e,t,n,a)=>{const s=e[t];return Ve(s)&&!Ve(n)?(s.value=n,!0):Reflect.set(e,t,n,a)}};function So(e){return Kt(e)?e:new Proxy(e,Au)}function xu(e){const t=ye(e)?new Array(e.length):{};for(const n in e)t[n]=Eu(e,n);return t}class Cu{constructor(t,n,a){this._object=t,this._defaultValue=a,this.__v_isRef=!0,this._value=void 0,this._key=_t(n)?n:String(n),this._raw=Ae(t);let s=!0,r=t;if(!ye(t)||_t(this._key)||!Va(this._key))do s=!qa(r)||ht(r);while(s&&(r=r.__v_raw));this._shallow=s}get value(){let t=this._object[this._key];return this._shallow&&(t=v(t)),this._value=t===void 0?this._defaultValue:t}set value(t){if(this._shallow&&Ve(this._raw[this._key])){const n=this._object[this._key];if(Ve(n)){n.value=t;return}}this._object[this._key]=t}get dep(){return ru(this._raw,this._key)}}function Eu(e,t,n){return new Cu(e,t,n)}class Ru{constructor(t,n,a){this.fn=t,this.setter=n,this._value=void 0,this.dep=new sr(this),this.__v_isRef=!0,this.deps=void 0,this.depsTail=void 0,this.flags=16,this.globalVersion=oa-1,this.next=void 0,this.effect=this,this.__v_isReadonly=!n,this.isSSR=a}notify(){if(this.flags|=16,!(this.flags&8)&&Ne!==this)return oo(this,!0),!0}get value(){const t=this.dep.track();return co(this),t&&(t.version=this.dep.version),this._value}set value(t){this.setter&&this.setter(t)}}function $u(e,t,n=!1){let a,s;return we(e)?a=e:(a=e.get,s=e.set),new Ru(a,s,n)}const wa={},Ea=new WeakMap;let pn;function Tu(e,t=!1,n=pn){if(n){let a=Ea.get(n);a||Ea.set(n,a=[]),a.push(e)}}function Pu(e,t,n=Me){const{immediate:a,deep:s,once:r,scheduler:o,augmentJob:i,call:l}=n,u=C=>s?C:ht(C)||s===!1||s===0?on(C,1):on(C);let c,d,f,_,h=!1,m=!1;if(Ve(e)?(d=()=>e.value,h=ht(e)):Kt(e)?(d=()=>u(e),h=!0):ye(e)?(m=!0,h=e.some(C=>Kt(C)||ht(C)),d=()=>e.map(C=>{if(Ve(C))return C.value;if(Kt(C))return u(C);if(we(C))return l?l(C,2):C()})):we(e)?t?d=l?()=>l(e,2):e:d=()=>{if(f){Wt();try{f()}finally{Jt()}}const C=pn;pn=c;try{return l?l(e,3,[_]):e(_)}finally{pn=C}}:d=Ft,t&&s){const C=d,I=s===!0?1/0:s;d=()=>on(C(),I)}const g=so(),E=()=>{c.stop(),g&&g.active&&Zs(g.effects,c)};if(r&&t){const C=t;t=(...I)=>{C(...I),E()}}let y=m?new Array(e.length).fill(wa):wa;const w=C=>{if(!(!(c.flags&1)||!c.dirty&&!C))if(t){const I=c.run();if(s||h||(m?I.some((P,R)=>Ot(P,y[R])):Ot(I,y))){f&&f();const P=pn;pn=c;try{const R=[I,y===wa?void 0:m&&y[0]===wa?[]:y,_];y=I,l?l(t,3,R):t(...R)}finally{pn=P}}}else c.run()};return i&&i(w),c=new ro(d),c.scheduler=o?()=>o(w,!1):w,_=C=>Tu(C,!1,c),f=c.onStop=()=>{const C=Ea.get(c);if(C){if(l)l(C,4);else for(const I of C)I();Ea.delete(c)}},t?a?w(!0):y=c.run():o?o(w.bind(null,!0),!0):c.run(),E.pause=c.pause.bind(c),E.resume=c.resume.bind(c),E.stop=E,E}function on(e,t=1/0,n){if(t<=0||!Te(e)||e.__v_skip||(n=n||new Map,(n.get(e)||0)>=t))return e;if(n.set(e,t),t--,Ve(e))on(e.value,t,n);else if(ye(e))for(let a=0;a{on(a,t,n)});else if(Xi(e)){for(const a in e)on(e[a],t,n);for(const a of Object.getOwnPropertySymbols(e))Object.prototype.propertyIsEnumerable.call(e,a)&&on(e[a],t,n)}return e}/** +* @vue/runtime-core v3.5.33 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/function ga(e,t,n,a){try{return a?e(...a):e()}catch(s){za(s,t,n)}}function Ut(e,t,n,a){if(we(e)){const s=ga(e,t,n,a);return s&&Ji(s)&&s.catch(r=>{za(r,t,n)}),s}if(ye(e)){const s=[];for(let r=0;r>>1,s=ct[a],r=ua(s);r=ua(n)?ct.push(e):ct.splice(Lu(t),0,e),e.flags|=1,Ao()}}function Ao(){Ra||(Ra=ko.then(Co))}function Du(e){ye(e)?Tn.push(...e):sn&&e.id===-1?sn.splice(xn+1,0,e):e.flags&1||(Tn.push(e),e.flags|=1),Ao()}function Fr(e,t,n=It+1){for(;nua(n)-ua(a));if(Tn.length=0,sn){sn.push(...t);return}for(sn=t,xn=0;xne.id==null?e.flags&2?-1:1/0:e.id;function Co(e){try{for(It=0;It{a._d&&Ia(-1);const r=$a(t);let o;try{o=e(...s)}finally{$a(r),a._d&&Ia(1)}return o};return a._n=!0,a._c=!0,a._d=!0,a}function dn(e,t,n,a){const s=e.dirs,r=t&&t.dirs;for(let o=0;o1)return n&&we(t)?t.call(a&&a.proxy):t}}function Ou(){return!!(Za()||mn)}const Fu=Symbol.for("v-scx"),Nu=()=>mt(Fu);function wt(e,t,n){return Ro(e,t,n)}function Ro(e,t,n=Me){const{immediate:a,deep:s,flush:r,once:o}=n,i=tt({},n),l=t&&a||!t&&r!=="post";let u;if(fa){if(r==="sync"){const _=Nu();u=_.__watcherHandles||(_.__watcherHandles=[])}else if(!l){const _=()=>{};return _.stop=Ft,_.resume=Ft,_.pause=Ft,_}}const c=rt;i.call=(_,h,m)=>Ut(_,c,h,m);let d=!1;r==="post"?i.scheduler=_=>{lt(_,c&&c.suspense)}:r!=="sync"&&(d=!0,i.scheduler=(_,h)=>{h?_():lr(_)}),i.augmentJob=_=>{t&&(_.flags|=4),d&&(_.flags|=2,c&&(_.id=c.uid,_.i=c))};const f=Pu(e,t,i);return fa&&(u?u.push(f):l&&f()),f}function Mu(e,t,n){const a=this.proxy,s=He(e)?e.includes(".")?$o(a,e):()=>a[e]:e.bind(a,a);let r;we(t)?r=t:(r=t.handler,n=t);const o=ma(this),i=Ro(s,r.bind(a),n);return o(),i}function $o(e,t){const n=t.split(".");return()=>{let a=e;for(let s=0;se.__isTeleport,vn=e=>e&&(e.disabled||e.disabled===""),Vu=e=>e&&(e.defer||e.defer===""),Nr=e=>typeof SVGElement<"u"&&e instanceof SVGElement,Mr=e=>typeof MathMLElement=="function"&&e instanceof MathMLElement,Ls=(e,t)=>{const n=e&&e.to;return He(n)?t?t(n):null:n},ju={name:"Teleport",__isTeleport:!0,process(e,t,n,a,s,r,o,i,l,u){const{mc:c,pc:d,pbc:f,o:{insert:_,querySelector:h,createText:m,createComment:g,parentNode:E}}=u,y=vn(t.props);let{dynamicChildren:w}=t;const C=(R,L,k)=>{R.shapeFlag&16&&c(R.children,L,k,s,r,o,i,l)},I=(R=t)=>{const L=vn(R.props),k=R.target=Ls(R.props,h),ee=Ds(k,R,m,_);k&&(o!=="svg"&&Nr(k)?o="svg":o!=="mathml"&&Mr(k)&&(o="mathml"),s&&s.isCE&&(s.ce._teleportTargets||(s.ce._teleportTargets=new Set)).add(k),L||(C(R,k,ee),Jn(R,!1)))},P=R=>{const L=()=>{if(nn.get(R)===L){if(nn.delete(R),vn(R.props)){const k=E(R.el)||n;C(R,k,R.anchor),Jn(R,!0)}I(R)}};nn.set(R,L),lt(L,r)};if(e==null){const R=t.el=m(""),L=t.anchor=m("");if(_(R,n,a),_(L,n,a),Vu(t.props)||r&&r.pendingBranch){P(t);return}y&&(C(t,n,L),Jn(t,!0)),I()}else{t.el=e.el;const R=t.anchor=e.anchor,L=nn.get(e);if(L){L.flags|=8,nn.delete(e),P(t);return}t.targetStart=e.targetStart;const k=t.target=e.target,ee=t.targetAnchor=e.targetAnchor,le=vn(e.props),fe=le?n:k,ge=le?R:ee;if(o==="svg"||Nr(k)?o="svg":(o==="mathml"||Mr(k))&&(o="mathml"),w?(f(e.dynamicChildren,w,fe,s,r,o,i),fr(e,t,!0)):l||d(e,t,fe,ge,s,r,o,i,!1),y)le?t.props&&e.props&&t.props.to!==e.props.to&&(t.props.to=e.props.to):Sa(t,n,R,u,1);else if((t.props&&t.props.to)!==(e.props&&e.props.to)){const B=t.target=Ls(t.props,h);B&&Sa(t,B,null,u,0)}else le&&Sa(t,k,ee,u,1);Jn(t,y)}},remove(e,t,n,{um:a,o:{remove:s}},r){const{shapeFlag:o,children:i,anchor:l,targetStart:u,targetAnchor:c,target:d,props:f}=e;let _=r||!vn(f);const h=nn.get(e);if(h&&(h.flags|=8,nn.delete(e),_=!1),d&&(s(u),s(c)),r&&s(l),o&16)for(let m=0;mna(m,t&&(ye(t)?t[g]:t),n,a,s));return}if(Pn(a)&&!s){a.shapeFlag&512&&a.type.__asyncResolved&&a.component.subTree.component&&na(e,t,n,a.component.subTree);return}const r=a.shapeFlag&4?vr(a.component):a.el,o=s?null:r,{i,r:l}=e,u=t&&t.r,c=i.refs===Me?i.refs={}:i.refs,d=i.setupState,f=Ae(d),_=d===Me?Ki:m=>Ur(c,m)?!1:Ce(f,m),h=(m,g)=>!(g&&Ur(c,g));if(u!=null&&u!==l){if(Vr(t),He(u))c[u]=null,_(u)&&(d[u]=null);else if(Ve(u)){const m=t;h(u,m.k)&&(u.value=null),m.k&&(c[m.k]=null)}}if(we(l))ga(l,i,12,[o,c]);else{const m=He(l),g=Ve(l);if(m||g){const E=()=>{if(e.f){const y=m?_(l)?d[l]:c[l]:h()||!e.k?l.value:c[e.k];if(s)ye(y)&&Zs(y,r);else if(ye(y))y.includes(r)||y.push(r);else if(m)c[l]=[r],_(l)&&(d[l]=c[l]);else{const w=[r];h(l,e.k)&&(l.value=w),e.k&&(c[e.k]=w)}}else m?(c[l]=o,_(l)&&(d[l]=o)):g&&(h(l,e.k)&&(l.value=o),e.k&&(c[e.k]=o))};if(o){const y=()=>{E(),Ta.delete(e)};y.id=-1,Ta.set(e,y),lt(y,n)}else Vr(e),E()}}}function Vr(e){const t=Ta.get(e);t&&(t.flags|=8,Ta.delete(e))}Ha().requestIdleCallback;Ha().cancelIdleCallback;const Pn=e=>!!e.type.__asyncLoader,Io=e=>e.type.__isKeepAlive;function qu(e,t){Lo(e,"a",t)}function zu(e,t){Lo(e,"da",t)}function Lo(e,t,n=rt){const a=e.__wdc||(e.__wdc=()=>{let s=n;for(;s;){if(s.isDeactivated)return;s=s.parent}return e()});if(Ka(t,a,n),n){let s=n.parent;for(;s&&s.parent;)Io(s.parent.vnode)&&Ku(a,t,n,s),s=s.parent}}function Ku(e,t,n,a){const s=Ka(t,e,a,!0);ha(()=>{Zs(a[t],s)},n)}function Ka(e,t,n=rt,a=!1){if(n){const s=n[e]||(n[e]=[]),r=t.__weh||(t.__weh=(...o)=>{Wt();const i=ma(n),l=Ut(t,n,e,o);return i(),Jt(),l});return a?s.unshift(r):s.push(r),r}}const Qt=e=>(t,n=rt)=>{(!fa||e==="sp")&&Ka(e,(...a)=>t(...a),n)},Wu=Qt("bm"),bt=Qt("m"),Ju=Qt("bu"),Yu=Qt("u"),Wa=Qt("bum"),ha=Qt("um"),Xu=Qt("sp"),Zu=Qt("rtg"),Qu=Qt("rtc");function Do(e,t=rt){Ka("ec",e,t)}const ec="components";function cn(e,t){return nc(ec,e,!0,t)||e}const tc=Symbol.for("v-ndc");function nc(e,t,n=!0,a=!1){const s=dt||rt;if(s){const r=s.type;{const i=Vc(r,!1);if(i&&(i===t||i===ft(t)||i===Ba(ft(t))))return r}const o=jr(s[e]||r[e],t)||jr(s.appContext[e],t);return!o&&a?r:o}}function jr(e,t){return e&&(e[t]||e[ft(t)]||e[Ba(ft(t))])}function Vt(e,t,n,a){let s;const r=n,o=ye(e);if(o||He(e)){const i=o&&Kt(e);let l=!1,u=!1;i&&(l=!ht(e),u=Yt(e),e=Ga(e)),s=new Array(e.length);for(let c=0,d=e.length;ct(i,l,void 0,r));else{const i=Object.keys(e);s=new Array(i.length);for(let l=0,u=i.length;l{const r=a.fn(...s);return r&&(r.key=a.key),r}:a.fn)}return e}function Ja(e,t,n={},a,s){if(dt.ce||dt.parent&&Pn(dt.parent)&&dt.parent.ce){const u=Object.keys(n).length>0;return t!=="default"&&(n.name=t),S(),q(Ee,null,[$("slot",n,a&&a())],u?-2:64)}let r=e[t];r&&r._c&&(r._d=!1),S();const o=r&&Fo(r(n)),i=n.key||o&&o.key,l=q(Ee,{key:(i&&!_t(i)?i:`_${t}`)+(!o&&a?"_fb":"")},o||(a?a():[]),o&&e._===1?64:-2);return!s&&l.scopeId&&(l.slotScopeIds=[l.scopeId+"-s"]),r&&r._c&&(r._d=!0),l}function Fo(e){return e.some(t=>da(t)?!(t.type===Xt||t.type===Ee&&!Fo(t.children)):!0)?e:null}const Os=e=>e?nl(e)?vr(e):Os(e.parent):null,aa=tt(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>Os(e.parent),$root:e=>Os(e.root),$host:e=>e.ce,$emit:e=>e.emit,$options:e=>Mo(e),$forceUpdate:e=>e.f||(e.f=()=>{lr(e.update)}),$nextTick:e=>e.n||(e.n=_n.bind(e.proxy)),$watch:e=>Mu.bind(e)}),vs=(e,t)=>e!==Me&&!e.__isScriptSetup&&Ce(e,t),ac={get({_:e},t){if(t==="__v_skip")return!0;const{ctx:n,setupState:a,data:s,props:r,accessCache:o,type:i,appContext:l}=e;if(t[0]!=="$"){const f=o[t];if(f!==void 0)switch(f){case 1:return a[t];case 2:return s[t];case 4:return n[t];case 3:return r[t]}else{if(vs(a,t))return o[t]=1,a[t];if(s!==Me&&Ce(s,t))return o[t]=2,s[t];if(Ce(r,t))return o[t]=3,r[t];if(n!==Me&&Ce(n,t))return o[t]=4,n[t];Fs&&(o[t]=0)}}const u=aa[t];let c,d;if(u)return t==="$attrs"&&st(e.attrs,"get",""),u(e);if((c=i.__cssModules)&&(c=c[t]))return c;if(n!==Me&&Ce(n,t))return o[t]=4,n[t];if(d=l.config.globalProperties,Ce(d,t))return d[t]},set({_:e},t,n){const{data:a,setupState:s,ctx:r}=e;return vs(s,t)?(s[t]=n,!0):a!==Me&&Ce(a,t)?(a[t]=n,!0):Ce(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(r[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:a,appContext:s,props:r,type:o}},i){let l;return!!(n[i]||e!==Me&&i[0]!=="$"&&Ce(e,i)||vs(t,i)||Ce(r,i)||Ce(a,i)||Ce(aa,i)||Ce(s.config.globalProperties,i)||(l=o.__cssModules)&&l[i])},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:Ce(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};function Br(e){return ye(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}let Fs=!0;function sc(e){const t=Mo(e),n=e.proxy,a=e.ctx;Fs=!1,t.beforeCreate&&Hr(t.beforeCreate,e,"bc");const{data:s,computed:r,methods:o,watch:i,provide:l,inject:u,created:c,beforeMount:d,mounted:f,beforeUpdate:_,updated:h,activated:m,deactivated:g,beforeDestroy:E,beforeUnmount:y,destroyed:w,unmounted:C,render:I,renderTracked:P,renderTriggered:R,errorCaptured:L,serverPrefetch:k,expose:ee,inheritAttrs:le,components:fe,directives:ge,filters:B}=t;if(u&&rc(u,a,null),o)for(const Y in o){const te=o[Y];we(te)&&(a[Y]=te.bind(n))}if(s){const Y=s.call(n,n);Te(Y)&&(e.data=Zt(Y))}if(Fs=!0,r)for(const Y in r){const te=r[Y],ve=we(te)?te.bind(n,n):we(te.get)?te.get.bind(n,n):Ft,ke=!we(te)&&we(te.set)?te.set.bind(n):Ft,Pe=Q({get:ve,set:ke});Object.defineProperty(a,Y,{enumerable:!0,configurable:!0,get:()=>Pe.value,set:be=>Pe.value=be})}if(i)for(const Y in i)No(i[Y],a,n,Y);if(l){const Y=we(l)?l.call(n):l;Reflect.ownKeys(Y).forEach(te=>{ta(te,Y[te])})}c&&Hr(c,e,"c");function Z(Y,te){ye(te)?te.forEach(ve=>Y(ve.bind(n))):te&&Y(te.bind(n))}if(Z(Wu,d),Z(bt,f),Z(Ju,_),Z(Yu,h),Z(qu,m),Z(zu,g),Z(Do,L),Z(Qu,P),Z(Zu,R),Z(Wa,y),Z(ha,C),Z(Xu,k),ye(ee))if(ee.length){const Y=e.exposed||(e.exposed={});ee.forEach(te=>{Object.defineProperty(Y,te,{get:()=>n[te],set:ve=>n[te]=ve,enumerable:!0})})}else e.exposed||(e.exposed={});I&&e.render===Ft&&(e.render=I),le!=null&&(e.inheritAttrs=le),fe&&(e.components=fe),ge&&(e.directives=ge),k&&Po(e)}function rc(e,t,n=Ft){ye(e)&&(e=Ns(e));for(const a in e){const s=e[a];let r;Te(s)?"default"in s?r=mt(s.from||a,s.default,!0):r=mt(s.from||a):r=mt(s),Ve(r)?Object.defineProperty(t,a,{enumerable:!0,configurable:!0,get:()=>r.value,set:o=>r.value=o}):t[a]=r}}function Hr(e,t,n){Ut(ye(e)?e.map(a=>a.bind(t.proxy)):e.bind(t.proxy),t,n)}function No(e,t,n,a){let s=a.includes(".")?$o(n,a):()=>n[a];if(He(e)){const r=t[e];we(r)&&wt(s,r)}else if(we(e))wt(s,e.bind(n));else if(Te(e))if(ye(e))e.forEach(r=>No(r,t,n,a));else{const r=we(e.handler)?e.handler.bind(n):t[e.handler];we(r)&&wt(s,r,e)}}function Mo(e){const t=e.type,{mixins:n,extends:a}=t,{mixins:s,optionsCache:r,config:{optionMergeStrategies:o}}=e.appContext,i=r.get(t);let l;return i?l=i:!s.length&&!n&&!a?l=t:(l={},s.length&&s.forEach(u=>Pa(l,u,o,!0)),Pa(l,t,o)),Te(t)&&r.set(t,l),l}function Pa(e,t,n,a=!1){const{mixins:s,extends:r}=t;r&&Pa(e,r,n,!0),s&&s.forEach(o=>Pa(e,o,n,!0));for(const o in t)if(!(a&&o==="expose")){const i=ic[o]||n&&n[o];e[o]=i?i(e[o],t[o]):t[o]}return e}const ic={data:Gr,props:qr,emits:qr,methods:Yn,computed:Yn,beforeCreate:ot,created:ot,beforeMount:ot,mounted:ot,beforeUpdate:ot,updated:ot,beforeDestroy:ot,beforeUnmount:ot,destroyed:ot,unmounted:ot,activated:ot,deactivated:ot,errorCaptured:ot,serverPrefetch:ot,components:Yn,directives:Yn,watch:lc,provide:Gr,inject:oc};function Gr(e,t){return t?e?function(){return tt(we(e)?e.call(this,this):e,we(t)?t.call(this,this):t)}:t:e}function oc(e,t){return Yn(Ns(e),Ns(t))}function Ns(e){if(ye(e)){const t={};for(let n=0;nt==="modelValue"||t==="model-value"?e.modelModifiers:e[`${t}Modifiers`]||e[`${ft(t)}Modifiers`]||e[`${un(t)}Modifiers`];function fc(e,t,...n){if(e.isUnmounted)return;const a=e.vnode.props||Me;let s=n;const r=t.startsWith("update:"),o=r&&dc(a,t.slice(7));o&&(o.trim&&(s=n.map(c=>He(c)?c.trim():c)),o.number&&(s=n.map(Wl)));let i,l=a[i=ls(t)]||a[i=ls(ft(t))];!l&&r&&(l=a[i=ls(un(t))]),l&&Ut(l,e,6,s);const u=a[i+"Once"];if(u){if(!e.emitted)e.emitted={};else if(e.emitted[i])return;e.emitted[i]=!0,Ut(u,e,6,s)}}const pc=new WeakMap;function Vo(e,t,n=!1){const a=n?pc:t.emitsCache,s=a.get(e);if(s!==void 0)return s;const r=e.emits;let o={},i=!1;if(!we(e)){const l=u=>{const c=Vo(u,t,!0);c&&(i=!0,tt(o,c))};!n&&t.mixins.length&&t.mixins.forEach(l),e.extends&&l(e.extends),e.mixins&&e.mixins.forEach(l)}return!r&&!i?(Te(e)&&a.set(e,null),null):(ye(r)?r.forEach(l=>o[l]=null):tt(o,r),Te(e)&&a.set(e,o),o)}function Ya(e,t){return!e||!Ma(t)?!1:(t=t.slice(2).replace(/Once$/,""),Ce(e,t[0].toLowerCase()+t.slice(1))||Ce(e,un(t))||Ce(e,t))}function zr(e){const{type:t,vnode:n,proxy:a,withProxy:s,propsOptions:[r],slots:o,attrs:i,emit:l,render:u,renderCache:c,props:d,data:f,setupState:_,ctx:h,inheritAttrs:m}=e,g=$a(e);let E,y;try{if(n.shapeFlag&4){const C=s||a,I=C;E=Dt(u.call(I,C,c,d,_,f,h)),y=i}else{const C=t;E=Dt(C.length>1?C(d,{attrs:i,slots:o,emit:l}):C(d,null)),y=t.props?i:vc(i)}}catch(C){sa.length=0,za(C,e,1),E=$(Xt)}let w=E;if(y&&m!==!1){const C=Object.keys(y),{shapeFlag:I}=w;C.length&&I&7&&(r&&C.some(Ua)&&(y=gc(y,r)),w=Ln(w,y,!1,!0))}return n.dirs&&(w=Ln(w,null,!1,!0),w.dirs=w.dirs?w.dirs.concat(n.dirs):n.dirs),n.transition&&ur(w,n.transition),E=w,$a(g),E}const vc=e=>{let t;for(const n in e)(n==="class"||n==="style"||Ma(n))&&((t||(t={}))[n]=e[n]);return t},gc=(e,t)=>{const n={};for(const a in e)(!Ua(a)||!(a.slice(9)in t))&&(n[a]=e[a]);return n};function hc(e,t,n){const{props:a,children:s,component:r}=e,{props:o,children:i,patchFlag:l}=t,u=r.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&l>=0){if(l&1024)return!0;if(l&16)return a?Kr(a,o,u):!!o;if(l&8){const c=t.dynamicProps;for(let d=0;dObject.create(Bo),Go=e=>Object.getPrototypeOf(e)===Bo;function yc(e,t,n,a=!1){const s={},r=Ho();e.propsDefaults=Object.create(null),qo(e,t,s,r);for(const o in e.propsOptions[0])o in s||(s[o]=void 0);n?e.props=a?s:bo(s):e.type.props?e.props=s:e.props=r,e.attrs=r}function _c(e,t,n,a){const{props:s,attrs:r,vnode:{patchFlag:o}}=e,i=Ae(s),[l]=e.propsOptions;let u=!1;if((a||o>0)&&!(o&16)){if(o&8){const c=e.vnode.dynamicProps;for(let d=0;d{l=!0;const[f,_]=zo(d,t,!0);tt(o,f),_&&i.push(..._)};!n&&t.mixins.length&&t.mixins.forEach(c),e.extends&&c(e.extends),e.mixins&&e.mixins.forEach(c)}if(!r&&!l)return Te(e)&&a.set(e,Rn),Rn;if(ye(r))for(let c=0;ce==="_"||e==="_ctx"||e==="$stable",dr=e=>ye(e)?e.map(Dt):[Dt(e)],wc=(e,t,n)=>{if(t._n)return t;const a=x((...s)=>dr(t(...s)),n);return a._c=!1,a},Ko=(e,t,n)=>{const a=e._ctx;for(const s in e){if(cr(s))continue;const r=e[s];if(we(r))t[s]=wc(s,r,a);else if(r!=null){const o=dr(r);t[s]=()=>o}}},Wo=(e,t)=>{const n=dr(t);e.slots.default=()=>n},Jo=(e,t,n)=>{for(const a in t)(n||!cr(a))&&(e[a]=t[a])},Sc=(e,t,n)=>{const a=e.slots=Ho();if(e.vnode.shapeFlag&32){const s=t._;s?(Jo(a,t,n),n&&Zi(a,"_",s,!0)):Ko(t,a)}else t&&Wo(e,t)},kc=(e,t,n)=>{const{vnode:a,slots:s}=e;let r=!0,o=Me;if(a.shapeFlag&32){const i=t._;i?n&&i===1?r=!1:Jo(s,t,n):(r=!t.$stable,Ko(t,s)),o=t}else t&&(Wo(e,t),o={default:1});if(r)for(const i in s)!cr(i)&&o[i]==null&&delete s[i]},lt=Rc;function Ac(e){return xc(e)}function xc(e,t){const n=Ha();n.__VUE__=!0;const{insert:a,remove:s,patchProp:r,createElement:o,createText:i,createComment:l,setText:u,setElementText:c,parentNode:d,nextSibling:f,setScopeId:_=Ft,insertStaticContent:h}=e,m=(p,b,A,V=null,K=null,z=null,oe=void 0,re=null,ae=!!b.dynamicChildren)=>{if(p===b)return;p&&!Bn(p,b)&&(V=M(p),be(p,K,z,!0),p=null),b.patchFlag===-2&&(ae=!1,b.dynamicChildren=null);const{type:X,ref:pe,shapeFlag:ue}=b;switch(X){case Xa:g(p,b,A,V);break;case Xt:E(p,b,A,V);break;case ka:p==null&&y(b,A,V,oe);break;case Ee:fe(p,b,A,V,K,z,oe,re,ae);break;default:ue&1?I(p,b,A,V,K,z,oe,re,ae):ue&6?ge(p,b,A,V,K,z,oe,re,ae):(ue&64||ue&128)&&X.process(p,b,A,V,K,z,oe,re,ae,F)}pe!=null&&K?na(pe,p&&p.ref,z,b||p,!b):pe==null&&p&&p.ref!=null&&na(p.ref,null,z,p,!0)},g=(p,b,A,V)=>{if(p==null)a(b.el=i(b.children),A,V);else{const K=b.el=p.el;b.children!==p.children&&u(K,b.children)}},E=(p,b,A,V)=>{p==null?a(b.el=l(b.children||""),A,V):b.el=p.el},y=(p,b,A,V)=>{[p.el,p.anchor]=h(p.children,b,A,V,p.el,p.anchor)},w=({el:p,anchor:b},A,V)=>{let K;for(;p&&p!==b;)K=f(p),a(p,A,V),p=K;a(b,A,V)},C=({el:p,anchor:b})=>{let A;for(;p&&p!==b;)A=f(p),s(p),p=A;s(b)},I=(p,b,A,V,K,z,oe,re,ae)=>{if(b.type==="svg"?oe="svg":b.type==="math"&&(oe="mathml"),p==null)P(b,A,V,K,z,oe,re,ae);else{const X=p.el&&p.el._isVueCE?p.el:null;try{X&&X._beginPatch(),k(p,b,K,z,oe,re,ae)}finally{X&&X._endPatch()}}},P=(p,b,A,V,K,z,oe,re)=>{let ae,X;const{props:pe,shapeFlag:ue,transition:ce,dirs:me}=p;if(ae=p.el=o(p.type,z,pe&&pe.is,pe),ue&8?c(ae,p.children):ue&16&&L(p.children,ae,null,V,K,gs(p,z),oe,re),me&&dn(p,null,V,"created"),R(ae,p,p.scopeId,oe,V),pe){for(const $e in pe)$e!=="value"&&!Zn($e)&&r(ae,$e,null,pe[$e],z,V);"value"in pe&&r(ae,"value",null,pe.value,z),(X=pe.onVnodeBeforeMount)&&$t(X,V,p)}me&&dn(p,null,V,"beforeMount");const Se=Cc(K,ce);Se&&ce.beforeEnter(ae),a(ae,b,A),((X=pe&&pe.onVnodeMounted)||Se||me)&<(()=>{try{X&&$t(X,V,p),Se&&ce.enter(ae),me&&dn(p,null,V,"mounted")}finally{}},K)},R=(p,b,A,V,K)=>{if(A&&_(p,A),V)for(let z=0;z{for(let X=ae;X{const re=b.el=p.el;let{patchFlag:ae,dynamicChildren:X,dirs:pe}=b;ae|=p.patchFlag&16;const ue=p.props||Me,ce=b.props||Me;let me;if(A&&fn(A,!1),(me=ce.onVnodeBeforeUpdate)&&$t(me,A,b,p),pe&&dn(b,p,A,"beforeUpdate"),A&&fn(A,!0),(ue.innerHTML&&ce.innerHTML==null||ue.textContent&&ce.textContent==null)&&c(re,""),X?ee(p.dynamicChildren,X,re,A,V,gs(b,K),z):oe||te(p,b,re,null,A,V,gs(b,K),z,!1),ae>0){if(ae&16)le(re,ue,ce,A,K);else if(ae&2&&ue.class!==ce.class&&r(re,"class",null,ce.class,K),ae&4&&r(re,"style",ue.style,ce.style,K),ae&8){const Se=b.dynamicProps;for(let $e=0;$e{me&&$t(me,A,b,p),pe&&dn(b,p,A,"updated")},V)},ee=(p,b,A,V,K,z,oe)=>{for(let re=0;re{if(b!==A){if(b!==Me)for(const z in b)!Zn(z)&&!(z in A)&&r(p,z,b[z],null,K,V);for(const z in A){if(Zn(z))continue;const oe=A[z],re=b[z];oe!==re&&z!=="value"&&r(p,z,re,oe,K,V)}"value"in A&&r(p,"value",b.value,A.value,K)}},fe=(p,b,A,V,K,z,oe,re,ae)=>{const X=b.el=p?p.el:i(""),pe=b.anchor=p?p.anchor:i("");let{patchFlag:ue,dynamicChildren:ce,slotScopeIds:me}=b;me&&(re=re?re.concat(me):me),p==null?(a(X,A,V),a(pe,A,V),L(b.children||[],A,pe,K,z,oe,re,ae)):ue>0&&ue&64&&ce&&p.dynamicChildren&&p.dynamicChildren.length===ce.length?(ee(p.dynamicChildren,ce,A,K,z,oe,re),(b.key!=null||K&&b===K.subTree)&&fr(p,b,!0)):te(p,b,A,pe,K,z,oe,re,ae)},ge=(p,b,A,V,K,z,oe,re,ae)=>{b.slotScopeIds=re,p==null?b.shapeFlag&512?K.ctx.activate(b,A,V,oe,ae):B(b,A,V,K,z,oe,ae):W(p,b,ae)},B=(p,b,A,V,K,z,oe)=>{const re=p.component=Oc(p,V,K);if(Io(p)&&(re.ctx.renderer=F),Fc(re,!1,oe),re.asyncDep){if(K&&K.registerDep(re,Z,oe),!p.el){const ae=re.subTree=$(Xt);E(null,ae,b,A),p.placeholder=ae.el}}else Z(re,p,b,A,K,z,oe)},W=(p,b,A)=>{const V=b.component=p.component;if(hc(p,b,A))if(V.asyncDep&&!V.asyncResolved){Y(V,b,A);return}else V.next=b,V.update();else b.el=p.el,V.vnode=b},Z=(p,b,A,V,K,z,oe)=>{const re=()=>{if(p.isMounted){let{next:ue,bu:ce,u:me,parent:Se,vnode:$e}=p;{const Le=Yo(p);if(Le){ue&&(ue.el=$e.el,Y(p,ue,oe)),Le.asyncDep.then(()=>{lt(()=>{p.isUnmounted||X()},K)});return}}let Ie=ue,je;fn(p,!1),ue?(ue.el=$e.el,Y(p,ue,oe)):ue=$e,ce&&us(ce),(je=ue.props&&ue.props.onVnodeBeforeUpdate)&&$t(je,Se,ue,$e),fn(p,!0);const ie=zr(p),D=p.subTree;p.subTree=ie,m(D,ie,d(D.el),M(D),p,K,z),ue.el=ie.el,Ie===null&&mc(p,ie.el),me&<(me,K),(je=ue.props&&ue.props.onVnodeUpdated)&<(()=>$t(je,Se,ue,$e),K)}else{let ue;const{el:ce,props:me}=b,{bm:Se,m:$e,parent:Ie,root:je,type:ie}=p,D=Pn(b);fn(p,!1),Se&&us(Se),!D&&(ue=me&&me.onVnodeBeforeMount)&&$t(ue,Ie,b),fn(p,!0);{je.ce&&je.ce._hasShadowRoot()&&je.ce._injectChildStyle(ie,p.parent?p.parent.type:void 0);const Le=p.subTree=zr(p);m(null,Le,A,V,p,K,z),b.el=Le.el}if($e&<($e,K),!D&&(ue=me&&me.onVnodeMounted)){const Le=b;lt(()=>$t(ue,Ie,Le),K)}(b.shapeFlag&256||Ie&&Pn(Ie.vnode)&&Ie.vnode.shapeFlag&256)&&p.a&<(p.a,K),p.isMounted=!0,b=A=V=null}};p.scope.on();const ae=p.effect=new ro(re);p.scope.off();const X=p.update=ae.run.bind(ae),pe=p.job=ae.runIfDirty.bind(ae);pe.i=p,pe.id=p.uid,ae.scheduler=()=>lr(pe),fn(p,!0),X()},Y=(p,b,A)=>{b.component=p;const V=p.vnode.props;p.vnode=b,p.next=null,_c(p,b.props,V,A),kc(p,b.children,A),Wt(),Fr(p),Jt()},te=(p,b,A,V,K,z,oe,re,ae=!1)=>{const X=p&&p.children,pe=p?p.shapeFlag:0,ue=b.children,{patchFlag:ce,shapeFlag:me}=b;if(ce>0){if(ce&128){ke(X,ue,A,V,K,z,oe,re,ae);return}else if(ce&256){ve(X,ue,A,V,K,z,oe,re,ae);return}}me&8?(pe&16&&Oe(X,K,z),ue!==X&&c(A,ue)):pe&16?me&16?ke(X,ue,A,V,K,z,oe,re,ae):Oe(X,K,z,!0):(pe&8&&c(A,""),me&16&&L(ue,A,V,K,z,oe,re,ae))},ve=(p,b,A,V,K,z,oe,re,ae)=>{p=p||Rn,b=b||Rn;const X=p.length,pe=b.length,ue=Math.min(X,pe);let ce;for(ce=0;cepe?Oe(p,K,z,!0,!1,ue):L(b,A,V,K,z,oe,re,ae,ue)},ke=(p,b,A,V,K,z,oe,re,ae)=>{let X=0;const pe=b.length;let ue=p.length-1,ce=pe-1;for(;X<=ue&&X<=ce;){const me=p[X],Se=b[X]=ae?qt(b[X]):Dt(b[X]);if(Bn(me,Se))m(me,Se,A,null,K,z,oe,re,ae);else break;X++}for(;X<=ue&&X<=ce;){const me=p[ue],Se=b[ce]=ae?qt(b[ce]):Dt(b[ce]);if(Bn(me,Se))m(me,Se,A,null,K,z,oe,re,ae);else break;ue--,ce--}if(X>ue){if(X<=ce){const me=ce+1,Se=mece)for(;X<=ue;)be(p[X],K,z,!0),X++;else{const me=X,Se=X,$e=new Map;for(X=Se;X<=ce;X++){const Je=b[X]=ae?qt(b[X]):Dt(b[X]);Je.key!=null&&$e.set(Je.key,X)}let Ie,je=0;const ie=ce-Se+1;let D=!1,Le=0;const et=new Array(ie);for(X=0;X=ie){be(Je,K,z,!0);continue}let Ke;if(Je.key!=null)Ke=$e.get(Je.key);else for(Ie=Se;Ie<=ce;Ie++)if(et[Ie-Se]===0&&Bn(Je,b[Ie])){Ke=Ie;break}Ke===void 0?be(Je,K,z,!0):(et[Ke-Se]=X+1,Ke>=Le?Le=Ke:D=!0,m(Je,b[Ke],A,null,K,z,oe,re,ae),je++)}const he=D?Ec(et):Rn;for(Ie=he.length-1,X=ie-1;X>=0;X--){const Je=Se+X,Ke=b[Je],Vn=b[Je+1],Pr=Je+1{const{el:z,type:oe,transition:re,children:ae,shapeFlag:X}=p;if(X&6){Pe(p.component.subTree,b,A,V);return}if(X&128){p.suspense.move(b,A,V);return}if(X&64){oe.move(p,b,A,F);return}if(oe===Ee){a(z,b,A);for(let ue=0;uere.enter(z),K);else{const{leave:ue,delayLeave:ce,afterLeave:me}=re,Se=()=>{p.ctx.isUnmounted?s(z):a(z,b,A)},$e=()=>{z._isLeaving&&z[Gu](!0),ue(z,()=>{Se(),me&&me()})};ce?ce(z,Se,$e):$e()}else a(z,b,A)},be=(p,b,A,V=!1,K=!1)=>{const{type:z,props:oe,ref:re,children:ae,dynamicChildren:X,shapeFlag:pe,patchFlag:ue,dirs:ce,cacheIndex:me,memo:Se}=p;if(ue===-2&&(K=!1),re!=null&&(Wt(),na(re,null,A,p,!0),Jt()),me!=null&&(b.renderCache[me]=void 0),pe&256){b.ctx.deactivate(p);return}const $e=pe&1&&ce,Ie=!Pn(p);let je;if(Ie&&(je=oe&&oe.onVnodeBeforeUnmount)&&$t(je,b,p),pe&6)De(p.component,A,V);else{if(pe&128){p.suspense.unmount(A,V);return}$e&&dn(p,null,b,"beforeUnmount"),pe&64?p.type.remove(p,b,A,F,V):X&&!X.hasOnce&&(z!==Ee||ue>0&&ue&64)?Oe(X,b,A,!1,!0):(z===Ee&&ue&384||!K&&pe&16)&&Oe(ae,b,A),V&&Ge(p)}const ie=Se!=null&&me==null;(Ie&&(je=oe&&oe.onVnodeUnmounted)||$e||ie)&<(()=>{je&&$t(je,b,p),$e&&dn(p,null,b,"unmounted"),ie&&(p.el=null)},A)},Ge=p=>{const{type:b,el:A,anchor:V,transition:K}=p;if(b===Ee){Ue(A,V);return}if(b===ka){C(p);return}const z=()=>{s(A),K&&!K.persisted&&K.afterLeave&&K.afterLeave()};if(p.shapeFlag&1&&K&&!K.persisted){const{leave:oe,delayLeave:re}=K,ae=()=>oe(A,z);re?re(p.el,z,ae):ae()}else z()},Ue=(p,b)=>{let A;for(;p!==b;)A=f(p),s(p),p=A;s(b)},De=(p,b,A)=>{const{bum:V,scope:K,job:z,subTree:oe,um:re,m:ae,a:X}=p;Jr(ae),Jr(X),V&&us(V),K.stop(),z&&(z.flags|=8,be(oe,p,b,A)),re&<(re,b),lt(()=>{p.isUnmounted=!0},b)},Oe=(p,b,A,V=!1,K=!1,z=0)=>{for(let oe=z;oe{if(p.shapeFlag&6)return M(p.component.subTree);if(p.shapeFlag&128)return p.suspense.next();const b=f(p.anchor||p.el),A=b&&b[To];return A?f(A):b};let se=!1;const H=(p,b,A)=>{let V;p==null?b._vnode&&(be(b._vnode,null,null,!0),V=b._vnode.component):m(b._vnode||null,p,b,null,null,null,A),b._vnode=p,se||(se=!0,Fr(V),xo(),se=!1)},F={p:m,um:be,m:Pe,r:Ge,mt:B,mc:L,pc:te,pbc:ee,n:M,o:e};return{render:H,hydrate:void 0,createApp:cc(H)}}function gs({type:e,props:t},n){return n==="svg"&&e==="foreignObject"||n==="mathml"&&e==="annotation-xml"&&t&&t.encoding&&t.encoding.includes("html")?void 0:n}function fn({effect:e,job:t},n){n?(e.flags|=32,t.flags|=4):(e.flags&=-33,t.flags&=-5)}function Cc(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function fr(e,t,n=!1){const a=e.children,s=t.children;if(ye(a)&&ye(s))for(let r=0;r>1,e[n[i]]0&&(t[a]=n[r-1]),n[r]=a)}}for(r=n.length,o=n[r-1];r-- >0;)n[r]=o,o=t[o];return n}function Yo(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:Yo(t)}function Jr(e){if(e)for(let t=0;te.__isSuspense;function Rc(e,t){t&&t.pendingBranch?ye(e)?t.effects.push(...e):t.effects.push(e):Du(e)}const Ee=Symbol.for("v-fgt"),Xa=Symbol.for("v-txt"),Xt=Symbol.for("v-cmt"),ka=Symbol.for("v-stc"),sa=[];let vt=null;function S(e=!1){sa.push(vt=e?null:[])}function $c(){sa.pop(),vt=sa[sa.length-1]||null}let ca=1;function Ia(e,t=!1){ca+=e,e<0&&vt&&t&&(vt.hasOnce=!0)}function Qo(e){return e.dynamicChildren=ca>0?vt||Rn:null,$c(),ca>0&&vt&&vt.push(e),e}function G(e,t,n,a,s,r){return Qo(T(e,t,n,a,s,r,!0))}function q(e,t,n,a,s){return Qo($(e,t,n,a,s,!0))}function da(e){return e?e.__v_isVNode===!0:!1}function Bn(e,t){return e.type===t.type&&e.key===t.key}const el=({key:e})=>e??null,Aa=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?He(e)||Ve(e)||we(e)?{i:dt,r:e,k:t,f:!!n}:e:null);function T(e,t=null,n=null,a=0,s=null,r=e===Ee?0:1,o=!1,i=!1){const l={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&el(t),ref:t&&Aa(t),scopeId:Eo,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetStart:null,targetAnchor:null,staticCount:0,shapeFlag:r,patchFlag:a,dynamicProps:s,dynamicChildren:null,appContext:null,ctx:dt};return i?(pr(l,n),r&128&&e.normalize(l)):n&&(l.shapeFlag|=He(n)?8:16),ca>0&&!o&&vt&&(l.patchFlag>0||r&6)&&l.patchFlag!==32&&vt.push(l),l}const $=Tc;function Tc(e,t=null,n=null,a=0,s=null,r=!1){if((!e||e===tc)&&(e=Xt),da(e)){const i=Ln(e,t,!0);return n&&pr(i,n),ca>0&&!r&&vt&&(i.shapeFlag&6?vt[vt.indexOf(e)]=i:vt.push(i)),i.patchFlag=-2,i}if(jc(e)&&(e=e.__vccOpts),t){t=Pc(t);let{class:i,style:l}=t;i&&!He(i)&&(t.class=Mt(i)),Te(l)&&(qa(l)&&!ye(l)&&(l=tt({},l)),t.style=Qs(l))}const o=He(e)?1:Zo(e)?128:Uu(e)?64:Te(e)?4:we(e)?2:0;return T(e,t,n,a,s,o,r,!0)}function Pc(e){return e?qa(e)||Go(e)?tt({},e):e:null}function Ln(e,t,n=!1,a=!1){const{props:s,ref:r,patchFlag:o,children:i,transition:l}=e,u=t?tl(s||{},t):s,c={__v_isVNode:!0,__v_skip:!0,type:e.type,props:u,key:u&&el(u),ref:t&&t.ref?n&&r?ye(r)?r.concat(Aa(t)):[r,Aa(t)]:Aa(t):r,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:i,target:e.target,targetStart:e.targetStart,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==Ee?o===-1?16:o|16:o,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:l,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&Ln(e.ssContent),ssFallback:e.ssFallback&&Ln(e.ssFallback),placeholder:e.placeholder,el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce};return l&&a&&ur(c,l.clone(c)),c}function N(e=" ",t=0){return $(Xa,null,e,t)}function Ic(e,t){const n=$(ka,null,e);return n.staticCount=t,n}function ne(e="",t=!1){return t?(S(),q(Xt,null,e)):$(Xt,null,e)}function Dt(e){return e==null||typeof e=="boolean"?$(Xt):ye(e)?$(Ee,null,e.slice()):da(e)?qt(e):$(Xa,null,String(e))}function qt(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:Ln(e)}function pr(e,t){let n=0;const{shapeFlag:a}=e;if(t==null)t=null;else if(ye(t))n=16;else if(typeof t=="object")if(a&65){const s=t.default;s&&(s._c&&(s._d=!1),pr(e,s()),s._c&&(s._d=!0));return}else{n=32;const s=t._;!s&&!Go(t)?t._ctx=dt:s===3&&dt&&(dt.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else we(t)?(t={default:t,_ctx:dt},n=32):(t=String(t),a&64?(n=16,t=[N(t)]):n=8);e.children=t,e.shapeFlag|=n}function tl(...e){const t={};for(let n=0;nrt||dt;let La,Us;{const e=Ha(),t=(n,a)=>{let s;return(s=e[n])||(s=e[n]=[]),s.push(a),r=>{s.length>1?s.forEach(o=>o(r)):s[0](r)}};La=t("__VUE_INSTANCE_SETTERS__",n=>rt=n),Us=t("__VUE_SSR_SETTERS__",n=>fa=n)}const ma=e=>{const t=rt;return La(e),e.scope.on(),()=>{e.scope.off(),La(t)}},Yr=()=>{rt&&rt.scope.off(),La(null)};function nl(e){return e.vnode.shapeFlag&4}let fa=!1;function Fc(e,t=!1,n=!1){t&&Us(t);const{props:a,children:s}=e.vnode,r=nl(e);yc(e,a,r,t),Sc(e,s,n||t);const o=r?Nc(e,t):void 0;return t&&Us(!1),o}function Nc(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=new Proxy(e.ctx,ac);const{setup:a}=n;if(a){Wt();const s=e.setupContext=a.length>1?Uc(e):null,r=ma(e),o=ga(a,e,0,[e.props,s]),i=Ji(o);if(Jt(),r(),(i||e.sp)&&!Pn(e)&&Po(e),i){if(o.then(Yr,Yr),t)return o.then(l=>{Xr(e,l)}).catch(l=>{za(l,e,0)});e.asyncDep=o}else Xr(e,o)}else al(e)}function Xr(e,t,n){we(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:Te(t)&&(e.setupState=So(t)),al(e)}function al(e,t,n){const a=e.type;e.render||(e.render=a.render||Ft);{const s=ma(e);Wt();try{sc(e)}finally{Jt(),s()}}}const Mc={get(e,t){return st(e,"get",""),e[t]}};function Uc(e){const t=n=>{e.exposed=n||{}};return{attrs:new Proxy(e.attrs,Mc),slots:e.slots,emit:e.emit,expose:t}}function vr(e){return e.exposed?e.exposeProxy||(e.exposeProxy=new Proxy(So(or(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in aa)return aa[n](e)},has(t,n){return n in t||n in aa}})):e.proxy}function Vc(e,t=!0){return we(e)?e.displayName||e.name:e.name||t&&e.__name}function jc(e){return we(e)&&"__vccOpts"in e}const Q=(e,t)=>$u(e,t,fa);function j(e,t,n){try{Ia(-1);const a=arguments.length;return a===2?Te(t)&&!ye(t)?da(t)?$(e,null,[t]):$(e,t):$(e,null,t):(a>3?n=Array.prototype.slice.call(arguments,2):a===3&&da(n)&&(n=[n]),$(e,t,n))}finally{Ia(1)}}const Bc="3.5.33";/** +* @vue/runtime-dom v3.5.33 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/let Vs;const Zr=typeof window<"u"&&window.trustedTypes;if(Zr)try{Vs=Zr.createPolicy("vue",{createHTML:e=>e})}catch{}const sl=Vs?e=>Vs.createHTML(e):e=>e,Hc="http://www.w3.org/2000/svg",Gc="http://www.w3.org/1998/Math/MathML",Gt=typeof document<"u"?document:null,Qr=Gt&&Gt.createElement("template"),qc={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,a)=>{const s=t==="svg"?Gt.createElementNS(Hc,e):t==="mathml"?Gt.createElementNS(Gc,e):n?Gt.createElement(e,{is:n}):Gt.createElement(e);return e==="select"&&a&&a.multiple!=null&&s.setAttribute("multiple",a.multiple),s},createText:e=>Gt.createTextNode(e),createComment:e=>Gt.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>Gt.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,a,s,r){const o=n?n.previousSibling:t.lastChild;if(s&&(s===r||s.nextSibling))for(;t.insertBefore(s.cloneNode(!0),n),!(s===r||!(s=s.nextSibling)););else{Qr.innerHTML=sl(a==="svg"?`${e}`:a==="mathml"?`${e}`:e);const i=Qr.content;if(a==="svg"||a==="mathml"){const l=i.firstChild;for(;l.firstChild;)i.appendChild(l.firstChild);i.removeChild(l)}t.insertBefore(i,n)}return[o?o.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},zc=Symbol("_vtc");function Kc(e,t,n){const a=e[zc];a&&(t=(t?[t,...a]:[...a]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const ei=Symbol("_vod"),Wc=Symbol("_vsh"),Jc=Symbol(""),Yc=/(?:^|;)\s*display\s*:/;function Xc(e,t,n){const a=e.style,s=He(n);let r=!1;if(n&&!s){if(t)if(He(t))for(const o of t.split(";")){const i=o.slice(0,o.indexOf(":")).trim();n[i]==null&&Xn(a,i,"")}else for(const o in t)n[o]==null&&Xn(a,o,"");for(const o in n){o==="display"&&(r=!0);const i=n[o];i!=null?Qc(e,o,!He(t)&&t?t[o]:void 0,i)||Xn(a,o,i):Xn(a,o,"")}}else if(s){if(t!==n){const o=a[Jc];o&&(n+=";"+o),a.cssText=n,r=Yc.test(n)}}else t&&e.removeAttribute("style");ei in e&&(e[ei]=r?a.display:"",e[Wc]&&(a.display="none"))}const ti=/\s*!important$/;function Xn(e,t,n){if(ye(n))n.forEach(a=>Xn(e,t,a));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const a=Zc(e,t);ti.test(n)?e.setProperty(un(a),n.replace(ti,""),"important"):e[a]=n}}const ni=["Webkit","Moz","ms"],hs={};function Zc(e,t){const n=hs[t];if(n)return n;let a=ft(t);if(a!=="filter"&&a in e)return hs[t]=a;a=Ba(a);for(let s=0;sms||(sd.then(()=>ms=0),ms=Date.now());function id(e,t){const n=a=>{if(!a._vts)a._vts=Date.now();else if(a._vts<=n.attached)return;Ut(od(a,n.value),t,5,[a])};return n.value=e,n.attached=rd(),n}function od(e,t){if(ye(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(a=>s=>!s._stopped&&a&&a(s))}else return t}const li=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,ld=(e,t,n,a,s,r)=>{const o=s==="svg";t==="class"?Kc(e,a,o):t==="style"?Xc(e,n,a):Ma(t)?Ua(t)||nd(e,t,n,a,r):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):ud(e,t,a,o))?(ri(e,t,a),!e.tagName.includes("-")&&(t==="value"||t==="checked"||t==="selected")&&si(e,t,a,o,r,t!=="value")):e._isVueCE&&(cd(e,t)||e._def.__asyncLoader&&(/[A-Z]/.test(t)||!He(a)))?ri(e,ft(t),a,r,t):(t==="true-value"?e._trueValue=a:t==="false-value"&&(e._falseValue=a),si(e,t,a,o))};function ud(e,t,n,a){if(a)return!!(t==="innerHTML"||t==="textContent"||t in e&&li(t)&&we(n));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="autocorrect"||t==="sandbox"&&e.tagName==="IFRAME"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const s=e.tagName;if(s==="IMG"||s==="VIDEO"||s==="CANVAS"||s==="SOURCE")return!1}return li(t)&&He(n)?!1:t in e}function cd(e,t){const n=e._def.props;if(!n)return!1;const a=ft(t);return Array.isArray(n)?n.some(s=>ft(s)===a):Object.keys(n).some(s=>ft(s)===a)}const dd=["ctrl","shift","alt","meta"],fd={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&e.button!==0,middle:e=>"button"in e&&e.button!==1,right:e=>"button"in e&&e.button!==2,exact:(e,t)=>dd.some(n=>e[`${n}Key`]&&!t.includes(n))},Qa=(e,t)=>{if(!e)return e;const n=e._withMods||(e._withMods={}),a=t.join(".");return n[a]||(n[a]=((s,...r)=>{for(let o=0;o{const n=e._withKeys||(e._withKeys={}),a=t.join(".");return n[a]||(n[a]=(s=>{if(!("key"in s))return;const r=un(s.key);if(t.some(o=>o===r||pd[o]===r))return e(s)}))},gd=tt({patchProp:ld},qc);let ui;function hd(){return ui||(ui=Ac(gd))}const md=((...e)=>{const t=hd().createApp(...e),{mount:n}=t;return t.mount=a=>{const s=_d(a);if(!s)return;const r=t._component;!we(r)&&!r.render&&!r.template&&(r.template=s.innerHTML),s.nodeType===1&&(s.textContent="");const o=n(s,!1,yd(s));return s instanceof Element&&(s.removeAttribute("v-cloak"),s.setAttribute("data-v-app","")),o},t});function yd(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function _d(e){return He(e)?document.querySelector(e):e}/*! + * pinia v2.3.1 + * (c) 2025 Eduardo San Martin Morote + * @license MIT + */let rl;const es=e=>rl=e,il=Symbol();function js(e){return e&&typeof e=="object"&&Object.prototype.toString.call(e)==="[object Object]"&&typeof e.toJSON!="function"}var ra;(function(e){e.direct="direct",e.patchObject="patch object",e.patchFunction="patch function"})(ra||(ra={}));function bd(){const e=ao(!0),t=e.run(()=>J({}));let n=[],a=[];const s=or({install(r){es(s),s._a=r,r.provide(il,s),r.config.globalProperties.$pinia=s,a.forEach(o=>n.push(o)),a=[]},use(r){return this._a?n.push(r):a.push(r),this},_p:n,_a:null,_e:e,_s:new Map,state:t});return s}const ol=()=>{};function ci(e,t,n,a=ol){e.push(t);const s=()=>{const r=e.indexOf(t);r>-1&&(e.splice(r,1),a())};return!n&&so()&&nu(s),s}function An(e,...t){e.slice().forEach(n=>{n(...t)})}const wd=e=>e(),di=Symbol(),ys=Symbol();function Bs(e,t){e instanceof Map&&t instanceof Map?t.forEach((n,a)=>e.set(a,n)):e instanceof Set&&t instanceof Set&&t.forEach(e.add,e);for(const n in t){if(!t.hasOwnProperty(n))continue;const a=t[n],s=e[n];js(s)&&js(a)&&e.hasOwnProperty(n)&&!Ve(a)&&!Kt(a)?e[n]=Bs(s,a):e[n]=a}return e}const Sd=Symbol();function kd(e){return!js(e)||!e.hasOwnProperty(Sd)}const{assign:an}=Object;function Ad(e){return!!(Ve(e)&&e.effect)}function xd(e,t,n,a){const{state:s,actions:r,getters:o}=t,i=n.state.value[e];let l;function u(){i||(n.state.value[e]=s?s():{});const c=xu(n.state.value[e]);return an(c,r,Object.keys(o||{}).reduce((d,f)=>(d[f]=or(Q(()=>{es(n);const _=n._s.get(e);return o[f].call(_,_)})),d),{}))}return l=ll(e,u,t,n,a,!0),l}function ll(e,t,n={},a,s,r){let o;const i=an({actions:{}},n),l={deep:!0};let u,c,d=[],f=[],_;const h=a.state.value[e];!r&&!h&&(a.state.value[e]={});let m;function g(L){let k;u=c=!1,typeof L=="function"?(L(a.state.value[e]),k={type:ra.patchFunction,storeId:e,events:_}):(Bs(a.state.value[e],L),k={type:ra.patchObject,payload:L,storeId:e,events:_});const ee=m=Symbol();_n().then(()=>{m===ee&&(u=!0)}),c=!0,An(d,k,a.state.value[e])}const E=r?function(){const{state:k}=n,ee=k?k():{};this.$patch(le=>{an(le,ee)})}:ol;function y(){o.stop(),d=[],f=[],a._s.delete(e)}const w=(L,k="")=>{if(di in L)return L[ys]=k,L;const ee=function(){es(a);const le=Array.from(arguments),fe=[],ge=[];function B(Y){fe.push(Y)}function W(Y){ge.push(Y)}An(f,{args:le,name:ee[ys],store:I,after:B,onError:W});let Z;try{Z=L.apply(this&&this.$id===e?this:I,le)}catch(Y){throw An(ge,Y),Y}return Z instanceof Promise?Z.then(Y=>(An(fe,Y),Y)).catch(Y=>(An(ge,Y),Promise.reject(Y))):(An(fe,Z),Z)};return ee[di]=!0,ee[ys]=k,ee},C={_p:a,$id:e,$onAction:ci.bind(null,f),$patch:g,$reset:E,$subscribe(L,k={}){const ee=ci(d,L,k.detached,()=>le()),le=o.run(()=>wt(()=>a.state.value[e],fe=>{(k.flush==="sync"?c:u)&&L({storeId:e,type:ra.direct,events:_},fe)},an({},l,k)));return ee},$dispose:y},I=Zt(C);a._s.set(e,I);const R=(a._a&&a._a.runWithContext||wd)(()=>a._e.run(()=>(o=ao()).run(()=>t({action:w}))));for(const L in R){const k=R[L];if(Ve(k)&&!Ad(k)||Kt(k))r||(h&&kd(k)&&(Ve(k)?k.value=h[L]:Bs(k,h[L])),a.state.value[e][L]=k);else if(typeof k=="function"){const ee=w(k,L);R[L]=ee,i.actions[L]=k}}return an(I,R),an(Ae(I),R),Object.defineProperty(I,"$state",{get:()=>a.state.value[e],set:L=>{g(k=>{an(k,L)})}}),a._p.forEach(L=>{an(I,o.run(()=>L({store:I,app:a._a,pinia:a,options:i})))}),h&&r&&n.hydrate&&n.hydrate(I.$state,h),u=!0,c=!0,I}/*! #__NO_SIDE_EFFECTS__ */function bn(e,t,n){let a,s;const r=typeof t=="function";typeof e=="string"?(a=e,s=r?n:t):(s=e,a=e.id);function o(i,l){const u=Ou();return i=i||(u?mt(il,null):null),i&&es(i),i=rl,i._s.has(a)||(r?ll(a,t,s,i):xd(a,s,i)),i._s.get(a)}return o.$id=a,o}const Cd="modulepreload",Ed=function(e){return"/"+e},fi={},gr=function(t,n,a){let s=Promise.resolve();if(n&&n.length>0){let o=function(u){return Promise.all(u.map(c=>Promise.resolve(c).then(d=>({status:"fulfilled",value:d}),d=>({status:"rejected",reason:d}))))};document.getElementsByTagName("link");const i=document.querySelector("meta[property=csp-nonce]"),l=(i==null?void 0:i.nonce)||(i==null?void 0:i.getAttribute("nonce"));s=o(n.map(u=>{if(u=Ed(u),u in fi)return;fi[u]=!0;const c=u.endsWith(".css"),d=c?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${u}"]${d}`))return;const f=document.createElement("link");if(f.rel=c?"stylesheet":Cd,c||(f.as="script"),f.crossOrigin="",f.href=u,l&&f.setAttribute("nonce",l),document.head.appendChild(f),c)return new Promise((_,h)=>{f.addEventListener("load",_),f.addEventListener("error",()=>h(new Error(`Unable to preload CSS for ${u}`)))})}))}function r(o){const i=new Event("vite:preloadError",{cancelable:!0});if(i.payload=o,window.dispatchEvent(i),!i.defaultPrevented)throw o}return s.then(o=>{for(const i of o||[])i.status==="rejected"&&r(i.reason);return t().catch(r)})};/*! Capacitor: https://capacitorjs.com/ - MIT License */var Dn;(function(e){e.Unimplemented="UNIMPLEMENTED",e.Unavailable="UNAVAILABLE"})(Dn||(Dn={}));class _s extends Error{constructor(t,n,a){super(t),this.message=t,this.code=n,this.data=a}}const Rd=e=>{var t,n;return e!=null&&e.androidBridge?"android":!((n=(t=e==null?void 0:e.webkit)===null||t===void 0?void 0:t.messageHandlers)===null||n===void 0)&&n.bridge?"ios":"web"},$d=e=>{const t=e.CapacitorCustomPlatform||null,n=e.Capacitor||{},a=n.Plugins=n.Plugins||{},s=()=>t!==null?t.name:Rd(e),r=()=>s()!=="web",o=d=>{const f=u.get(d);return!!(f!=null&&f.platforms.has(s())||i(d))},i=d=>{var f;return(f=n.PluginHeaders)===null||f===void 0?void 0:f.find(_=>_.name===d)},l=d=>e.console.error(d),u=new Map,c=(d,f={})=>{const _=u.get(d);if(_)return console.warn(`Capacitor plugin "${d}" already registered. Cannot register plugins twice.`),_.proxy;const h=s(),m=i(d);let g;const E=async()=>(!g&&h in f?g=typeof f[h]=="function"?g=await f[h]():g=f[h]:t!==null&&!g&&"web"in f&&(g=typeof f.web=="function"?g=await f.web():g=f.web),g),y=(L,k)=>{var ee,le;if(m){const fe=m==null?void 0:m.methods.find(ge=>k===ge.name);if(fe)return fe.rtype==="promise"?ge=>n.nativePromise(d,k.toString(),ge):(ge,B)=>n.nativeCallback(d,k.toString(),ge,B);if(L)return(ee=L[k])===null||ee===void 0?void 0:ee.bind(L)}else{if(L)return(le=L[k])===null||le===void 0?void 0:le.bind(L);throw new _s(`"${d}" plugin is not implemented on ${h}`,Dn.Unimplemented)}},w=L=>{let k;const ee=(...le)=>{const fe=E().then(ge=>{const B=y(ge,L);if(B){const W=B(...le);return k=W==null?void 0:W.remove,W}else throw new _s(`"${d}.${L}()" is not implemented on ${h}`,Dn.Unimplemented)});return L==="addListener"&&(fe.remove=async()=>k()),fe};return ee.toString=()=>`${L.toString()}() { [capacitor code] }`,Object.defineProperty(ee,"name",{value:L,writable:!1,configurable:!1}),ee},C=w("addListener"),I=w("removeListener"),P=(L,k)=>{const ee=C({eventName:L},k),le=async()=>{const ge=await ee;I({eventName:L,callbackId:ge},k)},fe=new Promise(ge=>ee.then(()=>ge({remove:le})));return fe.remove=async()=>{console.warn("Using addListener() without 'await' is deprecated."),await le()},fe},R=new Proxy({},{get(L,k){switch(k){case"$$typeof":return;case"toJSON":return()=>({});case"addListener":return m?P:C;case"removeListener":return I;default:return w(k)}}});return a[d]=R,u.set(d,{name:d,proxy:R,platforms:new Set([...Object.keys(f),...m?[h]:[]])}),R};return n.convertFileSrc||(n.convertFileSrc=d=>d),n.getPlatform=s,n.handleError=l,n.isNativePlatform=r,n.isPluginAvailable=o,n.registerPlugin=c,n.Exception=_s,n.DEBUG=!!n.DEBUG,n.isLoggingEnabled=!!n.isLoggingEnabled,n},Td=e=>e.Capacitor=$d(e),Da=Td(typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{}),ya=Da.registerPlugin;class hr{constructor(){this.listeners={},this.retainedEventArguments={},this.windowListeners={}}addListener(t,n){let a=!1;this.listeners[t]||(this.listeners[t]=[],a=!0),this.listeners[t].push(n);const r=this.windowListeners[t];r&&!r.registered&&this.addWindowListener(r),a&&this.sendRetainedArgumentsForEvent(t);const o=async()=>this.removeListener(t,n);return Promise.resolve({remove:o})}async removeAllListeners(){this.listeners={};for(const t in this.windowListeners)this.removeWindowListener(this.windowListeners[t]);this.windowListeners={}}notifyListeners(t,n,a){const s=this.listeners[t];if(!s){if(a){let r=this.retainedEventArguments[t];r||(r=[]),r.push(n),this.retainedEventArguments[t]=r}return}s.forEach(r=>r(n))}hasListeners(t){var n;return!!(!((n=this.listeners[t])===null||n===void 0)&&n.length)}registerWindowListener(t,n){this.windowListeners[n]={registered:!1,windowEventName:t,pluginEventName:n,handler:a=>{this.notifyListeners(n,a)}}}unimplemented(t="not implemented"){return new Da.Exception(t,Dn.Unimplemented)}unavailable(t="not available"){return new Da.Exception(t,Dn.Unavailable)}async removeListener(t,n){const a=this.listeners[t];if(!a)return;const s=a.indexOf(n);this.listeners[t].splice(s,1),this.listeners[t].length||this.removeWindowListener(this.windowListeners[t])}addWindowListener(t){window.addEventListener(t.windowEventName,t.handler),t.registered=!0}removeWindowListener(t){t&&(window.removeEventListener(t.windowEventName,t.handler),t.registered=!1)}sendRetainedArgumentsForEvent(t){const n=this.retainedEventArguments[t];n&&(delete this.retainedEventArguments[t],n.forEach(a=>{this.notifyListeners(t,a)}))}}const pi=e=>encodeURIComponent(e).replace(/%(2[346B]|5E|60|7C)/g,decodeURIComponent).replace(/[()]/g,escape),vi=e=>e.replace(/(%[\dA-F]{2})+/gi,decodeURIComponent);class Pd extends hr{async getCookies(){const t=document.cookie,n={};return t.split(";").forEach(a=>{if(a.length<=0)return;let[s,r]=a.replace(/=/,"CAP_COOKIE").split("CAP_COOKIE");s=vi(s).trim(),r=vi(r).trim(),n[s]=r}),n}async setCookie(t){try{const n=pi(t.key),a=pi(t.value),s=t.expires?`; expires=${t.expires.replace("expires=","")}`:"",r=(t.path||"/").replace("path=",""),o=t.url!=null&&t.url.length>0?`domain=${t.url}`:"";document.cookie=`${n}=${a||""}${s}; path=${r}; ${o};`}catch(n){return Promise.reject(n)}}async deleteCookie(t){try{document.cookie=`${t.key}=; Max-Age=0`}catch(n){return Promise.reject(n)}}async clearCookies(){try{const t=document.cookie.split(";")||[];for(const n of t)document.cookie=n.replace(/^ +/,"").replace(/=.*/,`=;expires=${new Date().toUTCString()};path=/`)}catch(t){return Promise.reject(t)}}async clearAllCookies(){try{await this.clearCookies()}catch(t){return Promise.reject(t)}}}ya("CapacitorCookies",{web:()=>new Pd});const Id=async e=>new Promise((t,n)=>{const a=new FileReader;a.onload=()=>{const s=a.result;t(s.indexOf(",")>=0?s.split(",")[1]:s)},a.onerror=s=>n(s),a.readAsDataURL(e)}),Ld=(e={})=>{const t=Object.keys(e);return Object.keys(e).map(s=>s.toLocaleLowerCase()).reduce((s,r,o)=>(s[r]=e[t[o]],s),{})},Dd=(e,t=!0)=>e?Object.entries(e).reduce((a,s)=>{const[r,o]=s;let i,l;return Array.isArray(o)?(l="",o.forEach(u=>{i=t?encodeURIComponent(u):u,l+=`${r}=${i}&`}),l.slice(0,-1)):(i=t?encodeURIComponent(o):o,l=`${r}=${i}`),`${a}&${l}`},"").substr(1):null,Od=(e,t={})=>{const n=Object.assign({method:e.method||"GET",headers:e.headers},t),s=Ld(e.headers)["content-type"]||"";if(typeof e.data=="string")n.body=e.data;else if(s.includes("application/x-www-form-urlencoded")){const r=new URLSearchParams;for(const[o,i]of Object.entries(e.data||{}))r.set(o,i);n.body=r.toString()}else if(s.includes("multipart/form-data")||e.data instanceof FormData){const r=new FormData;if(e.data instanceof FormData)e.data.forEach((i,l)=>{r.append(l,i)});else for(const i of Object.keys(e.data))r.append(i,e.data[i]);n.body=r;const o=new Headers(n.headers);o.delete("content-type"),n.headers=o}else(s.includes("application/json")||typeof e.data=="object")&&(n.body=JSON.stringify(e.data));return n};class Fd extends hr{async request(t){const n=Od(t,t.webFetchExtra),a=Dd(t.params,t.shouldEncodeUrlParams),s=a?`${t.url}?${a}`:t.url,r=await fetch(s,n),o=r.headers.get("content-type")||"";let{responseType:i="text"}=r.ok?t:{};o.includes("application/json")&&(i="json");let l,u;switch(i){case"arraybuffer":case"blob":u=await r.blob(),l=await Id(u);break;case"json":l=await r.json();break;case"document":case"text":default:l=await r.text()}const c={};return r.headers.forEach((d,f)=>{c[f]=d}),{data:l,headers:c,status:r.status,url:r.url}}async get(t){return this.request(Object.assign(Object.assign({},t),{method:"GET"}))}async post(t){return this.request(Object.assign(Object.assign({},t),{method:"POST"}))}async put(t){return this.request(Object.assign(Object.assign({},t),{method:"PUT"}))}async patch(t){return this.request(Object.assign(Object.assign({},t),{method:"PATCH"}))}async delete(t){return this.request(Object.assign(Object.assign({},t),{method:"DELETE"}))}}ya("CapacitorHttp",{web:()=>new Fd});var gi;(function(e){e.Dark="DARK",e.Light="LIGHT",e.Default="DEFAULT"})(gi||(gi={}));var hi;(function(e){e.StatusBar="StatusBar",e.NavigationBar="NavigationBar"})(hi||(hi={}));class Nd extends hr{async setStyle(){this.unavailable("not available for web")}async setAnimation(){this.unavailable("not available for web")}async show(){this.unavailable("not available for web")}async hide(){this.unavailable("not available for web")}}ya("SystemBars",{web:()=>new Nd});const Hs=ya("App",{web:()=>gr(()=>import("./web-Gt69b7cr.js"),[]).then(e=>new e.AppWeb)});/*! + * vue-router v4.6.4 + * (c) 2025 Eduardo San Martin Morote + * @license MIT + */const Cn=typeof document<"u";function ul(e){return typeof e=="object"||"displayName"in e||"props"in e||"__vccOpts"in e}function Md(e){return e.__esModule||e[Symbol.toStringTag]==="Module"||e.default&&ul(e.default)}const xe=Object.assign;function bs(e,t){const n={};for(const a in t){const s=t[a];n[a]=Et(s)?s.map(e):e(s)}return n}const ia=()=>{},Et=Array.isArray;function mi(e,t){const n={};for(const a in e)n[a]=a in t?t[a]:e[a];return n}const cl=/#/g,Ud=/&/g,Vd=/\//g,jd=/=/g,Bd=/\?/g,dl=/\+/g,Hd=/%5B/g,Gd=/%5D/g,fl=/%5E/g,qd=/%60/g,pl=/%7B/g,zd=/%7C/g,vl=/%7D/g,Kd=/%20/g;function mr(e){return e==null?"":encodeURI(""+e).replace(zd,"|").replace(Hd,"[").replace(Gd,"]")}function Wd(e){return mr(e).replace(pl,"{").replace(vl,"}").replace(fl,"^")}function Gs(e){return mr(e).replace(dl,"%2B").replace(Kd,"+").replace(cl,"%23").replace(Ud,"%26").replace(qd,"`").replace(pl,"{").replace(vl,"}").replace(fl,"^")}function Jd(e){return Gs(e).replace(jd,"%3D")}function Yd(e){return mr(e).replace(cl,"%23").replace(Bd,"%3F")}function Xd(e){return Yd(e).replace(Vd,"%2F")}function pa(e){if(e==null)return null;try{return decodeURIComponent(""+e)}catch{}return""+e}const Zd=/\/$/,Qd=e=>e.replace(Zd,"");function ws(e,t,n="/"){let a,s={},r="",o="";const i=t.indexOf("#");let l=t.indexOf("?");return l=i>=0&&l>i?-1:l,l>=0&&(a=t.slice(0,l),r=t.slice(l,i>0?i:t.length),s=e(r.slice(1))),i>=0&&(a=a||t.slice(0,i),o=t.slice(i,t.length)),a=af(a??t,n),{fullPath:a+r+o,path:a,query:s,hash:pa(o)}}function ef(e,t){const n=t.query?e(t.query):"";return t.path+(n&&"?")+n+(t.hash||"")}function yi(e,t){return!t||!e.toLowerCase().startsWith(t.toLowerCase())?e:e.slice(t.length)||"/"}function tf(e,t,n){const a=t.matched.length-1,s=n.matched.length-1;return a>-1&&a===s&&On(t.matched[a],n.matched[s])&&gl(t.params,n.params)&&e(t.query)===e(n.query)&&t.hash===n.hash}function On(e,t){return(e.aliasOf||e)===(t.aliasOf||t)}function gl(e,t){if(Object.keys(e).length!==Object.keys(t).length)return!1;for(var n in e)if(!nf(e[n],t[n]))return!1;return!0}function nf(e,t){return Et(e)?_i(e,t):Et(t)?_i(t,e):(e==null?void 0:e.valueOf())===(t==null?void 0:t.valueOf())}function _i(e,t){return Et(t)?e.length===t.length&&e.every((n,a)=>n===t[a]):e.length===1&&e[0]===t}function af(e,t){if(e.startsWith("/"))return e;if(!e)return t;const n=t.split("/"),a=e.split("/"),s=a[a.length-1];(s===".."||s===".")&&a.push("");let r=n.length-1,o,i;for(o=0;o1&&r--;else break;return n.slice(0,r).join("/")+"/"+a.slice(o).join("/")}const tn={path:"/",name:void 0,params:{},query:{},hash:"",fullPath:"/",matched:[],meta:{},redirectedFrom:void 0};let qs=(function(e){return e.pop="pop",e.push="push",e})({}),Ss=(function(e){return e.back="back",e.forward="forward",e.unknown="",e})({});function sf(e){if(!e)if(Cn){const t=document.querySelector("base");e=t&&t.getAttribute("href")||"/",e=e.replace(/^\w+:\/\/[^\/]+/,"")}else e="/";return e[0]!=="/"&&e[0]!=="#"&&(e="/"+e),Qd(e)}const rf=/^[^#]+#/;function of(e,t){return e.replace(rf,"#")+t}function lf(e,t){const n=document.documentElement.getBoundingClientRect(),a=e.getBoundingClientRect();return{behavior:t.behavior,left:a.left-n.left-(t.left||0),top:a.top-n.top-(t.top||0)}}const ts=()=>({left:window.scrollX,top:window.scrollY});function uf(e){let t;if("el"in e){const n=e.el,a=typeof n=="string"&&n.startsWith("#"),s=typeof n=="string"?a?document.getElementById(n.slice(1)):document.querySelector(n):n;if(!s)return;t=lf(s,e)}else t=e;"scrollBehavior"in document.documentElement.style?window.scrollTo(t):window.scrollTo(t.left!=null?t.left:window.scrollX,t.top!=null?t.top:window.scrollY)}function bi(e,t){return(history.state?history.state.position-t:-1)+e}const zs=new Map;function cf(e,t){zs.set(e,t)}function df(e){const t=zs.get(e);return zs.delete(e),t}function ff(e){return typeof e=="string"||e&&typeof e=="object"}function hl(e){return typeof e=="string"||typeof e=="symbol"}let qe=(function(e){return e[e.MATCHER_NOT_FOUND=1]="MATCHER_NOT_FOUND",e[e.NAVIGATION_GUARD_REDIRECT=2]="NAVIGATION_GUARD_REDIRECT",e[e.NAVIGATION_ABORTED=4]="NAVIGATION_ABORTED",e[e.NAVIGATION_CANCELLED=8]="NAVIGATION_CANCELLED",e[e.NAVIGATION_DUPLICATED=16]="NAVIGATION_DUPLICATED",e})({});const ml=Symbol("");qe.MATCHER_NOT_FOUND+"",qe.NAVIGATION_GUARD_REDIRECT+"",qe.NAVIGATION_ABORTED+"",qe.NAVIGATION_CANCELLED+"",qe.NAVIGATION_DUPLICATED+"";function Fn(e,t){return xe(new Error,{type:e,[ml]:!0},t)}function Ht(e,t){return e instanceof Error&&ml in e&&(t==null||!!(e.type&t))}const pf=["params","query","hash"];function vf(e){if(typeof e=="string")return e;if(e.path!=null)return e.path;const t={};for(const n of pf)n in e&&(t[n]=e[n]);return JSON.stringify(t,null,2)}function gf(e){const t={};if(e===""||e==="?")return t;const n=(e[0]==="?"?e.slice(1):e).split("&");for(let a=0;as&&Gs(s)):[a&&Gs(a)]).forEach(s=>{s!==void 0&&(t+=(t.length?"&":"")+n,s!=null&&(t+="="+s))})}return t}function hf(e){const t={};for(const n in e){const a=e[n];a!==void 0&&(t[n]=Et(a)?a.map(s=>s==null?null:""+s):a==null?a:""+a)}return t}const mf=Symbol(""),Si=Symbol(""),ns=Symbol(""),yr=Symbol(""),Ks=Symbol("");function Hn(){let e=[];function t(a){return e.push(a),()=>{const s=e.indexOf(a);s>-1&&e.splice(s,1)}}function n(){e=[]}return{add:t,list:()=>e.slice(),reset:n}}function rn(e,t,n,a,s,r=o=>o()){const o=a&&(a.enterCallbacks[s]=a.enterCallbacks[s]||[]);return()=>new Promise((i,l)=>{const u=f=>{f===!1?l(Fn(qe.NAVIGATION_ABORTED,{from:n,to:t})):f instanceof Error?l(f):ff(f)?l(Fn(qe.NAVIGATION_GUARD_REDIRECT,{from:t,to:f})):(o&&a.enterCallbacks[s]===o&&typeof f=="function"&&o.push(f),i())},c=r(()=>e.call(a&&a.instances[s],t,n,u));let d=Promise.resolve(c);e.length<3&&(d=d.then(u)),d.catch(f=>l(f))})}function ks(e,t,n,a,s=r=>r()){const r=[];for(const o of e)for(const i in o.components){let l=o.components[i];if(!(t!=="beforeRouteEnter"&&!o.instances[i]))if(ul(l)){const u=(l.__vccOpts||l)[t];u&&r.push(rn(u,n,a,o,i,s))}else{let u=l();r.push(()=>u.then(c=>{if(!c)throw new Error(`Couldn't resolve component "${i}" at "${o.path}"`);const d=Md(c)?c.default:c;o.mods[i]=c,o.components[i]=d;const f=(d.__vccOpts||d)[t];return f&&rn(f,n,a,o,i,s)()}))}}return r}function yf(e,t){const n=[],a=[],s=[],r=Math.max(t.matched.length,e.matched.length);for(let o=0;oOn(u,i))?a.push(i):n.push(i));const l=e.matched[o];l&&(t.matched.find(u=>On(u,l))||s.push(l))}return[n,a,s]}/*! + * vue-router v4.6.4 + * (c) 2025 Eduardo San Martin Morote + * @license MIT + */let _f=()=>location.protocol+"//"+location.host;function yl(e,t){const{pathname:n,search:a,hash:s}=t,r=e.indexOf("#");if(r>-1){let o=s.includes(e.slice(r))?e.slice(r).length:1,i=s.slice(o);return i[0]!=="/"&&(i="/"+i),yi(i,"")}return yi(n,e)+a+s}function bf(e,t,n,a){let s=[],r=[],o=null;const i=({state:f})=>{const _=yl(e,location),h=n.value,m=t.value;let g=0;if(f){if(n.value=_,t.value=f,o&&o===h){o=null;return}g=m?f.position-m.position:0}else a(_);s.forEach(E=>{E(n.value,h,{delta:g,type:qs.pop,direction:g?g>0?Ss.forward:Ss.back:Ss.unknown})})};function l(){o=n.value}function u(f){s.push(f);const _=()=>{const h=s.indexOf(f);h>-1&&s.splice(h,1)};return r.push(_),_}function c(){if(document.visibilityState==="hidden"){const{history:f}=window;if(!f.state)return;f.replaceState(xe({},f.state,{scroll:ts()}),"")}}function d(){for(const f of r)f();r=[],window.removeEventListener("popstate",i),window.removeEventListener("pagehide",c),document.removeEventListener("visibilitychange",c)}return window.addEventListener("popstate",i),window.addEventListener("pagehide",c),document.addEventListener("visibilitychange",c),{pauseListeners:l,listen:u,destroy:d}}function ki(e,t,n,a=!1,s=!1){return{back:e,current:t,forward:n,replaced:a,position:window.history.length,scroll:s?ts():null}}function wf(e){const{history:t,location:n}=window,a={value:yl(e,n)},s={value:t.state};s.value||r(a.value,{back:null,current:a.value,forward:null,position:t.length-1,replaced:!0,scroll:null},!0);function r(l,u,c){const d=e.indexOf("#"),f=d>-1?(n.host&&document.querySelector("base")?e:e.slice(d))+l:_f()+e+l;try{t[c?"replaceState":"pushState"](u,"",f),s.value=u}catch(_){console.error(_),n[c?"replace":"assign"](f)}}function o(l,u){r(l,xe({},t.state,ki(s.value.back,l,s.value.forward,!0),u,{position:s.value.position}),!0),a.value=l}function i(l,u){const c=xe({},s.value,t.state,{forward:l,scroll:ts()});r(c.current,c,!0),r(l,xe({},ki(a.value,l,null),{position:c.position+1},u),!1),a.value=l}return{location:a,state:s,push:i,replace:o}}function Sf(e){e=sf(e);const t=wf(e),n=bf(e,t.state,t.location,t.replace);function a(r,o=!0){o||n.pauseListeners(),history.go(r)}const s=xe({location:"",base:e,go:a,createHref:of.bind(null,e)},t,n);return Object.defineProperty(s,"location",{enumerable:!0,get:()=>t.location.value}),Object.defineProperty(s,"state",{enumerable:!0,get:()=>t.state.value}),s}function kf(e){return e=location.host?e||location.pathname+location.search:"",e.includes("#")||(e+="#"),Sf(e)}let gn=(function(e){return e[e.Static=0]="Static",e[e.Param=1]="Param",e[e.Group=2]="Group",e})({});var Ye=(function(e){return e[e.Static=0]="Static",e[e.Param=1]="Param",e[e.ParamRegExp=2]="ParamRegExp",e[e.ParamRegExpEnd=3]="ParamRegExpEnd",e[e.EscapeNext=4]="EscapeNext",e})(Ye||{});const Af={type:gn.Static,value:""},xf=/[a-zA-Z0-9_]/;function Cf(e){if(!e)return[[]];if(e==="/")return[[Af]];if(!e.startsWith("/"))throw new Error(`Invalid path "${e}"`);function t(_){throw new Error(`ERR (${n})/"${u}": ${_}`)}let n=Ye.Static,a=n;const s=[];let r;function o(){r&&s.push(r),r=[]}let i=0,l,u="",c="";function d(){u&&(n===Ye.Static?r.push({type:gn.Static,value:u}):n===Ye.Param||n===Ye.ParamRegExp||n===Ye.ParamRegExpEnd?(r.length>1&&(l==="*"||l==="+")&&t(`A repeatable param (${u}) must be alone in its segment. eg: '/:ids+.`),r.push({type:gn.Param,value:u,regexp:c,repeatable:l==="*"||l==="+",optional:l==="*"||l==="?"})):t("Invalid state to consume buffer"),u="")}function f(){u+=l}for(;it.length?t.length===1&&t[0]===ut.Static+ut.Segment?1:-1:0}function _l(e,t){let n=0;const a=e.score,s=t.score;for(;n0&&t[t.length-1]<0}const Pf={strict:!1,end:!0,sensitive:!1};function If(e,t,n){const a=$f(Cf(e.path),n),s=xe(a,{record:e,parent:t,children:[],alias:[]});return t&&!s.record.aliasOf==!t.record.aliasOf&&t.children.push(s),s}function Lf(e,t){const n=[],a=new Map;t=mi(Pf,t);function s(d){return a.get(d)}function r(d,f,_){const h=!_,m=Ei(d);m.aliasOf=_&&_.record;const g=mi(t,d),E=[m];if("alias"in d){const C=typeof d.alias=="string"?[d.alias]:d.alias;for(const I of C)E.push(Ei(xe({},m,{components:_?_.record.components:m.components,path:I,aliasOf:_?_.record:m})))}let y,w;for(const C of E){const{path:I}=C;if(f&&I[0]!=="/"){const P=f.record.path,R=P[P.length-1]==="/"?"":"/";C.path=f.record.path+(I&&R+I)}if(y=If(C,f,g),_?_.alias.push(y):(w=w||y,w!==y&&w.alias.push(y),h&&d.name&&!Ri(y)&&o(d.name)),bl(y)&&l(y),m.children){const P=m.children;for(let R=0;R{o(w)}:ia}function o(d){if(hl(d)){const f=a.get(d);f&&(a.delete(d),n.splice(n.indexOf(f),1),f.children.forEach(o),f.alias.forEach(o))}else{const f=n.indexOf(d);f>-1&&(n.splice(f,1),d.record.name&&a.delete(d.record.name),d.children.forEach(o),d.alias.forEach(o))}}function i(){return n}function l(d){const f=Ff(d,n);n.splice(f,0,d),d.record.name&&!Ri(d)&&a.set(d.record.name,d)}function u(d,f){let _,h={},m,g;if("name"in d&&d.name){if(_=a.get(d.name),!_)throw Fn(qe.MATCHER_NOT_FOUND,{location:d});g=_.record.name,h=xe(Ci(f.params,_.keys.filter(w=>!w.optional).concat(_.parent?_.parent.keys.filter(w=>w.optional):[]).map(w=>w.name)),d.params&&Ci(d.params,_.keys.map(w=>w.name))),m=_.stringify(h)}else if(d.path!=null)m=d.path,_=n.find(w=>w.re.test(m)),_&&(h=_.parse(m),g=_.record.name);else{if(_=f.name?a.get(f.name):n.find(w=>w.re.test(f.path)),!_)throw Fn(qe.MATCHER_NOT_FOUND,{location:d,currentLocation:f});g=_.record.name,h=xe({},f.params,d.params),m=_.stringify(h)}const E=[];let y=_;for(;y;)E.unshift(y.record),y=y.parent;return{name:g,path:m,params:h,matched:E,meta:Of(E)}}e.forEach(d=>r(d));function c(){n.length=0,a.clear()}return{addRoute:r,resolve:u,removeRoute:o,clearRoutes:c,getRoutes:i,getRecordMatcher:s}}function Ci(e,t){const n={};for(const a of t)a in e&&(n[a]=e[a]);return n}function Ei(e){const t={path:e.path,redirect:e.redirect,name:e.name,meta:e.meta||{},aliasOf:e.aliasOf,beforeEnter:e.beforeEnter,props:Df(e),children:e.children||[],instances:{},leaveGuards:new Set,updateGuards:new Set,enterCallbacks:{},components:"components"in e?e.components||null:e.component&&{default:e.component}};return Object.defineProperty(t,"mods",{value:{}}),t}function Df(e){const t={},n=e.props||!1;if("component"in e)t.default=n;else for(const a in e.components)t[a]=typeof n=="object"?n[a]:n;return t}function Ri(e){for(;e;){if(e.record.aliasOf)return!0;e=e.parent}return!1}function Of(e){return e.reduce((t,n)=>xe(t,n.meta),{})}function Ff(e,t){let n=0,a=t.length;for(;n!==a;){const r=n+a>>1;_l(e,t[r])<0?a=r:n=r+1}const s=Nf(e);return s&&(a=t.lastIndexOf(s,a-1)),a}function Nf(e){let t=e;for(;t=t.parent;)if(bl(t)&&_l(e,t)===0)return t}function bl({record:e}){return!!(e.name||e.components&&Object.keys(e.components).length||e.redirect)}function $i(e){const t=mt(ns),n=mt(yr),a=Q(()=>{const l=v(e.to);return t.resolve(l)}),s=Q(()=>{const{matched:l}=a.value,{length:u}=l,c=l[u-1],d=n.matched;if(!c||!d.length)return-1;const f=d.findIndex(On.bind(null,c));if(f>-1)return f;const _=Ti(l[u-2]);return u>1&&Ti(c)===_&&d[d.length-1].path!==_?d.findIndex(On.bind(null,l[u-2])):f}),r=Q(()=>s.value>-1&&Bf(n.params,a.value.params)),o=Q(()=>s.value>-1&&s.value===n.matched.length-1&&gl(n.params,a.value.params));function i(l={}){if(jf(l)){const u=t[v(e.replace)?"replace":"push"](v(e.to)).catch(ia);return e.viewTransition&&typeof document<"u"&&"startViewTransition"in document&&document.startViewTransition(()=>u),u}return Promise.resolve()}return{route:a,href:Q(()=>a.value.href),isActive:r,isExactActive:o,navigate:i}}function Mf(e){return e.length===1?e[0]:e}const Uf=Be({name:"RouterLink",compatConfig:{MODE:3},props:{to:{type:[String,Object],required:!0},replace:Boolean,activeClass:String,exactActiveClass:String,custom:Boolean,ariaCurrentValue:{type:String,default:"page"},viewTransition:Boolean},useLink:$i,setup(e,{slots:t}){const n=Zt($i(e)),{options:a}=mt(ns),s=Q(()=>({[Pi(e.activeClass,a.linkActiveClass,"router-link-active")]:n.isActive,[Pi(e.exactActiveClass,a.linkExactActiveClass,"router-link-exact-active")]:n.isExactActive}));return()=>{const r=t.default&&Mf(t.default(n));return e.custom?r:j("a",{"aria-current":n.isExactActive?e.ariaCurrentValue:null,href:n.href,onClick:n.navigate,class:s.value},r)}}}),Vf=Uf;function jf(e){if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)&&!e.defaultPrevented&&!(e.button!==void 0&&e.button!==0)){if(e.currentTarget&&e.currentTarget.getAttribute){const t=e.currentTarget.getAttribute("target");if(/\b_blank\b/i.test(t))return}return e.preventDefault&&e.preventDefault(),!0}}function Bf(e,t){for(const n in t){const a=t[n],s=e[n];if(typeof a=="string"){if(a!==s)return!1}else if(!Et(s)||s.length!==a.length||a.some((r,o)=>r.valueOf()!==s[o].valueOf()))return!1}return!0}function Ti(e){return e?e.aliasOf?e.aliasOf.path:e.path:""}const Pi=(e,t,n)=>e??t??n,Hf=Be({name:"RouterView",inheritAttrs:!1,props:{name:{type:String,default:"default"},route:Object},compatConfig:{MODE:3},setup(e,{attrs:t,slots:n}){const a=mt(Ks),s=Q(()=>e.route||a.value),r=mt(Si,0),o=Q(()=>{let u=v(r);const{matched:c}=s.value;let d;for(;(d=c[u])&&!d.components;)u++;return u}),i=Q(()=>s.value.matched[o.value]);ta(Si,Q(()=>o.value+1)),ta(mf,i),ta(Ks,s);const l=J();return wt(()=>[l.value,i.value,e.name],([u,c,d],[f,_,h])=>{c&&(c.instances[d]=u,_&&_!==c&&u&&u===f&&(c.leaveGuards.size||(c.leaveGuards=_.leaveGuards),c.updateGuards.size||(c.updateGuards=_.updateGuards))),u&&c&&(!_||!On(c,_)||!f)&&(c.enterCallbacks[d]||[]).forEach(m=>m(u))},{flush:"post"}),()=>{const u=s.value,c=e.name,d=i.value,f=d&&d.components[c];if(!f)return Ii(n.default,{Component:f,route:u});const _=d.props[c],h=_?_===!0?u.params:typeof _=="function"?_(u):_:null,g=j(f,xe({},h,t,{onVnodeUnmounted:E=>{E.component.isUnmounted&&(d.instances[c]=null)},ref:l}));return Ii(n.default,{Component:g,route:u})||g}}});function Ii(e,t){if(!e)return null;const n=e(t);return n.length===1?n[0]:n}const wl=Hf;function Gf(e){const t=Lf(e.routes,e),n=e.parseQuery||gf,a=e.stringifyQuery||wi,s=e.history,r=Hn(),o=Hn(),i=Hn(),l=Su(tn);let u=tn;Cn&&e.scrollBehavior&&"scrollRestoration"in history&&(history.scrollRestoration="manual");const c=bs.bind(null,M=>""+M),d=bs.bind(null,Xd),f=bs.bind(null,pa);function _(M,se){let H,F;return hl(M)?(H=t.getRecordMatcher(M),F=se):F=M,t.addRoute(F,H)}function h(M){const se=t.getRecordMatcher(M);se&&t.removeRoute(se)}function m(){return t.getRoutes().map(M=>M.record)}function g(M){return!!t.getRecordMatcher(M)}function E(M,se){if(se=xe({},se||l.value),typeof M=="string"){const A=ws(n,M,se.path),V=t.resolve({path:A.path},se),K=s.createHref(A.fullPath);return xe(A,V,{params:f(V.params),hash:pa(A.hash),redirectedFrom:void 0,href:K})}let H;if(M.path!=null)H=xe({},M,{path:ws(n,M.path,se.path).path});else{const A=xe({},M.params);for(const V in A)A[V]==null&&delete A[V];H=xe({},M,{params:d(A)}),se.params=d(se.params)}const F=t.resolve(H,se),U=M.hash||"";F.params=c(f(F.params));const p=ef(a,xe({},M,{hash:Wd(U),path:F.path})),b=s.createHref(p);return xe({fullPath:p,hash:U,query:a===wi?hf(M.query):M.query||{}},F,{redirectedFrom:void 0,href:b})}function y(M){return typeof M=="string"?ws(n,M,l.value.path):xe({},M)}function w(M,se){if(u!==M)return Fn(qe.NAVIGATION_CANCELLED,{from:se,to:M})}function C(M){return R(M)}function I(M){return C(xe(y(M),{replace:!0}))}function P(M,se){const H=M.matched[M.matched.length-1];if(H&&H.redirect){const{redirect:F}=H;let U=typeof F=="function"?F(M,se):F;return typeof U=="string"&&(U=U.includes("?")||U.includes("#")?U=y(U):{path:U},U.params={}),xe({query:M.query,hash:M.hash,params:U.path!=null?{}:M.params},U)}}function R(M,se){const H=u=E(M),F=l.value,U=M.state,p=M.force,b=M.replace===!0,A=P(H,F);if(A)return R(xe(y(A),{state:typeof A=="object"?xe({},U,A.state):U,force:p,replace:b}),se||H);const V=H;V.redirectedFrom=se;let K;return!p&&tf(a,F,H)&&(K=Fn(qe.NAVIGATION_DUPLICATED,{to:V,from:F}),Pe(F,F,!0,!1)),(K?Promise.resolve(K):ee(V,F)).catch(z=>Ht(z)?Ht(z,qe.NAVIGATION_GUARD_REDIRECT)?z:ke(z):te(z,V,F)).then(z=>{if(z){if(Ht(z,qe.NAVIGATION_GUARD_REDIRECT))return R(xe({replace:b},y(z.to),{state:typeof z.to=="object"?xe({},U,z.to.state):U,force:p}),se||V)}else z=fe(V,F,!0,b,U);return le(V,F,z),z})}function L(M,se){const H=w(M,se);return H?Promise.reject(H):Promise.resolve()}function k(M){const se=Ue.values().next().value;return se&&typeof se.runWithContext=="function"?se.runWithContext(M):M()}function ee(M,se){let H;const[F,U,p]=yf(M,se);H=ks(F.reverse(),"beforeRouteLeave",M,se);for(const A of F)A.leaveGuards.forEach(V=>{H.push(rn(V,M,se))});const b=L.bind(null,M,se);return H.push(b),Oe(H).then(()=>{H=[];for(const A of r.list())H.push(rn(A,M,se));return H.push(b),Oe(H)}).then(()=>{H=ks(U,"beforeRouteUpdate",M,se);for(const A of U)A.updateGuards.forEach(V=>{H.push(rn(V,M,se))});return H.push(b),Oe(H)}).then(()=>{H=[];for(const A of p)if(A.beforeEnter)if(Et(A.beforeEnter))for(const V of A.beforeEnter)H.push(rn(V,M,se));else H.push(rn(A.beforeEnter,M,se));return H.push(b),Oe(H)}).then(()=>(M.matched.forEach(A=>A.enterCallbacks={}),H=ks(p,"beforeRouteEnter",M,se,k),H.push(b),Oe(H))).then(()=>{H=[];for(const A of o.list())H.push(rn(A,M,se));return H.push(b),Oe(H)}).catch(A=>Ht(A,qe.NAVIGATION_CANCELLED)?A:Promise.reject(A))}function le(M,se,H){i.list().forEach(F=>k(()=>F(M,se,H)))}function fe(M,se,H,F,U){const p=w(M,se);if(p)return p;const b=se===tn,A=Cn?history.state:{};H&&(F||b?s.replace(M.fullPath,xe({scroll:b&&A&&A.scroll},U)):s.push(M.fullPath,U)),l.value=M,Pe(M,se,H,b),ke()}let ge;function B(){ge||(ge=s.listen((M,se,H)=>{if(!De.listening)return;const F=E(M),U=P(F,De.currentRoute.value);if(U){R(xe(U,{replace:!0,force:!0}),F).catch(ia);return}u=F;const p=l.value;Cn&&cf(bi(p.fullPath,H.delta),ts()),ee(F,p).catch(b=>Ht(b,qe.NAVIGATION_ABORTED|qe.NAVIGATION_CANCELLED)?b:Ht(b,qe.NAVIGATION_GUARD_REDIRECT)?(R(xe(y(b.to),{force:!0}),F).then(A=>{Ht(A,qe.NAVIGATION_ABORTED|qe.NAVIGATION_DUPLICATED)&&!H.delta&&H.type===qs.pop&&s.go(-1,!1)}).catch(ia),Promise.reject()):(H.delta&&s.go(-H.delta,!1),te(b,F,p))).then(b=>{b=b||fe(F,p,!1),b&&(H.delta&&!Ht(b,qe.NAVIGATION_CANCELLED)?s.go(-H.delta,!1):H.type===qs.pop&&Ht(b,qe.NAVIGATION_ABORTED|qe.NAVIGATION_DUPLICATED)&&s.go(-1,!1)),le(F,p,b)}).catch(ia)}))}let W=Hn(),Z=Hn(),Y;function te(M,se,H){ke(M);const F=Z.list();return F.length?F.forEach(U=>U(M,se,H)):console.error(M),Promise.reject(M)}function ve(){return Y&&l.value!==tn?Promise.resolve():new Promise((M,se)=>{W.add([M,se])})}function ke(M){return Y||(Y=!M,B(),W.list().forEach(([se,H])=>M?H(M):se()),W.reset()),M}function Pe(M,se,H,F){const{scrollBehavior:U}=e;if(!Cn||!U)return Promise.resolve();const p=!H&&df(bi(M.fullPath,0))||(F||!H)&&history.state&&history.state.scroll||null;return _n().then(()=>U(M,se,p)).then(b=>b&&uf(b)).catch(b=>te(b,M,se))}const be=M=>s.go(M);let Ge;const Ue=new Set,De={currentRoute:l,listening:!0,addRoute:_,removeRoute:h,clearRoutes:t.clearRoutes,hasRoute:g,getRoutes:m,resolve:E,options:e,push:C,replace:I,go:be,back:()=>be(-1),forward:()=>be(1),beforeEach:r.add,beforeResolve:o.add,afterEach:i.add,onError:Z.add,isReady:ve,install(M){M.component("RouterLink",Vf),M.component("RouterView",wl),M.config.globalProperties.$router=De,Object.defineProperty(M.config.globalProperties,"$route",{enumerable:!0,get:()=>v(l)}),Cn&&!Ge&&l.value===tn&&(Ge=!0,C(s.location).catch(F=>{}));const se={};for(const F in tn)Object.defineProperty(se,F,{get:()=>l.value[F],enumerable:!0});M.provide(ns,De),M.provide(yr,bo(se)),M.provide(Ks,l);const H=M.unmount;Ue.add(M),M.unmount=function(){Ue.delete(M),Ue.size<1&&(u=tn,ge&&ge(),ge=null,l.value=tn,Ge=!1,Y=!1),H()}}};function Oe(M){return M.reduce((se,H)=>se.then(()=>k(H)),Promise.resolve())}return De}function en(){return mt(ns)}function as(e){return mt(yr)}var qf={},zf=new Set(["primary","secondary","accent","success","warning","danger","error","info"]);function Re(...e){return e.flatMap(t=>t?Array.isArray(t)?t:typeof t=="object"?Object.entries(t).filter(([,n])=>n).map(([n])=>n):[t]:[]).filter(Boolean).join(" ")}function Mn(e,t="primary"){return zf.has(e)?e:t}function We(e,t=""){if(!e)return null;const n=e.includes("ph ")||e.startsWith("ph-");n||typeof process<"u"&&qf&&console.warn(`[gnexus-ui-kit] Icon "${e}" is missing the required "ph-" prefix. Use "ph-${e}" instead.`);const a=n?e:`ph-${e}`;return j("i",{class:Re("ph",a,t),"aria-hidden":"true"})}function ss(e){const t=e.target;return t.type==="checkbox"?t.checked:t.value}var Kf=["a[href]","button:not([disabled])","input:not([disabled])","select:not([disabled])","textarea:not([disabled])","[tabindex]:not([tabindex='-1'])"].join(",");function Wf(e,t){if(e.key!=="Tab"||!t)return;const n=[...t.querySelectorAll(Kf)].filter(r=>!r.hasAttribute("disabled")&&r.offsetParent!==null);if(!n.length){e.preventDefault(),t.focus();return}const a=n[0],s=n[n.length-1];e.shiftKey&&document.activeElement===a?(e.preventDefault(),s.focus()):!e.shiftKey&&document.activeElement===s&&(e.preventDefault(),a.focus())}var Jf=Be({name:"GnActionCard",props:{kicker:{type:String,default:""},title:{type:String,required:!0},text:{type:String,default:""}},setup(e,{slots:t}){return()=>{var n,a,s;return j("article",{class:"card action-card"},[j("div",{class:"card-content"},[(e.kicker||t.kicker)&&j("span",{class:"action-card-kicker"},((n=t.kicker)==null?void 0:n.call(t))||e.kicker),j("h3",{class:"action-card-title"},((a=t.title)==null?void 0:a.call(t))||e.title),(e.text||t.default)&&j("p",{class:"action-card-text"},((s=t.default)==null?void 0:s.call(t))||e.text),t.actions&&j("div",{class:"action-card-actions"},t.actions())])])}}}),Ze=Be({name:"GnAlert",inheritAttrs:!1,props:{variant:{type:String,default:"primary"},role:{type:String,default:"status"}},setup(e,{attrs:t,slots:n}){return()=>{var a;const s=Mn(e.variant);return j("div",{...t,role:e.role,class:Re("alert",`alert-${s}`,t.class)},(a=n.default)==null?void 0:a.call(n))}}}),Yf=Be({name:"GnAvatar",inheritAttrs:!1,props:{src:{type:String,default:""},alt:{type:String,default:""},initials:{type:String,default:""},icon:{type:String,default:""},size:{type:String,default:"md"},variant:{type:String,default:"primary"},outline:{type:Boolean,default:!1},status:{type:String,default:""}},setup(e,{attrs:t}){return()=>{const n=Mn(e.variant);return j("span",{...t,class:Re("avatar",`avatar-${n}`,{"avatar-sm":e.size==="sm","avatar-lg":e.size==="lg","avatar-outline":e.outline,"is-online":e.status==="online","is-busy":e.status==="busy","is-offline":e.status==="offline"},t.class)},[e.src?j("img",{src:e.src,alt:e.alt}):We(e.icon)||e.initials,e.status&&j("span",{class:"avatar-status","aria-hidden":"true"})])}}}),_e=Be({name:"GnBadge",inheritAttrs:!1,props:{variant:{type:String,default:"primary"},outline:{type:Boolean,default:!1}},setup(e,{attrs:t,slots:n}){return()=>{var a;const s=Mn(e.variant);return j("span",{...t,class:Re("badge",e.outline&&s==="primary"?"badge-primary-outline":`badge-${s}`,t.class)},(a=n.default)==null?void 0:a.call(n))}}}),de=Be({name:"GnButton",inheritAttrs:!1,props:{variant:{type:String,default:"primary"},size:{type:String,default:"md"},icon:{type:String,default:""},loading:{type:Boolean,default:!1},disabled:{type:Boolean,default:!1},type:{type:String,default:"button"}},setup(e,{attrs:t,slots:n}){return()=>{var a;const s=!!(e.icon||e.loading),r=Mn(e.variant);return j("button",{...t,type:e.type,disabled:e.disabled||e.loading,class:Re("btn",`btn-${r}`,{"btn-small":e.size==="sm","btn-large":e.size==="lg","with-icon":s,"loading-state":e.loading},t.class)},[e.loading?We("ph-bold ph-spinner"):We(e.icon),(a=n.default)==null?void 0:a.call(n)])}}}),Li=Be({name:"GnChip",inheritAttrs:!1,props:{variant:{type:String,default:""},icon:{type:String,default:""},selected:{type:Boolean,default:!1},disabled:{type:Boolean,default:!1},removable:{type:Boolean,default:!1},clickable:{type:Boolean,default:!1}},emits:["remove"],setup(e,{attrs:t,emit:n,slots:a}){return()=>{var s,r,o,i;const l=e.clickable?"button":"span",u=e.variant?Mn(e.variant):"",c=(o=(r=(s=a.default)==null?void 0:s.call(a))==null?void 0:r[0])==null?void 0:o.children;return j(l,{...t,type:l==="button"?"button":void 0,disabled:l==="button"?e.disabled:void 0,"aria-pressed":l==="button"?String(e.selected):void 0,class:Re("chip",u&&`chip-${u}`,{"chip-selected":e.selected,"chip-disabled":e.disabled},t.class)},[We(e.icon),(i=a.default)==null?void 0:i.call(a),e.removable&&j("button",{class:"chip-remove",type:"button","aria-label":c?`Remove ${c}`:"Remove",onClick:d=>{d.stopPropagation(),n("remove")}},[We("ph-x")])])}}}),Xf=0,at=Be({name:"GnModal",props:{open:{type:Boolean,default:!1},title:{type:String,default:""},closeOnBackdrop:{type:Boolean,default:!0}},emits:["update:open","close"],setup(e,{emit:t,slots:n}){const a=`gn-modal-title-${++Xf}`,s=J(null),r=J(!1),o=J(!1);let i=null,l=null;const u=()=>{t("update:open",!1),t("close")},c=f=>{f.key==="Escape"?(f.preventDefault(),u()):Wf(f,s.value)},d=()=>{_n(()=>{var f;(f=s.value)==null||f.focus()})};return wt(()=>e.open,f=>{var _;f?(o.value=!0,r.value=!0,_n(()=>{requestAnimationFrame(()=>{o.value=!1})}),i=document.activeElement,document.addEventListener("keydown",c),d()):(o.value=!0,document.removeEventListener("keydown",c),(_=i==null?void 0:i.focus)==null||_.call(i),i=null,l=window.setTimeout(()=>{r.value=!1,o.value=!1},300))},{flush:"post"}),Wa(()=>{document.removeEventListener("keydown",c),window.clearTimeout(l)}),()=>{var f,_,h;return r.value?j(Hu,{to:"body"},[j("div",{class:Re("modal",o.value?"a-hide":"a-show"),"aria-hidden":"false"},[j("div",{class:"modal-backdrop",onClick:()=>e.closeOnBackdrop&&u()}),j("div",{ref:s,class:"modal-dialog",role:"dialog","aria-modal":"true","aria-labelledby":a,tabindex:"-1"},[j("header",{class:"modal-header"},[j("h4",{class:"modal-title",id:a},((f=n.title)==null?void 0:f.call(n))||e.title),j("button",{class:"btn-icon modal-close",type:"button","aria-label":"Close",onClick:u},[We("ph-x")])]),j("div",{class:"modal-panel"},[j("div",{class:"modal-body"},(_=n.default)==null?void 0:_.call(n)),(n.footer||n.actions)&&j("footer",{class:"modal-footer"},[(h=n.footer)==null?void 0:h.call(n),n.actions&&j("div",{class:"actions"},n.actions({close:u}))])])])])]):null}}}),Zf=Be({name:"GnCopyButton",props:{text:{type:String,required:!0},icon:{type:String,default:"ph-copy"},successIcon:{type:String,default:"ph-check"},duration:{type:Number,default:3e3},label:{type:String,default:"Copy"},size:{type:String,default:null}},emits:["copy"],setup(e,{emit:t}){const n=J(!1);let a=null;const s=async()=>{try{await navigator.clipboard.writeText(e.text)}catch{const o=document.createElement("textarea");o.value=e.text,o.style.position="fixed",o.style.opacity="0",document.body.appendChild(o),o.select(),document.execCommand("copy"),document.body.removeChild(o)}n.value=!0,window.clearTimeout(a),a=window.setTimeout(()=>{n.value=!1},e.duration),t("copy",e.text)};return()=>j("button",{class:Re("btn-icon",{"btn-icon-sm":e.size==="sm"}),type:"button","aria-label":e.label,onClick:s},[We(n.value?e.successIcon:e.icon)])}}),Qf=Be({name:"GnDropdown",props:{label:{type:String,default:"Actions"},icon:{type:String,default:"ph-dots-three-outline"},variant:{type:String,default:"secondary"},items:{type:Array,default:()=>[]}},emits:["select"],setup(e,{emit:t,slots:n}){const a=J(!1),s=J(null),r=()=>{a.value=!1,document.removeEventListener("click",o),document.removeEventListener("keydown",i)},o=c=>{s.value&&!s.value.contains(c.target)&&r()},i=c=>{c.key==="Escape"&&(c.preventDefault(),r())},l=()=>{a.value=!a.value,a.value?(setTimeout(()=>document.addEventListener("click",o),0),document.addEventListener("keydown",i)):r()},u=c=>{var d;c.disabled||((d=c.onSelect)==null||d.call(c,c),t("select",c),r())};return Wa(r),()=>{var c,d;return j("div",{ref:s,class:Re("dropdown",{"is-open":a.value})},[((c=n.trigger)==null?void 0:c.call(n,{open:a.value,toggle:l}))||j(de,{variant:e.variant,icon:e.icon,"aria-expanded":a.value?"true":"false",onClick:l},()=>e.label),j("div",{class:"dropdown-menu",role:"menu"},((d=n.default)==null?void 0:d.call(n,{close:r}))||e.items.map(f=>j("button",{class:Re("dropdown-item",f.danger&&"dropdown-item-danger"),type:"button",role:"menuitem",disabled:f.disabled,onClick:()=>u(f)},[We(f.icon),f.label])))])}}}),ep=Be({name:"GnEmptyState",inheritAttrs:!1,props:{title:{type:String,required:!0},text:{type:String,default:""},icon:{type:String,default:"ph-package"},variant:{type:String,default:""}},setup(e,{attrs:t,slots:n}){return()=>{var a,s;return j("div",{...t,class:Re("empty-state",e.variant&&`empty-state-${e.variant}`,t.class)},[j("div",{class:"empty-state-icon"},[We(e.icon)]),j("h3",{class:"empty-state-title"},((a=n.title)==null?void 0:a.call(n))||e.title),(e.text||n.default)&&j("p",{class:"empty-state-text"},((s=n.default)==null?void 0:s.call(n))||e.text),n.actions&&j("div",{class:"empty-state-actions"},n.actions())])}}}),yt=Be({name:"GnInput",inheritAttrs:!1,props:{modelValue:{type:[String,Number],default:""},label:{type:String,default:""},type:{type:String,default:"text"},icon:{type:String,default:""},state:{type:String,default:""},help:{type:String,default:""},bare:{type:Boolean,default:!1}},emits:["update:modelValue"],setup(e,{attrs:t,emit:n}){return()=>{const a=j("input",{...t,type:e.type,value:e.modelValue,class:Re(e.bare?"":"input",t.class),onInput:s=>n("update:modelValue",ss(s))});return e.bare?a:j("div",{class:"form-group"},[j("label",{class:Re("label",e.state)},[e.label,We(e.icon),a]),e.help&&j("div",{class:Re("input-info",e.state==="error"&&"error")},e.help)])}}}),Sl=Be({name:"GnLoader",inheritAttrs:!1,props:{circle:{type:Boolean,default:!1},label:{type:String,default:"Loading"}},setup(e,{attrs:t}){return()=>e.circle?j("div",{...t,class:Re("circle-loader",t.class)},[We("ph-bold ph-spinner normalize"),e.label]):j("div",{...t,class:Re("loader",t.class),role:"status","aria-label":e.label})}});function tp(){var e;const t=Za();return((e=t==null?void 0:t.proxy)==null?void 0:e.$router)||null}function np(){var e;const t=Za();return((e=t==null?void 0:t.proxy)==null?void 0:e.$route)||null}function ap(e,t,n="prefix"){if(!e)return!1;const a=e.value||e;return typeof t=="string"?n==="exact"?a.path===t:a.path===t||a.path.startsWith(t+"/"):t.path?n==="exact"?a.path===t.path:a.path===t.path||a.path.startsWith(t.path+"/"):t.name?a.name===t.name:!1}var sp=Be({name:"GnNavList",inheritAttrs:!1,props:{items:{type:Array,default:()=>[]},activeMatch:{type:String,default:"prefix"}},emits:["select"],setup(e,{attrs:t,emit:n,slots:a}){const s=tp(),r=np(),o=!!(s&&r),i=u=>{if(u){if(typeof u=="string")return u;if(u.path)return u.path}},l=Q(()=>e.items.map(u=>{const c=!!u.to,d=c?o?s.resolve(u.to).href:i(u.to):u.href,f=c&&o?ap(r,u.to,e.activeMatch):!!u.active;return{...u,resolvedHref:d,isActive:f,hasTo:c}}));return()=>j("ul",{...t,class:Re("list list-nav",t.class)},l.value.map(u=>{var c,d;return j("li",{class:Re("list-item",{"list-item-active":u.isActive})},[j(u.resolvedHref?"a":"button",{class:"list-action",href:u.resolvedHref,type:u.resolvedHref?void 0:"button",onClick:f=>{var _;u.hasTo&&o&&(f.preventDefault(),s.push(u.to)),(_=u.onSelect)==null||_.call(u,u,f),n("select",u)}},[j("span",{class:"list-label"},[We(u.icon),((c=a.label)==null?void 0:c.call(a,{item:u}))||u.label]),(u.meta||a.meta)&&j("span",{class:"list-meta"},((d=a.meta)==null?void 0:d.call(a,{item:u}))||u.meta)])])}))}}),rp=0,ip=Be({name:"GnNavigationShell",props:{brand:{type:String,default:"GNexus UI Kit"},logoSrc:{type:String,default:"/assets/imgs/gnexus-mark.svg"},current:{type:String,default:""},title:{type:String,default:"Sections"},subtitle:{type:String,default:"Navigation"},footerLeft:{type:String,default:""},footerRight:{type:String,default:""},items:{type:Array,default:()=>[]},activeMatch:{type:String,default:"prefix"}},emits:["select"],setup(e,{emit:t,slots:n}){const a=J(!1),s=`gn-nav-drawer-${++rp}`,r=J(null);let o=null;const i=()=>{a.value=!1},l=()=>{a.value=!a.value},u=c=>{c.key==="Escape"&&(c.preventDefault(),i())};return wt(a,c=>{var d;c?(o=document.activeElement,document.body.classList.add("nav-drawer-open"),document.addEventListener("keydown",u),_n(()=>{var f;return(f=r.value)==null?void 0:f.focus()})):(document.body.classList.remove("nav-drawer-open"),document.removeEventListener("keydown",u),(d=o==null?void 0:o.focus)==null||d.call(o),o=null)}),Wa(()=>{document.body.classList.remove("nav-drawer-open"),document.removeEventListener("keydown",u)}),()=>{var c,d,f,_,h,m,g;return[j("header",{class:"nav-topbar"},[j("button",{class:"nav-topbar-toggle",type:"button","aria-controls":s,"aria-expanded":a.value?"true":"false",onClick:l},[We("ph-sidebar-simple"),j("span",{},"Menu")]),j("div",{class:"nav-topbar-brand"},[e.logoSrc&&j("img",{src:e.logoSrc,alt:"","aria-hidden":"true"}),j("span",{},((c=n.brand)==null?void 0:c.call(n))||e.brand)]),j("div",{class:"nav-topbar-current"},((d=n.current)==null?void 0:d.call(n))||e.current)]),j("div",{class:"nav-drawer-backdrop",onClick:i}),j("aside",{ref:r,class:["nav-drawer",{"is-open":a.value}],id:s,"aria-label":"Navigation","aria-hidden":a.value?"false":"true",tabindex:"-1"},[j("header",{class:"nav-drawer-header"},[j("div",{},[j("div",{class:"nav-drawer-title"},((f=n.title)==null?void 0:f.call(n))||e.title),j("div",{class:"nav-drawer-subtitle"},((_=n.subtitle)==null?void 0:_.call(n))||e.subtitle)]),j("button",{class:"nav-drawer-close",type:"button","aria-label":"Close navigation",onClick:i},[We("ph-x")])]),j("nav",{class:"nav-drawer-body"},[((h=n.default)==null?void 0:h.call(n,{close:i}))||j(sp,{items:e.items,activeMatch:e.activeMatch,onSelect:E=>{t("select",E),i()}})]),(n.footer||e.footerLeft||e.footerRight)&&j("footer",{class:"nav-drawer-footer"},((m=n.footer)==null?void 0:m.call(n))||[j("span",{},e.footerLeft),j("span",{},e.footerRight)])]),(g=n.content)==null?void 0:g.call(n)]}}}),Rt=Be({name:"GnPageHeader",inheritAttrs:!1,props:{title:{type:String,required:!0},subtitle:{type:String,default:""},kicker:{type:String,default:""},compact:{type:Boolean,default:!1},accent:{type:Boolean,default:!1}},setup(e,{attrs:t,slots:n}){return()=>{var a,s,r;return j("header",{...t,class:Re("page-header",{"page-header-compact":e.compact,"page-header-accent":e.accent},t.class)},[j("div",{class:"page-header-content"},[(e.kicker||n.kicker)&&j("div",{class:"page-header-kicker"},((a=n.kicker)==null?void 0:a.call(n))||e.kicker),j("h1",{class:"page-header-title"},((s=n.title)==null?void 0:s.call(n))||e.title),(e.subtitle||n.subtitle)&&j("p",{class:"page-header-subtitle"},((r=n.subtitle)==null?void 0:r.call(n))||e.subtitle),n.meta&&j("div",{class:"page-header-meta"},n.meta())]),n.actions&&j("div",{class:"page-header-actions"},n.actions())])}}}),op=Be({name:"GnRange",inheritAttrs:!1,props:{modelValue:{type:[Number,String],default:0},label:{type:String,default:""},min:{type:[Number,String],default:0},max:{type:[Number,String],default:100},step:{type:[Number,String],default:1}},emits:["update:modelValue"],setup(e,{attrs:t,emit:n}){return()=>j("div",{class:"range"},[j("label",{class:"label"},[e.label,j("input",{...t,type:"range",value:e.modelValue,min:e.min,max:e.max,step:e.step,onInput:a=>n("update:modelValue",ss(a))})])])}}),rs=Be({name:"GnSelect",inheritAttrs:!1,props:{modelValue:{type:[String,Number],default:""},label:{type:String,default:""},icon:{type:String,default:""},state:{type:String,default:""},help:{type:String,default:""},options:{type:Array,default:()=>[]}},emits:["update:modelValue"],setup(e,{attrs:t,emit:n,slots:a}){const s=()=>e.options.map(r=>{const o=typeof r=="object"?r.value:r,i=typeof r=="object"?r.label:r;return j("option",{value:o},i)});return()=>{var r;return j("div",{class:"form-group"},[j("label",{class:Re("label",e.state)},[e.label,We(e.icon),j("div",{class:"select-wrap"},[j("select",{...t,value:e.modelValue,class:Re("input select",t.class),onChange:o=>n("update:modelValue",ss(o))},((r=a.default)==null?void 0:r.call(a))||s())])]),e.help&&j("div",{class:Re("input-info",e.state==="error"&&"error")},e.help)])}}}),kl=Be({name:"GnSwitch",inheritAttrs:!1,props:{modelValue:{type:Boolean,default:!1},label:{type:String,default:""},disabled:{type:Boolean,default:!1}},emits:["update:modelValue"],setup(e,{attrs:t,emit:n,slots:a}){return()=>{var s;return j("label",{class:Re("switch",t.class)},[j("input",{...t,type:"checkbox",checked:e.modelValue,disabled:e.disabled,onChange:r=>n("update:modelValue",r.target.checked)}),j("span",{class:"switch-control","aria-hidden":"true"}),j("span",{class:"switch-label"},((s=a.default)==null?void 0:s.call(a))||e.label)])}}}),Nn=Be({name:"GnTable",props:{columns:{type:Array,required:!0},rows:{type:Array,default:()=>[]},caption:{type:String,default:""},emptyText:{type:String,default:"Empty"}},setup(e,{attrs:t,slots:n}){return()=>{var a;return j("div",{class:"table-wrapper"},[j("table",{class:Re("table data-list",{"table-empty":!e.rows.length},t.class)},[e.caption&&j("caption",{class:"table-caption"},e.caption),j("thead",{class:"table-head"},[j("tr",{class:"table-row"},e.columns.map(s=>j("th",{scope:"col"},s.label)))]),j("tbody",{class:"table-body"},e.rows.length?e.rows.map(s=>j("tr",{class:"table-row"},e.columns.map(r=>{var o;const i=`cell-${r.key}`;return j("td",{},((o=n[i])==null?void 0:o.call(n,{row:s,column:r,value:s[r.key]}))||s[r.key])}))):j("tr",{},[j("td",{class:"is-empty",colspan:e.columns.length},((a=n.empty)==null?void 0:a.call(n))||e.emptyText)]))])])}}}),lp=Be({name:"GnTextarea",inheritAttrs:!1,props:{modelValue:{type:String,default:""},label:{type:String,default:""},icon:{type:String,default:""},state:{type:String,default:""},help:{type:String,default:""}},emits:["update:modelValue"],setup(e,{attrs:t,emit:n}){return()=>j("div",{class:"form-group"},[j("label",{class:Re("label",e.state)},[e.label,We(e.icon),j("textarea",{...t,value:e.modelValue,class:Re("input",t.class),onInput:a=>n("update:modelValue",ss(a))})]),e.help&&j("div",{class:Re("input-info",e.state==="error"&&"error")},e.help)])}}),Al=Symbol("gnexus-ui-kit-toast"),Di={info:"ph-info",success:"ph-check-circle",warning:"ph-warning",danger:"ph-warning-octagon",error:"ph-warning-octagon",primary:"ph-info",secondary:"ph-info"},up=Be({name:"GnToastProvider",props:{lifetime:{type:Number,default:4e3}},setup(e,{slots:t,expose:n}){const a=J(null),s=J(!1),r=J(!1);let o=null,i=null,l=null;const u=J(100),c=()=>{window.clearTimeout(i),window.clearInterval(l),s.value=!0,r.value=!1,i=window.setTimeout(()=>{a.value=null,s.value=!1,u.value=100,window.clearTimeout(o),o=null},300)},d=()=>{window.clearTimeout(i),window.clearTimeout(o),window.clearInterval(l),s.value=!1,r.value=!1,u.value=100,a.value=null},f=m=>{window.clearTimeout(i),window.clearInterval(l),s.value=!1,r.value=!1,u.value=100;const g=Mn(m.variant||m.type||"info","info"),E=m.lifetime!==void 0?m.lifetime:e.lifetime;if(a.value={id:Date.now(),variant:g==="error"?"danger":g,title:m.title||"",text:m.text||m.message||"",icon:m.icon||Di[g]||Di.info,lifetime:E},window.clearTimeout(o),E!==0){const w=E/100;u.value=100,l=window.setInterval(()=>{u.value-=100/w,u.value<=0&&window.clearInterval(l)},100),o=window.setTimeout(c,E)}_n(()=>{requestAnimationFrame(()=>{r.value=!0})})},_={show:f,close:d,info:m=>f({...m,variant:"info"}),success:m=>f({...m,variant:"success"}),warning:m=>f({...m,variant:"warning"}),danger:m=>f({...m,variant:"danger"}),error:m=>f({...m,variant:"danger"})};ta(Al,_),n(_);const h=()=>s.value?"a-hide":r.value?"a-show":"";return()=>{var m;return[(m=t.default)==null?void 0:m.call(t),a.value&&j("div",{class:Re("toast",h(),`toast-${a.value.variant}`),role:"alert"},[j("div",{class:"toast-content"},[j("div",{class:"toast-header"},[We(a.value.icon),a.value.title]),a.value.text&&j("p",{class:"toast-text"},a.value.text)]),j("button",{class:"btn-icon toast-close",type:"button","aria-label":"Close",onClick:c},[We("ph-x")]),a.value.lifetime!==0&&j("div",{class:"toast-progress"},[j("div",{class:"toast-progress-bar",style:{transform:`scaleX(${Math.max(0,u.value/100)})`}})])])]}}}),cp=Be({name:"GnUserCard",props:{name:{type:String,required:!0},email:{type:String,default:""},role:{type:String,default:""},avatar:{type:Object,default:()=>({})},href:{type:String,default:""},compact:{type:Boolean,default:!1},actions:{type:Array,default:()=>[]}},setup(e,{slots:t}){const n=()=>{var r;return((r=t.avatar)==null?void 0:r.call(t))||j(Yf,{...e.avatar,size:e.compact?"sm":"md"})},a=()=>j("span",{class:"identity"},[n(),j("span",{class:"identity-content"},[j("span",{class:"identity-title"},e.name),e.email&&j("span",{class:"identity-meta"},e.email)])]),s=()=>t.actions?t.actions():e.actions.length?j("div",{class:"user-card-actions"},e.actions.map(r=>{if(e.compact)return j("button",{class:"btn-icon",type:"button","aria-label":r.label,onClick:r.onClick},[We(r.icon)]);const o=!!r.icon,i=Re("btn","btn-small",{[`btn-${r.variant}`]:r.variant,"btn-secondary":!r.variant,"with-icon":o});return j("button",{class:i,type:"button",onClick:r.onClick},[o&&We(r.icon),r.label])})):null;return()=>{const r=Re("card","user-card",{"user-card-compact":e.compact}),o=[];e.href?o.push(j("a",{class:"profile-identity",href:e.href,target:"_blank",rel:"noopener noreferrer"},[a()])):o.push(a()),!e.compact&&e.role&&o.push(j("span",{class:"user-card-role"},e.role)),t.default&&!e.compact&&o.push(j("div",{class:"user-card-extra"},t.default()));const i=s();return i&&o.push(i),j("article",{class:r},[j("div",{class:"user-card-body"},o)])}}});function wn(){const e=mt(Al,null);if(e)return e;const t=()=>{throw new Error("GNexus UI Kit: useToast() requires near the app root.")};return{show:t,info:t,success:t,warning:t,danger:t,error:t,close:t}}const As=ya("Preferences",{web:()=>gr(()=>import("./web-BPiyNEQ1.js"),[]).then(e=>new e.PreferencesWeb)}),_r="shserv_server_url";let br="";function Nt(){return Da.isNativePlatform()}function xl(){return br}function xa(e){br=String(e||"").replace(/\/+$/,"")}async function dp(){if(!Nt()){xa("");return}try{const e=await At.get(_r);xa(e||"")}catch{xa("")}}async function fp(e){const t=String(e||"").replace(/\/+$/,"");if(xa(t),!!Nt())try{await At.set(_r,t)}catch{}}function pp(e){const t=xl();if(!t)return e;const n=String(e||"").replace(/^\/+/,"");return n?`${t}/${n}`:t}async function vp(){return!Nt()||br?!0:!!await At.get(_r)}const At={async get(e){if(Nt())try{const{value:t}=await As.get({key:e});return t}catch{return null}try{return localStorage.getItem(e)}catch{return null}},async set(e,t){if(Nt()){try{await As.set({key:e,value:t})}catch{}return}try{localStorage.setItem(e,t)}catch{}},async remove(e){if(Nt()){try{await As.remove({key:e})}catch{}return}try{localStorage.removeItem(e)}catch{}}},Oa="shserv_access_token",Fa="shserv_expires_at";let yn=null,ln=null;async function gp(){try{yn=await At.get(Oa)||null;const t=await At.get(Fa);ln=t?Number(t):null}catch{yn=null,ln=null}}function is(e,t=null){yn=e||null,t!=null&&t>0?ln=Date.now()+t*1e3:ln=null,yn?(At.set(Oa,yn),ln&&At.set(Fa,String(ln))):(At.remove(Oa),At.remove(Fa))}function Cl(){return yn}function hp(){return ln}function En(){yn=null,ln=null,At.remove(Oa),At.remove(Fa)}const Na={DEBUG:0,INFO:1,WARN:2,ERROR:3};function El(){return Na[void 0]??Na.INFO}function wr(){return El()<=Na.DEBUG}function Oi(e){return Na[e]>=El()}function Fi(e){return e<10?`${e.toFixed(1)}ms`:`${Math.round(e)}ms`}function Rl(e,t=500){if(!e)return"";const n=String(e);return n.length>t?n.slice(0,t)+"…":n}function $l(e,t){try{const n=JSON.stringify(e);return t?Rl(n,t):n}catch{return"[Circular]"}}const mp=1e4,xs="[vue:http]";function yp(e){const t=new URLSearchParams;for(const[a,s]of Object.entries(e||{}))s!=null&&t.append(a,String(s));const n=t.toString();return n?`?${n}`:""}function _p(e,t){const n=String(e||"").replace(/\/+$/,""),a=String(t||"").replace(/^\/+/,"");return n?`${n}/${a}`:`/${a}`}function bp(e,t){return`${e}${yp(t)}`}async function Ni(e,t,n,a={}){const s=Number(a.timeoutMs||mp),r=new AbortController,o=setTimeout(()=>r.abort(),s),i=xl(),l=_p(i,bp(t,a.query)),u={Accept:"application/json",...a.headers||{}},c=Cl();c&&(u.Authorization=`Bearer ${c}`);const d={method:e,headers:u,signal:r.signal,credentials:"include"};a.signal&&a.signal.addEventListener("abort",()=>r.abort(),{once:!0}),n!=null&&(u["Content-Type"]="application/json",d.body=JSON.stringify(n)),wr()&&console.debug(xs,e,l,n?$l(n,500):"");const f=performance.now();try{const _=await fetch(l,d),h=await _.text();let m=h;if(h)try{m=JSON.parse(h)}catch{m=h}const g=performance.now()-f,E=_.status>=500?"ERROR":_.status>=400?"WARN":"INFO";return Oi(E)&&console[E.toLowerCase()](xs,`${e} ${l} — ${_.status} in ${Fi(g)}`,Rl(h||"",200)),{response:_,data:m,meta:{url:l,method:e,statusCode:_.status,headers:_.headers}}}catch(_){const h=performance.now()-f;throw Oi("ERROR")&&console.error(xs,`${e} ${l} — FAILED in ${Fi(h)}`,(_==null?void 0:_.message)||_),_}finally{clearTimeout(o)}}function Sr(e){const t=pp(`/auth/login?return_to=${encodeURIComponent(e)}`);window.location.href=t}function Tl(){window.location.href="/#/login"}function kr(){return Nt()?"/auth/mobile-bridge":window.location.href}let Cs=!1,Ws=[];function wp(e){Ws.push(e)}function Mi(e){Ws.forEach(t=>t(e)),Ws=[]}function Gn(e,t,n={}){return{type:e,message:t,...n}}async function Ar(e,t,n,a){var s,r;try{const{response:o,data:i,meta:l}=await Ni(e,t,n,a);if(!o.ok){if(o.status===401&&!(a!=null&&a._retryOnce)){if(Cs)await new Promise(c=>{wp(d=>c(d))});else{Cs=!0;try{const c=await Ni("POST","/auth/refresh",null);if(c.response.ok){const d=(r=(s=c.data)==null?void 0:s.data)==null?void 0:r.access_token;if(d)is(d),Mi(d);else throw new Error("No token in refresh response")}else throw new Error("Refresh failed")}catch{return Mi(null),En(),window.location.hash.includes("/login")||Tl(),{ok:!1,error:Gn("http_error","HTTP 401",{statusCode:401,raw:i}),meta:l}}finally{Cs=!1}}return Cl()?Ar(e,t,n,{...a,_retryOnce:!0}):{ok:!1,error:Gn("http_error","HTTP 401",{statusCode:401,raw:i}),meta:l}}return{ok:!1,error:Gn("http_error",`HTTP ${o.status}`,{statusCode:o.status,raw:i}),meta:l}}return i&&typeof i=="object"&&(i.status===!1||i.status==="error")?{ok:!1,error:Gn("api_error",i.msg||i.message||"API error",{errorAlias:i.error_alias,failedFields:i.failed_fields||[],raw:i}),meta:l}:{ok:!0,data:i,meta:l}}catch(o){const i=(o==null?void 0:o.name)==="AbortError";return{ok:!1,error:Gn(i?"timeout":"network_error",(o==null?void 0:o.message)||"Network error",{details:o}),meta:{url:t,method:e,statusCode:0,headers:null}}}}function Fe(e,t){return Ar("GET",e,null,t)}function Qe(e,t,n){return Ar("POST",e,t,n)}const Un=bn("auth",()=>{const e=J(null),t=J([]),n=J(!1),a=J(null),s=Q(()=>!!e.value),r=Q(()=>new Set(t.value));function o(m){return r.value.has(m)}function i(m){return Array.isArray(m)?m.some(g=>r.value.has(g)):!1}function l(){a.value&&(clearTimeout(a.value),a.value=null);const m=hp();if(!m)return;const g=m-Date.now()-6e4;g>0?a.value=setTimeout(()=>{f().then(()=>{l()})},g):f().then(()=>{l()})}function u(){a.value&&(clearTimeout(a.value),a.value=null)}let c=null;async function d(){return c||(n.value=!0,c=Fe("/auth/me").then(async m=>{var g,E,y;if(m.ok){const w=((g=m.data)==null?void 0:g.data)||{};e.value=w.user||null,t.value=w.permissions||[],l()}else if(((E=m.error)==null?void 0:E.statusCode)===401){await f();const w=await Fe("/auth/me");if(w.ok){const C=((y=w.data)==null?void 0:y.data)||{};e.value=C.user||null,t.value=C.permissions||[],l()}else e.value=null,t.value=[],En(),u()}else e.value=null,t.value=[],En(),u()}).catch(()=>{e.value=null,t.value=[],En(),u()}).finally(()=>{n.value=!1}),c)}async function f(){var g,E,y,w;const m=await Qe("/auth/refresh");if(m.ok){const C=((E=(g=m.data)==null?void 0:g.data)==null?void 0:E.access_token)||null,I=((w=(y=m.data)==null?void 0:y.data)==null?void 0:w.expires_in)||null;is(C,I),l()}else En(),u()}async function _(){try{await Qe("/auth/logout")}catch{}e.value=null,t.value=[],En(),u(),window.location.href="/#/login"}function h(){if(Nt()){Tl();return}Sr(kr())}return{user:e,permissions:t,isLoading:n,isAuthenticated:s,hasPermission:o,hasAnyPermission:i,init:d,refreshToken:f,logout:_,redirectToLogin:h}}),Sp={__name:"AppShell",setup(e){const t=as(),n=Un(),a={login:"Login","areas-favorites":"Favorites","areas-tree":"Areas","area-detail":"Area",devices:"Devices","device-detail":"Device","devices-scanning":"Scanning","scripts-actions":"Actions","scripts-regular":"Regular","scripts-scopes":"Scopes","script-detail":"Script",firmwares:"Firmwares"},s=Q(()=>{const f=t==null?void 0:t.name;return f&&a[f]?a[f]:""}),r=[{label:"Favorites",to:"/areas/favorites",icon:"ph-bookmarks",permission:"areas.view"},{label:"Areas",to:"/areas/tree",icon:"ph-map-trifold",permission:"areas.view"},{label:"Devices",to:"/devices",icon:"ph-cpu",permission:"devices.view"},{label:"Scanning",to:"/devices/scanning",icon:"ph-magnifying-glass",permission:"devices.scan"},{label:"Actions",to:"/scripts/actions",icon:"ph-play",permission:"scripts.run"},{label:"Regular",to:"/scripts/regular",icon:"ph-clock",permission:"scripts.view"},{label:"Scopes",to:"/scripts/scopes",icon:"ph-brackets-curly",permission:"scripts.view"},{label:"Firmwares",to:"/firmwares",icon:"ph-cloud-arrow-down",permission:"firmware.view"}],o=Q(()=>r.filter(f=>f.permission?n.hasPermission(f.permission):!0));function i(f){return f?f.split(/\s+/).slice(0,2).map(_=>{var h;return(h=_[0])==null?void 0:h.toUpperCase()}).join(""):""}function l(f){return f?f.charAt(0).toUpperCase()+f.slice(1):""}function u(){Sr(kr())}function c(){const f=document.querySelector(".nav-drawer-backdrop");f&&f.click()}function d(){c(),n.logout()}return(f,_)=>(S(),q(v(ip),{brand:"SHSERV","logo-src":"/logo-cube-square.svg",title:"Navigation",subtitle:"Smart Home",items:o.value,"active-match":"prefix",current:s.value},{content:x(()=>[Ja(f.$slots,"default")]),footer:x(()=>{var h,m,g,E,y,w;return[v(n).isAuthenticated?(S(),q(v(cp),{key:0,name:((h=v(n).user)==null?void 0:h.display_name)||"User",email:((m=v(n).user)==null?void 0:m.email)||"",role:l((g=v(n).user)==null?void 0:g.system_role),avatar:{src:((E=v(n).user)==null?void 0:E.avatar_url)||"",initials:i((y=v(n).user)==null?void 0:y.display_name),size:"sm"},href:((w=v(n).user)==null?void 0:w.gauth_profile_url)||"",compact:"",actions:[{label:"Logout",icon:"ph-sign-out",variant:"ghost",onClick:d}]},null,8,["name","email","role","avatar","href","actions"])):(S(),q(v(de),{key:1,variant:"primary",size:"sm",onClick:u},{icon:x(()=>[..._[0]||(_[0]=[T("i",{class:"ph ph-sign-in"},null,-1)])]),default:x(()=>[_[1]||(_[1]=N(" Sign in ",-1))]),_:1}))]}),_:3},8,["items","current"]))}},ze=(e,t)=>{const n=e.__vccOpts||e;for(const[a,s]of t)n[a]=s;return n},kp={key:0},Ap={key:1,class:"error-meta"},xp={class:"error-actions"},Cp={__name:"AppErrorState",props:{title:{type:String,default:"Request failed"},message:{type:String,default:""},retry:{type:Function,default:null},error:{type:Object,default:null}},setup(e){const t=e,n=Q(()=>{var s;return t.message||((s=t.error)==null?void 0:s.message)||""}),a=Q(()=>{if(!t.error)return"";try{return JSON.stringify(t.error,null,2)}catch{return String(t.error)}});return(s,r)=>(S(),q(v(Ze),{variant:"danger",role:"alert"},{default:x(()=>[T("strong",null,O(e.title),1),n.value?(S(),G("p",kp,O(n.value),1)):ne("",!0),e.error?(S(),G("div",Ap,[e.error.type?(S(),q(v(_e),{key:0,variant:"secondary"},{default:x(()=>[N(O(e.error.type),1)]),_:1})):ne("",!0),e.error.statusCode?(S(),q(v(_e),{key:1,variant:"secondary"},{default:x(()=>[N("HTTP "+O(e.error.statusCode),1)]),_:1})):ne("",!0),e.error.errorAlias?(S(),q(v(_e),{key:2,variant:"warning"},{default:x(()=>[N(O(e.error.errorAlias),1)]),_:1})):ne("",!0)])):ne("",!0),T("div",xp,[e.error?(S(),q(v(Zf),{key:0,text:a.value,label:"Copy error details",size:"sm"},null,8,["text"])):ne("",!0),e.retry?(S(),q(v(de),{key:1,variant:"danger",onClick:e.retry},{default:x(()=>[...r[0]||(r[0]=[N("Retry",-1)])]),_:1},8,["onClick"])):ne("",!0)])]),_:1}))}},pt=ze(Cp,[["__scopeId","data-v-f1e6bcb8"]]),Ep={key:0,class:"error-boundary",role:"alert"},Rp={__name:"AppErrorBoundary",setup(e){const t=J(!1),n=J("");Do((s,r,o)=>{const i=(s==null?void 0:s.message)||String(s);return console.error("[AppErrorBoundary] Caught Vue error:",i,"| info:",o,s),t.value=!0,n.value=i,!1});function a(){t.value=!1,n.value=""}return(s,r)=>t.value?(S(),G("div",Ep,[$(pt,{title:"Something went wrong",message:n.value,retry:a},null,8,["message"])])):Ja(s.$slots,"default",{key:1},void 0,!0)}},$p=ze(Rp,[["__scopeId","data-v-1e10ea7f"]]),Tp={__name:"App",setup(e){return(t,n)=>(S(),q(Sp,null,{default:x(()=>[$(v(up),null,{default:x(()=>[$($p,null,{default:x(()=>[$(v(wl))]),_:1})]),_:1})]),_:1}))}},Tt={list(e){return Fe("/api/v1/areas/list",e)},innerList(e,t){return Fe(`/api/v1/areas/id/${encodeURIComponent(String(e))}/list`,t)},newArea(e){return Qe("/api/v1/areas/new-area",e)},remove(e){return Fe(`/api/v1/areas/id/${encodeURIComponent(String(e))}/remove`)},devices(e,t){return Fe(`/api/v1/areas/id/${encodeURIComponent(String(e))}/devices`,t)},scripts(e,t){return Fe(`/api/v1/areas/id/${encodeURIComponent(String(e))}/scripts`,t)},updateDisplayName(e){return Qe("/api/v1/areas/update-display-name",e)},updateAlias(e){return Qe("/api/v1/areas/update-alias",e)},placeInArea(e){return Qe("/api/v1/areas/place-in-area",e)},unassign(e){return Fe(`/api/v1/areas/id/${encodeURIComponent(String(e))}/unassign-from-area`)}};function gt(e={}){const t=J(null),n=J(!1),a=J(null);async function s(i){var u,c;(u=t.value)==null||u.abort();const l=new AbortController;t.value=l,n.value=!0,a.value=null;try{const d=await i(l.signal);return t.value=null,n.value=!1,d.ok||e.ignoreTimeout!==!1&&((c=d.error)==null?void 0:c.type)==="timeout"||(a.value=d.error),d}catch(d){return t.value=null,n.value=!1,a.value={type:"network_error",message:(d==null?void 0:d.message)||"Network error"},{ok:!1,error:a.value}}}function r(){var i;(i=t.value)==null||i.abort(),t.value=null}function o(){a.value=null,r()}return{abortController:t,isLoading:n,error:a,execute:s,abort:r,clear:o}}const Pl="sh:areas:expandedNodes";function Pp(){try{const e=localStorage.getItem(Pl);if(e){const t=JSON.parse(e);if(Array.isArray(t))return new Set(t)}}catch{}return new Set}function Ip(e){try{localStorage.setItem(Pl,JSON.stringify([...e]))}catch{}}function Lp(e){const t={},n=[];for(const a of e)t[a.id]={...a,children:[]};for(const a of e){const s=t[a.id],r=a.parent_id&&a.parent_id==a.id,o=a.parent_id&&t[a.parent_id];!r&&o?t[a.parent_id].children.push(s):n.push(s)}return n.length===0&&e.length>0?Object.values(t):n}const kt=bn("areas",()=>{const e=J([]),t=J(null),n=J([]),a=J([]),s=gt(),r=gt(),o=Q(()=>Object.fromEntries(e.value.map(P=>[String(P.id),P]))),i=Q(()=>Lp(e.value)),l=J(Pp());wt(l,P=>{Ip(P)},{deep:!0});function u(P){const R=new Set(l.value);R.has(P)?R.delete(P):R.add(P),l.value=R}function c(P){return l.value.has(P)}async function d(){return s.execute(async P=>{var L,k;const R=await Tt.list({signal:P});return R.ok&&(e.value=((k=(L=R.data)==null?void 0:L.data)==null?void 0:k.areas)||[]),R})}async function f(P){var L,k,ee,le,fe,ge;r.abort();const R=new AbortController;r.abortController.value=R,r.isLoading.value=!0,r.error.value=null,t.value=o.value[String(P)]||null,n.value=[],a.value=[];try{const[B,W]=await Promise.all([Tt.devices(P,{signal:R.signal}),Tt.scripts(P,{signal:R.signal})]);return r.abortController.value=null,r.isLoading.value=!1,B.ok?W.ok?(n.value=((le=(ee=B.data)==null?void 0:ee.data)==null?void 0:le.devices)||[],a.value=((ge=(fe=W.data)==null?void 0:fe.data)==null?void 0:ge.scripts)||[],{ok:!0}):(((k=W.error)==null?void 0:k.type)!=="timeout"&&(r.error.value=W.error),{ok:!1,error:r.error.value}):(((L=B.error)==null?void 0:L.type)!=="timeout"&&(r.error.value=B.error),{ok:!1,error:r.error.value})}catch(B){return r.abortController.value=null,r.isLoading.value=!1,r.error.value={type:"network_error",message:(B==null?void 0:B.message)||"Network error"},{ok:!1,error:r.error.value}}}function _(){t.value=null,n.value=[],a.value=[],r.clear()}async function h(P){var L,k;const R=await Tt.devices(P);return R.ok&&(n.value=((k=(L=R.data)==null?void 0:L.data)==null?void 0:k.devices)||[]),R}async function m(P){var L,k;const R=await Tt.scripts(P);return R.ok&&(a.value=((k=(L=R.data)==null?void 0:L.data)==null?void 0:k.scripts)||[]),R}async function g(P){var L,k;const R=await Tt.newArea(P);if(R.ok){const ee=(k=(L=R.data)==null?void 0:L.data)==null?void 0:k.area;ee&&e.value.push(ee)}return R}async function E(P,R){const L=await Tt.updateDisplayName({area_id:P,display_name:R});if(L.ok){const k=e.value.findIndex(ee=>ee.id===P);k!==-1&&(e.value[k]={...e.value[k],display_name:R})}return L}async function y(P){const R=await Tt.remove(P);return R.ok&&(e.value=e.value.filter(L=>L.id!==P)),R}function w(P){return!(P!=null&&P.parent_id)||P.parent_id<=0}async function C(P,R){const L=e.value.find(le=>le.id===P),k=e.value.filter(w).length;if(L&&w(L)&&k===1)return{ok:!1,error:{message:"Cannot assign the last root area as a child."}};const ee=await Tt.placeInArea({target_id:P,place_in_area_id:R});if(ee.ok){const le=e.value.findIndex(fe=>fe.id===P);le!==-1&&e.value.splice(le,1,{...e.value[le],parent_id:Number(R)})}return ee}async function I(P){const R=await Tt.unassign(P);if(R.ok){const L=e.value.findIndex(k=>k.id===P);L!==-1&&e.value.splice(L,1,{...e.value[L],parent_id:0})}return R}return{areas:e,isLoading:s.isLoading,error:s.error,currentArea:t,currentAreaDevices:n,currentAreaScripts:a,isLoadingAreaDetail:r.isLoading,errorAreaDetail:r.error,areasById:o,areaTree:i,expandedNodeIds:l,toggleNode:u,isNodeExpanded:c,loadAreas:d,loadAreaDetail:f,clearAreaDetail:_,loadAreaDevices:h,loadAreaScripts:m,createArea:g,renameArea:E,removeArea:y,assignToArea:C,unassignArea:I}}),Il="sh_fav_areas";function Dp(){try{return JSON.parse(localStorage.getItem(Il)||"[]").map(String)}catch{return[]}}function Ui(e){localStorage.setItem(Il,JSON.stringify(e.map(String)))}const xr=bn("favorites",()=>{const e=J(Dp());function t(r){return e.value.includes(String(r))}function n(r){const o=String(r);e.value.includes(o)||(e.value.push(o),Ui(e.value))}function a(r){e.value=e.value.filter(o=>o!==String(r)),Ui(e.value)}function s(r){return t(r)?(a(r),!1):(n(r),!0)}return{ids:e,has:t,add:n,remove:a,toggle:s}}),Op=["aria-label"],Ll={__name:"AreaFavoriteButton",props:{areaId:{type:[String,Number],required:!0}},setup(e){const t=e,n=xr(),a=Q(()=>n.has(t.areaId));return(s,r)=>(S(),G("button",{class:Mt(["btn-icon area-favorite-btn",{"is-active":a.value,"text-muted":!a.value,"text-warning":a.value}]),type:"button","aria-label":a.value?"Remove bookmark":"Bookmark",onClick:r[0]||(r[0]=Qa(o=>v(n).toggle(e.areaId),["stop"]))},[T("i",{class:Mt(["ph",a.value?"ph-fill ph-bookmark-simple":"ph-bookmark-simple"])},null,2)],10,Op))}},St={__name:"AppLoadingState",props:{text:{type:String,default:"Loading"}},setup(e){return(t,n)=>(S(),q(v(Sl),{circle:"",label:e.text},null,8,["label"]))}},it={__name:"AppEmptyState",props:{title:{type:String,default:"Nothing here"},message:{type:String,default:""}},setup(e){return(t,n)=>(S(),q(v(ep),{title:e.title,text:e.message,icon:"ph-package"},{actions:x(()=>[Ja(t.$slots,"action")]),_:3},8,["title","text"]))}},Fp={class:"page"},Np={key:3,class:"area-favorites-list"},Mp=["onClick"],Up={class:"area-favorite-info"},Vp={class:"area-favorite-title"},jp={class:"area-favorite-meta"},Bp={key:0,class:"area-favorite-parent"},Hp={class:"area-favorite-actions"},Gp={__name:"AreaFavoritesPage",setup(e){const t=kt(),n=xr(),a=en(),s=Q(()=>{const i=new Set(n.ids.map(String));return t.areas.filter(l=>i.has(String(l.id)))});function r(i){if(!i.parent_id)return null;const l=t.areasById[String(i.parent_id)];return(l==null?void 0:l.display_name)||null}function o(i){a.push({name:"area-detail",params:{id:String(i.id)}})}return bt(()=>{t.areas.length===0&&t.loadAreas()}),(i,l)=>{const u=cn("router-link");return S(),G("section",Fp,[$(v(Rt),{title:"Favorites",kicker:"Areas"},{actions:x(()=>[$(v(_e),{variant:"primary"},{default:x(()=>[N(O(s.value.length)+" favorite areas",1)]),_:1})]),_:1}),v(t).isLoading?(S(),q(St,{key:0,text:"Loading areas"})):v(t).error?(S(),q(pt,{key:1,title:"Areas loading failed",error:v(t).error,retry:v(t).loadAreas},null,8,["error","retry"])):s.value.length===0?(S(),q(it,{key:2,title:"No favorite areas",message:"Favorite areas from the current client are preserved through localStorage."})):(S(),G("ul",Np,[(S(!0),G(Ee,null,Vt(s.value,c=>(S(),G("li",{key:c.id,class:"area-favorite-item"},[T("article",{class:"area-favorite-card",onClick:d=>o(c)},[l[2]||(l[2]=T("div",{class:"area-favorite-icon"},[T("i",{class:"ph ph-fill ph-bookmark-simple"})],-1)),T("div",Up,[T("h2",Vp,O(c.display_name),1),T("p",jp,[$(v(_e),{variant:"secondary"},{default:x(()=>[N(O(c.type),1)]),_:2},1024),T("code",null,O(c.alias),1),r(c)?(S(),G("span",Bp,[l[1]||(l[1]=N(" in ",-1)),$(u,{to:{name:"area-detail",params:{id:String(c.parent_id)}},class:"parent-link",onClick:l[0]||(l[0]=Qa(()=>{},["stop"]))},{default:x(()=>[N(O(r(c)),1)]),_:2},1032,["to"])])):ne("",!0)])]),T("div",Hp,[$(Ll,{"area-id":c.id},null,8,["area-id"])])],8,Mp)]))),128))]))])}}},qp=ze(Gp,[["__scopeId","data-v-f8795944"]]);function jt(){const e=Un();return{has:t=>e.hasPermission(t),hasAny:t=>e.hasAnyPermission(t),permissions:e.permissions}}const zp=["disabled","aria-expanded"],Kp={class:"area-tree-info"},Wp={class:"text-muted"},Jp={class:"area-tree-actions"},Yp={key:0,class:"area-tree-children"},Xp={key:1,class:"area-tree-node"},Zp={class:"area-tree-card area-tree-cycle text-danger"},Qp={__name:"AreaTreeNode",props:{area:{type:Object,required:!0},ancestors:{type:Array,default:()=>[]}},setup(e){const t=e,n=en(),a=kt(),s=Q(()=>a.isNodeExpanded(t.area.id)),r=Q(()=>{var c;return!((c=t.area.children)!=null&&c.length)}),o=Q(()=>t.ancestors.includes(String(t.area.id))),i=Q(()=>[...t.ancestors,String(t.area.id)]);function l(){a.toggleNode(t.area.id)}function u(){n.push({name:"area-detail",params:{id:String(t.area.id)}})}return(c,d)=>{var _;const f=cn("AreaTreeNode",!0);return o.value?(S(),G("li",Xp,[T("article",Zp," Cycle skipped for area ID "+O(e.area.id),1)])):(S(),G("li",{key:0,class:Mt(["area-tree-node",{"is-open":s.value,"is-leaf":r.value}])},[T("article",{class:"area-tree-card",onClick:u},[T("button",{class:Mt(["tree-toggle",{"text-primary":!r.value,"text-muted":r.value}]),type:"button",disabled:r.value,"aria-expanded":s.value,onClick:Qa(l,["stop"])},O(r.value?"·":s.value?"−":"+"),11,zp),T("div",Kp,[T("h2",null,O(e.area.display_name),1),T("p",Wp,[$(v(_e),{variant:"secondary"},{default:x(()=>[N(O(e.area.type),1)]),_:1}),T("code",null,O(e.area.alias),1)])]),T("div",Jp,[$(Ll,{"area-id":e.area.id},null,8,["area-id"])])]),(_=e.area.children)!=null&&_.length&&s.value?(S(),G("ul",Yp,[(S(!0),G(Ee,null,Vt(e.area.children,h=>(S(),q(f,{key:h.id,area:h,ancestors:i.value},null,8,["area","ancestors"]))),128))])):ne("",!0)],2))}}},ev={class:"page"},tv={key:3,class:"area-tree"},nv={class:"form-group"},av={class:"form-group"},sv={class:"form-group"},rv={key:0,class:"form-group"},iv={__name:"AreaTreePage",setup(e){const t=kt(),n=wn(),a=jt(),s=J(!1),r=J(!1),o=J(""),i=Zt({type:"",alias:"",display_name:""});function l(){i.type="",i.alias="",i.display_name="",o.value="",s.value=!0}async function u(){var d;r.value=!0,o.value="";const c=await t.createArea({...i});if(r.value=!1,!c.ok){o.value=((d=c.error)==null?void 0:d.message)||"Failed to create area";return}s.value=!1,n.success({title:"Created",text:"Area created successfully"})}return bt(()=>{t.loadAreas()}),(c,d)=>(S(),G("section",ev,[$(v(Rt),{title:"Tree",kicker:"Areas"},{actions:x(()=>[v(a).has("areas.manage")?(S(),q(v(de),{key:0,variant:"primary",icon:"ph-plus",onClick:l},{default:x(()=>[...d[5]||(d[5]=[N("Create area",-1)])]),_:1})):ne("",!0)]),_:1}),v(t).isLoading?(S(),q(St,{key:0,text:"Loading areas tree"})):v(t).error?(S(),q(pt,{key:1,title:"Areas loading failed",error:v(t).error,retry:v(t).loadAreas},null,8,["error","retry"])):v(t).areaTree.length===0?(S(),q(it,{key:2,title:"No areas",message:"No areas found. Create one to get started."})):(S(),G("ul",tv,[(S(!0),G(Ee,null,Vt(v(t).areaTree,f=>(S(),q(Qp,{key:f.id,area:f},null,8,["area"]))),128))])),$(v(at),{open:s.value,title:"Create area","onUpdate:open":d[4]||(d[4]=f=>s.value=f)},{footer:x(()=>[$(v(de),{variant:"secondary",onClick:d[3]||(d[3]=f=>s.value=!1)},{default:x(()=>[...d[6]||(d[6]=[N("Cancel",-1)])]),_:1}),$(v(de),{variant:"primary",icon:"ph-plus",loading:r.value,onClick:u},{default:x(()=>[...d[7]||(d[7]=[N("Create",-1)])]),_:1},8,["loading"])]),default:x(()=>[T("div",nv,[$(v(yt),{modelValue:i.type,"onUpdate:modelValue":d[0]||(d[0]=f=>i.type=f),label:"Type",placeholder:"room"},null,8,["modelValue"])]),T("div",av,[$(v(yt),{modelValue:i.alias,"onUpdate:modelValue":d[1]||(d[1]=f=>i.alias=f),label:"Alias",placeholder:"kitchen"},null,8,["modelValue"])]),T("div",sv,[$(v(yt),{modelValue:i.display_name,"onUpdate:modelValue":d[2]||(d[2]=f=>i.display_name=f),label:"Display name",placeholder:"Kitchen"},null,8,["modelValue"])]),o.value?(S(),G("div",rv,[$(v(Ze),{variant:"danger"},{default:x(()=>[N(O(o.value),1)]),_:1})])):ne("",!0)]),_:1},8,["open"])]))}},ov=ze(iv,[["__scopeId","data-v-5f02f384"]]),lv={device_name:"name",device_hard_id:"device_id",device_ip:"ip",ip_address:"ip",mac_address:"mac",device_mac:"mac",core_version:"firmware_core_version",type:"device_type"};function uv(e){const t={};for(const[n,a]of Object.entries(e||{}))t[lv[n]||n]=a;return t}function qn(e){return encodeURIComponent(String(e))}function cv(e){var n,a,s;if(!e.ok)return e;const t=((a=(n=e.data)==null?void 0:n.data)==null?void 0:a.devices)||[];return{...e,data:{...e.data,data:{...(s=e.data)==null?void 0:s.data,devices:t.map(uv)}}}}const nt={async list(){return cv(await Fe("/api/v1/devices/list"))},status(e,t){return Fe(`/api/v1/devices/id/${qn(e)}/status`,t)},reboot(e){return Fe(`/api/v1/devices/id/${qn(e)}/reboot`)},action(e){return Qe("/api/v1/devices/action",e)},scanningSetup(e){return Fe("/api/v1/devices/scanning/setup",{timeoutMs:12e4,...e})},scanningAll(e){return Fe("/api/v1/devices/scanning/all",{timeoutMs:12e4,...e})},setupNewDevice(e){return Qe("/api/v1/devices/setup/new-device",e)},detail(e,t){return Fe(`/api/v1/devices/id/${qn(e)}`,t)},updateName(e,t){return Qe("/api/v1/devices/update-name",{device_id:e,name:t})},updateDescription(e,t){return Qe("/api/v1/devices/update-description",{device_id:e,description:t})},updateAlias(e,t){return Qe("/api/v1/devices/update-alias",{device_id:e,new_alias:t})},remove(e){return Fe(`/api/v1/devices/id/${qn(e)}/remove`)},resetup(e){return Qe("/api/v1/devices/resetup",{device_id:e})},reset(e){return Qe("/api/v1/devices/reset",{device_id:e})},unassign(e){return Fe(`/api/v1/devices/id/${qn(e)}/unassign-from-area`)},placeInArea(e){return Qe("/api/v1/devices/place-in-area",e)}},dv=4;function Js(e){return String((e==null?void 0:e.id)||"")}function Cr(e,t){return{deviceId:Js(e),status:"idle",message:"",response:null,connectionStatus:(e==null?void 0:e.connection_status)||"unknown",updatedAt:null,...t}}function fv(e,t){var s,r;const a=(((r=(s=t.data)==null?void 0:s.data)==null?void 0:r.device)||{}).device_response||{};return Cr(e,{status:"ready",message:a.status||"ok",response:a,connectionStatus:"active",updatedAt:new Date().toISOString()})}function pv(e,t){var s,r,o;const n=((s=t.error)==null?void 0:s.raw)||{},a=((r=n==null?void 0:n.data)==null?void 0:r.connection_status)||(e==null?void 0:e.connection_status)||"unknown";return Cr(e,{status:"error",message:((o=t.error)==null?void 0:o.message)||"Device state is unavailable",response:n,connectionStatus:a,updatedAt:new Date().toISOString()})}async function vv(e,t,n){let a=0;const s=Math.max(1,Math.min(t,e.length));async function r(){for(;a{const e=J([]),t=J({}),n=J(0),a=J(new Set),s=J(null),r=J(null),o=J(null),i=J(!1),l=J(null),u=gt(),c=gt(),d=Q(()=>e.value.length),f=Q(()=>B=>a.value.has(String(B)));async function _(){return u.execute(async B=>{var Z,Y;const W=await nt.list({signal:B});return W.ok&&(e.value=((Y=(Z=W.data)==null?void 0:Z.data)==null?void 0:Y.devices)||[],o.value=new Date().toISOString()),W})}function h(B,W){const Z=Js(B);Z&&(t.value={...t.value,[Z]:Cr(B,W)})}async function m(B,W,Z){const Y=n.value+1;n.value=Y,i.value=!0,l.value=null,Z&&(t.value={});const te=[];for(const ve of B)ve.connection_status==="lost"?h(ve,{status:"skipped",message:"Connection lost",connectionStatus:"lost"}):(h(ve,{status:"loading",message:"Loading"}),te.push(ve));try{await vv(te,W.concurrency||dv,async ve=>{const ke=await nt.status(ve.id);n.value===Y&&(t.value={...t.value,[Js(ve)]:ke.ok?fv(ve,ke):pv(ve,ke)})})}catch(ve){n.value===Y&&(l.value={type:"state_loader_error",message:(ve==null?void 0:ve.message)||"Device states loader failed"})}finally{n.value===Y&&(i.value=!1)}}async function g(B,W={}){return m(B,W,!1)}async function E(B={}){return m(e.value,B,!0)}async function y(B){const W=String(B);a.value=new Set(a.value).add(W);const Z=await nt.reboot(B),Y=new Set(a.value);return Y.delete(W),a.value=Y,Z}async function w(B){return c.execute(async W=>{var Y,te;const Z=await nt.detail(B,{signal:W});return Z.ok&&(s.value=((te=(Y=Z.data)==null?void 0:Y.data)==null?void 0:te.device)||null),Z})}async function C(B){var te,ve;const W=await nt.status(B);if(!W.ok)return r.value={ok:!1,error:W.error,channels:[]},W;const Y=(((ve=(te=W.data)==null?void 0:te.data)==null?void 0:ve.device)||{}).device_response||{};return r.value={ok:!0,channels:Y.channels||[],raw:Y},W}async function I(B,W){const Z=await nt.updateName(B,W);return Z.ok&&s.value&&(s.value={...s.value,name:W}),Z}async function P(B,W){const Z=await nt.updateDescription(B,W);return Z.ok&&s.value&&(s.value={...s.value,description:W}),Z}async function R(B,W){const Z=await nt.updateAlias(B,W);return Z.ok&&s.value&&(s.value={...s.value,alias:W}),Z}async function L(B){return nt.remove(B)}async function k(B){return nt.resetup(B)}async function ee(B){return nt.reset(B)}async function le(B){const W=await nt.unassign(B);return W.ok&&s.value&&(s.value={...s.value,area_id:null}),W}async function fe(B,W){const Z=await nt.placeInArea({target_id:B,place_in_area_id:W});return Z.ok&&s.value&&(s.value={...s.value,area_id:W}),Z}function ge(){s.value=null,r.value=null,c.clear()}return{devices:e,isLoading:u.isLoading,error:u.error,isLoadingStates:i,stateError:l,stateByDeviceId:t,stateRunId:n,rebootingIds:a,lastLoadedAt:o,currentDevice:s,currentDeviceStatus:r,isLoadingDetail:c.isLoading,errorDetail:c.error,total:d,isRebooting:f,loadDevices:_,setDeviceState:h,loadDeviceStates:E,loadStatesFor:g,rebootDevice:y,loadDeviceDetail:w,loadDeviceStatus:C,updateDeviceName:I,updateDeviceDescription:P,updateDeviceAlias:R,removeDevice:L,unassignDevice:le,assignToArea:fe,resetupDevice:k,resetDevice:ee,clearDeviceDetail:ge}}),Pt={actionsList(e){return Fe("/api/v1/scripts/actions/list",e)},regularList(e){return Fe("/api/v1/scripts/regular/list",e)},scopesList(e){return Fe("/api/v1/scripts/scopes/list",e)},runAction(e,t={}){return Qe("/api/v1/scripts/actions/run",{alias:e,params:t})},setActionState(e,t){return Fe(`/api/v1/scripts/actions/alias/${encodeURIComponent(e)}/${t?"enable":"disable"}`)},setRegularState(e,t){return Fe(`/api/v1/scripts/regular/alias/${encodeURIComponent(e)}/${t?"enable":"disable"}`)},setScopeState(e,t){return Fe(`/api/v1/scripts/scopes/name/${encodeURIComponent(e)}/${t?"enable":"disable"}`)},scopeCode(e,t){return Fe(`/api/v1/scripts/scopes/name/${encodeURIComponent(e)}`,t)},placeInArea(e){return Qe("/api/v1/scripts/place-in-area",e)},unassign(e){return Fe(`/api/v1/scripts/id/${encodeURIComponent(String(e))}/unassign-from-area`)}},Sn=bn("scripts",()=>{const e=J([]),t=J([]),n=J([]),a=J(new Set),s=J(null),r=J(""),o=gt(),i=gt(),l=gt(),u=gt(),c=Q(()=>e.value.length),d=Q(()=>t.value.length),f=Q(()=>n.value.length),_=Q(()=>B=>a.value.has(B)),h=Q(()=>B=>e.value.find(W=>W.alias===B)||null),m=Q(()=>B=>t.value.find(W=>W.alias===B)||null),g=Q(()=>B=>n.value.find(W=>W.name===B)||null),E=Q(()=>B=>e.value.filter(W=>W.scope===B)),y=Q(()=>B=>t.value.filter(W=>W.scope===B));async function w(){return o.execute(async B=>{var Z,Y;const W=await Pt.actionsList({signal:B});return W.ok&&(e.value=((Y=(Z=W.data)==null?void 0:Z.data)==null?void 0:Y.scripts)||[]),W})}async function C(){return i.execute(async B=>{var Z,Y;const W=await Pt.regularList({signal:B});return W.ok&&(t.value=((Y=(Z=W.data)==null?void 0:Z.data)==null?void 0:Y.scripts)||[]),W})}async function I(){return l.execute(async B=>{var Z,Y;const W=await Pt.scopesList({signal:B});return W.ok&&(n.value=((Y=(Z=W.data)==null?void 0:Z.data)==null?void 0:Y.scopes)||[]),W})}async function P(B,W={}){var te,ve,ke,Pe,be,Ge;a.value=new Set(a.value).add(B),s.value=null;const Z=await Pt.runAction(B,W),Y=new Set(a.value);return Y.delete(B),a.value=Y,Z.ok?(s.value={alias:B,ok:!0,data:(ke=(ve=(te=Z.data)==null?void 0:te.data)==null?void 0:ve.return)==null?void 0:ke.result,execTime:(Ge=(be=(Pe=Z.data)==null?void 0:Pe.data)==null?void 0:be.return)==null?void 0:Ge.exec_time},Z):(s.value={alias:B,ok:!1,error:Z.error},Z)}async function R(B,W){const Z=await Pt.setActionState(B,W);if(Z.ok){const Y=e.value.findIndex(te=>te.alias===B);Y!==-1&&(e.value[Y]={...e.value[Y],state:W?"enabled":"disabled"})}return Z}async function L(B,W){const Z=await Pt.setRegularState(B,W);if(Z.ok){const Y=t.value.findIndex(te=>te.alias===B);Y!==-1&&(t.value[Y]={...t.value[Y],state:W?"enabled":"disabled"})}return Z}async function k(B,W){const Z=await Pt.setScopeState(B,W);if(Z.ok){const Y=n.value.findIndex(te=>te.name===B);Y!==-1&&(n.value[Y]={...n.value[Y],state:W?"enabled":"disabled"})}return Z}async function ee(B,W){const Z=await Pt.placeInArea({target_id:B,place_in_area_id:W});if(Z.ok){const Y=e.value.findIndex(ve=>ve.id===B);Y!==-1&&e.value.splice(Y,1,{...e.value[Y],area_id:W});const te=t.value.findIndex(ve=>ve.id===B);te!==-1&&t.value.splice(te,1,{...t.value[te],area_id:W})}return Z}async function le(B){const W=await Pt.unassign(B);if(W.ok){const Z=e.value.findIndex(te=>te.id===B);Z!==-1&&e.value.splice(Z,1,{...e.value[Z],area_id:null});const Y=t.value.findIndex(te=>te.id===B);Y!==-1&&t.value.splice(Y,1,{...t.value[Y],area_id:null})}return W}async function fe(B){return u.execute(async W=>{const Z=await Pt.scopeCode(B,{signal:W});return Z.ok&&(r.value=typeof Z.data=="string"?Z.data:""),Z})}function ge(){r.value="",u.clear()}return{actions:e,regular:t,scopes:n,isLoadingActions:o.isLoading,isLoadingRegular:i.isLoading,isLoadingScopes:l.isLoading,errorActions:o.error,errorRegular:i.error,errorScopes:l.error,runningAliases:a,lastRunResult:s,currentScopeCode:r,isLoadingScopeCode:u.isLoading,errorScopeCode:u.error,totalActions:c,totalRegular:d,totalScopes:f,isRunning:_,actionByAlias:h,regularByAlias:m,scopeByName:g,actionsByScope:E,regularByScope:y,loadActions:w,loadRegular:C,loadScopes:I,runScript:P,setActionState:R,setRegularState:L,setScopeState:k,assignToArea:ee,unassignFromArea:le,loadScopeCode:fe,clearScopeCode:ge}});function Er(){const e=kt(),t=J(""),n=Q(()=>e.areas.filter(u=>String(u.id)!==String(t.value)).map(u=>({value:String(u.id),label:`${u.display_name} (${u.type})`}))),a=J(!1),s=J(""),r=J(!1),o=J("");function i(u){s.value=u?String(u):"",t.value=u?String(u):"",o.value="",a.value=!0}async function l(u,c){var f;if(!u||!c)return;r.value=!0,o.value="";const d=await c(u,s.value);return r.value=!1,d.ok?(a.value=!1,d):(o.value=((f=d.error)==null?void 0:f.message)||"Failed to assign area",d)}return{areaOptions:n,showAssignModal:a,selectedAreaId:s,assignLoading:r,assignError:o,openAssign:i,submitAssignCore:l}}const gv={key:1,class:"text-muted",style:{"font-size":"13px"}},hv={__name:"AreaBadgeLink",props:{area:{type:Object,default:null},areaId:{type:[Number,String],default:null}},setup(e){return(t,n)=>{const a=cn("router-link");return e.area?(S(),q(a,{key:0,to:{name:"area-detail",params:{id:e.area.id}},class:"area-link"},{default:x(()=>[$(v(_e),{variant:"info"},{default:x(()=>[N(O(e.area.display_name),1)]),_:1})]),_:1},8,["to"])):e.areaId?(S(),G("span",gv,"Area ID: "+O(e.areaId),1)):ne("",!0)}}},Rr=ze(hv,[["__scopeId","data-v-91230b95"]]),mv={class:"devices-panel"},yv={class:"block-title"},_v={key:0,class:"area-assigned"},bv={class:"area-card-info"},wv={class:"text-muted"},Sv={__name:"AreaAssignSection",props:{item:{type:Object,default:null},areaId:{type:[Number,String],default:null},title:{type:String,default:"Area"},emptyMessage:{type:String,default:"This item is not assigned to any area."}},emits:["assign"],setup(e,{emit:t}){const n=e,a=t,s=kt(),r=Q(()=>{var i;const o=n.areaId!=null?n.areaId:(i=n.item)==null?void 0:i.area_id;return o&&s.areasById[String(o)]||null});return(o,i)=>{const l=cn("router-link");return S(),G("div",mv,[T("div",yv,O(e.title),1),r.value?(S(),G("div",_v,[$(l,{to:{name:"area-detail",params:{id:r.value.id}},class:"area-card"},{default:x(()=>[i[1]||(i[1]=T("div",{class:"area-card-icon text-primary"},[T("i",{class:"ph ph-map-trifold"})],-1)),T("div",bv,[T("strong",null,O(r.value.display_name),1),T("small",wv,O(r.value.type)+" — "+O(r.value.alias),1)])]),_:1},8,["to"])])):(S(),q(it,{key:1,title:"Not assigned",message:e.emptyMessage},{action:x(()=>[Ja(o.$slots,"action",{},()=>[$(v(de),{variant:"primary",icon:"ph-map-pin",onClick:i[0]||(i[0]=u=>a("assign"))},{default:x(()=>[...i[2]||(i[2]=[N("Assign to area",-1)])]),_:1})],!0)]),_:3},8,["message"]))])}}},$r=ze(Sv,[["__scopeId","data-v-92cae82c"]]);function Dl(e){if(!e)return"";const t=Ol(e);if(!t)return e;const a=new Date-t,s=Math.floor(a/1e3),r=Math.floor(s/60),o=Math.floor(r/60),i=Math.floor(o/24),l=Math.floor(i/7),u=Math.floor(i/30);if(s<10)return"just now";if(s<60)return`${s} sec ago`;if(r<60)return`${r} min ago`;if(o<24){const d=r%60;return d>0?`${o} hour${o>1?"s":""} ${d} min ago`:`${o} hour${o>1?"s":""} ago`}if(i<7)return`${i} day${i>1?"s":""} ago`;if(l<4)return`${l} week${l>1?"s":""} ago`;if(u<12)return`${u} month${u>1?"s":""} ago`;const c=Math.floor(i/365);return`${c} year${c>1?"s":""} ago`}function Ys(e){if(!e)return"";const t=Ol(e);if(!t)return e;const a=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"][t.getMonth()],s=t.getDate(),r=t.getFullYear(),o=String(t.getHours()).padStart(2,"0"),i=String(t.getMinutes()).padStart(2,"0");return`${a} ${s}, ${r} ${o}:${i}`}function Ol(e){if(!e)return null;const t=/^(\d{4})-(\d{2})-(\d{2})\s+(\d{2}):(\d{2}):(\d{2})$/,n=e.match(t);if(n){const[,s,r,o,i,l,u]=n;return new Date(s,parseInt(r)-1,o,i,l,u)}const a=new Date(e);return isNaN(a.getTime())?null:a}const kv={class:"device-channels-state"},Av={key:3,class:"channels-grid"},xv={key:0,class:"ph ph-caret-up"},Cv={key:1,class:"ph ph-caret-down"},Ev={key:0,class:"ph ph-caret-up"},Rv={key:1,class:"ph ph-caret-down"},$v={key:0,class:"ph ph-caret-up"},Tv={key:1,class:"ph ph-caret-down"},Pv={key:0,class:"ph ph-caret-up"},Iv={key:1,class:"ph ph-caret-down"},Lv={key:0,class:"ph ph-caret-up"},Dv={key:1,class:"ph ph-caret-down"},Ov={key:0,class:"raw-json text-muted"},Fv={__name:"DeviceChannelsState",props:{deviceType:{type:String,default:""},response:{type:Object,default:null},loading:{type:Boolean,default:!1},error:{type:[String,Object],default:null},connectionStatus:{type:String,default:"unknown"}},setup(e){const t=e,n=Q(()=>t.connectionStatus==="lost"),a=Q(()=>{var h;return((h=t.response)==null?void 0:h.channels)||[]}),s=Q(()=>{var h;return((h=t.response)==null?void 0:h.sensors)||{}}),r=Q(()=>{var h,m;return((m=(h=t.response)==null?void 0:h.hatch)==null?void 0:m.state)||"—"}),o=Q(()=>{var h,m;return((m=(h=t.response)==null?void 0:h.hatch)==null?void 0:m.position_pct)??"—"}),i=Q(()=>String(r.value).includes("open")?"warning":"primary"),l=Q(()=>String(r.value).includes("open")),u=Q(()=>{var h;return((h=t.response)==null?void 0:h.status)==="ok"}),c=Q(()=>{if(!t.response)return"";try{return JSON.stringify(t.response).slice(0,200)}catch{return""}}),d=Q(()=>{var h;return u.value?t.deviceType==="relay"||t.deviceType==="button"?a.value.length>0:t.deviceType==="sensor"?Object.keys(s.value).length>0:t.deviceType==="hatch"?!!((h=t.response)!=null&&h.hatch):!1:!1});function f(h){return h.id??h.channel}function _(h){return{enabled:"success",disabled:"secondary",mute:"primary",waiting:"warning",error:"danger"}[h]||"secondary"}return(h,m)=>(S(),G("div",kv,[e.loading?(S(),q(v(Sl),{key:0,circle:"",size:"sm",label:"Loading state"})):n.value?(S(),q(v(_e),{key:1,variant:"danger",size:"sm"},{default:x(()=>[...m[0]||(m[0]=[T("i",{class:"ph ph-wifi-slash"},null,-1),N(" Offline ",-1)])]),_:1})):e.error||!u.value?(S(),q(v(_e),{key:2,variant:"danger",size:"sm"},{default:x(()=>[m[1]||(m[1]=T("i",{class:"ph ph-warning-octagon"},null,-1)),typeof e.error=="string"?(S(),G(Ee,{key:0},[N(O(e.error),1)],64)):(S(),G(Ee,{key:1},[N("Error")],64))]),_:1})):d.value?(S(),G("div",Av,[e.deviceType==="relay"?(S(!0),G(Ee,{key:0},Vt(a.value,g=>(S(),q(v(_e),{key:f(g),variant:g.state==="on"||g.state===!0?"success":"secondary",size:"sm"},{default:x(()=>[a.value.length>1?(S(),G(Ee,{key:0},[N(O(f(g))+": ",1)],64)):ne("",!0),T("b",null,O(g.state=="off"?"OFF":"ON"),1)]),_:2},1032,["variant"]))),128)):e.deviceType==="button"?(S(!0),G(Ee,{key:1},Vt(a.value,g=>(S(),q(v(_e),{key:f(g),variant:_(g.indicator),size:"sm"},{default:x(()=>[N(O(f(g))+": ",1),T("b",null,O(g.indicator),1)]),_:2},1032,["variant"]))),128)):e.deviceType==="sensor"?(S(),G(Ee,{key:2},[s.value.radar?(S(),q(v(_e),{key:0,variant:"primary",size:"sm"},{default:x(()=>[T("i",{class:Mt(["ph",s.value.radar.presence?"ph-user-square":"ph-square"])},null,2),s.value.radar.presence?(S(),G(Ee,{key:0},[N(O(s.value.radar.activity_score)+" ",1),s.value.radar.activity_score_dynamics==="increasing"?(S(),G("i",xv)):s.value.radar.activity_score_dynamics==="decreasing"?(S(),G("i",Cv)):ne("",!0)],64)):ne("",!0)]),_:1})):ne("",!0),s.value.temperature?(S(),q(v(_e),{key:1,variant:"primary",size:"sm"},{default:x(()=>[m[2]||(m[2]=T("i",{class:"ph ph-thermometer"},null,-1)),N(" "+O(s.value.temperature.current)+"°C ",1),s.value.temperature.dynamics==="increasing"?(S(),G("i",Ev)):s.value.temperature.dynamics==="decreasing"?(S(),G("i",Rv)):ne("",!0)]),_:1})):ne("",!0),s.value.humidity?(S(),q(v(_e),{key:2,variant:"primary",size:"sm"},{default:x(()=>[m[3]||(m[3]=T("i",{class:"ph ph-drop-half-bottom"},null,-1)),N(" "+O(s.value.humidity.current)+"% ",1),s.value.humidity.dynamics==="increasing"?(S(),G("i",$v)):s.value.humidity.dynamics==="decreasing"?(S(),G("i",Tv)):ne("",!0)]),_:1})):ne("",!0),s.value.pressure?(S(),q(v(_e),{key:3,variant:"primary",size:"sm"},{default:x(()=>[N(O(s.value.pressure.current)+"hpa ",1),s.value.pressure.dynamics==="increasing"?(S(),G("i",Pv)):s.value.pressure.dynamics==="decreasing"?(S(),G("i",Iv)):ne("",!0)]),_:1})):ne("",!0),s.value.light?(S(),q(v(_e),{key:4,variant:"primary",size:"sm"},{default:x(()=>[m[4]||(m[4]=T("i",{class:"ph ph-lightbulb"},null,-1)),N(" "+O(s.value.light.percent)+"% ",1)]),_:1})):ne("",!0),s.value.microphone?(S(),q(v(_e),{key:5,variant:"primary",size:"sm"},{default:x(()=>[m[5]||(m[5]=T("i",{class:"ph ph-ear"},null,-1)),N(" "+O(s.value.microphone.current_noise)+"dBi ",1),s.value.microphone.noise_dynamics==="increasing"?(S(),G("i",Lv)):s.value.microphone.noise_dynamics==="decreasing"?(S(),G("i",Dv)):ne("",!0)]),_:1})):ne("",!0)],64)):e.deviceType==="hatch"?(S(),q(v(_e),{key:3,variant:i.value,size:"sm"},{default:x(()=>[N(O(r.value)+" ",1),l.value?(S(),G(Ee,{key:0},[N(" - "+O(o.value)+"%",1)],64)):ne("",!0)]),_:1},8,["variant"])):(S(),G(Ee,{key:4},[m[6]||(m[6]=T("span",{class:"unknown-type text-muted"},"Unknown type",-1)),c.value?(S(),G("pre",Ov,O(c.value),1)):ne("",!0)],64))])):(S(),q(v(_e),{key:4,variant:"secondary",size:"sm"},{default:x(()=>[...m[7]||(m[7]=[N("No data",-1)])]),_:1}))]))}},Fl=ze(Fv,[["__scopeId","data-v-08541c71"]]),Nv={class:"device-cell"},Mv=["innerHTML"],Uv={class:"device-info"},Vv={class:"device-name-row"},jv=["title"],Bv={class:"text-muted"},Hv=["title"],Gv={key:1,class:"text-muted"},qv={__name:"DeviceTable",props:{devices:{type:Array,required:!0},showActions:{type:Boolean,default:!0},showLastContact:{type:Boolean,default:!0},caption:{type:String,default:"Devices"}},setup(e){const t=e,n=os(),a=wn(),s=jt(),r={relay:'',button:'',sensor:''},o=Q(()=>{const d=[{key:"device",label:"Device"},{key:"state",label:"State"}];return t.showLastContact&&d.push({key:"lastContact",label:"Last Contact"}),t.showActions&&d.push({key:"actions",label:"Actions"}),d});function i(d){return r[d]||r.relay}function l(d){return{active:"success",removed:"danger",freezed:"warning",setup:"primary"}[d]||"secondary"}function u(d){return n.stateByDeviceId[String(d.id)]||{status:"idle",message:"Not loaded",connectionStatus:d.connection_status||"unknown"}}async function c(d){var h;const f=t.devices.find(m=>String(m.id)===String(d)),_=await n.rebootDevice(d);_.ok?a.success({title:"Rebooting",text:`Device ${(f==null?void 0:f.name)||(f==null?void 0:f.alias)||"#"+d} is rebooting`}):a.error({title:"Reboot failed",text:((h=_.error)==null?void 0:h.message)||"Failed to reboot device"})}return(d,f)=>{const _=cn("router-link");return S(),q(v(Nn),{columns:o.value,rows:e.devices,caption:e.caption},Oo({"cell-device":x(({row:h})=>[$(_,{to:{name:"device-detail",params:{id:String(h.id)}},class:"device-link"},{default:x(()=>[T("div",Nv,[T("div",{class:"device-icon text-primary",innerHTML:i(h.device_type)},null,8,Mv),T("div",Uv,[T("div",Vv,[T("strong",null,O(h.name||h.alias||`Device #${h.id}`),1),h.status&&h.status!=="active"?(S(),q(v(_e),{key:0,variant:l(h.status),size:"sm"},{default:x(()=>[N(O(h.status),1)]),_:2},1032,["variant"])):ne("",!0),T("span",{class:Mt(["status-dot",{"text-success":h.connection_status==="active","text-danger":h.connection_status!=="active"}]),"aria-hidden":"true",title:h.connection_status==="active"?"Online":"Offline"},null,10,jv)]),T("small",Bv,O(h.alias)+" — "+O(h.device_ip||"—"),1)])])]),_:2},1032,["to"])]),"cell-state":x(({row:h})=>[$(Fl,{"device-type":h.device_type,response:u(h).response,loading:u(h).status==="loading",error:u(h).status==="error"?u(h).message:null,"connection-status":h.connection_status||"unknown"},null,8,["device-type","response","loading","error","connection-status"])]),"cell-lastContact":x(({row:h})=>[h.last_contact?(S(),G("span",{key:0,title:v(Ys)(h.last_contact)},O(v(Dl)(h.last_contact)),9,Hv)):(S(),G("span",Gv,"—"))]),_:2},[e.showActions&&v(s).has("devices.control")?{name:"cell-actions",fn:x(({row:h})=>[$(v(de),{variant:"warning",icon:"ph-arrow-clockwise",size:"sm",loading:v(n).isRebooting(h.id),onClick:m=>c(h.id)},{default:x(()=>[...f[0]||(f[0]=[N(" Reboot ",-1)])]),_:1},8,["loading","onClick"])]),key:"0"}:void 0]),1032,["columns","rows","caption"])}}},Nl=ze(qv,[["__scopeId","data-v-32549911"]]),zv={class:"scope-name"},Kv={key:1,class:"muted"},Wv={key:1,class:"muted"},Jv={__name:"ScriptTable",props:{scripts:{type:Array,required:!0},scriptType:{type:String,default:"regular"},showArea:{type:Boolean,default:!1},showScope:{type:Boolean,default:!0},showFilename:{type:Boolean,default:!0},showActions:{type:Boolean,default:!0},caption:{type:String,default:"Scripts"}},setup(e){const t=e,n=Sn(),a=kt(),s=jt(),r=Q(()=>{const c={};for(const d of a.areas)c[d.id]=d;return c});function o(c){var d;return c.area_id?((d=r.value[c.area_id])==null?void 0:d.display_name)||`Area ${c.area_id}`:null}function i(c){const d=c.type||t.scriptType;return d==="action"?"actions":d==="scope"?"scopes":d}const l=Q(()=>{const c=[{key:"alias",label:"Alias"},{key:"name",label:"Name"}];return t.showScope&&c.push({key:"scope",label:"Scope"}),t.showArea&&c.push({key:"area",label:"Area"}),c.push({key:"state",label:"State"}),t.showFilename&&c.push({key:"filename",label:"File"}),t.showActions&&c.push({key:"actions",label:"Actions"}),c});function u(c,d,f){const _=f.type||t.scriptType;_==="action"?n.setActionState(c,d):_==="regular"&&n.setRegularState(c,d)}return(c,d)=>{const f=cn("router-link");return S(),q(v(Nn),{columns:l.value,rows:e.scripts,caption:e.caption},Oo({"cell-alias":x(({row:_})=>[$(f,{to:{name:"script-detail",params:{type:i(_),id:_.alias}},class:"script-link"},{default:x(()=>[N(O(_.alias),1)]),_:2},1032,["to"])]),"cell-scope":x(({row:_})=>[_.scope?(S(),q(f,{key:0,to:{name:"script-detail",params:{type:"scopes",id:_.scope}},class:"scope-link"},{default:x(()=>[d[0]||(d[0]=T("span",{class:"scope-label"},"Scope",-1)),T("span",zv,O(_.scope),1),d[1]||(d[1]=T("i",{class:"ph ph-arrow-right"},null,-1))]),_:2},1032,["to"])):(S(),G("span",Kv,"—"))]),"cell-area":x(({row:_})=>[_.area_id?(S(),q(v(_e),{key:0,variant:"primary"},{default:x(()=>[N(O(o(_)),1)]),_:2},1024)):(S(),G("span",Wv,"—"))]),"cell-state":x(({row:_})=>[$(v(_e),{variant:_.state==="enabled"?"success":"secondary"},{default:x(()=>[N(O(_.state),1)]),_:2},1032,["variant"])]),_:2},[e.showActions&&v(s).has("scripts.edit")?{name:"cell-actions",fn:x(({row:_})=>[_.state==="enabled"?(S(),q(v(de),{key:0,variant:"secondary",icon:"ph-pause",onClick:h=>u(_.alias,!1,_)},{default:x(()=>[...d[2]||(d[2]=[N(" Disable ",-1)])]),_:1},8,["onClick"])):(S(),q(v(de),{key:1,variant:"primary",icon:"ph-play",onClick:h=>u(_.alias,!0,_)},{default:x(()=>[...d[3]||(d[3]=[N(" Enable ",-1)])]),_:1},8,["onClick"]))]),key:"0"}:void 0]),1032,["columns","rows","caption"])}}},Ml=ze(Jv,[["__scopeId","data-v-1ead75a7"]]),Yv={class:"page-actions-dropdown"},Xv=["aria-expanded","onClick"],Tr={__name:"PageActionsDropdown",props:{items:{type:Array,required:!0}},setup(e){return(t,n)=>(S(),G("div",Yv,[$(v(Qf),tl({items:e.items},t.$attrs),{trigger:x(({toggle:a,open:s})=>[T("button",{class:"btn-icon",type:"button","aria-label":"Actions","aria-expanded":s?"true":"false",onClick:a},[...n[0]||(n[0]=[T("i",{class:"ph ph-dots-three-vertical"},null,-1)])],8,Xv)]),_:1},16,["items"])]))}},Zv={key:0,class:"script-run-form"},Qv={key:6,class:"field-error"},eg={__name:"ScriptRunModal",props:{open:{type:Boolean,default:!1},script:{type:Object,default:null}},emits:["update:open","run"],setup(e,{emit:t}){const n=e,a=t,s=J({}),r=J(new Set);function o(h,m){switch(h){case"text":case"textarea":return"";case"number":return 0;case"range":return m.min??0;case"select":{const g=Object.keys(m.options||{});return g.length?g[0]:""}case"toggle":return!1;default:return""}}function i(){var m;if(r.value=new Set,!((m=n.script)!=null&&m.params_schema)){s.value={};return}const h={};for(const[g,E]of Object.entries(n.script.params_schema))h[g]=E.default!==void 0?E.default:o(E.type,E);s.value=h}wt(()=>n.open,h=>{h&&i()},{immediate:!0});function l(h){return h?Object.entries(h).map(([m,g])=>({value:m,label:g})):[]}function u(h,m){const g=s.value[h];return g==null?!0:m.type==="text"||m.type==="textarea"?String(g).trim()==="":!1}function c(h,m){return r.value.has(h)&&m.required&&u(h,m)?"error":null}function d(h,m){return r.value.has(h)&&m.required&&u(h,m)?`${m.label||h} is required`:null}const f=Q(()=>{var h;if(!((h=n.script)!=null&&h.params_schema))return!0;for(const[m,g]of Object.entries(n.script.params_schema))if(g.required&&u(m,g))return!1;return!0});function _(){var h;for(const m of Object.keys(((h=n.script)==null?void 0:h.params_schema)||{}))r.value.add(m);f.value&&(a("run",{alias:n.script.alias,params:{...s.value}}),a("update:open",!1))}return(h,m)=>{var g,E;return S(),q(v(at),{open:e.open,title:`Run: ${((g=e.script)==null?void 0:g.name)??((E=e.script)==null?void 0:E.alias)??""}`,"onUpdate:open":m[1]||(m[1]=y=>h.$emit("update:open",y))},{footer:x(()=>[$(v(de),{variant:"secondary",onClick:m[0]||(m[0]=y=>h.$emit("update:open",!1))},{default:x(()=>[...m[2]||(m[2]=[N(" Cancel ",-1)])]),_:1}),$(v(de),{variant:"primary",icon:"ph-play",disabled:!f.value,onClick:_},{default:x(()=>[...m[3]||(m[3]=[N(" Run ",-1)])]),_:1},8,["disabled"])]),default:x(()=>{var y;return[(y=e.script)!=null&&y.params_schema?(S(),G("div",Zv,[(S(!0),G(Ee,null,Vt(e.script.params_schema,(w,C)=>(S(),G("div",{key:C,class:"form-field"},[w.type==="text"?(S(),q(v(yt),{key:0,modelValue:s.value[C],"onUpdate:modelValue":I=>s.value[C]=I,label:w.label||C,placeholder:w.placeholder||"",state:c(C,w)},null,8,["modelValue","onUpdate:modelValue","label","placeholder","state"])):w.type==="number"?(S(),q(v(yt),{key:1,modelValue:s.value[C],"onUpdate:modelValue":I=>s.value[C]=I,modelModifiers:{number:!0},type:"number",label:w.label||C,placeholder:w.placeholder||"",state:c(C,w)},null,8,["modelValue","onUpdate:modelValue","label","placeholder","state"])):w.type==="range"?(S(),q(v(op),{key:2,modelValue:s.value[C],"onUpdate:modelValue":I=>s.value[C]=I,modelModifiers:{number:!0},label:w.label||C,min:w.min??0,max:w.max??100,step:w.step??1,state:c(C,w)},null,8,["modelValue","onUpdate:modelValue","label","min","max","step","state"])):w.type==="select"?(S(),q(v(rs),{key:3,modelValue:s.value[C],"onUpdate:modelValue":I=>s.value[C]=I,label:w.label||C,options:l(w.options),state:c(C,w)},null,8,["modelValue","onUpdate:modelValue","label","options","state"])):w.type==="toggle"?(S(),q(v(kl),{key:4,modelValue:s.value[C],"onUpdate:modelValue":I=>s.value[C]=I,label:w.label||C},null,8,["modelValue","onUpdate:modelValue","label"])):w.type==="textarea"?(S(),q(v(lp),{key:5,modelValue:s.value[C],"onUpdate:modelValue":I=>s.value[C]=I,label:w.label||C,placeholder:w.placeholder||"",state:c(C,w)},null,8,["modelValue","onUpdate:modelValue","label","placeholder","state"])):ne("",!0),d(C,w)?(S(),G("p",Qv,O(d(C,w)),1)):ne("",!0)]))),128))])):ne("",!0)]}),_:1},8,["open","title"])}}},Ul=ze(eg,[["__scopeId","data-v-c51fae66"]]),tg={class:"area-grid"},ng=["innerHTML"],ag={key:1},sg={class:"script-meta"},rg={key:2},ig={__name:"ActionScriptsGrid",props:{scripts:{type:Array,required:!0},showAreaBadge:{type:Boolean,default:!1}},emits:["run-success"],setup(e,{emit:t}){const n=e,a=t,s=en(),r=Sn(),o=kt(),i=wn(),l=jt(),u=J(!1),c=J(null);function d(m){return!m.area_id||!n.showAreaBadge?null:o.areas.find(g=>g.id===m.area_id)||null}function f(m){const g=m.params_schema;if(g&&Object.keys(g).length>0){c.value=m,u.value=!0;return}_(m.alias,{})}async function _(m,g){var y,w;const E=await r.runScript(m,g);E!=null&&E.ok?(i.success({title:`Ran ${m}`,text:(y=r.lastRunResult)!=null&&y.execTime?`Exec time: ${r.lastRunResult.execTime}`:void 0}),a("run-success",{alias:m})):i.error({title:`Failed ${m}`,text:((w=E==null?void 0:E.error)==null?void 0:w.message)||"Unknown error"})}function h(m){s.push({name:"script-detail",params:{type:"actions",id:m}})}return(m,g)=>(S(),G(Ee,null,[T("div",tg,[(S(!0),G(Ee,null,Vt(e.scripts,E=>(S(),q(v(Jf),{key:E.alias,title:E.name,onClick:y=>h(E.alias)},{default:x(()=>[E.icon?(S(),G("div",{key:0,innerHTML:E.icon,class:"script-icon"},null,8,ng)):ne("",!0),E.description?(S(),G("p",ag,O(E.description),1)):ne("",!0),T("div",sg,[$(v(_e),{variant:E.state==="enabled"?"success":"secondary"},{default:x(()=>[N(O(E.state),1)]),_:2},1032,["variant"]),E.scope?(S(),q(v(_e),{key:0,variant:"primary"},{default:x(()=>[N(O(E.scope),1)]),_:2},1024)):ne("",!0),e.showAreaBadge&&d(E)?(S(),q(v(_e),{key:1,variant:"primary"},{default:x(()=>[N(O(d(E).display_name),1)]),_:2},1024)):ne("",!0)]),E.created_by||E.author?(S(),G("small",rg,O(E.created_by||E.author),1)):ne("",!0)]),actions:x(()=>[v(l).has("scripts.run")?(S(),q(v(de),{key:0,variant:"primary",icon:"ph-play",loading:v(r).isRunning(E.alias),disabled:E.state!=="enabled",onClick:Qa(y=>f(E),["stop"])},{default:x(()=>[...g[2]||(g[2]=[N(" Run ",-1)])]),_:1},8,["loading","disabled","onClick"])):ne("",!0)]),_:2},1032,["title","onClick"]))),128))]),c.value?(S(),q(Ul,{key:0,open:u.value,script:c.value,"onUpdate:open":g[0]||(g[0]=E=>u.value=E),onRun:g[1]||(g[1]=E=>_(E.alias,E.params))},null,8,["open","script"])):ne("",!0)],64))}},Vl=ze(ig,[["__scopeId","data-v-1576dd59"]]),og={class:"page"},lg={key:3},ug={class:"area-meta"},cg={class:"actions-panel"},dg={class:"block-title"},fg={class:"devices-panel"},pg={class:"block-title"},vg={class:"scripts-panel"},gg={class:"block-title"},hg={class:"form-group"},mg={key:0,class:"form-group"},yg={key:1,class:"form-group"},_g={key:2,class:"form-group"},bg={key:0,class:"form-group"},wg={key:0,class:"form-group"},Sg={__name:"AreaDetailPage",setup(e){const t=as(),n=en(),a=kt(),s=os(),r=xr();Sn();const o=wn(),i=jt(),{showAssignModal:l,selectedAreaId:u,assignLoading:c,assignError:d,openAssign:f,submitAssignCore:_}=Er(),h=Q(()=>a.areasById[String(t.params.id)]||null),m=Q(()=>h.value?r.has(h.value.id):!1),g=Q(()=>{var F;const H=[];return i.has("areas.manage")&&(H.push({label:"Rename",icon:"ph-pencil",onSelect:ve}),((F=h.value)==null?void 0:F.parent_id)>0?H.push({label:"Change parent area",icon:"ph-map-pin",onSelect:Ge},{label:"Unassign from parent",icon:"ph-x-circle",onSelect:De}):H.push({label:"Assign to area",icon:"ph-map-pin",onSelect:Ge})),H.push({label:m.value?"Remove bookmark":"Bookmark",icon:m.value?"ph-fill ph-bookmark-simple":"ph-bookmark-simple",onSelect:()=>{var U;return r.toggle((U=h.value)==null?void 0:U.id)}}),i.has("areas.manage")&&H.push({label:"Remove",icon:"ph-trash",danger:!0,onSelect:Pe}),H}),E=Q(()=>!h.value||h.value.parent_id<=0?null:a.areasById[String(h.value.parent_id)]||null),y=Q(()=>a.currentAreaScripts.filter(H=>H.type==="action")),w=Q(()=>a.currentAreaScripts.filter(H=>H.type!=="action")),C=Q(()=>{if(!h.value)return!1;const H=!h.value.parent_id||h.value.parent_id<=0,F=a.areas.filter(U=>!U.parent_id||U.parent_id<=0).length;return H&&F===1});function I(H){const F=new Set,U=[H];for(;U.length;){const p=U.shift(),b=a.areas.filter(A=>A.parent_id===p);for(const A of b)F.add(A.id),U.push(A.id)}return F}const P=Q(()=>{if(!h.value)return[];const H=new Set([h.value.id,...I(h.value.id)]);return a.areas.filter(F=>!H.has(F.id)).map(F=>({value:String(F.id),label:`${F.display_name} (${F.type})`}))}),R=J(!1),L=J(!1),k=J(""),ee=Zt({areaId:null,display_name:""}),le=J(!1),fe=J(""),ge=J(!1),B=J(""),W=J(!1),Z=J(""),Y=J(!1),te=J("");function ve(){h.value&&(ee.areaId=h.value.id,ee.display_name=h.value.display_name,k.value="",R.value=!0)}async function ke(){var F;L.value=!0,k.value="";const H=await a.renameArea(ee.areaId,ee.display_name);if(L.value=!1,!H.ok){k.value=((F=H.error)==null?void 0:F.message)||"Failed to rename area";return}R.value=!1,o.success({title:"Renamed",text:"Area renamed successfully"})}function Pe(){h.value&&(fe.value=`Are you sure you want to remove area "${h.value.display_name}"?`,B.value="",le.value=!0)}async function be(){var F;if(!h.value)return;ge.value=!0,B.value="";const H=await a.removeArea(h.value.id);if(ge.value=!1,!H.ok){B.value=((F=H.error)==null?void 0:F.message)||"Failed to remove area";return}le.value=!1,o.success({title:"Removed",text:"Area removed successfully"}),n.push({name:"areas-tree"})}function Ge(){var H;f(((H=h.value)==null?void 0:H.parent_id)>0?h.value.parent_id:"")}async function Ue(){var U;const H=(U=h.value)==null?void 0:U.id,F=await _(H,(p,b)=>a.assignToArea(p,b));F!=null&&F.ok&&o.success({title:"Assigned",text:"Area assigned successfully"})}function De(){h.value&&(Z.value=`Are you sure you want to unassign area "${h.value.display_name}" from its parent?`,te.value="",W.value=!0)}async function Oe(){var F;if(!h.value)return;Y.value=!0,te.value="";const H=await a.unassignArea(h.value.id);if(Y.value=!1,!H.ok){te.value=((F=H.error)==null?void 0:F.message)||"Failed to unassign area";return}W.value=!1,o.success({title:"Unassigned",text:"Area unassigned from parent successfully"})}async function M(){a.currentAreaDevices.length>0&&await s.loadStatesFor(a.currentAreaDevices)}async function se(){const H=t.params.id;H&&(a.areas.length===0&&await a.loadAreas(),a.areasById[String(H)]&&(await a.loadAreaDetail(H),await M()))}return wt(()=>t.params.id,async(H,F)=>{H&&H!==F&&await se()},{immediate:!1}),bt(()=>{se()}),ha(()=>{a.clearAreaDetail()}),(H,F)=>(S(),G("section",og,[v(a).isLoading||v(a).isLoadingAreaDetail?(S(),q(St,{key:0,text:"Loading area"})):v(a).error&&!v(a).areas.length?(S(),q(pt,{key:1,title:"Areas loading failed",error:v(a).error,retry:se},null,8,["error"])):v(a).errorAreaDetail?(S(),q(pt,{key:2,title:"Area loading failed",error:v(a).errorAreaDetail,retry:se},null,8,["error"])):h.value?(S(),G("div",lg,[$(v(Rt),{title:h.value.display_name,kicker:"Area"},{actions:x(()=>[$(Tr,{items:g.value},null,8,["items"])]),_:1},8,["title"]),T("div",ug,[$(v(_e),{variant:"secondary"},{default:x(()=>[N(O(h.value.type),1)]),_:1}),T("code",null,O(h.value.alias),1),$(Rr,{area:E.value,areaId:h.value.parent_id},null,8,["area","areaId"])]),T("div",cg,[T("div",dg,"Actions ("+O(y.value.length)+")",1),y.value.length===0?(S(),q(it,{key:0,title:"No actions",message:"No action scripts assigned to this area."})):(S(),q(Vl,{key:1,scripts:y.value,onRunSuccess:M},null,8,["scripts"]))]),T("div",fg,[T("div",pg,"Devices ("+O(v(a).currentAreaDevices.length)+")",1),v(a).currentAreaDevices.length===0?(S(),q(it,{key:0,title:"No devices",message:"No devices assigned to this area."})):(S(),q(Nl,{key:1,devices:v(a).currentAreaDevices,caption:"Area devices"},null,8,["devices"]))]),$($r,{areaId:h.value.parent_id>0?h.value.parent_id:null,title:"Parent area",emptyMessage:"This area is not assigned to any parent area.",onAssign:Ge},{action:x(()=>[v(i).has("areas.manage")?(S(),q(v(de),{key:0,variant:"primary",icon:"ph-map-pin",onClick:Ge},{default:x(()=>[N(O(h.value.parent_id>0?"Change parent area":"Assign to area"),1)]),_:1})):ne("",!0)]),_:1},8,["areaId"]),T("div",vg,[T("div",gg,"Regular scripts ("+O(w.value.length)+")",1),w.value.length===0?(S(),q(it,{key:0,title:"No regular scripts",message:"No regular scripts assigned to this area."})):(S(),q(Ml,{key:1,scripts:w.value,scriptType:"regular",showArea:!1,showActions:!1,showFilename:!1,caption:"Area regular scripts"},null,8,["scripts"]))])])):(S(),q(it,{key:4,title:"Area not found",message:"The requested area does not exist."})),$(v(at),{open:R.value,title:"Rename area","onUpdate:open":F[2]||(F[2]=U=>R.value=U)},{footer:x(()=>[$(v(de),{variant:"secondary",onClick:F[1]||(F[1]=U=>R.value=!1)},{default:x(()=>[...F[10]||(F[10]=[N("Cancel",-1)])]),_:1}),$(v(de),{variant:"primary",icon:"ph-check",loading:L.value,onClick:ke},{default:x(()=>[...F[11]||(F[11]=[N("Rename",-1)])]),_:1},8,["loading"])]),default:x(()=>[T("div",hg,[$(v(yt),{modelValue:ee.display_name,"onUpdate:modelValue":F[0]||(F[0]=U=>ee.display_name=U),label:"Display name"},null,8,["modelValue"])]),k.value?(S(),G("div",mg,[$(v(Ze),{variant:"danger"},{default:x(()=>[N(O(k.value),1)]),_:1})])):ne("",!0)]),_:1},8,["open"]),$(v(at),{open:v(l),title:"Assign to parent area","onUpdate:open":F[5]||(F[5]=U=>l.value=U)},{footer:x(()=>[$(v(de),{variant:"secondary",onClick:F[4]||(F[4]=U=>l.value=!1)},{default:x(()=>[...F[13]||(F[13]=[N("Cancel",-1)])]),_:1}),C.value?ne("",!0):(S(),q(v(de),{key:0,variant:"primary",icon:"ph-check",loading:v(c),onClick:Ue},{default:x(()=>[...F[14]||(F[14]=[N(" Assign ",-1)])]),_:1},8,["loading"]))]),default:x(()=>[C.value?ne("",!0):(S(),q(v(rs),{key:0,modelValue:v(u),"onUpdate:modelValue":F[3]||(F[3]=U=>Ve(u)?u.value=U:null),label:"Parent area",options:P.value,icon:"ph-map-trifold"},null,8,["modelValue","options"])),C.value?(S(),G("div",yg,[$(v(Ze),{variant:"warning"},{default:x(()=>[...F[12]||(F[12]=[N(" This is the last root area and cannot be assigned as a child. At least one root area must remain. ",-1)])]),_:1})])):ne("",!0),v(d)?(S(),G("div",_g,[$(v(Ze),{variant:"danger"},{default:x(()=>[N(O(v(d)),1)]),_:1})])):ne("",!0)]),_:1},8,["open"]),$(v(at),{open:W.value,title:"Unassign from parent","onUpdate:open":F[7]||(F[7]=U=>W.value=U)},{footer:x(()=>[$(v(de),{variant:"secondary",onClick:F[6]||(F[6]=U=>W.value=!1)},{default:x(()=>[...F[15]||(F[15]=[N("Cancel",-1)])]),_:1}),$(v(de),{variant:"warning",icon:"ph-x-circle",loading:Y.value,onClick:Oe},{default:x(()=>[...F[16]||(F[16]=[N(" Unassign ",-1)])]),_:1},8,["loading"])]),default:x(()=>[T("p",null,O(Z.value),1),te.value?(S(),G("div",bg,[$(v(Ze),{variant:"danger"},{default:x(()=>[N(O(te.value),1)]),_:1})])):ne("",!0)]),_:1},8,["open"]),$(v(at),{open:le.value,title:"Remove area","onUpdate:open":F[9]||(F[9]=U=>le.value=U)},{footer:x(()=>[$(v(de),{variant:"secondary",onClick:F[8]||(F[8]=U=>le.value=!1)},{default:x(()=>[...F[17]||(F[17]=[N("Cancel",-1)])]),_:1}),$(v(de),{variant:"danger",icon:"ph-trash",loading:ge.value,onClick:be},{default:x(()=>[...F[18]||(F[18]=[N(" Remove ",-1)])]),_:1},8,["loading"])]),default:x(()=>[T("p",null,O(fe.value),1),B.value?(S(),G("div",wg,[$(v(Ze),{variant:"danger"},{default:x(()=>[N(O(B.value),1)]),_:1})])):ne("",!0)]),_:1},8,["open"])]))}},kg=ze(Sg,[["__scopeId","data-v-757a0469"]]),Ag={class:"page"},xg={key:3,class:"devices-panel"},Cg={class:"devices-summary"},Eg=300*1e3,Rg={__name:"DevicesListPage",setup(e){const t=os(),n=Q(()=>{if(!t.lastLoadedAt)return!1;const s=new Date(t.lastLoadedAt).getTime();return Date.now()-s>Eg});async function a(){(await t.loadDevices()).ok&&await t.loadDeviceStates()}return bt(a),(s,r)=>(S(),G("section",Ag,[$(v(Rt),{title:"Device Matrix",kicker:"Devices"},{actions:x(()=>[$(v(de),{loading:v(t).isLoading||v(t).isLoadingStates,icon:"ph-arrow-clockwise",onClick:a},{default:x(()=>[...r[0]||(r[0]=[N(" Refresh ",-1)])]),_:1},8,["loading"])]),_:1}),v(t).isLoading?(S(),q(St,{key:0,text:"Loading devices"})):v(t).error?(S(),q(pt,{key:1,title:"Devices loading failed",error:v(t).error,retry:a},null,8,["error"])):v(t).devices.length===0?(S(),q(it,{key:2,title:"No active devices",message:"No active devices found."})):(S(),G("div",xg,[T("div",Cg,[$(v(_e),{variant:"primary"},{default:x(()=>[N("Total: "+O(v(t).total),1)]),_:1}),v(t).isLoadingStates?(S(),q(v(_e),{key:0,variant:"secondary"},{default:x(()=>[...r[1]||(r[1]=[N("States loading",-1)])]),_:1})):(S(),q(v(_e),{key:1,variant:"success"},{default:x(()=>[...r[2]||(r[2]=[N("States settled",-1)])]),_:1})),n.value?(S(),q(v(_e),{key:2,variant:"warning"},{default:x(()=>[...r[3]||(r[3]=[N("Stale data",-1)])]),_:1})):ne("",!0)]),v(t).stateError?(S(),q(pt,{key:0,title:"Device states loading failed",error:v(t).stateError},null,8,["error"])):ne("",!0),$(Nl,{devices:v(t).devices,caption:"Registered devices"},null,8,["devices"])]))]))}},$g=ze(Rg,[["__scopeId","data-v-635f3900"]]),Tg=bn("scanning",()=>{const e=J("setup"),t=J([]),n=gt(),a=Q(()=>t.value.length);async function s(){return n.execute(async i=>{var u,c;const l=e.value==="setup"?await nt.scanningSetup({signal:i}):await nt.scanningAll({signal:i});return l.ok&&(t.value=((c=(u=l.data)==null?void 0:u.data)==null?void 0:c.devices)||[]),l})}function r(i){e.value=i,t.value=[],n.clear()}async function o(i){return nt.setupNewDevice(i)}return{mode:e,devices:t,isLoading:n.isLoading,error:n.error,total:a,scan:s,setMode:r,setupDevice:o}}),Pg={class:"page"},Ig={class:"scan-filters"},Lg={key:3,class:"devices-panel"},Dg={class:"devices-summary"},Og={class:"device-cell"},Fg=["innerHTML"],Ng={class:"device-info"},Mg={class:"firmware"},Ug={key:1,class:"muted"},Vg={class:"form-group"},jg={class:"form-group"},Bg={class:"form-group"},Hg={key:0,class:"form-group"},Gg={__name:"DevicesScanningPage",setup(e){const t=Tg(),n=wn(),a=jt(),s=J(!1),r=J(!1),o=J(""),i=Zt({device_ip:"",alias:"",name:"",description:""}),l={relay:'',button:'',sensor:''},u=[{key:"device",label:"Device"},{key:"status",label:"Status"},{key:"firmware",label:"Firmware"},{key:"actions",label:"Actions"}];function c(m){return l[m]||l.relay}function d(m){t.setMode(m)}function f(){t.scan()}function _(m){i.device_ip=m.ip_address,i.alias="",i.name="",i.description="",o.value="",s.value=!0}async function h(){var g;r.value=!0,o.value="";const m=await t.setupDevice({...i});if(r.value=!1,!m.ok){o.value=((g=m.error)==null?void 0:g.message)||"Failed to setup device";return}s.value=!1,n.success({title:"Device added",text:`Device ${i.alias||i.name||""} added successfully`})}return(m,g)=>(S(),G("section",Pg,[$(v(Rt),{title:"Scanning",kicker:"Devices"},{actions:x(()=>[$(v(de),{loading:v(t).isLoading,icon:"ph-magnifying-glass",onClick:f},{default:x(()=>[...g[7]||(g[7]=[N(" Scan ",-1)])]),_:1},8,["loading"])]),_:1}),T("div",Ig,[g[10]||(g[10]=T("span",{class:"filter-label text-muted"},"Mode:",-1)),$(v(Li),{selected:v(t).mode==="setup",clickable:"",icon:"ph-plug",onClick:g[0]||(g[0]=E=>d("setup"))},{default:x(()=>[...g[8]||(g[8]=[N(" Setup ",-1)])]),_:1},8,["selected"]),$(v(Li),{selected:v(t).mode==="all",clickable:"",icon:"ph-scan",onClick:g[1]||(g[1]=E=>d("all"))},{default:x(()=>[...g[9]||(g[9]=[N(" All ",-1)])]),_:1},8,["selected"])]),v(t).isLoading?(S(),q(St,{key:0,text:"Scanning network"})):v(t).error?(S(),q(pt,{key:1,title:"Scan failed",error:v(t).error,retry:f},null,8,["error"])):v(t).devices.length===0?(S(),q(it,{key:2,title:"No devices found",message:"Choose scan mode and click Scan to discover devices."})):(S(),G("div",Lg,[T("div",Dg,[$(v(_e),{variant:"primary"},{default:x(()=>[N(O(v(t).total)+" found",1)]),_:1})]),$(v(Nn),{columns:u,rows:v(t).devices,caption:"Discovered devices"},{"cell-device":x(({row:E})=>[T("div",Og,[T("div",{class:"device-icon",innerHTML:c(E.device_type)},null,8,Fg),T("div",Ng,[T("strong",null,O(E.device_name||"Unknown"),1),T("small",null,O(E.device_type||"unknown")+" — "+O(E.ip_address||"—"),1)])])]),"cell-status":x(({row:E})=>[$(v(_e),{variant:E.status==="setup"?"warning":"success"},{default:x(()=>[N(O(E.status||"unknown"),1)]),_:2},1032,["variant"])]),"cell-firmware":x(({row:E})=>[T("span",Mg,O(E.firmware_version||"—"),1)]),"cell-actions":x(({row:E})=>[E.status==="setup"&&v(a).has("devices.setup")?(S(),q(v(de),{key:0,variant:"primary",icon:"ph-plus",size:"sm",onClick:y=>_(E)},{default:x(()=>[...g[11]||(g[11]=[N(" Add ",-1)])]),_:1},8,["onClick"])):(S(),G("span",Ug,"—"))]),_:1},8,["rows"])])),$(v(at),{open:s.value,title:"Setup new device","onUpdate:open":g[6]||(g[6]=E=>s.value=E)},{footer:x(()=>[$(v(de),{variant:"secondary",onClick:g[5]||(g[5]=E=>s.value=!1)},{default:x(()=>[...g[12]||(g[12]=[N("Cancel",-1)])]),_:1}),$(v(de),{variant:"primary",icon:"ph-plus",loading:r.value,onClick:h},{default:x(()=>[...g[13]||(g[13]=[N(" Add device ",-1)])]),_:1},8,["loading"])]),default:x(()=>[T("div",Vg,[$(v(yt),{modelValue:i.alias,"onUpdate:modelValue":g[2]||(g[2]=E=>i.alias=E),label:"Alias",placeholder:"kitchen_relay"},null,8,["modelValue"])]),T("div",jg,[$(v(yt),{modelValue:i.name,"onUpdate:modelValue":g[3]||(g[3]=E=>i.name=E),label:"Name",placeholder:"Kitchen Relay"},null,8,["modelValue"])]),T("div",Bg,[$(v(yt),{modelValue:i.description,"onUpdate:modelValue":g[4]||(g[4]=E=>i.description=E),label:"Description"},null,8,["modelValue"])]),o.value?(S(),G("div",Hg,[$(v(Ze),{variant:"danger"},{default:x(()=>[N(O(o.value),1)]),_:1})])):ne("",!0)]),_:1},8,["open"])]))}},qg=ze(Gg,[["__scopeId","data-v-1a01bb19"]]);function Vi(e){return encodeURIComponent(String(e))}const zn={async list(){return Fe("/api/v1/firmwares")},async detail(e){return Fe(`/api/v1/firmwares/id/${Vi(e)}`)},async refresh(){return Qe("/api/v1/firmwares/refresh")},async deviceCompatibility(e){return Fe(`/api/v1/devices/id/${Vi(e)}/firmware-compatibility`)},async updateDeviceFirmware(e,t){return Qe("/api/v1/devices/update-firmware",{device_id:e,firmware_id:t})}},jl=bn("firmwares",()=>{const e=J([]),t=J(null),n=J(null),a=gt(),s=gt(),r=gt(),o=gt(),i=Q(()=>a.isLoading.value),l=Q(()=>s.isLoading.value),u=Q(()=>r.isLoading.value),c=Q(()=>o.isLoading.value);async function d(){return a.execute(async E=>{var w,C;const y=await zn.list({signal:E});return y.ok&&(e.value=((C=(w=y.data)==null?void 0:w.data)==null?void 0:C.firmwares)||[]),y})}async function f(){return r.execute(async()=>{const E=await zn.refresh();return E.ok&&await d(),E})}async function _(E){return s.execute(async y=>{var C,I;const w=await zn.detail(E,{signal:y});return w.ok&&(t.value=((I=(C=w.data)==null?void 0:C.data)==null?void 0:I.firmware)||null),w})}async function h(E){return o.execute(async y=>{var C,I,P,R;const w=await zn.deviceCompatibility(E,{signal:y});return w.ok&&(n.value={compatible:((I=(C=w.data)==null?void 0:C.data)==null?void 0:I.compatible)||[],currentVersion:((R=(P=w.data)==null?void 0:P.data)==null?void 0:R.current_version)||"unknown"}),w})}async function m(E,y){return r.execute(async()=>zn.updateDeviceFirmware(E,y))}function g(){n.value=null}return{firmwares:e,current:t,compatibility:n,isLoadingList:i,isLoadingDetail:l,isUpdating:u,isLoadingCompatibility:c,loadFirmwares:d,refreshFirmwares:f,loadFirmwareDetail:_,loadDeviceCompatibility:h,updateDeviceFirmware:m,clearCompatibility:g}}),zg={class:"page"},Kg={key:2},Wg={class:"device-meta"},Jg={class:"script-info-panel"},Yg={class:"info-row"},Xg={class:"info-value"},Zg={class:"info-row"},Qg={class:"info-value"},eh={class:"info-row"},th={class:"info-value"},nh={class:"info-row"},ah={class:"info-value"},sh={class:"info-row"},rh={class:"info-value"},ih={class:"info-row"},oh={class:"info-value"},lh={class:"info-row"},uh={class:"info-value"},ch={key:0,class:"info-row"},dh=["title"],fh={key:1,class:"info-row"},ph={class:"info-value"},vh={key:0,class:"devices-panel"},gh={key:1,class:"devices-panel"},hh={class:"form-group"},mh={class:"form-group"},yh={class:"form-group"},_h={key:0,class:"form-group"},bh={key:0,class:"form-group"},wh={key:0,class:"form-group"},Sh={key:0,class:"form-group"},kh={key:0,class:"form-group"},Ah={key:0,class:"form-group"},xh={class:"firmware-options"},Ch=["onClick"],Eh={class:"fw-version"},Rh={key:0,class:"fw-desc"},$h={key:0,class:"form-group"},Th={__name:"DeviceDetailPage",setup(e){const t=as(),n=en(),a=os(),s=kt(),r=jl(),o=wn(),i=jt(),{areaOptions:l,showAssignModal:u,selectedAreaId:c,assignLoading:d,assignError:f,openAssign:_,submitAssignCore:h}=Er(),m=Q(()=>t.params.id),g=Q(()=>a.currentDevice),E=Q(()=>a.isLoadingDetail),y=Q(()=>a.errorDetail),w=J(!1),C=J(null),I=Q(()=>{var D;const ie=(D=g.value)==null?void 0:D.area_id;return ie&&s.areasById[String(ie)]||null}),P=J(!1),R=J(!1),L=J(""),k=Zt({name:"",description:"",alias:""}),ee=J(!1),le=J(""),fe=J(!1),ge=J(""),B=J(!1),W=J(""),Z=J(!1),Y=J(""),te=J(!1),ve=J(""),ke=J(!1),Pe=J(""),be=J(!1),Ge=J(""),Ue=J(!1),De=J(""),Oe=J(!1),M=J(null),se=J(""),H=Q(()=>{var ie,D;return(((D=(ie=r.compatibility)==null?void 0:ie.compatible)==null?void 0:D.length)||0)>0}),F=Q(()=>{var ie;return((ie=r.compatibility)==null?void 0:ie.compatible)||[]}),U=Q(()=>{var D,Le;const ie=[];return i.has("devices.edit")&&(ie.push({label:"Edit",icon:"ph-pencil",onSelect:p}),(D=g.value)!=null&&D.area_id?ie.push({label:"Change area",icon:"ph-map-pin",onSelect:A},{label:"Unassign from area",icon:"ph-x-circle",onSelect:K}):ie.push({label:"Assign to area",icon:"ph-map-pin",onSelect:A})),i.has("devices.setup")&&ie.push({label:"ReSetup",icon:"ph-gear",onSelect:X}),i.has("devices.control")&&ie.push({label:"Reboot",icon:"ph-arrow-clockwise",disabled:a.isRebooting((Le=g.value)==null?void 0:Le.id),onSelect:ae}),i.has("devices.edit")&&ie.push({label:"Reset",icon:"ph-x",danger:!0,onSelect:ue}),i.has("devices.delete")&&ie.push({label:"Remove",icon:"ph-trash",danger:!0,onSelect:oe}),ie});function p(){g.value&&(k.name=g.value.name||"",k.description=g.value.description||"",k.alias=g.value.alias||"",L.value="",P.value=!0)}async function b(){var et,he,Je,Ke;R.value=!0,L.value="";const ie=m.value,D=await Promise.all([k.name!==((et=g.value)==null?void 0:et.name)?a.updateDeviceName(ie,k.name):{ok:!0},k.description!==((he=g.value)==null?void 0:he.description)?a.updateDeviceDescription(ie,k.description):{ok:!0},k.alias!==((Je=g.value)==null?void 0:Je.alias)?a.updateDeviceAlias(ie,k.alias):{ok:!0}]);R.value=!1;const Le=D.find(Vn=>!Vn.ok);if(Le){L.value=((Ke=Le.error)==null?void 0:Ke.message)||"Failed to update device";return}P.value=!1,o.success({title:"Updated",text:"Device updated successfully"})}function A(){var ie;_((ie=g.value)==null?void 0:ie.area_id)}async function V(){const ie=await h(m.value,a.assignToArea.bind(a));ie!=null&&ie.ok&&o.success({title:"Assigned",text:"Device assigned to area successfully"})}function K(){g.value&&(W.value=`Are you sure you want to unassign device "${g.value.name||g.value.alias}" from its area?`,Y.value="",B.value=!0)}async function z(){var D;if(!g.value)return;Z.value=!0,Y.value="";const ie=await a.unassignDevice(m.value);if(Z.value=!1,!ie.ok){Y.value=((D=ie.error)==null?void 0:D.message)||"Failed to unassign device";return}B.value=!1,o.success({title:"Unassigned",text:"Device unassigned from area successfully"})}function oe(){g.value&&(le.value=`Are you sure you want to remove device "${g.value.name||g.value.alias}"?`,ge.value="",ee.value=!0)}async function re(){var Le;const ie=m.value;fe.value=!0,ge.value="";const D=await a.removeDevice(ie);if(fe.value=!1,!D.ok){ge.value=((Le=D.error)==null?void 0:Le.message)||"Failed to remove device";return}ee.value=!1,o.success({title:"Removed",text:"Device removed successfully"}),n.push({name:"devices"})}async function ae(){var D;if(!g.value)return;const ie=await a.rebootDevice(g.value.id);ie.ok?o.success({title:"Rebooting",text:`Device ${g.value.name||g.value.alias||"#"+g.value.id} is rebooting`}):o.error({title:"Reboot failed",text:((D=ie.error)==null?void 0:D.message)||"Failed to reboot device"})}function X(){g.value&&(ve.value=`Are you sure you want to repeat setup for device "${g.value.name||g.value.alias}"?`,Pe.value="",te.value=!0)}async function pe(){var Le,et,he;const ie=m.value;ke.value=!0,Pe.value="";const D=await a.resetupDevice(ie);if(ke.value=!1,!D.ok){Pe.value=((Le=D.error)==null?void 0:Le.message)||"Failed to repeat device setup";return}te.value=!1,o.success({title:"Success",text:`Device ${((et=g.value)==null?void 0:et.name)||((he=g.value)==null?void 0:he.alias)||"#"+ie} setup repeated`}),n.push({name:"devices"})}function ue(){g.value&&(Ge.value=`Are you sure you want to reset device "${g.value.name||g.value.alias}"?`,De.value="",be.value=!0)}async function ce(){var Le,et,he;const ie=m.value;Ue.value=!0,De.value="";const D=await a.resetDevice(ie);if(Ue.value=!1,!D.ok){De.value=((Le=D.error)==null?void 0:Le.message)||"Failed to reset device";return}be.value=!1,o.success({title:"Success",text:`Device ${((et=g.value)==null?void 0:et.name)||((he=g.value)==null?void 0:he.alias)||"#"+ie} reset`}),n.push({name:"devices"})}function me(){var ie;M.value=((ie=F.value[0])==null?void 0:ie.id)||null,se.value="",Oe.value=!0}async function Se(){var D;if(!M.value||!g.value)return;const ie=await r.updateDeviceFirmware(g.value.id,M.value);if(!ie.ok){se.value=((D=ie.error)==null?void 0:D.message)||"Firmware update failed";return}Oe.value=!1,o.success({title:"Updated",text:"Firmware update pushed successfully"}),await a.loadDeviceDetail(m.value)}function $e(ie){return{active:"success",removed:"danger",freezed:"warning",setup:"primary"}[ie]||"secondary"}async function Ie(){const ie=m.value;if(!ie||!g.value||g.value.connection_status!=="active")return;w.value=!0,C.value=null;const D=await a.loadDeviceStatus(ie);w.value=!1,D.ok||(C.value=D.error)}async function je(){var D;const ie=m.value;ie&&(s.areas.length===0&&await s.loadAreas(),await a.loadDeviceDetail(ie),((D=g.value)==null?void 0:D.connection_status)==="active"&&(await Ie(),await r.loadDeviceCompatibility(ie)))}return bt(()=>{je()}),ha(()=>{a.clearDeviceDetail(),r.clearCompatibility()}),wt(()=>t.params.id,(ie,D)=>{ie!==D&&(a.clearDeviceDetail(),je())}),(ie,D)=>{var Le,et;return S(),G("section",zg,[E.value?(S(),q(St,{key:0,text:"Loading device details"})):y.value?(S(),q(pt,{key:1,title:"Device loading failed",error:y.value,retry:je},null,8,["error"])):g.value?(S(),G("div",Kg,[$(v(Rt),{title:g.value.name||g.value.alias||`Device #${g.value.id}`,kicker:"Device"},{actions:x(()=>[$(Tr,{items:U.value},null,8,["items"])]),_:1},8,["title"]),T("div",Wg,[$(v(_e),{variant:g.value.connection_status==="active"?"success":"danger"},{default:x(()=>[N(O(g.value.connection_status==="active"?"Online":"Offline"),1)]),_:1},8,["variant"]),T("code",null,O(g.value.alias),1),$(Rr,{area:I.value,areaId:g.value.area_id},null,8,["area","areaId"])]),T("div",Jg,[T("div",Yg,[D[18]||(D[18]=T("span",{class:"info-label text-muted"},"System status:",-1)),T("span",Xg,[$(v(_e),{variant:$e(g.value.status)},{default:x(()=>[N(O(g.value.status),1)]),_:1},8,["variant"])])]),T("div",Zg,[D[19]||(D[19]=T("span",{class:"info-label text-muted"},"Type:",-1)),T("span",Qg,O(g.value.device_type),1)]),T("div",eh,[D[20]||(D[20]=T("span",{class:"info-label text-muted"},"State:",-1)),T("span",th,[$(Fl,{"device-type":g.value.device_type,response:(Le=v(a).currentDeviceStatus)==null?void 0:Le.raw,loading:w.value,error:(et=C.value)==null?void 0:et.message,"connection-status":g.value.connection_status},null,8,["device-type","response","loading","error","connection-status"])])]),T("div",nh,[D[21]||(D[21]=T("span",{class:"info-label text-muted"},"IP:",-1)),T("span",ah,O(g.value.device_ip),1)]),T("div",sh,[D[22]||(D[22]=T("span",{class:"info-label text-muted"},"MAC:",-1)),T("span",rh,O(g.value.device_mac),1)]),T("div",ih,[D[23]||(D[23]=T("span",{class:"info-label text-muted"},"Hard ID:",-1)),T("span",oh,O(g.value.device_hard_id),1)]),T("div",lh,[D[24]||(D[24]=T("span",{class:"info-label text-muted"},"Firmware:",-1)),T("span",uh,O(g.value.firmware_version),1)]),g.value.last_contact?(S(),G("div",ch,[D[25]||(D[25]=T("span",{class:"info-label text-muted"},"Last contact:",-1)),T("span",{class:"info-value",title:v(Ys)(g.value.last_contact)},O(v(Dl)(g.value.last_contact)),9,dh)])):ne("",!0),g.value.create_at?(S(),G("div",fh,[D[26]||(D[26]=T("span",{class:"info-label text-muted"},"Created:",-1)),T("span",ph,O(v(Ys)(g.value.create_at)),1)])):ne("",!0)]),$($r,{item:g.value,emptyMessage:"This device is not assigned to any area.",onAssign:A},{action:x(()=>[v(i).has("devices.edit")?(S(),q(v(de),{key:0,variant:"primary",icon:"ph-map-pin",onClick:A},{default:x(()=>{var he;return[N(O((he=g.value)!=null&&he.area_id?"Change area":"Assign to area"),1)]}),_:1})):ne("",!0)]),_:1},8,["item"]),H.value&&v(i).has("firmware.upload")?(S(),G("div",vh,[D[29]||(D[29]=T("div",{class:"block-title"},"Firmware Update",-1)),$(v(Ze),{variant:"info"},{default:x(()=>[D[27]||(D[27]=N(" New firmware available: ",-1)),(S(!0),G(Ee,null,Vt(F.value,he=>(S(),q(v(_e),{key:he.id,variant:"success"},{default:x(()=>[N(O(he.version),1)]),_:2},1024))),128))]),_:1}),$(v(de),{variant:"primary",icon:"ph-cloud-arrow-down",onClick:me},{default:x(()=>[...D[28]||(D[28]=[N(" Update Firmware ",-1)])]),_:1})])):ne("",!0),g.value.description?(S(),G("div",gh,[D[30]||(D[30]=T("div",{class:"block-title"},"Description",-1)),T("p",null,O(g.value.description),1)])):ne("",!0)])):(S(),q(it,{key:3,title:"Device not found",message:"The requested device does not exist."})),$(v(at),{open:P.value,title:"Edit device","onUpdate:open":D[4]||(D[4]=he=>P.value=he)},{footer:x(()=>[$(v(de),{variant:"secondary",onClick:D[3]||(D[3]=he=>P.value=!1)},{default:x(()=>[...D[31]||(D[31]=[N("Cancel",-1)])]),_:1}),$(v(de),{variant:"primary",icon:"ph-check",loading:R.value,onClick:b},{default:x(()=>[...D[32]||(D[32]=[N(" Save ",-1)])]),_:1},8,["loading"])]),default:x(()=>[T("div",hh,[$(v(yt),{modelValue:k.name,"onUpdate:modelValue":D[0]||(D[0]=he=>k.name=he),label:"Name"},null,8,["modelValue"])]),T("div",mh,[$(v(yt),{modelValue:k.description,"onUpdate:modelValue":D[1]||(D[1]=he=>k.description=he),label:"Description"},null,8,["modelValue"])]),T("div",yh,[$(v(yt),{modelValue:k.alias,"onUpdate:modelValue":D[2]||(D[2]=he=>k.alias=he),label:"Alias"},null,8,["modelValue"])]),L.value?(S(),G("div",_h,[$(v(Ze),{variant:"danger"},{default:x(()=>[N(O(L.value),1)]),_:1})])):ne("",!0)]),_:1},8,["open"]),$(v(at),{open:v(u),title:"Assign to area","onUpdate:open":D[7]||(D[7]=he=>u.value=he)},{footer:x(()=>[$(v(de),{variant:"secondary",onClick:D[6]||(D[6]=he=>u.value=!1)},{default:x(()=>[...D[33]||(D[33]=[N("Cancel",-1)])]),_:1}),$(v(de),{variant:"primary",icon:"ph-check",loading:v(d),onClick:V},{default:x(()=>[...D[34]||(D[34]=[N(" Assign ",-1)])]),_:1},8,["loading"])]),default:x(()=>[$(v(rs),{modelValue:v(c),"onUpdate:modelValue":D[5]||(D[5]=he=>Ve(c)?c.value=he:null),label:"Area",options:v(l),icon:"ph-map-trifold"},null,8,["modelValue","options"]),v(f)?(S(),G("div",bh,[$(v(Ze),{variant:"danger"},{default:x(()=>[N(O(v(f)),1)]),_:1})])):ne("",!0)]),_:1},8,["open"]),$(v(at),{open:B.value,title:"Unassign from area","onUpdate:open":D[9]||(D[9]=he=>B.value=he)},{footer:x(()=>[$(v(de),{variant:"secondary",onClick:D[8]||(D[8]=he=>B.value=!1)},{default:x(()=>[...D[35]||(D[35]=[N("Cancel",-1)])]),_:1}),$(v(de),{variant:"warning",icon:"ph-x-circle",loading:Z.value,onClick:z},{default:x(()=>[...D[36]||(D[36]=[N(" Unassign ",-1)])]),_:1},8,["loading"])]),default:x(()=>[T("p",null,O(W.value),1),Y.value?(S(),G("div",wh,[$(v(Ze),{variant:"danger"},{default:x(()=>[N(O(Y.value),1)]),_:1})])):ne("",!0)]),_:1},8,["open"]),$(v(at),{open:ee.value,title:"Remove device","onUpdate:open":D[11]||(D[11]=he=>ee.value=he)},{footer:x(()=>[$(v(de),{variant:"secondary",onClick:D[10]||(D[10]=he=>ee.value=!1)},{default:x(()=>[...D[37]||(D[37]=[N("Cancel",-1)])]),_:1}),$(v(de),{variant:"danger",icon:"ph-trash",loading:fe.value,onClick:re},{default:x(()=>[...D[38]||(D[38]=[N(" Remove ",-1)])]),_:1},8,["loading"])]),default:x(()=>[T("p",null,O(le.value),1),ge.value?(S(),G("div",Sh,[$(v(Ze),{variant:"danger"},{default:x(()=>[N(O(ge.value),1)]),_:1})])):ne("",!0)]),_:1},8,["open"]),$(v(at),{open:te.value,title:"Repeat device setup","onUpdate:open":D[13]||(D[13]=he=>te.value=he)},{footer:x(()=>[$(v(de),{variant:"secondary",onClick:D[12]||(D[12]=he=>te.value=!1)},{default:x(()=>[...D[39]||(D[39]=[N("Cancel",-1)])]),_:1}),$(v(de),{variant:"primary",icon:"ph-gear",loading:ke.value,onClick:pe},{default:x(()=>[...D[40]||(D[40]=[N(" ReSetup ",-1)])]),_:1},8,["loading"])]),default:x(()=>[T("p",null,O(ve.value),1),Pe.value?(S(),G("div",kh,[$(v(Ze),{variant:"danger"},{default:x(()=>[N(O(Pe.value),1)]),_:1})])):ne("",!0)]),_:1},8,["open"]),$(v(at),{open:be.value,title:"Reset device","onUpdate:open":D[15]||(D[15]=he=>be.value=he)},{footer:x(()=>[$(v(de),{variant:"secondary",onClick:D[14]||(D[14]=he=>be.value=!1)},{default:x(()=>[...D[41]||(D[41]=[N("Cancel",-1)])]),_:1}),$(v(de),{variant:"danger",icon:"ph-x",loading:Ue.value,onClick:ce},{default:x(()=>[...D[42]||(D[42]=[N(" Reset ",-1)])]),_:1},8,["loading"])]),default:x(()=>[T("p",null,O(Ge.value),1),De.value?(S(),G("div",Ah,[$(v(Ze),{variant:"danger"},{default:x(()=>[N(O(De.value),1)]),_:1})])):ne("",!0)]),_:1},8,["open"]),$(v(at),{open:Oe.value,title:"Update Firmware","onUpdate:open":D[17]||(D[17]=he=>Oe.value=he)},{footer:x(()=>[$(v(de),{variant:"secondary",onClick:D[16]||(D[16]=he=>Oe.value=!1)},{default:x(()=>[...D[45]||(D[45]=[N("Cancel",-1)])]),_:1}),$(v(de),{variant:"primary",icon:"ph-check",loading:v(r).isUpdating,disabled:!M.value,onClick:Se},{default:x(()=>[...D[46]||(D[46]=[N(" Update ",-1)])]),_:1},8,["loading","disabled"])]),default:x(()=>{var he,Je;return[T("p",null,[D[43]||(D[43]=N("Select firmware to install on ",-1)),T("strong",null,O(((he=g.value)==null?void 0:he.name)||((Je=g.value)==null?void 0:Je.alias)),1),D[44]||(D[44]=N(":",-1))]),T("div",xh,[(S(!0),G(Ee,null,Vt(F.value,Ke=>(S(),G("div",{key:Ke.id,class:Mt(["firmware-option",{active:M.value===Ke.id}]),onClick:Vn=>M.value=Ke.id},[T("div",Eh,O(Ke.version),1),Ke.description?(S(),G("div",Rh,O(Ke.description),1)):ne("",!0)],10,Ch))),128))]),se.value?(S(),G("div",$h,[$(v(Ze),{variant:"danger"},{default:x(()=>[N(O(se.value),1)]),_:1})])):ne("",!0)]}),_:1},8,["open"])])}}},Ph=ze(Th,[["__scopeId","data-v-a9f83185"]]),Ih={class:"page"},Lh={__name:"ScriptsActionsPage",setup(e){const t=Sn(),n=kt();return bt(()=>{t.loadActions(),n.areas.length===0&&n.loadAreas()}),(a,s)=>(S(),G("section",Ih,[$(v(Rt),{title:"Actions",kicker:"Scripts"},{actions:x(()=>[$(v(_e),{variant:"primary"},{default:x(()=>[N(O(v(t).totalActions)+" scripts",1)]),_:1})]),_:1}),v(t).isLoadingActions?(S(),q(St,{key:0,text:"Loading actions"})):v(t).errorActions?(S(),q(pt,{key:1,title:"Actions loading failed",error:v(t).errorActions,retry:v(t).loadActions},null,8,["error","retry"])):v(t).actions.length===0?(S(),q(it,{key:2,title:"No action scripts",message:"No action scripts registered."})):(S(),q(Vl,{key:3,scripts:v(t).actions,"show-area-badge":""},null,8,["scripts"]))]))}},Dh=ze(Lh,[["__scopeId","data-v-f336617a"]]),Oh={class:"page"},Fh={key:3,class:"devices-panel"},Nh={__name:"ScriptsRegularPage",setup(e){const t=Sn(),n=kt();return bt(()=>{t.loadRegular(),n.areas.length===0&&n.loadAreas()}),(a,s)=>(S(),G("section",Oh,[$(v(Rt),{title:"Regular",kicker:"Scripts"},{actions:x(()=>[$(v(_e),{variant:"primary"},{default:x(()=>[N(O(v(t).totalRegular)+" scripts",1)]),_:1})]),_:1}),v(t).isLoadingRegular?(S(),q(St,{key:0,text:"Loading regular scripts"})):v(t).errorRegular?(S(),q(pt,{key:1,title:"Regular scripts loading failed",error:v(t).errorRegular,retry:v(t).loadRegular},null,8,["error","retry"])):v(t).regular.length===0?(S(),q(it,{key:2,title:"No regular scripts",message:"No regular scripts registered."})):(S(),G("div",Fh,[$(Ml,{scripts:v(t).regular,scriptType:"regular",showArea:!0,showScope:!0,showFilename:!0,showActions:!0,caption:"Regular scripts"},null,8,["scripts"])]))]))}},Mh={class:"page"},Uh={key:3,class:"devices-panel"},Vh={__name:"ScriptsScopesPage",setup(e){en();const t=Sn(),n=jt(),a=[{key:"name",label:"Name"},{key:"filename",label:"File"},{key:"state",label:"State"},{key:"path",label:"Path"},{key:"actions",label:"Actions"}];function s(r,o){t.setScopeState(r,o)}return bt(()=>{t.loadScopes()}),(r,o)=>{const i=cn("router-link");return S(),G("section",Mh,[$(v(Rt),{title:"Scopes",kicker:"Scripts"},{actions:x(()=>[$(v(_e),{variant:"primary"},{default:x(()=>[N(O(v(t).totalScopes)+" scopes",1)]),_:1})]),_:1}),v(t).isLoadingScopes?(S(),q(St,{key:0,text:"Loading scopes"})):v(t).errorScopes?(S(),q(pt,{key:1,title:"Scopes loading failed",error:v(t).errorScopes,retry:v(t).loadScopes},null,8,["error","retry"])):v(t).scopes.length===0?(S(),q(it,{key:2,title:"No scopes",message:"No script scopes registered."})):(S(),G("div",Uh,[$(v(Nn),{columns:a,rows:v(t).scopes,caption:"Script scopes"},{"cell-name":x(({row:l})=>[$(i,{to:{name:"script-detail",params:{type:"scopes",id:l.name}},class:"script-link"},{default:x(()=>[N(O(l.name),1)]),_:2},1032,["to"])]),"cell-state":x(({row:l})=>[$(v(_e),{variant:l.state==="enabled"?"success":"secondary"},{default:x(()=>[N(O(l.state),1)]),_:2},1032,["variant"])]),"cell-actions":x(({row:l})=>[l.state==="enabled"&&v(n).has("scripts.edit")?(S(),q(v(de),{key:0,variant:"secondary",icon:"ph-pause",onClick:u=>s(l.name,!1)},{default:x(()=>[...o[0]||(o[0]=[N(" Disable ",-1)])]),_:1},8,["onClick"])):v(n).has("scripts.edit")?(S(),q(v(de),{key:1,variant:"primary",icon:"ph-play",onClick:u=>s(l.name,!0)},{default:x(()=>[...o[1]||(o[1]=[N(" Enable ",-1)])]),_:1},8,["onClick"])):ne("",!0)]),_:1},8,["rows"])]))])}}},jh=ze(Vh,[["__scopeId","data-v-c8486788"]]);var ji=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function Bh(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var Es={exports:{}},Bi;function Hh(){return Bi||(Bi=1,(function(e){var t=typeof window<"u"?window:typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope?self:{};/** + * Prism: Lightweight, robust, elegant syntax highlighting + * + * @license MIT + * @author Lea Verou + * @namespace + * @public + */var n=(function(a){var s=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,r=0,o={},i={manual:a.Prism&&a.Prism.manual,disableWorkerMessageHandler:a.Prism&&a.Prism.disableWorkerMessageHandler,util:{encode:function y(w){return w instanceof l?new l(w.type,y(w.content),w.alias):Array.isArray(w)?w.map(y):w.replace(/&/g,"&").replace(/"u")return null;if(document.currentScript&&document.currentScript.tagName==="SCRIPT")return document.currentScript;try{throw new Error}catch(I){var y=(/at [^(\r\n]*\((.*):[^:]+:[^:]+\)$/i.exec(I.stack)||[])[1];if(y){var w=document.getElementsByTagName("script");for(var C in w)if(w[C].src==y)return w[C]}return null}},isActive:function(y,w,C){for(var I="no-"+w;y;){var P=y.classList;if(P.contains(w))return!0;if(P.contains(I))return!1;y=y.parentElement}return!!C}},languages:{plain:o,plaintext:o,text:o,txt:o,extend:function(y,w){var C=i.util.clone(i.languages[y]);for(var I in w)C[I]=w[I];return C},insertBefore:function(y,w,C,I){I=I||i.languages;var P=I[y],R={};for(var L in P)if(P.hasOwnProperty(L)){if(L==w)for(var k in C)C.hasOwnProperty(k)&&(R[k]=C[k]);C.hasOwnProperty(L)||(R[L]=P[L])}var ee=I[y];return I[y]=R,i.languages.DFS(i.languages,function(le,fe){fe===ee&&le!=y&&(this[le]=R)}),R},DFS:function y(w,C,I,P){P=P||{};var R=i.util.objId;for(var L in w)if(w.hasOwnProperty(L)){C.call(w,L,w[L],I||L);var k=w[L],ee=i.util.type(k);ee==="Object"&&!P[R(k)]?(P[R(k)]=!0,y(k,C,null,P)):ee==="Array"&&!P[R(k)]&&(P[R(k)]=!0,y(k,C,L,P))}}},plugins:{},highlightAll:function(y,w){i.highlightAllUnder(document,y,w)},highlightAllUnder:function(y,w,C){var I={callback:C,container:y,selector:'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'};i.hooks.run("before-highlightall",I),I.elements=Array.prototype.slice.apply(I.container.querySelectorAll(I.selector)),i.hooks.run("before-all-elements-highlight",I);for(var P=0,R;R=I.elements[P++];)i.highlightElement(R,w===!0,I.callback)},highlightElement:function(y,w,C){var I=i.util.getLanguage(y),P=i.languages[I];i.util.setLanguage(y,I);var R=y.parentElement;R&&R.nodeName.toLowerCase()==="pre"&&i.util.setLanguage(R,I);var L=y.textContent,k={element:y,language:I,grammar:P,code:L};function ee(fe){k.highlightedCode=fe,i.hooks.run("before-insert",k),k.element.innerHTML=k.highlightedCode,i.hooks.run("after-highlight",k),i.hooks.run("complete",k),C&&C.call(k.element)}if(i.hooks.run("before-sanity-check",k),R=k.element.parentElement,R&&R.nodeName.toLowerCase()==="pre"&&!R.hasAttribute("tabindex")&&R.setAttribute("tabindex","0"),!k.code){i.hooks.run("complete",k),C&&C.call(k.element);return}if(i.hooks.run("before-highlight",k),!k.grammar){ee(i.util.encode(k.code));return}if(w&&a.Worker){var le=new Worker(i.filename);le.onmessage=function(fe){ee(fe.data)},le.postMessage(JSON.stringify({language:k.language,code:k.code,immediateClose:!0}))}else ee(i.highlight(k.code,k.grammar,k.language))},highlight:function(y,w,C){var I={code:y,grammar:w,language:C};if(i.hooks.run("before-tokenize",I),!I.grammar)throw new Error('The language "'+I.language+'" has no grammar.');return I.tokens=i.tokenize(I.code,I.grammar),i.hooks.run("after-tokenize",I),l.stringify(i.util.encode(I.tokens),I.language)},tokenize:function(y,w){var C=w.rest;if(C){for(var I in C)w[I]=C[I];delete w.rest}var P=new d;return f(P,P.head,y),c(y,P,w,P.head,0),h(P)},hooks:{all:{},add:function(y,w){var C=i.hooks.all;C[y]=C[y]||[],C[y].push(w)},run:function(y,w){var C=i.hooks.all[y];if(!(!C||!C.length))for(var I=0,P;P=C[I++];)P(w)}},Token:l};a.Prism=i;function l(y,w,C,I){this.type=y,this.content=w,this.alias=C,this.length=(I||"").length|0}l.stringify=function y(w,C){if(typeof w=="string")return w;if(Array.isArray(w)){var I="";return w.forEach(function(ee){I+=y(ee,C)}),I}var P={type:w.type,content:y(w.content,C),tag:"span",classes:["token",w.type],attributes:{},language:C},R=w.alias;R&&(Array.isArray(R)?Array.prototype.push.apply(P.classes,R):P.classes.push(R)),i.hooks.run("wrap",P);var L="";for(var k in P.attributes)L+=" "+k+'="'+(P.attributes[k]||"").replace(/"/g,""")+'"';return"<"+P.tag+' class="'+P.classes.join(" ")+'"'+L+">"+P.content+""};function u(y,w,C,I){y.lastIndex=w;var P=y.exec(C);if(P&&I&&P[1]){var R=P[1].length;P.index+=R,P[0]=P[0].slice(R)}return P}function c(y,w,C,I,P,R){for(var L in C)if(!(!C.hasOwnProperty(L)||!C[L])){var k=C[L];k=Array.isArray(k)?k:[k];for(var ee=0;ee=R.reach);ve+=te.value.length,te=te.next){var ke=te.value;if(w.length>y.length)return;if(!(ke instanceof l)){var Pe=1,be;if(B){if(be=u(Y,ve,y,ge),!be||be.index>=y.length)break;var Oe=be.index,Ge=be.index+be[0].length,Ue=ve;for(Ue+=te.value.length;Oe>=Ue;)te=te.next,Ue+=te.value.length;if(Ue-=te.value.length,ve=Ue,te.value instanceof l)continue;for(var De=te;De!==w.tail&&(UeR.reach&&(R.reach=F);var U=te.prev;se&&(U=f(w,U,se),ve+=se.length),_(w,U,Pe);var p=new l(L,fe?i.tokenize(M,fe):M,W,M);if(te=f(w,U,p),H&&f(w,te,H),Pe>1){var b={cause:L+","+ee,reach:F};c(y,w,C,te.prev,ve,b),R&&b.reach>R.reach&&(R.reach=b.reach)}}}}}}function d(){var y={value:null,prev:null,next:null},w={value:null,prev:y,next:null};y.next=w,this.head=y,this.tail=w,this.length=0}function f(y,w,C){var I=w.next,P={value:C,prev:w,next:I};return w.next=P,I.prev=P,y.length++,P}function _(y,w,C){for(var I=w.next,P=0;P/,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},{pattern:/^(\s*)["']|["']$/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},n.languages.markup.tag.inside["attr-value"].inside.entity=n.languages.markup.entity,n.languages.markup.doctype.inside["internal-subset"].inside=n.languages.markup,n.hooks.add("wrap",function(a){a.type==="entity"&&(a.attributes.title=a.content.replace(/&/,"&"))}),Object.defineProperty(n.languages.markup.tag,"addInlined",{value:function(s,r){var o={};o["language-"+r]={pattern:/(^$)/i,lookbehind:!0,inside:n.languages[r]},o.cdata=/^$/i;var i={"included-cdata":{pattern://i,inside:o}};i["language-"+r]={pattern:/[\s\S]+/,inside:n.languages[r]};var l={};l[s]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,function(){return s}),"i"),lookbehind:!0,greedy:!0,inside:i},n.languages.insertBefore("markup","cdata",l)}}),Object.defineProperty(n.languages.markup.tag,"addAttribute",{value:function(a,s){n.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+a+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[s,"language-"+s],inside:n.languages[s]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),n.languages.html=n.languages.markup,n.languages.mathml=n.languages.markup,n.languages.svg=n.languages.markup,n.languages.xml=n.languages.extend("markup",{}),n.languages.ssml=n.languages.xml,n.languages.atom=n.languages.xml,n.languages.rss=n.languages.xml,(function(a){var s=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;a.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:RegExp("@[\\w-](?:"+/[^;{\s"']|\s+(?!\s)/.source+"|"+s.source+")*?"+/(?:;|(?=\s*\{))/.source),inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+s.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+s.source+"$"),alias:"url"}}},selector:{pattern:RegExp(`(^|[{}\\s])[^{}\\s](?:[^{};"'\\s]|\\s+(?![\\s{])|`+s.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:s,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},a.languages.css.atrule.inside.rest=a.languages.css;var r=a.languages.markup;r&&(r.tag.addInlined("style","css"),r.tag.addAttribute("style","css"))})(n),n.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},n.languages.javascript=n.languages.extend("clike",{"class-name":[n.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+(/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source)+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),n.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,n.languages.insertBefore("javascript","keyword",{regex:{pattern:RegExp(/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source+/\//.source+"(?:"+/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/.source+"|"+/(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/.source+")"+/(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source),lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:n.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:n.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:n.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:n.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:n.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),n.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:n.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),n.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),n.languages.markup&&(n.languages.markup.tag.addInlined("script","javascript"),n.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),n.languages.js=n.languages.javascript,(function(){if(typeof n>"u"||typeof document>"u")return;Element.prototype.matches||(Element.prototype.matches=Element.prototype.msMatchesSelector||Element.prototype.webkitMatchesSelector);var a="Loading…",s=function(m,g){return"✖ Error "+m+" while fetching file: "+g},r="✖ Error: File does not exist or is empty",o={js:"javascript",py:"python",rb:"ruby",ps1:"powershell",psm1:"powershell",sh:"bash",bat:"batch",h:"c",tex:"latex"},i="data-src-status",l="loading",u="loaded",c="failed",d="pre[data-src]:not(["+i+'="'+u+'"]):not(['+i+'="'+l+'"])';function f(m,g,E){var y=new XMLHttpRequest;y.open("GET",m,!0),y.onreadystatechange=function(){y.readyState==4&&(y.status<400&&y.responseText?g(y.responseText):y.status>=400?E(s(y.status,y.statusText)):E(r))},y.send(null)}function _(m){var g=/^\s*(\d+)\s*(?:(,)\s*(?:(\d+)\s*)?)?$/.exec(m||"");if(g){var E=Number(g[1]),y=g[2],w=g[3];return y?w?[E,Number(w)]:[E,void 0]:[E,E]}}n.hooks.add("before-highlightall",function(m){m.selector+=", "+d}),n.hooks.add("before-sanity-check",function(m){var g=m.element;if(g.matches(d)){m.code="",g.setAttribute(i,l);var E=g.appendChild(document.createElement("CODE"));E.textContent=a;var y=g.getAttribute("data-src"),w=m.language;if(w==="none"){var C=(/\.(\w+)$/.exec(y)||[,"none"])[1];w=o[C]||C}n.util.setLanguage(E,w),n.util.setLanguage(g,w);var I=n.plugins.autoloader;I&&I.loadLanguages(w),f(y,function(P){g.setAttribute(i,u);var R=_(g.getAttribute("data-range"));if(R){var L=P.split(/\r\n?|\n/g),k=R[0],ee=R[1]==null?L.length:R[1];k<0&&(k+=L.length),k=Math.max(0,Math.min(k-1,L.length)),ee<0&&(ee+=L.length),ee=Math.max(0,Math.min(ee,L.length)),P=L.slice(k,ee).join(` +`),g.hasAttribute("data-start")||g.setAttribute("data-start",String(k+1))}E.textContent=P,n.highlightElement(E)},function(P){g.setAttribute(i,c),E.textContent=P})}}),n.plugins.fileHighlight={highlight:function(g){for(var E=(g||document).querySelectorAll(d),y=0,w;w=E[y++];)n.highlightElement(w)}};var h=!1;n.fileHighlight=function(){h||(console.warn("Prism.fileHighlight is deprecated. Use `Prism.plugins.fileHighlight.highlight` instead."),h=!0),n.plugins.fileHighlight.highlight.apply(this,arguments)}})()})(Es)),Es.exports}var Gh=Hh();const Hi=Bh(Gh);(function(e){function t(n,a){return"___"+n.toUpperCase()+a+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,a,s,r){if(n.language===a){var o=n.tokenStack=[];n.code=n.code.replace(s,function(i){if(typeof r=="function"&&!r(i))return i;for(var l=o.length,u;n.code.indexOf(u=t(a,l))!==-1;)++l;return o[l]=i,u}),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,a){if(n.language!==a||!n.tokenStack)return;n.grammar=e.languages[a];var s=0,r=Object.keys(n.tokenStack);function o(i){for(var l=0;l=r.length);l++){var u=i[l];if(typeof u=="string"||u.content&&typeof u.content=="string"){var c=r[s],d=n.tokenStack[c],f=typeof u=="string"?u:u.content,_=t(a,c),h=f.indexOf(_);if(h>-1){++s;var m=f.substring(0,h),g=new e.Token(a,e.tokenize(d,n.grammar),"language-"+a,d),E=f.substring(h+_.length),y=[];m&&y.push.apply(y,o([m])),y.push(g),E&&y.push.apply(y,o([E])),typeof u=="string"?i.splice.apply(i,[l,1].concat(y)):u.content=y}}else u.content&&o(u.content)}return i}o(n.tokens)}}})})(Prism);var Gi={},qi;function qh(){return qi||(qi=1,(function(e){var t=/\/\*[\s\S]*?\*\/|\/\/.*|#(?!\[).*/,n=[{pattern:/\b(?:false|true)\b/i,alias:"boolean"},{pattern:/(::\s*)\b[a-z_]\w*\b(?!\s*\()/i,greedy:!0,lookbehind:!0},{pattern:/(\b(?:case|const)\s+)\b[a-z_]\w*(?=\s*[;=])/i,greedy:!0,lookbehind:!0},/\b(?:null)\b/i,/\b[A-Z_][A-Z0-9_]*\b(?!\s*\()/],a=/\b0b[01]+(?:_[01]+)*\b|\b0o[0-7]+(?:_[0-7]+)*\b|\b0x[\da-f]+(?:_[\da-f]+)*\b|(?:\b\d+(?:_\d+)*\.?(?:\d+(?:_\d+)*)?|\B\.\d+)(?:e[+-]?\d+)?/i,s=/|\?\?=?|\.{3}|\??->|[!=]=?=?|::|\*\*=?|--|\+\+|&&|\|\||<<|>>|[?~]|[/^|%*&<>.+-]=?/,r=/[{}\[\](),:;]/;e.languages.php={delimiter:{pattern:/\?>$|^<\?(?:php(?=\s)|=)?/i,alias:"important"},comment:t,variable:/\$+(?:\w+\b|(?=\{))/,package:{pattern:/(namespace\s+|use\s+(?:function\s+)?)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,lookbehind:!0,inside:{punctuation:/\\/}},"class-name-definition":{pattern:/(\b(?:class|enum|interface|trait)\s+)\b[a-z_]\w*(?!\\)\b/i,lookbehind:!0,alias:"class-name"},"function-definition":{pattern:/(\bfunction\s+)[a-z_]\w*(?=\s*\()/i,lookbehind:!0,alias:"function"},keyword:[{pattern:/(\(\s*)\b(?:array|bool|boolean|float|int|integer|object|string)\b(?=\s*\))/i,alias:"type-casting",greedy:!0,lookbehind:!0},{pattern:/([(,?]\s*)\b(?:array(?!\s*\()|bool|callable|(?:false|null)(?=\s*\|)|float|int|iterable|mixed|object|self|static|string)\b(?=\s*\$)/i,alias:"type-hint",greedy:!0,lookbehind:!0},{pattern:/(\)\s*:\s*(?:\?\s*)?)\b(?:array(?!\s*\()|bool|callable|(?:false|null)(?=\s*\|)|float|int|iterable|mixed|never|object|self|static|string|void)\b/i,alias:"return-type",greedy:!0,lookbehind:!0},{pattern:/\b(?:array(?!\s*\()|bool|float|int|iterable|mixed|object|string|void)\b/i,alias:"type-declaration",greedy:!0},{pattern:/(\|\s*)(?:false|null)\b|\b(?:false|null)(?=\s*\|)/i,alias:"type-declaration",greedy:!0,lookbehind:!0},{pattern:/\b(?:parent|self|static)(?=\s*::)/i,alias:"static-context",greedy:!0},{pattern:/(\byield\s+)from\b/i,lookbehind:!0},/\bclass\b/i,{pattern:/((?:^|[^\s>:]|(?:^|[^-])>|(?:^|[^:]):)\s*)\b(?:abstract|and|array|as|break|callable|case|catch|clone|const|continue|declare|default|die|do|echo|else|elseif|empty|enddeclare|endfor|endforeach|endif|endswitch|endwhile|enum|eval|exit|extends|final|finally|fn|for|foreach|function|global|goto|if|implements|include|include_once|instanceof|insteadof|interface|isset|list|match|namespace|never|new|or|parent|print|private|protected|public|readonly|require|require_once|return|self|static|switch|throw|trait|try|unset|use|var|while|xor|yield|__halt_compiler)\b/i,lookbehind:!0}],"argument-name":{pattern:/([(,]\s*)\b[a-z_]\w*(?=\s*:(?!:))/i,lookbehind:!0},"class-name":[{pattern:/(\b(?:extends|implements|instanceof|new(?!\s+self|\s+static))\s+|\bcatch\s*\()\b[a-z_]\w*(?!\\)\b/i,greedy:!0,lookbehind:!0},{pattern:/(\|\s*)\b[a-z_]\w*(?!\\)\b/i,greedy:!0,lookbehind:!0},{pattern:/\b[a-z_]\w*(?!\\)\b(?=\s*\|)/i,greedy:!0},{pattern:/(\|\s*)(?:\\?\b[a-z_]\w*)+\b/i,alias:"class-name-fully-qualified",greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/(?:\\?\b[a-z_]\w*)+\b(?=\s*\|)/i,alias:"class-name-fully-qualified",greedy:!0,inside:{punctuation:/\\/}},{pattern:/(\b(?:extends|implements|instanceof|new(?!\s+self\b|\s+static\b))\s+|\bcatch\s*\()(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,alias:"class-name-fully-qualified",greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/\b[a-z_]\w*(?=\s*\$)/i,alias:"type-declaration",greedy:!0},{pattern:/(?:\\?\b[a-z_]\w*)+(?=\s*\$)/i,alias:["class-name-fully-qualified","type-declaration"],greedy:!0,inside:{punctuation:/\\/}},{pattern:/\b[a-z_]\w*(?=\s*::)/i,alias:"static-context",greedy:!0},{pattern:/(?:\\?\b[a-z_]\w*)+(?=\s*::)/i,alias:["class-name-fully-qualified","static-context"],greedy:!0,inside:{punctuation:/\\/}},{pattern:/([(,?]\s*)[a-z_]\w*(?=\s*\$)/i,alias:"type-hint",greedy:!0,lookbehind:!0},{pattern:/([(,?]\s*)(?:\\?\b[a-z_]\w*)+(?=\s*\$)/i,alias:["class-name-fully-qualified","type-hint"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/(\)\s*:\s*(?:\?\s*)?)\b[a-z_]\w*(?!\\)\b/i,alias:"return-type",greedy:!0,lookbehind:!0},{pattern:/(\)\s*:\s*(?:\?\s*)?)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,alias:["class-name-fully-qualified","return-type"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}}],constant:n,function:{pattern:/(^|[^\\\w])\\?[a-z_](?:[\w\\]*\w)?(?=\s*\()/i,lookbehind:!0,inside:{punctuation:/\\/}},property:{pattern:/(->\s*)\w+/,lookbehind:!0},number:a,operator:s,punctuation:r};var o={pattern:/\{\$(?:\{(?:\{[^{}]+\}|[^{}]+)\}|[^{}])+\}|(^|[^\\{])\$+(?:\w+(?:\[[^\r\n\[\]]+\]|->\w+)?)/,lookbehind:!0,inside:e.languages.php},i=[{pattern:/<<<'([^']+)'[\r\n](?:.*[\r\n])*?\1;/,alias:"nowdoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<<'[^']+'|[a-z_]\w*;$/i,alias:"symbol",inside:{punctuation:/^<<<'?|[';]$/}}}},{pattern:/<<<(?:"([^"]+)"[\r\n](?:.*[\r\n])*?\1;|([a-z_]\w*)[\r\n](?:.*[\r\n])*?\2;)/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<<(?:"[^"]+"|[a-z_]\w*)|[a-z_]\w*;$/i,alias:"symbol",inside:{punctuation:/^<<<"?|[";]$/}},interpolation:o}},{pattern:/`(?:\\[\s\S]|[^\\`])*`/,alias:"backtick-quoted-string",greedy:!0},{pattern:/'(?:\\[\s\S]|[^\\'])*'/,alias:"single-quoted-string",greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,alias:"double-quoted-string",greedy:!0,inside:{interpolation:o}}];e.languages.insertBefore("php","variable",{string:i,attribute:{pattern:/#\[(?:[^"'\/#]|\/(?![*/])|\/\/.*$|#(?!\[).*$|\/\*(?:[^*]|\*(?!\/))*\*\/|"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*')+\](?=\s*[a-z$#])/im,greedy:!0,inside:{"attribute-content":{pattern:/^(#\[)[\s\S]+(?=\]$)/,lookbehind:!0,inside:{comment:t,string:i,"attribute-class-name":[{pattern:/([^:]|^)\b[a-z_]\w*(?!\\)\b/i,alias:"class-name",greedy:!0,lookbehind:!0},{pattern:/([^:]|^)(?:\\?\b[a-z_]\w*)+/i,alias:["class-name","class-name-fully-qualified"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}}],constant:n,number:a,operator:s,punctuation:r}},delimiter:{pattern:/^#\[|\]$/,alias:"punctuation"}}}}),e.hooks.add("before-tokenize",function(l){if(/<\?/.test(l.code)){var u=/<\?(?:[^"'/#]|\/(?![*/])|("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|(?:\/\/|#(?!\[))(?:[^?\n\r]|\?(?!>))*(?=$|\?>|[\r\n])|#\[|\/\*(?:[^*]|\*(?!\/))*(?:\*\/|$))*?(?:\?>|$)/g;e.languages["markup-templating"].buildPlaceholders(l,"php",u)}}),e.hooks.add("after-tokenize",function(l){e.languages["markup-templating"].tokenizePlaceholders(l,"php")})})(Prism)),Gi}qh();const zh={class:"page"},Kh={key:2},Wh={class:"script-detail-meta"},Jh=["innerHTML"],Yh={key:1},Xh={class:"script-meta"},Zh={key:0},Qh={class:"scope-name"},em={class:"script-info-panel"},tm={key:0,class:"info-row"},nm={class:"info-value"},am={key:1,class:"info-row"},sm={class:"info-value"},rm={key:2,class:"info-row"},im={class:"info-value"},om={key:1,class:"devices-panel"},lm={class:"block-title"},um={key:2,class:"devices-panel"},cm={class:"block-title"},dm={key:3,class:"devices-panel"},fm={key:2,class:"code-block"},pm=["innerHTML"],vm={key:0,class:"form-group"},gm={key:0,class:"form-group"},hm={__name:"ScriptDetailPage",setup(e){const t=as(),n=Sn(),a=kt(),s=wn(),r=jt(),{areaOptions:o,showAssignModal:i,selectedAreaId:l,assignLoading:u,assignError:c,openAssign:d,submitAssignCore:f}=Er(),_=Q(()=>t.params.type),h=Q(()=>t.params.id),m=J(!1),g=Q(()=>_.value==="actions"),E=Q(()=>_.value==="regular"),y=Q(()=>_.value==="scopes"),w=Q(()=>{var p,b,A;const U=[];return!y.value&&r.has("scripts.edit")&&((p=k.value)!=null&&p.area_id?U.push({label:"Change area",icon:"ph-map-pin",onSelect:ke},{label:"Unassign from area",icon:"ph-x-circle",onSelect:Oe}):U.push({label:"Assign to area",icon:"ph-map-pin",onSelect:ke})),g.value&&r.has("scripts.run")&&U.push({label:"Run",icon:"ph-play",disabled:((b=k.value)==null?void 0:b.state)!=="enabled"||n.isRunning((A=k.value)==null?void 0:A.alias),onSelect:Y}),U}),C=Q(()=>g.value?"Actions":E.value?"Regular":y.value?"Scope":"Script"),I=Q(()=>`Loading ${C.value.toLowerCase()} details`),P=Q(()=>g.value?n.isLoadingActions:E.value?n.isLoadingRegular:y.value?n.isLoadingScopes||n.isLoadingActions||n.isLoadingRegular:!1),R=Q(()=>g.value?n.errorActions:E.value?n.errorRegular:y.value?n.errorScopes:null),L=Q(()=>g.value?n.actions.length>0:E.value?n.regular.length>0:y.value?n.scopes.length>0:!1),k=Q(()=>{const U=h.value;return U?g.value?n.actionByAlias(U):E.value?n.regularByAlias(U):y.value?n.scopeByName(U):null:null}),ee=Q(()=>{const U=h.value;return!U||!y.value?[]:n.actionsByScope(U)}),le=Q(()=>{const U=h.value;return!U||!y.value?[]:n.regularByScope(U)}),fe=Q(()=>{var p;const U=(p=k.value)==null?void 0:p.area_id;return U&&a.areasById[String(U)]||null}),ge=Q(()=>y.value?n.isLoadingScopeCode:!1),B=Q(()=>y.value?n.errorScopeCode:null),W=Q(()=>{var U;return g.value||E.value?((U=k.value)==null?void 0:U.code)||"":y.value?n.currentScopeCode:""}),Z=Q(()=>{const U=W.value;return U?Hi.highlight(U,Hi.languages.php,"php"):""});function Y(){var p;if(!((p=k.value)!=null&&p.alias))return;const U=k.value.params_schema;if(U&&Object.keys(U).length>0){m.value=!0;return}te(k.value.alias,{})}async function te(U,p){var A,V;const b=await n.runScript(U,p);b!=null&&b.ok?s.success({title:`Ran ${U}`,text:(A=n.lastRunResult)!=null&&A.execTime?`Exec time: ${n.lastRunResult.execTime}`:void 0}):s.error({title:`Failed ${U}`,text:((V=b==null?void 0:b.error)==null?void 0:V.message)||"Unknown error"})}async function ve(U){var V,K;const p=h.value;if(!p)return;let b;g.value?b=await n.setActionState(p,U):E.value?b=await n.setRegularState(p,U):y.value&&(b=await n.setScopeState(p,U));const A=((V=k.value)==null?void 0:V.alias)||p;b&&!b.ok?s.error({title:`Failed to ${U?"enable":"disable"} ${A}`,text:((K=b.error)==null?void 0:K.message)||"Unknown error"}):b&&s.success({title:`${U?"Enabled":"Disabled"} ${A}`})}function ke(){var U;d((U=k.value)==null?void 0:U.area_id)}async function Pe(){var b;const U=(b=k.value)==null?void 0:b.id,p=await f(U,n.assignToArea.bind(n));p!=null&&p.ok&&s.success({title:"Assigned",text:"Script assigned to area successfully"})}const be=J(!1),Ge=J(""),Ue=J(!1),De=J("");function Oe(){k.value&&(Ge.value=`Are you sure you want to unassign script "${k.value.name||k.value.alias}" from its area?`,De.value="",be.value=!0)}async function M(){var p;if(!k.value)return;Ue.value=!0,De.value="";const U=await n.unassignFromArea(k.value.id);if(Ue.value=!1,!U.ok){De.value=((p=U.error)==null?void 0:p.message)||"Failed to unassign script";return}be.value=!1,s.success({title:"Unassigned",text:"Script unassigned from area successfully"})}async function se(){const U=h.value;!U||!y.value||await n.loadScopeCode(U)}async function H(){h.value&&(g.value&&n.actions.length===0?await n.loadActions():E.value&&n.regular.length===0?await n.loadRegular():y.value&&n.scopes.length===0&&await n.loadScopes(),y.value&&(n.actions.length===0&&await n.loadActions(),n.regular.length===0&&await n.loadRegular(),await se()),a.areas.length===0&&await a.loadAreas())}const F=[{key:"alias",label:"Alias"},{key:"name",label:"Name"},{key:"state",label:"State"}];return bt(()=>{H()}),ha(()=>{n.clearScopeCode()}),wt(()=>[t.params.type,t.params.id],([U,p],[b,A])=>{(U!==b||p!==A)&&(n.clearScopeCode(),H())}),(U,p)=>{const b=cn("router-link");return S(),G("section",zh,[P.value?(S(),q(St,{key:0,text:I.value},null,8,["text"])):R.value&&!L.value?(S(),q(pt,{key:1,title:`${C.value} loading failed`,error:R.value,retry:H},null,8,["title","error"])):k.value?(S(),G("div",Kh,[$(v(Rt),{title:k.value.name||k.value.alias||k.value.name,kicker:C.value},{actions:x(()=>[v(r).has("scripts.edit")?(S(),q(v(kl),{key:0,"model-value":k.value.state==="enabled",label:"Enabled","onUpdate:modelValue":p[0]||(p[0]=A=>ve(A))},null,8,["model-value"])):ne("",!0),$(Tr,{items:w.value},null,8,["items"])]),_:1},8,["title","kicker"]),T("div",Wh,[k.value.icon?(S(),G("div",{key:0,innerHTML:k.value.icon,class:"script-icon"},null,8,Jh)):ne("",!0),k.value.description?(S(),G("p",Yh,O(k.value.description),1)):ne("",!0),T("div",Xh,[$(v(_e),{variant:k.value.state==="enabled"?"success":"secondary"},{default:x(()=>[N(O(k.value.state),1)]),_:1},8,["variant"]),T("code",null,O(k.value.alias||k.value.name),1),k.value.author?(S(),G("small",Zh,O(k.value.author),1)):ne("",!0),$(Rr,{area:fe.value,areaId:k.value.area_id},null,8,["area","areaId"]),k.value.scope?(S(),q(b,{key:1,to:{name:"script-detail",params:{type:"scopes",id:k.value.scope}},class:"scope-link"},{default:x(()=>[p[8]||(p[8]=T("span",{class:"scope-label"},"Scope",-1)),T("span",Qh,O(k.value.scope),1),p[9]||(p[9]=T("i",{class:"ph ph-arrow-right"},null,-1))]),_:1},8,["to"])):ne("",!0)]),T("div",em,[k.value.filename?(S(),G("div",tm,[p[10]||(p[10]=T("span",{class:"info-label text-muted"},"File:",-1)),T("span",nm,O(k.value.filename),1)])):ne("",!0),k.value.path?(S(),G("div",am,[p[11]||(p[11]=T("span",{class:"info-label text-muted"},"Path:",-1)),T("span",sm,O(k.value.path),1)])):ne("",!0),k.value.created_by?(S(),G("div",rm,[p[12]||(p[12]=T("span",{class:"info-label text-muted"},"Author:",-1)),T("span",im,O(k.value.created_by),1)])):ne("",!0)])]),y.value?ne("",!0):(S(),q($r,{key:0,item:k.value,emptyMessage:"This script is not assigned to any area.",onAssign:ke},{action:x(()=>[v(r).has("scripts.edit")?(S(),q(v(de),{key:0,variant:"primary",icon:"ph-map-pin",onClick:ke},{default:x(()=>{var A;return[N(O((A=k.value)!=null&&A.area_id?"Change area":"Assign to area"),1)]}),_:1})):ne("",!0)]),_:1},8,["item"])),y.value&&ee.value.length>0?(S(),G("div",om,[T("div",lm,"Action scripts ("+O(ee.value.length)+")",1),$(v(Nn),{rows:ee.value,columns:F},{"cell-state":x(({row:A})=>[$(v(_e),{variant:A.state==="enabled"?"success":"secondary"},{default:x(()=>[N(O(A.state),1)]),_:2},1032,["variant"])]),"cell-alias":x(({row:A})=>[$(b,{to:{name:"script-detail",params:{type:"actions",id:A.alias}},class:"script-link"},{default:x(()=>[N(O(A.alias),1)]),_:2},1032,["to"])]),_:1},8,["rows"])])):ne("",!0),y.value&&le.value.length>0?(S(),G("div",um,[T("div",cm,"Regular scripts ("+O(le.value.length)+")",1),$(v(Nn),{rows:le.value,columns:F},{"cell-state":x(({row:A})=>[$(v(_e),{variant:A.state==="enabled"?"success":"secondary"},{default:x(()=>[N(O(A.state),1)]),_:2},1032,["variant"])]),"cell-alias":x(({row:A})=>[$(b,{to:{name:"script-detail",params:{type:"regular",id:A.alias}},class:"script-link"},{default:x(()=>[N(O(A.alias),1)]),_:2},1032,["to"])]),_:1},8,["rows"])])):ne("",!0),k.value.code||y.value?(S(),G("div",dm,[p[13]||(p[13]=T("div",{class:"block-title"},"Source code",-1)),ge.value?(S(),q(St,{key:0,text:"Loading source code"})):B.value?(S(),q(pt,{key:1,title:"Code loading failed",error:B.value,retry:se},null,8,["error"])):W.value?(S(),G("pre",fm,[T("code",{class:"language-php",innerHTML:Z.value},null,8,pm)])):(S(),q(it,{key:3,title:"No code",message:"Source code is not available."}))])):ne("",!0)])):(S(),q(it,{key:3,title:"Not found",message:"The requested script does not exist."})),$(v(at),{open:v(i),title:"Assign to area","onUpdate:open":p[3]||(p[3]=A=>i.value=A)},{footer:x(()=>[$(v(de),{variant:"secondary",onClick:p[2]||(p[2]=A=>i.value=!1)},{default:x(()=>[...p[14]||(p[14]=[N("Cancel",-1)])]),_:1}),$(v(de),{variant:"primary",icon:"ph-check",loading:v(u),onClick:Pe},{default:x(()=>[...p[15]||(p[15]=[N(" Assign ",-1)])]),_:1},8,["loading"])]),default:x(()=>[$(v(rs),{modelValue:v(l),"onUpdate:modelValue":p[1]||(p[1]=A=>Ve(l)?l.value=A:null),label:"Area",options:v(o),icon:"ph-map-trifold"},null,8,["modelValue","options"]),v(c)?(S(),G("div",vm,[$(v(Ze),{variant:"danger"},{default:x(()=>[N(O(v(c)),1)]),_:1})])):ne("",!0)]),_:1},8,["open"]),$(v(at),{open:be.value,title:"Unassign from area","onUpdate:open":p[5]||(p[5]=A=>be.value=A)},{footer:x(()=>[$(v(de),{variant:"secondary",onClick:p[4]||(p[4]=A=>be.value=!1)},{default:x(()=>[...p[16]||(p[16]=[N("Cancel",-1)])]),_:1}),$(v(de),{variant:"warning",icon:"ph-x-circle",loading:Ue.value,onClick:M},{default:x(()=>[...p[17]||(p[17]=[N(" Unassign ",-1)])]),_:1},8,["loading"])]),default:x(()=>[T("p",null,O(Ge.value),1),De.value?(S(),G("div",gm,[$(v(Ze),{variant:"danger"},{default:x(()=>[N(O(De.value),1)]),_:1})])):ne("",!0)]),_:1},8,["open"]),g.value&&k.value?(S(),q(Ul,{key:4,open:m.value,script:k.value,"onUpdate:open":p[6]||(p[6]=A=>m.value=A),onRun:p[7]||(p[7]=A=>te(A.alias,A.params))},null,8,["open","script"])):ne("",!0)])}}},mm=ze(hm,[["__scopeId","data-v-c052dd3b"]]),ym={class:"page"},_m={key:3,class:"firmwares-panel"},bm={class:"firmwares-summary"},wm={class:"firmwares-list"},Sm={class:"firmware-header"},km={class:"firmware-id"},Am={class:"firmware-meta"},xm={key:0,class:"firmware-desc"},Cm={key:1,class:"firmware-changelog"},Em={__name:"FirmwaresListPage",setup(e){const t=jl(),n=jt(),a=J(null);async function s(){var i;a.value=null;const o=await t.loadFirmwares();o.ok||(a.value=((i=o.error)==null?void 0:i.message)||"Failed to load catalog")}async function r(){var i;a.value=null;const o=await t.refreshFirmwares();o.ok||(a.value=((i=o.error)==null?void 0:i.message)||"Failed to refresh catalog")}return bt(s),(o,i)=>(S(),G("section",ym,[$(v(Rt),{title:"Firmware Catalog",kicker:"Firmwares"},{actions:x(()=>[v(n).has("firmware.upload")?(S(),q(v(de),{key:0,loading:v(t).isUpdating,icon:"ph-arrow-clockwise",onClick:r},{default:x(()=>[...i[0]||(i[0]=[N(" Refresh Catalog ",-1)])]),_:1},8,["loading"])):ne("",!0)]),_:1}),v(t).isLoadingList?(S(),q(St,{key:0,text:"Loading firmware catalog"})):a.value?(S(),q(pt,{key:1,title:"Catalog loading failed",error:a.value,retry:s},null,8,["error"])):v(t).firmwares.length===0?(S(),q(it,{key:2,title:"No firmwares found",message:"No firmware packages detected in the firmwares directory."})):(S(),G("div",_m,[T("div",bm,[$(v(_e),{variant:"primary"},{default:x(()=>[N("Total: "+O(v(t).firmwares.length),1)]),_:1})]),T("div",wm,[(S(!0),G(Ee,null,Vt(v(t).firmwares,l=>(S(),G("div",{key:l.id,class:"firmware-card"},[T("div",Sm,[T("span",km,O(l.id),1),$(v(_e),{variant:"success"},{default:x(()=>[N(O(l.version),1)]),_:2},1024)]),T("div",Am,[$(v(_e),{variant:"secondary"},{default:x(()=>[N(O(l.device_type),1)]),_:2},1024),l.platform?(S(),q(v(_e),{key:0,variant:"info"},{default:x(()=>[N(O(l.platform),1)]),_:2},1024)):ne("",!0),l.channels?(S(),q(v(_e),{key:1,variant:"warning"},{default:x(()=>[N(O(l.channels)+" ch",1)]),_:2},1024)):ne("",!0)]),l.description?(S(),G("p",xm,O(l.description),1)):ne("",!0),l.changelog?(S(),G("pre",Cm,O(l.changelog),1)):ne("",!0)]))),128))])]))]))}},Rm=ze(Em,[["__scopeId","data-v-c0c73f70"]]),Bl="/logo-cube-square.svg",$m={class:"login-page"},Tm={class:"login-card"},Pm={key:0,class:"login-loading text-muted"},Im={__name:"LoginPage",setup(e){const t=en(),n=Un();bt(()=>{n.isAuthenticated&&t.replace({name:"areas-favorites"})});function a(){Sr(kr())}return(s,r)=>(S(),G("div",$m,[T("div",Tm,[r[2]||(r[2]=T("div",{class:"login-brand"},[T("img",{src:Bl,alt:"Smart Home",class:"brand-logo"}),T("h1",{class:"brand-title"},"Smart Home Server")],-1)),r[3]||(r[3]=T("p",{class:"login-hint text-muted"}," You need to sign in to access the smart home dashboard. ",-1)),$(v(de),{variant:"primary",class:"login-btn",icon:"ph-sign-in",onClick:a},{default:x(()=>[...r[0]||(r[0]=[N(" LOGIN WITH GNEXUS ",-1)])]),_:1}),v(n).isLoading?(S(),G("p",Pm,[...r[1]||(r[1]=[T("i",{class:"ph ph-spinner ph-spin"},null,-1),N(" Checking session… ",-1)])])):ne("",!0)])]))}},Lm=ze(Im,[["__scopeId","data-v-7f18a357"]]),Dm={class:"setup-page"},Om={class:"setup-card"},Fm={class:"setup-form"},Nm={key:0,class:"setup-error text-danger"},Mm={__name:"MobileSetupPage",setup(e){en();const t=J(""),n=J(""),a=J(!1),s=J("");async function r(){n.value="",s.value="";const o=t.value.trim();if(!o){n.value="Server URL is required";return}let i=o;/^https?:\/\//i.test(i)||(i="http://"+i);try{new URL(i)}catch{n.value="Invalid URL format";return}a.value=!0;try{const l=[`${i}/api/v1/about`,`${i}/about`];let u=!1;for(const c of l)try{const d=new AbortController,f=setTimeout(()=>d.abort(),5e3),_=await fetch(c,{method:"GET",signal:d.signal});if(clearTimeout(f),_.ok||_.status===401){u=!0;break}}catch{}if(!u){s.value="Could not connect to server. Please check the address.",a.value=!1;return}await fp(i),alert("Server address saved. Please restart the app to continue."),Hs.exitApp();return}catch{s.value="Connection check failed. Please try again.",a.value=!1}}return(o,i)=>(S(),G("div",Dm,[T("div",Om,[i[3]||(i[3]=Ic('

Smart Home

Mobile App Setup

Enter the address of your Smart Home server. Example: https://shserv.home or http://192.168.1.10

',3)),T("div",Fm,[$(v(yt),{modelValue:t.value,"onUpdate:modelValue":i[0]||(i[0]=l=>t.value=l),label:"Server URL",placeholder:"https://your-server.com",error:n.value,onKeyup:vd(r,["enter"])},null,8,["modelValue","error"]),$(v(de),{variant:"primary",size:"lg",class:"setup-btn",loading:a.value,onClick:r},{icon:x(()=>[...i[1]||(i[1]=[T("i",{class:"ph ph-check"},null,-1)])]),default:x(()=>[N(" "+O(a.value?"Checking connection…":"Save and continue"),1)]),_:1},8,["loading"])]),s.value?(S(),G("p",Nm,[i[2]||(i[2]=T("i",{class:"ph ph-warning-circle"},null,-1)),N(" "+O(s.value),1)])):ne("",!0)])]))}},Um=ze(Mm,[["__scopeId","data-v-a50065c7"]]),Vm={class:"mobile-auth-page"},jm={class:"mobile-auth-card"},Bm={class:"text-muted"},Hm={__name:"MobileAuthPage",setup(e){const t=en(),n=Un(),a=J("Authenticating…");return bt(async()=>{const s=window.location.hash,r=s.indexOf("?");if(r===-1){a.value="Invalid login link. Redirecting…",setTimeout(()=>t.replace({name:"login"}),1500);return}const o=new URLSearchParams(s.slice(r+1)),i=o.get("token"),l=o.get("expires_in");if(!i){a.value="No token received. Redirecting…",setTimeout(()=>t.replace({name:"login"}),1500);return}is(i,l?parseInt(l,10):null);const u=s.slice(0,r);window.history.replaceState(null,"",u||"#/"),a.value="Loading profile…";try{await n.init(),n.isAuthenticated?t.replace({name:"areas-favorites"}):(a.value="Session invalid. Redirecting…",setTimeout(()=>t.replace({name:"login"}),1500))}catch{a.value="Failed to load profile. Redirecting…",setTimeout(()=>t.replace({name:"login"}),1500)}}),(s,r)=>(S(),G("div",Vm,[T("div",jm,[r[0]||(r[0]=T("div",{class:"spinner"},null,-1)),T("p",Bm,O(a.value),1)])]))}},Gm=ze(Hm,[["__scopeId","data-v-9c0afc74"]]),qm=[{path:"/",redirect:"/areas/favorites"},{path:"/login",name:"login",component:Lm,meta:{public:!0}},{path:"/mobile-setup",name:"mobile-setup",component:Um,meta:{public:!0}},{path:"/mobile-auth",name:"mobile-auth",component:Gm,meta:{public:!0}},{path:"/areas/favorites",name:"areas-favorites",component:qp,meta:{permission:"areas.view"}},{path:"/areas/tree",name:"areas-tree",component:ov,meta:{permission:"areas.view"}},{path:"/areas/:id",name:"area-detail",component:kg,meta:{permission:"areas.view"}},{path:"/devices",name:"devices",component:$g,meta:{permission:"devices.view"}},{path:"/devices/scanning",name:"devices-scanning",component:qg,meta:{permission:"devices.scan"}},{path:"/devices/:id",name:"device-detail",component:Ph,meta:{permission:"devices.view"}},{path:"/scripts/actions",name:"scripts-actions",component:Dh,meta:{permission:"scripts.run"}},{path:"/scripts/regular",name:"scripts-regular",component:Nh,meta:{permission:"scripts.view"}},{path:"/scripts/scopes",name:"scripts-scopes",component:jh,meta:{permission:"scripts.view"}},{path:"/scripts/:type(actions|regular|scopes)/:id",name:"script-detail",component:mm,meta:{permission:"scripts.view"}},{path:"/firmwares",name:"firmwares",component:Rm,meta:{permission:"firmware.view"}},{path:"/:pathMatch(.*)*",name:"not-found",component:()=>gr(()=>import("./NotFoundPage-YUIFZ53x.js"),[])}],Kn="[vue:router]",Wn=wr(),Hl=Gf({history:kf(),routes:qm});Hl.beforeEach(async(e,t,n)=>{var r,o;if(Nt()&&e.name!=="mobile-setup")try{if(!await vp()){Wn&&console.debug(Kn,"Redirect: native app missing server URL → mobile-setup"),n({name:"mobile-setup"});return}}catch{if(e.name!=="mobile-setup"){n({name:"mobile-setup"});return}}const a=Un();if(Wn&&console.debug(Kn,`Navigate: ${t.fullPath||"init"} → ${e.fullPath}`),await a.init(),(r=e.meta)!=null&&r.public){if(e.name==="login"&&a.isAuthenticated){Wn&&console.debug(Kn,"Redirect: authenticated user at login → areas-favorites"),n({name:"areas-favorites"});return}n();return}if(!a.isAuthenticated){Wn&&console.debug(Kn,"Redirect: unauthenticated → login"),n({name:"login"});return}const s=(o=e.meta)==null?void 0:o.permission;if(s&&!a.hasPermission(s)){Wn&&console.warn(Kn,`Forbidden: ${e.fullPath} requires ${s}`),n({name:"areas-favorites"});return}n()});function zm(e){const t="[vue:error]";e.config.errorHandler=(n,a,s)=>{const r=(n==null?void 0:n.message)||String(n);console.error(t,`Vue ${s}`,r,(n==null?void 0:n.stack)||"")},window.addEventListener("unhandledrejection",n=>{var r;const a=n.reason,s=(a==null?void 0:a.message)||((r=a==null?void 0:a.error)==null?void 0:r.message)||String(a);console.error(t,"Unhandled rejection:",s,(a==null?void 0:a.stack)||""),n.preventDefault()}),window.addEventListener("error",n=>{const a=n.error,s=(a==null?void 0:a.message)||n.message||"Unknown error";console.error(t,`Global error: ${s}`,`at ${n.filename}:${n.lineno}:${n.colno}`,(a==null?void 0:a.stack)||"")})}const Rs="[vue:pinia]",Km=e=>{if(!wr())return;const{store:t,options:n}=e,a=n.id,s=Object.keys(n.actions||{});for(const r of s){const o=t[r];t[r]=async function(...i){console.debug(Rs,`${a}.${r}(${i.map(u=>$l(u)).join(", ")})`);const l=performance.now();try{const u=await o.apply(this,i);return console.debug(Rs,`${a}.${r} completed in ${(performance.now()-l).toFixed(1)}ms`),u}catch(u){throw console.error(Rs,`${a}.${r} failed: ${(u==null?void 0:u.message)||u}`),u}}}};function zi(e){try{const t=new URL(e);if(t.host==="auth"&&t.pathname==="/callback"){const n=t.searchParams.get("token"),a=t.searchParams.get("expires_in");n&&(is(n,a?parseInt(a,10):null),window.location.reload())}}catch{}}async function Wm(){if(await dp(),await gp(),Nt()){try{const a=await Hs.getLaunchUrl();if(a!=null&&a.url){zi(a.url);return}}catch{}Hs.addListener("appUrlOpen",a=>{zi(a.url)})}const e=md(Tp);zm(e);const t=bd();t.use(Km),e.use(t).use(Hl),await Un().init(),e.mount("#app")}Wm();export{ep as G,hr as W,$ as a,G as c,S as o,v as u}; diff --git a/server/dist/assets/index-VysuaK1T.css b/server/dist/assets/index-VysuaK1T.css new file mode 100644 index 0000000..89f944e --- /dev/null +++ b/server/dist/assets/index-VysuaK1T.css @@ -0,0 +1 @@ +@charset "UTF-8";.nav-topbar-brand img{width:50px!important;height:50px!important}.error-meta[data-v-f1e6bcb8]{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}.error-actions[data-v-f1e6bcb8]{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-top:12px}.error-boundary[data-v-1e10ea7f]{padding:24px}.area-favorites-list[data-v-f8795944]{display:grid;gap:12px;margin:0;padding:0;list-style:none}.area-favorite-card[data-v-f8795944]{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:14px;padding:14px 16px;border:1px solid rgba(192,202,245,.12);background:var(--color-panel);cursor:pointer;transition:background .15s ease}.area-favorite-card[data-v-f8795944]:hover{background:var(--color-panel-strong)}.area-favorite-icon[data-v-f8795944]{display:flex;align-items:center;justify-content:center;width:40px;height:40px;border:2px solid var(--color-primary);color:var(--color-primary);font-size:20px}.area-favorite-info[data-v-f8795944]{min-width:0}.area-favorite-title[data-v-f8795944]{margin:0 0 6px;font-size:18px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.area-favorite-meta[data-v-f8795944]{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin:0;color:var(--color-muted);font-size:13px}.area-favorite-parent[data-v-f8795944]{color:var(--color-muted)}.area-favorite-parent .parent-link[data-v-f8795944]{color:var(--color-primary);text-decoration:none}.area-favorite-parent .parent-link[data-v-f8795944]:hover{text-decoration:underline}@media(max-width:720px){.area-favorite-card[data-v-f8795944]{grid-template-columns:auto 1fr;gap:12px}.area-favorite-actions[data-v-f8795944]{grid-column:1 / -1;justify-self:end}}.form-group[data-v-5f02f384]{margin-bottom:16px}.area-link[data-v-91230b95]{text-decoration:none}.devices-panel[data-v-92cae82c]{margin-bottom:24px}.block-title[data-v-92cae82c]{font-weight:700;text-transform:uppercase;margin-bottom:12px;color:var(--color-primary)}.area-assigned[data-v-92cae82c]{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.area-card[data-v-92cae82c]{display:flex;align-items:center;gap:10px;padding:10px 14px;background:var(--color-panel);border:1px solid rgba(192,202,245,.12);color:inherit;text-decoration:none;transition:border-color .15s}.area-card[data-v-92cae82c]:hover{border-color:var(--color-primary)}.area-card-icon[data-v-92cae82c]{font-size:20px}.area-card-info[data-v-92cae82c]{display:flex;flex-direction:column;gap:2px}.area-card-info small[data-v-92cae82c]{font-size:12px}.form-group[data-v-92cae82c]{margin-bottom:16px}.device-channels-state[data-v-08541c71]{display:inline-flex;align-items:center}.channels-grid[data-v-08541c71]{display:inline-flex;flex-wrap:wrap;gap:6px;align-items:center}.unknown-type[data-v-08541c71]{font-size:12px}.raw-json[data-v-08541c71]{font-size:10px;margin:4px 0 0;max-width:400px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.device-cell[data-v-32549911]{display:flex;align-items:center;gap:10px}.device-icon[data-v-32549911]{font-size:20px}.device-info[data-v-32549911]{display:flex;flex-direction:column;gap:2px}.device-name-row[data-v-32549911]{display:inline-flex;align-items:center;gap:6px}.status-dot[data-v-32549911]{display:inline-block;width:8px;height:8px;border-radius:50%;flex-shrink:0;background:currentColor;box-shadow:0 0 4px currentColor}.device-info small[data-v-32549911]{font-size:12px}.device-link[data-v-32549911]{color:inherit;text-decoration:none}.device-link:hover strong[data-v-32549911]{color:var(--color-primary)}.script-link[data-v-1ead75a7]{color:var(--color-primary);text-decoration:none}.scope-link[data-v-1ead75a7]{display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border:1px solid var(--color-primary);color:var(--color-primary);text-decoration:none;font-size:13px;cursor:pointer;transition:background .15s,color .15s}.scope-link[data-v-1ead75a7]:hover{background:var(--color-primary);color:var(--color-bg)}.scope-label[data-v-1ead75a7]{text-transform:uppercase;font-size:11px;font-weight:700;opacity:.8}.muted[data-v-1ead75a7]{color:var(--color-muted)}.page-header:has(>.page-header-actions .page-actions-dropdown){overflow:visible}.page-actions-dropdown .btn-icon{width:44px;height:44px;font-size:24px}.page-actions-dropdown .dropdown-menu{left:auto;right:0;transform-origin:top right}.script-run-form[data-v-c51fae66]{display:flex;flex-direction:column;gap:16px}.form-field[data-v-c51fae66]{display:flex;flex-direction:column;gap:4px}.field-error[data-v-c51fae66]{color:var(--color-danger, #ef4444);font-size:12px;margin:0}.script-icon[data-v-1576dd59]{font-size:32px}.script-meta[data-v-1576dd59]{display:flex;flex-wrap:wrap;gap:8px;align-items:center}.area-meta[data-v-757a0469]{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:24px}.area-parent[data-v-757a0469]{color:var(--color-muted)}.actions-panel[data-v-757a0469],.devices-panel[data-v-757a0469],.scripts-panel[data-v-757a0469]{margin-bottom:24px}.block-title[data-v-757a0469]{font-weight:700;text-transform:uppercase;margin-bottom:12px;color:var(--color-primary)}.form-group[data-v-757a0469]{margin-bottom:16px}.devices-summary[data-v-635f3900]{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:12px}.scan-filters[data-v-1a01bb19]{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-bottom:24px}.filter-label[data-v-1a01bb19]{font-size:13px;text-transform:uppercase}.devices-summary[data-v-1a01bb19]{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:12px}.device-cell[data-v-1a01bb19]{display:flex;align-items:center;gap:10px}.device-icon[data-v-1a01bb19]{font-size:20px;color:var(--color-primary)}.device-info[data-v-1a01bb19]{display:flex;flex-direction:column;gap:2px}.device-info small[data-v-1a01bb19]{color:var(--color-muted);font-size:12px}.firmware[data-v-1a01bb19]{font-size:12px;color:var(--color-muted)}.muted[data-v-1a01bb19]{color:var(--color-muted)}.form-group[data-v-1a01bb19]{margin-bottom:16px}.device-meta[data-v-a9f83185]{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:24px}.script-info-panel[data-v-a9f83185]{display:grid;gap:8px;padding:12px;background:var(--color-panel);border:1px solid rgba(192,202,245,.12);margin-bottom:24px}.info-row[data-v-a9f83185]{display:flex;gap:8px;align-items:baseline}.info-label[data-v-a9f83185]{font-size:12px;text-transform:uppercase;min-width:48px}.info-value[data-v-a9f83185]{font-size:13px;word-break:break-all}.devices-panel[data-v-a9f83185]{margin-bottom:24px}.block-title[data-v-a9f83185]{font-weight:700;text-transform:uppercase;margin-bottom:12px;color:var(--color-primary)}.form-group[data-v-a9f83185]{margin-bottom:16px}.firmware-options[data-v-a9f83185]{display:grid;gap:8px;margin:12px 0}.firmware-option[data-v-a9f83185]{padding:10px 12px;border:1px solid rgba(192,202,245,.12);border-radius:6px;cursor:pointer;background:var(--color-panel)}.firmware-option.active[data-v-a9f83185]{border-color:var(--color-primary);background:#3b82f61a}.fw-version[data-v-a9f83185]{font-weight:600;font-size:13px}.fw-desc[data-v-a9f83185]{font-size:12px;color:var(--color-text-muted);margin-top:2px}.result-alert[data-v-f336617a]{margin-top:24px}.script-link[data-v-c8486788]{color:var(--color-primary)}.script-detail-meta[data-v-c052dd3b]{display:flex;flex-direction:column;gap:16px;margin-bottom:24px}.script-icon[data-v-c052dd3b]{font-size:32px}.script-meta[data-v-c052dd3b]{display:flex;flex-wrap:wrap;gap:8px;align-items:center}.result-alert[data-v-c052dd3b]{margin-top:24px}.devices-panel[data-v-c052dd3b]{margin-bottom:24px}.block-title[data-v-c052dd3b]{font-weight:700;text-transform:uppercase;margin-bottom:12px;color:var(--color-primary)}.script-link[data-v-c052dd3b]{color:var(--color-primary)}.scope-link[data-v-c052dd3b]{display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border:1px solid var(--color-primary);color:var(--color-primary);text-decoration:none;font-size:13px;cursor:pointer;transition:background .15s,color .15s}.scope-link[data-v-c052dd3b]:hover{background:var(--color-primary);color:var(--color-bg)}.scope-label[data-v-c052dd3b]{text-transform:uppercase;font-size:11px;font-weight:700;opacity:.8}.script-info-panel[data-v-c052dd3b]{display:grid;gap:8px;padding:12px;background:var(--color-panel);border:1px solid rgba(192,202,245,.12)}.info-row[data-v-c052dd3b]{display:flex;gap:8px;align-items:baseline}.info-label[data-v-c052dd3b]{font-size:12px;text-transform:uppercase;min-width:48px}.info-value[data-v-c052dd3b]{font-size:13px;word-break:break-all}.code-block[data-v-c052dd3b]{margin:0;padding:14px;overflow-x:auto}.firmwares-summary[data-v-c0c73f70]{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:12px}.firmwares-list[data-v-c0c73f70]{display:grid;gap:12px}.firmware-card[data-v-c0c73f70]{background:var(--color-panel);border:1px solid rgba(192,202,245,.12);border-radius:8px;padding:12px 16px}.firmware-header[data-v-c0c73f70]{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}.firmware-id[data-v-c0c73f70]{font-family:monospace;font-size:13px;word-break:break-all}.firmware-meta[data-v-c0c73f70]{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:8px}.firmware-desc[data-v-c0c73f70]{font-size:13px;color:var(--color-text-muted);margin:0}.firmware-changelog[data-v-c0c73f70]{font-size:12px;background:#0f172a80;padding:8px;border-radius:6px;margin-top:8px;white-space:pre-wrap;word-break:break-word}.login-page[data-v-7f18a357]{display:flex;align-items:center;justify-content:center;min-height:100vh;padding:1rem}.login-card[data-v-7f18a357]{display:flex;flex-direction:column;align-items:center;gap:1.5rem;max-width:360px;width:100%;padding:2rem;text-align:center}.login-brand[data-v-7f18a357]{display:flex;flex-direction:column;align-items:center;gap:.5rem}.brand-logo[data-v-7f18a357]{width:120px;height:120px}.brand-title[data-v-7f18a357]{margin:0;font-size:1.25rem;font-weight:700}.login-hint[data-v-7f18a357]{margin:0;font-size:.875rem;line-height:1.5}.login-btn[data-v-7f18a357]{width:100%}.login-loading[data-v-7f18a357]{margin:0;font-size:.8125rem;display:flex;align-items:center;gap:.375rem}.setup-page[data-v-a50065c7]{display:flex;align-items:center;justify-content:center;min-height:100vh;padding:1rem}.setup-card[data-v-a50065c7]{display:flex;flex-direction:column;align-items:center;gap:1.5rem;max-width:360px;width:100%;padding:2rem;text-align:center}.setup-brand[data-v-a50065c7]{display:flex;flex-direction:column;align-items:center;gap:.5rem}.brand-logo[data-v-a50065c7]{width:120px;height:120px}.brand-title[data-v-a50065c7]{margin:0;font-size:1.25rem;font-weight:700}.brand-subtitle[data-v-a50065c7]{margin:0;font-size:.875rem}.setup-divider[data-v-a50065c7]{width:48px;height:2px;background:currentColor;border-radius:1px}.setup-hint[data-v-a50065c7]{margin:0;font-size:.875rem;line-height:1.5}.setup-form[data-v-a50065c7]{display:flex;flex-direction:column;gap:1rem;width:100%}.setup-btn[data-v-a50065c7]{width:100%}.setup-error[data-v-a50065c7]{margin:0;font-size:.875rem;display:flex;align-items:center;gap:.375rem}.mobile-auth-page[data-v-9c0afc74]{display:flex;align-items:center;justify-content:center;min-height:100vh;padding:1rem}.mobile-auth-card[data-v-9c0afc74]{display:flex;flex-direction:column;align-items:center;gap:1rem;text-align:center}.spinner[data-v-9c0afc74]{width:40px;height:40px;border:3px solid rgba(255,255,255,.2);border-top-color:#12b7f5;border-radius:50%;animation:spin-9c0afc74 1s linear infinite}@keyframes spin-9c0afc74{to{transform:rotate(360deg)}}@font-face{font-family:Phosphor;src:url(/assets/Phosphor-DtdjzkpE.woff2) format("woff2"),url(/assets/Phosphor-BdqudwT5.woff) format("woff"),url(/assets/Phosphor-CDxgqcPu.ttf) format("truetype"),url(/assets/Phosphor-BXRFlF4V.svg#Phosphor) format("svg");font-weight:400;font-style:normal;font-display:block}.ph{font-family:Phosphor!important;speak:never;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;letter-spacing:0;-webkit-font-feature-settings:"liga";-moz-font-feature-settings:"liga=1";-moz-font-feature-settings:"liga";-ms-font-feature-settings:"liga" 1;font-feature-settings:"liga";-webkit-font-variant-ligatures:discretionary-ligatures;font-variant-ligatures:discretionary-ligatures;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.ph.ph-acorn:before{content:""}.ph.ph-address-book:before{content:""}.ph.ph-address-book-tabs:before{content:""}.ph.ph-air-traffic-control:before{content:""}.ph.ph-airplane:before{content:""}.ph.ph-airplane-in-flight:before{content:""}.ph.ph-airplane-landing:before{content:""}.ph.ph-airplane-takeoff:before{content:""}.ph.ph-airplane-taxiing:before{content:""}.ph.ph-airplane-tilt:before{content:""}.ph.ph-airplay:before{content:""}.ph.ph-alarm:before{content:""}.ph.ph-alien:before{content:""}.ph.ph-align-bottom:before{content:""}.ph.ph-align-bottom-simple:before{content:""}.ph.ph-align-center-horizontal:before{content:""}.ph.ph-align-center-horizontal-simple:before{content:""}.ph.ph-align-center-vertical:before{content:""}.ph.ph-align-center-vertical-simple:before{content:""}.ph.ph-align-left:before{content:""}.ph.ph-align-left-simple:before{content:""}.ph.ph-align-right:before{content:""}.ph.ph-align-right-simple:before{content:""}.ph.ph-align-top:before{content:""}.ph.ph-align-top-simple:before{content:""}.ph.ph-amazon-logo:before{content:""}.ph.ph-ambulance:before{content:""}.ph.ph-anchor:before{content:""}.ph.ph-anchor-simple:before{content:""}.ph.ph-android-logo:before{content:""}.ph.ph-angle:before{content:""}.ph.ph-angular-logo:before{content:""}.ph.ph-aperture:before{content:""}.ph.ph-app-store-logo:before{content:""}.ph.ph-app-window:before{content:""}.ph.ph-apple-logo:before{content:""}.ph.ph-apple-podcasts-logo:before{content:""}.ph.ph-approximate-equals:before{content:""}.ph.ph-archive:before{content:""}.ph.ph-armchair:before{content:""}.ph.ph-arrow-arc-left:before{content:""}.ph.ph-arrow-arc-right:before{content:""}.ph.ph-arrow-bend-double-up-left:before{content:""}.ph.ph-arrow-bend-double-up-right:before{content:""}.ph.ph-arrow-bend-down-left:before{content:""}.ph.ph-arrow-bend-down-right:before{content:""}.ph.ph-arrow-bend-left-down:before{content:""}.ph.ph-arrow-bend-left-up:before{content:""}.ph.ph-arrow-bend-right-down:before{content:""}.ph.ph-arrow-bend-right-up:before{content:""}.ph.ph-arrow-bend-up-left:before{content:""}.ph.ph-arrow-bend-up-right:before{content:""}.ph.ph-arrow-circle-down:before{content:""}.ph.ph-arrow-circle-down-left:before{content:""}.ph.ph-arrow-circle-down-right:before{content:""}.ph.ph-arrow-circle-left:before{content:""}.ph.ph-arrow-circle-right:before{content:""}.ph.ph-arrow-circle-up:before{content:""}.ph.ph-arrow-circle-up-left:before{content:""}.ph.ph-arrow-circle-up-right:before{content:""}.ph.ph-arrow-clockwise:before{content:""}.ph.ph-arrow-counter-clockwise:before{content:""}.ph.ph-arrow-down:before{content:""}.ph.ph-arrow-down-left:before{content:""}.ph.ph-arrow-down-right:before{content:""}.ph.ph-arrow-elbow-down-left:before{content:""}.ph.ph-arrow-elbow-down-right:before{content:""}.ph.ph-arrow-elbow-left:before{content:""}.ph.ph-arrow-elbow-left-down:before{content:""}.ph.ph-arrow-elbow-left-up:before{content:""}.ph.ph-arrow-elbow-right:before{content:""}.ph.ph-arrow-elbow-right-down:before{content:""}.ph.ph-arrow-elbow-right-up:before{content:""}.ph.ph-arrow-elbow-up-left:before{content:""}.ph.ph-arrow-elbow-up-right:before{content:""}.ph.ph-arrow-fat-down:before{content:""}.ph.ph-arrow-fat-left:before{content:""}.ph.ph-arrow-fat-line-down:before{content:""}.ph.ph-arrow-fat-line-left:before{content:""}.ph.ph-arrow-fat-line-right:before{content:""}.ph.ph-arrow-fat-line-up:before{content:""}.ph.ph-arrow-fat-lines-down:before{content:""}.ph.ph-arrow-fat-lines-left:before{content:""}.ph.ph-arrow-fat-lines-right:before{content:""}.ph.ph-arrow-fat-lines-up:before{content:""}.ph.ph-arrow-fat-right:before{content:""}.ph.ph-arrow-fat-up:before{content:""}.ph.ph-arrow-left:before{content:""}.ph.ph-arrow-line-down:before{content:""}.ph.ph-arrow-line-down-left:before{content:""}.ph.ph-arrow-line-down-right:before{content:""}.ph.ph-arrow-line-left:before{content:""}.ph.ph-arrow-line-right:before{content:""}.ph.ph-arrow-line-up:before{content:""}.ph.ph-arrow-line-up-left:before{content:""}.ph.ph-arrow-line-up-right:before{content:""}.ph.ph-arrow-right:before{content:""}.ph.ph-arrow-square-down:before{content:""}.ph.ph-arrow-square-down-left:before{content:""}.ph.ph-arrow-square-down-right:before{content:""}.ph.ph-arrow-square-in:before{content:""}.ph.ph-arrow-square-left:before{content:""}.ph.ph-arrow-square-out:before{content:""}.ph.ph-arrow-square-right:before{content:""}.ph.ph-arrow-square-up:before{content:""}.ph.ph-arrow-square-up-left:before{content:""}.ph.ph-arrow-square-up-right:before{content:""}.ph.ph-arrow-u-down-left:before{content:""}.ph.ph-arrow-u-down-right:before{content:""}.ph.ph-arrow-u-left-down:before{content:""}.ph.ph-arrow-u-left-up:before{content:""}.ph.ph-arrow-u-right-down:before{content:""}.ph.ph-arrow-u-right-up:before{content:""}.ph.ph-arrow-u-up-left:before{content:""}.ph.ph-arrow-u-up-right:before{content:""}.ph.ph-arrow-up:before{content:""}.ph.ph-arrow-up-left:before{content:""}.ph.ph-arrow-up-right:before{content:""}.ph.ph-arrows-clockwise:before{content:""}.ph.ph-arrows-counter-clockwise:before{content:""}.ph.ph-arrows-down-up:before{content:""}.ph.ph-arrows-horizontal:before{content:""}.ph.ph-arrows-in:before{content:""}.ph.ph-arrows-in-cardinal:before{content:""}.ph.ph-arrows-in-line-horizontal:before{content:""}.ph.ph-arrows-in-line-vertical:before{content:""}.ph.ph-arrows-in-simple:before{content:""}.ph.ph-arrows-left-right:before{content:""}.ph.ph-arrows-merge:before{content:""}.ph.ph-arrows-out:before{content:""}.ph.ph-arrows-out-cardinal:before{content:""}.ph.ph-arrows-out-line-horizontal:before{content:""}.ph.ph-arrows-out-line-vertical:before{content:""}.ph.ph-arrows-out-simple:before{content:""}.ph.ph-arrows-split:before{content:""}.ph.ph-arrows-vertical:before{content:""}.ph.ph-article:before{content:""}.ph.ph-article-medium:before{content:""}.ph.ph-article-ny-times:before{content:""}.ph.ph-asclepius:before{content:""}.ph.ph-caduceus:before{content:""}.ph.ph-asterisk:before{content:""}.ph.ph-asterisk-simple:before{content:""}.ph.ph-at:before{content:""}.ph.ph-atom:before{content:""}.ph.ph-avocado:before{content:""}.ph.ph-axe:before{content:""}.ph.ph-baby:before{content:""}.ph.ph-baby-carriage:before{content:""}.ph.ph-backpack:before{content:""}.ph.ph-backspace:before{content:""}.ph.ph-bag:before{content:""}.ph.ph-bag-simple:before{content:""}.ph.ph-balloon:before{content:""}.ph.ph-bandaids:before{content:""}.ph.ph-bank:before{content:""}.ph.ph-barbell:before{content:""}.ph.ph-barcode:before{content:""}.ph.ph-barn:before{content:""}.ph.ph-barricade:before{content:""}.ph.ph-baseball:before{content:""}.ph.ph-baseball-cap:before{content:""}.ph.ph-baseball-helmet:before{content:""}.ph.ph-basket:before{content:""}.ph.ph-basketball:before{content:""}.ph.ph-bathtub:before{content:""}.ph.ph-battery-charging:before{content:""}.ph.ph-battery-charging-vertical:before{content:""}.ph.ph-battery-empty:before{content:""}.ph.ph-battery-full:before{content:""}.ph.ph-battery-high:before{content:""}.ph.ph-battery-low:before{content:""}.ph.ph-battery-medium:before{content:""}.ph.ph-battery-plus:before{content:""}.ph.ph-battery-plus-vertical:before{content:""}.ph.ph-battery-vertical-empty:before{content:""}.ph.ph-battery-vertical-full:before{content:""}.ph.ph-battery-vertical-high:before{content:""}.ph.ph-battery-vertical-low:before{content:""}.ph.ph-battery-vertical-medium:before{content:""}.ph.ph-battery-warning:before{content:""}.ph.ph-battery-warning-vertical:before{content:""}.ph.ph-beach-ball:before{content:""}.ph.ph-beanie:before{content:""}.ph.ph-bed:before{content:""}.ph.ph-beer-bottle:before{content:""}.ph.ph-beer-stein:before{content:""}.ph.ph-behance-logo:before{content:""}.ph.ph-bell:before{content:""}.ph.ph-bell-ringing:before{content:""}.ph.ph-bell-simple:before{content:""}.ph.ph-bell-simple-ringing:before{content:""}.ph.ph-bell-simple-slash:before{content:""}.ph.ph-bell-simple-z:before{content:""}.ph.ph-bell-slash:before{content:""}.ph.ph-bell-z:before{content:""}.ph.ph-belt:before{content:""}.ph.ph-bezier-curve:before{content:""}.ph.ph-bicycle:before{content:""}.ph.ph-binary:before{content:""}.ph.ph-binoculars:before{content:""}.ph.ph-biohazard:before{content:""}.ph.ph-bird:before{content:""}.ph.ph-blueprint:before{content:""}.ph.ph-bluetooth:before{content:""}.ph.ph-bluetooth-connected:before{content:""}.ph.ph-bluetooth-slash:before{content:""}.ph.ph-bluetooth-x:before{content:""}.ph.ph-boat:before{content:""}.ph.ph-bomb:before{content:""}.ph.ph-bone:before{content:""}.ph.ph-book:before{content:""}.ph.ph-book-bookmark:before{content:""}.ph.ph-book-open:before{content:""}.ph.ph-book-open-text:before{content:""}.ph.ph-book-open-user:before{content:""}.ph.ph-bookmark:before{content:""}.ph.ph-bookmark-simple:before{content:""}.ph.ph-bookmarks:before{content:""}.ph.ph-bookmarks-simple:before{content:""}.ph.ph-books:before{content:""}.ph.ph-boot:before{content:""}.ph.ph-boules:before{content:""}.ph.ph-bounding-box:before{content:""}.ph.ph-bowl-food:before{content:""}.ph.ph-bowl-steam:before{content:""}.ph.ph-bowling-ball:before{content:""}.ph.ph-box-arrow-down:before{content:""}.ph.ph-archive-box:before{content:""}.ph.ph-box-arrow-up:before{content:""}.ph.ph-boxing-glove:before{content:""}.ph.ph-brackets-angle:before{content:""}.ph.ph-brackets-curly:before{content:""}.ph.ph-brackets-round:before{content:""}.ph.ph-brackets-square:before{content:""}.ph.ph-brain:before{content:""}.ph.ph-brandy:before{content:""}.ph.ph-bread:before{content:""}.ph.ph-bridge:before{content:""}.ph.ph-briefcase:before{content:""}.ph.ph-briefcase-metal:before{content:""}.ph.ph-broadcast:before{content:""}.ph.ph-broom:before{content:""}.ph.ph-browser:before{content:""}.ph.ph-browsers:before{content:""}.ph.ph-bug:before{content:""}.ph.ph-bug-beetle:before{content:""}.ph.ph-bug-droid:before{content:""}.ph.ph-building:before{content:""}.ph.ph-building-apartment:before{content:""}.ph.ph-building-office:before{content:""}.ph.ph-buildings:before{content:""}.ph.ph-bulldozer:before{content:""}.ph.ph-bus:before{content:""}.ph.ph-butterfly:before{content:""}.ph.ph-cable-car:before{content:""}.ph.ph-cactus:before{content:""}.ph.ph-cake:before{content:""}.ph.ph-calculator:before{content:""}.ph.ph-calendar:before{content:""}.ph.ph-calendar-blank:before{content:""}.ph.ph-calendar-check:before{content:""}.ph.ph-calendar-dot:before{content:""}.ph.ph-calendar-dots:before{content:""}.ph.ph-calendar-heart:before{content:""}.ph.ph-calendar-minus:before{content:""}.ph.ph-calendar-plus:before{content:""}.ph.ph-calendar-slash:before{content:""}.ph.ph-calendar-star:before{content:""}.ph.ph-calendar-x:before{content:""}.ph.ph-call-bell:before{content:""}.ph.ph-camera:before{content:""}.ph.ph-camera-plus:before{content:""}.ph.ph-camera-rotate:before{content:""}.ph.ph-camera-slash:before{content:""}.ph.ph-campfire:before{content:""}.ph.ph-car:before{content:""}.ph.ph-car-battery:before{content:""}.ph.ph-car-profile:before{content:""}.ph.ph-car-simple:before{content:""}.ph.ph-cardholder:before{content:""}.ph.ph-cards:before{content:""}.ph.ph-cards-three:before{content:""}.ph.ph-caret-circle-double-down:before{content:""}.ph.ph-caret-circle-double-left:before{content:""}.ph.ph-caret-circle-double-right:before{content:""}.ph.ph-caret-circle-double-up:before{content:""}.ph.ph-caret-circle-down:before{content:""}.ph.ph-caret-circle-left:before{content:""}.ph.ph-caret-circle-right:before{content:""}.ph.ph-caret-circle-up:before{content:""}.ph.ph-caret-circle-up-down:before{content:""}.ph.ph-caret-double-down:before{content:""}.ph.ph-caret-double-left:before{content:""}.ph.ph-caret-double-right:before{content:""}.ph.ph-caret-double-up:before{content:""}.ph.ph-caret-down:before{content:""}.ph.ph-caret-left:before{content:""}.ph.ph-caret-line-down:before{content:""}.ph.ph-caret-line-left:before{content:""}.ph.ph-caret-line-right:before{content:""}.ph.ph-caret-line-up:before{content:""}.ph.ph-caret-right:before{content:""}.ph.ph-caret-up:before{content:""}.ph.ph-caret-up-down:before{content:""}.ph.ph-carrot:before{content:""}.ph.ph-cash-register:before{content:""}.ph.ph-cassette-tape:before{content:""}.ph.ph-castle-turret:before{content:""}.ph.ph-cat:before{content:""}.ph.ph-cell-signal-full:before{content:""}.ph.ph-cell-signal-high:before{content:""}.ph.ph-cell-signal-low:before{content:""}.ph.ph-cell-signal-medium:before{content:""}.ph.ph-cell-signal-none:before{content:""}.ph.ph-cell-signal-slash:before{content:""}.ph.ph-cell-signal-x:before{content:""}.ph.ph-cell-tower:before{content:""}.ph.ph-certificate:before{content:""}.ph.ph-chair:before{content:""}.ph.ph-chalkboard:before{content:""}.ph.ph-chalkboard-simple:before{content:""}.ph.ph-chalkboard-teacher:before{content:""}.ph.ph-champagne:before{content:""}.ph.ph-charging-station:before{content:""}.ph.ph-chart-bar:before{content:""}.ph.ph-chart-bar-horizontal:before{content:""}.ph.ph-chart-donut:before{content:""}.ph.ph-chart-line:before{content:""}.ph.ph-chart-line-down:before{content:""}.ph.ph-chart-line-up:before{content:""}.ph.ph-chart-pie:before{content:""}.ph.ph-chart-pie-slice:before{content:""}.ph.ph-chart-polar:before{content:""}.ph.ph-chart-scatter:before{content:""}.ph.ph-chat:before{content:""}.ph.ph-chat-centered:before{content:""}.ph.ph-chat-centered-dots:before{content:""}.ph.ph-chat-centered-slash:before{content:""}.ph.ph-chat-centered-text:before{content:""}.ph.ph-chat-circle:before{content:""}.ph.ph-chat-circle-dots:before{content:""}.ph.ph-chat-circle-slash:before{content:""}.ph.ph-chat-circle-text:before{content:""}.ph.ph-chat-dots:before{content:""}.ph.ph-chat-slash:before{content:""}.ph.ph-chat-teardrop:before{content:""}.ph.ph-chat-teardrop-dots:before{content:""}.ph.ph-chat-teardrop-slash:before{content:""}.ph.ph-chat-teardrop-text:before{content:""}.ph.ph-chat-text:before{content:""}.ph.ph-chats:before{content:""}.ph.ph-chats-circle:before{content:""}.ph.ph-chats-teardrop:before{content:""}.ph.ph-check:before{content:""}.ph.ph-check-circle:before{content:""}.ph.ph-check-fat:before{content:""}.ph.ph-check-square:before{content:""}.ph.ph-check-square-offset:before{content:""}.ph.ph-checkerboard:before{content:""}.ph.ph-checks:before{content:""}.ph.ph-cheers:before{content:""}.ph.ph-cheese:before{content:""}.ph.ph-chef-hat:before{content:""}.ph.ph-cherries:before{content:""}.ph.ph-church:before{content:""}.ph.ph-cigarette:before{content:""}.ph.ph-cigarette-slash:before{content:""}.ph.ph-circle:before{content:""}.ph.ph-circle-dashed:before{content:""}.ph.ph-circle-half:before{content:""}.ph.ph-circle-half-tilt:before{content:""}.ph.ph-circle-notch:before{content:""}.ph.ph-circles-four:before{content:""}.ph.ph-circles-three:before{content:""}.ph.ph-circles-three-plus:before{content:""}.ph.ph-circuitry:before{content:""}.ph.ph-city:before{content:""}.ph.ph-clipboard:before{content:""}.ph.ph-clipboard-text:before{content:""}.ph.ph-clock:before{content:""}.ph.ph-clock-afternoon:before{content:""}.ph.ph-clock-clockwise:before{content:""}.ph.ph-clock-countdown:before{content:""}.ph.ph-clock-counter-clockwise:before{content:""}.ph.ph-clock-user:before{content:""}.ph.ph-closed-captioning:before{content:""}.ph.ph-cloud:before{content:""}.ph.ph-cloud-arrow-down:before{content:""}.ph.ph-cloud-arrow-up:before{content:""}.ph.ph-cloud-check:before{content:""}.ph.ph-cloud-fog:before{content:""}.ph.ph-cloud-lightning:before{content:""}.ph.ph-cloud-moon:before{content:""}.ph.ph-cloud-rain:before{content:""}.ph.ph-cloud-slash:before{content:""}.ph.ph-cloud-snow:before{content:""}.ph.ph-cloud-sun:before{content:""}.ph.ph-cloud-warning:before{content:""}.ph.ph-cloud-x:before{content:""}.ph.ph-clover:before{content:""}.ph.ph-club:before{content:""}.ph.ph-coat-hanger:before{content:""}.ph.ph-coda-logo:before{content:""}.ph.ph-code:before{content:""}.ph.ph-code-block:before{content:""}.ph.ph-code-simple:before{content:""}.ph.ph-codepen-logo:before{content:""}.ph.ph-codesandbox-logo:before{content:""}.ph.ph-coffee:before{content:""}.ph.ph-coffee-bean:before{content:""}.ph.ph-coin:before{content:""}.ph.ph-coin-vertical:before{content:""}.ph.ph-coins:before{content:""}.ph.ph-columns:before{content:""}.ph.ph-columns-plus-left:before{content:""}.ph.ph-columns-plus-right:before{content:""}.ph.ph-command:before{content:""}.ph.ph-compass:before{content:""}.ph.ph-compass-rose:before{content:""}.ph.ph-compass-tool:before{content:""}.ph.ph-computer-tower:before{content:""}.ph.ph-confetti:before{content:""}.ph.ph-contactless-payment:before{content:""}.ph.ph-control:before{content:""}.ph.ph-cookie:before{content:""}.ph.ph-cooking-pot:before{content:""}.ph.ph-copy:before{content:""}.ph.ph-copy-simple:before{content:""}.ph.ph-copyleft:before{content:""}.ph.ph-copyright:before{content:""}.ph.ph-corners-in:before{content:""}.ph.ph-corners-out:before{content:""}.ph.ph-couch:before{content:""}.ph.ph-court-basketball:before{content:""}.ph.ph-cow:before{content:""}.ph.ph-cowboy-hat:before{content:""}.ph.ph-cpu:before{content:""}.ph.ph-crane:before{content:""}.ph.ph-crane-tower:before{content:""}.ph.ph-credit-card:before{content:""}.ph.ph-cricket:before{content:""}.ph.ph-crop:before{content:""}.ph.ph-cross:before{content:""}.ph.ph-crosshair:before{content:""}.ph.ph-crosshair-simple:before{content:""}.ph.ph-crown:before{content:""}.ph.ph-crown-cross:before{content:""}.ph.ph-crown-simple:before{content:""}.ph.ph-cube:before{content:""}.ph.ph-cube-focus:before{content:""}.ph.ph-cube-transparent:before{content:""}.ph.ph-currency-btc:before{content:""}.ph.ph-currency-circle-dollar:before{content:""}.ph.ph-currency-cny:before{content:""}.ph.ph-currency-dollar:before{content:""}.ph.ph-currency-dollar-simple:before{content:""}.ph.ph-currency-eth:before{content:""}.ph.ph-currency-eur:before{content:""}.ph.ph-currency-gbp:before{content:""}.ph.ph-currency-inr:before{content:""}.ph.ph-currency-jpy:before{content:""}.ph.ph-currency-krw:before{content:""}.ph.ph-currency-kzt:before{content:""}.ph.ph-currency-ngn:before{content:""}.ph.ph-currency-rub:before{content:""}.ph.ph-cursor:before{content:""}.ph.ph-cursor-click:before{content:""}.ph.ph-cursor-text:before{content:""}.ph.ph-cylinder:before{content:""}.ph.ph-database:before{content:""}.ph.ph-desk:before{content:""}.ph.ph-desktop:before{content:""}.ph.ph-desktop-tower:before{content:""}.ph.ph-detective:before{content:""}.ph.ph-dev-to-logo:before{content:""}.ph.ph-device-mobile:before{content:""}.ph.ph-device-mobile-camera:before{content:""}.ph.ph-device-mobile-slash:before{content:""}.ph.ph-device-mobile-speaker:before{content:""}.ph.ph-device-rotate:before{content:""}.ph.ph-device-tablet:before{content:""}.ph.ph-device-tablet-camera:before{content:""}.ph.ph-device-tablet-speaker:before{content:""}.ph.ph-devices:before{content:""}.ph.ph-diamond:before{content:""}.ph.ph-diamonds-four:before{content:""}.ph.ph-dice-five:before{content:""}.ph.ph-dice-four:before{content:""}.ph.ph-dice-one:before{content:""}.ph.ph-dice-six:before{content:""}.ph.ph-dice-three:before{content:""}.ph.ph-dice-two:before{content:""}.ph.ph-disc:before{content:""}.ph.ph-disco-ball:before{content:""}.ph.ph-discord-logo:before{content:""}.ph.ph-divide:before{content:""}.ph.ph-dna:before{content:""}.ph.ph-dog:before{content:""}.ph.ph-door:before{content:""}.ph.ph-door-open:before{content:""}.ph.ph-dot:before{content:""}.ph.ph-dot-outline:before{content:""}.ph.ph-dots-nine:before{content:""}.ph.ph-dots-six:before{content:""}.ph.ph-dots-six-vertical:before{content:""}.ph.ph-dots-three:before{content:""}.ph.ph-dots-three-circle:before{content:""}.ph.ph-dots-three-circle-vertical:before{content:""}.ph.ph-dots-three-outline:before{content:""}.ph.ph-dots-three-outline-vertical:before{content:""}.ph.ph-dots-three-vertical:before{content:""}.ph.ph-download:before{content:""}.ph.ph-download-simple:before{content:""}.ph.ph-dress:before{content:""}.ph.ph-dresser:before{content:""}.ph.ph-dribbble-logo:before{content:""}.ph.ph-drone:before{content:""}.ph.ph-drop:before{content:""}.ph.ph-drop-half:before{content:""}.ph.ph-drop-half-bottom:before{content:""}.ph.ph-drop-simple:before{content:""}.ph.ph-drop-slash:before{content:""}.ph.ph-dropbox-logo:before{content:""}.ph.ph-ear:before{content:""}.ph.ph-ear-slash:before{content:""}.ph.ph-egg:before{content:""}.ph.ph-egg-crack:before{content:""}.ph.ph-eject:before{content:""}.ph.ph-eject-simple:before{content:""}.ph.ph-elevator:before{content:""}.ph.ph-empty:before{content:""}.ph.ph-engine:before{content:""}.ph.ph-envelope:before{content:""}.ph.ph-envelope-open:before{content:""}.ph.ph-envelope-simple:before{content:""}.ph.ph-envelope-simple-open:before{content:""}.ph.ph-equalizer:before{content:""}.ph.ph-equals:before{content:""}.ph.ph-eraser:before{content:""}.ph.ph-escalator-down:before{content:""}.ph.ph-escalator-up:before{content:""}.ph.ph-exam:before{content:""}.ph.ph-exclamation-mark:before{content:""}.ph.ph-exclude:before{content:""}.ph.ph-exclude-square:before{content:""}.ph.ph-export:before{content:""}.ph.ph-eye:before{content:""}.ph.ph-eye-closed:before{content:""}.ph.ph-eye-slash:before{content:""}.ph.ph-eyedropper:before{content:""}.ph.ph-eyedropper-sample:before{content:""}.ph.ph-eyeglasses:before{content:""}.ph.ph-eyes:before{content:""}.ph.ph-face-mask:before{content:""}.ph.ph-facebook-logo:before{content:""}.ph.ph-factory:before{content:""}.ph.ph-faders:before{content:""}.ph.ph-faders-horizontal:before{content:""}.ph.ph-fallout-shelter:before{content:""}.ph.ph-fan:before{content:""}.ph.ph-farm:before{content:""}.ph.ph-fast-forward:before{content:""}.ph.ph-fast-forward-circle:before{content:""}.ph.ph-feather:before{content:""}.ph.ph-fediverse-logo:before{content:""}.ph.ph-figma-logo:before{content:""}.ph.ph-file:before{content:""}.ph.ph-file-archive:before{content:""}.ph.ph-file-arrow-down:before{content:""}.ph.ph-file-arrow-up:before{content:""}.ph.ph-file-audio:before{content:""}.ph.ph-file-c:before{content:""}.ph.ph-file-c-sharp:before{content:""}.ph.ph-file-cloud:before{content:""}.ph.ph-file-code:before{content:""}.ph.ph-file-cpp:before{content:""}.ph.ph-file-css:before{content:""}.ph.ph-file-csv:before{content:""}.ph.ph-file-dashed:before{content:""}.ph.ph-file-dotted:before{content:""}.ph.ph-file-doc:before{content:""}.ph.ph-file-html:before{content:""}.ph.ph-file-image:before{content:""}.ph.ph-file-ini:before{content:""}.ph.ph-file-jpg:before{content:""}.ph.ph-file-js:before{content:""}.ph.ph-file-jsx:before{content:""}.ph.ph-file-lock:before{content:""}.ph.ph-file-magnifying-glass:before{content:""}.ph.ph-file-search:before{content:""}.ph.ph-file-md:before{content:""}.ph.ph-file-minus:before{content:""}.ph.ph-file-pdf:before{content:""}.ph.ph-file-plus:before{content:""}.ph.ph-file-png:before{content:""}.ph.ph-file-ppt:before{content:""}.ph.ph-file-py:before{content:""}.ph.ph-file-rs:before{content:""}.ph.ph-file-sql:before{content:""}.ph.ph-file-svg:before{content:""}.ph.ph-file-text:before{content:""}.ph.ph-file-ts:before{content:""}.ph.ph-file-tsx:before{content:""}.ph.ph-file-txt:before{content:""}.ph.ph-file-video:before{content:""}.ph.ph-file-vue:before{content:""}.ph.ph-file-x:before{content:""}.ph.ph-file-xls:before{content:""}.ph.ph-file-zip:before{content:""}.ph.ph-files:before{content:""}.ph.ph-film-reel:before{content:""}.ph.ph-film-script:before{content:""}.ph.ph-film-slate:before{content:""}.ph.ph-film-strip:before{content:""}.ph.ph-fingerprint:before{content:""}.ph.ph-fingerprint-simple:before{content:""}.ph.ph-finn-the-human:before{content:""}.ph.ph-fire:before{content:""}.ph.ph-fire-extinguisher:before{content:""}.ph.ph-fire-simple:before{content:""}.ph.ph-fire-truck:before{content:""}.ph.ph-first-aid:before{content:""}.ph.ph-first-aid-kit:before{content:""}.ph.ph-fish:before{content:""}.ph.ph-fish-simple:before{content:""}.ph.ph-flag:before{content:""}.ph.ph-flag-banner:before{content:""}.ph.ph-flag-banner-fold:before{content:""}.ph.ph-flag-checkered:before{content:""}.ph.ph-flag-pennant:before{content:""}.ph.ph-flame:before{content:""}.ph.ph-flashlight:before{content:""}.ph.ph-flask:before{content:""}.ph.ph-flip-horizontal:before{content:""}.ph.ph-flip-vertical:before{content:""}.ph.ph-floppy-disk:before{content:""}.ph.ph-floppy-disk-back:before{content:""}.ph.ph-flow-arrow:before{content:""}.ph.ph-flower:before{content:""}.ph.ph-flower-lotus:before{content:""}.ph.ph-flower-tulip:before{content:""}.ph.ph-flying-saucer:before{content:""}.ph.ph-folder:before{content:""}.ph.ph-folder-notch:before{content:""}.ph.ph-folder-dashed:before{content:""}.ph.ph-folder-dotted:before{content:""}.ph.ph-folder-lock:before{content:""}.ph.ph-folder-minus:before{content:""}.ph.ph-folder-notch-minus:before{content:""}.ph.ph-folder-open:before{content:""}.ph.ph-folder-notch-open:before{content:""}.ph.ph-folder-plus:before{content:""}.ph.ph-folder-notch-plus:before{content:""}.ph.ph-folder-simple:before{content:""}.ph.ph-folder-simple-dashed:before{content:""}.ph.ph-folder-simple-dotted:before{content:""}.ph.ph-folder-simple-lock:before{content:""}.ph.ph-folder-simple-minus:before{content:""}.ph.ph-folder-simple-plus:before{content:""}.ph.ph-folder-simple-star:before{content:""}.ph.ph-folder-simple-user:before{content:""}.ph.ph-folder-star:before{content:""}.ph.ph-folder-user:before{content:""}.ph.ph-folders:before{content:""}.ph.ph-football:before{content:""}.ph.ph-football-helmet:before{content:""}.ph.ph-footprints:before{content:""}.ph.ph-fork-knife:before{content:""}.ph.ph-four-k:before{content:""}.ph.ph-frame-corners:before{content:""}.ph.ph-framer-logo:before{content:""}.ph.ph-function:before{content:""}.ph.ph-funnel:before{content:""}.ph.ph-funnel-simple:before{content:""}.ph.ph-funnel-simple-x:before{content:""}.ph.ph-funnel-x:before{content:""}.ph.ph-game-controller:before{content:""}.ph.ph-garage:before{content:""}.ph.ph-gas-can:before{content:""}.ph.ph-gas-pump:before{content:""}.ph.ph-gauge:before{content:""}.ph.ph-gavel:before{content:""}.ph.ph-gear:before{content:""}.ph.ph-gear-fine:before{content:""}.ph.ph-gear-six:before{content:""}.ph.ph-gender-female:before{content:""}.ph.ph-gender-intersex:before{content:""}.ph.ph-gender-male:before{content:""}.ph.ph-gender-neuter:before{content:""}.ph.ph-gender-nonbinary:before{content:""}.ph.ph-gender-transgender:before{content:""}.ph.ph-ghost:before{content:""}.ph.ph-gif:before{content:""}.ph.ph-gift:before{content:""}.ph.ph-git-branch:before{content:""}.ph.ph-git-commit:before{content:""}.ph.ph-git-diff:before{content:""}.ph.ph-git-fork:before{content:""}.ph.ph-git-merge:before{content:""}.ph.ph-git-pull-request:before{content:""}.ph.ph-github-logo:before{content:""}.ph.ph-gitlab-logo:before{content:""}.ph.ph-gitlab-logo-simple:before{content:""}.ph.ph-globe:before{content:""}.ph.ph-globe-hemisphere-east:before{content:""}.ph.ph-globe-hemisphere-west:before{content:""}.ph.ph-globe-simple:before{content:""}.ph.ph-globe-simple-x:before{content:""}.ph.ph-globe-stand:before{content:""}.ph.ph-globe-x:before{content:""}.ph.ph-goggles:before{content:""}.ph.ph-golf:before{content:""}.ph.ph-goodreads-logo:before{content:""}.ph.ph-google-cardboard-logo:before{content:""}.ph.ph-google-chrome-logo:before{content:""}.ph.ph-google-drive-logo:before{content:""}.ph.ph-google-logo:before{content:""}.ph.ph-google-photos-logo:before{content:""}.ph.ph-google-play-logo:before{content:""}.ph.ph-google-podcasts-logo:before{content:""}.ph.ph-gps:before{content:""}.ph.ph-gps-fix:before{content:""}.ph.ph-gps-slash:before{content:""}.ph.ph-gradient:before{content:""}.ph.ph-graduation-cap:before{content:""}.ph.ph-grains:before{content:""}.ph.ph-grains-slash:before{content:""}.ph.ph-graph:before{content:""}.ph.ph-graphics-card:before{content:""}.ph.ph-greater-than:before{content:""}.ph.ph-greater-than-or-equal:before{content:""}.ph.ph-grid-four:before{content:""}.ph.ph-grid-nine:before{content:""}.ph.ph-guitar:before{content:""}.ph.ph-hair-dryer:before{content:""}.ph.ph-hamburger:before{content:""}.ph.ph-hammer:before{content:""}.ph.ph-hand:before{content:""}.ph.ph-hand-arrow-down:before{content:""}.ph.ph-hand-arrow-up:before{content:""}.ph.ph-hand-coins:before{content:""}.ph.ph-hand-deposit:before{content:""}.ph.ph-hand-eye:before{content:""}.ph.ph-hand-fist:before{content:""}.ph.ph-hand-grabbing:before{content:""}.ph.ph-hand-heart:before{content:""}.ph.ph-hand-palm:before{content:""}.ph.ph-hand-peace:before{content:""}.ph.ph-hand-pointing:before{content:""}.ph.ph-hand-soap:before{content:""}.ph.ph-hand-swipe-left:before{content:""}.ph.ph-hand-swipe-right:before{content:""}.ph.ph-hand-tap:before{content:""}.ph.ph-hand-waving:before{content:""}.ph.ph-hand-withdraw:before{content:""}.ph.ph-handbag:before{content:""}.ph.ph-handbag-simple:before{content:""}.ph.ph-hands-clapping:before{content:""}.ph.ph-hands-praying:before{content:""}.ph.ph-handshake:before{content:""}.ph.ph-hard-drive:before{content:""}.ph.ph-hard-drives:before{content:""}.ph.ph-hard-hat:before{content:""}.ph.ph-hash:before{content:""}.ph.ph-hash-straight:before{content:""}.ph.ph-head-circuit:before{content:""}.ph.ph-headlights:before{content:""}.ph.ph-headphones:before{content:""}.ph.ph-headset:before{content:""}.ph.ph-heart:before{content:""}.ph.ph-heart-break:before{content:""}.ph.ph-heart-half:before{content:""}.ph.ph-heart-straight:before{content:""}.ph.ph-heart-straight-break:before{content:""}.ph.ph-heartbeat:before{content:""}.ph.ph-hexagon:before{content:""}.ph.ph-high-definition:before{content:""}.ph.ph-high-heel:before{content:""}.ph.ph-highlighter:before{content:""}.ph.ph-highlighter-circle:before{content:""}.ph.ph-hockey:before{content:""}.ph.ph-hoodie:before{content:""}.ph.ph-horse:before{content:""}.ph.ph-hospital:before{content:""}.ph.ph-hourglass:before{content:""}.ph.ph-hourglass-high:before{content:""}.ph.ph-hourglass-low:before{content:""}.ph.ph-hourglass-medium:before{content:""}.ph.ph-hourglass-simple:before{content:""}.ph.ph-hourglass-simple-high:before{content:""}.ph.ph-hourglass-simple-low:before{content:""}.ph.ph-hourglass-simple-medium:before{content:""}.ph.ph-house:before{content:""}.ph.ph-house-line:before{content:""}.ph.ph-house-simple:before{content:""}.ph.ph-hurricane:before{content:""}.ph.ph-ice-cream:before{content:""}.ph.ph-identification-badge:before{content:""}.ph.ph-identification-card:before{content:""}.ph.ph-image:before{content:""}.ph.ph-image-broken:before{content:""}.ph.ph-image-square:before{content:""}.ph.ph-images:before{content:""}.ph.ph-images-square:before{content:""}.ph.ph-infinity:before{content:""}.ph.ph-lemniscate:before{content:""}.ph.ph-info:before{content:""}.ph.ph-instagram-logo:before{content:""}.ph.ph-intersect:before{content:""}.ph.ph-intersect-square:before{content:""}.ph.ph-intersect-three:before{content:""}.ph.ph-intersection:before{content:""}.ph.ph-invoice:before{content:""}.ph.ph-island:before{content:""}.ph.ph-jar:before{content:""}.ph.ph-jar-label:before{content:""}.ph.ph-jeep:before{content:""}.ph.ph-joystick:before{content:""}.ph.ph-kanban:before{content:""}.ph.ph-key:before{content:""}.ph.ph-key-return:before{content:""}.ph.ph-keyboard:before{content:""}.ph.ph-keyhole:before{content:""}.ph.ph-knife:before{content:""}.ph.ph-ladder:before{content:""}.ph.ph-ladder-simple:before{content:""}.ph.ph-lamp:before{content:""}.ph.ph-lamp-pendant:before{content:""}.ph.ph-laptop:before{content:""}.ph.ph-lasso:before{content:""}.ph.ph-lastfm-logo:before{content:""}.ph.ph-layout:before{content:""}.ph.ph-leaf:before{content:""}.ph.ph-lectern:before{content:""}.ph.ph-lego:before{content:""}.ph.ph-lego-smiley:before{content:""}.ph.ph-less-than:before{content:""}.ph.ph-less-than-or-equal:before{content:""}.ph.ph-letter-circle-h:before{content:""}.ph.ph-letter-circle-p:before{content:""}.ph.ph-letter-circle-v:before{content:""}.ph.ph-lifebuoy:before{content:""}.ph.ph-lightbulb:before{content:""}.ph.ph-lightbulb-filament:before{content:""}.ph.ph-lighthouse:before{content:""}.ph.ph-lightning:before{content:""}.ph.ph-lightning-a:before{content:""}.ph.ph-lightning-slash:before{content:""}.ph.ph-line-segment:before{content:""}.ph.ph-line-segments:before{content:""}.ph.ph-line-vertical:before{content:""}.ph.ph-link:before{content:""}.ph.ph-link-break:before{content:""}.ph.ph-link-simple:before{content:""}.ph.ph-link-simple-break:before{content:""}.ph.ph-link-simple-horizontal:before{content:""}.ph.ph-link-simple-horizontal-break:before{content:""}.ph.ph-linkedin-logo:before{content:""}.ph.ph-linktree-logo:before{content:""}.ph.ph-linux-logo:before{content:""}.ph.ph-list:before{content:""}.ph.ph-list-bullets:before{content:""}.ph.ph-list-checks:before{content:""}.ph.ph-list-dashes:before{content:""}.ph.ph-list-heart:before{content:""}.ph.ph-list-magnifying-glass:before{content:""}.ph.ph-list-numbers:before{content:""}.ph.ph-list-plus:before{content:""}.ph.ph-list-star:before{content:""}.ph.ph-lock:before{content:""}.ph.ph-lock-key:before{content:""}.ph.ph-lock-key-open:before{content:""}.ph.ph-lock-laminated:before{content:""}.ph.ph-lock-laminated-open:before{content:""}.ph.ph-lock-open:before{content:""}.ph.ph-lock-simple:before{content:""}.ph.ph-lock-simple-open:before{content:""}.ph.ph-lockers:before{content:""}.ph.ph-log:before{content:""}.ph.ph-magic-wand:before{content:""}.ph.ph-magnet:before{content:""}.ph.ph-magnet-straight:before{content:""}.ph.ph-magnifying-glass:before{content:""}.ph.ph-magnifying-glass-minus:before{content:""}.ph.ph-magnifying-glass-plus:before{content:""}.ph.ph-mailbox:before{content:""}.ph.ph-map-pin:before{content:""}.ph.ph-map-pin-area:before{content:""}.ph.ph-map-pin-line:before{content:""}.ph.ph-map-pin-plus:before{content:""}.ph.ph-map-pin-simple:before{content:""}.ph.ph-map-pin-simple-area:before{content:""}.ph.ph-map-pin-simple-line:before{content:""}.ph.ph-map-trifold:before{content:""}.ph.ph-markdown-logo:before{content:""}.ph.ph-marker-circle:before{content:""}.ph.ph-martini:before{content:""}.ph.ph-mask-happy:before{content:""}.ph.ph-mask-sad:before{content:""}.ph.ph-mastodon-logo:before{content:""}.ph.ph-math-operations:before{content:""}.ph.ph-matrix-logo:before{content:""}.ph.ph-medal:before{content:""}.ph.ph-medal-military:before{content:""}.ph.ph-medium-logo:before{content:""}.ph.ph-megaphone:before{content:""}.ph.ph-megaphone-simple:before{content:""}.ph.ph-member-of:before{content:""}.ph.ph-memory:before{content:""}.ph.ph-messenger-logo:before{content:""}.ph.ph-meta-logo:before{content:""}.ph.ph-meteor:before{content:""}.ph.ph-metronome:before{content:""}.ph.ph-microphone:before{content:""}.ph.ph-microphone-slash:before{content:""}.ph.ph-microphone-stage:before{content:""}.ph.ph-microscope:before{content:""}.ph.ph-microsoft-excel-logo:before{content:""}.ph.ph-microsoft-outlook-logo:before{content:""}.ph.ph-microsoft-powerpoint-logo:before{content:""}.ph.ph-microsoft-teams-logo:before{content:""}.ph.ph-microsoft-word-logo:before{content:""}.ph.ph-minus:before{content:""}.ph.ph-minus-circle:before{content:""}.ph.ph-minus-square:before{content:""}.ph.ph-money:before{content:""}.ph.ph-money-wavy:before{content:""}.ph.ph-monitor:before{content:""}.ph.ph-monitor-arrow-up:before{content:""}.ph.ph-monitor-play:before{content:""}.ph.ph-moon:before{content:""}.ph.ph-moon-stars:before{content:""}.ph.ph-moped:before{content:""}.ph.ph-moped-front:before{content:""}.ph.ph-mosque:before{content:""}.ph.ph-motorcycle:before{content:""}.ph.ph-mountains:before{content:""}.ph.ph-mouse:before{content:""}.ph.ph-mouse-left-click:before{content:""}.ph.ph-mouse-middle-click:before{content:""}.ph.ph-mouse-right-click:before{content:""}.ph.ph-mouse-scroll:before{content:""}.ph.ph-mouse-simple:before{content:""}.ph.ph-music-note:before{content:""}.ph.ph-music-note-simple:before{content:""}.ph.ph-music-notes:before{content:""}.ph.ph-music-notes-minus:before{content:""}.ph.ph-music-notes-plus:before{content:""}.ph.ph-music-notes-simple:before{content:""}.ph.ph-navigation-arrow:before{content:""}.ph.ph-needle:before{content:""}.ph.ph-network:before{content:""}.ph.ph-network-slash:before{content:""}.ph.ph-network-x:before{content:""}.ph.ph-newspaper:before{content:""}.ph.ph-newspaper-clipping:before{content:""}.ph.ph-not-equals:before{content:""}.ph.ph-not-member-of:before{content:""}.ph.ph-not-subset-of:before{content:""}.ph.ph-not-superset-of:before{content:""}.ph.ph-notches:before{content:""}.ph.ph-note:before{content:""}.ph.ph-note-blank:before{content:""}.ph.ph-note-pencil:before{content:""}.ph.ph-notebook:before{content:""}.ph.ph-notepad:before{content:""}.ph.ph-notification:before{content:""}.ph.ph-notion-logo:before{content:""}.ph.ph-nuclear-plant:before{content:""}.ph.ph-number-circle-eight:before{content:""}.ph.ph-number-circle-five:before{content:""}.ph.ph-number-circle-four:before{content:""}.ph.ph-number-circle-nine:before{content:""}.ph.ph-number-circle-one:before{content:""}.ph.ph-number-circle-seven:before{content:""}.ph.ph-number-circle-six:before{content:""}.ph.ph-number-circle-three:before{content:""}.ph.ph-number-circle-two:before{content:""}.ph.ph-number-circle-zero:before{content:""}.ph.ph-number-eight:before{content:""}.ph.ph-number-five:before{content:""}.ph.ph-number-four:before{content:""}.ph.ph-number-nine:before{content:""}.ph.ph-number-one:before{content:""}.ph.ph-number-seven:before{content:""}.ph.ph-number-six:before{content:""}.ph.ph-number-square-eight:before{content:""}.ph.ph-number-square-five:before{content:""}.ph.ph-number-square-four:before{content:""}.ph.ph-number-square-nine:before{content:""}.ph.ph-number-square-one:before{content:""}.ph.ph-number-square-seven:before{content:""}.ph.ph-number-square-six:before{content:""}.ph.ph-number-square-three:before{content:""}.ph.ph-number-square-two:before{content:""}.ph.ph-number-square-zero:before{content:""}.ph.ph-number-three:before{content:""}.ph.ph-number-two:before{content:""}.ph.ph-number-zero:before{content:""}.ph.ph-numpad:before{content:""}.ph.ph-nut:before{content:""}.ph.ph-ny-times-logo:before{content:""}.ph.ph-octagon:before{content:""}.ph.ph-office-chair:before{content:""}.ph.ph-onigiri:before{content:""}.ph.ph-open-ai-logo:before{content:""}.ph.ph-option:before{content:""}.ph.ph-orange:before{content:""}.ph.ph-orange-slice:before{content:""}.ph.ph-oven:before{content:""}.ph.ph-package:before{content:""}.ph.ph-paint-brush:before{content:""}.ph.ph-paint-brush-broad:before{content:""}.ph.ph-paint-brush-household:before{content:""}.ph.ph-paint-bucket:before{content:""}.ph.ph-paint-roller:before{content:""}.ph.ph-palette:before{content:""}.ph.ph-panorama:before{content:""}.ph.ph-pants:before{content:""}.ph.ph-paper-plane:before{content:""}.ph.ph-paper-plane-right:before{content:""}.ph.ph-paper-plane-tilt:before{content:""}.ph.ph-paperclip:before{content:""}.ph.ph-paperclip-horizontal:before{content:""}.ph.ph-parachute:before{content:""}.ph.ph-paragraph:before{content:""}.ph.ph-parallelogram:before{content:""}.ph.ph-park:before{content:""}.ph.ph-password:before{content:""}.ph.ph-path:before{content:""}.ph.ph-patreon-logo:before{content:""}.ph.ph-pause:before{content:""}.ph.ph-pause-circle:before{content:""}.ph.ph-paw-print:before{content:""}.ph.ph-paypal-logo:before{content:""}.ph.ph-peace:before{content:""}.ph.ph-pen:before{content:""}.ph.ph-pen-nib:before{content:""}.ph.ph-pen-nib-straight:before{content:""}.ph.ph-pencil:before{content:""}.ph.ph-pencil-circle:before{content:""}.ph.ph-pencil-line:before{content:""}.ph.ph-pencil-ruler:before{content:""}.ph.ph-pencil-simple:before{content:""}.ph.ph-pencil-simple-line:before{content:""}.ph.ph-pencil-simple-slash:before{content:""}.ph.ph-pencil-slash:before{content:""}.ph.ph-pentagon:before{content:""}.ph.ph-pentagram:before{content:""}.ph.ph-pepper:before{content:""}.ph.ph-percent:before{content:""}.ph.ph-person:before{content:""}.ph.ph-person-arms-spread:before{content:""}.ph.ph-person-simple:before{content:""}.ph.ph-person-simple-bike:before{content:""}.ph.ph-person-simple-circle:before{content:""}.ph.ph-person-simple-hike:before{content:""}.ph.ph-person-simple-run:before{content:""}.ph.ph-person-simple-ski:before{content:""}.ph.ph-person-simple-snowboard:before{content:""}.ph.ph-person-simple-swim:before{content:""}.ph.ph-person-simple-tai-chi:before{content:""}.ph.ph-person-simple-throw:before{content:""}.ph.ph-person-simple-walk:before{content:""}.ph.ph-perspective:before{content:""}.ph.ph-phone:before{content:""}.ph.ph-phone-call:before{content:""}.ph.ph-phone-disconnect:before{content:""}.ph.ph-phone-incoming:before{content:""}.ph.ph-phone-list:before{content:""}.ph.ph-phone-outgoing:before{content:""}.ph.ph-phone-pause:before{content:""}.ph.ph-phone-plus:before{content:""}.ph.ph-phone-slash:before{content:""}.ph.ph-phone-transfer:before{content:""}.ph.ph-phone-x:before{content:""}.ph.ph-phosphor-logo:before{content:""}.ph.ph-pi:before{content:""}.ph.ph-piano-keys:before{content:""}.ph.ph-picnic-table:before{content:""}.ph.ph-picture-in-picture:before{content:""}.ph.ph-piggy-bank:before{content:""}.ph.ph-pill:before{content:""}.ph.ph-ping-pong:before{content:""}.ph.ph-pint-glass:before{content:""}.ph.ph-pinterest-logo:before{content:""}.ph.ph-pinwheel:before{content:""}.ph.ph-pipe:before{content:""}.ph.ph-pipe-wrench:before{content:""}.ph.ph-pix-logo:before{content:""}.ph.ph-pizza:before{content:""}.ph.ph-placeholder:before{content:""}.ph.ph-planet:before{content:""}.ph.ph-plant:before{content:""}.ph.ph-play:before{content:""}.ph.ph-play-circle:before{content:""}.ph.ph-play-pause:before{content:""}.ph.ph-playlist:before{content:""}.ph.ph-plug:before{content:""}.ph.ph-plug-charging:before{content:""}.ph.ph-plugs:before{content:""}.ph.ph-plugs-connected:before{content:""}.ph.ph-plus:before{content:""}.ph.ph-plus-circle:before{content:""}.ph.ph-plus-minus:before{content:""}.ph.ph-plus-square:before{content:""}.ph.ph-poker-chip:before{content:""}.ph.ph-police-car:before{content:""}.ph.ph-polygon:before{content:""}.ph.ph-popcorn:before{content:""}.ph.ph-popsicle:before{content:""}.ph.ph-potted-plant:before{content:""}.ph.ph-power:before{content:""}.ph.ph-prescription:before{content:""}.ph.ph-presentation:before{content:""}.ph.ph-presentation-chart:before{content:""}.ph.ph-printer:before{content:""}.ph.ph-prohibit:before{content:""}.ph.ph-prohibit-inset:before{content:""}.ph.ph-projector-screen:before{content:""}.ph.ph-projector-screen-chart:before{content:""}.ph.ph-pulse:before{content:""}.ph.ph-activity:before{content:""}.ph.ph-push-pin:before{content:""}.ph.ph-push-pin-simple:before{content:""}.ph.ph-push-pin-simple-slash:before{content:""}.ph.ph-push-pin-slash:before{content:""}.ph.ph-puzzle-piece:before{content:""}.ph.ph-qr-code:before{content:""}.ph.ph-question:before{content:""}.ph.ph-question-mark:before{content:""}.ph.ph-queue:before{content:""}.ph.ph-quotes:before{content:""}.ph.ph-rabbit:before{content:""}.ph.ph-racquet:before{content:""}.ph.ph-radical:before{content:""}.ph.ph-radio:before{content:""}.ph.ph-radio-button:before{content:""}.ph.ph-radioactive:before{content:""}.ph.ph-rainbow:before{content:""}.ph.ph-rainbow-cloud:before{content:""}.ph.ph-ranking:before{content:""}.ph.ph-read-cv-logo:before{content:""}.ph.ph-receipt:before{content:""}.ph.ph-receipt-x:before{content:""}.ph.ph-record:before{content:""}.ph.ph-rectangle:before{content:""}.ph.ph-rectangle-dashed:before{content:""}.ph.ph-recycle:before{content:""}.ph.ph-reddit-logo:before{content:""}.ph.ph-repeat:before{content:""}.ph.ph-repeat-once:before{content:""}.ph.ph-replit-logo:before{content:""}.ph.ph-resize:before{content:""}.ph.ph-rewind:before{content:""}.ph.ph-rewind-circle:before{content:""}.ph.ph-road-horizon:before{content:""}.ph.ph-robot:before{content:""}.ph.ph-rocket:before{content:""}.ph.ph-rocket-launch:before{content:""}.ph.ph-rows:before{content:""}.ph.ph-rows-plus-bottom:before{content:""}.ph.ph-rows-plus-top:before{content:""}.ph.ph-rss:before{content:""}.ph.ph-rss-simple:before{content:""}.ph.ph-rug:before{content:""}.ph.ph-ruler:before{content:""}.ph.ph-sailboat:before{content:""}.ph.ph-scales:before{content:""}.ph.ph-scan:before{content:""}.ph.ph-scan-smiley:before{content:""}.ph.ph-scissors:before{content:""}.ph.ph-scooter:before{content:""}.ph.ph-screencast:before{content:""}.ph.ph-screwdriver:before{content:""}.ph.ph-scribble:before{content:""}.ph.ph-scribble-loop:before{content:""}.ph.ph-scroll:before{content:""}.ph.ph-seal:before{content:""}.ph.ph-circle-wavy:before{content:""}.ph.ph-seal-check:before{content:""}.ph.ph-circle-wavy-check:before{content:""}.ph.ph-seal-percent:before{content:""}.ph.ph-seal-question:before{content:""}.ph.ph-circle-wavy-question:before{content:""}.ph.ph-seal-warning:before{content:""}.ph.ph-circle-wavy-warning:before{content:""}.ph.ph-seat:before{content:""}.ph.ph-seatbelt:before{content:""}.ph.ph-security-camera:before{content:""}.ph.ph-selection:before{content:""}.ph.ph-selection-all:before{content:""}.ph.ph-selection-background:before{content:""}.ph.ph-selection-foreground:before{content:""}.ph.ph-selection-inverse:before{content:""}.ph.ph-selection-plus:before{content:""}.ph.ph-selection-slash:before{content:""}.ph.ph-shapes:before{content:""}.ph.ph-share:before{content:""}.ph.ph-share-fat:before{content:""}.ph.ph-share-network:before{content:""}.ph.ph-shield:before{content:""}.ph.ph-shield-check:before{content:""}.ph.ph-shield-checkered:before{content:""}.ph.ph-shield-chevron:before{content:""}.ph.ph-shield-plus:before{content:""}.ph.ph-shield-slash:before{content:""}.ph.ph-shield-star:before{content:""}.ph.ph-shield-warning:before{content:""}.ph.ph-shipping-container:before{content:""}.ph.ph-shirt-folded:before{content:""}.ph.ph-shooting-star:before{content:""}.ph.ph-shopping-bag:before{content:""}.ph.ph-shopping-bag-open:before{content:""}.ph.ph-shopping-cart:before{content:""}.ph.ph-shopping-cart-simple:before{content:""}.ph.ph-shovel:before{content:""}.ph.ph-shower:before{content:""}.ph.ph-shrimp:before{content:""}.ph.ph-shuffle:before{content:""}.ph.ph-shuffle-angular:before{content:""}.ph.ph-shuffle-simple:before{content:""}.ph.ph-sidebar:before{content:""}.ph.ph-sidebar-simple:before{content:""}.ph.ph-sigma:before{content:""}.ph.ph-sign-in:before{content:""}.ph.ph-sign-out:before{content:""}.ph.ph-signature:before{content:""}.ph.ph-signpost:before{content:""}.ph.ph-sim-card:before{content:""}.ph.ph-siren:before{content:""}.ph.ph-sketch-logo:before{content:""}.ph.ph-skip-back:before{content:""}.ph.ph-skip-back-circle:before{content:""}.ph.ph-skip-forward:before{content:""}.ph.ph-skip-forward-circle:before{content:""}.ph.ph-skull:before{content:""}.ph.ph-skype-logo:before{content:""}.ph.ph-slack-logo:before{content:""}.ph.ph-sliders:before{content:""}.ph.ph-sliders-horizontal:before{content:""}.ph.ph-slideshow:before{content:""}.ph.ph-smiley:before{content:""}.ph.ph-smiley-angry:before{content:""}.ph.ph-smiley-blank:before{content:""}.ph.ph-smiley-meh:before{content:""}.ph.ph-smiley-melting:before{content:""}.ph.ph-smiley-nervous:before{content:""}.ph.ph-smiley-sad:before{content:""}.ph.ph-smiley-sticker:before{content:""}.ph.ph-smiley-wink:before{content:""}.ph.ph-smiley-x-eyes:before{content:""}.ph.ph-snapchat-logo:before{content:""}.ph.ph-sneaker:before{content:""}.ph.ph-sneaker-move:before{content:""}.ph.ph-snowflake:before{content:""}.ph.ph-soccer-ball:before{content:""}.ph.ph-sock:before{content:""}.ph.ph-solar-panel:before{content:""}.ph.ph-solar-roof:before{content:""}.ph.ph-sort-ascending:before{content:""}.ph.ph-sort-descending:before{content:""}.ph.ph-soundcloud-logo:before{content:""}.ph.ph-spade:before{content:""}.ph.ph-sparkle:before{content:""}.ph.ph-speaker-hifi:before{content:""}.ph.ph-speaker-high:before{content:""}.ph.ph-speaker-low:before{content:""}.ph.ph-speaker-none:before{content:""}.ph.ph-speaker-simple-high:before{content:""}.ph.ph-speaker-simple-low:before{content:""}.ph.ph-speaker-simple-none:before{content:""}.ph.ph-speaker-simple-slash:before{content:""}.ph.ph-speaker-simple-x:before{content:""}.ph.ph-speaker-slash:before{content:""}.ph.ph-speaker-x:before{content:""}.ph.ph-speedometer:before{content:""}.ph.ph-sphere:before{content:""}.ph.ph-spinner:before{content:""}.ph.ph-spinner-ball:before{content:""}.ph.ph-spinner-gap:before{content:""}.ph.ph-spiral:before{content:""}.ph.ph-split-horizontal:before{content:""}.ph.ph-split-vertical:before{content:""}.ph.ph-spotify-logo:before{content:""}.ph.ph-spray-bottle:before{content:""}.ph.ph-square:before{content:""}.ph.ph-square-half:before{content:""}.ph.ph-square-half-bottom:before{content:""}.ph.ph-square-logo:before{content:""}.ph.ph-square-split-horizontal:before{content:""}.ph.ph-square-split-vertical:before{content:""}.ph.ph-squares-four:before{content:""}.ph.ph-stack:before{content:""}.ph.ph-stack-minus:before{content:""}.ph.ph-stack-overflow-logo:before{content:""}.ph.ph-stack-plus:before{content:""}.ph.ph-stack-simple:before{content:""}.ph.ph-stairs:before{content:""}.ph.ph-stamp:before{content:""}.ph.ph-standard-definition:before{content:""}.ph.ph-star:before{content:""}.ph.ph-star-and-crescent:before{content:""}.ph.ph-star-four:before{content:""}.ph.ph-star-half:before{content:""}.ph.ph-star-of-david:before{content:""}.ph.ph-steam-logo:before{content:""}.ph.ph-steering-wheel:before{content:""}.ph.ph-steps:before{content:""}.ph.ph-stethoscope:before{content:""}.ph.ph-sticker:before{content:""}.ph.ph-stool:before{content:""}.ph.ph-stop:before{content:""}.ph.ph-stop-circle:before{content:""}.ph.ph-storefront:before{content:""}.ph.ph-strategy:before{content:""}.ph.ph-stripe-logo:before{content:""}.ph.ph-student:before{content:""}.ph.ph-subset-of:before{content:""}.ph.ph-subset-proper-of:before{content:""}.ph.ph-subtitles:before{content:""}.ph.ph-subtitles-slash:before{content:""}.ph.ph-subtract:before{content:""}.ph.ph-subtract-square:before{content:""}.ph.ph-subway:before{content:""}.ph.ph-suitcase:before{content:""}.ph.ph-suitcase-rolling:before{content:""}.ph.ph-suitcase-simple:before{content:""}.ph.ph-sun:before{content:""}.ph.ph-sun-dim:before{content:""}.ph.ph-sun-horizon:before{content:""}.ph.ph-sunglasses:before{content:""}.ph.ph-superset-of:before{content:""}.ph.ph-superset-proper-of:before{content:""}.ph.ph-swap:before{content:""}.ph.ph-swatches:before{content:""}.ph.ph-swimming-pool:before{content:""}.ph.ph-sword:before{content:""}.ph.ph-synagogue:before{content:""}.ph.ph-syringe:before{content:""}.ph.ph-t-shirt:before{content:""}.ph.ph-table:before{content:""}.ph.ph-tabs:before{content:""}.ph.ph-tag:before{content:""}.ph.ph-tag-chevron:before{content:""}.ph.ph-tag-simple:before{content:""}.ph.ph-target:before{content:""}.ph.ph-taxi:before{content:""}.ph.ph-tea-bag:before{content:""}.ph.ph-telegram-logo:before{content:""}.ph.ph-television:before{content:""}.ph.ph-television-simple:before{content:""}.ph.ph-tennis-ball:before{content:""}.ph.ph-tent:before{content:""}.ph.ph-terminal:before{content:""}.ph.ph-terminal-window:before{content:""}.ph.ph-test-tube:before{content:""}.ph.ph-text-a-underline:before{content:""}.ph.ph-text-aa:before{content:""}.ph.ph-text-align-center:before{content:""}.ph.ph-text-align-justify:before{content:""}.ph.ph-text-align-left:before{content:""}.ph.ph-text-align-right:before{content:""}.ph.ph-text-b:before{content:""}.ph.ph-text-bolder:before{content:""}.ph.ph-text-columns:before{content:""}.ph.ph-text-h:before{content:""}.ph.ph-text-h-five:before{content:""}.ph.ph-text-h-four:before{content:""}.ph.ph-text-h-one:before{content:""}.ph.ph-text-h-six:before{content:""}.ph.ph-text-h-three:before{content:""}.ph.ph-text-h-two:before{content:""}.ph.ph-text-indent:before{content:""}.ph.ph-text-italic:before{content:""}.ph.ph-text-outdent:before{content:""}.ph.ph-text-strikethrough:before{content:""}.ph.ph-text-subscript:before{content:""}.ph.ph-text-superscript:before{content:""}.ph.ph-text-t:before{content:""}.ph.ph-text-t-slash:before{content:""}.ph.ph-text-underline:before{content:""}.ph.ph-textbox:before{content:""}.ph.ph-thermometer:before{content:""}.ph.ph-thermometer-cold:before{content:""}.ph.ph-thermometer-hot:before{content:""}.ph.ph-thermometer-simple:before{content:""}.ph.ph-threads-logo:before{content:""}.ph.ph-three-d:before{content:""}.ph.ph-thumbs-down:before{content:""}.ph.ph-thumbs-up:before{content:""}.ph.ph-ticket:before{content:""}.ph.ph-tidal-logo:before{content:""}.ph.ph-tiktok-logo:before{content:""}.ph.ph-tilde:before{content:""}.ph.ph-timer:before{content:""}.ph.ph-tip-jar:before{content:""}.ph.ph-tipi:before{content:""}.ph.ph-tire:before{content:""}.ph.ph-toggle-left:before{content:""}.ph.ph-toggle-right:before{content:""}.ph.ph-toilet:before{content:""}.ph.ph-toilet-paper:before{content:""}.ph.ph-toolbox:before{content:""}.ph.ph-tooth:before{content:""}.ph.ph-tornado:before{content:""}.ph.ph-tote:before{content:""}.ph.ph-tote-simple:before{content:""}.ph.ph-towel:before{content:""}.ph.ph-tractor:before{content:""}.ph.ph-trademark:before{content:""}.ph.ph-trademark-registered:before{content:""}.ph.ph-traffic-cone:before{content:""}.ph.ph-traffic-sign:before{content:""}.ph.ph-traffic-signal:before{content:""}.ph.ph-train:before{content:""}.ph.ph-train-regional:before{content:""}.ph.ph-train-simple:before{content:""}.ph.ph-tram:before{content:""}.ph.ph-translate:before{content:""}.ph.ph-trash:before{content:""}.ph.ph-trash-simple:before{content:""}.ph.ph-tray:before{content:""}.ph.ph-tray-arrow-down:before{content:""}.ph.ph-archive-tray:before{content:""}.ph.ph-tray-arrow-up:before{content:""}.ph.ph-treasure-chest:before{content:""}.ph.ph-tree:before{content:""}.ph.ph-tree-evergreen:before{content:""}.ph.ph-tree-palm:before{content:""}.ph.ph-tree-structure:before{content:""}.ph.ph-tree-view:before{content:""}.ph.ph-trend-down:before{content:""}.ph.ph-trend-up:before{content:""}.ph.ph-triangle:before{content:""}.ph.ph-triangle-dashed:before{content:""}.ph.ph-trolley:before{content:""}.ph.ph-trolley-suitcase:before{content:""}.ph.ph-trophy:before{content:""}.ph.ph-truck:before{content:""}.ph.ph-truck-trailer:before{content:""}.ph.ph-tumblr-logo:before{content:""}.ph.ph-twitch-logo:before{content:""}.ph.ph-twitter-logo:before{content:""}.ph.ph-umbrella:before{content:""}.ph.ph-umbrella-simple:before{content:""}.ph.ph-union:before{content:""}.ph.ph-unite:before{content:""}.ph.ph-unite-square:before{content:""}.ph.ph-upload:before{content:""}.ph.ph-upload-simple:before{content:""}.ph.ph-usb:before{content:""}.ph.ph-user:before{content:""}.ph.ph-user-check:before{content:""}.ph.ph-user-circle:before{content:""}.ph.ph-user-circle-check:before{content:""}.ph.ph-user-circle-dashed:before{content:""}.ph.ph-user-circle-gear:before{content:""}.ph.ph-user-circle-minus:before{content:""}.ph.ph-user-circle-plus:before{content:""}.ph.ph-user-focus:before{content:""}.ph.ph-user-gear:before{content:""}.ph.ph-user-list:before{content:""}.ph.ph-user-minus:before{content:""}.ph.ph-user-plus:before{content:""}.ph.ph-user-rectangle:before{content:""}.ph.ph-user-sound:before{content:""}.ph.ph-user-square:before{content:""}.ph.ph-user-switch:before{content:""}.ph.ph-users:before{content:""}.ph.ph-users-four:before{content:""}.ph.ph-users-three:before{content:""}.ph.ph-van:before{content:""}.ph.ph-vault:before{content:""}.ph.ph-vector-three:before{content:""}.ph.ph-vector-two:before{content:""}.ph.ph-vibrate:before{content:""}.ph.ph-video:before{content:""}.ph.ph-video-camera:before{content:""}.ph.ph-video-camera-slash:before{content:""}.ph.ph-video-conference:before{content:""}.ph.ph-vignette:before{content:""}.ph.ph-vinyl-record:before{content:""}.ph.ph-virtual-reality:before{content:""}.ph.ph-virus:before{content:""}.ph.ph-visor:before{content:""}.ph.ph-voicemail:before{content:""}.ph.ph-volleyball:before{content:""}.ph.ph-wall:before{content:""}.ph.ph-wallet:before{content:""}.ph.ph-warehouse:before{content:""}.ph.ph-warning:before{content:""}.ph.ph-warning-circle:before{content:""}.ph.ph-warning-diamond:before{content:""}.ph.ph-warning-octagon:before{content:""}.ph.ph-washing-machine:before{content:""}.ph.ph-watch:before{content:""}.ph.ph-wave-sawtooth:before{content:""}.ph.ph-wave-sine:before{content:""}.ph.ph-wave-square:before{content:""}.ph.ph-wave-triangle:before{content:""}.ph.ph-waveform:before{content:""}.ph.ph-waveform-slash:before{content:""}.ph.ph-waves:before{content:""}.ph.ph-webcam:before{content:""}.ph.ph-webcam-slash:before{content:""}.ph.ph-webhooks-logo:before{content:""}.ph.ph-wechat-logo:before{content:""}.ph.ph-whatsapp-logo:before{content:""}.ph.ph-wheelchair:before{content:""}.ph.ph-wheelchair-motion:before{content:""}.ph.ph-wifi-high:before{content:""}.ph.ph-wifi-low:before{content:""}.ph.ph-wifi-medium:before{content:""}.ph.ph-wifi-none:before{content:""}.ph.ph-wifi-slash:before{content:""}.ph.ph-wifi-x:before{content:""}.ph.ph-wind:before{content:""}.ph.ph-windmill:before{content:""}.ph.ph-windows-logo:before{content:""}.ph.ph-wine:before{content:""}.ph.ph-wrench:before{content:""}.ph.ph-x:before{content:""}.ph.ph-x-circle:before{content:""}.ph.ph-x-logo:before{content:""}.ph.ph-x-square:before{content:""}.ph.ph-yarn:before{content:""}.ph.ph-yin-yang:before{content:""}.ph.ph-youtube-logo:before{content:""}@font-face{font-family:Phosphor-Fill;src:url(/assets/Phosphor-Fill-D4CDmGRg.woff2) format("woff2"),url(/assets/Phosphor-Fill-CS2zOYDV.woff) format("woff"),url(/assets/Phosphor-Fill-N9gYSHy0.ttf) format("truetype"),url(/assets/Phosphor-Fill-BofDnXwa.svg#Phosphor-Fill) format("svg");font-weight:400;font-style:normal;font-display:block}.ph-fill{font-family:Phosphor-Fill!important;speak:never;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;letter-spacing:0;-webkit-font-feature-settings:"liga";-moz-font-feature-settings:"liga=1";-moz-font-feature-settings:"liga";-ms-font-feature-settings:"liga" 1;font-feature-settings:"liga";-webkit-font-variant-ligatures:discretionary-ligatures;font-variant-ligatures:discretionary-ligatures;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.ph-fill.ph-acorn:before{content:""}.ph-fill.ph-address-book:before{content:""}.ph-fill.ph-address-book-tabs:before{content:""}.ph-fill.ph-air-traffic-control:before{content:""}.ph-fill.ph-airplane:before{content:""}.ph-fill.ph-airplane-in-flight:before{content:""}.ph-fill.ph-airplane-landing:before{content:""}.ph-fill.ph-airplane-takeoff:before{content:""}.ph-fill.ph-airplane-taxiing:before{content:""}.ph-fill.ph-airplane-tilt:before{content:""}.ph-fill.ph-airplay:before{content:""}.ph-fill.ph-alarm:before{content:""}.ph-fill.ph-alien:before{content:""}.ph-fill.ph-align-bottom:before{content:""}.ph-fill.ph-align-bottom-simple:before{content:""}.ph-fill.ph-align-center-horizontal:before{content:""}.ph-fill.ph-align-center-horizontal-simple:before{content:""}.ph-fill.ph-align-center-vertical:before{content:""}.ph-fill.ph-align-center-vertical-simple:before{content:""}.ph-fill.ph-align-left:before{content:""}.ph-fill.ph-align-left-simple:before{content:""}.ph-fill.ph-align-right:before{content:""}.ph-fill.ph-align-right-simple:before{content:""}.ph-fill.ph-align-top:before{content:""}.ph-fill.ph-align-top-simple:before{content:""}.ph-fill.ph-amazon-logo:before{content:""}.ph-fill.ph-ambulance:before{content:""}.ph-fill.ph-anchor:before{content:""}.ph-fill.ph-anchor-simple:before{content:""}.ph-fill.ph-android-logo:before{content:""}.ph-fill.ph-angle:before{content:""}.ph-fill.ph-angular-logo:before{content:""}.ph-fill.ph-aperture:before{content:""}.ph-fill.ph-app-store-logo:before{content:""}.ph-fill.ph-app-window:before{content:""}.ph-fill.ph-apple-logo:before{content:""}.ph-fill.ph-apple-podcasts-logo:before{content:""}.ph-fill.ph-approximate-equals:before{content:""}.ph-fill.ph-archive:before{content:""}.ph-fill.ph-armchair:before{content:""}.ph-fill.ph-arrow-arc-left:before{content:""}.ph-fill.ph-arrow-arc-right:before{content:""}.ph-fill.ph-arrow-bend-double-up-left:before{content:""}.ph-fill.ph-arrow-bend-double-up-right:before{content:""}.ph-fill.ph-arrow-bend-down-left:before{content:""}.ph-fill.ph-arrow-bend-down-right:before{content:""}.ph-fill.ph-arrow-bend-left-down:before{content:""}.ph-fill.ph-arrow-bend-left-up:before{content:""}.ph-fill.ph-arrow-bend-right-down:before{content:""}.ph-fill.ph-arrow-bend-right-up:before{content:""}.ph-fill.ph-arrow-bend-up-left:before{content:""}.ph-fill.ph-arrow-bend-up-right:before{content:""}.ph-fill.ph-arrow-circle-down:before{content:""}.ph-fill.ph-arrow-circle-down-left:before{content:""}.ph-fill.ph-arrow-circle-down-right:before{content:""}.ph-fill.ph-arrow-circle-left:before{content:""}.ph-fill.ph-arrow-circle-right:before{content:""}.ph-fill.ph-arrow-circle-up:before{content:""}.ph-fill.ph-arrow-circle-up-left:before{content:""}.ph-fill.ph-arrow-circle-up-right:before{content:""}.ph-fill.ph-arrow-clockwise:before{content:""}.ph-fill.ph-arrow-counter-clockwise:before{content:""}.ph-fill.ph-arrow-down:before{content:""}.ph-fill.ph-arrow-down-left:before{content:""}.ph-fill.ph-arrow-down-right:before{content:""}.ph-fill.ph-arrow-elbow-down-left:before{content:""}.ph-fill.ph-arrow-elbow-down-right:before{content:""}.ph-fill.ph-arrow-elbow-left:before{content:""}.ph-fill.ph-arrow-elbow-left-down:before{content:""}.ph-fill.ph-arrow-elbow-left-up:before{content:""}.ph-fill.ph-arrow-elbow-right:before{content:""}.ph-fill.ph-arrow-elbow-right-down:before{content:""}.ph-fill.ph-arrow-elbow-right-up:before{content:""}.ph-fill.ph-arrow-elbow-up-left:before{content:""}.ph-fill.ph-arrow-elbow-up-right:before{content:""}.ph-fill.ph-arrow-fat-down:before{content:""}.ph-fill.ph-arrow-fat-left:before{content:""}.ph-fill.ph-arrow-fat-line-down:before{content:""}.ph-fill.ph-arrow-fat-line-left:before{content:""}.ph-fill.ph-arrow-fat-line-right:before{content:""}.ph-fill.ph-arrow-fat-line-up:before{content:""}.ph-fill.ph-arrow-fat-lines-down:before{content:""}.ph-fill.ph-arrow-fat-lines-left:before{content:""}.ph-fill.ph-arrow-fat-lines-right:before{content:""}.ph-fill.ph-arrow-fat-lines-up:before{content:""}.ph-fill.ph-arrow-fat-right:before{content:""}.ph-fill.ph-arrow-fat-up:before{content:""}.ph-fill.ph-arrow-left:before{content:""}.ph-fill.ph-arrow-line-down:before{content:""}.ph-fill.ph-arrow-line-down-left:before{content:""}.ph-fill.ph-arrow-line-down-right:before{content:""}.ph-fill.ph-arrow-line-left:before{content:""}.ph-fill.ph-arrow-line-right:before{content:""}.ph-fill.ph-arrow-line-up:before{content:""}.ph-fill.ph-arrow-line-up-left:before{content:""}.ph-fill.ph-arrow-line-up-right:before{content:""}.ph-fill.ph-arrow-right:before{content:""}.ph-fill.ph-arrow-square-down:before{content:""}.ph-fill.ph-arrow-square-down-left:before{content:""}.ph-fill.ph-arrow-square-down-right:before{content:""}.ph-fill.ph-arrow-square-in:before{content:""}.ph-fill.ph-arrow-square-left:before{content:""}.ph-fill.ph-arrow-square-out:before{content:""}.ph-fill.ph-arrow-square-right:before{content:""}.ph-fill.ph-arrow-square-up:before{content:""}.ph-fill.ph-arrow-square-up-left:before{content:""}.ph-fill.ph-arrow-square-up-right:before{content:""}.ph-fill.ph-arrow-u-down-left:before{content:""}.ph-fill.ph-arrow-u-down-right:before{content:""}.ph-fill.ph-arrow-u-left-down:before{content:""}.ph-fill.ph-arrow-u-left-up:before{content:""}.ph-fill.ph-arrow-u-right-down:before{content:""}.ph-fill.ph-arrow-u-right-up:before{content:""}.ph-fill.ph-arrow-u-up-left:before{content:""}.ph-fill.ph-arrow-u-up-right:before{content:""}.ph-fill.ph-arrow-up:before{content:""}.ph-fill.ph-arrow-up-left:before{content:""}.ph-fill.ph-arrow-up-right:before{content:""}.ph-fill.ph-arrows-clockwise:before{content:""}.ph-fill.ph-arrows-counter-clockwise:before{content:""}.ph-fill.ph-arrows-down-up:before{content:""}.ph-fill.ph-arrows-horizontal:before{content:""}.ph-fill.ph-arrows-in:before{content:""}.ph-fill.ph-arrows-in-cardinal:before{content:""}.ph-fill.ph-arrows-in-line-horizontal:before{content:""}.ph-fill.ph-arrows-in-line-vertical:before{content:""}.ph-fill.ph-arrows-in-simple:before{content:""}.ph-fill.ph-arrows-left-right:before{content:""}.ph-fill.ph-arrows-merge:before{content:""}.ph-fill.ph-arrows-out:before{content:""}.ph-fill.ph-arrows-out-cardinal:before{content:""}.ph-fill.ph-arrows-out-line-horizontal:before{content:""}.ph-fill.ph-arrows-out-line-vertical:before{content:""}.ph-fill.ph-arrows-out-simple:before{content:""}.ph-fill.ph-arrows-split:before{content:""}.ph-fill.ph-arrows-vertical:before{content:""}.ph-fill.ph-article:before{content:""}.ph-fill.ph-article-medium:before{content:""}.ph-fill.ph-article-ny-times:before{content:""}.ph-fill.ph-asclepius:before{content:""}.ph-fill.ph-caduceus:before{content:""}.ph-fill.ph-asterisk:before{content:""}.ph-fill.ph-asterisk-simple:before{content:""}.ph-fill.ph-at:before{content:""}.ph-fill.ph-atom:before{content:""}.ph-fill.ph-avocado:before{content:""}.ph-fill.ph-axe:before{content:""}.ph-fill.ph-baby:before{content:""}.ph-fill.ph-baby-carriage:before{content:""}.ph-fill.ph-backpack:before{content:""}.ph-fill.ph-backspace:before{content:""}.ph-fill.ph-bag:before{content:""}.ph-fill.ph-bag-simple:before{content:""}.ph-fill.ph-balloon:before{content:""}.ph-fill.ph-bandaids:before{content:""}.ph-fill.ph-bank:before{content:""}.ph-fill.ph-barbell:before{content:""}.ph-fill.ph-barcode:before{content:""}.ph-fill.ph-barn:before{content:""}.ph-fill.ph-barricade:before{content:""}.ph-fill.ph-baseball:before{content:""}.ph-fill.ph-baseball-cap:before{content:""}.ph-fill.ph-baseball-helmet:before{content:""}.ph-fill.ph-basket:before{content:""}.ph-fill.ph-basketball:before{content:""}.ph-fill.ph-bathtub:before{content:""}.ph-fill.ph-battery-charging:before{content:""}.ph-fill.ph-battery-charging-vertical:before{content:""}.ph-fill.ph-battery-empty:before{content:""}.ph-fill.ph-battery-full:before{content:""}.ph-fill.ph-battery-high:before{content:""}.ph-fill.ph-battery-low:before{content:""}.ph-fill.ph-battery-medium:before{content:""}.ph-fill.ph-battery-plus:before{content:""}.ph-fill.ph-battery-plus-vertical:before{content:""}.ph-fill.ph-battery-vertical-empty:before{content:""}.ph-fill.ph-battery-vertical-full:before{content:""}.ph-fill.ph-battery-vertical-high:before{content:""}.ph-fill.ph-battery-vertical-low:before{content:""}.ph-fill.ph-battery-vertical-medium:before{content:""}.ph-fill.ph-battery-warning:before{content:""}.ph-fill.ph-battery-warning-vertical:before{content:""}.ph-fill.ph-beach-ball:before{content:""}.ph-fill.ph-beanie:before{content:""}.ph-fill.ph-bed:before{content:""}.ph-fill.ph-beer-bottle:before{content:""}.ph-fill.ph-beer-stein:before{content:""}.ph-fill.ph-behance-logo:before{content:""}.ph-fill.ph-bell:before{content:""}.ph-fill.ph-bell-ringing:before{content:""}.ph-fill.ph-bell-simple:before{content:""}.ph-fill.ph-bell-simple-ringing:before{content:""}.ph-fill.ph-bell-simple-slash:before{content:""}.ph-fill.ph-bell-simple-z:before{content:""}.ph-fill.ph-bell-slash:before{content:""}.ph-fill.ph-bell-z:before{content:""}.ph-fill.ph-belt:before{content:""}.ph-fill.ph-bezier-curve:before{content:""}.ph-fill.ph-bicycle:before{content:""}.ph-fill.ph-binary:before{content:""}.ph-fill.ph-binoculars:before{content:""}.ph-fill.ph-biohazard:before{content:""}.ph-fill.ph-bird:before{content:""}.ph-fill.ph-blueprint:before{content:""}.ph-fill.ph-bluetooth:before{content:""}.ph-fill.ph-bluetooth-connected:before{content:""}.ph-fill.ph-bluetooth-slash:before{content:""}.ph-fill.ph-bluetooth-x:before{content:""}.ph-fill.ph-boat:before{content:""}.ph-fill.ph-bomb:before{content:""}.ph-fill.ph-bone:before{content:""}.ph-fill.ph-book:before{content:""}.ph-fill.ph-book-bookmark:before{content:""}.ph-fill.ph-book-open:before{content:""}.ph-fill.ph-book-open-text:before{content:""}.ph-fill.ph-book-open-user:before{content:""}.ph-fill.ph-bookmark:before{content:""}.ph-fill.ph-bookmark-simple:before{content:""}.ph-fill.ph-bookmarks:before{content:""}.ph-fill.ph-bookmarks-simple:before{content:""}.ph-fill.ph-books:before{content:""}.ph-fill.ph-boot:before{content:""}.ph-fill.ph-boules:before{content:""}.ph-fill.ph-bounding-box:before{content:""}.ph-fill.ph-bowl-food:before{content:""}.ph-fill.ph-bowl-steam:before{content:""}.ph-fill.ph-bowling-ball:before{content:""}.ph-fill.ph-box-arrow-down:before{content:""}.ph-fill.ph-archive-box:before{content:""}.ph-fill.ph-box-arrow-up:before{content:""}.ph-fill.ph-boxing-glove:before{content:""}.ph-fill.ph-brackets-angle:before{content:""}.ph-fill.ph-brackets-curly:before{content:""}.ph-fill.ph-brackets-round:before{content:""}.ph-fill.ph-brackets-square:before{content:""}.ph-fill.ph-brain:before{content:""}.ph-fill.ph-brandy:before{content:""}.ph-fill.ph-bread:before{content:""}.ph-fill.ph-bridge:before{content:""}.ph-fill.ph-briefcase:before{content:""}.ph-fill.ph-briefcase-metal:before{content:""}.ph-fill.ph-broadcast:before{content:""}.ph-fill.ph-broom:before{content:""}.ph-fill.ph-browser:before{content:""}.ph-fill.ph-browsers:before{content:""}.ph-fill.ph-bug:before{content:""}.ph-fill.ph-bug-beetle:before{content:""}.ph-fill.ph-bug-droid:before{content:""}.ph-fill.ph-building:before{content:""}.ph-fill.ph-building-apartment:before{content:""}.ph-fill.ph-building-office:before{content:""}.ph-fill.ph-buildings:before{content:""}.ph-fill.ph-bulldozer:before{content:""}.ph-fill.ph-bus:before{content:""}.ph-fill.ph-butterfly:before{content:""}.ph-fill.ph-cable-car:before{content:""}.ph-fill.ph-cactus:before{content:""}.ph-fill.ph-cake:before{content:""}.ph-fill.ph-calculator:before{content:""}.ph-fill.ph-calendar:before{content:""}.ph-fill.ph-calendar-blank:before{content:""}.ph-fill.ph-calendar-check:before{content:""}.ph-fill.ph-calendar-dot:before{content:""}.ph-fill.ph-calendar-dots:before{content:""}.ph-fill.ph-calendar-heart:before{content:""}.ph-fill.ph-calendar-minus:before{content:""}.ph-fill.ph-calendar-plus:before{content:""}.ph-fill.ph-calendar-slash:before{content:""}.ph-fill.ph-calendar-star:before{content:""}.ph-fill.ph-calendar-x:before{content:""}.ph-fill.ph-call-bell:before{content:""}.ph-fill.ph-camera:before{content:""}.ph-fill.ph-camera-plus:before{content:""}.ph-fill.ph-camera-rotate:before{content:""}.ph-fill.ph-camera-slash:before{content:""}.ph-fill.ph-campfire:before{content:""}.ph-fill.ph-car:before{content:""}.ph-fill.ph-car-battery:before{content:""}.ph-fill.ph-car-profile:before{content:""}.ph-fill.ph-car-simple:before{content:""}.ph-fill.ph-cardholder:before{content:""}.ph-fill.ph-cards:before{content:""}.ph-fill.ph-cards-three:before{content:""}.ph-fill.ph-caret-circle-double-down:before{content:""}.ph-fill.ph-caret-circle-double-left:before{content:""}.ph-fill.ph-caret-circle-double-right:before{content:""}.ph-fill.ph-caret-circle-double-up:before{content:""}.ph-fill.ph-caret-circle-down:before{content:""}.ph-fill.ph-caret-circle-left:before{content:""}.ph-fill.ph-caret-circle-right:before{content:""}.ph-fill.ph-caret-circle-up:before{content:""}.ph-fill.ph-caret-circle-up-down:before{content:""}.ph-fill.ph-caret-double-down:before{content:""}.ph-fill.ph-caret-double-left:before{content:""}.ph-fill.ph-caret-double-right:before{content:""}.ph-fill.ph-caret-double-up:before{content:""}.ph-fill.ph-caret-down:before{content:""}.ph-fill.ph-caret-left:before{content:""}.ph-fill.ph-caret-line-down:before{content:""}.ph-fill.ph-caret-line-left:before{content:""}.ph-fill.ph-caret-line-right:before{content:""}.ph-fill.ph-caret-line-up:before{content:""}.ph-fill.ph-caret-right:before{content:""}.ph-fill.ph-caret-up:before{content:""}.ph-fill.ph-caret-up-down:before{content:""}.ph-fill.ph-carrot:before{content:""}.ph-fill.ph-cash-register:before{content:""}.ph-fill.ph-cassette-tape:before{content:""}.ph-fill.ph-castle-turret:before{content:""}.ph-fill.ph-cat:before{content:""}.ph-fill.ph-cell-signal-full:before{content:""}.ph-fill.ph-cell-signal-high:before{content:""}.ph-fill.ph-cell-signal-low:before{content:""}.ph-fill.ph-cell-signal-medium:before{content:""}.ph-fill.ph-cell-signal-none:before{content:""}.ph-fill.ph-cell-signal-slash:before{content:""}.ph-fill.ph-cell-signal-x:before{content:""}.ph-fill.ph-cell-tower:before{content:""}.ph-fill.ph-certificate:before{content:""}.ph-fill.ph-chair:before{content:""}.ph-fill.ph-chalkboard:before{content:""}.ph-fill.ph-chalkboard-simple:before{content:""}.ph-fill.ph-chalkboard-teacher:before{content:""}.ph-fill.ph-champagne:before{content:""}.ph-fill.ph-charging-station:before{content:""}.ph-fill.ph-chart-bar:before{content:""}.ph-fill.ph-chart-bar-horizontal:before{content:""}.ph-fill.ph-chart-donut:before{content:""}.ph-fill.ph-chart-line:before{content:""}.ph-fill.ph-chart-line-down:before{content:""}.ph-fill.ph-chart-line-up:before{content:""}.ph-fill.ph-chart-pie:before{content:""}.ph-fill.ph-chart-pie-slice:before{content:""}.ph-fill.ph-chart-polar:before{content:""}.ph-fill.ph-chart-scatter:before{content:""}.ph-fill.ph-chat:before{content:""}.ph-fill.ph-chat-centered:before{content:""}.ph-fill.ph-chat-centered-dots:before{content:""}.ph-fill.ph-chat-centered-slash:before{content:""}.ph-fill.ph-chat-centered-text:before{content:""}.ph-fill.ph-chat-circle:before{content:""}.ph-fill.ph-chat-circle-dots:before{content:""}.ph-fill.ph-chat-circle-slash:before{content:""}.ph-fill.ph-chat-circle-text:before{content:""}.ph-fill.ph-chat-dots:before{content:""}.ph-fill.ph-chat-slash:before{content:""}.ph-fill.ph-chat-teardrop:before{content:""}.ph-fill.ph-chat-teardrop-dots:before{content:""}.ph-fill.ph-chat-teardrop-slash:before{content:""}.ph-fill.ph-chat-teardrop-text:before{content:""}.ph-fill.ph-chat-text:before{content:""}.ph-fill.ph-chats:before{content:""}.ph-fill.ph-chats-circle:before{content:""}.ph-fill.ph-chats-teardrop:before{content:""}.ph-fill.ph-check:before{content:""}.ph-fill.ph-check-circle:before{content:""}.ph-fill.ph-check-fat:before{content:""}.ph-fill.ph-check-square:before{content:""}.ph-fill.ph-check-square-offset:before{content:""}.ph-fill.ph-checkerboard:before{content:""}.ph-fill.ph-checks:before{content:""}.ph-fill.ph-cheers:before{content:""}.ph-fill.ph-cheese:before{content:""}.ph-fill.ph-chef-hat:before{content:""}.ph-fill.ph-cherries:before{content:""}.ph-fill.ph-church:before{content:""}.ph-fill.ph-cigarette:before{content:""}.ph-fill.ph-cigarette-slash:before{content:""}.ph-fill.ph-circle:before{content:""}.ph-fill.ph-circle-dashed:before{content:""}.ph-fill.ph-circle-half:before{content:""}.ph-fill.ph-circle-half-tilt:before{content:""}.ph-fill.ph-circle-notch:before{content:""}.ph-fill.ph-circles-four:before{content:""}.ph-fill.ph-circles-three:before{content:""}.ph-fill.ph-circles-three-plus:before{content:""}.ph-fill.ph-circuitry:before{content:""}.ph-fill.ph-city:before{content:""}.ph-fill.ph-clipboard:before{content:""}.ph-fill.ph-clipboard-text:before{content:""}.ph-fill.ph-clock:before{content:""}.ph-fill.ph-clock-afternoon:before{content:""}.ph-fill.ph-clock-clockwise:before{content:""}.ph-fill.ph-clock-countdown:before{content:""}.ph-fill.ph-clock-counter-clockwise:before{content:""}.ph-fill.ph-clock-user:before{content:""}.ph-fill.ph-closed-captioning:before{content:""}.ph-fill.ph-cloud:before{content:""}.ph-fill.ph-cloud-arrow-down:before{content:""}.ph-fill.ph-cloud-arrow-up:before{content:""}.ph-fill.ph-cloud-check:before{content:""}.ph-fill.ph-cloud-fog:before{content:""}.ph-fill.ph-cloud-lightning:before{content:""}.ph-fill.ph-cloud-moon:before{content:""}.ph-fill.ph-cloud-rain:before{content:""}.ph-fill.ph-cloud-slash:before{content:""}.ph-fill.ph-cloud-snow:before{content:""}.ph-fill.ph-cloud-sun:before{content:""}.ph-fill.ph-cloud-warning:before{content:""}.ph-fill.ph-cloud-x:before{content:""}.ph-fill.ph-clover:before{content:""}.ph-fill.ph-club:before{content:""}.ph-fill.ph-coat-hanger:before{content:""}.ph-fill.ph-coda-logo:before{content:""}.ph-fill.ph-code:before{content:""}.ph-fill.ph-code-block:before{content:""}.ph-fill.ph-code-simple:before{content:""}.ph-fill.ph-codepen-logo:before{content:""}.ph-fill.ph-codesandbox-logo:before{content:""}.ph-fill.ph-coffee:before{content:""}.ph-fill.ph-coffee-bean:before{content:""}.ph-fill.ph-coin:before{content:""}.ph-fill.ph-coin-vertical:before{content:""}.ph-fill.ph-coins:before{content:""}.ph-fill.ph-columns:before{content:""}.ph-fill.ph-columns-plus-left:before{content:""}.ph-fill.ph-columns-plus-right:before{content:""}.ph-fill.ph-command:before{content:""}.ph-fill.ph-compass:before{content:""}.ph-fill.ph-compass-rose:before{content:""}.ph-fill.ph-compass-tool:before{content:""}.ph-fill.ph-computer-tower:before{content:""}.ph-fill.ph-confetti:before{content:""}.ph-fill.ph-contactless-payment:before{content:""}.ph-fill.ph-control:before{content:""}.ph-fill.ph-cookie:before{content:""}.ph-fill.ph-cooking-pot:before{content:""}.ph-fill.ph-copy:before{content:""}.ph-fill.ph-copy-simple:before{content:""}.ph-fill.ph-copyleft:before{content:""}.ph-fill.ph-copyright:before{content:""}.ph-fill.ph-corners-in:before{content:""}.ph-fill.ph-corners-out:before{content:""}.ph-fill.ph-couch:before{content:""}.ph-fill.ph-court-basketball:before{content:""}.ph-fill.ph-cow:before{content:""}.ph-fill.ph-cowboy-hat:before{content:""}.ph-fill.ph-cpu:before{content:""}.ph-fill.ph-crane:before{content:""}.ph-fill.ph-crane-tower:before{content:""}.ph-fill.ph-credit-card:before{content:""}.ph-fill.ph-cricket:before{content:""}.ph-fill.ph-crop:before{content:""}.ph-fill.ph-cross:before{content:""}.ph-fill.ph-crosshair:before{content:""}.ph-fill.ph-crosshair-simple:before{content:""}.ph-fill.ph-crown:before{content:""}.ph-fill.ph-crown-cross:before{content:""}.ph-fill.ph-crown-simple:before{content:""}.ph-fill.ph-cube:before{content:""}.ph-fill.ph-cube-focus:before{content:""}.ph-fill.ph-cube-transparent:before{content:""}.ph-fill.ph-currency-btc:before{content:""}.ph-fill.ph-currency-circle-dollar:before{content:""}.ph-fill.ph-currency-cny:before{content:""}.ph-fill.ph-currency-dollar:before{content:""}.ph-fill.ph-currency-dollar-simple:before{content:""}.ph-fill.ph-currency-eth:before{content:""}.ph-fill.ph-currency-eur:before{content:""}.ph-fill.ph-currency-gbp:before{content:""}.ph-fill.ph-currency-inr:before{content:""}.ph-fill.ph-currency-jpy:before{content:""}.ph-fill.ph-currency-krw:before{content:""}.ph-fill.ph-currency-kzt:before{content:""}.ph-fill.ph-currency-ngn:before{content:""}.ph-fill.ph-currency-rub:before{content:""}.ph-fill.ph-cursor:before{content:""}.ph-fill.ph-cursor-click:before{content:""}.ph-fill.ph-cursor-text:before{content:""}.ph-fill.ph-cylinder:before{content:""}.ph-fill.ph-database:before{content:""}.ph-fill.ph-desk:before{content:""}.ph-fill.ph-desktop:before{content:""}.ph-fill.ph-desktop-tower:before{content:""}.ph-fill.ph-detective:before{content:""}.ph-fill.ph-dev-to-logo:before{content:""}.ph-fill.ph-device-mobile:before{content:""}.ph-fill.ph-device-mobile-camera:before{content:""}.ph-fill.ph-device-mobile-slash:before{content:""}.ph-fill.ph-device-mobile-speaker:before{content:""}.ph-fill.ph-device-rotate:before{content:""}.ph-fill.ph-device-tablet:before{content:""}.ph-fill.ph-device-tablet-camera:before{content:""}.ph-fill.ph-device-tablet-speaker:before{content:""}.ph-fill.ph-devices:before{content:""}.ph-fill.ph-diamond:before{content:""}.ph-fill.ph-diamonds-four:before{content:""}.ph-fill.ph-dice-five:before{content:""}.ph-fill.ph-dice-four:before{content:""}.ph-fill.ph-dice-one:before{content:""}.ph-fill.ph-dice-six:before{content:""}.ph-fill.ph-dice-three:before{content:""}.ph-fill.ph-dice-two:before{content:""}.ph-fill.ph-disc:before{content:""}.ph-fill.ph-disco-ball:before{content:""}.ph-fill.ph-discord-logo:before{content:""}.ph-fill.ph-divide:before{content:""}.ph-fill.ph-dna:before{content:""}.ph-fill.ph-dog:before{content:""}.ph-fill.ph-door:before{content:""}.ph-fill.ph-door-open:before{content:""}.ph-fill.ph-dot:before{content:""}.ph-fill.ph-dot-outline:before{content:""}.ph-fill.ph-dots-nine:before{content:""}.ph-fill.ph-dots-six:before{content:""}.ph-fill.ph-dots-six-vertical:before{content:""}.ph-fill.ph-dots-three:before{content:""}.ph-fill.ph-dots-three-circle:before{content:""}.ph-fill.ph-dots-three-circle-vertical:before{content:""}.ph-fill.ph-dots-three-outline:before{content:""}.ph-fill.ph-dots-three-outline-vertical:before{content:""}.ph-fill.ph-dots-three-vertical:before{content:""}.ph-fill.ph-download:before{content:""}.ph-fill.ph-download-simple:before{content:""}.ph-fill.ph-dress:before{content:""}.ph-fill.ph-dresser:before{content:""}.ph-fill.ph-dribbble-logo:before{content:""}.ph-fill.ph-drone:before{content:""}.ph-fill.ph-drop:before{content:""}.ph-fill.ph-drop-half:before{content:""}.ph-fill.ph-drop-half-bottom:before{content:""}.ph-fill.ph-drop-simple:before{content:""}.ph-fill.ph-drop-slash:before{content:""}.ph-fill.ph-dropbox-logo:before{content:""}.ph-fill.ph-ear:before{content:""}.ph-fill.ph-ear-slash:before{content:""}.ph-fill.ph-egg:before{content:""}.ph-fill.ph-egg-crack:before{content:""}.ph-fill.ph-eject:before{content:""}.ph-fill.ph-eject-simple:before{content:""}.ph-fill.ph-elevator:before{content:""}.ph-fill.ph-empty:before{content:""}.ph-fill.ph-engine:before{content:""}.ph-fill.ph-envelope:before{content:""}.ph-fill.ph-envelope-open:before{content:""}.ph-fill.ph-envelope-simple:before{content:""}.ph-fill.ph-envelope-simple-open:before{content:""}.ph-fill.ph-equalizer:before{content:""}.ph-fill.ph-equals:before{content:""}.ph-fill.ph-eraser:before{content:""}.ph-fill.ph-escalator-down:before{content:""}.ph-fill.ph-escalator-up:before{content:""}.ph-fill.ph-exam:before{content:""}.ph-fill.ph-exclamation-mark:before{content:""}.ph-fill.ph-exclude:before{content:""}.ph-fill.ph-exclude-square:before{content:""}.ph-fill.ph-export:before{content:""}.ph-fill.ph-eye:before{content:""}.ph-fill.ph-eye-closed:before{content:""}.ph-fill.ph-eye-slash:before{content:""}.ph-fill.ph-eyedropper:before{content:""}.ph-fill.ph-eyedropper-sample:before{content:""}.ph-fill.ph-eyeglasses:before{content:""}.ph-fill.ph-eyes:before{content:""}.ph-fill.ph-face-mask:before{content:""}.ph-fill.ph-facebook-logo:before{content:""}.ph-fill.ph-factory:before{content:""}.ph-fill.ph-faders:before{content:""}.ph-fill.ph-faders-horizontal:before{content:""}.ph-fill.ph-fallout-shelter:before{content:""}.ph-fill.ph-fan:before{content:""}.ph-fill.ph-farm:before{content:""}.ph-fill.ph-fast-forward:before{content:""}.ph-fill.ph-fast-forward-circle:before{content:""}.ph-fill.ph-feather:before{content:""}.ph-fill.ph-fediverse-logo:before{content:""}.ph-fill.ph-figma-logo:before{content:""}.ph-fill.ph-file:before{content:""}.ph-fill.ph-file-archive:before{content:""}.ph-fill.ph-file-arrow-down:before{content:""}.ph-fill.ph-file-arrow-up:before{content:""}.ph-fill.ph-file-audio:before{content:""}.ph-fill.ph-file-c:before{content:""}.ph-fill.ph-file-c-sharp:before{content:""}.ph-fill.ph-file-cloud:before{content:""}.ph-fill.ph-file-code:before{content:""}.ph-fill.ph-file-cpp:before{content:""}.ph-fill.ph-file-css:before{content:""}.ph-fill.ph-file-csv:before{content:""}.ph-fill.ph-file-dashed:before{content:""}.ph-fill.ph-file-dotted:before{content:""}.ph-fill.ph-file-doc:before{content:""}.ph-fill.ph-file-html:before{content:""}.ph-fill.ph-file-image:before{content:""}.ph-fill.ph-file-ini:before{content:""}.ph-fill.ph-file-jpg:before{content:""}.ph-fill.ph-file-js:before{content:""}.ph-fill.ph-file-jsx:before{content:""}.ph-fill.ph-file-lock:before{content:""}.ph-fill.ph-file-magnifying-glass:before{content:""}.ph-fill.ph-file-search:before{content:""}.ph-fill.ph-file-md:before{content:""}.ph-fill.ph-file-minus:before{content:""}.ph-fill.ph-file-pdf:before{content:""}.ph-fill.ph-file-plus:before{content:""}.ph-fill.ph-file-png:before{content:""}.ph-fill.ph-file-ppt:before{content:""}.ph-fill.ph-file-py:before{content:""}.ph-fill.ph-file-rs:before{content:""}.ph-fill.ph-file-sql:before{content:""}.ph-fill.ph-file-svg:before{content:""}.ph-fill.ph-file-text:before{content:""}.ph-fill.ph-file-ts:before{content:""}.ph-fill.ph-file-tsx:before{content:""}.ph-fill.ph-file-txt:before{content:""}.ph-fill.ph-file-video:before{content:""}.ph-fill.ph-file-vue:before{content:""}.ph-fill.ph-file-x:before{content:""}.ph-fill.ph-file-xls:before{content:""}.ph-fill.ph-file-zip:before{content:""}.ph-fill.ph-files:before{content:""}.ph-fill.ph-film-reel:before{content:""}.ph-fill.ph-film-script:before{content:""}.ph-fill.ph-film-slate:before{content:""}.ph-fill.ph-film-strip:before{content:""}.ph-fill.ph-fingerprint:before{content:""}.ph-fill.ph-fingerprint-simple:before{content:""}.ph-fill.ph-finn-the-human:before{content:""}.ph-fill.ph-fire:before{content:""}.ph-fill.ph-fire-extinguisher:before{content:""}.ph-fill.ph-fire-simple:before{content:""}.ph-fill.ph-fire-truck:before{content:""}.ph-fill.ph-first-aid:before{content:""}.ph-fill.ph-first-aid-kit:before{content:""}.ph-fill.ph-fish:before{content:""}.ph-fill.ph-fish-simple:before{content:""}.ph-fill.ph-flag:before{content:""}.ph-fill.ph-flag-banner:before{content:""}.ph-fill.ph-flag-banner-fold:before{content:""}.ph-fill.ph-flag-checkered:before{content:""}.ph-fill.ph-flag-pennant:before{content:""}.ph-fill.ph-flame:before{content:""}.ph-fill.ph-flashlight:before{content:""}.ph-fill.ph-flask:before{content:""}.ph-fill.ph-flip-horizontal:before{content:""}.ph-fill.ph-flip-vertical:before{content:""}.ph-fill.ph-floppy-disk:before{content:""}.ph-fill.ph-floppy-disk-back:before{content:""}.ph-fill.ph-flow-arrow:before{content:""}.ph-fill.ph-flower:before{content:""}.ph-fill.ph-flower-lotus:before{content:""}.ph-fill.ph-flower-tulip:before{content:""}.ph-fill.ph-flying-saucer:before{content:""}.ph-fill.ph-folder:before{content:""}.ph-fill.ph-folder-notch:before{content:""}.ph-fill.ph-folder-dashed:before{content:""}.ph-fill.ph-folder-dotted:before{content:""}.ph-fill.ph-folder-lock:before{content:""}.ph-fill.ph-folder-minus:before{content:""}.ph-fill.ph-folder-notch-minus:before{content:""}.ph-fill.ph-folder-open:before{content:""}.ph-fill.ph-folder-notch-open:before{content:""}.ph-fill.ph-folder-plus:before{content:""}.ph-fill.ph-folder-notch-plus:before{content:""}.ph-fill.ph-folder-simple:before{content:""}.ph-fill.ph-folder-simple-dashed:before{content:""}.ph-fill.ph-folder-simple-dotted:before{content:""}.ph-fill.ph-folder-simple-lock:before{content:""}.ph-fill.ph-folder-simple-minus:before{content:""}.ph-fill.ph-folder-simple-plus:before{content:""}.ph-fill.ph-folder-simple-star:before{content:""}.ph-fill.ph-folder-simple-user:before{content:""}.ph-fill.ph-folder-star:before{content:""}.ph-fill.ph-folder-user:before{content:""}.ph-fill.ph-folders:before{content:""}.ph-fill.ph-football:before{content:""}.ph-fill.ph-football-helmet:before{content:""}.ph-fill.ph-footprints:before{content:""}.ph-fill.ph-fork-knife:before{content:""}.ph-fill.ph-four-k:before{content:""}.ph-fill.ph-frame-corners:before{content:""}.ph-fill.ph-framer-logo:before{content:""}.ph-fill.ph-function:before{content:""}.ph-fill.ph-funnel:before{content:""}.ph-fill.ph-funnel-simple:before{content:""}.ph-fill.ph-funnel-simple-x:before{content:""}.ph-fill.ph-funnel-x:before{content:""}.ph-fill.ph-game-controller:before{content:""}.ph-fill.ph-garage:before{content:""}.ph-fill.ph-gas-can:before{content:""}.ph-fill.ph-gas-pump:before{content:""}.ph-fill.ph-gauge:before{content:""}.ph-fill.ph-gavel:before{content:""}.ph-fill.ph-gear:before{content:""}.ph-fill.ph-gear-fine:before{content:""}.ph-fill.ph-gear-six:before{content:""}.ph-fill.ph-gender-female:before{content:""}.ph-fill.ph-gender-intersex:before{content:""}.ph-fill.ph-gender-male:before{content:""}.ph-fill.ph-gender-neuter:before{content:""}.ph-fill.ph-gender-nonbinary:before{content:""}.ph-fill.ph-gender-transgender:before{content:""}.ph-fill.ph-ghost:before{content:""}.ph-fill.ph-gif:before{content:""}.ph-fill.ph-gift:before{content:""}.ph-fill.ph-git-branch:before{content:""}.ph-fill.ph-git-commit:before{content:""}.ph-fill.ph-git-diff:before{content:""}.ph-fill.ph-git-fork:before{content:""}.ph-fill.ph-git-merge:before{content:""}.ph-fill.ph-git-pull-request:before{content:""}.ph-fill.ph-github-logo:before{content:""}.ph-fill.ph-gitlab-logo:before{content:""}.ph-fill.ph-gitlab-logo-simple:before{content:""}.ph-fill.ph-globe:before{content:""}.ph-fill.ph-globe-hemisphere-east:before{content:""}.ph-fill.ph-globe-hemisphere-west:before{content:""}.ph-fill.ph-globe-simple:before{content:""}.ph-fill.ph-globe-simple-x:before{content:""}.ph-fill.ph-globe-stand:before{content:""}.ph-fill.ph-globe-x:before{content:""}.ph-fill.ph-goggles:before{content:""}.ph-fill.ph-golf:before{content:""}.ph-fill.ph-goodreads-logo:before{content:""}.ph-fill.ph-google-cardboard-logo:before{content:""}.ph-fill.ph-google-chrome-logo:before{content:""}.ph-fill.ph-google-drive-logo:before{content:""}.ph-fill.ph-google-logo:before{content:""}.ph-fill.ph-google-photos-logo:before{content:""}.ph-fill.ph-google-play-logo:before{content:""}.ph-fill.ph-google-podcasts-logo:before{content:""}.ph-fill.ph-gps:before{content:""}.ph-fill.ph-gps-fix:before{content:""}.ph-fill.ph-gps-slash:before{content:""}.ph-fill.ph-gradient:before{content:""}.ph-fill.ph-graduation-cap:before{content:""}.ph-fill.ph-grains:before{content:""}.ph-fill.ph-grains-slash:before{content:""}.ph-fill.ph-graph:before{content:""}.ph-fill.ph-graphics-card:before{content:""}.ph-fill.ph-greater-than:before{content:""}.ph-fill.ph-greater-than-or-equal:before{content:""}.ph-fill.ph-grid-four:before{content:""}.ph-fill.ph-grid-nine:before{content:""}.ph-fill.ph-guitar:before{content:""}.ph-fill.ph-hair-dryer:before{content:""}.ph-fill.ph-hamburger:before{content:""}.ph-fill.ph-hammer:before{content:""}.ph-fill.ph-hand:before{content:""}.ph-fill.ph-hand-arrow-down:before{content:""}.ph-fill.ph-hand-arrow-up:before{content:""}.ph-fill.ph-hand-coins:before{content:""}.ph-fill.ph-hand-deposit:before{content:""}.ph-fill.ph-hand-eye:before{content:""}.ph-fill.ph-hand-fist:before{content:""}.ph-fill.ph-hand-grabbing:before{content:""}.ph-fill.ph-hand-heart:before{content:""}.ph-fill.ph-hand-palm:before{content:""}.ph-fill.ph-hand-peace:before{content:""}.ph-fill.ph-hand-pointing:before{content:""}.ph-fill.ph-hand-soap:before{content:""}.ph-fill.ph-hand-swipe-left:before{content:""}.ph-fill.ph-hand-swipe-right:before{content:""}.ph-fill.ph-hand-tap:before{content:""}.ph-fill.ph-hand-waving:before{content:""}.ph-fill.ph-hand-withdraw:before{content:""}.ph-fill.ph-handbag:before{content:""}.ph-fill.ph-handbag-simple:before{content:""}.ph-fill.ph-hands-clapping:before{content:""}.ph-fill.ph-hands-praying:before{content:""}.ph-fill.ph-handshake:before{content:""}.ph-fill.ph-hard-drive:before{content:""}.ph-fill.ph-hard-drives:before{content:""}.ph-fill.ph-hard-hat:before{content:""}.ph-fill.ph-hash:before{content:""}.ph-fill.ph-hash-straight:before{content:""}.ph-fill.ph-head-circuit:before{content:""}.ph-fill.ph-headlights:before{content:""}.ph-fill.ph-headphones:before{content:""}.ph-fill.ph-headset:before{content:""}.ph-fill.ph-heart:before{content:""}.ph-fill.ph-heart-break:before{content:""}.ph-fill.ph-heart-half:before{content:""}.ph-fill.ph-heart-straight:before{content:""}.ph-fill.ph-heart-straight-break:before{content:""}.ph-fill.ph-heartbeat:before{content:""}.ph-fill.ph-hexagon:before{content:""}.ph-fill.ph-high-definition:before{content:""}.ph-fill.ph-high-heel:before{content:""}.ph-fill.ph-highlighter:before{content:""}.ph-fill.ph-highlighter-circle:before{content:""}.ph-fill.ph-hockey:before{content:""}.ph-fill.ph-hoodie:before{content:""}.ph-fill.ph-horse:before{content:""}.ph-fill.ph-hospital:before{content:""}.ph-fill.ph-hourglass:before{content:""}.ph-fill.ph-hourglass-high:before{content:""}.ph-fill.ph-hourglass-low:before{content:""}.ph-fill.ph-hourglass-medium:before{content:""}.ph-fill.ph-hourglass-simple:before{content:""}.ph-fill.ph-hourglass-simple-high:before{content:""}.ph-fill.ph-hourglass-simple-low:before{content:""}.ph-fill.ph-hourglass-simple-medium:before{content:""}.ph-fill.ph-house:before{content:""}.ph-fill.ph-house-line:before{content:""}.ph-fill.ph-house-simple:before{content:""}.ph-fill.ph-hurricane:before{content:""}.ph-fill.ph-ice-cream:before{content:""}.ph-fill.ph-identification-badge:before{content:""}.ph-fill.ph-identification-card:before{content:""}.ph-fill.ph-image:before{content:""}.ph-fill.ph-image-broken:before{content:""}.ph-fill.ph-image-square:before{content:""}.ph-fill.ph-images:before{content:""}.ph-fill.ph-images-square:before{content:""}.ph-fill.ph-infinity:before{content:""}.ph-fill.ph-lemniscate:before{content:""}.ph-fill.ph-info:before{content:""}.ph-fill.ph-instagram-logo:before{content:""}.ph-fill.ph-intersect:before{content:""}.ph-fill.ph-intersect-square:before{content:""}.ph-fill.ph-intersect-three:before{content:""}.ph-fill.ph-intersection:before{content:""}.ph-fill.ph-invoice:before{content:""}.ph-fill.ph-island:before{content:""}.ph-fill.ph-jar:before{content:""}.ph-fill.ph-jar-label:before{content:""}.ph-fill.ph-jeep:before{content:""}.ph-fill.ph-joystick:before{content:""}.ph-fill.ph-kanban:before{content:""}.ph-fill.ph-key:before{content:""}.ph-fill.ph-key-return:before{content:""}.ph-fill.ph-keyboard:before{content:""}.ph-fill.ph-keyhole:before{content:""}.ph-fill.ph-knife:before{content:""}.ph-fill.ph-ladder:before{content:""}.ph-fill.ph-ladder-simple:before{content:""}.ph-fill.ph-lamp:before{content:""}.ph-fill.ph-lamp-pendant:before{content:""}.ph-fill.ph-laptop:before{content:""}.ph-fill.ph-lasso:before{content:""}.ph-fill.ph-lastfm-logo:before{content:""}.ph-fill.ph-layout:before{content:""}.ph-fill.ph-leaf:before{content:""}.ph-fill.ph-lectern:before{content:""}.ph-fill.ph-lego:before{content:""}.ph-fill.ph-lego-smiley:before{content:""}.ph-fill.ph-less-than:before{content:""}.ph-fill.ph-less-than-or-equal:before{content:""}.ph-fill.ph-letter-circle-h:before{content:""}.ph-fill.ph-letter-circle-p:before{content:""}.ph-fill.ph-letter-circle-v:before{content:""}.ph-fill.ph-lifebuoy:before{content:""}.ph-fill.ph-lightbulb:before{content:""}.ph-fill.ph-lightbulb-filament:before{content:""}.ph-fill.ph-lighthouse:before{content:""}.ph-fill.ph-lightning:before{content:""}.ph-fill.ph-lightning-a:before{content:""}.ph-fill.ph-lightning-slash:before{content:""}.ph-fill.ph-line-segment:before{content:""}.ph-fill.ph-line-segments:before{content:""}.ph-fill.ph-line-vertical:before{content:""}.ph-fill.ph-link:before{content:""}.ph-fill.ph-link-break:before{content:""}.ph-fill.ph-link-simple:before{content:""}.ph-fill.ph-link-simple-break:before{content:""}.ph-fill.ph-link-simple-horizontal:before{content:""}.ph-fill.ph-link-simple-horizontal-break:before{content:""}.ph-fill.ph-linkedin-logo:before{content:""}.ph-fill.ph-linktree-logo:before{content:""}.ph-fill.ph-linux-logo:before{content:""}.ph-fill.ph-list:before{content:""}.ph-fill.ph-list-bullets:before{content:""}.ph-fill.ph-list-checks:before{content:""}.ph-fill.ph-list-dashes:before{content:""}.ph-fill.ph-list-heart:before{content:""}.ph-fill.ph-list-magnifying-glass:before{content:""}.ph-fill.ph-list-numbers:before{content:""}.ph-fill.ph-list-plus:before{content:""}.ph-fill.ph-list-star:before{content:""}.ph-fill.ph-lock:before{content:""}.ph-fill.ph-lock-key:before{content:""}.ph-fill.ph-lock-key-open:before{content:""}.ph-fill.ph-lock-laminated:before{content:""}.ph-fill.ph-lock-laminated-open:before{content:""}.ph-fill.ph-lock-open:before{content:""}.ph-fill.ph-lock-simple:before{content:""}.ph-fill.ph-lock-simple-open:before{content:""}.ph-fill.ph-lockers:before{content:""}.ph-fill.ph-log:before{content:""}.ph-fill.ph-magic-wand:before{content:""}.ph-fill.ph-magnet:before{content:""}.ph-fill.ph-magnet-straight:before{content:""}.ph-fill.ph-magnifying-glass:before{content:""}.ph-fill.ph-magnifying-glass-minus:before{content:""}.ph-fill.ph-magnifying-glass-plus:before{content:""}.ph-fill.ph-mailbox:before{content:""}.ph-fill.ph-map-pin:before{content:""}.ph-fill.ph-map-pin-area:before{content:""}.ph-fill.ph-map-pin-line:before{content:""}.ph-fill.ph-map-pin-plus:before{content:""}.ph-fill.ph-map-pin-simple:before{content:""}.ph-fill.ph-map-pin-simple-area:before{content:""}.ph-fill.ph-map-pin-simple-line:before{content:""}.ph-fill.ph-map-trifold:before{content:""}.ph-fill.ph-markdown-logo:before{content:""}.ph-fill.ph-marker-circle:before{content:""}.ph-fill.ph-martini:before{content:""}.ph-fill.ph-mask-happy:before{content:""}.ph-fill.ph-mask-sad:before{content:""}.ph-fill.ph-mastodon-logo:before{content:""}.ph-fill.ph-math-operations:before{content:""}.ph-fill.ph-matrix-logo:before{content:""}.ph-fill.ph-medal:before{content:""}.ph-fill.ph-medal-military:before{content:""}.ph-fill.ph-medium-logo:before{content:""}.ph-fill.ph-megaphone:before{content:""}.ph-fill.ph-megaphone-simple:before{content:""}.ph-fill.ph-member-of:before{content:""}.ph-fill.ph-memory:before{content:""}.ph-fill.ph-messenger-logo:before{content:""}.ph-fill.ph-meta-logo:before{content:""}.ph-fill.ph-meteor:before{content:""}.ph-fill.ph-metronome:before{content:""}.ph-fill.ph-microphone:before{content:""}.ph-fill.ph-microphone-slash:before{content:""}.ph-fill.ph-microphone-stage:before{content:""}.ph-fill.ph-microscope:before{content:""}.ph-fill.ph-microsoft-excel-logo:before{content:""}.ph-fill.ph-microsoft-outlook-logo:before{content:""}.ph-fill.ph-microsoft-powerpoint-logo:before{content:""}.ph-fill.ph-microsoft-teams-logo:before{content:""}.ph-fill.ph-microsoft-word-logo:before{content:""}.ph-fill.ph-minus:before{content:""}.ph-fill.ph-minus-circle:before{content:""}.ph-fill.ph-minus-square:before{content:""}.ph-fill.ph-money:before{content:""}.ph-fill.ph-money-wavy:before{content:""}.ph-fill.ph-monitor:before{content:""}.ph-fill.ph-monitor-arrow-up:before{content:""}.ph-fill.ph-monitor-play:before{content:""}.ph-fill.ph-moon:before{content:""}.ph-fill.ph-moon-stars:before{content:""}.ph-fill.ph-moped:before{content:""}.ph-fill.ph-moped-front:before{content:""}.ph-fill.ph-mosque:before{content:""}.ph-fill.ph-motorcycle:before{content:""}.ph-fill.ph-mountains:before{content:""}.ph-fill.ph-mouse:before{content:""}.ph-fill.ph-mouse-left-click:before{content:""}.ph-fill.ph-mouse-middle-click:before{content:""}.ph-fill.ph-mouse-right-click:before{content:""}.ph-fill.ph-mouse-scroll:before{content:""}.ph-fill.ph-mouse-simple:before{content:""}.ph-fill.ph-music-note:before{content:""}.ph-fill.ph-music-note-simple:before{content:""}.ph-fill.ph-music-notes:before{content:""}.ph-fill.ph-music-notes-minus:before{content:""}.ph-fill.ph-music-notes-plus:before{content:""}.ph-fill.ph-music-notes-simple:before{content:""}.ph-fill.ph-navigation-arrow:before{content:""}.ph-fill.ph-needle:before{content:""}.ph-fill.ph-network:before{content:""}.ph-fill.ph-network-slash:before{content:""}.ph-fill.ph-network-x:before{content:""}.ph-fill.ph-newspaper:before{content:""}.ph-fill.ph-newspaper-clipping:before{content:""}.ph-fill.ph-not-equals:before{content:""}.ph-fill.ph-not-member-of:before{content:""}.ph-fill.ph-not-subset-of:before{content:""}.ph-fill.ph-not-superset-of:before{content:""}.ph-fill.ph-notches:before{content:""}.ph-fill.ph-note:before{content:""}.ph-fill.ph-note-blank:before{content:""}.ph-fill.ph-note-pencil:before{content:""}.ph-fill.ph-notebook:before{content:""}.ph-fill.ph-notepad:before{content:""}.ph-fill.ph-notification:before{content:""}.ph-fill.ph-notion-logo:before{content:""}.ph-fill.ph-nuclear-plant:before{content:""}.ph-fill.ph-number-circle-eight:before{content:""}.ph-fill.ph-number-circle-five:before{content:""}.ph-fill.ph-number-circle-four:before{content:""}.ph-fill.ph-number-circle-nine:before{content:""}.ph-fill.ph-number-circle-one:before{content:""}.ph-fill.ph-number-circle-seven:before{content:""}.ph-fill.ph-number-circle-six:before{content:""}.ph-fill.ph-number-circle-three:before{content:""}.ph-fill.ph-number-circle-two:before{content:""}.ph-fill.ph-number-circle-zero:before{content:""}.ph-fill.ph-number-eight:before{content:""}.ph-fill.ph-number-five:before{content:""}.ph-fill.ph-number-four:before{content:""}.ph-fill.ph-number-nine:before{content:""}.ph-fill.ph-number-one:before{content:""}.ph-fill.ph-number-seven:before{content:""}.ph-fill.ph-number-six:before{content:""}.ph-fill.ph-number-square-eight:before{content:""}.ph-fill.ph-number-square-five:before{content:""}.ph-fill.ph-number-square-four:before{content:""}.ph-fill.ph-number-square-nine:before{content:""}.ph-fill.ph-number-square-one:before{content:""}.ph-fill.ph-number-square-seven:before{content:""}.ph-fill.ph-number-square-six:before{content:""}.ph-fill.ph-number-square-three:before{content:""}.ph-fill.ph-number-square-two:before{content:""}.ph-fill.ph-number-square-zero:before{content:""}.ph-fill.ph-number-three:before{content:""}.ph-fill.ph-number-two:before{content:""}.ph-fill.ph-number-zero:before{content:""}.ph-fill.ph-numpad:before{content:""}.ph-fill.ph-nut:before{content:""}.ph-fill.ph-ny-times-logo:before{content:""}.ph-fill.ph-octagon:before{content:""}.ph-fill.ph-office-chair:before{content:""}.ph-fill.ph-onigiri:before{content:""}.ph-fill.ph-open-ai-logo:before{content:""}.ph-fill.ph-option:before{content:""}.ph-fill.ph-orange:before{content:""}.ph-fill.ph-orange-slice:before{content:""}.ph-fill.ph-oven:before{content:""}.ph-fill.ph-package:before{content:""}.ph-fill.ph-paint-brush:before{content:""}.ph-fill.ph-paint-brush-broad:before{content:""}.ph-fill.ph-paint-brush-household:before{content:""}.ph-fill.ph-paint-bucket:before{content:""}.ph-fill.ph-paint-roller:before{content:""}.ph-fill.ph-palette:before{content:""}.ph-fill.ph-panorama:before{content:""}.ph-fill.ph-pants:before{content:""}.ph-fill.ph-paper-plane:before{content:""}.ph-fill.ph-paper-plane-right:before{content:""}.ph-fill.ph-paper-plane-tilt:before{content:""}.ph-fill.ph-paperclip:before{content:""}.ph-fill.ph-paperclip-horizontal:before{content:""}.ph-fill.ph-parachute:before{content:""}.ph-fill.ph-paragraph:before{content:""}.ph-fill.ph-parallelogram:before{content:""}.ph-fill.ph-park:before{content:""}.ph-fill.ph-password:before{content:""}.ph-fill.ph-path:before{content:""}.ph-fill.ph-patreon-logo:before{content:""}.ph-fill.ph-pause:before{content:""}.ph-fill.ph-pause-circle:before{content:""}.ph-fill.ph-paw-print:before{content:""}.ph-fill.ph-paypal-logo:before{content:""}.ph-fill.ph-peace:before{content:""}.ph-fill.ph-pen:before{content:""}.ph-fill.ph-pen-nib:before{content:""}.ph-fill.ph-pen-nib-straight:before{content:""}.ph-fill.ph-pencil:before{content:""}.ph-fill.ph-pencil-circle:before{content:""}.ph-fill.ph-pencil-line:before{content:""}.ph-fill.ph-pencil-ruler:before{content:""}.ph-fill.ph-pencil-simple:before{content:""}.ph-fill.ph-pencil-simple-line:before{content:""}.ph-fill.ph-pencil-simple-slash:before{content:""}.ph-fill.ph-pencil-slash:before{content:""}.ph-fill.ph-pentagon:before{content:""}.ph-fill.ph-pentagram:before{content:""}.ph-fill.ph-pepper:before{content:""}.ph-fill.ph-percent:before{content:""}.ph-fill.ph-person:before{content:""}.ph-fill.ph-person-arms-spread:before{content:""}.ph-fill.ph-person-simple:before{content:""}.ph-fill.ph-person-simple-bike:before{content:""}.ph-fill.ph-person-simple-circle:before{content:""}.ph-fill.ph-person-simple-hike:before{content:""}.ph-fill.ph-person-simple-run:before{content:""}.ph-fill.ph-person-simple-ski:before{content:""}.ph-fill.ph-person-simple-snowboard:before{content:""}.ph-fill.ph-person-simple-swim:before{content:""}.ph-fill.ph-person-simple-tai-chi:before{content:""}.ph-fill.ph-person-simple-throw:before{content:""}.ph-fill.ph-person-simple-walk:before{content:""}.ph-fill.ph-perspective:before{content:""}.ph-fill.ph-phone:before{content:""}.ph-fill.ph-phone-call:before{content:""}.ph-fill.ph-phone-disconnect:before{content:""}.ph-fill.ph-phone-incoming:before{content:""}.ph-fill.ph-phone-list:before{content:""}.ph-fill.ph-phone-outgoing:before{content:""}.ph-fill.ph-phone-pause:before{content:""}.ph-fill.ph-phone-plus:before{content:""}.ph-fill.ph-phone-slash:before{content:""}.ph-fill.ph-phone-transfer:before{content:""}.ph-fill.ph-phone-x:before{content:""}.ph-fill.ph-phosphor-logo:before{content:""}.ph-fill.ph-pi:before{content:""}.ph-fill.ph-piano-keys:before{content:""}.ph-fill.ph-picnic-table:before{content:""}.ph-fill.ph-picture-in-picture:before{content:""}.ph-fill.ph-piggy-bank:before{content:""}.ph-fill.ph-pill:before{content:""}.ph-fill.ph-ping-pong:before{content:""}.ph-fill.ph-pint-glass:before{content:""}.ph-fill.ph-pinterest-logo:before{content:""}.ph-fill.ph-pinwheel:before{content:""}.ph-fill.ph-pipe:before{content:""}.ph-fill.ph-pipe-wrench:before{content:""}.ph-fill.ph-pix-logo:before{content:""}.ph-fill.ph-pizza:before{content:""}.ph-fill.ph-placeholder:before{content:""}.ph-fill.ph-planet:before{content:""}.ph-fill.ph-plant:before{content:""}.ph-fill.ph-play:before{content:""}.ph-fill.ph-play-circle:before{content:""}.ph-fill.ph-play-pause:before{content:""}.ph-fill.ph-playlist:before{content:""}.ph-fill.ph-plug:before{content:""}.ph-fill.ph-plug-charging:before{content:""}.ph-fill.ph-plugs:before{content:""}.ph-fill.ph-plugs-connected:before{content:""}.ph-fill.ph-plus:before{content:""}.ph-fill.ph-plus-circle:before{content:""}.ph-fill.ph-plus-minus:before{content:""}.ph-fill.ph-plus-square:before{content:""}.ph-fill.ph-poker-chip:before{content:""}.ph-fill.ph-police-car:before{content:""}.ph-fill.ph-polygon:before{content:""}.ph-fill.ph-popcorn:before{content:""}.ph-fill.ph-popsicle:before{content:""}.ph-fill.ph-potted-plant:before{content:""}.ph-fill.ph-power:before{content:""}.ph-fill.ph-prescription:before{content:""}.ph-fill.ph-presentation:before{content:""}.ph-fill.ph-presentation-chart:before{content:""}.ph-fill.ph-printer:before{content:""}.ph-fill.ph-prohibit:before{content:""}.ph-fill.ph-prohibit-inset:before{content:""}.ph-fill.ph-projector-screen:before{content:""}.ph-fill.ph-projector-screen-chart:before{content:""}.ph-fill.ph-pulse:before{content:""}.ph-fill.ph-activity:before{content:""}.ph-fill.ph-push-pin:before{content:""}.ph-fill.ph-push-pin-simple:before{content:""}.ph-fill.ph-push-pin-simple-slash:before{content:""}.ph-fill.ph-push-pin-slash:before{content:""}.ph-fill.ph-puzzle-piece:before{content:""}.ph-fill.ph-qr-code:before{content:""}.ph-fill.ph-question:before{content:""}.ph-fill.ph-question-mark:before{content:""}.ph-fill.ph-queue:before{content:""}.ph-fill.ph-quotes:before{content:""}.ph-fill.ph-rabbit:before{content:""}.ph-fill.ph-racquet:before{content:""}.ph-fill.ph-radical:before{content:""}.ph-fill.ph-radio:before{content:""}.ph-fill.ph-radio-button:before{content:""}.ph-fill.ph-radioactive:before{content:""}.ph-fill.ph-rainbow:before{content:""}.ph-fill.ph-rainbow-cloud:before{content:""}.ph-fill.ph-ranking:before{content:""}.ph-fill.ph-read-cv-logo:before{content:""}.ph-fill.ph-receipt:before{content:""}.ph-fill.ph-receipt-x:before{content:""}.ph-fill.ph-record:before{content:""}.ph-fill.ph-rectangle:before{content:""}.ph-fill.ph-rectangle-dashed:before{content:""}.ph-fill.ph-recycle:before{content:""}.ph-fill.ph-reddit-logo:before{content:""}.ph-fill.ph-repeat:before{content:""}.ph-fill.ph-repeat-once:before{content:""}.ph-fill.ph-replit-logo:before{content:""}.ph-fill.ph-resize:before{content:""}.ph-fill.ph-rewind:before{content:""}.ph-fill.ph-rewind-circle:before{content:""}.ph-fill.ph-road-horizon:before{content:""}.ph-fill.ph-robot:before{content:""}.ph-fill.ph-rocket:before{content:""}.ph-fill.ph-rocket-launch:before{content:""}.ph-fill.ph-rows:before{content:""}.ph-fill.ph-rows-plus-bottom:before{content:""}.ph-fill.ph-rows-plus-top:before{content:""}.ph-fill.ph-rss:before{content:""}.ph-fill.ph-rss-simple:before{content:""}.ph-fill.ph-rug:before{content:""}.ph-fill.ph-ruler:before{content:""}.ph-fill.ph-sailboat:before{content:""}.ph-fill.ph-scales:before{content:""}.ph-fill.ph-scan:before{content:""}.ph-fill.ph-scan-smiley:before{content:""}.ph-fill.ph-scissors:before{content:""}.ph-fill.ph-scooter:before{content:""}.ph-fill.ph-screencast:before{content:""}.ph-fill.ph-screwdriver:before{content:""}.ph-fill.ph-scribble:before{content:""}.ph-fill.ph-scribble-loop:before{content:""}.ph-fill.ph-scroll:before{content:""}.ph-fill.ph-seal:before{content:""}.ph-fill.ph-circle-wavy:before{content:""}.ph-fill.ph-seal-check:before{content:""}.ph-fill.ph-circle-wavy-check:before{content:""}.ph-fill.ph-seal-percent:before{content:""}.ph-fill.ph-seal-question:before{content:""}.ph-fill.ph-circle-wavy-question:before{content:""}.ph-fill.ph-seal-warning:before{content:""}.ph-fill.ph-circle-wavy-warning:before{content:""}.ph-fill.ph-seat:before{content:""}.ph-fill.ph-seatbelt:before{content:""}.ph-fill.ph-security-camera:before{content:""}.ph-fill.ph-selection:before{content:""}.ph-fill.ph-selection-all:before{content:""}.ph-fill.ph-selection-background:before{content:""}.ph-fill.ph-selection-foreground:before{content:""}.ph-fill.ph-selection-inverse:before{content:""}.ph-fill.ph-selection-plus:before{content:""}.ph-fill.ph-selection-slash:before{content:""}.ph-fill.ph-shapes:before{content:""}.ph-fill.ph-share:before{content:""}.ph-fill.ph-share-fat:before{content:""}.ph-fill.ph-share-network:before{content:""}.ph-fill.ph-shield:before{content:""}.ph-fill.ph-shield-check:before{content:""}.ph-fill.ph-shield-checkered:before{content:""}.ph-fill.ph-shield-chevron:before{content:""}.ph-fill.ph-shield-plus:before{content:""}.ph-fill.ph-shield-slash:before{content:""}.ph-fill.ph-shield-star:before{content:""}.ph-fill.ph-shield-warning:before{content:""}.ph-fill.ph-shipping-container:before{content:""}.ph-fill.ph-shirt-folded:before{content:""}.ph-fill.ph-shooting-star:before{content:""}.ph-fill.ph-shopping-bag:before{content:""}.ph-fill.ph-shopping-bag-open:before{content:""}.ph-fill.ph-shopping-cart:before{content:""}.ph-fill.ph-shopping-cart-simple:before{content:""}.ph-fill.ph-shovel:before{content:""}.ph-fill.ph-shower:before{content:""}.ph-fill.ph-shrimp:before{content:""}.ph-fill.ph-shuffle:before{content:""}.ph-fill.ph-shuffle-angular:before{content:""}.ph-fill.ph-shuffle-simple:before{content:""}.ph-fill.ph-sidebar:before{content:""}.ph-fill.ph-sidebar-simple:before{content:""}.ph-fill.ph-sigma:before{content:""}.ph-fill.ph-sign-in:before{content:""}.ph-fill.ph-sign-out:before{content:""}.ph-fill.ph-signature:before{content:""}.ph-fill.ph-signpost:before{content:""}.ph-fill.ph-sim-card:before{content:""}.ph-fill.ph-siren:before{content:""}.ph-fill.ph-sketch-logo:before{content:""}.ph-fill.ph-skip-back:before{content:""}.ph-fill.ph-skip-back-circle:before{content:""}.ph-fill.ph-skip-forward:before{content:""}.ph-fill.ph-skip-forward-circle:before{content:""}.ph-fill.ph-skull:before{content:""}.ph-fill.ph-skype-logo:before{content:""}.ph-fill.ph-slack-logo:before{content:""}.ph-fill.ph-sliders:before{content:""}.ph-fill.ph-sliders-horizontal:before{content:""}.ph-fill.ph-slideshow:before{content:""}.ph-fill.ph-smiley:before{content:""}.ph-fill.ph-smiley-angry:before{content:""}.ph-fill.ph-smiley-blank:before{content:""}.ph-fill.ph-smiley-meh:before{content:""}.ph-fill.ph-smiley-melting:before{content:""}.ph-fill.ph-smiley-nervous:before{content:""}.ph-fill.ph-smiley-sad:before{content:""}.ph-fill.ph-smiley-sticker:before{content:""}.ph-fill.ph-smiley-wink:before{content:""}.ph-fill.ph-smiley-x-eyes:before{content:""}.ph-fill.ph-snapchat-logo:before{content:""}.ph-fill.ph-sneaker:before{content:""}.ph-fill.ph-sneaker-move:before{content:""}.ph-fill.ph-snowflake:before{content:""}.ph-fill.ph-soccer-ball:before{content:""}.ph-fill.ph-sock:before{content:""}.ph-fill.ph-solar-panel:before{content:""}.ph-fill.ph-solar-roof:before{content:""}.ph-fill.ph-sort-ascending:before{content:""}.ph-fill.ph-sort-descending:before{content:""}.ph-fill.ph-soundcloud-logo:before{content:""}.ph-fill.ph-spade:before{content:""}.ph-fill.ph-sparkle:before{content:""}.ph-fill.ph-speaker-hifi:before{content:""}.ph-fill.ph-speaker-high:before{content:""}.ph-fill.ph-speaker-low:before{content:""}.ph-fill.ph-speaker-none:before{content:""}.ph-fill.ph-speaker-simple-high:before{content:""}.ph-fill.ph-speaker-simple-low:before{content:""}.ph-fill.ph-speaker-simple-none:before{content:""}.ph-fill.ph-speaker-simple-slash:before{content:""}.ph-fill.ph-speaker-simple-x:before{content:""}.ph-fill.ph-speaker-slash:before{content:""}.ph-fill.ph-speaker-x:before{content:""}.ph-fill.ph-speedometer:before{content:""}.ph-fill.ph-sphere:before{content:""}.ph-fill.ph-spinner:before{content:""}.ph-fill.ph-spinner-ball:before{content:""}.ph-fill.ph-spinner-gap:before{content:""}.ph-fill.ph-spiral:before{content:""}.ph-fill.ph-split-horizontal:before{content:""}.ph-fill.ph-split-vertical:before{content:""}.ph-fill.ph-spotify-logo:before{content:""}.ph-fill.ph-spray-bottle:before{content:""}.ph-fill.ph-square:before{content:""}.ph-fill.ph-square-half:before{content:""}.ph-fill.ph-square-half-bottom:before{content:""}.ph-fill.ph-square-logo:before{content:""}.ph-fill.ph-square-split-horizontal:before{content:""}.ph-fill.ph-square-split-vertical:before{content:""}.ph-fill.ph-squares-four:before{content:""}.ph-fill.ph-stack:before{content:""}.ph-fill.ph-stack-minus:before{content:""}.ph-fill.ph-stack-overflow-logo:before{content:""}.ph-fill.ph-stack-plus:before{content:""}.ph-fill.ph-stack-simple:before{content:""}.ph-fill.ph-stairs:before{content:""}.ph-fill.ph-stamp:before{content:""}.ph-fill.ph-standard-definition:before{content:""}.ph-fill.ph-star:before{content:""}.ph-fill.ph-star-and-crescent:before{content:""}.ph-fill.ph-star-four:before{content:""}.ph-fill.ph-star-half:before{content:""}.ph-fill.ph-star-of-david:before{content:""}.ph-fill.ph-steam-logo:before{content:""}.ph-fill.ph-steering-wheel:before{content:""}.ph-fill.ph-steps:before{content:""}.ph-fill.ph-stethoscope:before{content:""}.ph-fill.ph-sticker:before{content:""}.ph-fill.ph-stool:before{content:""}.ph-fill.ph-stop:before{content:""}.ph-fill.ph-stop-circle:before{content:""}.ph-fill.ph-storefront:before{content:""}.ph-fill.ph-strategy:before{content:""}.ph-fill.ph-stripe-logo:before{content:""}.ph-fill.ph-student:before{content:""}.ph-fill.ph-subset-of:before{content:""}.ph-fill.ph-subset-proper-of:before{content:""}.ph-fill.ph-subtitles:before{content:""}.ph-fill.ph-subtitles-slash:before{content:""}.ph-fill.ph-subtract:before{content:""}.ph-fill.ph-subtract-square:before{content:""}.ph-fill.ph-subway:before{content:""}.ph-fill.ph-suitcase:before{content:""}.ph-fill.ph-suitcase-rolling:before{content:""}.ph-fill.ph-suitcase-simple:before{content:""}.ph-fill.ph-sun:before{content:""}.ph-fill.ph-sun-dim:before{content:""}.ph-fill.ph-sun-horizon:before{content:""}.ph-fill.ph-sunglasses:before{content:""}.ph-fill.ph-superset-of:before{content:""}.ph-fill.ph-superset-proper-of:before{content:""}.ph-fill.ph-swap:before{content:""}.ph-fill.ph-swatches:before{content:""}.ph-fill.ph-swimming-pool:before{content:""}.ph-fill.ph-sword:before{content:""}.ph-fill.ph-synagogue:before{content:""}.ph-fill.ph-syringe:before{content:""}.ph-fill.ph-t-shirt:before{content:""}.ph-fill.ph-table:before{content:""}.ph-fill.ph-tabs:before{content:""}.ph-fill.ph-tag:before{content:""}.ph-fill.ph-tag-chevron:before{content:""}.ph-fill.ph-tag-simple:before{content:""}.ph-fill.ph-target:before{content:""}.ph-fill.ph-taxi:before{content:""}.ph-fill.ph-tea-bag:before{content:""}.ph-fill.ph-telegram-logo:before{content:""}.ph-fill.ph-television:before{content:""}.ph-fill.ph-television-simple:before{content:""}.ph-fill.ph-tennis-ball:before{content:""}.ph-fill.ph-tent:before{content:""}.ph-fill.ph-terminal:before{content:""}.ph-fill.ph-terminal-window:before{content:""}.ph-fill.ph-test-tube:before{content:""}.ph-fill.ph-text-a-underline:before{content:""}.ph-fill.ph-text-aa:before{content:""}.ph-fill.ph-text-align-center:before{content:""}.ph-fill.ph-text-align-justify:before{content:""}.ph-fill.ph-text-align-left:before{content:""}.ph-fill.ph-text-align-right:before{content:""}.ph-fill.ph-text-b:before{content:""}.ph-fill.ph-text-bolder:before{content:""}.ph-fill.ph-text-columns:before{content:""}.ph-fill.ph-text-h:before{content:""}.ph-fill.ph-text-h-five:before{content:""}.ph-fill.ph-text-h-four:before{content:""}.ph-fill.ph-text-h-one:before{content:""}.ph-fill.ph-text-h-six:before{content:""}.ph-fill.ph-text-h-three:before{content:""}.ph-fill.ph-text-h-two:before{content:""}.ph-fill.ph-text-indent:before{content:""}.ph-fill.ph-text-italic:before{content:""}.ph-fill.ph-text-outdent:before{content:""}.ph-fill.ph-text-strikethrough:before{content:""}.ph-fill.ph-text-subscript:before{content:""}.ph-fill.ph-text-superscript:before{content:""}.ph-fill.ph-text-t:before{content:""}.ph-fill.ph-text-t-slash:before{content:""}.ph-fill.ph-text-underline:before{content:""}.ph-fill.ph-textbox:before{content:""}.ph-fill.ph-thermometer:before{content:""}.ph-fill.ph-thermometer-cold:before{content:""}.ph-fill.ph-thermometer-hot:before{content:""}.ph-fill.ph-thermometer-simple:before{content:""}.ph-fill.ph-threads-logo:before{content:""}.ph-fill.ph-three-d:before{content:""}.ph-fill.ph-thumbs-down:before{content:""}.ph-fill.ph-thumbs-up:before{content:""}.ph-fill.ph-ticket:before{content:""}.ph-fill.ph-tidal-logo:before{content:""}.ph-fill.ph-tiktok-logo:before{content:""}.ph-fill.ph-tilde:before{content:""}.ph-fill.ph-timer:before{content:""}.ph-fill.ph-tip-jar:before{content:""}.ph-fill.ph-tipi:before{content:""}.ph-fill.ph-tire:before{content:""}.ph-fill.ph-toggle-left:before{content:""}.ph-fill.ph-toggle-right:before{content:""}.ph-fill.ph-toilet:before{content:""}.ph-fill.ph-toilet-paper:before{content:""}.ph-fill.ph-toolbox:before{content:""}.ph-fill.ph-tooth:before{content:""}.ph-fill.ph-tornado:before{content:""}.ph-fill.ph-tote:before{content:""}.ph-fill.ph-tote-simple:before{content:""}.ph-fill.ph-towel:before{content:""}.ph-fill.ph-tractor:before{content:""}.ph-fill.ph-trademark:before{content:""}.ph-fill.ph-trademark-registered:before{content:""}.ph-fill.ph-traffic-cone:before{content:""}.ph-fill.ph-traffic-sign:before{content:""}.ph-fill.ph-traffic-signal:before{content:""}.ph-fill.ph-train:before{content:""}.ph-fill.ph-train-regional:before{content:""}.ph-fill.ph-train-simple:before{content:""}.ph-fill.ph-tram:before{content:""}.ph-fill.ph-translate:before{content:""}.ph-fill.ph-trash:before{content:""}.ph-fill.ph-trash-simple:before{content:""}.ph-fill.ph-tray:before{content:""}.ph-fill.ph-tray-arrow-down:before{content:""}.ph-fill.ph-archive-tray:before{content:""}.ph-fill.ph-tray-arrow-up:before{content:""}.ph-fill.ph-treasure-chest:before{content:""}.ph-fill.ph-tree:before{content:""}.ph-fill.ph-tree-evergreen:before{content:""}.ph-fill.ph-tree-palm:before{content:""}.ph-fill.ph-tree-structure:before{content:""}.ph-fill.ph-tree-view:before{content:""}.ph-fill.ph-trend-down:before{content:""}.ph-fill.ph-trend-up:before{content:""}.ph-fill.ph-triangle:before{content:""}.ph-fill.ph-triangle-dashed:before{content:""}.ph-fill.ph-trolley:before{content:""}.ph-fill.ph-trolley-suitcase:before{content:""}.ph-fill.ph-trophy:before{content:""}.ph-fill.ph-truck:before{content:""}.ph-fill.ph-truck-trailer:before{content:""}.ph-fill.ph-tumblr-logo:before{content:""}.ph-fill.ph-twitch-logo:before{content:""}.ph-fill.ph-twitter-logo:before{content:""}.ph-fill.ph-umbrella:before{content:""}.ph-fill.ph-umbrella-simple:before{content:""}.ph-fill.ph-union:before{content:""}.ph-fill.ph-unite:before{content:""}.ph-fill.ph-unite-square:before{content:""}.ph-fill.ph-upload:before{content:""}.ph-fill.ph-upload-simple:before{content:""}.ph-fill.ph-usb:before{content:""}.ph-fill.ph-user:before{content:""}.ph-fill.ph-user-check:before{content:""}.ph-fill.ph-user-circle:before{content:""}.ph-fill.ph-user-circle-check:before{content:""}.ph-fill.ph-user-circle-dashed:before{content:""}.ph-fill.ph-user-circle-gear:before{content:""}.ph-fill.ph-user-circle-minus:before{content:""}.ph-fill.ph-user-circle-plus:before{content:""}.ph-fill.ph-user-focus:before{content:""}.ph-fill.ph-user-gear:before{content:""}.ph-fill.ph-user-list:before{content:""}.ph-fill.ph-user-minus:before{content:""}.ph-fill.ph-user-plus:before{content:""}.ph-fill.ph-user-rectangle:before{content:""}.ph-fill.ph-user-sound:before{content:""}.ph-fill.ph-user-square:before{content:""}.ph-fill.ph-user-switch:before{content:""}.ph-fill.ph-users:before{content:""}.ph-fill.ph-users-four:before{content:""}.ph-fill.ph-users-three:before{content:""}.ph-fill.ph-van:before{content:""}.ph-fill.ph-vault:before{content:""}.ph-fill.ph-vector-three:before{content:""}.ph-fill.ph-vector-two:before{content:""}.ph-fill.ph-vibrate:before{content:""}.ph-fill.ph-video:before{content:""}.ph-fill.ph-video-camera:before{content:""}.ph-fill.ph-video-camera-slash:before{content:""}.ph-fill.ph-video-conference:before{content:""}.ph-fill.ph-vignette:before{content:""}.ph-fill.ph-vinyl-record:before{content:""}.ph-fill.ph-virtual-reality:before{content:""}.ph-fill.ph-virus:before{content:""}.ph-fill.ph-visor:before{content:""}.ph-fill.ph-voicemail:before{content:""}.ph-fill.ph-volleyball:before{content:""}.ph-fill.ph-wall:before{content:""}.ph-fill.ph-wallet:before{content:""}.ph-fill.ph-warehouse:before{content:""}.ph-fill.ph-warning:before{content:""}.ph-fill.ph-warning-circle:before{content:""}.ph-fill.ph-warning-diamond:before{content:""}.ph-fill.ph-warning-octagon:before{content:""}.ph-fill.ph-washing-machine:before{content:""}.ph-fill.ph-watch:before{content:""}.ph-fill.ph-wave-sawtooth:before{content:""}.ph-fill.ph-wave-sine:before{content:""}.ph-fill.ph-wave-square:before{content:""}.ph-fill.ph-wave-triangle:before{content:""}.ph-fill.ph-waveform:before{content:""}.ph-fill.ph-waveform-slash:before{content:""}.ph-fill.ph-waves:before{content:""}.ph-fill.ph-webcam:before{content:""}.ph-fill.ph-webcam-slash:before{content:""}.ph-fill.ph-webhooks-logo:before{content:""}.ph-fill.ph-wechat-logo:before{content:""}.ph-fill.ph-whatsapp-logo:before{content:""}.ph-fill.ph-wheelchair:before{content:""}.ph-fill.ph-wheelchair-motion:before{content:""}.ph-fill.ph-wifi-high:before{content:""}.ph-fill.ph-wifi-low:before{content:""}.ph-fill.ph-wifi-medium:before{content:""}.ph-fill.ph-wifi-none:before{content:""}.ph-fill.ph-wifi-slash:before{content:""}.ph-fill.ph-wifi-x:before{content:""}.ph-fill.ph-wind:before{content:""}.ph-fill.ph-windmill:before{content:""}.ph-fill.ph-windows-logo:before{content:""}.ph-fill.ph-wine:before{content:""}.ph-fill.ph-wrench:before{content:""}.ph-fill.ph-x:before{content:""}.ph-fill.ph-x-circle:before{content:""}.ph-fill.ph-x-logo:before{content:""}.ph-fill.ph-x-square:before{content:""}.ph-fill.ph-yarn:before{content:""}.ph-fill.ph-yin-yang:before{content:""}.ph-fill.ph-youtube-logo:before{content:""}@font-face{font-family:IBM Plex Mono;src:url(/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Regular.ttf) format("truetype");font-weight:400;font-style:normal;font-display:swap}@font-face{font-family:IBM Plex Mono;src:url(/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Medium.ttf) format("truetype");font-weight:500;font-style:normal;font-display:swap}@font-face{font-family:IBM Plex Mono;src:url(/assets/fonts/IBM_Plex_Mono/IBMPlexMono-SemiBold.ttf) format("truetype");font-weight:600;font-style:normal;font-display:swap}@font-face{font-family:IBM Plex Mono;src:url(/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Bold.ttf) format("truetype");font-weight:700;font-style:normal;font-display:swap}@font-face{font-family:IBM Plex Mono;src:url(/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Italic.ttf) format("truetype");font-weight:400;font-style:italic;font-display:swap}.container{padding:18px}.section{margin-bottom:48px}.section-title,.block{margin-bottom:34px}.block-title{margin-bottom:22px}.text,p{margin-bottom:15px}.hint{margin-top:8px}.list{padding-left:22px;margin-bottom:15px}.list-item{margin-bottom:8px}.list-nested{margin-top:8px}.table{margin-bottom:22px}.table-caption{margin-bottom:8px}.form-group{margin-bottom:15px}.label{margin-bottom:5px;display:block}.input,.select,.textarea{margin-top:5px}.toast{padding:15px}.toast-stack{gap:8px}@keyframes terminal_scan_x{0%{transform:translate(-120%)}to{transform:translate(220%)}}@keyframes terminal_scan_y{0%{transform:translateY(-120%)}to{transform:translateY(220%)}}@keyframes terminal_pulse{0%,to{box-shadow:0 0 #c0caf500}50%{box-shadow:0 0 0 4px #c0caf52e}}@keyframes panel_boot{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}@keyframes overlay_reveal{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}@keyframes tooltip_reveal{0%{opacity:0;transform:translate(-50%) translateY(5px)}to{opacity:1;transform:translate(-50%) translateY(0)}}@media(prefers-reduced-motion:reduce){*,:after,:before{animation-duration:0s!important;animation-iteration-count:1!important;scroll-behavior:auto!important;transition-duration:0s!important}}html{font-size:100%}body{font-family:IBM Plex Mono,monospace;font-size:15px;font-weight:400;line-height:1.6;letter-spacing:0;color:#c0caf5}h1,h2,h3,h4,h5,h6{font-family:IBM Plex Mono,monospace;font-weight:600;line-height:1.25;margin:0}h1.contrast,h2.contrast,h3.contrast,h4.contrast,h5.contrast,h6.contrast{background:#c0caf5;color:#16161e;display:inline;padding:0 8px}h1{font-size:34px;letter-spacing:0}h2{font-size:26px}h3{font-size:22px}h4{font-size:20px}h5{font-size:18px}h6{font-size:16px;font-weight:500}.text,p{font-size:15px;line-height:1.6}.text-sm{font-size:13px;line-height:1.4}.text-lg{font-size:16px;line-height:1.6}.text-lead{max-width:760px;color:#c0caf5;font-size:16px;font-weight:500;line-height:1.6}.text-muted{font-size:13px;color:#787c99}.text-strong,strong{font-weight:600}.text-bold{font-weight:700}.text-italic,em{font-style:italic}.text-success{color:#9ece6a}.text-warning{color:#e0af68}.text-danger,.text-error{color:#f7768e}.text-info{color:#bb9af7}.eyebrow{display:inline-flex;width:-moz-max-content;width:max-content;max-width:100%;padding:5px 8px;color:#16161e;background:#7aa2f7;font-size:12px;font-weight:700;line-height:1;text-transform:uppercase}.caption{color:#787c99;font-size:12px;line-height:1.4}.code,code,pre{font-family:IBM Plex Mono,monospace;font-size:15px;line-height:1.4;background-color:#1f2335}.text-primary{color:#c0caf5}.text-secondary{color:#a9b1d6}pre{font-size:15px;line-height:1.6;white-space:pre-wrap}.code,pre code{-o-tab-size:2;tab-size:2;-moz-tab-size:2}.code{display:inline-flex;padding:0 5px;color:#7aa2f7;border:2px solid rgba(122,162,247,.24)}.kbd{display:inline-flex;align-items:center;min-height:24px;padding:0 8px;border:2px solid rgba(192,202,245,.24);border-bottom-color:#7aa2f7;color:#c0caf5;background:#1f2335;font-family:IBM Plex Mono,monospace;font-size:12px;font-weight:700;line-height:1;text-transform:uppercase}.quote{max-width:760px;margin:0;padding:15px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;color:#a9b1d6;background:#1f2335;font-size:15px;line-height:1.6}.quote cite{display:block;margin-top:12px;color:#7aa2f7;font-size:13px;font-style:normal;text-transform:uppercase}a{font-weight:500;text-decoration:none;color:#7aa2f7}@media(hover:hover)and (pointer:fine){a:hover{color:#e0af68}}@media(hover:none)and (pointer:coarse){a:active{color:#e0af68}}.link{font-size:inherit;font-weight:500}.label{font-size:13px;font-weight:500;line-height:1.4}.hint,.meta{font-size:12px;line-height:1.4}.table{font-size:13px;line-height:1.4}.table th{font-weight:600}.table td{font-weight:400}.list{font-size:15px;line-height:1.6}.list-item{font-size:inherit}.modal-title{font-size:20px;font-weight:600}.modal-body{font-size:15px}.toast-title{font-size:14px;font-weight:600}.toast-text{font-size:13px;line-height:1.4}.palette{display:flex;flex-direction:row;flex-wrap:wrap;gap:8px}.palette .color .color-box{width:92px;height:68px}body .bg-primary{background:#c0caf5}body .bg-secondary{background:#7aa2f7}body .bg-success{background:#9ece6a}body .bg-accent{background:#ff9e64}body .bg-info{background:#bb9af7}body .bg-warning{background:#e0af68}body .bg-error{background:#f7768e}body .text-color-primary{color:#c0caf5}body .text-color-secondary{color:#7aa2f7}body .text-color-success{color:#9ece6a}body .text-color-accent{color:#ff9e64}body .text-color-info{color:#bb9af7}body .text-color-warning{color:#e0af68}body .text-color-error{color:#f7768e}.loader{width:32px;aspect-ratio:1;--c:no-repeat linear-gradient(#FF3C00 0 0);background:var(--c) 0 0,var(--c) 0 100%,var(--c) 50% 0,var(--c) 50% 100%,var(--c) 100% 0,var(--c) 100% 100%;animation:l12 1s infinite}@keyframes l12{0%,to{background-size:20% 50%}16.67%{background-size:20% 30%,20% 30%,20% 50%,20% 50%,20% 50%,20% 50%}33.33%{background-size:20% 30%,20% 30%,20% 30%,20% 30%,20% 50%,20% 50%}50%{background-size:20% 30%,20% 30%,20% 30%,20% 30%,20% 30%,20% 30%}66.67%{background-size:20% 50%,20% 50%,20% 30%,20% 30%,20% 30%,20% 30%}83.33%{background-size:20% 50%,20% 50%,20% 50%,20% 50%,20% 30%,20% 30%}}.circle-loader{display:flex;flex-direction:row;align-items:center;gap:8px}.circle-loader .ph,.circle-loader .ph-bold{font-size:26px;transform-origin:50% 50%;animation:icon_spin 1.2s linear infinite}.progress{display:flex;flex-direction:column;gap:8px;width:100%;max-width:640px}.progress .progress-header{display:flex;align-items:center;justify-content:space-between;gap:12px;color:#a9b1d6;font-size:13px;font-weight:600;text-transform:uppercase}.progress .progress-value{color:#c0caf5;font-family:IBM Plex Mono,monospace}.progress .progress-track{position:relative;width:100%;height:18px;overflow:hidden;border:2px solid rgba(192,202,245,.24);background:#1f2335}.progress .progress-bar{display:block;position:relative;overflow:hidden;width:var(--progress-value,0%);height:100%;background:#7aa2f7;transition:width .28s ease}.progress.progress-success .progress-bar{background:#9ece6a}.progress.progress-warning .progress-bar{background:#e0af68}.progress.progress-danger .progress-bar,.progress.progress-error .progress-bar{background:#f7768e}.progress.progress-striped .progress-bar{background-image:repeating-linear-gradient(90deg,transparent 0,transparent 14px,rgba(22,22,30,.2) 14px,rgba(22,22,30,.2) 16px)}.progress.progress-animated .progress-bar:after{content:"";position:absolute;top:0;right:0;bottom:0;left:0;width:48%;background:linear-gradient(90deg,transparent,rgba(192,202,245,.28),transparent);transform:translate(-120%);animation:progress_scan 1.4s ease infinite}.usage-meter{display:grid;gap:12px;width:100%;max-width:420px;padding:15px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#1f2335}.usage-meter .usage-meter-title{display:flex;align-items:center;justify-content:space-between;gap:12px;margin:0;font-size:16px;font-weight:700;line-height:1;text-transform:uppercase}.usage-meter .usage-meter-value{color:#7aa2f7;font-family:IBM Plex Mono,monospace;font-size:13px}.usage-meter .usage-meter-meta{margin:0;color:#a9b1d6;font-size:13px;line-height:1.4}.progress-stages{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;width:100%;max-width:720px}.progress-stages .progress-stage{min-height:42px;padding:8px 12px;border:2px solid rgba(192,202,245,.24);color:#787c99;background:#1f2335;font-size:13px;font-weight:600;line-height:1.4;text-transform:uppercase}.progress-stages .progress-stage-complete{color:#16161e;background:#9ece6a;border-color:#9ece6a}.progress-stages .progress-stage-current{color:#16161e;background:#e0af68;border-color:#e0af68}@media(max-width:767px){.progress-stages{grid-template-columns:1fr 1fr}}@media(max-width:479px){.progress-stages{grid-template-columns:1fr}}@keyframes progress_scan{0%{transform:translate(-120%)}to{transform:translate(220%)}}@keyframes icon_spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.btn{display:inline-flex;align-items:center;justify-content:center;min-height:46px;font-family:IBM Plex Mono,monospace;font-size:15px;font-weight:600;line-height:1;letter-spacing:.04em;padding:12px 22px;border-radius:0;border-width:2px;border-left-width:6px;border-style:solid;border-color:#c0caf5;text-transform:uppercase;background-color:transparent;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:background-color,border-color,color,opacity}.btn:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}.btn.with-icon{border-left-width:46px;position:relative}.btn.with-icon .ph,.btn.with-icon .ph-bold{position:absolute;color:#16161e;left:-46px;top:1px;font-size:26px;height:100%;display:inline-flex;align-items:center;width:46px;justify-content:center;transition-duration:.2s;transition-property:color,left}@media(hover:hover)and (pointer:fine){.btn:hover.with-icon:not(.loading-state):not(.btn-small) .ph,.btn:hover.with-icon:not(.loading-state):not(.btn-small) .ph-bold{left:-28px}}@media(hover:none)and (pointer:coarse){.btn:active.with-icon:not(.loading-state):not(.btn-small) .ph,.btn:active.with-icon:not(.loading-state):not(.btn-small) .ph-bold{left:-28px}}.btn.btn-primary{color:#c0caf5;border-color:#c0caf5}@media(hover:hover)and (pointer:fine){.btn.btn-primary:hover{background-color:#c0caf5;color:#16161e}}@media(hover:none)and (pointer:coarse){.btn.btn-primary:active{background-color:#c0caf5;color:#16161e}}.btn.btn-secondary{color:#7aa2f7;border-color:#7aa2f7}@media(hover:hover)and (pointer:fine){.btn.btn-secondary:hover{background-color:#7aa2f7;color:#16161e}.btn.btn-secondary:hover.with-icon .ph,.btn.btn-secondary:hover.with-icon .ph-bold{color:#16161e}}@media(hover:none)and (pointer:coarse){.btn.btn-secondary:active{background-color:#7aa2f7;color:#16161e}.btn.btn-secondary:active.with-icon .ph,.btn.btn-secondary:active.with-icon .ph-bold{color:#16161e}}.btn.btn-accent{color:#ff9e64;border-color:#ff9e64}@media(hover:hover)and (pointer:fine){.btn.btn-accent:hover{background-color:#ff9e64;color:#16161e}.btn.btn-accent:hover.with-icon .ph,.btn.btn-accent:hover.with-icon .ph-bold{color:#16161e}}@media(hover:none)and (pointer:coarse){.btn.btn-accent:active{background-color:#ff9e64;color:#16161e}.btn.btn-accent:active.with-icon .ph,.btn.btn-accent:active.with-icon .ph-bold{color:#16161e}}.btn.btn-danger{color:#f7768e;border-color:#f7768e}@media(hover:hover)and (pointer:fine){.btn.btn-danger:hover{background-color:#f7768e;color:#16161e}}@media(hover:none)and (pointer:coarse){.btn.btn-danger:active{background-color:#f7768e;color:#16161e}}.btn.btn-warning{color:#e0af68;border-color:#e0af68}@media(hover:hover)and (pointer:fine){.btn.btn-warning:hover{background-color:#e0af68;color:#16161e}}@media(hover:none)and (pointer:coarse){.btn.btn-warning:active{background-color:#e0af68;color:#16161e}}.btn.btn-success{color:#9ece6a;border-color:#9ece6a}@media(hover:hover)and (pointer:fine){.btn.btn-success:hover{background-color:#9ece6a;color:#16161e}}@media(hover:none)and (pointer:coarse){.btn.btn-success:active{background-color:#9ece6a;color:#16161e}}.btn.btn-info{color:#bb9af7;border-color:#bb9af7}@media(hover:hover)and (pointer:fine){.btn.btn-info:hover{background-color:#bb9af7;color:#16161e}.btn.btn-info:hover.with-icon .ph,.btn.btn-info:hover.with-icon .ph-bold{color:#16161e}}@media(hover:none)and (pointer:coarse){.btn.btn-info:active{background-color:#bb9af7;color:#16161e}.btn.btn-info:active.with-icon .ph,.btn.btn-info:active.with-icon .ph-bold{color:#16161e}}.btn[disabled]:not(.loading-state){color:#787c99;border-color:#c0caf53d;background-color:#1f2335;cursor:not-allowed;opacity:.72}.btn[disabled]:not(.loading-state).with-icon .ph,.btn[disabled]:not(.loading-state).with-icon .ph-bold{color:#787c99}@media(hover:hover)and (pointer:fine){.btn[disabled]:not(.loading-state):hover{background-color:#1f2335;color:#787c99}.btn[disabled]:not(.loading-state):hover.with-icon .ph,.btn[disabled]:not(.loading-state):hover.with-icon .ph-bold{color:#787c99}}@media(hover:none)and (pointer:coarse){.btn[disabled]:not(.loading-state):active{background-color:#1f2335;color:#787c99}.btn[disabled]:not(.loading-state):active.with-icon .ph,.btn[disabled]:not(.loading-state):active.with-icon .ph-bold{color:#787c99}}.btn[disabled]:not(.loading-state).with-icon:not(.btn-small) .ph,.btn[disabled]:not(.loading-state).with-icon:not(.btn-small) .ph-bold{left:-28px}.btn.btn-small{font-size:13px;font-weight:500;min-height:38px;padding:8px}.btn.btn-small.with-icon{border-left-width:32px}.btn.btn-small.with-icon .ph,.btn.btn-small.with-icon .ph-bold{top:0;left:-40px;font-size:22px}.btn.btn-small.with-icon.loading-state .ph,.btn.btn-small.with-icon.loading-state .ph-bold{font-size:26px}.btn.btn-large{font-size:16px;font-weight:700;min-height:54px;padding:15px 48px}.btn.loading-state{color:#16161e!important;border-color:#c0caf5!important;background-color:#c0caf5!important}.btn.loading-state .ph,.btn.loading-state .ph-bold{font-size:26px;transform-origin:50% 50%;animation:icon_spin 1.2s linear infinite}.btn-icon{display:flex;justify-content:center;align-items:center;width:38px;height:38px;background:0 0;color:#c0caf5;font-size:22px;border:2px solid transparent;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background,border-color}.btn-icon:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}@media(hover:hover)and (pointer:fine){.btn-icon:not(.without-hover):hover{color:#e0af68;border-color:#e0af68}}@media(hover:none)and (pointer:coarse){.btn-icon:not(.without-hover):active{color:#e0af68;border-color:#e0af68}}.btn-icon:disabled,.btn-icon[disabled]{color:#787c99;border-color:transparent;background-color:transparent;cursor:not-allowed;opacity:.72}@media(hover:hover)and (pointer:fine){.btn-icon:disabled:not(.without-hover):hover,.btn-icon[disabled]:not(.without-hover):hover{color:#787c99;border-color:transparent}}@media(hover:none)and (pointer:coarse){.btn-icon:disabled:not(.without-hover):active,.btn-icon[disabled]:not(.without-hover):active{color:#787c99;border-color:transparent}}.btn-icon-sm{width:28px;height:28px;font-size:18px}.form-group{width:100%;max-width:600px}.form-group .label{display:flex;flex-direction:column;font-size:15px;width:100%;position:relative;color:#c0caf5}.form-group .label>.ph{position:absolute;color:#c0caf5;left:0;bottom:1px;font-size:26px;height:54px;display:inline-flex;align-items:center;width:46px;justify-content:center;transition-duration:.2s;transition-property:color,left}.form-group .label .input{min-height:54px;font-family:IBM Plex Mono,monospace;font-size:15px;font-weight:500;line-height:1;letter-spacing:.04em;padding:12px 22px;margin-top:8px;border-radius:0;border-width:2px;border-bottom-width:6px;border-style:solid;border-color:#c0caf5;color:#c0caf5;background-color:#1f2335;transition-duration:.2s;transition-timing-function:ease;transition-property:background-color,border-color,color}@media(hover:hover)and (pointer:fine){.form-group .label .input:hover{border-bottom-color:#787c99}}@media(hover:none)and (pointer:coarse){.form-group .label .input:active{border-bottom-color:#787c99}}.form-group .label .input:focus{outline:2px solid #E0AF68;outline-offset:3px;border-color:#7aa2f7;background-color:transparent}.form-group .label .input:disabled{color:#787c99;border-color:#c0caf53d;background:#1f2335;cursor:not-allowed;opacity:.72}.form-group .label .input[readonly]{color:#a9b1d6;border-color:#c0caf53d;background:#c0caf508}.form-group .label .input::-moz-placeholder{color:#787c99}.form-group .label .input::placeholder{color:#787c99}.form-group .label .input::-webkit-search-cancel-button,.form-group .label .input::-webkit-search-decoration,.form-group .label .input::-webkit-search-results-button,.form-group .label .input::-webkit-search-results-decoration{display:none;-webkit-appearance:none}.form-group .label .input[type=date],.form-group .label .input[type=datetime-local],.form-group .label .input[type=month],.form-group .label .input[type=time]{color-scheme:dark;cursor:pointer;min-width:0;padding-right:46px;text-transform:uppercase}.form-group .label .input[type=date]::-webkit-calendar-picker-indicator,.form-group .label .input[type=datetime-local]::-webkit-calendar-picker-indicator,.form-group .label .input[type=month]::-webkit-calendar-picker-indicator,.form-group .label .input[type=time]::-webkit-calendar-picker-indicator{width:46px;height:100%;margin:0;padding:0;background:0 0;cursor:pointer;opacity:0}.form-group .label .input[type=date]::-webkit-datetime-edit,.form-group .label .input[type=datetime-local]::-webkit-datetime-edit,.form-group .label .input[type=month]::-webkit-datetime-edit,.form-group .label .input[type=time]::-webkit-datetime-edit{padding:0}.form-group .label .input[type=date]::-webkit-datetime-edit-fields-wrapper,.form-group .label .input[type=datetime-local]::-webkit-datetime-edit-fields-wrapper,.form-group .label .input[type=month]::-webkit-datetime-edit-fields-wrapper,.form-group .label .input[type=time]::-webkit-datetime-edit-fields-wrapper{color:#c0caf5}.form-group .label textarea.input{height:108px;line-height:1.25;resize:none}.form-group .label .ph+.input,.form-group .label .ph+.select-wrap .select{padding-left:46px}.form-group .label .select-wrap{margin-top:8px}.form-group .label .select{width:100%;height:54px;margin-top:0;appearance:none;-webkit-appearance:none;-moz-appearance:none}.form-group .label .select:focus{outline:0}.form-group .label .select option{color:#c0caf5;background:#1f2335}.form-group .label .select-wrap:after{content:"";position:absolute;right:22px;bottom:18px;transform:translateY(-50%);width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-top:10px solid #c0caf5;pointer-events:none}.form-group .label.error .input:not(:focus){border-color:#f7768e}.form-group .label.error+.input-info{color:#e0af68}.form-group .label.success .input:not(:focus){border-color:#9ece6a}.form-group .label.success+.input-info{color:#9ece6a}.form-group .label.warning .input:not(:focus){border-color:#e0af68}.form-group .label.warning+.input-info{color:#e0af68}.form-group .input-info{font-size:14px;margin-top:8px}.form-group .input-info .ph{position:relative;top:1px}.form-group .input-info.error{color:#e0af68}.form-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:15px;width:100%;max-width:760px}.fieldset{width:100%;max-width:760px;margin:0;padding:18px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#1f2335}.legend{padding:5px 8px;color:#16161e;background:#c0caf5;font-size:13px;font-weight:700;line-height:1;text-transform:uppercase}.file-upload{display:inline-flex;align-items:center;gap:8px;min-height:46px;padding:8px 12px;border:2px solid #7aa2f7;border-left-width:6px;color:#7aa2f7;background:#1f2335;font-size:13px;font-weight:700;text-transform:uppercase;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background,border-color}.file-upload input[type=file]{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}@media(hover:hover)and (pointer:fine){.file-upload:hover{color:#16161e;background:#7aa2f7}}@media(hover:none)and (pointer:coarse){.file-upload:active{color:#16161e;background:#7aa2f7}}.file-upload:focus-within{outline:2px solid #E0AF68;outline-offset:3px}.file-upload-panel{width:100%;max-width:760px;background:#1f2335;border:2px solid rgba(192,202,245,.24);border-left-width:6px}.file-upload-form{display:flex;flex-direction:column;gap:15px;margin:0}.file-upload-header{display:flex;align-items:flex-start;justify-content:space-between;gap:15px;padding:15px 15px 0}.file-upload-heading{display:flex;flex-direction:column;gap:5px;min-width:0}.file-upload-title{margin:0;color:#c0caf5;font-size:16px;font-weight:700;line-height:1.25;text-transform:uppercase}.file-upload-description{margin:0;color:#a9b1d6;font-size:13px;line-height:1.6}.file-upload-dropzone{display:grid;grid-template-columns:auto minmax(0,1fr);align-items:center;gap:15px;margin:0 15px;padding:18px;border:2px dashed #7aa2f7;background:#7aa2f714;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:background,border-color}.file-upload-dropzone input[type=file]{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}@media(hover:hover)and (pointer:fine){.file-upload-dropzone:hover{border-color:#c0caf5;background:#c0caf51a}}@media(hover:none)and (pointer:coarse){.file-upload-dropzone:active{border-color:#c0caf5;background:#c0caf51a}}.file-upload-dropzone:focus-within{outline:2px solid #E0AF68;outline-offset:3px}.file-upload-icon{display:inline-flex;align-items:center;justify-content:center;width:54px;height:54px;color:#16161e;background:#7aa2f7;font-size:26px}.file-upload-body{display:flex;flex-direction:column;gap:5px;min-width:0}.file-upload-primary{color:#c0caf5;font-size:15px;font-weight:700;line-height:1.25;text-transform:uppercase}.file-upload-secondary{color:#a9b1d6;font-size:13px;line-height:1.4}.file-upload-preview{display:grid;grid-template-columns:repeat(auto-fill,minmax(148px,1fr));gap:12px;margin:0 15px}.file-upload-preview[hidden]{display:none}.file-upload-preview-item{position:relative;min-width:0;margin:0;border:2px solid rgba(192,202,245,.24);background:#1f2335}.file-upload-preview-remove{position:absolute;top:8px;right:8px;z-index:1;display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;border:2px solid #f7768e;color:#f7768e;background:#1f2335;font-size:18px;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background,border-color}@media(hover:hover)and (pointer:fine){.file-upload-preview-remove:hover{color:#16161e;background:#f7768e}}@media(hover:none)and (pointer:coarse){.file-upload-preview-remove:active{color:#16161e;background:#f7768e}}.file-upload-preview-remove:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}.file-upload-preview-visual{display:flex;align-items:center;justify-content:center;aspect-ratio:1;background:#1f2335}.file-upload-preview-visual img{display:block;width:100%;height:100%;-o-object-fit:cover;object-fit:cover}.file-upload-preview-type{display:inline-flex;align-items:center;justify-content:center;min-width:54px;min-height:54px;padding:8px;color:#16161e;background:#7aa2f7;font-size:13px;font-weight:700;line-height:1;text-transform:uppercase}.file-upload-preview-item figcaption{display:flex;flex-direction:column;gap:5px;overflow:hidden;padding:8px}.file-upload-preview-name{overflow:hidden;color:#c0caf5;font-size:12px;font-weight:700;line-height:1.25;text-overflow:ellipsis;white-space:nowrap}.file-upload-preview-meta{color:#a9b1d6;font-size:12px;font-weight:700;line-height:1.25;text-transform:uppercase}.file-upload-actions{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:8px;padding:0 15px 15px}.range{width:100%;max-width:600px;accent-color:#7AA2F7}.range input[type=range]{-webkit-appearance:none;-moz-appearance:none;appearance:none;width:100%;height:46px;margin:0;background:0 0;cursor:pointer}.range input[type=range]::-webkit-slider-runnable-track{height:6px;background:#c0caf516;border:2px solid rgba(192,202,245,.24)}.range input[type=range]::-webkit-slider-thumb{width:22px;height:38px;margin-top:-19px;border:2px solid #7aa2f7;background:#7aa2f7;-webkit-appearance:none}.range input[type=range]::-moz-range-track{height:6px;background:#c0caf516;border:2px solid rgba(192,202,245,.24)}.range input[type=range]::-moz-range-thumb{width:22px;height:38px;border:2px solid #7aa2f7;border-radius:0;background:#7aa2f7}@media(max-width:767px){.form-grid{grid-template-columns:1fr}.file-upload-header{flex-direction:column;align-items:stretch}.file-upload-dropzone{grid-template-columns:1fr}.file-upload-actions{justify-content:stretch}.file-upload-actions .btn{width:100%}}.radio{display:inline-flex;flex-direction:row;gap:8px;align-items:center;cursor:pointer}.radio input[type=radio]{display:none}.radio .radio-control{width:22px;height:22px;border-radius:100%;border:3px solid #c0caf5;background:#1f2335;position:relative;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition-duration:.2s;transition-property:border-color,background}.radio .radio-control:before{content:"";display:block;width:10px;height:10px;border-radius:100%;background:#c0caf5;transform:scale(0);transition-duration:.2s;transition-property:transform,background}@media(hover:hover)and (pointer:fine){.radio:hover .radio-control{border-color:#c0caf5}}@media(hover:none)and (pointer:coarse){.radio:active .radio-control{border-color:#c0caf5}}.radio input[type=radio]:checked+.radio-control{border-color:#c0caf5;background:#c0caf52e}.radio input[type=radio]:checked+.radio-control:before{transform:scale(1)}.radio input[type=radio]:disabled+.radio-control{border-color:#414868;background:#4148681f;opacity:.5}.radio input[type=radio]:disabled:checked+.radio-control:before{background:#414868}.radio input[type=radio]:focus-visible+.radio-control{outline:2px solid #E0AF68;outline-offset:3px}.radio .radio-label{font-size:15px}.radio-group{display:flex;flex-wrap:wrap;gap:12px;align-items:center}.switch{display:inline-flex;flex-direction:row;gap:8px;align-items:center}.switch input[type=checkbox]{display:none}.switch .switch-control{height:16px;width:32px;border:2px solid #c0caf5;position:relative;background:0 0;transition-duration:.2s;transition-property:border-color,background;display:block}.switch .switch-control:before{content:"";display:block;height:20px;width:20px;background:#c0caf5;position:absolute;left:-5px;top:-5px;transition-duration:.2s;transition-property:left,background}@media(hover:hover)and (pointer:fine){.switch:hover .switch-control{background:#414868}}@media(hover:none)and (pointer:coarse){.switch:active .switch-control{background:#414868}}.switch input[type=checkbox]:checked:not(:disabled)+.switch-control{background:#7aa2f7;border-color:#7aa2f7}.switch input[type=checkbox]:checked+.switch-control:before{left:17px}.switch input[type=checkbox]:disabled+.switch-control{border-color:#414868}.switch input[type=checkbox]:focus-visible+.switch-control{outline:2px solid #E0AF68;outline-offset:3px}.switch input[type=checkbox]:disabled+.switch-control:before{background:#414868}.checkbox{display:inline-flex;flex-direction:row;gap:8px;align-items:center;cursor:pointer}.checkbox input[type=checkbox]{display:none}.checkbox .checkbox-control{width:22px;height:22px;border:2px solid #c0caf5;border-bottom-width:6px;background:#1f2335;position:relative;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition-duration:.2s;transition-property:border-color,background}.checkbox .checkbox-control:before{content:"";display:block;width:10px;height:5px;border-left:2px solid #c0caf5;border-bottom:2px solid #c0caf5;transform:rotate(-45deg) scale(0);opacity:0;margin-top:-2px;transition-duration:.2s;transition-property:transform,opacity,border-color}@media(hover:hover)and (pointer:fine){.checkbox:hover .checkbox-control{border-color:#c0caf5}}@media(hover:none)and (pointer:coarse){.checkbox:active .checkbox-control{border-color:#c0caf5}}.checkbox input[type=checkbox]:checked+.checkbox-control{border-color:#c0caf5;background:#c0caf52e}.checkbox input[type=checkbox]:checked+.checkbox-control:before{transform:rotate(-45deg) scale(1);opacity:1;border-color:#c0caf5}.checkbox input[type=checkbox]:disabled+.checkbox-control{border-color:#414868;background:#4148681f;opacity:.5}.checkbox input[type=checkbox]:disabled:checked+.checkbox-control:before{border-color:#414868}.checkbox input[type=checkbox]:focus-visible+.checkbox-control{outline:2px solid #E0AF68;outline-offset:3px}.checkbox .checkbox-label{font-size:15px}.input-group{display:flex;align-items:stretch;width:100%;max-width:600px;min-height:54px;border:2px solid #c0caf5;border-bottom-width:6px;background:#1f2335;transition-duration:.2s;transition-timing-function:ease;transition-property:border-color,background}.input-group:focus-within{outline:2px solid #E0AF68;outline-offset:3px;border-color:#7aa2f7;background:0 0}.input-group .input-group-action,.input-group .input-group-addon{display:inline-flex;align-items:center;justify-content:center;min-width:54px;padding:0 12px;color:#a9b1d6;background:#c0caf50b;border:0;font-family:IBM Plex Mono,monospace;font-size:13px;font-weight:600;text-transform:uppercase}.input-group .input-group-action{color:#c0caf5;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background}.input-group .input-group-input{flex:1 1 auto;min-width:0;border:0;padding:12px 15px;color:#c0caf5;background:0 0;font-family:IBM Plex Mono,monospace;font-size:15px;font-weight:500;letter-spacing:.04em}.input-group .input-group-input:focus{outline:0}.input-group .input-group-input::-moz-placeholder{color:#787c99}.input-group .input-group-input::placeholder{color:#787c99}.input-group .input-group-input::-webkit-search-cancel-button,.input-group .input-group-input::-webkit-search-decoration,.input-group .input-group-input::-webkit-search-results-button,.input-group .input-group-input::-webkit-search-results-decoration{display:none;-webkit-appearance:none}.input-group .ph,.input-group .ph-bold{font-size:22px}.input-group.input-group-compact{min-height:46px}.input-group.input-group-compact .input-group-action,.input-group.input-group-compact .input-group-addon{min-width:46px}.input-group.input-group-compact .input-group-input{padding:8px 12px;font-size:13px}.search-field{max-width:420px}.repeater .repeater-header{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:12px}.repeater .repeater-title{font-size:15px;font-weight:600;color:#c0caf5}.repeater .repeater-list{display:grid;gap:8px}.repeater .repeater-item{background:#1f2335;border:2px solid rgba(192,202,245,.24);padding:12px;display:grid;grid-template-columns:1fr auto;gap:12px;align-items:start}.repeater .repeater-item-body{width:100%}.repeater .repeater-item-actions{display:flex;align-items:center;gap:8px;padding-top:22px}.repeater.repeater-disabled{opacity:.6;pointer-events:none}.list{display:flex;flex-direction:column;gap:5px;list-style-type:none;padding-left:0}.list .list-item{display:flex;flex-direction:row;align-items:center;gap:8px;margin-left:0}.list.list-ordered{list-style-type:decimal;display:list-item;margin-left:30px}.list.list-ordered .list-item{display:list-item}.list.list-definition{width:100%;max-width:620px;gap:0;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#1f2335}.list.list-definition .list-row{display:grid;grid-template-columns:minmax(120px,.32fr) minmax(0,1fr);gap:15px;align-items:start;padding:12px 15px;border-bottom:2px solid rgba(192,202,245,.08);transition-duration:.2s;transition-timing-function:ease;transition-property:background,border-color}.list.list-definition .list-row .list-term{display:inline-flex;width:-moz-max-content;width:max-content;max-width:100%;margin:0;padding:5px 8px;color:#16161e;background:#c0caf5;font-size:13px;font-weight:700;line-height:1;text-transform:uppercase;transition-duration:.2s;transition-timing-function:ease;transition-property:background,transform}.list.list-definition .list-row .list-desc{margin:0;color:#a9b1d6;font-size:13px;line-height:1.6;transition-duration:.2s;transition-timing-function:ease;transition-property:color,transform}.list.list-definition .list-row:last-child{border-bottom:0}@media(hover:hover)and (pointer:fine){.list.list-definition .list-row:hover{background:#c0caf516}.list.list-definition .list-row:hover .list-term{background:#7aa2f7;transform:translate(5px)}.list.list-definition .list-row:hover .list-desc{color:#c0caf5;transform:translate(5px)}}@media(hover:none)and (pointer:coarse){.list.list-definition .list-row:active{background:#c0caf516}.list.list-definition .list-row:active .list-term{background:#7aa2f7;transform:translate(5px)}.list.list-definition .list-row:active .list-desc{color:#c0caf5;transform:translate(5px)}}.list.list-nav{max-width:420px;width:100%;gap:0}.list.list-nav .list-item{display:flex;flex-direction:column;align-items:flex-start;height:50px;margin:0}.list.list-nav .list-item .list-action{display:flex;justify-content:space-between;align-items:center;width:100%;height:100%;padding:8px 12px;border:2px solid transparent;font-size:15px;background:#1f2335;color:inherit;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:background,border-color,color}.list.list-nav .list-item .list-action:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}@media(hover:hover)and (pointer:fine){.list.list-nav .list-item .list-action:hover{background:#7aa2f7;color:#16161e}}@media(hover:none)and (pointer:coarse){.list.list-nav .list-item .list-action:active{background:#7aa2f7;color:#16161e}}.list.list-nav .list-item .list-action .list-label{display:flex;flex-direction:row;gap:8px;align-items:center;letter-spacing:0;font-weight:400}.list.list-nav .list-item .list-action .list-meta{padding:8px;background:#9ece6a;color:#16161e;display:flex}.list.list-nav .list-item.list-item-active .list-action{background:#7aa2f7;color:#16161e;border-color:#7aa2f7}.list.list-actions{width:100%;max-width:420px;gap:22px}.list.list-actions .list-item{justify-content:space-between;align-items:flex-start;padding:12px 0;border-bottom:2px solid rgba(192,202,245,.08)}.list.list-actions .list-item .list-content{display:flex;flex-direction:column;gap:8px}.list.list-actions .list-item .list-content .list-title{font-size:16px;line-height:1}.list.list-actions .list-item .list-content .list-subtitle{color:#787c99}@media(hover:hover)and (pointer:fine){.list.list-actions .list-item:hover .list-title{color:#7aa2f7}}@media(hover:none)and (pointer:coarse){.list.list-actions .list-item:active .list-title{color:#7aa2f7}}@media(max-width:479px){.list.list-definition .list-row{grid-template-columns:1fr;gap:8px}}.badge{position:relative;overflow:hidden;background:#c0caf5;color:#16161e;padding:5px 8px;font-size:13px;font-weight:600;line-height:1;letter-spacing:.04em;text-transform:uppercase;display:inline-flex;align-items:center;min-height:24px;transition-duration:.2s;transition-timing-function:ease;transition-property:filter,transform,border-color,color,background}.badge:after{content:"";position:absolute;inset:0 auto 0 0;width:40%;background:linear-gradient(90deg,transparent,rgba(22,22,30,.16),transparent);opacity:0;pointer-events:none;transform:translate(-120%)}@media(hover:hover)and (pointer:fine){.badge:hover{filter:saturate(1.12);transform:translateY(-1px)}.badge:hover:after{opacity:1;animation:terminal_scan_x .7s ease}}@media(hover:none)and (pointer:coarse){.badge:active{filter:saturate(1.12);transform:translateY(-1px)}.badge:active:after{opacity:1;animation:terminal_scan_x .7s ease}}.badge.badge-success{background:#9ece6a}.badge.badge-warning{background:#e0af68}.badge.badge-danger,.badge.badge-error{background:#f7768e}.badge.badge-info{background:#bb9af7;color:#16161e}.badge.badge-secondary{background:#7aa2f7;color:#16161e}.badge.badge-primary-outline{color:#c0caf5;border:2px solid #c0caf5;background:0 0;padding:3px 8px}.chip-group{display:flex;flex-wrap:wrap;gap:8px;align-items:center}.chip{display:inline-flex;align-items:center;gap:8px;min-height:30px;padding:5px 12px;border:2px solid rgba(192,202,245,.24);color:#a9b1d6;background:#1f2335;font-family:IBM Plex Mono,monospace;font-size:12px;font-weight:600;line-height:1;text-transform:uppercase;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background,border-color,opacity}.chip .ph,.chip .ph-bold{font-size:18px}.chip:before{content:"";display:inline-block;width:7px;height:7px;flex:0 0 auto;background:#787c99;transition-duration:.2s;transition-timing-function:ease;transition-property:background,box-shadow,transform}.chip:has(.ph):before,.chip:has(.ph-bold):before{display:none}.chip .chip-remove{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;margin-right:-5px;border:0;color:inherit;background:0 0;font:inherit;cursor:pointer}.chip .chip-remove:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}.chip.chip-primary{color:#c0caf5;background:#c0caf514;border-color:#c0caf5}.chip.chip-primary:before{background:#c0caf5}.chip.chip-secondary{color:#7aa2f7;background:#7aa2f714;border-color:#7aa2f7}.chip.chip-secondary:before{background:#7aa2f7}.chip.chip-success{color:#9ece6a;background:#9ece6a14;border-color:#9ece6a}.chip.chip-success:before{background:#9ece6a}.chip.chip-warning{color:#e0af68;background:#e0af6814;border-color:#e0af68}.chip.chip-warning:before{background:#e0af68}.chip.chip-danger,.chip.chip-error{color:#f7768e;background:#f7768e14;border-color:#f7768e}.chip.chip-danger:before,.chip.chip-error:before{background:#f7768e}.chip.chip-selected,.chip[aria-pressed=true],.chip[aria-selected=true]{color:#16161e;background:#c0caf5;border-color:#c0caf5}.chip.chip-selected:before,.chip[aria-pressed=true]:before,.chip[aria-selected=true]:before{background:#16161e}.chip.chip-secondary[aria-pressed=true],.chip.chip-secondary[aria-selected=true],.chip.chip-selected.chip-secondary{background:#7aa2f7;border-color:#7aa2f7}.chip.chip-disabled,.chip:disabled{color:#787c99;background:#1f2335;border-color:#c0caf53d;cursor:not-allowed;opacity:.7}.chip.chip-disabled:before,.chip:disabled:before{background:#414868}a.chip,button.chip{cursor:pointer}a.chip:focus-visible,button.chip:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}@media(hover:hover)and (pointer:fine){a.chip:hover,button.chip:hover{color:#c0caf5;background:#c0caf516;border-color:#7aa2f7}a.chip:hover:before,button.chip:hover:before{background:#7aa2f7;animation:terminal_pulse .7s ease;transform:scale(1.12)}}@media(hover:none)and (pointer:coarse){a.chip:active,button.chip:active{color:#c0caf5;background:#c0caf516;border-color:#7aa2f7}a.chip:active:before,button.chip:active:before{background:#7aa2f7;animation:terminal_pulse .7s ease;transform:scale(1.12)}}.tag-input{background:#1f2335;border:2px solid rgba(192,202,245,.24);position:relative}.tag-input .tag-input-wrap{display:flex;flex-wrap:wrap;align-items:center;gap:8px;padding:8px 12px;min-height:46px;cursor:text}.tag-input .tag-input-field{flex:1 1 auto;min-width:80px;padding:5px 0;border:0;color:#c0caf5;background:0 0;font-family:IBM Plex Mono,monospace;font-size:13px;line-height:1;outline:0}.tag-input .tag-input-field::-moz-placeholder{color:#787c99;opacity:1}.tag-input .tag-input-field::placeholder{color:#787c99;opacity:1}.tag-input.tag-input-focused{border-color:#c0caf5}.tag-input .tag-input-meta{padding:0 12px 8px;color:#787c99;font-size:12px;line-height:1}.avatar{position:relative;display:inline-flex;align-items:center;justify-content:center;width:46px;height:46px;flex:0 0 auto;overflow:hidden;border:2px solid rgba(192,202,245,.24);color:#16161e;background:#c0caf5;font-family:IBM Plex Mono,monospace;font-size:13px;font-weight:700;line-height:1;text-transform:uppercase}.avatar img{width:100%;height:100%;-o-object-fit:cover;object-fit:cover}.avatar .ph,.avatar .ph-bold{font-size:22px}.avatar .avatar-status{position:absolute;right:-2px;bottom:-2px;width:13px;height:13px;border:2px solid #16161e;background:#787c99;transition-duration:.2s;transition-timing-function:ease;transition-property:background,box-shadow}.avatar.avatar-sm{width:38px;height:38px;font-size:12px}.avatar.avatar-sm .ph,.avatar.avatar-sm .ph-bold{font-size:18px}.avatar.avatar-lg{width:54px;height:54px;font-size:14px}.avatar.avatar-lg .ph,.avatar.avatar-lg .ph-bold{font-size:26px}.avatar.avatar-secondary{background:#7aa2f7}.avatar.avatar-success{background:#9ece6a}.avatar.avatar-warning{background:#e0af68}.avatar.avatar-danger,.avatar.avatar-error{background:#f7768e}.avatar.avatar-outline{color:#c0caf5;background:#1f2335;border-color:#c0caf5}.avatar.is-online .avatar-status{background:#9ece6a;animation:terminal_pulse 1.8s ease infinite}.avatar.is-busy .avatar-status{background:#e0af68}.avatar.is-offline .avatar-status{background:#787c99}.identity{display:inline-flex;align-items:center;gap:12px;min-width:0}.identity-content{display:flex;flex-direction:column;gap:5px;min-width:0}.identity-title{color:#c0caf5;font-size:15px;font-weight:600;line-height:1}.identity-meta{color:#787c99;font-size:13px;line-height:1.4}.avatar-stack{display:inline-flex;align-items:center}.avatar-stack .avatar{margin-right:-8px;border-color:#16161e}.avatar-stack .avatar-stack-count{display:inline-flex;align-items:center;justify-content:center;min-width:46px;height:46px;padding:0 8px;border:2px solid #16161e;color:#16161e;background:#e0af68;font-size:13px;font-weight:700}.table{width:100%;text-align:left;border:2px solid rgba(192,202,245,.24);border-collapse:collapse;background:#1f2335}.table .table-caption{text-align:left;font-size:16px;background:#c0caf5;width:-moz-max-content;width:max-content;color:#16161e;padding:5px 12px;margin-bottom:0;font-weight:700;text-transform:uppercase}.table.table-empty{width:100%}.table.table-empty .is-empty{width:100%;padding:15px;font-size:13px;color:#787c99;text-align:left}.table .table-row td,.table .table-row th{padding:12px 18px;font-size:13px;vertical-align:middle;border-bottom:2px solid rgba(192,202,245,.08)}.table .table-row th{color:#c0caf5;background:#c0caf50a;text-transform:uppercase;letter-spacing:.04em}.table .table-head{border-bottom:2px solid #c0caf5}.table .table-body .table-row{transition-duration:.2s;transition-timing-function:ease;transition-property:background,color}.table .table-body .table-row td{transition-duration:.2s;transition-timing-function:ease;transition-property:color,background}@media(hover:hover)and (pointer:fine){.table .table-body .table-row:hover{background:#7aa2f714}.table .table-body .table-row:hover td:first-child{color:#7aa2f7}}@media(hover:none)and (pointer:coarse){.table .table-body .table-row:active{background:#7aa2f714}.table .table-body .table-row:active td:first-child{color:#7aa2f7}}.table .table-foot td,.table .table-foot th{padding-top:15px}.table.table-compact .table-caption{font-size:14px}.table.table-compact .table-row td,.table.table-compact .table-row th{padding:8px 12px;font-size:12px}.table.table-compact .table-cell-mono{color:#a9b1d6;font-family:IBM Plex Mono,monospace;letter-spacing:0}.table.table-compact .table-cell-actions{width:1%;white-space:nowrap}.table-wrapper{width:100%;overflow-x:auto}.toolbar{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px;width:100%;padding:12px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#1f2335}.toolbar .toolbar-group{display:flex;flex-wrap:wrap;align-items:center;gap:8px;min-width:0}.toolbar .toolbar-title{margin:0;font-size:16px;font-weight:700;line-height:1;text-transform:uppercase}.toolbar .toolbar-meta{color:#787c99;font-size:13px}.pagination{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.pagination .pagination-item{display:inline-flex;align-items:center;justify-content:center;min-width:38px;height:38px;padding:0 12px;border:2px solid rgba(192,202,245,.24);color:#a9b1d6;background:#1f2335;font-family:IBM Plex Mono,monospace;font-size:13px;font-weight:600;line-height:1;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background,border-color,opacity}.pagination .pagination-item:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}@media(hover:hover)and (pointer:fine){.pagination .pagination-item:hover{color:#16161e;background:#7aa2f7;border-color:#7aa2f7}}@media(hover:none)and (pointer:coarse){.pagination .pagination-item:active{color:#16161e;background:#7aa2f7;border-color:#7aa2f7}}.pagination .pagination-item.pagination-item-active,.pagination .pagination-item[aria-current=page]{color:#16161e;background:#c0caf5;border-color:#c0caf5}.pagination .pagination-item.pagination-item-disabled,.pagination .pagination-item:disabled{color:#787c99;background:#1f2335;border-color:#c0caf53d;cursor:not-allowed;opacity:.72}.pagination .pagination-ellipsis{color:#787c99;padding:0 5px}.empty-state{max-width:560px;padding:22px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#1f2335}.empty-state .empty-state-icon{display:inline-flex;align-items:center;justify-content:center;width:54px;height:54px;margin-bottom:15px;color:#16161e;background:#c0caf5;font-size:26px}.empty-state .empty-state-title{margin:0 0 8px;font-size:20px;font-weight:700;text-transform:uppercase}.empty-state .empty-state-text{max-width:440px;margin:0 0 18px;color:#a9b1d6;line-height:1.6}.empty-state .empty-state-actions{display:flex;flex-wrap:wrap;gap:8px}.empty-state.empty-state-error{border-color:#f7768e}.empty-state.empty-state-error .empty-state-icon{background:#f7768e}.skeleton{display:block;position:relative;overflow:hidden;background:#c0caf516}.skeleton:after{content:"";position:absolute;top:0;right:0;bottom:0;left:0;transform:translate(-100%);background:linear-gradient(90deg,transparent,rgba(192,202,245,.12),transparent);animation:skeleton_shimmer 1.6s infinite}.skeleton.skeleton-line{width:100%;height:14px}.skeleton.skeleton-title{width:60%;height:22px}.skeleton.skeleton-block{width:100%;height:120px}.skeleton.skeleton-square{width:54px;height:54px}.skeleton-stack{display:flex;flex-direction:column;gap:12px;max-width:520px;padding:15px;border:2px solid rgba(192,202,245,.24);background:#1f2335}@keyframes skeleton_shimmer{to{transform:translate(100%)}}.page-header{position:relative;display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;gap:18px;width:100%;padding:18px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#1f2335;overflow:hidden;animation:panel_boot .28s ease both}.page-header:after{content:"";position:absolute;top:0;left:0;width:34%;height:2px;background:linear-gradient(90deg,transparent,#7aa2f7,transparent);opacity:.72;pointer-events:none;transform:translate(-120%)}@media(hover:hover)and (pointer:fine){.page-header:hover:after{animation:terminal_scan_x .9s ease}}@media(hover:none)and (pointer:coarse){.page-header:active:after{animation:terminal_scan_x .9s ease}}.page-header .page-header-content{display:flex;flex-direction:column;gap:8px;min-width:min(100%,320px)}.page-header .page-header-kicker{color:#7aa2f7;font-size:13px;font-weight:700;line-height:1;text-transform:uppercase;transition-duration:.2s;transition-timing-function:ease;transition-property:color}.page-header .page-header-title{margin:0;color:#c0caf5;font-size:26px;font-weight:700;line-height:1.15}.page-header .page-header-subtitle{max-width:720px;margin:0;color:#a9b1d6;font-size:15px;line-height:1.6}.page-header .page-header-meta{display:flex;flex-wrap:wrap;align-items:center;gap:8px;color:#787c99;font-size:13px}.page-header .page-header-actions{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:8px}.page-header.page-header-compact{align-items:center;padding:15px}.page-header.page-header-compact .page-header-title{font-size:20px}.page-header.page-header-accent{border-color:#7aa2f7;background:#7aa2f70e}.description-list{display:grid;width:100%;max-width:760px;margin:0;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#1f2335}.description-list .description-list-row{display:grid;grid-template-columns:minmax(140px,.36fr) minmax(0,1fr);gap:15px;padding:12px 15px;border-bottom:2px solid rgba(192,202,245,.08);transition-duration:.2s;transition-timing-function:ease;transition-property:background}.description-list .description-list-row:last-child{border-bottom:0}@media(hover:hover)and (pointer:fine){.description-list .description-list-row:hover{background:#c0caf516}.description-list .description-list-row:hover .description-list-term{color:#7aa2f7}.description-list .description-list-row:hover .description-list-value{transform:translate(5px)}}@media(hover:none)and (pointer:coarse){.description-list .description-list-row:active{background:#c0caf516}.description-list .description-list-row:active .description-list-term{color:#7aa2f7}.description-list .description-list-row:active .description-list-value{transform:translate(5px)}}.description-list .description-list-term{margin:0;color:#787c99;font-size:13px;font-weight:600;line-height:1.4;text-transform:uppercase;transition-duration:.2s;transition-timing-function:ease;transition-property:color}.description-list .description-list-value{display:flex;flex-wrap:wrap;align-items:center;gap:8px;min-width:0;margin:0;color:#c0caf5;font-size:15px;line-height:1.4;transition-duration:.2s;transition-timing-function:ease;transition-property:transform}.description-list .description-list-value-muted{color:#a9b1d6}.description-list.description-list-compact{max-width:520px}.description-list.description-list-compact .description-list-row{grid-template-columns:minmax(112px,.42fr) minmax(0,1fr);gap:12px;padding:8px 12px}.description-list.description-list-compact .description-list-term,.description-list.description-list-compact .description-list-value{font-size:13px}@media(max-width:479px){.description-list .description-list-row{grid-template-columns:1fr;gap:5px}}.steps{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;width:100%;max-width:900px;margin:0;padding:0;list-style:none}.steps .step{position:relative;display:flex;flex-direction:column;gap:8px;min-height:120px;padding:15px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#1f2335}.steps .step-marker{display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;color:#c0caf5;border:2px solid rgba(192,202,245,.24);font-size:13px;font-weight:700;line-height:1}.steps .step-title{margin:0;font-size:14px;font-weight:700;line-height:1.25;text-transform:uppercase}.steps .step-text{margin:0;color:#a9b1d6;font-size:13px;line-height:1.4}.steps .step-complete{border-color:#9ece6a}.steps .step-complete .step-marker{color:#16161e;background:#9ece6a;border-color:#9ece6a}.steps .step-current{border-color:#7aa2f7}.steps .step-current .step-marker{color:#16161e;background:#7aa2f7;border-color:#7aa2f7}.steps .step-disabled{opacity:.62}.steps.steps-vertical{grid-template-columns:1fr;max-width:520px;gap:0}.steps.steps-vertical .step{min-height:auto;border-bottom-width:0}.steps.steps-vertical .step:last-child{border-bottom-width:2px}@media(max-width:1023px){.steps{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(max-width:479px){.steps{grid-template-columns:1fr}}.timeline{display:grid;gap:0;width:100%;max-width:760px;margin:0;padding:0;list-style:none}.timeline .timeline-item{position:relative;display:grid;grid-template-columns:46px minmax(0,1fr);gap:12px;min-height:88px}.timeline .timeline-item:before{content:"";position:absolute;top:46px;bottom:0;left:22px;width:2px;background:#c0caf53d}.timeline .timeline-item:last-child:before{display:none}.timeline .timeline-marker{position:relative;z-index:1;display:inline-flex;align-items:center;justify-content:center;width:46px;height:46px;border:2px solid rgba(192,202,245,.24);color:#a9b1d6;background:#16161e;font-size:18px;transition-duration:.2s;transition-timing-function:ease;transition-property:border-color,background,color,box-shadow,transform}.timeline .timeline-content{min-width:0;padding:0 0 18px}.timeline .timeline-card{padding:15px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#1f2335;transition-duration:.2s;transition-timing-function:ease;transition-property:border-color,background,transform}.timeline .timeline-header{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:8px;margin-bottom:8px}.timeline .timeline-title{margin:0;font-size:14px;font-weight:700;line-height:1.25;text-transform:uppercase}.timeline .timeline-time{color:#787c99;font-size:12px;font-family:IBM Plex Mono,monospace;line-height:1.4}.timeline .timeline-text{margin:0;color:#a9b1d6;font-size:13px;line-height:1.4}.timeline .timeline-meta{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}.timeline .timeline-item-success .timeline-card,.timeline .timeline-item-success .timeline-marker{border-color:#9ece6a}.timeline .timeline-item-success .timeline-marker{color:#16161e;background:#9ece6a}.timeline .timeline-item-warning .timeline-card,.timeline .timeline-item-warning .timeline-marker{border-color:#e0af68}.timeline .timeline-item-warning .timeline-marker{color:#16161e;background:#e0af68}.timeline .timeline-item-danger .timeline-card,.timeline .timeline-item-danger .timeline-marker,.timeline .timeline-item-error .timeline-card,.timeline .timeline-item-error .timeline-marker{border-color:#f7768e}.timeline .timeline-item-danger .timeline-marker,.timeline .timeline-item-error .timeline-marker{color:#16161e;background:#f7768e}@media(hover:hover)and (pointer:fine){.timeline .timeline-item:hover .timeline-marker{box-shadow:0 0 0 4px #7aa2f724;transform:scale(1.04)}.timeline .timeline-item:hover .timeline-card{background:#c0caf516;transform:translate(5px)}}@media(hover:none)and (pointer:coarse){.timeline .timeline-item:active .timeline-marker{box-shadow:0 0 0 4px #7aa2f724;transform:scale(1.04)}.timeline .timeline-item:active .timeline-card{background:#c0caf516;transform:translate(5px)}}.activity-log{display:grid;width:100%;max-width:720px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#1f2335}.activity-log .activity-log-row{display:grid;grid-template-columns:minmax(120px,.24fr) minmax(0,1fr) auto;gap:12px;align-items:center;padding:12px 15px;border-bottom:2px solid rgba(192,202,245,.08);transition-duration:.2s;transition-timing-function:ease;transition-property:background}.activity-log .activity-log-row:last-child{border-bottom:0}@media(hover:hover)and (pointer:fine){.activity-log .activity-log-row:hover{background:#c0caf516}}@media(hover:none)and (pointer:coarse){.activity-log .activity-log-row:active{background:#c0caf516}}.activity-log .activity-log-time{color:#787c99;font-family:IBM Plex Mono,monospace;font-size:12px}.activity-log .activity-log-title{color:#c0caf5;font-size:13px;font-weight:600;line-height:1.4}@media(max-width:479px){.activity-log .activity-log-row{grid-template-columns:1fr;gap:8px}}.accordion{display:grid;width:100%;max-width:760px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#1f2335}.accordion-item{border-bottom:2px solid rgba(192,202,245,.08);overflow:hidden}.accordion-item:last-child{border-bottom:0}.accordion-item[open] .accordion-summary{color:#16161e;background:#c0caf5}.accordion-item[open] .accordion-icon{transform:rotate(180deg)}.accordion-summary{display:flex;width:100%;align-items:center;justify-content:space-between;gap:12px;min-height:46px;padding:12px 15px;border:0;color:#c0caf5;background:0 0;cursor:pointer;font-size:13px;font-weight:700;line-height:1;text-transform:uppercase;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background}.accordion-summary::-webkit-details-marker{display:none}.accordion-summary::marker{content:""}.accordion-summary:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}@media(hover:hover)and (pointer:fine){.accordion-summary:hover{color:#16161e;background:#7aa2f7}}@media(hover:none)and (pointer:coarse){.accordion-summary:active{color:#16161e;background:#7aa2f7}}.accordion-summary-content{display:flex;align-items:center;gap:8px;min-width:0}.accordion-icon{flex:0 0 auto;font-size:18px;transition-duration:.2s;transition-property:transform}.accordion-panel{overflow:hidden;padding:15px;color:#a9b1d6;font-size:13px;line-height:1.6;transition-duration:.28s;transition-timing-function:ease;transition-property:height,opacity,transform}.accordion-panel p{margin-top:0}.accordion-panel p:last-child{margin-bottom:0}.disclosure{max-width:520px;border:2px solid rgba(192,202,245,.24);background:#1f2335}.disclosure .accordion-summary{min-height:38px;padding:8px 12px}.disclosure .accordion-panel{padding:12px}.tabs{width:100%;max-width:900px}.tabs-list{display:flex;align-items:stretch;gap:0;max-width:100%;overflow-x:auto;scrollbar-width:thin}.tab{position:relative;display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:46px;padding:12px 15px;border:0;border-right:2px solid rgba(192,202,245,.08);border-radius:0;color:#a9b1d6;background:0 0;font-family:IBM Plex Mono,monospace;font-size:13px;font-weight:700;line-height:1;text-transform:uppercase;white-space:nowrap;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background,opacity}.tab .ph,.tab .ph-bold{font-size:18px}.tab:focus-visible{outline:2px solid #E0AF68;outline-offset:3px;z-index:1}@media(hover:hover)and (pointer:fine){.tab:hover{color:#16161e;background:#7aa2f7}}@media(hover:none)and (pointer:coarse){.tab:active{color:#16161e;background:#7aa2f7}}.tab:disabled,.tab[aria-disabled=true]{color:#787c99;cursor:not-allowed;opacity:.62}@media(hover:hover)and (pointer:fine){.tab:disabled:hover,.tab[aria-disabled=true]:hover{color:#787c99;background:0 0}}@media(hover:none)and (pointer:coarse){.tab:disabled:active,.tab[aria-disabled=true]:active{color:#787c99;background:0 0}}.tab-active,.tab[aria-selected=true]{color:#16161e;background:#c0caf5}.tab-panel{display:none}.tab-panel p{margin-top:0}.tab-panel p:last-child{margin-bottom:0}.tab-panel-active{display:block}.tabs-compact{max-width:620px}.tabs-compact .tabs-list{border-left-width:2px}.tabs-compact .tab{min-height:38px;padding:8px 12px}.tabs-vertical{grid-template-columns:minmax(180px,240px) minmax(0,1fr);align-items:start}.tabs-vertical .tabs-list{flex-direction:column;overflow-x:visible}.tabs-vertical .tab{justify-content:flex-start;border-right:0;border-bottom:2px solid rgba(192,202,245,.08);text-align:left}@media(max-width:767px){.tabs-vertical{grid-template-columns:1fr}.tabs-vertical .tabs-list{flex-direction:row;overflow-x:auto}.tabs-vertical .tab{justify-content:center;border-right:2px solid rgba(192,202,245,.08);border-bottom:0;text-align:center}}.drawer{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1000;display:flex;justify-content:flex-end;pointer-events:none}.drawer .drawer-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1010;background:#16161e;opacity:0;transition-duration:.28s;transition-timing-function:ease;transition-property:opacity;pointer-events:auto}.drawer .drawer-panel{position:relative;z-index:1020;width:min(460px,100vw - 18px);min-height:100vh;display:flex;flex-direction:column;gap:15px;background:#16161e;border-left:2px solid #c0caf5;box-shadow:-18px 0 42px #16161e61;opacity:0;transform:translate(100%);transition-duration:.28s;transition-timing-function:ease;transition-property:opacity,transform;pointer-events:auto}.drawer .drawer-header{display:flex;align-items:center;justify-content:space-between;padding-right:15px;border-bottom:2px solid rgba(192,202,245,.24)}.drawer .drawer-title{margin:0;padding:12px 15px;background:#c0caf5;color:#16161e;text-transform:uppercase;letter-spacing:.04em}.drawer .drawer-body{flex:1;overflow-y:auto;padding:18px}.drawer .drawer-footer{padding:18px;border-top:2px solid rgba(192,202,245,.24)}.drawer .drawer-footer .actions{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:12px;width:100%}.drawer.drawer-left{justify-content:flex-start}.drawer.drawer-left .drawer-panel{border-left:0;border-right:2px solid #c0caf5;box-shadow:18px 0 42px #16161e61;transform:translate(-100%)}.drawer.a-show .drawer-backdrop{opacity:.82}.drawer.a-show .drawer-panel{opacity:1;transform:translate(0)}.drawer.a-hide .drawer-backdrop{opacity:0}.drawer.a-hide .drawer-panel{opacity:0;transform:translate(100%)}.drawer.a-hide.drawer-left .drawer-panel{transform:translate(-100%)}.drawer-preview{display:grid;grid-template-columns:minmax(0,1fr) minmax(180px,280px);gap:18px;align-items:stretch;padding:18px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#1f2335}.drawer-preview .drawer-preview-content{display:flex;flex-direction:column;gap:12px}.drawer-preview .drawer-preview-panel{display:flex;flex-direction:column;gap:12px;padding:15px;border:2px solid #7aa2f7;background:#1f2335}.drawer-preview .drawer-preview-title{margin:0;color:#7aa2f7;font-size:14px;text-transform:uppercase}.drawer-preview .drawer-preview-text{margin:0;color:#a9b1d6;font-size:13px;line-height:1.6}@media(max-width:720px){.drawer-preview{grid-template-columns:1fr}}.nav-topbar{position:sticky;top:0;z-index:900;display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;min-height:58px;border-bottom:2px solid rgba(192,202,245,.24);background:#16161ef5;box-shadow:0 10px 28px #16161e42}.nav-topbar-toggle{display:inline-flex;align-items:center;align-self:stretch;gap:8px;min-width:150px;padding:0 15px;border:0;border-right:2px solid rgba(192,202,245,.24);color:#c0caf5;background:#1f2335;font-family:IBM Plex Mono,monospace;font-size:13px;font-weight:700;text-transform:uppercase;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background}.nav-topbar-toggle .ph{color:#7aa2f7;font-size:22px}.nav-topbar-toggle:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}@media(hover:hover)and (pointer:fine){.nav-topbar-toggle:hover{color:#16161e;background:#7aa2f7}.nav-topbar-toggle:hover .ph{color:#16161e}}@media(hover:none)and (pointer:coarse){.nav-topbar-toggle:active{color:#16161e;background:#7aa2f7}.nav-topbar-toggle:active .ph{color:#16161e}}.nav-topbar-brand{display:inline-flex;align-items:center;gap:8px;min-width:0;padding:0 15px;color:#c0caf5;font-size:13px;font-weight:700;text-transform:uppercase}.nav-topbar-brand img{width:22px;height:22px}.nav-topbar-current{min-width:160px;margin-right:15px;padding:5px 8px;border:2px solid rgba(192,202,245,.24);color:#a9b1d6;background:#1f2335;font-size:12px;font-weight:700;text-align:center;text-transform:uppercase}.nav-drawer-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:910;background:#16161e;opacity:0;pointer-events:none;transition-duration:.28s;transition-timing-function:ease;transition-property:opacity}.nav-drawer{position:fixed;inset:0 auto 0 0;z-index:920;display:flex;flex-direction:column;width:min(380px,100vw);max-height:100vh;border-right:2px solid #c0caf5;background:#1f2335;box-shadow:18px 0 42px #16161e61;opacity:0;overflow:hidden;pointer-events:none;transform:translate(-100%);transition-duration:.28s;transition-timing-function:ease;transition-property:opacity,transform}.nav-drawer.is-open{opacity:1;pointer-events:auto;transform:translate(0)}.nav-drawer-header{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px;border-bottom:2px solid rgba(192,202,245,.24)}.nav-drawer-title{display:inline-flex;padding:8px 12px;color:#16161e;background:#c0caf5;font-size:13px;font-weight:700;text-transform:uppercase}.nav-drawer-subtitle{margin-top:8px;color:#787c99;font-size:12px;font-weight:700;text-transform:uppercase}.nav-drawer-close{display:inline-flex;align-items:center;justify-content:center;width:46px;height:46px;padding:0;border:2px solid rgba(192,202,245,.24);color:#c0caf5;background:0 0;font-size:22px;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background,border-color}.nav-drawer-close:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}@media(hover:hover)and (pointer:fine){.nav-drawer-close:hover{color:#16161e;background:#f7768e;border-color:#f7768e}}@media(hover:none)and (pointer:coarse){.nav-drawer-close:active{color:#16161e;background:#f7768e;border-color:#f7768e}}.nav-drawer-body{flex:1;overflow-y:auto;overscroll-behavior:contain;padding:12px;scrollbar-width:thin;scrollbar-color:#7AA2F7 #1F2335}.nav-drawer-body::-webkit-scrollbar{width:8px}.nav-drawer-body::-webkit-scrollbar-track{background:#1f2335}.nav-drawer-body::-webkit-scrollbar-thumb{background:#7aa2f7}.nav-drawer-body .list.list-nav{max-width:none}.nav-drawer-footer{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px;border-top:2px solid rgba(192,202,245,.24);color:#787c99;background:#1f2335;font-size:12px;font-weight:700;text-transform:uppercase}.nav-drawer-footer .profile-identity{display:block;text-decoration:none;color:inherit;min-width:0;flex:1 1 auto;overflow:hidden}@media(hover:hover)and (pointer:fine){.nav-drawer-footer .profile-identity:hover{color:inherit}}@media(hover:none)and (pointer:coarse){.nav-drawer-footer .profile-identity:active{color:inherit}}.nav-drawer-open{overflow:hidden}.nav-drawer-open .nav-drawer-backdrop{opacity:.82;pointer-events:auto}@media(max-width:767px){.nav-topbar-toggle{min-width:54px;padding:0 12px}.nav-topbar-brand{padding-right:12px;padding-left:12px}.nav-topbar-current{max-width:38vw;min-width:0;margin-right:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nav-drawer{width:100vw;border-right:0}}.nav-shell-preview{width:100%;max-width:900px;overflow:hidden;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#16161e}.nav-shell-preview-topbar{position:relative;z-index:0;min-height:52px;box-shadow:none}.nav-shell-preview-body{display:grid;grid-template-columns:280px minmax(0,1fr);min-height:320px}.nav-shell-preview-drawer{position:relative;z-index:0;inset:auto;width:auto;max-height:none;opacity:1;pointer-events:auto;transform:none;box-shadow:none}.nav-shell-preview-content{display:flex;flex-direction:column;justify-content:center;gap:12px;min-width:0;padding:18px;border-left:2px solid rgba(192,202,245,.24);background:#1f2335}.nav-shell-preview-content h3{margin:0;color:#c0caf5;font-size:20px;text-transform:uppercase}.nav-shell-preview-content p{max-width:360px;margin:0;color:#a9b1d6;font-size:13px;line-height:1.6}@media(max-width:767px){.nav-shell-preview-body{grid-template-columns:1fr}.nav-shell-preview-content{min-height:180px;border-top:2px solid rgba(192,202,245,.24);border-left:0}}.toast{position:fixed;z-index:1100;bottom:-100px;right:15px;max-width:420px;background:#1f2335;border:2px solid #c0caf5;border-left-width:6px;padding:0;opacity:0;overflow:hidden;transition-duration:.28s;transition-timing-function:ease;transition-property:opacity,bottom}.toast.a-show{bottom:15px;opacity:1}.toast.a-hide{bottom:-45px;opacity:0}.toast .toast-content{display:flex;flex-direction:column;gap:0;padding:12px 48px 12px 15px}.toast .toast-content .toast-header{display:flex;align-items:center;gap:8px;font-size:13px;font-weight:700;text-transform:uppercase;color:#c0caf5;line-height:1}.toast .toast-content .toast-header .ph{font-size:22px;flex-shrink:0}.toast .toast-content .toast-text{font-size:13px;padding:8px 0 0;margin:0;color:#a9b1d6;line-height:1.4}.toast .toast-close{position:absolute;top:5px;right:8px;color:#c0caf5;width:38px;height:38px;border-color:transparent;background:0 0}.toast .toast-progress{height:3px;width:100%;background:#16161e;overflow:hidden;margin-top:1px}.toast .toast-progress .toast-progress-bar{height:100%;width:100%;transform-origin:left;animation:toast-progress linear forwards;background:#c0caf5}.toast.toast-info{border-color:#bb9af7;background:#bb9af72e}.toast.toast-info .toast-header .ph{color:#bb9af7}.toast.toast-info .toast-progress-bar{background:#bb9af7}.toast.toast-success{border-color:#9ece6a;background:#9ece6a2e}.toast.toast-success .toast-header .ph{color:#9ece6a}.toast.toast-success .toast-progress-bar{background:#9ece6a}.toast.toast-warning{border-color:#e0af68;background:#e0af682e}.toast.toast-warning .toast-header .ph{color:#e0af68}.toast.toast-warning .toast-progress-bar{background:#e0af68}.toast.toast-danger{border-color:#f7768e;background:#f7768e2e}.toast.toast-danger .toast-header .ph{color:#f7768e}.toast.toast-danger .toast-progress-bar{background:#f7768e}@keyframes toast-progress{0%{transform:scaleX(1)}to{transform:scaleX(0)}}.card{position:relative;max-width:340px;width:-moz-max-content;width:max-content;overflow:hidden;background:#1f2335;border:2px solid #c0caf5}.card .card-title{color:#16161e;background:#c0caf5;padding:8px 12px;font-weight:700;text-transform:uppercase}.card .card-content{padding:15px;height:100%}.card .card-content .card-thumb{display:block;width:min(68%,190px);margin:18px auto 22px}.card .card-content p{margin-top:8px;margin-bottom:0}.card .card-footer{padding:8px 15px 15px}.card.status-card{max-width:220px;overflow:hidden}.card.status-card .status-icon-container{position:relative}.card.status-card .status-icon-container .status-indicator{position:absolute;top:-15px;left:-5px;font-size:22px;color:#f7768e}.card.status-card .status-icon-container .status-indicator.status-online{color:#9ece6a}.card.status-card .status-icon-container .status-icon{display:flex;flex-direction:row;align-items:center;justify-content:flex-start;font-size:56px;height:108px;width:100%}.card.status-card .card-title{display:flex;width:100%;font-size:14px;font-weight:700;align-items:center;flex-direction:row;flex-wrap:nowrap;justify-content:space-between}.card.status-card .status-name{font-size:13px;line-height:1.4}.card.status-card.card-success{border-color:#9ece6a}.card.status-card.card-success .card-title,.card.status-card.card-success .modal-title,.card.status-card.card-success .toast-title{color:#16161e;background:#9ece6a}.card.status-card.card-success .status-icon{color:#9ece6a}.card.status-card.card-warning{border-color:#e0af68}.card.status-card.card-warning .card-title,.card.status-card.card-warning .modal-title,.card.status-card.card-warning .toast-title{color:#16161e;background:#e0af68}.card.status-card.card-warning .status-icon{color:#e0af68}.card.status-card.card-info{border-color:#bb9af7}.card.status-card.card-info .card-title,.card.status-card.card-info .modal-title,.card.status-card.card-info .toast-title{color:#16161e;background:#bb9af7}.card.status-card.card-info .status-icon{color:#bb9af7}.card.status-card.card-secondary{border-color:#7aa2f7}.card.status-card.card-secondary .card-title,.card.status-card.card-secondary .modal-title,.card.status-card.card-secondary .toast-title{color:#16161e;background:#7aa2f7}.card.status-card.card-secondary .status-icon{color:#7aa2f7}.card.status-card.card-danger,.card.status-card.card-error{border-color:#f7768e}.card.status-card.card-danger .card-title,.card.status-card.card-danger .modal-title,.card.status-card.card-danger .toast-title,.card.status-card.card-error .card-title,.card.status-card.card-error .modal-title,.card.status-card.card-error .toast-title{color:#16161e;background:#f7768e}.card.status-card.card-danger .status-icon,.card.status-card.card-error .status-icon{color:#f7768e}.card.metric-card{max-width:320px;border-color:#c0caf53d}.card.metric-card .card-content{display:flex;flex-direction:column;gap:15px}.card.metric-card .metric-card-header{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.card.metric-card .metric-card-label{margin:0;color:#a9b1d6;font-size:13px;font-weight:600;text-transform:uppercase}.card.metric-card .metric-card-icon{display:inline-flex;align-items:center;justify-content:center;width:46px;height:46px;color:#16161e;background:#7aa2f7;font-size:22px}.card.metric-card .metric-card-value{margin:0;color:#c0caf5;font-size:34px;font-weight:700;line-height:1.15}.card.metric-card .metric-card-meta{display:flex;flex-wrap:wrap;align-items:center;gap:8px;color:#787c99;font-size:13px}.card.metric-card .metric-card-delta{color:#9ece6a;font-weight:700}.card.metric-card .metric-card-delta.metric-card-delta-negative{color:#f7768e}.card.card-horizontal{max-width:none;display:flex;flex-direction:row;align-items:stretch;overflow:hidden}.card.card-horizontal .card-media{flex:0 0 20%;min-width:80px;max-width:160px;max-height:160px;overflow:hidden;position:relative;aspect-ratio:1;align-self:start}.card.card-horizontal .card-media img{width:100%;height:100%;-o-object-fit:cover;object-fit:cover;display:block}.card.card-horizontal .card-body{flex:1 1 auto;display:flex;flex-direction:column;padding:15px;gap:12px}.card.card-horizontal .card-title{padding:0;background:0 0;color:#c0caf5;font-size:16px;font-weight:700;text-transform:none;line-height:1.25}.card.card-horizontal .card-title a{color:inherit;text-decoration:none}.card.card-horizontal .card-content{padding:0;height:auto}.card.card-horizontal .card-content p{margin:0}.card.card-horizontal .card-footer{padding:0;display:flex;flex-wrap:wrap;align-items:center;gap:12px;color:#a9b1d6;font-size:13px}.card.action-card{max-width:360px;border-color:#7aa2f7}.card.action-card .card-content{display:flex;flex-direction:column;gap:15px}.card.action-card .action-card-kicker{display:inline-flex;width:-moz-max-content;width:max-content;padding:5px 8px;color:#16161e;background:#7aa2f7;font-size:12px;font-weight:700;line-height:1;text-transform:uppercase}.card.action-card .action-card-title{margin:0;font-size:20px;font-weight:700;line-height:1.25;text-transform:uppercase}.card.action-card .action-card-text{margin:0;color:#a9b1d6;font-size:13px;line-height:1.6}.card.action-card .action-card-actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:8px}.card.login-card{max-width:100%;width:460px;border-color:#c0caf5}.card.login-card .login-card-header{display:flex;align-items:center;justify-content:flex-start;gap:12px;padding:12px}.card.login-card .login-card-logo{display:block;width:auto;max-height:40px}.card.login-card .login-card-logo-icon{font-size:56px;color:#c0caf5}.card.login-card .login-card-title{font-size:20px;font-weight:700;text-transform:uppercase}.card.login-card .login-card-form{display:flex;flex-direction:column;gap:15px}.card.login-card .login-card-submit{width:-moz-max-content;width:max-content;margin-top:8px}.card.login-card .form-group{margin-bottom:0}.card.login-card .login-card-links{display:flex;justify-content:space-between;gap:12px;margin-top:8px;font-size:13px}.card.login-card .login-card-link{color:#a9b1d6;text-decoration:none}@media(hover:hover)and (pointer:fine){.card.login-card .login-card-link:hover{color:#c0caf5;text-decoration:underline}}@media(hover:none)and (pointer:coarse){.card.login-card .login-card-link:active{color:#c0caf5;text-decoration:underline}}.card.login-card .login-card-error{margin-bottom:8px}.card.user-card{max-width:320px}.card.user-card .user-card-body{display:flex;flex-direction:column;align-items:center;gap:15px;padding:18px;text-align:center}.card.user-card .identity{flex-direction:column;align-items:center;gap:15px}.card.user-card .identity .avatar{width:64px;height:64px;font-size:20px}.card.user-card .identity .identity-content{align-items:center;text-align:center}.card.user-card .user-card-role{color:#a9b1d6;font-size:13px;margin-top:5px}.card.user-card .user-card-actions{display:flex;gap:8px}.card.user-card-compact{max-width:none}.card.user-card-compact .user-card-body{flex-direction:row;justify-content:space-between;align-items:center;padding:12px 15px;text-align:left}.card.user-card-compact .identity{flex-direction:row;gap:12px}.card.user-card-compact .identity .avatar{width:38px;height:38px;font-size:13px}.card.user-card-compact .identity .identity-content{align-items:flex-start}.card.user-card-compact .user-card-actions{display:flex;gap:5px}.modal{position:fixed;top:0;bottom:0;left:0;right:0;z-index:1000;display:flex;flex-direction:column;align-items:center;justify-content:center}.modal .modal-backdrop{position:fixed;z-index:1010;top:0;bottom:0;left:0;right:0;background:#16161e;opacity:0;transition-duration:.25s;transition-property:opacity}.modal .modal-dialog{position:relative;z-index:1020;width:100%;max-width:960px;margin:200px 18px 18px;height:auto;max-height:calc(100vh - 48px);padding:0;display:flex;flex-direction:column;gap:0;opacity:0;transition-duration:.28s;transition-timing-function:ease;transition-property:opacity,margin-top}.modal .modal-dialog .modal-header{display:flex;flex-direction:row;justify-content:space-between;align-items:center;gap:15px}.modal .modal-dialog .modal-header .modal-title{padding:12px 15px;background:#c0caf5;color:#16161e;text-transform:uppercase;letter-spacing:.04em}.modal .modal-dialog .modal-header .modal-close{flex:0 0 auto;color:#c0caf5;border-color:#c0caf53d;background:#16161e}.modal .modal-dialog .modal-panel{min-height:200px;display:flex;flex-direction:column;gap:15px;overflow:hidden;background:#16161e;border:2px solid #c0caf5;border-left-width:6px}.modal .modal-dialog .modal-body{max-height:700px;overflow-y:auto;padding:18px}.modal .modal-dialog .modal-footer{padding:18px}.modal .modal-dialog .modal-footer .actions{display:flex;flex-direction:row;justify-content:flex-end;gap:15px;width:100%}.modal.a-show .modal-backdrop{opacity:1}.modal.a-show .modal-dialog{opacity:1;margin-top:0}.modal.a-hide .modal-backdrop{opacity:0}.modal.a-hide .modal-dialog{opacity:0;margin-top:-200px}.alert{position:relative;overflow:hidden;margin-bottom:12px;padding:12px 15px;border:2px solid transparent;border-left-style:solid;border-left-width:6px;background:#1f2335;color:#c0caf5;font-weight:500;line-height:1.4;transition-duration:.2s;transition-timing-function:ease;transition-property:background,color,border-color}.alert:after{content:"";position:absolute;inset:0 auto 0 0;width:36%;background:linear-gradient(90deg,transparent,rgba(192,202,245,.12),transparent);opacity:0;pointer-events:none;transform:translate(-120%)}@media(hover:hover)and (pointer:fine){.alert:hover:after{opacity:1;animation:terminal_scan_x .8s ease}}@media(hover:none)and (pointer:coarse){.alert:active:after{opacity:1;animation:terminal_scan_x .8s ease}}.alert.alert-primary{border-color:#c0caf5;background:#c0caf51a;color:#c0caf5}.alert.alert-success{border-color:#9ece6a;background:#9ece6a1a;color:#9ece6a}.alert.alert-secondary{border-color:#7aa2f7;background:#7aa2f71a;color:#7aa2f7}.alert.alert-info{border-color:#bb9af7;background:#bb9af71a;color:#c0caf5}.alert.alert-warning{border-color:#e0af68;background:#e0af681a;color:#e0af68}.alert.alert-danger,.alert.alert-error{border-color:#f7768e;background:#f7768e1a;color:#f7768e}.advanced-select-container{position:relative;height:0}.advanced-select{position:absolute;z-index:100;top:6px;width:100%;height:auto;max-height:200px;overflow-y:auto;background:#16161e;border:2px solid #c0caf5;border-left-width:6px;margin-top:20px;opacity:0;visibility:hidden;transition-property:opacity,margin-top,visibility;transition-duration:.2s;transition-timing-function:ease}.advanced-select.a-show{opacity:1;margin-top:0;visibility:visible}.advanced-select .popup-options-container .not-found{width:100%;padding:15px;text-align:center;display:none}.advanced-select .popup-options-container .not-found.show{display:block}.advanced-select .popup-options-container .options{width:100%;display:none}.advanced-select .popup-options-container .options.show{display:block}.advanced-select .popup-options-container .options .option{padding:8px 15px;transition-property:color,background;transition-duration:.15s}.advanced-select .popup-options-container .options .option.hide{display:none}.advanced-select .popup-options-container .options .option.focus,.advanced-select .popup-options-container .options .option:hover{color:#16161e;background:#e0af68}.component.editable-string-component .editable-string-content{display:flex;flex-direction:row;align-items:center;gap:8px;font-size:inherit}.component.editable-string-component .editable-string-content .editable-string{font-size:inherit;border-bottom:2px solid rgba(192,202,245,.24)}@media(hover:hover)and (pointer:fine){.component.editable-string-component .apply-changes-btn:hover,.component.editable-string-component .cancel-changes-btn:hover,.component.editable-string-component .edit-text-btn:hover{color:#16161e;background:#e0af68}}@media(hover:none)and (pointer:coarse){.component.editable-string-component .apply-changes-btn:active,.component.editable-string-component .cancel-changes-btn:active,.component.editable-string-component .edit-text-btn:active{color:#16161e;background:#e0af68}}.component.editable-string-component .apply-changes-btn{color:#e0af68}.component.editable-string-component .editable-string-form{display:flex;flex-direction:row;align-items:center;gap:8px}.component.editable-string-component .editable-string-form .form-group{max-width:260px;margin:0}.component.editable-string-component .editable-string-form .form-group .input{padding:8px 15px}.tabs{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:15px}.tabs .tab{display:inline-flex;align-items:center;min-height:38px;padding:8px 12px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;color:#a9b1d6;background:#1f2335;font-family:IBM Plex Mono,monospace;font-size:13px;font-weight:600;line-height:1;text-transform:uppercase;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background,border-color}.tabs .tab:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}@media(hover:hover)and (pointer:fine){.tabs .tab:hover{color:#16161e;background:#7aa2f7;border-color:#7aa2f7}}@media(hover:none)and (pointer:coarse){.tabs .tab:active{color:#16161e;background:#7aa2f7;border-color:#7aa2f7}}.tabs .tab.tab-active,.tabs .tab[aria-selected=true]{color:#16161e;background:#c0caf5;border-color:#c0caf5}.dropdown,.popover{position:relative;display:inline-flex}.dropdown-menu,.popover-panel,.tooltip-panel{z-index:40;background:#1f2335;border:2px solid rgba(192,202,245,.24);border-left-width:6px;box-shadow:0 14px 36px #16161e5c}.dropdown-menu,.popover-panel{position:absolute;top:calc(100% + 8px);left:0;min-width:220px;display:none;transform-origin:top left}.dropdown.is-open .dropdown-menu,.popover.is-open .popover-panel{display:block;animation:overlay_reveal .2s ease both}.dropdown-menu{padding:5px}.dropdown-menu .dropdown-item{display:flex;align-items:center;gap:8px;width:100%;min-height:38px;padding:8px 12px;border:0;color:#c0caf5;background:0 0;font-family:IBM Plex Mono,monospace;font-size:13px;text-align:left;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background}.dropdown-menu .dropdown-item .ph,.dropdown-menu .dropdown-item .ph-bold{font-size:18px}.dropdown-menu .dropdown-item:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}@media(hover:hover)and (pointer:fine){.dropdown-menu .dropdown-item:hover{color:#16161e;background:#7aa2f7}}@media(hover:none)and (pointer:coarse){.dropdown-menu .dropdown-item:active{color:#16161e;background:#7aa2f7}}.dropdown-menu .dropdown-item.dropdown-item-danger{color:#f7768e}@media(hover:hover)and (pointer:fine){.dropdown-menu .dropdown-item.dropdown-item-danger:hover{color:#16161e;background:#f7768e}}@media(hover:none)and (pointer:coarse){.dropdown-menu .dropdown-item.dropdown-item-danger:active{color:#16161e;background:#f7768e}}.popover-panel{width:min(320px,100vw - 22px);padding:15px}.popover-panel .popover-title{margin:0 0 8px;font-size:14px;font-weight:700;text-transform:uppercase}.popover-panel .popover-text{margin:0;color:#a9b1d6;font-size:13px;line-height:1.6}.tooltip{position:relative;display:inline-flex}.tooltip-panel{position:absolute;left:50%;bottom:calc(100% + 8px);width:-moz-max-content;width:max-content;max-width:260px;padding:8px 12px;color:#c0caf5;font-size:12px;line-height:1.4;transform:translate(-50%);opacity:0;visibility:hidden;pointer-events:none;transition-duration:.15s;transition-timing-function:ease;transition-property:opacity,visibility}.tooltip.is-open .tooltip-panel,.tooltip:focus-within .tooltip-panel,.tooltip:hover .tooltip-panel{opacity:1;visibility:visible;animation:tooltip_reveal .15s ease both}.m-0{margin:0!important}.mt-0{margin-top:0!important}.mr-0{margin-right:0!important}.mb-0{margin-bottom:0!important}.ml-0{margin-left:0!important}.mx-0{margin-left:0!important;margin-right:0!important}.my-0{margin-top:0!important;margin-bottom:0!important}.p-0{padding:0!important}.pt-0{padding-top:0!important}.pr-0{padding-right:0!important}.pb-0{padding-bottom:0!important}.pl-0{padding-left:0!important}.px-0{padding-left:0!important;padding-right:0!important}.py-0{padding-top:0!important;padding-bottom:0!important}.g-0{gap:0!important}.gx-0{-moz-column-gap:0!important;column-gap:0!important}.gy-0{row-gap:0!important}.m-1{margin:5px!important}.mt-1{margin-top:5px!important}.mr-1{margin-right:5px!important}.mb-1{margin-bottom:5px!important}.ml-1{margin-left:5px!important}.mx-1{margin-left:5px!important;margin-right:5px!important}.my-1{margin-top:5px!important;margin-bottom:5px!important}.p-1{padding:5px!important}.pt-1{padding-top:5px!important}.pr-1{padding-right:5px!important}.pb-1{padding-bottom:5px!important}.pl-1{padding-left:5px!important}.px-1{padding-left:5px!important;padding-right:5px!important}.py-1{padding-top:5px!important;padding-bottom:5px!important}.g-1{gap:5px!important}.gx-1{-moz-column-gap:5px!important;column-gap:5px!important}.gy-1{row-gap:5px!important}.m-2{margin:8px!important}.mt-2{margin-top:8px!important}.mr-2{margin-right:8px!important}.mb-2{margin-bottom:8px!important}.ml-2{margin-left:8px!important}.mx-2{margin-left:8px!important;margin-right:8px!important}.my-2{margin-top:8px!important;margin-bottom:8px!important}.p-2{padding:8px!important}.pt-2{padding-top:8px!important}.pr-2{padding-right:8px!important}.pb-2{padding-bottom:8px!important}.pl-2{padding-left:8px!important}.px-2{padding-left:8px!important;padding-right:8px!important}.py-2{padding-top:8px!important;padding-bottom:8px!important}.g-2{gap:8px!important}.gx-2{-moz-column-gap:8px!important;column-gap:8px!important}.gy-2{row-gap:8px!important}.m-3{margin:12px!important}.mt-3{margin-top:12px!important}.mr-3{margin-right:12px!important}.mb-3{margin-bottom:12px!important}.ml-3{margin-left:12px!important}.mx-3{margin-left:12px!important;margin-right:12px!important}.my-3{margin-top:12px!important;margin-bottom:12px!important}.p-3{padding:12px!important}.pt-3{padding-top:12px!important}.pr-3{padding-right:12px!important}.pb-3{padding-bottom:12px!important}.pl-3{padding-left:12px!important}.px-3{padding-left:12px!important;padding-right:12px!important}.py-3{padding-top:12px!important;padding-bottom:12px!important}.g-3{gap:12px!important}.gx-3{-moz-column-gap:12px!important;column-gap:12px!important}.gy-3{row-gap:12px!important}.m-4{margin:15px!important}.mt-4{margin-top:15px!important}.mr-4{margin-right:15px!important}.mb-4{margin-bottom:15px!important}.ml-4{margin-left:15px!important}.mx-4{margin-left:15px!important;margin-right:15px!important}.my-4{margin-top:15px!important;margin-bottom:15px!important}.p-4{padding:15px!important}.pt-4{padding-top:15px!important}.pr-4{padding-right:15px!important}.pb-4{padding-bottom:15px!important}.pl-4{padding-left:15px!important}.px-4{padding-left:15px!important;padding-right:15px!important}.py-4{padding-top:15px!important;padding-bottom:15px!important}.g-4{gap:15px!important}.gx-4{-moz-column-gap:15px!important;column-gap:15px!important}.gy-4{row-gap:15px!important}.m-5{margin:18px!important}.mt-5{margin-top:18px!important}.mr-5{margin-right:18px!important}.mb-5{margin-bottom:18px!important}.ml-5{margin-left:18px!important}.mx-5{margin-left:18px!important;margin-right:18px!important}.my-5{margin-top:18px!important;margin-bottom:18px!important}.p-5{padding:18px!important}.pt-5{padding-top:18px!important}.pr-5{padding-right:18px!important}.pb-5{padding-bottom:18px!important}.pl-5{padding-left:18px!important}.px-5{padding-left:18px!important;padding-right:18px!important}.py-5{padding-top:18px!important;padding-bottom:18px!important}.g-5{gap:18px!important}.gx-5{-moz-column-gap:18px!important;column-gap:18px!important}.gy-5{row-gap:18px!important}.m-6{margin:22px!important}.mt-6{margin-top:22px!important}.mr-6{margin-right:22px!important}.mb-6{margin-bottom:22px!important}.ml-6{margin-left:22px!important}.mx-6{margin-left:22px!important;margin-right:22px!important}.my-6{margin-top:22px!important;margin-bottom:22px!important}.p-6{padding:22px!important}.pt-6{padding-top:22px!important}.pr-6{padding-right:22px!important}.pb-6{padding-bottom:22px!important}.pl-6{padding-left:22px!important}.px-6{padding-left:22px!important;padding-right:22px!important}.py-6{padding-top:22px!important;padding-bottom:22px!important}.g-6{gap:22px!important}.gx-6{-moz-column-gap:22px!important;column-gap:22px!important}.gy-6{row-gap:22px!important}.m-7{margin:26px!important}.mt-7{margin-top:26px!important}.mr-7{margin-right:26px!important}.mb-7{margin-bottom:26px!important}.ml-7{margin-left:26px!important}.mx-7{margin-left:26px!important;margin-right:26px!important}.my-7{margin-top:26px!important;margin-bottom:26px!important}.p-7{padding:26px!important}.pt-7{padding-top:26px!important}.pr-7{padding-right:26px!important}.pb-7{padding-bottom:26px!important}.pl-7{padding-left:26px!important}.px-7{padding-left:26px!important;padding-right:26px!important}.py-7{padding-top:26px!important;padding-bottom:26px!important}.g-7{gap:26px!important}.gx-7{-moz-column-gap:26px!important;column-gap:26px!important}.gy-7{row-gap:26px!important}.m-8{margin:34px!important}.mt-8{margin-top:34px!important}.mr-8{margin-right:34px!important}.mb-8{margin-bottom:34px!important}.ml-8{margin-left:34px!important}.mx-8{margin-left:34px!important;margin-right:34px!important}.my-8{margin-top:34px!important;margin-bottom:34px!important}.p-8{padding:34px!important}.pt-8{padding-top:34px!important}.pr-8{padding-right:34px!important}.pb-8{padding-bottom:34px!important}.pl-8{padding-left:34px!important}.px-8{padding-left:34px!important;padding-right:34px!important}.py-8{padding-top:34px!important;padding-bottom:34px!important}.g-8{gap:34px!important}.gx-8{-moz-column-gap:34px!important;column-gap:34px!important}.gy-8{row-gap:34px!important}.m-9{margin:42px!important}.mt-9{margin-top:42px!important}.mr-9{margin-right:42px!important}.mb-9{margin-bottom:42px!important}.ml-9{margin-left:42px!important}.mx-9{margin-left:42px!important;margin-right:42px!important}.my-9{margin-top:42px!important;margin-bottom:42px!important}.p-9{padding:42px!important}.pt-9{padding-top:42px!important}.pr-9{padding-right:42px!important}.pb-9{padding-bottom:42px!important}.pl-9{padding-left:42px!important}.px-9{padding-left:42px!important;padding-right:42px!important}.py-9{padding-top:42px!important;padding-bottom:42px!important}.g-9{gap:42px!important}.gx-9{-moz-column-gap:42px!important;column-gap:42px!important}.gy-9{row-gap:42px!important}.m-10{margin:48px!important}.mt-10{margin-top:48px!important}.mr-10{margin-right:48px!important}.mb-10{margin-bottom:48px!important}.ml-10{margin-left:48px!important}.mx-10{margin-left:48px!important;margin-right:48px!important}.my-10{margin-top:48px!important;margin-bottom:48px!important}.p-10{padding:48px!important}.pt-10{padding-top:48px!important}.pr-10{padding-right:48px!important}.pb-10{padding-bottom:48px!important}.pl-10{padding-left:48px!important}.px-10{padding-left:48px!important;padding-right:48px!important}.py-10{padding-top:48px!important;padding-bottom:48px!important}.g-10{gap:48px!important}.gx-10{-moz-column-gap:48px!important;column-gap:48px!important}.gy-10{row-gap:48px!important}.m-11{margin:64px!important}.mt-11{margin-top:64px!important}.mr-11{margin-right:64px!important}.mb-11{margin-bottom:64px!important}.ml-11{margin-left:64px!important}.mx-11{margin-left:64px!important;margin-right:64px!important}.my-11{margin-top:64px!important;margin-bottom:64px!important}.p-11{padding:64px!important}.pt-11{padding-top:64px!important}.pr-11{padding-right:64px!important}.pb-11{padding-bottom:64px!important}.pl-11{padding-left:64px!important}.px-11{padding-left:64px!important;padding-right:64px!important}.py-11{padding-top:64px!important;padding-bottom:64px!important}.g-11{gap:64px!important}.gx-11{-moz-column-gap:64px!important;column-gap:64px!important}.gy-11{row-gap:64px!important}.m-12{margin:80px!important}.mt-12{margin-top:80px!important}.mr-12{margin-right:80px!important}.mb-12{margin-bottom:80px!important}.ml-12{margin-left:80px!important}.mx-12{margin-left:80px!important;margin-right:80px!important}.my-12{margin-top:80px!important;margin-bottom:80px!important}.p-12{padding:80px!important}.pt-12{padding-top:80px!important}.pr-12{padding-right:80px!important}.pb-12{padding-bottom:80px!important}.pl-12{padding-left:80px!important}.px-12{padding-left:80px!important;padding-right:80px!important}.py-12{padding-top:80px!important;padding-bottom:80px!important}.g-12{gap:80px!important}.gx-12{-moz-column-gap:80px!important;column-gap:80px!important}.gy-12{row-gap:80px!important}.row{display:flex;flex-direction:row}@media(max-width:1279px){.row.adaptive{flex-direction:column}}.column{display:flex;flex-direction:column}.f-grid{display:flex;flex-direction:row;flex-wrap:wrap}.grid{display:grid}.grid-2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr))}.grid-3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr))}.items-start{align-items:flex-start!important}.items-center{align-items:center!important}.items-end{align-items:flex-end!important}.justify-start{justify-content:flex-start!important}.justify-center{justify-content:center!important}.justify-between{justify-content:space-between!important}.justify-end{justify-content:flex-end!important}.w-100{width:100%}.w-auto{width:auto!important}.w-fit{width:-moz-fit-content!important;width:fit-content!important}.w-200{width:200%}.h-100{height:100%}.min-w-0{min-width:0!important}.overflow-hidden{overflow:hidden!important}.overflow-auto{overflow:auto!important}.fs-xs{font-size:12px}.fs-sm{font-size:13px}.fs-md{font-size:14px}.fs-base{font-size:15px}.fs-lg{font-size:16px}.fs-xl{font-size:20px}.text-left{text-align:left!important}.text-center{text-align:center!important}.text-right{text-align:right!important}.text-uppercase{text-transform:uppercase!important}.text-nowrap{white-space:nowrap!important}.d-none{display:none!important}.d-block{display:block!important}.d-inline-flex{display:inline-flex!important}.d-flex{display:flex!important}.d-grid{display:grid!important}@media(max-width:767px){.grid-2,.grid-3{grid-template-columns:1fr}}*{box-sizing:border-box}body,html{padding:0;margin:0}body{background-color:#16161e;color:#c0caf5}::-webkit-scrollbar{width:10px}::-webkit-scrollbar-track{width:10px;background:#16161e;cursor:pointer}::-webkit-scrollbar-thumb{width:10px;background:#414868;cursor:default}::-webkit-scrollbar-corner{background:0 0;height:1px}::-webkit-scrollbar-button{display:none}.ph.normalize{position:relative;top:.15em}code[class*=language-],pre[class*=language-]{color:#000;background:none;text-shadow:0 1px white;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,code[class*=language-] ::-moz-selection{text-shadow:none;background:#b3d4fc}pre[class*=language-]::selection,pre[class*=language-] ::selection,code[class*=language-]::selection,code[class*=language-] ::selection{text-shadow:none;background:#b3d4fc}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#f5f2f0}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.comment,.token.prolog,.token.doctype,.token.cdata{color:#708090}.token.punctuation{color:#999}.token.property,.token.tag,.token.boolean,.token.number,.token.constant,.token.symbol,.token.deleted{color:#905}.token.selector,.token.attr-name,.token.string,.token.char,.token.builtin,.token.inserted{color:#690}.token.operator,.token.entity,.token.url,.language-css .token.string,.style .token.string{color:#9a6e3a;background:#ffffff80}.token.atrule,.token.attr-value,.token.keyword{color:#07a}.token.function,.token.class-name{color:#dd4a68}.token.regex,.token.important,.token.variable{color:#e90}pre[class*=language-],code[class*=language-]{color:#c0caf5;background:none;font-family:IBM Plex Mono,Courier New,monospace;font-size:12px;line-height:1.6;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;-moz-tab-size:2;tab-size:2;-webkit-hyphens:none;hyphens:none}pre[class*=language-]{padding:14px;margin:0;overflow:auto;background:#11131a;border:1px solid rgba(192,202,245,.12)}.token.comment,.token.prolog,.token.doctype,.token.cdata{color:#565f89}.token.punctuation{color:#7aa2f7}.token.namespace{opacity:.7}.token.property,.token.tag,.token.boolean,.token.number,.token.constant,.token.symbol,.token.deleted{color:#ff9e64}.token.selector,.token.attr-name,.token.string,.token.char,.token.builtin,.token.inserted{color:#9ece6a}.token.operator,.token.entity,.token.url,.language-css .token.string,.style .token.string{color:#89ddff;background:none}.token.atrule,.token.attr-value,.token.keyword{color:#bb9af7}.token.function,.token.class-name{color:#0db9d7}.token.regex,.token.important,.token.variable{color:#e0af68}.token.important,.token.bold{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}:root{color-scheme:dark;font-family:IBM Plex Mono,Courier New,monospace;background:#07080b;color:#f4f4f5;--color-bg: #07080b;--color-panel: #11131a;--color-panel-strong: #171a24;--color-text: #f4f4f5;--color-muted: #9ca3af;--color-primary: #12b7f5;--color-accent: #00f5a0;--color-warning: #ffe500;--color-danger: #ff3d00;--border: 1px solid #f4f4f5}*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}html,body{overscroll-behavior-y:none;-webkit-overflow-scrolling:touch}body{margin:0;min-width:320px;min-height:100vh;background:radial-gradient(circle at 20% 0%,rgba(18,183,245,.12),transparent 30%),var(--color-bg)}a{color:inherit}button,input,textarea{font:inherit}.page{width:min(1200px,100%);margin:0 auto;padding:36px 14px}.page .page-header{margin-bottom:24px;animation:none}.page .page-header:after,.page .page-header:hover:after{display:none}.area-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:16px;align-items:stretch}.area-grid .card{width:100%;max-width:none;display:flex;flex-direction:column}.area-grid .card .card-content{flex:1;display:flex;flex-direction:column;gap:12px}.area-grid .card .card-footer{margin-top:auto}.area-grid .card-content p,.area-grid .card-content .text{margin-bottom:0}.area-tree,.area-tree-children{display:grid;gap:12px;margin:0;padding:0;list-style:none}.area-tree-children{margin-top:12px;padding-left:28px}.area-tree-card{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:14px;padding:14px;border:var(--border);background:var(--color-panel);cursor:pointer}.area-tree-card:hover{background:var(--color-panel-strong)}.tree-toggle{width:36px;height:36px;border:2px solid currentColor;background:transparent;cursor:pointer;font-weight:800}.tree-toggle:disabled{cursor:default}.area-tree-info h2{margin:0 0 8px;font-size:20px}.area-tree-info p,.area-tree-actions{display:flex;flex-wrap:wrap;gap:8px;margin:0}.devices-panel{display:grid;gap:16px}.devices-summary,.devices-actions{display:flex;flex-wrap:wrap;gap:8px}.modal-footer{display:flex;justify-content:flex-end;gap:12px}.nav-drawer-footer .card.user-card-compact{border:0;width:100%}.nav-drawer-footer .card.user-card-compact .user-card-body{padding:0}.toast.toast-info,.toast.toast-success,.toast.toast-warning,.toast.toast-danger{background:var(--color-panel-strong)}@media(max-width:720px){.area-tree-card{grid-template-columns:1fr}.area-tree-children{padding-left:14px}} diff --git a/server/dist/assets/web-BPiyNEQ1.js b/server/dist/assets/web-BPiyNEQ1.js new file mode 100644 index 0000000..9396814 --- /dev/null +++ b/server/dist/assets/web-BPiyNEQ1.js @@ -0,0 +1 @@ +import{W as p}from"./index-C4kiMKve.js";class f extends p{constructor(){super(...arguments),this.group="CapacitorStorage"}async configure({group:e}){typeof e=="string"&&(this.group=e)}async get(e){return{value:this.impl.getItem(this.applyPrefix(e.key))}}async set(e){this.impl.setItem(this.applyPrefix(e.key),e.value)}async remove(e){this.impl.removeItem(this.applyPrefix(e.key))}async keys(){return{keys:this.rawKeys().map(t=>t.substring(this.prefix.length))}}async clear(){for(const e of this.rawKeys())this.impl.removeItem(e)}async migrate(){var e;const t=[],s=[],n="_cap_",o=Object.keys(this.impl).filter(i=>i.indexOf(n)===0);for(const i of o){const r=i.substring(n.length),a=(e=this.impl.getItem(i))!==null&&e!==void 0?e:"",{value:l}=await this.get({key:r});typeof l=="string"?s.push(r):(await this.set({key:r,value:a}),t.push(r))}return{migrated:t,existing:s}}async removeOld(){const e="_cap_",t=Object.keys(this.impl).filter(s=>s.indexOf(e)===0);for(const s of t)this.impl.removeItem(s)}get impl(){return window.localStorage}get prefix(){return this.group==="NativeStorage"?"":`${this.group}.`}rawKeys(){return Object.keys(this.impl).filter(e=>e.indexOf(this.prefix)===0)}applyPrefix(e){return this.prefix+e}}export{f as PreferencesWeb}; diff --git a/server/dist/assets/web-DxttIM6a.js b/server/dist/assets/web-DxttIM6a.js deleted file mode 100644 index 82539a9..0000000 --- a/server/dist/assets/web-DxttIM6a.js +++ /dev/null @@ -1 +0,0 @@ -import{W as p}from"./index-BxlltLEk.js";class f extends p{constructor(){super(...arguments),this.group="CapacitorStorage"}async configure({group:e}){typeof e=="string"&&(this.group=e)}async get(e){return{value:this.impl.getItem(this.applyPrefix(e.key))}}async set(e){this.impl.setItem(this.applyPrefix(e.key),e.value)}async remove(e){this.impl.removeItem(this.applyPrefix(e.key))}async keys(){return{keys:this.rawKeys().map(t=>t.substring(this.prefix.length))}}async clear(){for(const e of this.rawKeys())this.impl.removeItem(e)}async migrate(){var e;const t=[],s=[],n="_cap_",o=Object.keys(this.impl).filter(i=>i.indexOf(n)===0);for(const i of o){const r=i.substring(n.length),a=(e=this.impl.getItem(i))!==null&&e!==void 0?e:"",{value:l}=await this.get({key:r});typeof l=="string"?s.push(r):(await this.set({key:r,value:a}),t.push(r))}return{migrated:t,existing:s}}async removeOld(){const e="_cap_",t=Object.keys(this.impl).filter(s=>s.indexOf(e)===0);for(const s of t)this.impl.removeItem(s)}get impl(){return window.localStorage}get prefix(){return this.group==="NativeStorage"?"":`${this.group}.`}rawKeys(){return Object.keys(this.impl).filter(e=>e.indexOf(this.prefix)===0)}applyPrefix(e){return this.prefix+e}}export{f as PreferencesWeb}; diff --git a/server/dist/assets/web-Gt69b7cr.js b/server/dist/assets/web-Gt69b7cr.js new file mode 100644 index 0000000..3cc3681 --- /dev/null +++ b/server/dist/assets/web-Gt69b7cr.js @@ -0,0 +1 @@ +import{W as t}from"./index-C4kiMKve.js";class s extends t{constructor(){super(),this.handleVisibilityChange=()=>{const e={isActive:document.hidden!==!0};this.notifyListeners("appStateChange",e),document.hidden?this.notifyListeners("pause",null):this.notifyListeners("resume",null)},document.addEventListener("visibilitychange",this.handleVisibilityChange,!1)}exitApp(){throw this.unimplemented("Not implemented on web.")}async getInfo(){throw this.unimplemented("Not implemented on web.")}async getLaunchUrl(){return{url:""}}async getState(){return{isActive:document.hidden!==!0}}async minimizeApp(){throw this.unimplemented("Not implemented on web.")}async toggleBackButtonHandler(){throw this.unimplemented("Not implemented on web.")}async getAppLanguage(){return{value:navigator.language.split("-")[0].toLowerCase()}}}export{s as AppWeb}; diff --git a/server/dist/assets/web-f7iCgAY0.js b/server/dist/assets/web-f7iCgAY0.js deleted file mode 100644 index f599719..0000000 --- a/server/dist/assets/web-f7iCgAY0.js +++ /dev/null @@ -1 +0,0 @@ -import{W as t}from"./index-BxlltLEk.js";class s extends t{constructor(){super(),this.handleVisibilityChange=()=>{const e={isActive:document.hidden!==!0};this.notifyListeners("appStateChange",e),document.hidden?this.notifyListeners("pause",null):this.notifyListeners("resume",null)},document.addEventListener("visibilitychange",this.handleVisibilityChange,!1)}exitApp(){throw this.unimplemented("Not implemented on web.")}async getInfo(){throw this.unimplemented("Not implemented on web.")}async getLaunchUrl(){return{url:""}}async getState(){return{isActive:document.hidden!==!0}}async minimizeApp(){throw this.unimplemented("Not implemented on web.")}async toggleBackButtonHandler(){throw this.unimplemented("Not implemented on web.")}async getAppLanguage(){return{value:navigator.language.split("-")[0].toLowerCase()}}}export{s as AppWeb}; diff --git a/server/dist/index.html b/server/dist/index.html index d84e099..431a2ed 100644 --- a/server/dist/index.html +++ b/server/dist/index.html @@ -12,8 +12,8 @@ - - + +
diff --git a/server/plan.md b/server/plan.md new file mode 100644 index 0000000..2bcd71e --- /dev/null +++ b/server/plan.md @@ -0,0 +1,204 @@ + +# План: Params Schema для Action Scripts + +## Цель +Scope-классы могут декларировать JSON-схему параметров при регистрации action-скрипта. Vue-клиент отображает динамическую форму в модалке вместо пустого `{}` при запуске. Сервер валидирует входящие параметры по схеме перед вызовом closure. + +## Дизайн (утверждён) + +**Формат в PHP Scope:** +```php +$this->add_action_script([ + "alias" => "dim_lights", + "name" => "Диммер", + "params_schema" => [ + "level" => [ + "type" => "range", + "label" => "Яркость, %", + "min" => 0, + "max" => 100, + "step" => 5, + "default" => 50, + "required" => true, + ], + "room" => [ + "type" => "select", + "label" => "Комната", + "options" => ["kitchen" => "Кухня", "hall" => "Зал"], + "default" => "hall", + ], + "instant" => [ + "type" => "toggle", + "label" => "Мгновенно", + "default" => false, + ], + ], +], function($params) { ... }); +``` + +**Типы:** `text`, `number`, `range`, `select`, `toggle`, `textarea`. +**Валидация PHP:** тип, `required`, `min/max` для `number`/`range`, ключ в `options` для `select`. +**UI:** модал `GnModal` с динамической формой; `GnInput`, `GnRange`, `GnSelect`, `GnSwitch`, `GnTextarea`. + +--- + +## Фаза 1 — PHP backend + +### 1.1 Миграция +**Файл:** `server/database/migrations/2026_06_08_000003_script_params_schema.php` +- `ALTER TABLE scripts ADD COLUMN params_schema TEXT NULL` + +### 1.2 Entity `Script` +**Файл:** `server/SHServ/Entities/Script.php` +- Добавить `"params_schema"` в `$fields` + +### 1.3 Model `Scripts` — синхронизация и мерж +**Файл:** `server/SHServ/Models/Scripts.php` +- `prepare_script_to_view()` — мержить `params_schema` из DB entity в ответ (если есть) +- Новый приватный метод `sync_params_schema_to_db($type, $uniq_name, $schema)`: + - Если запись в БД существует и `params_schema` отличается от registry — `UPDATE` + - Вызывать из `get_scripts_list()` при подготовке к view (lazy sync) +- Новый метод `get_params_schema($type, $uniq_name): ?array` — декодировать JSON из БД + +### 1.4 `ControlScripts::add_action_script()` +**Файл:** `server/SHServ/Middleware/ControlScripts.php` +- Принимать `"params_schema"` из `$attributes` +- Сохранять в `ScriptsRegistry::$actions[$alias]["params_schema"]` +- `add_regular_script()` пока без изменений (можно заложить, но action — MVP) + +### 1.5 `ScriptsRegistry` +**Файл:** `server/SHServ/Middleware/ScriptsRegistry.php` +- Entry теперь: `["attributes", "code", "script", "params_schema"]` + +### 1.6 Валидация params по schema +**Новый файл:** `server/SHServ/Helpers/ScriptParamsValidator.php` +- Метод `validate($schema, $params): array` — возвращает `["ok" => bool, "errors" => [...]]` +- Проверки по типам: + - `required` — поле присутствует в `$params` + - `select` — значение ∈ keys `options` + - `number`/`range` — `is_numeric`, в границах `min/max` + - `toggle` — `is_bool` + - `text`/`textarea` — `is_string` + +### 1.7 `ScriptsRESTAPIController::run_action_script()` +**Файл:** `server/SHServ/Controllers/ScriptsRESTAPIController.php` +- После проверки alias и state, перед вызовом `ControlScripts::run_action_script()`: + 1. Получить schema из `ScriptsRegistry::$actions[$alias]["params_schema"]` или из БД + 2. Если schema не null — валидировать `$params` через `ScriptParamsValidator` + 3. Если ошибка — ответ `invalid_params` с `failed_fields` + 4. Применить `default` для отсутствующих необязательных полей + 5. Затем вызвать `ControlScripts::run_action_script($alias, $params)` + +### 1.8 `ScriptsRESTAPIController::actions_scripts_list()` +- Убедиться что `params_schema` присутствует в ответе (через `prepare_script_to_view`) + +--- + +## Фаза 2 — Vue frontend + +### 2.1 API module (без изменений) +`scriptsApi.runAction(alias, params)` уже поддерживает params — достаточно. + +### 2.2 Store (минимальные изменения) +**Файл:** `webclient/src/stores/scripts.js` +- `runScript(alias, params)` уже принимает params +- Добавить state `runModalScript: null` — текущий скрипт для модалки (или управлять через emit) + +### 2.3 Новый компонент `ScriptRunModal.vue` +**Файл:** `webclient/src/components/script/ScriptRunModal.vue` +- Props: `script` (alias, name, params_schema) +- `GnModal :open` + `@update:open` +- Внутри: динамическая форма: + - `v-for="(config, name) in script.params_schema" :key="name"` + - Маппинг `type` → компонент: + - `text` → `GnInput type="text"` + - `number` → `GnInput type="number"` + - `range` → `GnRange` (`min`, `max`, `step`) + - `select` → `GnSelect` (`:options` — массив `{value, label}` из `Object.entries(config.options)`) + - `toggle` → `GnSwitch` + - `textarea` → `GnTextarea` + - `v-model` на реактивный объект `formValues[name]` + - Инициализация `formValues` значениями `default` из schema + - Валидация клиента: `required` → красная рамка/сообщение, `GnInput`/`GnRange` props +- Footer: `Run` (disabled если есть required-ошибки) + `Cancel` +- При submit: `$emit('run', { alias: script.alias, params: formValues })` + +### 2.4 `ActionScriptsGrid.vue` +**Файл:** `webclient/src/components/script/ActionScriptsGrid.vue` +- Метод `run(alias)` заменить на: + ```js + function run(script) { + if (!script.params_schema || Object.keys(script.params_schema).length === 0) { + executeRun(script.alias, {}); + return; + } + activeScriptForModal.value = script; + showRunModal.value = true; + } + ``` +- Добавить `` +- `onModalRun({ alias, params })` → `executeRun(alias, params)` + +### 2.5 `ScriptDetailPage.vue` +**Файл:** `webclient/src/features/scripts/pages/ScriptDetailPage.vue` +- Аналогично: если action script имеет `params_schema`, Run открывает модал вместо прямого вызова + +--- + +## Фаза 3 — Тесты + +### 3.1 PHP tests +**Новый файл:** `server/tests/ScriptParamsValidatorTest.php` +- Проверка валидации по каждому типу (valid / invalid) +- Проверка `required` и `default` +- Проверка edge cases (null, пустая строка) + +**Файл:** `server/tests/ScriptsModelStateTest.php` или новый `ScriptParamsSchemaTest.php` +- Проверка что `prepare_script_to_view` возвращает `params_schema` +- Проверка lazy sync в DB + +### 3.2 Vue tests +**Новый файл:** `webclient/src/components/script/__tests__/ScriptRunModal.spec.js` +- Рендеринг полей по schema +- Валидация required +- Событие submit с правильными params + +--- + +## Фаза 4 — Документация + +### 4.1 `docs/control-scripts-guide.md` +- Обновить раздел "Action-скрипты": добавить `params_schema` в пример +- Добавить подраздел "Params Schema" с таблицей типов и их полей + +### 4.2 `docs/server-api-v1/scripts.md` +- В `GET /api/v1/scripts/actions/list` — добавить `params_schema` в пример ответа +- В `POST /api/v1/scripts/actions/run` — добавить пример с `params` и ошибку `invalid_params` + +--- + +## Критические файлы + +| Файл | Действие | +|------|----------| +| `server/database/migrations/2026_06_08_000003_script_params_schema.php` | Создать | +| `server/SHServ/Entities/Script.php` | Добавить поле | +| `server/SHServ/Models/Scripts.php` | Lazy sync + merge | +| `server/SHServ/Middleware/ControlScripts.php` | Принимать params_schema | +| `server/SHServ/Middleware/ScriptsRegistry.php` | Хранить params_schema | +| `server/SHServ/Helpers/ScriptParamsValidator.php` | Создать | +| `server/SHServ/Controllers/ScriptsRESTAPIController.php` | Валидация при run | +| `webclient/src/components/script/ScriptRunModal.vue` | Создать | +| `webclient/src/components/script/ActionScriptsGrid.vue` | Открывать модал | +| `webclient/src/features/scripts/pages/ScriptDetailPage.vue` | Открывать модал | + +## Риски + +- **Lazy sync side-effect:** `get_scripts_list()` делает UPDATE. Альтернатива: синхронизировать при старте сервера в `ControlScripts::add_action_script()` через `Scripts::set_script_state()` (который уже делает INSERT/UPDATE), но туда нужно добавить `params_schema`. Это чище. Решение: обновить `set_script_state()` чтобы при INSERT/UPDATE сохранять `params_schema` из registry. +- **Каскад миграции:** `params_schema TEXT NULL` совместимо с существующими данными. +- **Vue компонент не в kit:** создаём свой `ScriptRunModal.vue` на базе `GnModal` и kit-инпутов. + +## Решение по lazy sync +Вместо lazy sync в read-методе — обновить `Scripts::set_script_state()`. Когда `add_action_script()` вызывается при старте, `ControlScripts` может вызвать `set_script_state("action", $alias, true)` (или новый метод) для записи `params_schema` в БД. Но `set_script_state()` сейчас вызывается только через API enable/disable. + +Наиболее чистый путь: в `Scripts::get_scripts_list()` при наличии `$script_entity` сравнивать `params_schema` и делать `thin_builder->update()` если отличается. Это один UPDATE на рестарт, приемлемо. diff --git a/server/tests/AreaRecursionTest.php b/server/tests/AreaRecursionTest.php index d2ee80f..bcf9ae6 100644 --- a/server/tests/AreaRecursionTest.php +++ b/server/tests/AreaRecursionTest.php @@ -44,6 +44,7 @@ uniq_name TEXT, type TEXT, state TEXT, + params_schema TEXT, create_at TEXT, update_at TEXT )"); diff --git a/server/tests/ControlScriptsRegularTest.php b/server/tests/ControlScriptsRegularTest.php index 98d551a..687386c 100644 --- a/server/tests/ControlScriptsRegularTest.php +++ b/server/tests/ControlScriptsRegularTest.php @@ -14,9 +14,13 @@ uniq_name TEXT, type TEXT, state TEXT, + params_schema TEXT, create_at TEXT, update_at TEXT )"); + if(!isset(app() -> scripts_registry)) { + app() -> scripts_registry = new \SHServ\Middleware\ScriptsRegistry(); + } ControlScripts::flush_statics(); } @@ -30,16 +34,11 @@ } public function test_run_regular_script_returns_false_when_disabled(): void { - $ref = new \ReflectionClass(ControlScripts::class); - $prop = $ref -> getProperty('regular_scripts'); - $prop -> setAccessible(true); - $prop -> setValue(null, [ - 'disabled' => [ - 'attributes' => ['alias' => 'disabled'], - 'code' => '', - 'script' => function() {} - ] - ]); + app() -> scripts_registry -> regular['disabled'] = [ + 'attributes' => ['alias' => 'disabled'], + 'code' => '', + 'script' => function() {} + ]; $this -> tb -> insert('scripts', [ 'uniq_name' => 'disabled', @@ -52,16 +51,11 @@ } public function test_run_regular_script_catches_exception(): void { - $ref = new \ReflectionClass(ControlScripts::class); - $prop = $ref -> getProperty('regular_scripts'); - $prop -> setAccessible(true); - $prop -> setValue(null, [ - 'fail' => [ - 'attributes' => ['alias' => 'fail'], - 'code' => '', - 'script' => function() { throw new \Exception('boom'); } - ] - ]); + app() -> scripts_registry -> regular['fail'] = [ + 'attributes' => ['alias' => 'fail'], + 'code' => '', + 'script' => function() { throw new \Exception('boom'); } + ]; $this -> tb -> insert('scripts', [ 'uniq_name' => 'fail', @@ -74,16 +68,11 @@ } public function test_run_regular_script_returns_true_on_success(): void { - $ref = new \ReflectionClass(ControlScripts::class); - $prop = $ref -> getProperty('regular_scripts'); - $prop -> setAccessible(true); - $prop -> setValue(null, [ - 'ok' => [ - 'attributes' => ['alias' => 'ok'], - 'code' => '', - 'script' => function() { return true; } - ] - ]); + app() -> scripts_registry -> regular['ok'] = [ + 'attributes' => ['alias' => 'ok'], + 'code' => '', + 'script' => function() { return true; } + ]; $this -> tb -> insert('scripts', [ 'uniq_name' => 'ok', diff --git a/server/tests/CronControllerTest.php b/server/tests/CronControllerTest.php index 08da8d8..4020e86 100644 --- a/server/tests/CronControllerTest.php +++ b/server/tests/CronControllerTest.php @@ -13,15 +13,8 @@ } class TestableCronController extends CronController { - public $cliCalls = []; - public $returnCodes = []; public $mockScannerResults = []; - protected function run_script_cli(String $alias): int { - $this -> cliCalls[] = $alias; - return $this -> returnCodes[$alias] ?? 0; - } - protected function createDeviceScanner(): DeviceScanner { $scanner = new TestableDeviceScanner(); $scanner -> mockResults = $this -> mockScannerResults; @@ -40,6 +33,7 @@ uniq_name TEXT, type TEXT, state TEXT, + params_schema TEXT, create_at TEXT, update_at TEXT )"); @@ -60,6 +54,9 @@ create_at TEXT, update_at TEXT )"); + if(!isset(app() -> scripts_registry)) { + app() -> scripts_registry = new \SHServ\Middleware\ScriptsRegistry(); + } ControlScripts::flush_statics(); } @@ -69,24 +66,19 @@ ControlScripts::flush_statics(); } - public function test_regular_scripts_are_dispatched_to_cli(): void { - $ref = new \ReflectionClass(ControlScripts::class); - $prop = $ref -> getProperty('regular_scripts'); - $prop -> setAccessible(true); + public function test_runs_enabled_regular_scripts(): void { + $ran = []; - $scripts = [ - 'fail_script' => [ - 'attributes' => ['alias' => 'fail_script', 'name' => 'Fail'], - 'code' => '', - 'script' => function() {} - ], - 'ok_script' => [ - 'attributes' => ['alias' => 'ok_script', 'name' => 'OK'], - 'code' => '', - 'script' => function() {} - ] + app() -> scripts_registry -> regular['fail_script'] = [ + 'attributes' => ['alias' => 'fail_script', 'name' => 'Fail'], + 'code' => '', + 'script' => function() use (&$ran) { $ran[] = 'fail_script'; throw new \Exception('boom'); } ]; - $prop -> setValue(null, $scripts); + app() -> scripts_registry -> regular['ok_script'] = [ + 'attributes' => ['alias' => 'ok_script', 'name' => 'OK'], + 'code' => '', + 'script' => function() use (&$ran) { $ran[] = 'ok_script'; } + ]; $this -> tb -> insert('scripts', [ 'uniq_name' => 'fail_script', @@ -103,25 +95,19 @@ $_SERVER['REMOTE_ADDR'] = '127.0.0.1'; $controller = new TestableCronController(); - $controller -> returnCodes = ['fail_script' => 1, 'ok_script' => 0]; $controller -> run_regular_cron_scripts(); - $this -> assertSame(['fail_script', 'ok_script'], $controller -> cliCalls); + $this -> assertSame(['fail_script', 'ok_script'], $ran); } public function test_disabled_regular_scripts_are_skipped(): void { - $ref = new \ReflectionClass(ControlScripts::class); - $prop = $ref -> getProperty('regular_scripts'); - $prop -> setAccessible(true); + $ran = false; - $scripts = [ - 'disabled_script' => [ - 'attributes' => ['alias' => 'disabled_script', 'name' => 'Disabled'], - 'code' => '', - 'script' => function() {} - ] + app() -> scripts_registry -> regular['disabled_script'] = [ + 'attributes' => ['alias' => 'disabled_script', 'name' => 'Disabled'], + 'code' => '', + 'script' => function() use (&$ran) { $ran = true; } ]; - $prop -> setValue(null, $scripts); $this -> tb -> insert('scripts', [ 'uniq_name' => 'disabled_script', @@ -134,7 +120,7 @@ $controller = new TestableCronController(); $controller -> run_regular_cron_scripts(); - $this -> assertSame([], $controller -> cliCalls); + $this -> assertFalse($ran); } public function test_marks_stale_devices_as_lost(): void { diff --git a/server/tests/ModesTest.php b/server/tests/ModesTest.php new file mode 100644 index 0000000..4febfad --- /dev/null +++ b/server/tests/ModesTest.php @@ -0,0 +1,129 @@ + tb = app() -> thin_builder; + $this -> tb -> query(" + CREATE TABLE shserv_modes ( + tag VARCHAR(32) PRIMARY KEY, + is_active TINYINT(1) NOT NULL DEFAULT 0, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + ) + "); + } + + protected function tearDown(): void { + $this -> tb -> query("DROP TABLE IF EXISTS shserv_modes"); + } + + public function testSyncRegistryTagsCreatesRows() { + $model = new Modes(); + $model -> sync_registry_tags(); + + $definitions = \ControlScripts\ModesRegistry::definitions(); + $tags = array_keys($definitions); + + $rows = $this -> tb -> select('shserv_modes', [], []); + $this -> assertCount(count($tags), $rows); + + foreach($rows as $row) { + $this -> assertContains($row['tag'], $tags); + $this -> assertEquals(0, $row['is_active']); + } + } + + public function testEnableAndDisable() { + $model = new Modes(); + $model -> sync_registry_tags(); + + $this -> assertFalse($model -> is_active('night')); + + $model -> enable('night'); + $this -> assertTrue($model -> is_active('night')); + + $model -> disable('night'); + $this -> assertFalse($model -> is_active('night')); + } + + public function testAnyActive() { + $model = new Modes(); + $model -> sync_registry_tags(); + + $this -> assertFalse($model -> any_active(['night', 'sleep'])); + + $model -> enable('sleep'); + $this -> assertTrue($model -> any_active(['night', 'sleep'])); + $this -> assertFalse($model -> any_active(['night', 'away'])); + } + + public function testAllActive() { + $model = new Modes(); + $model -> sync_registry_tags(); + + $this -> assertFalse($model -> all_active(['night', 'sleep'])); + + $model -> enable('night'); + $this -> assertFalse($model -> all_active(['night', 'sleep'])); + + $model -> enable('sleep'); + $this -> assertTrue($model -> all_active(['night', 'sleep'])); + } + + public function testActiveTags() { + $model = new Modes(); + $model -> sync_registry_tags(); + + $this -> assertEquals([], $model -> active_tags()); + + $model -> enable('away'); + $model -> enable('sleep'); + + $active = $model -> active_tags(); + $this -> assertCount(2, $active); + $this -> assertContains('away', $active); + $this -> assertContains('sleep', $active); + } + + public function testListAllReturnsMeta() { + $model = new Modes(); + $model -> sync_registry_tags(); + $model -> enable('night'); + + $list = $model -> list_all(); + $night = array_values(array_filter($list, fn($m) => $m['tag'] === 'night'))[0]; + + $this -> assertEquals('night', $night['tag']); + $this -> assertEquals('Ночь', $night['label']); + $this -> assertNotEmpty($night['description']); + $this -> assertTrue($night['is_active']); + } + + public function testModesContextToggle() { + $model = new Modes(); + $model -> sync_registry_tags(); + + $ctx = new \SHServ\Middleware\ModesContext(); + + $this -> assertFalse($ctx -> is('movie')); + + $ctx -> toggle('movie'); + $this -> assertTrue($ctx -> is('movie')); + + $ctx -> toggle('movie'); + $this -> assertFalse($ctx -> is('movie')); + } + + public function testModesContextMeta() { + $ctx = new \SHServ\Middleware\ModesContext(); + + $meta = $ctx -> meta('away'); + $this -> assertEquals('Не дома', $meta['label']); + $this -> assertNotEmpty($meta['description']); + } +} diff --git a/server/tests/ScriptParamsValidatorTest.php b/server/tests/ScriptParamsValidatorTest.php new file mode 100644 index 0000000..9a2454c --- /dev/null +++ b/server/tests/ScriptParamsValidatorTest.php @@ -0,0 +1,118 @@ + "bar"]); + $this->assertTrue($result["ok"]); + $this->assertEmpty($result["errors"]); + } + + public function test_required_field_missing() { + $schema = [ + "level" => ["type" => "number", "required" => true], + ]; + $result = ScriptParamsValidator::validate($schema, []); + $this->assertFalse($result["ok"]); + $this->assertEquals("required", $result["errors"][0]["error"]); + $this->assertEquals("level", $result["errors"][0]["field"]); + } + + public function test_default_applied_when_missing() { + $schema = [ + "level" => ["type" => "number", "default" => 42], + ]; + $result = ScriptParamsValidator::validate($schema, []); + $this->assertTrue($result["ok"]); + $this->assertEquals(42, $result["params"]["level"]); + } + + public function test_text_type_string_ok() { + $schema = ["msg" => ["type" => "text"]]; + $result = ScriptParamsValidator::validate($schema, ["msg" => "hello"]); + $this->assertTrue($result["ok"]); + } + + public function test_text_type_number_fails() { + $schema = ["msg" => ["type" => "text"]]; + $result = ScriptParamsValidator::validate($schema, ["msg" => 123]); + $this->assertFalse($result["ok"]); + $this->assertEquals("expected_string", $result["errors"][0]["error"]); + } + + public function test_number_type_int_ok() { + $schema = ["count" => ["type" => "number", "min" => 0, "max" => 10]]; + $result = ScriptParamsValidator::validate($schema, ["count" => 5]); + $this->assertTrue($result["ok"]); + } + + public function test_number_type_string_numeric_ok() { + $schema = ["count" => ["type" => "number"]]; + $result = ScriptParamsValidator::validate($schema, ["count" => "7"]); + $this->assertTrue($result["ok"]); + $this->assertEquals(7.0, $result["params"]["count"]); + } + + public function test_number_min_violation() { + $schema = ["count" => ["type" => "number", "min" => 0]]; + $result = ScriptParamsValidator::validate($schema, ["count" => -5]); + $this->assertFalse($result["ok"]); + $this->assertEquals("min", $result["errors"][0]["error"]); + } + + public function test_range_type_ok() { + $schema = ["level" => ["type" => "range", "min" => 0, "max" => 100]]; + $result = ScriptParamsValidator::validate($schema, ["level" => 50]); + $this->assertTrue($result["ok"]); + } + + public function test_range_max_violation() { + $schema = ["level" => ["type" => "range", "min" => 0, "max" => 100]]; + $result = ScriptParamsValidator::validate($schema, ["level" => 120]); + $this->assertFalse($result["ok"]); + $this->assertEquals("max", $result["errors"][0]["error"]); + } + + public function test_select_valid_option() { + $schema = ["room" => ["type" => "select", "options" => ["kitchen" => "Кухня", "hall" => "Зал"]]]; + $result = ScriptParamsValidator::validate($schema, ["room" => "hall"]); + $this->assertTrue($result["ok"]); + } + + public function test_select_invalid_option() { + $schema = ["room" => ["type" => "select", "options" => ["kitchen" => "Кухня"]]]; + $result = ScriptParamsValidator::validate($schema, ["room" => "bedroom"]); + $this->assertFalse($result["ok"]); + $this->assertEquals("invalid_option", $result["errors"][0]["error"]); + } + + public function test_toggle_bool_ok() { + $schema = ["instant" => ["type" => "toggle"]]; + $result = ScriptParamsValidator::validate($schema, ["instant" => true]); + $this->assertTrue($result["ok"]); + } + + public function test_toggle_non_bool_fails() { + $schema = ["instant" => ["type" => "toggle"]]; + $result = ScriptParamsValidator::validate($schema, ["instant" => "yes"]); + $this->assertFalse($result["ok"]); + $this->assertEquals("expected_bool", $result["errors"][0]["error"]); + } + + public function test_textarea_type_string_ok() { + $schema = ["note" => ["type" => "textarea"]]; + $result = ScriptParamsValidator::validate($schema, ["note" => "line1\nline2"]); + $this->assertTrue($result["ok"]); + } + + public function test_unknown_type_ignored() { + $schema = ["foo" => ["type" => "custom"]]; + $result = ScriptParamsValidator::validate($schema, ["foo" => "anything"]); + $this->assertTrue($result["ok"]); + } +} diff --git a/server/tests/ScriptsModelStateTest.php b/server/tests/ScriptsModelStateTest.php index 9997e63..79ddd9a 100644 --- a/server/tests/ScriptsModelStateTest.php +++ b/server/tests/ScriptsModelStateTest.php @@ -21,12 +21,7 @@ $this -> tb -> query("DROP TABLE IF EXISTS scripts"); app() -> control_scripts_instances = $this -> originalScopes; // Reset static script registries to avoid leakage between tests - $refRegular = new \ReflectionProperty(ControlScripts::class, 'regular_scripts'); - $refRegular -> setAccessible(true); - $refRegular -> setValue(null, []); - $refActions = new \ReflectionProperty(ControlScripts::class, 'actions_scripts'); - $refActions -> setAccessible(true); - $refActions -> setValue(null, []); + ControlScripts::flush_statics(); } private function create_scripts_table(): void { @@ -36,6 +31,7 @@ uniq_name TEXT, type TEXT, state TEXT, + params_schema TEXT, create_at TEXT, update_at TEXT )"); diff --git a/server/tests/TestApp.php b/server/tests/TestApp.php index 49bd8a4..5ed2085 100644 --- a/server/tests/TestApp.php +++ b/server/tests/TestApp.php @@ -6,4 +6,6 @@ public \SHServ\DevTools $devtools; public $factory = null; public array $control_scripts_instances = []; + public $scripts_registry; + public $modes_context; } diff --git a/server/tests/TimersTest.php b/server/tests/TimersTest.php new file mode 100644 index 0000000..8a9d750 --- /dev/null +++ b/server/tests/TimersTest.php @@ -0,0 +1,109 @@ + tb = app() -> thin_builder; + $this -> tb -> query(" + CREATE TABLE shserv_timers ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + timer_alias TEXT, + scope_name TEXT, + target_type TEXT, + target_alias TEXT, + params TEXT, + execute_at TEXT, + status TEXT, + error_message TEXT, + created_at TEXT, + executed_at TEXT + ) + "); + } + + protected function tearDown(): void { + $this -> tb -> query("DROP TABLE IF EXISTS shserv_timers"); + } + + public function test_create_and_get_pending(): void { + $timers = new Timers(); + $result = $timers -> create_timer("test_off", "LightHubScope", "action", "kitchen_light_switcher", [], time() - 1); + $this -> assertTrue($result); + + $pending = $timers -> get_pending_timers(); + $this -> assertCount(1, $pending); + $this -> assertEquals("test_off", $pending[0]["timer_alias"]); + $this -> assertEquals("action", $pending[0]["target_type"]); + } + + public function test_cancel_timer_scoped(): void { + $timers = new Timers(); + $timers -> create_timer("test_cancel", "LightHubScope", "action", "alias", [], time() + 100); + $result = $timers -> cancel_timer("test_cancel", "LightHubScope"); + $this -> assertTrue($result); + + $pending = $timers -> get_pending_timers(); + $this -> assertCount(0, $pending); + } + + public function test_cancel_by_alias(): void { + $timers = new Timers(); + $timers -> create_timer("global_cancel", "OfficeRoomScope", "event", "door.open", [], time() + 100); + $result = $timers -> cancel_by_alias("global_cancel"); + $this -> assertTrue($result); + + $pending = $timers -> get_pending_timers(); + $this -> assertCount(0, $pending); + } + + public function test_mark_status_executed(): void { + $timers = new Timers(); + $timers -> create_timer("test_exec", "LightHubScope", "action", "alias", [], time() - 1); + $pending = $timers -> get_pending_timers(); + $this -> assertCount(1, $pending); + + $result = $timers -> mark_status((int)$pending[0]["id"], "executed"); + $this -> assertTrue($result); + + $all = $timers -> get_timers("executed"); + $this -> assertCount(1, $all); + $this -> assertNotNull($all[0]["executed_at"]); + } + + public function test_mark_status_failed(): void { + $timers = new Timers(); + $timers -> create_timer("test_fail", "LightHubScope", "regular", "alias", [], time() - 1); + $pending = $timers -> get_pending_timers(); + $this -> assertCount(1, $pending); + + $result = $timers -> mark_status((int)$pending[0]["id"], "failed", "Something broke"); + $this -> assertTrue($result); + + $all = $timers -> get_timers("failed"); + $this -> assertCount(1, $all); + $this -> assertEquals("Something broke", $all[0]["error_message"]); + } + + public function test_duplicate_alias_replaces_pending(): void { + $timers = new Timers(); + $timers -> create_timer("dup", "LightHubScope", "action", "a", [], time() + 100); + $timers -> create_timer("dup", "LightHubScope", "action", "b", [], time() + 200); + + $pending = $timers -> get_timers("pending"); + $this -> assertCount(1, $pending); + $this -> assertEquals("b", $pending[0]["target_alias"]); + } + + public function test_get_timers_with_limit(): void { + $timers = new Timers(); + for($i = 1; $i <= 5; $i++) { + $timers -> create_timer("t{$i}", "LightHubScope", "action", "alias", [], time() + $i); + } + $all = $timers -> get_timers(null, 3); + $this -> assertCount(3, $all); + } +} diff --git a/server/tests/bootstrap.php b/server/tests/bootstrap.php index d08a8f5..24577d1 100644 --- a/server/tests/bootstrap.php +++ b/server/tests/bootstrap.php @@ -2,6 +2,7 @@ require_once __DIR__ . '/../Fury/fury.php'; require_once __DIR__ . '/TestApp.php'; +require_once __DIR__ . '/../../automation/ModesRegistry.php'; // PHPUnit auto-loads via composer, but Fury's own autoloader // handles the legacy namespace-to-path mapping. @@ -16,6 +17,9 @@ $testApp->thin_builder = $tb; $testApp->utils = new \SHServ\Utils(); $testApp->devtools = new \SHServ\DevTools(); +$testApp->scripts_registry = new \SHServ\Middleware\ScriptsRegistry(); +$testApp->scripts_registry->flush(); +$testApp->modes_context = new \SHServ\Middleware\ModesContext(); \Fury\Kernel\AppContainer::set_app($testApp); diff --git a/webclient/src/components/script/ActionScriptsGrid.vue b/webclient/src/components/script/ActionScriptsGrid.vue index f76a326..a18f22e 100644 --- a/webclient/src/components/script/ActionScriptsGrid.vue +++ b/webclient/src/components/script/ActionScriptsGrid.vue @@ -24,20 +24,29 @@ icon="ph-play" :loading="scriptsStore.isRunning(script.alias)" :disabled="script.state !== 'enabled'" - @click.stop="run(script.alias)" + @click.stop="run(script)" > Run + + + diff --git a/webclient/src/components/script/__tests__/ScriptRunModal.spec.js b/webclient/src/components/script/__tests__/ScriptRunModal.spec.js new file mode 100644 index 0000000..6f4b022 --- /dev/null +++ b/webclient/src/components/script/__tests__/ScriptRunModal.spec.js @@ -0,0 +1,90 @@ +import { describe, it, expect, beforeEach, vi } from "vitest"; +import { mount } from "@vue/test-utils"; +import ScriptRunModal from "../ScriptRunModal.vue"; + +vi.mock("gnexus-ui-kit/vue", async () => { + const actual = await vi.importActual("gnexus-ui-kit/vue"); + return { + ...actual, + useToast: () => ({ success: vi.fn(), error: vi.fn() }), + }; +}); + +describe("ScriptRunModal", () => { + const script = { + alias: "dim_lights", + name: "Диммер", + params_schema: { + level: { type: "range", label: "Яркость", min: 0, max: 100, step: 5, default: 50 }, + room: { type: "select", label: "Комната", options: { kitchen: "Кухня", hall: "Зал" }, default: "hall" }, + instant: { type: "toggle", label: "Мгновенно", default: false }, + note: { type: "textarea", label: "Примечание" }, + }, + }; + + function createWrapper(props = {}) { + return mount(ScriptRunModal, { + props: { + open: true, + script, + ...props, + }, + }); + } + + it("renders modal when open", () => { + const wrapper = createWrapper(); + expect(wrapper.findComponent({ name: "GnModal" }).exists()).toBe(true); + }); + + it("initializes form values with defaults", () => { + const wrapper = createWrapper(); + expect(wrapper.vm.formValues).toEqual({ + level: 50, + room: "hall", + instant: false, + note: "", + }); + }); + + it("emits run event with params on submit", async () => { + const wrapper = createWrapper(); + wrapper.vm.formValues = { + level: 80, + room: "kitchen", + instant: true, + note: "test", + }; + + wrapper.vm.submit(); + + expect(wrapper.emitted("run")).toBeTruthy(); + expect(wrapper.emitted("run")[0]).toEqual([ + { alias: "dim_lights", params: { level: 80, room: "kitchen", instant: true, note: "test" } }, + ]); + }); + + it("closes modal on run", async () => { + const wrapper = createWrapper(); + wrapper.vm.formValues = { level: 80, room: "kitchen", instant: false, note: "" }; + wrapper.vm.submit(); + expect(wrapper.emitted("update:open")?.[0]).toEqual([false]); + }); + + it("disables submit when required field is empty", async () => { + const requiredScript = { + alias: "test", + name: "Test", + params_schema: { + name: { type: "text", label: "Name", required: true }, + }, + }; + const wrapper = mount(ScriptRunModal, { + props: { open: true, script: requiredScript }, + }); + + wrapper.vm.formValues.name = ""; + await wrapper.vm.$nextTick(); + expect(wrapper.vm.canSubmit).toBe(false); + }); +}); diff --git a/webclient/src/features/scripts/pages/ScriptDetailPage.vue b/webclient/src/features/scripts/pages/ScriptDetailPage.vue index f21e561..aaa1409 100644 --- a/webclient/src/features/scripts/pages/ScriptDetailPage.vue +++ b/webclient/src/features/scripts/pages/ScriptDetailPage.vue @@ -178,6 +178,14 @@ + + @@ -208,6 +216,7 @@ import AreaBadgeLink from "../../../components/area/AreaBadgeLink.vue"; import AreaAssignSection from "../../../components/area/AreaAssignSection.vue"; import PageActionsDropdown from "../../../components/layout/PageActionsDropdown.vue"; +import ScriptRunModal from "../../../components/script/ScriptRunModal.vue"; const route = useRoute(); const scriptsStore = useScriptsStore(); @@ -227,6 +236,7 @@ const scriptType = computed(() => route.params.type); const scriptId = computed(() => route.params.id); +const showRunModal = ref(false); const isAction = computed(() => scriptType.value === "actions"); const isRegular = computed(() => scriptType.value === "regular"); @@ -334,13 +344,22 @@ return Prism.highlight(code, Prism.languages.php, "php"); }); -async function run() { +function run() { if (!script.value?.alias) return; - const result = await scriptsStore.runScript(script.value.alias); + const schema = script.value.params_schema; + if (schema && Object.keys(schema).length > 0) { + showRunModal.value = true; + return; + } + executeRun(script.value.alias, {}); +} + +async function executeRun(alias, params) { + const result = await scriptsStore.runScript(alias, params); if (result?.ok) { - toast.success({ title: `Ran ${script.value.alias}`, text: scriptsStore.lastRunResult?.execTime ? `Exec time: ${scriptsStore.lastRunResult.execTime}` : undefined }); + toast.success({ title: `Ran ${alias}`, text: scriptsStore.lastRunResult?.execTime ? `Exec time: ${scriptsStore.lastRunResult.execTime}` : undefined }); } else { - toast.error({ title: `Failed ${script.value.alias}`, text: result?.error?.message || "Unknown error" }); + toast.error({ title: `Failed ${alias}`, text: result?.error?.message || "Unknown error" }); } }