mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-30 03:38:47 +00:00
fix(dialogs): находки код-ревью #600 r1 — сегмент без разрыва слов, радиус без блокировки Save, свидетель дефекта №5
M1. Подпись сегмента больше не рвётся посреди слова: колонка `.hpf-seg label` не сжимается ниже самого длинного слова (`min-width: fit-content`, для браузеров без него — прежний `0` строкой выше), слова переносятся только по пробелам (`overflow-wrap: normal`), не поместившийся сегмент переносится на вторую строку целыми кнопками (`flex-wrap`). Новый свидетель demo/smoke_dialog_segments_i18n.mjs — четыре диалога × en/ru/de/fr: у каждой подписи число строк (по Range текстового узла: span — flex-элемент, у блока один прямоугольник даже при переносе) не больше числа слов, текст внутри кнопки. На разметке r1 краснеет на en/ru/fr комнаты («Temperature» в 2 строки, «По температуре» в 3). Мутант form-kit-segment-breaks-words возвращает прежние две строки CSS. ACCEPTANCE.md — строка про подписи сегмента переписана. M2. Glow radius — не условие Save: как на dev, нечисло или неположительное значение при сохранении молча становится общим радиусом. Удалены glowRadiusValid, MarkerProblem marker.error_glow_radius, ключ в четырёх локалях словаря settings, aria-invalid у поля; смок device_settings_form утверждает обратное прежнему (badRadiusDoesNotBlockSave, zeroRadiusKeepsSaveEnabled) и проверяет «Review N fields» на привязке в create-режиме. Changelog EN/RU и USER-GUIDE ru/en больше не называют радиус среди ошибок; таблица устройства говорит про молчаливый общий радиус. M3. Свидетель дефекта №5 (поповер «?» обрезается границей диалога комнаты): demo/smoke_dialog_help_clipping.mjs — короткое окно 900×620, диалог комнаты скроллится, «?» нижней карточки прижат к краю; подсказка выходит за край скроллера и остаётся hit-test'ируемой во всех пяти точках (elementsFromPoint сквозь теневые корни — обрезанная часть не hit-test'ится). Четыре ветки: нативный <dialog> и ha-dialog × Popover API и портальный fallback; ветка ha-dialog — заглушка с ловушками настоящей mwc-поверхности (transform + overflow: hidden + собственный скроллер), portal вне поверхности проверен явно. Настоящий ha-dialog (#505, загрузка колеса HA-frontend) — отдельная диагностическая приёмка владельца; так и записано в ACCEPTANCE.md, где появилась таблица AC8 «девять дефектов — свидетель на каждый». M4. ACCEPTANCE.md: эталонов 13, а не 11 — одиннадцать из ТЗ (список AC10 унаследован от #598 без комнаты) плюс две room-temperature-dialog-*. L1. USER-GUIDE.ru.md: испорченная строка таблицы настроек пространства (хвост удалённой строки про декоративный слой) — убран; пояснение «в редакторе подложки остаются видимыми» вернулось в строку «Видимые слои»; строка про солнце говорит «слой Двери, окна и ворота выключен» вместо «Скрыть проёмы включено». Фикстуры листа диалогов набора пересняты (панель — байт в байт). Бюджет: initial 289 852 / 290 900; lazy editor 242 989 / 243 900. Гейты: typecheck, build, bundle:sync (три копии), npm test 2794 pass по четырём частям, no-new-any, mutation-gate --check, check-inputs --coverage, смоки: segments_i18n, help_clipping, четыре формы, config_parity, help_affordance, room_settings, settings_dialog_cards. Issue: #600 User-Visible: yes
This commit is contained in:
@@ -1,312 +1,312 @@
|
||||
{
|
||||
"schema": 1,
|
||||
"fingerprint": "c6e9a7f9c0e3096b40b9ae51df9d052aeddc8359d008fd86a2e4cbef1aba717f",
|
||||
"fingerprint": "54fcdd48a85ca3f133f7a631e38722f7eb58d88c475a1cfb768130946dffad32",
|
||||
"entry": "houseplan-card.js",
|
||||
"panelEntry": "houseplan-panel.js",
|
||||
"initialViewFiles": [
|
||||
"houseplan-assets/houseplan-card-BWAph8ZF.js",
|
||||
"houseplan-assets/houseplan-card-9fMSy3y3.js",
|
||||
"houseplan-card.js"
|
||||
],
|
||||
"initialViewGzipBytes": 289829,
|
||||
"initialViewGzipBytes": 289852,
|
||||
"initialPanelFiles": [
|
||||
"houseplan-assets/houseplan-card-BWAph8ZF.js",
|
||||
"houseplan-assets/houseplan-card-9fMSy3y3.js",
|
||||
"houseplan-panel.js"
|
||||
],
|
||||
"initialPanelGzipBytes": 291350,
|
||||
"initialPanelGzipBytes": 291374,
|
||||
"initialPanelOnlyFiles": [
|
||||
"houseplan-panel.js"
|
||||
],
|
||||
"initialPanelOnlyGzipBytes": 2323,
|
||||
"initialPanelOnlyGzipBytes": 2325,
|
||||
"lazyFiles": [
|
||||
"houseplan-assets/backdrop-pick-CtZfmF4H.js",
|
||||
"houseplan-assets/de-AkOtg0jq.js",
|
||||
"houseplan-assets/editor-_VTHnoKH.js",
|
||||
"houseplan-assets/form-kit.styles-DcvCvE8g.js",
|
||||
"houseplan-assets/fr-Ds3OdruH.js",
|
||||
"houseplan-assets/furniture-plan-art.generated-Ck1wv9qF.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-BlocE3XU.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-DYojoXE_.js",
|
||||
"houseplan-assets/hp-zigbee-topology-overlay-jGSF0zVB.js",
|
||||
"houseplan-assets/iso-scene-render-BfrsUAJf.js",
|
||||
"houseplan-assets/live-interaction-runtime-CCfHOfT8.js",
|
||||
"houseplan-assets/pdf-export-Bslsp3h0.js",
|
||||
"houseplan-assets/summary-panel-runtime-loaded-BGIJeXIz.js",
|
||||
"houseplan-assets/zigbee-topology-D0gydI7H.js",
|
||||
"houseplan-assets/zigbee-topology-runtime-BXasXMdL.js"
|
||||
"houseplan-assets/backdrop-pick-BJOCHJxe.js",
|
||||
"houseplan-assets/de-DVCIKwC0.js",
|
||||
"houseplan-assets/editor-C694OxAO.js",
|
||||
"houseplan-assets/form-kit.styles-CKUQLdmn.js",
|
||||
"houseplan-assets/fr-DHxhbm5E.js",
|
||||
"houseplan-assets/furniture-plan-art.generated-DaxkO8ol.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-AzCVhtuX.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-Dp2b84fm.js",
|
||||
"houseplan-assets/hp-zigbee-topology-overlay-CbSbT5WT.js",
|
||||
"houseplan-assets/iso-scene-render-fYqz_-Ot.js",
|
||||
"houseplan-assets/live-interaction-runtime-XyTIhKAA.js",
|
||||
"houseplan-assets/pdf-export-D3vmqIY6.js",
|
||||
"houseplan-assets/summary-panel-runtime-loaded-CX2cplA1.js",
|
||||
"houseplan-assets/zigbee-topology-CI6PJorK.js",
|
||||
"houseplan-assets/zigbee-topology-runtime-d-S2Abll.js"
|
||||
],
|
||||
"lazyGzipBytes": 459663,
|
||||
"lazyGzipBytes": 459551,
|
||||
"lazyEditorFiles": [
|
||||
"houseplan-assets/backdrop-pick-CtZfmF4H.js",
|
||||
"houseplan-assets/editor-_VTHnoKH.js",
|
||||
"houseplan-assets/form-kit.styles-DcvCvE8g.js",
|
||||
"houseplan-assets/furniture-plan-art.generated-Ck1wv9qF.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-BlocE3XU.js",
|
||||
"houseplan-assets/zigbee-topology-D0gydI7H.js"
|
||||
"houseplan-assets/backdrop-pick-BJOCHJxe.js",
|
||||
"houseplan-assets/editor-C694OxAO.js",
|
||||
"houseplan-assets/form-kit.styles-CKUQLdmn.js",
|
||||
"houseplan-assets/furniture-plan-art.generated-DaxkO8ol.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-AzCVhtuX.js",
|
||||
"houseplan-assets/zigbee-topology-CI6PJorK.js"
|
||||
],
|
||||
"lazyEditorGzipBytes": 243125,
|
||||
"lazyEditorGzipBytes": 242989,
|
||||
"lazyOnboardingFiles": [
|
||||
"houseplan-assets/backdrop-pick-CtZfmF4H.js",
|
||||
"houseplan-assets/form-kit.styles-DcvCvE8g.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-DYojoXE_.js"
|
||||
"houseplan-assets/backdrop-pick-BJOCHJxe.js",
|
||||
"houseplan-assets/form-kit.styles-CKUQLdmn.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-Dp2b84fm.js"
|
||||
],
|
||||
"lazyOnboardingGzipBytes": 33646,
|
||||
"lazyOnboardingGzipBytes": 33577,
|
||||
"lazyLocaleFiles": [
|
||||
"houseplan-assets/de-AkOtg0jq.js",
|
||||
"houseplan-assets/fr-Ds3OdruH.js"
|
||||
"houseplan-assets/de-DVCIKwC0.js",
|
||||
"houseplan-assets/fr-DHxhbm5E.js"
|
||||
],
|
||||
"lazyLocaleGzipBytes": 55372,
|
||||
"lazyLocaleGzipBytes": 55383,
|
||||
"lazyIsometricFiles": [
|
||||
"houseplan-assets/iso-scene-render-BfrsUAJf.js"
|
||||
"houseplan-assets/iso-scene-render-fYqz_-Ot.js"
|
||||
],
|
||||
"lazyIsometricGzipBytes": 17644,
|
||||
"lazyIsometricGzipBytes": 17643,
|
||||
"lazyFurnitureArtFiles": [
|
||||
"houseplan-assets/furniture-plan-art.generated-Ck1wv9qF.js"
|
||||
"houseplan-assets/furniture-plan-art.generated-DaxkO8ol.js"
|
||||
],
|
||||
"lazyFurnitureArtGzipBytes": 16945,
|
||||
"lazyFurnitureArtGzipBytes": 16942,
|
||||
"lazyPdfFiles": [
|
||||
"houseplan-assets/furniture-plan-art.generated-Ck1wv9qF.js",
|
||||
"houseplan-assets/pdf-export-Bslsp3h0.js"
|
||||
"houseplan-assets/furniture-plan-art.generated-DaxkO8ol.js",
|
||||
"houseplan-assets/pdf-export-D3vmqIY6.js"
|
||||
],
|
||||
"lazyPdfGzipBytes": 126819,
|
||||
"lazyPdfGzipBytes": 126817,
|
||||
"files": [
|
||||
{
|
||||
"path": "houseplan-assets/backdrop-pick-CtZfmF4H.js",
|
||||
"sha256": "0318781a07d46ab4852f6ab7b0fdc44c180a1b0271935e031f9a9f885de62991",
|
||||
"rawBytes": 74764,
|
||||
"gzipBytes": 24114,
|
||||
"path": "houseplan-assets/backdrop-pick-BJOCHJxe.js",
|
||||
"sha256": "c24f2896a89f71e0a4147184f93b0e69e0c22eb705b772e644e9fc131ff879f4",
|
||||
"rawBytes": 74375,
|
||||
"gzipBytes": 24031,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/form-kit.styles-DcvCvE8g.js",
|
||||
"houseplan-assets/houseplan-card-BWAph8ZF.js"
|
||||
"houseplan-assets/form-kit.styles-CKUQLdmn.js",
|
||||
"houseplan-assets/houseplan-card-9fMSy3y3.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/de-AkOtg0jq.js",
|
||||
"sha256": "21cadc32b989295b913052353b5c8049b844474028e72162f8564698c0bdb9db",
|
||||
"path": "houseplan-assets/de-DVCIKwC0.js",
|
||||
"sha256": "6f716933e452260c6e7c0c40d7193e750b6fc443f162cca5cb814c734142dde5",
|
||||
"rawBytes": 92513,
|
||||
"gzipBytes": 27927,
|
||||
"gzipBytes": 27933,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/editor-_VTHnoKH.js",
|
||||
"sha256": "881257f965ba340ab8367a3a0ffbfaf7e4509a38997c7b3b33281ff27b700907",
|
||||
"path": "houseplan-assets/editor-C694OxAO.js",
|
||||
"sha256": "f95242b8000cddf2fe1856a5518883c00a27a90c2983f228003db0189dffc1b4",
|
||||
"rawBytes": 3833,
|
||||
"gzipBytes": 1583,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-BWAph8ZF.js"
|
||||
"houseplan-assets/houseplan-card-9fMSy3y3.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/form-kit.styles-DcvCvE8g.js",
|
||||
"sha256": "5068cd6f5bd37792a593096b142ea5e9b729b0f85a1cf4d3c5722f714ff64eb2",
|
||||
"rawBytes": 23495,
|
||||
"gzipBytes": 4704,
|
||||
"path": "houseplan-assets/form-kit.styles-CKUQLdmn.js",
|
||||
"sha256": "44a654e7c905948ab4bb363514532c13e67e3e54eee37e4af0ec8447f706fbc1",
|
||||
"rawBytes": 23544,
|
||||
"gzipBytes": 4716,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/fr-Ds3OdruH.js",
|
||||
"sha256": "395585192b0478200785d46cb37805871bd0726088ca776e0f95150af595633c",
|
||||
"path": "houseplan-assets/fr-DHxhbm5E.js",
|
||||
"sha256": "f603ade3217ebe9959225379598608583ec29ab654dc257f57ae894d85ca448f",
|
||||
"rawBytes": 94824,
|
||||
"gzipBytes": 27445,
|
||||
"gzipBytes": 27450,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/furniture-plan-art.generated-Ck1wv9qF.js",
|
||||
"sha256": "2f193022979145fe8544c3c498fb8f1e9b3690fa6500fcd70a6c4f34c8a13860",
|
||||
"path": "houseplan-assets/furniture-plan-art.generated-DaxkO8ol.js",
|
||||
"sha256": "86d1074252f182c84d47285560a5b22c26724e21f21d03fbac4583973a9c11a7",
|
||||
"rawBytes": 52033,
|
||||
"gzipBytes": 16945,
|
||||
"gzipBytes": 16942,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-card-BWAph8ZF.js",
|
||||
"sha256": "ded6a4cd113062c60ed2086560b03f1cdba08884b0454c85f7140f5f51b284cb",
|
||||
"path": "houseplan-assets/houseplan-card-9fMSy3y3.js",
|
||||
"sha256": "e475fbae1c25540d2e349d4441bc963a4ff4181b8659fd491309dd1e578f716a",
|
||||
"rawBytes": 1027208,
|
||||
"gzipBytes": 289027,
|
||||
"gzipBytes": 289049,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": [
|
||||
"houseplan-assets/de-AkOtg0jq.js",
|
||||
"houseplan-assets/editor-_VTHnoKH.js",
|
||||
"houseplan-assets/fr-Ds3OdruH.js",
|
||||
"houseplan-assets/furniture-plan-art.generated-Ck1wv9qF.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-BlocE3XU.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-DYojoXE_.js",
|
||||
"houseplan-assets/hp-zigbee-topology-overlay-jGSF0zVB.js",
|
||||
"houseplan-assets/iso-scene-render-BfrsUAJf.js",
|
||||
"houseplan-assets/live-interaction-runtime-CCfHOfT8.js",
|
||||
"houseplan-assets/pdf-export-Bslsp3h0.js",
|
||||
"houseplan-assets/summary-panel-runtime-loaded-BGIJeXIz.js"
|
||||
"houseplan-assets/de-DVCIKwC0.js",
|
||||
"houseplan-assets/editor-C694OxAO.js",
|
||||
"houseplan-assets/fr-DHxhbm5E.js",
|
||||
"houseplan-assets/furniture-plan-art.generated-DaxkO8ol.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-AzCVhtuX.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-Dp2b84fm.js",
|
||||
"houseplan-assets/hp-zigbee-topology-overlay-CbSbT5WT.js",
|
||||
"houseplan-assets/iso-scene-render-fYqz_-Ot.js",
|
||||
"houseplan-assets/live-interaction-runtime-XyTIhKAA.js",
|
||||
"houseplan-assets/pdf-export-D3vmqIY6.js",
|
||||
"houseplan-assets/summary-panel-runtime-loaded-CX2cplA1.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-editor-runtime-BlocE3XU.js",
|
||||
"sha256": "1af11a5d027eec8d8a0793eae9be1713b6387d3a15c239e83f8623f87877f8a1",
|
||||
"rawBytes": 677599,
|
||||
"gzipBytes": 188352,
|
||||
"path": "houseplan-assets/houseplan-editor-runtime-AzCVhtuX.js",
|
||||
"sha256": "e84feb1cf320be8297982134d45a5adceaec5a50f95aaa884e6e53cae2664edd",
|
||||
"rawBytes": 677390,
|
||||
"gzipBytes": 188290,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/backdrop-pick-CtZfmF4H.js",
|
||||
"houseplan-assets/form-kit.styles-DcvCvE8g.js",
|
||||
"houseplan-assets/furniture-plan-art.generated-Ck1wv9qF.js",
|
||||
"houseplan-assets/houseplan-card-BWAph8ZF.js",
|
||||
"houseplan-assets/zigbee-topology-D0gydI7H.js"
|
||||
"houseplan-assets/backdrop-pick-BJOCHJxe.js",
|
||||
"houseplan-assets/form-kit.styles-CKUQLdmn.js",
|
||||
"houseplan-assets/furniture-plan-art.generated-DaxkO8ol.js",
|
||||
"houseplan-assets/houseplan-card-9fMSy3y3.js",
|
||||
"houseplan-assets/zigbee-topology-CI6PJorK.js"
|
||||
],
|
||||
"dynamicImports": [
|
||||
"houseplan-assets/zigbee-topology-runtime-BXasXMdL.js"
|
||||
"houseplan-assets/zigbee-topology-runtime-d-S2Abll.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-onboarding-runtime-DYojoXE_.js",
|
||||
"sha256": "a30a515e61b632b90005e296b23d5cc52d3266c91ce29760fbb7358180956d1c",
|
||||
"path": "houseplan-assets/houseplan-onboarding-runtime-Dp2b84fm.js",
|
||||
"sha256": "64367a8743ea22c4a9a350456878b7006ba01a346cc89eabb786e3c1d944ad3a",
|
||||
"rawBytes": 15667,
|
||||
"gzipBytes": 4828,
|
||||
"gzipBytes": 4830,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/backdrop-pick-CtZfmF4H.js",
|
||||
"houseplan-assets/form-kit.styles-DcvCvE8g.js",
|
||||
"houseplan-assets/houseplan-card-BWAph8ZF.js"
|
||||
"houseplan-assets/backdrop-pick-BJOCHJxe.js",
|
||||
"houseplan-assets/form-kit.styles-CKUQLdmn.js",
|
||||
"houseplan-assets/houseplan-card-9fMSy3y3.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/hp-zigbee-topology-overlay-jGSF0zVB.js",
|
||||
"sha256": "780e78bbb5e04de2042497fdea47f44c31f8abeef03ad7cae3aeaf0e776f0db5",
|
||||
"path": "houseplan-assets/hp-zigbee-topology-overlay-CbSbT5WT.js",
|
||||
"sha256": "b2fa73ad0fc3353630e380abe1f63f483113c7bfc5f1e634150c2f0e12b4e0cf",
|
||||
"rawBytes": 10759,
|
||||
"gzipBytes": 3684,
|
||||
"gzipBytes": 3686,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-BWAph8ZF.js",
|
||||
"houseplan-assets/zigbee-topology-D0gydI7H.js",
|
||||
"houseplan-assets/zigbee-topology-runtime-BXasXMdL.js"
|
||||
"houseplan-assets/houseplan-card-9fMSy3y3.js",
|
||||
"houseplan-assets/zigbee-topology-CI6PJorK.js",
|
||||
"houseplan-assets/zigbee-topology-runtime-d-S2Abll.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/iso-scene-render-BfrsUAJf.js",
|
||||
"sha256": "2806544f1906569d9613087eea4ca3b7017d0394147d6913f9e9998b8b4b456b",
|
||||
"path": "houseplan-assets/iso-scene-render-fYqz_-Ot.js",
|
||||
"sha256": "009a9217d1c522a5c2b6f9d5ea3450e2a77aafe52096d9c1d19902a18c6632f9",
|
||||
"rawBytes": 51983,
|
||||
"gzipBytes": 17644,
|
||||
"gzipBytes": 17643,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-BWAph8ZF.js"
|
||||
"houseplan-assets/houseplan-card-9fMSy3y3.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/live-interaction-runtime-CCfHOfT8.js",
|
||||
"sha256": "5b905320a37ded5bfb1b52a4095e6a5821644d4ce0031d2ba2374b1418be2239",
|
||||
"path": "houseplan-assets/live-interaction-runtime-XyTIhKAA.js",
|
||||
"sha256": "0fd38fd067699ea97f11565db7c4ae86c1bcc867041e7e3377408f40e741f03f",
|
||||
"rawBytes": 8216,
|
||||
"gzipBytes": 3205,
|
||||
"gzipBytes": 3209,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-BWAph8ZF.js"
|
||||
"houseplan-assets/houseplan-card-9fMSy3y3.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/pdf-export-Bslsp3h0.js",
|
||||
"sha256": "c7fc552565f6551b70366350399fbbe9bb849a588be6c293e6fb17602dabd0ae",
|
||||
"path": "houseplan-assets/pdf-export-D3vmqIY6.js",
|
||||
"sha256": "4c60cf0b34a17777c60c4849f1ee42841fb74b69466366adcf94cf97eec9ad2e",
|
||||
"rawBytes": 236247,
|
||||
"gzipBytes": 109874,
|
||||
"gzipBytes": 109875,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/furniture-plan-art.generated-Ck1wv9qF.js",
|
||||
"houseplan-assets/houseplan-card-BWAph8ZF.js"
|
||||
"houseplan-assets/furniture-plan-art.generated-DaxkO8ol.js",
|
||||
"houseplan-assets/houseplan-card-9fMSy3y3.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/summary-panel-editor-1TWzLmMH.js",
|
||||
"sha256": "b6fad5dd728b4b6cfa4b4d54989a2d9d9dd9f37aba52301332a0bf3a4e69a66b",
|
||||
"rawBytes": 14862,
|
||||
"gzipBytes": 3424,
|
||||
"path": "houseplan-assets/summary-panel-editor-CNT_mev4.js",
|
||||
"sha256": "ef5dcf22a38fb5df834dcce277de7967303b8025167527483aab726dd30f3a2c",
|
||||
"rawBytes": 14867,
|
||||
"gzipBytes": 3427,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/form-kit.styles-DcvCvE8g.js",
|
||||
"houseplan-assets/houseplan-card-BWAph8ZF.js",
|
||||
"houseplan-assets/summary-panel-runtime-loaded-BGIJeXIz.js"
|
||||
"houseplan-assets/form-kit.styles-CKUQLdmn.js",
|
||||
"houseplan-assets/houseplan-card-9fMSy3y3.js",
|
||||
"houseplan-assets/summary-panel-runtime-loaded-CX2cplA1.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/summary-panel-metrics-CsJSnPHD.js",
|
||||
"sha256": "a9c4d54e9e1d168a3dd48fd8f09d8470eafa3b9dbc825fe6f9dda5bcb34a7029",
|
||||
"path": "houseplan-assets/summary-panel-metrics-BhoEMuKv.js",
|
||||
"sha256": "0b4f1816c4069cc62f20dccaeeeceb82c139dee339782833e594e46aa768fe06",
|
||||
"rawBytes": 2611,
|
||||
"gzipBytes": 1306,
|
||||
"gzipBytes": 1308,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-BWAph8ZF.js"
|
||||
"houseplan-assets/houseplan-card-9fMSy3y3.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/summary-panel-runtime-loaded-BGIJeXIz.js",
|
||||
"sha256": "e3042c31f4e963a6c91fec76b05b1900e79360f60c246d8ce32291dd71201840",
|
||||
"path": "houseplan-assets/summary-panel-runtime-loaded-CX2cplA1.js",
|
||||
"sha256": "95e65a1d327f9d2f90796b9ae7754e0d8a64c15e44a82cefe329dca8f6115689",
|
||||
"rawBytes": 72733,
|
||||
"gzipBytes": 20171,
|
||||
"gzipBytes": 20172,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/form-kit.styles-DcvCvE8g.js",
|
||||
"houseplan-assets/houseplan-card-BWAph8ZF.js"
|
||||
"houseplan-assets/form-kit.styles-CKUQLdmn.js",
|
||||
"houseplan-assets/houseplan-card-9fMSy3y3.js"
|
||||
],
|
||||
"dynamicImports": [
|
||||
"houseplan-assets/summary-panel-editor-1TWzLmMH.js",
|
||||
"houseplan-assets/summary-panel-metrics-CsJSnPHD.js"
|
||||
"houseplan-assets/summary-panel-editor-CNT_mev4.js",
|
||||
"houseplan-assets/summary-panel-metrics-BhoEMuKv.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/zigbee-topology-D0gydI7H.js",
|
||||
"sha256": "abe70ae6d783881bc6e8bdaac98a7372d1263f206103bf7110348f83f4a8dc2a",
|
||||
"path": "houseplan-assets/zigbee-topology-CI6PJorK.js",
|
||||
"sha256": "6e503b93a48deeda46368588fd4eebf7215aa4a2928e1162747da8b3ffe4b67a",
|
||||
"rawBytes": 18962,
|
||||
"gzipBytes": 7427,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-BWAph8ZF.js"
|
||||
"houseplan-assets/houseplan-card-9fMSy3y3.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/zigbee-topology-runtime-BXasXMdL.js",
|
||||
"sha256": "c7dd23a95592651b462f8ef86d073b4aa98b6fad4ce3395b5bbeb0679bf0c76d",
|
||||
"path": "houseplan-assets/zigbee-topology-runtime-d-S2Abll.js",
|
||||
"sha256": "f6aad0abbf74532abc1c705d1268cce95048e7dbdc81a52a776a996c8b70f969",
|
||||
"rawBytes": 3942,
|
||||
"gzipBytes": 1760,
|
||||
"gzipBytes": 1764,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-BWAph8ZF.js",
|
||||
"houseplan-assets/zigbee-topology-D0gydI7H.js"
|
||||
"houseplan-assets/houseplan-card-9fMSy3y3.js",
|
||||
"houseplan-assets/zigbee-topology-CI6PJorK.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-card.js",
|
||||
"sha256": "d5d8d4cbc7b0a71e4c6ba3f4cffb2fd412a9f8ce922200659ce96ee8f70d0bc0",
|
||||
"sha256": "c796620c6d67c8fb18479291279eb410302ad541ed2b3679d59b780f74e8935b",
|
||||
"rawBytes": 1205,
|
||||
"gzipBytes": 802,
|
||||
"gzipBytes": 803,
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-BWAph8ZF.js"
|
||||
"houseplan-assets/houseplan-card-9fMSy3y3.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-panel.js",
|
||||
"sha256": "a34d397053df4099bce9aca317cfa95619c4e031796d77a1da09c15aab69a132",
|
||||
"sha256": "c134452d829194d8d630e5859f8142d345e15348a706d7a83d5d9328b0df3faa",
|
||||
"rawBytes": 6165,
|
||||
"gzipBytes": 2323,
|
||||
"gzipBytes": 2325,
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-BWAph8ZF.js"
|
||||
"houseplan-assets/houseplan-card-9fMSy3y3.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
}
|
||||
|
||||
+16
-16
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+5
-5
@@ -1,14 +1,14 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="c6e9a7f9c0e3096b40b9ae51df9d052aeddc8359d008fd86a2e4cbef1aba717f";import{az as e,l as o,aC as t,e7 as s,A as a,e8 as i,e9 as l,ea as n,E as r,c}from"./houseplan-card-BWAph8ZF.js";class h extends e{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1,this._spacesAuthoritative=!1}setConfig(e){this._config=e}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const e=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(e?.config?.spaces||[]).map(e=>({value:e.id,label:e.title||e.id})),this._spacesAuthoritative=!0}catch{this._spaces=[],this._spacesAuthoritative=!1}finally{this._spacesLoading=!1}}}get _lang(){return o(this.hass,this._config?.language)}get _floorToken(){const e=this._config?.floor;return"number"==typeof e?`__houseplan_yaml_floor_index__:${String(e)}`:null}get _formData(){const e={...this._config},o=this._floorToken;return o?e.floor=o:Object.prototype.hasOwnProperty.call(e,"floor")||(e.floor=""),e}get _schema(){const e=this._spaces||[],o=this._lang,a=[{value:"",label:t(o,"editor.floor_none")}],i=this._floorToken;i&&a.push({value:i,label:t(o,"editor.floor_index",{index:String(this._config?.floor)})});const l="string"==typeof this._config?.floor?this._config.floor:"";l&&!e.some(e=>e.value===l)&&a.push({value:l,label:l}),a.push(...e);const n="string"==typeof this._config?.default_floor?this._config.default_floor:"",r=[...e];return n&&!e.some(e=>e.value===n)&&r.unshift({value:n,label:n}),[{name:"title",selector:{text:{}}},{name:"floor",selector:{select:{mode:"dropdown",options:a}}},e.length?{name:"default_floor",selector:{select:{mode:"dropdown",options:r}}}:{name:"default_floor",selector:{text:{}}},{name:"language",selector:{select:{mode:"dropdown",options:s(t(o,"editor.lang_auto"),this._config?.language)}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}},{name:"kiosk",selector:{boolean:{}}},{name:"cycle",selector:{number:{min:0,max:3600,step:5,mode:"box"}}}]}render(){if(!this.hass||!this._config)return a;const e=i(this,l,o(this.hass,this._config.language));if("cold"===e)return n();if("warm"===e)return r;this._loadSpaces();const s=this._lang,h={title:t(s,"editor.title"),floor:t(s,"editor.floor"),default_floor:t(s,"editor.default_floor"),language:t(s,"editor.language"),icon_size:t(s,"editor.icon_size"),show_temperature:t(s,"editor.show_temperature"),live_states:t(s,"editor.live_states"),show_signal:t(s,"editor.show_signal"),kiosk:t(s,"editor.kiosk"),cycle:t(s,"editor.cycle")},f=this._schema,_=function(e,o,t){if(!t||null===o)return null;const s="string"==typeof e?.default_floor?e.default_floor:"";return!s||o.some(e=>e.value===s)?null:s}(this._config,this._spaces,this._spacesAuthoritative),d=e=>c`<ha-form
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="54fcdd48a85ca3f133f7a631e38722f7eb58d88c475a1cfb768130946dffad32";import{az as e,l as o,aC as t,e7 as s,A as a,e8 as i,e9 as l,ea as n,E as r,c}from"./houseplan-card-9fMSy3y3.js";class f extends e{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1,this._spacesAuthoritative=!1}setConfig(e){this._config=e}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const e=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(e?.config?.spaces||[]).map(e=>({value:e.id,label:e.title||e.id})),this._spacesAuthoritative=!0}catch{this._spaces=[],this._spacesAuthoritative=!1}finally{this._spacesLoading=!1}}}get _lang(){return o(this.hass,this._config?.language)}get _floorToken(){const e=this._config?.floor;return"number"==typeof e?`__houseplan_yaml_floor_index__:${String(e)}`:null}get _formData(){const e={...this._config},o=this._floorToken;return o?e.floor=o:Object.prototype.hasOwnProperty.call(e,"floor")||(e.floor=""),e}get _schema(){const e=this._spaces||[],o=this._lang,a=[{value:"",label:t(o,"editor.floor_none")}],i=this._floorToken;i&&a.push({value:i,label:t(o,"editor.floor_index",{index:String(this._config?.floor)})});const l="string"==typeof this._config?.floor?this._config.floor:"";l&&!e.some(e=>e.value===l)&&a.push({value:l,label:l}),a.push(...e);const n="string"==typeof this._config?.default_floor?this._config.default_floor:"",r=[...e];return n&&!e.some(e=>e.value===n)&&r.unshift({value:n,label:n}),[{name:"title",selector:{text:{}}},{name:"floor",selector:{select:{mode:"dropdown",options:a}}},e.length?{name:"default_floor",selector:{select:{mode:"dropdown",options:r}}}:{name:"default_floor",selector:{text:{}}},{name:"language",selector:{select:{mode:"dropdown",options:s(t(o,"editor.lang_auto"),this._config?.language)}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}},{name:"kiosk",selector:{boolean:{}}},{name:"cycle",selector:{number:{min:0,max:3600,step:5,mode:"box"}}}]}render(){if(!this.hass||!this._config)return a;const e=i(this,l,o(this.hass,this._config.language));if("cold"===e)return n();if("warm"===e)return r;this._loadSpaces();const s=this._lang,f={title:t(s,"editor.title"),floor:t(s,"editor.floor"),default_floor:t(s,"editor.default_floor"),language:t(s,"editor.language"),icon_size:t(s,"editor.icon_size"),show_temperature:t(s,"editor.show_temperature"),live_states:t(s,"editor.live_states"),show_signal:t(s,"editor.show_signal"),kiosk:t(s,"editor.kiosk"),cycle:t(s,"editor.cycle")},h=this._schema,_=function(e,o,t){if(!t||null===o)return null;const s="string"==typeof e?.default_floor?e.default_floor:"";return!s||o.some(e=>e.value===s)?null:s}(this._config,this._spaces,this._spacesAuthoritative),d=e=>c`<ha-form
|
||||
.hass=${this.hass}
|
||||
.data=${this._formData}
|
||||
.schema=${e}
|
||||
.computeLabel=${e=>h[e.name]||e.name}
|
||||
.computeLabel=${e=>f[e.name]||e.name}
|
||||
@value-changed=${this._valueChanged}
|
||||
></ha-form>`;return c`
|
||||
${d(f.slice(0,3))}
|
||||
${d(h.slice(0,3))}
|
||||
${_?c`<div class="default-floor-error" role="alert"
|
||||
style="color:var(--error-color,#db4437);margin:-4px 0 12px;overflow-wrap:anywhere">
|
||||
${t(s,"editor.default_floor_missing",{id:_})}
|
||||
</div>`:a}
|
||||
${d(f.slice(3))}
|
||||
`}_valueChanged(e){const o={...this._config,...e.detail.value};""===o.floor?delete o.floor:o.floor===this._floorToken&&(o.floor=this._config?.floor);const t=new Event("config-changed",{bubbles:!0,composed:!0});t.detail={config:o},this.dispatchEvent(t)}}h.properties={hass:{attribute:!1},_config:{state:!0},_spaces:{state:!0}},customElements.get("houseplan-card-editor")||customElements.define("houseplan-card-editor",h);
|
||||
${d(h.slice(3))}
|
||||
`}_valueChanged(e){const o={...this._config,...e.detail.value};""===o.floor?delete o.floor:o.floor===this._floorToken&&(o.floor=this._config?.floor);const t=new Event("config-changed",{bubbles:!0,composed:!0});t.detail={config:o},this.dispatchEvent(t)}}f.properties={hass:{attribute:!1},_config:{state:!0},_spaces:{state:!0}},customElements.get("houseplan-card-editor")||customElements.define("houseplan-card-editor",f);
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+6
-6
File diff suppressed because one or more lines are too long
+145
-145
File diff suppressed because one or more lines are too long
+3
-3
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+2
-2
File diff suppressed because one or more lines are too long
+52
-52
@@ -1,4 +1,4 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="c6e9a7f9c0e3096b40b9ae51df9d052aeddc8359d008fd86a2e4cbef1aba717f";import{c as a,A as e}from"./houseplan-card-BWAph8ZF.js";import{s,n as t,a as l,m as r,b as o,c as i,d as u}from"./summary-panel-runtime-loaded-BGIJeXIz.js";import"./form-kit.styles-DcvCvE8g.js";const m=m=>{const{host:c,dialog:d,problems:n,t:b}=m,y=n.find(a=>"error"===a.kind),$=d.localShow!==d.baseLocalShow||!d.localOnly&&!s(t(d.draft),d.base),p=$&&!d.busy&&!y,v=a=>n.find(e=>e.path===a),h=a=>a?b(`summary.problem.${a.code}`):"",k=()=>m.close(),g=a`<label class="summary-switch" for="summary-local-show">
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="54fcdd48a85ca3f133f7a631e38722f7eb58d88c475a1cfb768130946dffad32";import{c as a,A as s}from"./houseplan-card-9fMSy3y3.js";import{s as e,n as t,a as l,m as r,b as o,c as i,d as u}from"./summary-panel-runtime-loaded-CX2cplA1.js";import"./form-kit.styles-CKUQLdmn.js";const m=m=>{const{host:c,dialog:d,problems:n,t:b}=m,y=n.find(a=>"error"===a.kind),$=d.localShow!==d.baseLocalShow||!d.localOnly&&!e(t(d.draft),d.base),p=$&&!d.busy&&!y,v=a=>n.find(s=>s.path===a),h=a=>a?b(`summary.problem.${a.code}`):"",k=()=>m.close(),g=a`<label class="summary-switch" for="summary-local-show">
|
||||
<span class="summary-switch-caption"><strong>${b("summary.show_local")}</strong>
|
||||
<small id="summary-local-show-hint">${b("summary.show_local_hint")}</small></span>
|
||||
<input id="summary-local-show" data-summary-local-show type="checkbox"
|
||||
@@ -10,31 +10,31 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="c6e9a7f9c0e3096b40b9ae51df9d052aeddc
|
||||
dismiss-on-scrim aria-busy=${String(d.busy)}
|
||||
@hp-close=${k}>
|
||||
<div class="body summary-editor" @click=${()=>m.closeSource()}>
|
||||
${d.localOnly?a`<p class="summary-local-hint">${b(d.localOnlyHint)}</p>`:e}
|
||||
${d.localOnly?a`<p class="summary-local-hint">${b(d.localOnlyHint)}</p>`:s}
|
||||
<section class="summary-general" aria-labelledby="summary-general-title">
|
||||
<h3 id="summary-general-title">${b("summary.general_settings")}</h3>
|
||||
<div class="summary-general-grid">
|
||||
${d.localOnly?e:a`<div class="summary-field">
|
||||
${d.localOnly?s:a`<div class="summary-field">
|
||||
<label for="summary-panel-title">${b("summary.panel_title")}</label>
|
||||
<input id="summary-panel-title" type="text" .value=${d.draft.title}
|
||||
?disabled=${d.busy}
|
||||
data-summary-error=${String(d.attempted&&"title"===y?.path)}
|
||||
aria-invalid=${"error"===v("title")?.kind?"true":"false"}
|
||||
@input=${a=>m.mutate(e=>{e.title=a.target.value})} />
|
||||
${v("title")?a`<div class="summary-problem error">${h(v("title"))}</div>`:e}
|
||||
@input=${a=>m.mutate(s=>{s.title=a.target.value})} />
|
||||
${v("title")?a`<div class="summary-problem error">${h(v("title"))}</div>`:s}
|
||||
</div>`}
|
||||
${g}
|
||||
${d.localOnly?e:a`<label class="summary-switch" for="summary-mobile-show">
|
||||
${d.localOnly?s:a`<label class="summary-switch" for="summary-mobile-show">
|
||||
<span class="summary-switch-caption"><strong>${b("summary.show_mobile")}</strong>
|
||||
<small id="summary-mobile-show-hint">${b("summary.show_mobile_hint")}</small></span>
|
||||
<input id="summary-mobile-show" data-summary-mobile-show type="checkbox"
|
||||
.checked=${d.draft.show_on_mobile} ?disabled=${!d.localShow||d.busy}
|
||||
aria-label=${b("summary.show_mobile")} aria-describedby="summary-mobile-show-hint"
|
||||
@change=${a=>m.mutate(e=>{e.show_on_mobile=a.target.checked})} /></label>`}
|
||||
@change=${a=>m.mutate(s=>{s.show_on_mobile=a.target.checked})} /></label>`}
|
||||
</div>
|
||||
${m.storageUnavailable?a`<div class="summary-problem warning">${b("summary.storage_unavailable")}</div>`:e}
|
||||
${m.storageUnavailable?a`<div class="summary-problem warning">${b("summary.storage_unavailable")}</div>`:s}
|
||||
</section>
|
||||
${d.localOnly?e:a`
|
||||
${d.localOnly?s:a`
|
||||
<section class="summary-blocks-card" aria-labelledby="summary-blocks-title">
|
||||
<header class="summary-blocks-heading">
|
||||
<div><h3 id="summary-blocks-title">${b("summary.blocks")}</h3>
|
||||
@@ -42,7 +42,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="c6e9a7f9c0e3096b40b9ae51df9d052aeddc
|
||||
<span class="summary-block-count">${b("summary.block_count").replace("{count}",String(d.draft.blocks.length)).replace("{limit}","10")}</span>
|
||||
</header>
|
||||
<div class="summary-editor-blocks">
|
||||
${d.draft.blocks.map((s,t)=>{const u=`blocks.${t}`,n=v(`${u}.scope`);return a`<article class="summary-editor-block"
|
||||
${d.draft.blocks.map((e,t)=>{const u=`blocks.${t}`,n=v(`${u}.scope`);return a`<article class="summary-editor-block"
|
||||
@dragover=${a=>a.preventDefault()}
|
||||
@drop=${a=>m.drop(a,`block:${t}`)}>
|
||||
<div class="summary-block-head">
|
||||
@@ -57,40 +57,40 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="c6e9a7f9c0e3096b40b9ae51df9d052aeddc
|
||||
?disabled=${t===d.draft.blocks.length-1||d.busy}
|
||||
@click=${()=>m.mutate(a=>{a.blocks=r(a.blocks,t,t+1)})}>${l("down")}</button>
|
||||
</div>
|
||||
<input class="summary-block-title" type="text" .value=${s.title}
|
||||
<input class="summary-block-title" type="text" .value=${e.title}
|
||||
placeholder=${b("summary.block_title")} aria-label=${b("summary.block_title")}
|
||||
?disabled=${d.busy}
|
||||
data-summary-error=${String(d.attempted&&y?.path===`${u}.title`)}
|
||||
aria-invalid=${"error"===v(`${u}.title`)?.kind?"true":"false"}
|
||||
@input=${a=>m.mutate(e=>{e.blocks[t].title=a.target.value})} />
|
||||
@input=${a=>m.mutate(s=>{s.blocks[t].title=a.target.value})} />
|
||||
<button class="summary-icon-button summary-visibility" type="button"
|
||||
?disabled=${d.busy} aria-pressed=${String(s.visible)}
|
||||
title=${b(s.visible?"summary.hide_block":"summary.show_block")}
|
||||
aria-label=${b(s.visible?"summary.hide_block":"summary.show_block")}
|
||||
@click=${()=>m.mutate(a=>{a.blocks[t].visible=!a.blocks[t].visible})}>${l(s.visible?"eye":"eyeOff")}</button>
|
||||
${v(`${u}.title`)?a`<div class="summary-problem error summary-block-title-error">${h(v(`${u}.title`))}</div>`:e}
|
||||
?disabled=${d.busy} aria-pressed=${String(e.visible)}
|
||||
title=${b(e.visible?"summary.hide_block":"summary.show_block")}
|
||||
aria-label=${b(e.visible?"summary.hide_block":"summary.show_block")}
|
||||
@click=${()=>m.mutate(a=>{a.blocks[t].visible=!a.blocks[t].visible})}>${l(e.visible?"eye":"eyeOff")}</button>
|
||||
${v(`${u}.title`)?a`<div class="summary-problem error summary-block-title-error">${h(v(`${u}.title`))}</div>`:s}
|
||||
<div class="summary-scope">
|
||||
<select .value=${s.scope.type} ?disabled=${d.busy}
|
||||
<select .value=${e.scope.type} ?disabled=${d.busy}
|
||||
aria-label=${b("summary.scope")}
|
||||
@change=${a=>m.mutate(e=>{e.blocks[t].scope="space"===a.target.value?{type:"space",space_id:c._space}:{type:"all"}})}>
|
||||
<option value="all" ?selected=${"all"===s.scope.type}>${b("summary.scope_all")}</option>
|
||||
<option value="space" ?selected=${"space"===s.scope.type}>${b("summary.scope_space")}</option>
|
||||
@change=${a=>m.mutate(s=>{s.blocks[t].scope="space"===a.target.value?{type:"space",space_id:c._space}:{type:"all"}})}>
|
||||
<option value="all" ?selected=${"all"===e.scope.type}>${b("summary.scope_all")}</option>
|
||||
<option value="space" ?selected=${"space"===e.scope.type}>${b("summary.scope_space")}</option>
|
||||
</select>
|
||||
${"space"===s.scope.type?a`<select .value=${s.scope.space_id}
|
||||
${"space"===e.scope.type?a`<select .value=${e.scope.space_id}
|
||||
?disabled=${d.busy} aria-label=${b("summary.scope_space")}
|
||||
data-summary-error=${String(d.attempted&&y?.path===`${u}.scope`)}
|
||||
aria-invalid=${"error"===n?.kind?"true":"false"}
|
||||
@change=${a=>m.mutate(e=>{const s=e.blocks[t].scope;"space"===s.type&&(s.space_id=a.target.value)})}>
|
||||
${c._model.some(a=>a.id===s.scope.space_id)?e:a`<option value=${s.scope.space_id} selected>${s.scope.space_id}</option>`}
|
||||
${c._model.map(e=>a`<option value=${e.id}
|
||||
?selected=${e.id===s.scope.space_id}>${e.title}</option>`)}
|
||||
</select>`:e}
|
||||
@change=${a=>m.mutate(s=>{const e=s.blocks[t].scope;"space"===e.type&&(e.space_id=a.target.value)})}>
|
||||
${c._model.some(a=>a.id===e.scope.space_id)?s:a`<option value=${e.scope.space_id} selected>${e.scope.space_id}</option>`}
|
||||
${c._model.map(s=>a`<option value=${s.id}
|
||||
?selected=${s.id===e.scope.space_id}>${s.title}</option>`)}
|
||||
</select>`:s}
|
||||
</div>
|
||||
${n?a`<div class="summary-problem summary-scope-problem ${n.kind}">${h(n)}</div>`:e}
|
||||
${n?a`<div class="summary-problem summary-scope-problem ${n.kind}">${h(n)}</div>`:s}
|
||||
</div>
|
||||
<div class="summary-block-body">
|
||||
<div class="summary-editor-values">
|
||||
${s.values.map((i,c)=>{const n=`${u}.values.${c}`,$=v(`${n}.source`),p=m.sourceToken(i.source),k=d.activeSource?.blockId===s.id&&d.activeSource.valueId===i.id,g="system"===i.source.type?b(`summary.system.${i.source.key}`):i.source.entity_id?m.entityIndex.labels.get(i.source.entity_id)||i.source.entity_id:b("summary.select_source"),_="system"===i.source.type?b("summary.system_source"):i.source.entity_id,f=k?o(m.entityIndex,d.entityFilter):null,w="entity"===i.source.type&&!!i.source.entity_id&&!m.entityIndex.labels.has(i.source.entity_id),S=`${s.id}\n${i.id}`;return a`<div class="summary-editor-value"
|
||||
${e.values.map((i,c)=>{const n=`${u}.values.${c}`,$=v(`${n}.source`),p=m.sourceToken(i.source),k=d.activeSource?.blockId===e.id&&d.activeSource.valueId===i.id,g="system"===i.source.type?b(`summary.system.${i.source.key}`):i.source.entity_id?m.entityIndex.labels.get(i.source.entity_id)||i.source.entity_id:b("summary.select_source"),_="system"===i.source.type?b("summary.system_source"):i.source.entity_id,f=k?o(m.entityIndex,d.entityFilter):null,w="entity"===i.source.type&&!!i.source.entity_id&&!m.entityIndex.labels.has(i.source.entity_id),S=`${e.id}\n${i.id}`;return a`<div class="summary-editor-value"
|
||||
@dragover=${a=>{a.preventDefault(),a.stopPropagation()}}
|
||||
@drop=${a=>m.drop(a,`value:${t}:${c}`)}>
|
||||
<span class="summary-drag" draggable=${String(!d.busy)} title=${b("summary.drag")}
|
||||
@@ -101,7 +101,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="c6e9a7f9c0e3096b40b9ae51df9d052aeddc
|
||||
@click=${()=>m.mutate(a=>{a.blocks[t].values=r(a.blocks[t].values,c,c-1)})}>${l("up")}</button>
|
||||
<button class="summary-icon-button" type="button" title=${b("summary.down")}
|
||||
aria-label=${b("summary.down")}
|
||||
?disabled=${c===s.values.length-1||d.busy}
|
||||
?disabled=${c===e.values.length-1||d.busy}
|
||||
@click=${()=>m.mutate(a=>{a.blocks[t].values=r(a.blocks[t].values,c,c+1)})}>${l("down")}</button>
|
||||
</div>
|
||||
<div class="summary-value-label">
|
||||
@@ -109,8 +109,8 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="c6e9a7f9c0e3096b40b9ae51df9d052aeddc
|
||||
placeholder=${b("summary.value_name")} aria-label=${b("summary.value_name")}
|
||||
data-summary-error=${String(d.attempted&&y?.path===`${n}.label`)}
|
||||
aria-invalid=${"error"===v(`${n}.label`)?.kind?"true":"false"}
|
||||
@input=${a=>m.mutate(e=>{e.blocks[t].values[c].label=a.target.value})} />
|
||||
${v(`${n}.label`)?a`<div class="summary-problem error">${h(v(`${n}.label`))}</div>`:e}
|
||||
@input=${a=>m.mutate(s=>{s.blocks[t].values[c].label=a.target.value})} />
|
||||
${v(`${n}.label`)?a`<div class="summary-problem error">${h(v(`${n}.label`))}</div>`:s}
|
||||
</div>
|
||||
<div class="summary-source-field">
|
||||
<button class="summary-source" type="button"
|
||||
@@ -119,9 +119,9 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="c6e9a7f9c0e3096b40b9ae51df9d052aeddc
|
||||
data-summary-error=${String(d.attempted&&y?.path===`${n}.source`)}
|
||||
aria-invalid=${"error"===$?.kind?"true":"false"}
|
||||
aria-haspopup="listbox" aria-expanded=${k?"true":"false"}
|
||||
@click=${a=>{a.stopPropagation(),k?m.closeSource():m.openSource(s.id,i.id)}}>
|
||||
@click=${a=>{a.stopPropagation(),k?m.closeSource():m.openSource(e.id,i.id)}}>
|
||||
<span class="summary-source-caption"><strong>${g}</strong>
|
||||
${_?a`<small>${_}</small>`:e}</span>
|
||||
${_?a`<small>${_}</small>`:s}</span>
|
||||
${l("chevron")}
|
||||
</button>
|
||||
${k&&f?a`<div class="summary-source-picker"
|
||||
@@ -135,39 +135,39 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="c6e9a7f9c0e3096b40b9ae51df9d052aeddc
|
||||
<div class="summary-source-results" role="listbox"
|
||||
aria-label=${b("summary.select_source")}>
|
||||
<div class="summary-source-group">${b("summary.system_group")}</div>
|
||||
${["device_count","total_area","datetime"].map(e=>a`
|
||||
${["device_count","total_area","datetime"].map(s=>a`
|
||||
<button type="button" role="option"
|
||||
?disabled=${d.busy}
|
||||
aria-selected=${p===`system:${e}`?"true":"false"}
|
||||
@click=${()=>m.setSource(s.id,i.id,`system:${e}`)}>
|
||||
${b(`summary.system.${e}`)}
|
||||
aria-selected=${p===`system:${s}`?"true":"false"}
|
||||
@click=${()=>m.setSource(e.id,i.id,`system:${s}`)}>
|
||||
${b(`summary.system.${s}`)}
|
||||
</button>`)}
|
||||
${w?a`<div class="summary-source-group">${b("summary.current_source")}</div>
|
||||
<button type="button" role="option" class="broken" aria-selected="true"
|
||||
?disabled=${d.busy}
|
||||
@click=${()=>m.setSource(s.id,i.id,p)}>
|
||||
@click=${()=>m.setSource(e.id,i.id,p)}>
|
||||
${g}
|
||||
</button>`:e}
|
||||
</button>`:s}
|
||||
<div class="summary-source-group">${b("summary.entities_group")}</div>
|
||||
${f.entries.map(e=>a`<button type="button" role="option"
|
||||
${f.entries.map(s=>a`<button type="button" role="option"
|
||||
?disabled=${d.busy}
|
||||
aria-selected=${p===`entity:${e.id}`?"true":"false"}
|
||||
@click=${()=>m.setSource(s.id,i.id,`entity:${e.id}`)}>
|
||||
<span>${e.label}</span><small>${e.id}</small>
|
||||
aria-selected=${p===`entity:${s.id}`?"true":"false"}
|
||||
@click=${()=>m.setSource(e.id,i.id,`entity:${s.id}`)}>
|
||||
<span>${s.label}</span><small>${s.id}</small>
|
||||
</button>`)}
|
||||
${f.total?e:a`<div class="summary-empty">${b("summary.no_search_results")}</div>`}
|
||||
${f.truncated?a`<div class="summary-refine">${b("summary.refine_search")}</div>`:e}
|
||||
${f.total?s:a`<div class="summary-empty">${b("summary.no_search_results")}</div>`}
|
||||
${f.truncated?a`<div class="summary-refine">${b("summary.refine_search")}</div>`:s}
|
||||
</div>
|
||||
</div>`:e}
|
||||
${$?a`<div class="summary-problem ${$.kind}">${h($)}</div>`:e}
|
||||
</div>`:s}
|
||||
${$?a`<div class="summary-problem ${$.kind}">${h($)}</div>`:s}
|
||||
</div>
|
||||
<button class="summary-icon-button summary-value-remove" type="button"
|
||||
title=${b("btn.delete")} aria-label=${b("btn.delete")} ?disabled=${d.busy}
|
||||
@click=${()=>m.mutate(a=>{a.blocks[t].values.splice(c,1)})}>${l("close")}</button>
|
||||
</div>`})}
|
||||
<button class="summary-add summary-add-value" type="button"
|
||||
?disabled=${s.values.length>=20||d.busy}
|
||||
title=${s.values.length>=20?b("summary.limit_values"):""}
|
||||
?disabled=${e.values.length>=20||d.busy}
|
||||
title=${e.values.length>=20?b("summary.limit_values"):""}
|
||||
@click=${()=>m.mutate(a=>{a.blocks[t].values.push(i())})}>
|
||||
${l("plus")}${b("summary.add_value")}
|
||||
</button>
|
||||
@@ -186,11 +186,11 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="c6e9a7f9c0e3096b40b9ae51df9d052aeddc
|
||||
${l("plus")}${b("summary.add_block")}
|
||||
</button>
|
||||
</section>
|
||||
${d.error?a`<div class="summary-problem error" role="alert">${d.error}</div>`:e}
|
||||
${d.error?a`<div class="summary-problem error" role="alert">${d.error}</div>`:s}
|
||||
${d.conflict?a`<button class="btn ghost summary-reload" type="button"
|
||||
?disabled=${d.busy} @click=${()=>m.reload()}>
|
||||
<ha-icon icon="mdi:reload"></ha-icon>${b("summary.reload_current")}
|
||||
</button>`:e}
|
||||
</button>`:s}
|
||||
`}
|
||||
</div>
|
||||
<div class="row summary-editor-footer" slot="footer">
|
||||
+1
-1
@@ -1 +1 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="c6e9a7f9c0e3096b40b9ae51df9d052aeddc8359d008fd86a2e4cbef1aba717f";import{ed as e,K as t,aX as n,I as i,ab as o,a9 as r,bO as a,bN as s,aW as c,aV as l,aY as d,ee as u,ef as f,bQ as m,eg as g}from"./houseplan-card-BWAph8ZF.js";function v(e){if(!e.registry.authoritative)return null;const t=new Set,n=d(e.markers);for(const i of Object.values(e.registry.devices||{}))i?.id&&"service"!==i.entry_type&&!n.devices.has(i.id)&&i.area_id&&e.areaToSpace[i.area_id]&&t.add(i.id);for(const i of e.markers||[]){if(i.removed||"virtual"===i.binding)continue;const o=String(i.binding||"").indexOf(":");if(o<1)continue;const r=i.binding.slice(0,o),a=i.binding.slice(o+1),s="device"===r?e.registry.devices?.[a]:null,c="entity"===r?e.registry.entities?.[a]:null,l="device"===r?a:c?.device_id,d="device"===r?s?.area_id:c?.area_id||l&&e.registry.devices?.[l]?.area_id,u="string"==typeof i.room_id&&i.room_id.length>0&&null===i.area?"":i.area||d||"",f=u&&e.areaToSpace[u]||i.space||e.firstSpaceId;l&&e.registry.devices?.[l]&&e.spaceIds.has(f)&&(!n.devices.has(l)||"entity"===r&&n.liveEntities.has(a))&&t.add(l)}return t}function y(e,t){return e?.length?t?.length?g(e,t):e:t}function _(e,t){const n=c(e.rooms,t.walls,t.openCuts,[],i,t.cellCm,o,r);return{roomGeom:"ok"===n.status||"degraded-extra"===n.status?n.roomGeom:void 0,multiWallNodes:l(e.rooms,t.walls,t.openCuts,i,t.cellCm,o,r)}}function*h(c,l,d=_){try{let u=0;for(const f of l){const l=c.spaces.find(e=>String(e?.id)===f.id);if(!l)continue;const m=e(l,f),g=d(f,m);let v=null;for(const e of f.rooms){if(!e.id)continue;const s=t(e);if(!s)continue;const c=n(f.rooms,e.id,m.walls,m.openCuts,i,m.cellCm,o,r,g.roomGeom,g.multiWallNodes)||s;v=y(v,a(c,m.physicalBodies)),yield}const _=m.cellCm/o;u+=s(v)*_*_/1e4}return u}catch{return null}}function p(e,t,n=_){const i=h(e,t,n);let o=i.next();for(;!o.done;)o=i.next();return o.value}function b(e,t,n,i){if("system"!==e.type)return null;if("device_count"===e.key)return null===t.deviceCount?null:String(t.deviceCount);if("total_area"===e.key)return null===t.areaM2?null:m(t.areaM2,"mi"===n?.config?.unit_system?.length);try{return new Intl.DateTimeFormat(i||void 0,{dateStyle:"short",timeStyle:"short",timeZone:n?.config?.time_zone||void 0}).format(t.now)}catch{return t.now.toLocaleString()}}function S(e,t){const n=e?.states?.[t];if(!n)return null;const i=u(e,t);return i?f(i,String(n.attributes?.unit_of_measurement||"")):null}export{h as cleanFloorAreaSteps,v as representedHaDeviceIds,_ as spaceWallGeometry,S as summaryEntityValue,b as summarySystemValue,p as totalCleanFloorAreaM2};
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="54fcdd48a85ca3f133f7a631e38722f7eb58d88c475a1cfb768130946dffad32";import{ed as e,J as t,aX as n,H as i,aa as o,a8 as r,bO as a,bN as s,aW as c,aV as l,aY as d,ee as u,ef as f,bQ as m,eg as g}from"./houseplan-card-9fMSy3y3.js";function v(e){if(!e.registry.authoritative)return null;const t=new Set,n=d(e.markers);for(const i of Object.values(e.registry.devices||{}))i?.id&&"service"!==i.entry_type&&!n.devices.has(i.id)&&i.area_id&&e.areaToSpace[i.area_id]&&t.add(i.id);for(const i of e.markers||[]){if(i.removed||"virtual"===i.binding)continue;const o=String(i.binding||"").indexOf(":");if(o<1)continue;const r=i.binding.slice(0,o),a=i.binding.slice(o+1),s="device"===r?e.registry.devices?.[a]:null,c="entity"===r?e.registry.entities?.[a]:null,l="device"===r?a:c?.device_id,d="device"===r?s?.area_id:c?.area_id||l&&e.registry.devices?.[l]?.area_id,u="string"==typeof i.room_id&&i.room_id.length>0&&null===i.area?"":i.area||d||"",f=u&&e.areaToSpace[u]||i.space||e.firstSpaceId;l&&e.registry.devices?.[l]&&e.spaceIds.has(f)&&(!n.devices.has(l)||"entity"===r&&n.liveEntities.has(a))&&t.add(l)}return t}function y(e,t){return e?.length?t?.length?g(e,t):e:t}function _(e,t){const n=c(e.rooms,t.walls,t.openCuts,[],i,t.cellCm,o,r);return{roomGeom:"ok"===n.status||"degraded-extra"===n.status?n.roomGeom:void 0,multiWallNodes:l(e.rooms,t.walls,t.openCuts,i,t.cellCm,o,r)}}function*h(c,l,d=_){try{let u=0;for(const f of l){const l=c.spaces.find(e=>String(e?.id)===f.id);if(!l)continue;const m=e(l,f),g=d(f,m);let v=null;for(const e of f.rooms){if(!e.id)continue;const s=t(e);if(!s)continue;const c=n(f.rooms,e.id,m.walls,m.openCuts,i,m.cellCm,o,r,g.roomGeom,g.multiWallNodes)||s;v=y(v,a(c,m.physicalBodies)),yield}const _=m.cellCm/o;u+=s(v)*_*_/1e4}return u}catch{return null}}function p(e,t,n=_){const i=h(e,t,n);let o=i.next();for(;!o.done;)o=i.next();return o.value}function b(e,t,n,i){if("system"!==e.type)return null;if("device_count"===e.key)return null===t.deviceCount?null:String(t.deviceCount);if("total_area"===e.key)return null===t.areaM2?null:m(t.areaM2,"mi"===n?.config?.unit_system?.length);try{return new Intl.DateTimeFormat(i||void 0,{dateStyle:"short",timeStyle:"short",timeZone:n?.config?.time_zone||void 0}).format(t.now)}catch{return t.now.toLocaleString()}}function S(e,t){const n=e?.states?.[t];if(!n)return null;const i=u(e,t);return i?f(i,String(n.attributes?.unit_of_measurement||"")):null}export{h as cleanFloorAreaSteps,v as representedHaDeviceIds,_ as spaceWallGeometry,S as summaryEntityValue,b as summarySystemValue,p as totalCleanFloorAreaM2};
|
||||
+2
-2
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="c6e9a7f9c0e3096b40b9ae51df9d052aeddc8359d008fd86a2e4cbef1aba717f";import{n as t,b as n}from"./zigbee-topology-D0gydI7H.js";import{aI as e}from"./houseplan-card-BWAph8ZF.js";const o=new WeakMap;function i(t){const n=function(t){const n=t?.connection||t;return!n||"object"!=typeof n&&"function"!=typeof n?null:n}(t);if(!n)return null;let e=o.get(n);return e||(e={revision:0,topologies:[],states:{},listeners:new Set,inflight:new Map},o.set(n,e)),e}function r(t,n,e){t.states={...t.states,[n]:e},function(t){t.revision++;for(const n of t.listeners)n()}(t)}function s(t){const n=t?.code;if("permission"===n||"unsupported"===n||"timeout"===n||"invalid_topic"===n||"invalid_payload"===n)return n;const e=String(t?.message||"").toLowerCase();return e.includes("unauthor")||e.includes("permission")?"permission":e.includes("unknown_command")||e.includes("not found")?"unsupported":"provider"}function a(t){return Object.assign(new Error(t),{code:t})}function c(t,n,e){const o=t.inflight.get(n);if(o)return o;r(t,n,{phase:"loading"});const i=e().then(n=>{if(!n.nodes.length&&n.warnings.some(t=>"invalid_payload"===t.code))throw a("invalid_payload");!function(t,n){t.topologies=[...t.topologies.filter(t=>!(t.provider===n.provider&&t.instanceId===n.instanceId)),n],r(t,"zha"===n.provider?"zha":`z2m:${n.instanceId}`,{phase:"ready",obtainedAt:n.obtainedAt,partial:n.warnings.length>0})}(t,n)}).catch(e=>{r(t,n,{phase:"error",error:s(e)})}).finally(()=>t.inflight.delete(n));return t.inflight.set(n,i),i}function l(t){const n=i(t);return n?{revision:n.revision,topologies:n.topologies,states:n.states}:{revision:0,topologies:[],states:{}}}function u(t,n){const e=i(t);return e?(e.listeners.add(n),()=>e.listeners.delete(n)):()=>{}}function f(t){if(!0!==t?.user?.is_admin)throw a("permission")}function p(n){const e=i(n);return e?c(e,"zha",async()=>{if(f(n),"function"!=typeof n?.callWS)throw a("unsupported");return t(await n.callWS({type:"zha/devices"}))}):Promise.resolve()}function d(t){return null!==t&&"object"==typeof t?t:null}function h(t){const n=d(t),e=n?.payload??t;if("string"!=typeof e)return e;try{return JSON.parse(e)}catch{return null}}async function m(t,n){let e;try{return await Promise.race([t,new Promise((t,o)=>{e=globalThis.setTimeout(()=>o(a("timeout")),Math.max(1,n))})])}finally{void 0!==e&&globalThis.clearTimeout(e)}}function g(t,o,r=15e4){const s=i(t);if(!s)return Promise.resolve();const l=e(o);return c(s,`z2m:${l||String(o)}`,async()=>{if(f(t),!l)throw a("invalid_topic");const e=t.connection,o=e?.subscribeMessage;if("function"!=typeof o||"function"!=typeof t?.callService)throw a("unsupported");const i=function(){const t=globalThis.crypto;return"function"==typeof t?.randomUUID?`houseplan-${t.randomUUID()}`:`houseplan-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}(),s=Date.now()+Math.max(1,r);let c=!1,u=null,p=null,g=null;const y=new Promise(t=>{u=t}),w=new Promise((t,n)=>{p=t,g=n}),b=[];try{const r=await o.call(e,t=>{!0===d(t)?.retain&&h(t)&&u?.()},{type:"mqtt/subscribe",topic:`${l}/bridge/info`});"function"==typeof r&&b.push(r);const f=await o.call(e,t=>{if(!0===d(t)?.retain)return;const n=h(t);null!==n?n&&function(t){const n=d(t),e=n?.transaction??d(n?.data)?.transaction;return"string"==typeof e||"number"==typeof e?String(e):null}(n)===i&&p?.(n):c&&g?.(a("invalid_payload"))},{type:"mqtt/subscribe",topic:`${l}/bridge/response/networkmap`});"function"==typeof f&&b.push(f),await m(y,Math.min(4e3,Math.max(1,s-Date.now()))),c=!0,await t.callService("mqtt","publish",{topic:`${l}/bridge/request/networkmap`,payload:JSON.stringify({type:"raw",routes:!1,transaction:i}),qos:0,retain:!1});const v=await m(w,s-Date.now()),_=d(v)?.status;if(_&&"ok"!==_)throw a("provider");return n(v,l)}finally{for(const t of b)try{t()}catch{}}})}export{p as readZhaTopology,g as refreshZ2mTopology,u as subscribeZigbeeTopology,l as zigbeeTopologyRuntimeSnapshot};
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="54fcdd48a85ca3f133f7a631e38722f7eb58d88c475a1cfb768130946dffad32";import{n as t,b as n}from"./zigbee-topology-CI6PJorK.js";import{aI as e}from"./houseplan-card-9fMSy3y3.js";const o=new WeakMap;function i(t){const n=function(t){const n=t?.connection||t;return!n||"object"!=typeof n&&"function"!=typeof n?null:n}(t);if(!n)return null;let e=o.get(n);return e||(e={revision:0,topologies:[],states:{},listeners:new Set,inflight:new Map},o.set(n,e)),e}function r(t,n,e){t.states={...t.states,[n]:e},function(t){t.revision++;for(const n of t.listeners)n()}(t)}function s(t){const n=t?.code;if("permission"===n||"unsupported"===n||"timeout"===n||"invalid_topic"===n||"invalid_payload"===n)return n;const e=String(t?.message||"").toLowerCase();return e.includes("unauthor")||e.includes("permission")?"permission":e.includes("unknown_command")||e.includes("not found")?"unsupported":"provider"}function a(t){return Object.assign(new Error(t),{code:t})}function c(t,n,e){const o=t.inflight.get(n);if(o)return o;r(t,n,{phase:"loading"});const i=e().then(n=>{if(!n.nodes.length&&n.warnings.some(t=>"invalid_payload"===t.code))throw a("invalid_payload");!function(t,n){t.topologies=[...t.topologies.filter(t=>!(t.provider===n.provider&&t.instanceId===n.instanceId)),n],r(t,"zha"===n.provider?"zha":`z2m:${n.instanceId}`,{phase:"ready",obtainedAt:n.obtainedAt,partial:n.warnings.length>0})}(t,n)}).catch(e=>{r(t,n,{phase:"error",error:s(e)})}).finally(()=>t.inflight.delete(n));return t.inflight.set(n,i),i}function l(t){const n=i(t);return n?{revision:n.revision,topologies:n.topologies,states:n.states}:{revision:0,topologies:[],states:{}}}function u(t,n){const e=i(t);return e?(e.listeners.add(n),()=>e.listeners.delete(n)):()=>{}}function f(t){if(!0!==t?.user?.is_admin)throw a("permission")}function p(n){const e=i(n);return e?c(e,"zha",async()=>{if(f(n),"function"!=typeof n?.callWS)throw a("unsupported");return t(await n.callWS({type:"zha/devices"}))}):Promise.resolve()}function d(t){return null!==t&&"object"==typeof t?t:null}function h(t){const n=d(t),e=n?.payload??t;if("string"!=typeof e)return e;try{return JSON.parse(e)}catch{return null}}async function m(t,n){let e;try{return await Promise.race([t,new Promise((t,o)=>{e=globalThis.setTimeout(()=>o(a("timeout")),Math.max(1,n))})])}finally{void 0!==e&&globalThis.clearTimeout(e)}}function g(t,o,r=15e4){const s=i(t);if(!s)return Promise.resolve();const l=e(o);return c(s,`z2m:${l||String(o)}`,async()=>{if(f(t),!l)throw a("invalid_topic");const e=t.connection,o=e?.subscribeMessage;if("function"!=typeof o||"function"!=typeof t?.callService)throw a("unsupported");const i=function(){const t=globalThis.crypto;return"function"==typeof t?.randomUUID?`houseplan-${t.randomUUID()}`:`houseplan-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}(),s=Date.now()+Math.max(1,r);let c=!1,u=null,p=null,g=null;const y=new Promise(t=>{u=t}),w=new Promise((t,n)=>{p=t,g=n}),b=[];try{const r=await o.call(e,t=>{!0===d(t)?.retain&&h(t)&&u?.()},{type:"mqtt/subscribe",topic:`${l}/bridge/info`});"function"==typeof r&&b.push(r);const f=await o.call(e,t=>{if(!0===d(t)?.retain)return;const n=h(t);null!==n?n&&function(t){const n=d(t),e=n?.transaction??d(n?.data)?.transaction;return"string"==typeof e||"number"==typeof e?String(e):null}(n)===i&&p?.(n):c&&g?.(a("invalid_payload"))},{type:"mqtt/subscribe",topic:`${l}/bridge/response/networkmap`});"function"==typeof f&&b.push(f),await m(y,Math.min(4e3,Math.max(1,s-Date.now()))),c=!0,await t.callService("mqtt","publish",{topic:`${l}/bridge/request/networkmap`,payload:JSON.stringify({type:"raw",routes:!1,transaction:i}),qos:0,retain:!1});const v=await m(w,s-Date.now()),_=d(v)?.status;if(_&&"ok"!==_)throw a("provider");return n(v,l)}finally{for(const t of b)try{t()}catch{}}})}export{p as readZhaTopology,g as refreshZ2mTopology,u as subscribeZigbeeTopology,l as zigbeeTopologyRuntimeSnapshot};
|
||||
@@ -1 +1 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="c6e9a7f9c0e3096b40b9ae51df9d052aeddc8359d008fd86a2e4cbef1aba717f";try{await import("./houseplan-assets/houseplan-card-BWAph8ZF.js")}catch(e){if(!customElements.get("houseplan-card")){const l=String(navigator.language||"en").toLowerCase();const m=l.startsWith("ru")?"House Plan обновился — перезагрузите страницу (Ctrl+F5).":l.startsWith("de")?"House Plan wurde aktualisiert — bitte laden Sie die Seite neu (Strg+F5).":l.startsWith("fr")?"House Plan a été mis à jour — veuillez recharger la page (Ctrl+F5).":"House Plan was updated — please reload the page (Ctrl+F5).";customElements.define("houseplan-card",class extends HTMLElement{setConfig(){}getCardSize(){return 1}connectedCallback(){this.style.cssText="display:block;box-sizing:border-box;padding:16px;border:1px solid var(--divider-color,#e0e0e0);border-radius:var(--ha-card-border-radius,12px);background:var(--card-background-color,#fff);color:var(--primary-text-color,#212121);font:14px/1.4 var(--paper-font-body1_-_font-family,sans-serif)";this.textContent=m}})}console.error("[houseplan] stale houseplan-card.js: the implementation chunk is unavailable",e)}
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="54fcdd48a85ca3f133f7a631e38722f7eb58d88c475a1cfb768130946dffad32";try{await import("./houseplan-assets/houseplan-card-9fMSy3y3.js")}catch(e){if(!customElements.get("houseplan-card")){const l=String(navigator.language||"en").toLowerCase();const m=l.startsWith("ru")?"House Plan обновился — перезагрузите страницу (Ctrl+F5).":l.startsWith("de")?"House Plan wurde aktualisiert — bitte laden Sie die Seite neu (Strg+F5).":l.startsWith("fr")?"House Plan a été mis à jour — veuillez recharger la page (Ctrl+F5).":"House Plan was updated — please reload the page (Ctrl+F5).";customElements.define("houseplan-card",class extends HTMLElement{setConfig(){}getCardSize(){return 1}connectedCallback(){this.style.cssText="display:block;box-sizing:border-box;padding:16px;border:1px solid var(--divider-color,#e0e0e0);border-radius:var(--ha-card-border-radius,12px);background:var(--card-background-color,#fff);color:var(--primary-text-color,#212121);font:14px/1.4 var(--paper-font-body1_-_font-family,sans-serif)";this.textContent=m}})}console.error("[houseplan] stale houseplan-card.js: the implementation chunk is unavailable",e)}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -98,13 +98,17 @@ const out = await page.evaluate(async () => {
|
||||
input(q('#marker-glow-brightness'), '42'); await upd();
|
||||
o.brightnessNumberWrites = c._markerDialog.glowBrightness === 42 && c._markerDialog.glowTouched === true;
|
||||
o.radiusHintWhenEmpty = c._markerDialog.glowRadius === '' && !!q('#marker-glow-radius')?.closest('.hpf-field')?.querySelector('.hpf-hint');
|
||||
// Ревью r1 M2: радиус — не условие Save. Нечисло или ноль, как на dev, при
|
||||
// сохранении молча становится общим радиусом; поле не помечается ошибкой.
|
||||
c._markerDialog = { ...c._markerDialog, glowRadius: 'x' }; await upd();
|
||||
o.badRadiusBlocksSave = saveBtn().disabled === true && !!q('#marker-glow-radius[aria-invalid="true"]')
|
||||
&& !!q('.hpf-card[data-card="light"] .hpf-error') && !!q('.hpf-status .hpf-link');
|
||||
q('.hpf-status .hpf-link').click(); await upd();
|
||||
o.reviewLinkFocusesRadius = (sr().activeElement ?? document.activeElement)?.id === 'marker-glow-radius';
|
||||
o.badRadiusDoesNotBlockSave = saveBtn().disabled === false && !q('#marker-glow-radius[aria-invalid="true"]')
|
||||
&& !q('.hpf-card[data-card="light"] .hpf-error') && !q('.hpf-status .hpf-link');
|
||||
input(q('#marker-glow-radius'), '2.5'); await upd();
|
||||
o.radiusWrites = c._markerDialog.glowRadius === '2.5' && saveBtn().disabled === false;
|
||||
// «Review N fields» ведёт к первому ошибочному полю — здесь к привязке (create-режим ниже проверяет ссылку).
|
||||
input(q('#marker-glow-radius'), '0'); await upd();
|
||||
o.zeroRadiusKeepsSaveEnabled = saveBtn().disabled === false;
|
||||
input(q('#marker-glow-radius'), ''); await upd();
|
||||
|
||||
// --- Appearance: иконка, display, бейдж, превью (Q3), размеры ----------------
|
||||
o.iconFieldHasPreview = !!q('#marker-icon') && !!q('.hpf-iconfield .hpf-iconpreview ha-icon');
|
||||
@@ -172,6 +176,8 @@ const out = await page.evaluate(async () => {
|
||||
await pickSeg('bmode', 'ha');
|
||||
o.createHaWithoutBindingIsAProblem = saveBtn().disabled === true && !!q('.hpf-status .hpf-link')
|
||||
&& !!q('.hpf-card[data-card="basics"] .hpf-error') && q('#marker-binding').getAttribute('aria-expanded') === 'true';
|
||||
q('.hpf-status .hpf-link').click(); await upd();
|
||||
o.reviewLinkFocusesBinding = (sr().activeElement ?? document.activeElement)?.id === 'marker-binding';
|
||||
await pickSeg('bmode', 'virtual');
|
||||
o.createVirtualHasHint = c._markerDialog.binding === 'virtual' && saveBtn().disabled === false
|
||||
&& !!q('input[name="bmode"]')?.closest('.hpf-field')?.querySelector('.hpf-hint');
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
// #600 AC8, дефект №5 («поповер «?» обрезается границей диалога комнаты»),
|
||||
// ревью r1 M3: свидетель, что подсказка «?» в диалоге комнаты не режется ни
|
||||
// скроллером диалога, ни поверхностью ha-dialog.
|
||||
//
|
||||
// Проверяется исполнением, а не чтением: подсказка открывается у карточки,
|
||||
// прижатой к нижнему краю короткого окна (диалог скроллится), и каждый угол её
|
||||
// прямоугольника hit-test'ом (elementsFromPoint сквозь теневые корни) попадает
|
||||
// в саму подсказку — обрезанная часть элемента не hit-test'ится. Четыре
|
||||
// комбинации: нативный <dialog> и ветка ha-dialog × Popover API и портальный
|
||||
// fallback. Ветка ha-dialog берётся заглушкой с теми же ловушками, что у
|
||||
// настоящей mwc-поверхности: transform на поверхности (ловит position: fixed) и
|
||||
// overflow: hidden с собственным скроллером содержимого. Настоящий ha-dialog
|
||||
// (#505) требует загрузки колеса HA-frontend — это отдельная приёмка владельца.
|
||||
import { launch, checkAll, finish } from './serve.mjs';
|
||||
|
||||
const { page, browser } = await launch({ width: 900, height: 620 });
|
||||
|
||||
const out = await page.evaluate(async () => {
|
||||
const o = {};
|
||||
const c = window.__card;
|
||||
const sr = () => c.shadowRoot || c.renderRoot;
|
||||
const frame = () => new Promise((r) => requestAnimationFrame(() => requestAnimationFrame(r)));
|
||||
const upd = async () => { c.requestUpdate(); await c.updateComplete; await frame(); await new Promise((r) => setTimeout(r, 40)); };
|
||||
const dlg = () => sr().querySelector('hp-dialog[data-kind="room"]');
|
||||
const helpOf = (key) => dlg()?.querySelector(`hp-help[data-help-key="${key}"]`);
|
||||
const surfaceOf = (key) => helpOf(key)?.shadowRoot?.querySelector('.tooltip')
|
||||
|| dlg()?.shadowRoot?.querySelector('[data-hp-overlay="help"]')?.shadowRoot?.querySelector('.tooltip');
|
||||
// hit-test сквозь теневые корни: есть ли в точке именно .tooltip
|
||||
const tooltipAt = (x, y) => {
|
||||
const seen = new Set();
|
||||
const visit = (root) => {
|
||||
for (const el of root.elementsFromPoint(x, y)) {
|
||||
if (seen.has(el)) continue; seen.add(el);
|
||||
if (el.classList?.contains('tooltip')) return true;
|
||||
if (el.shadowRoot && visit(el.shadowRoot)) return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
return visit(document);
|
||||
};
|
||||
const scroller = () => dlg()?.shadowRoot?.querySelector('.content')
|
||||
|| dlg()?.shadowRoot?.querySelector('ha-dialog')?.shadowRoot?.querySelector('.content');
|
||||
const probe = async (label, key) => {
|
||||
const help = helpOf(key);
|
||||
// прижать «?» к нижнему краю окна — там подсказка обязана уйти вверх, а не под срез
|
||||
help.scrollIntoView({ block: 'end' });
|
||||
await frame();
|
||||
const trigger = help.shadowRoot.querySelector('.trigger');
|
||||
trigger.click(); await frame(); await new Promise((r) => setTimeout(r, 60));
|
||||
const surface = surfaceOf(key);
|
||||
const r = surface?.getBoundingClientRect();
|
||||
const inViewport = !!r && r.width > 40 && r.height > 20 && r.left >= 0 && r.top >= 0
|
||||
&& r.right <= innerWidth && r.bottom <= innerHeight;
|
||||
// 12 px от края: у подсказки скруглённые углы (radius 9), точка в 2 px от угла — за скруглением
|
||||
const corners = r ? [[r.left + 12, r.top + 12], [r.right - 12, r.top + 12], [r.left + 12, r.bottom - 12], [r.right - 12, r.bottom - 12], [(r.left + r.right) / 2, (r.top + r.bottom) / 2]] : [];
|
||||
const hits = corners.map(([x, y]) => tooltipAt(x, y));
|
||||
o[`${label}_open`] = trigger.getAttribute('aria-expanded') === 'true' && !!surface;
|
||||
o[`${label}_insideViewport`] = inViewport;
|
||||
o[`${label}_notClipped`] = hits.length === 5 && hits.every(Boolean);
|
||||
// подсказка стоит ВНЕ скроллера содержимого: её низ ниже или верх выше «?» так, что часть
|
||||
// прямоугольника лежит за пределами видимой области скроллера — и всё равно hit-test'ится
|
||||
const sc = scroller()?.getBoundingClientRect();
|
||||
o[`${label}_crossesScrollerEdge`] = !!r && !!sc && (r.top < sc.top || r.bottom > sc.bottom);
|
||||
trigger.click(); await frame();
|
||||
};
|
||||
const openRoom = async () => {
|
||||
if (c._roomDialog) { c._roomDialogCancel(); await upd(); }
|
||||
c._setMode('plan'); await upd();
|
||||
c._openRoomEdit(c._curSpaceCfg.rooms[0]); await upd();
|
||||
c._roomFill = 'temp'; await upd();
|
||||
};
|
||||
const withFallback = async (fn) => {
|
||||
const show = Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'showPopover');
|
||||
const hide = Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'hidePopover');
|
||||
Object.defineProperty(HTMLElement.prototype, 'showPopover', { configurable: true, value: undefined });
|
||||
Object.defineProperty(HTMLElement.prototype, 'hidePopover', { configurable: true, value: undefined });
|
||||
try { await fn(); } finally {
|
||||
if (show) Object.defineProperty(HTMLElement.prototype, 'showPopover', show); else delete HTMLElement.prototype.showPopover;
|
||||
if (hide) Object.defineProperty(HTMLElement.prototype, 'hidePopover', hide); else delete HTMLElement.prototype.hidePopover;
|
||||
}
|
||||
};
|
||||
|
||||
// --- нативный <dialog> ------------------------------------------------------
|
||||
await openRoom();
|
||||
o.nativeBranch = !!dlg().shadowRoot.querySelector('dialog') && !dlg().shadowRoot.querySelector('ha-dialog');
|
||||
o.dialogScrolls = scroller().scrollHeight > scroller().clientHeight + 10;
|
||||
await probe('native_popover_sizes', 'room.sizes_section.help');
|
||||
await probe('native_popover_fill', 'room.group_fill.help');
|
||||
await withFallback(async () => {
|
||||
await probe('native_fallback_sizes', 'room.sizes_section.help');
|
||||
});
|
||||
// доказательство содержательное только если подсказка реально вышла за край скроллера
|
||||
o.native_tooltipLeavesScrollerAndStaysVisible = o.native_popover_sizes_crossesScrollerEdge === true
|
||||
&& o.native_fallback_sizes_crossesScrollerEdge === true;
|
||||
|
||||
// --- ветка ha-dialog: заглушка с ловушками настоящей mwc-поверхности --------
|
||||
customElements.define('ha-dialog', class extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
this.attachShadow({ mode: 'open' }).innerHTML = `<style>
|
||||
:host { position: fixed; inset: 0; z-index: 7; display: flex; align-items: center; justify-content: center; }
|
||||
.scrim { position: absolute; inset: 0; background: rgba(0,0,0,.32); }
|
||||
.surface { position: relative; display: flex; flex-direction: column; width: min(560px, 94vw); max-height: calc(100vh - 72px);
|
||||
overflow: hidden; transform: scale(1); border-radius: 12px; background: var(--card-background-color, #fff); }
|
||||
.head { flex: 0 0 auto; padding: 12px 16px; }
|
||||
.content { flex: 1 1 auto; min-height: 0; overflow: auto; }
|
||||
.foot { flex: 0 0 auto; }
|
||||
</style><div class="scrim"></div><div class="surface"><div class="head"><slot name="headerTitle"></slot></div>
|
||||
<div class="content"><slot></slot></div><div class="foot"><slot name="footer"></slot></div></div>`;
|
||||
}
|
||||
connectedCallback() { queueMicrotask(() => this.dispatchEvent(new CustomEvent('opened'))); }
|
||||
set open(v) { this._open = v; } get open() { return this._open; }
|
||||
});
|
||||
c._roomDialogCancel(); await upd();
|
||||
await openRoom();
|
||||
o.haDialogBranch = !!dlg().shadowRoot.querySelector('ha-dialog') && !dlg().shadowRoot.querySelector('dialog');
|
||||
o.haDialogPortalOutsideSurface = (() => {
|
||||
const portal = dlg().shadowRoot.querySelector('.overlay-portal');
|
||||
return !!portal && !dlg().shadowRoot.querySelector('ha-dialog').contains(portal);
|
||||
})();
|
||||
o.haDialogScrolls = scroller().scrollHeight > scroller().clientHeight + 10;
|
||||
await probe('ha_popover_sizes', 'room.sizes_section.help');
|
||||
await withFallback(async () => {
|
||||
await probe('ha_fallback_sizes', 'room.sizes_section.help');
|
||||
await probe('ha_fallback_fill', 'room.group_fill.help');
|
||||
});
|
||||
o.ha_tooltipLeavesScrollerAndStaysVisible = o.ha_popover_sizes_crossesScrollerEdge === true
|
||||
&& o.ha_fallback_sizes_crossesScrollerEdge === true;
|
||||
c._roomDialogCancel(); await upd();
|
||||
return o;
|
||||
});
|
||||
|
||||
checkAll(Object.fromEntries(Object.entries(out).filter(([k]) => !k.endsWith('_crossesScrollerEdge'))));
|
||||
await finish(browser, out);
|
||||
@@ -0,0 +1,71 @@
|
||||
// #600 AC2/AC9, ревью r1 M1: подписи сегментов не рвутся посреди слова ни в
|
||||
// одной из четырёх локалей ни в одном из четырёх диалогов. Смок на скролл
|
||||
// контейнера этого не видел: слово ломалось внутри кнопки, scrollWidth не рос.
|
||||
//
|
||||
// Проверка: у текстового span'а каждого варианта число клиентских прямоугольников
|
||||
// (строк) не больше числа слов — однословная подпись всегда в одну строку,
|
||||
// многословная переносится только по пробелам; кнопка при этом не выходит за
|
||||
// границы своего сегмента.
|
||||
import { launch, checkAll, finish } from './serve.mjs';
|
||||
|
||||
const { page, browser } = await launch({ width: 1280, height: 900 });
|
||||
|
||||
const out = await page.evaluate(async () => {
|
||||
const o = {};
|
||||
const c = window.__card;
|
||||
const sr = () => c.shadowRoot || c.renderRoot;
|
||||
const upd = async () => { c.requestUpdate(); await c.updateComplete; await new Promise((r) => setTimeout(r, 40)); };
|
||||
const spId = c._space;
|
||||
const closeAll = async () => {
|
||||
c._settingsDialog = null; c._spaceDialog = null; c._markerDialog = null; if (c._roomDialog) c._roomDialogCancel();
|
||||
await upd();
|
||||
};
|
||||
const open = {
|
||||
space: async () => { c._setMode('view'); c._openSpaceDialog('edit', spId); await upd(); c._spaceDialog = { ...c._spaceDialog, fillMode: 'temp', northMode: 'custom', northDeg: 35 }; await upd(); },
|
||||
settings: async () => { c._openSettingsDialog(); await upd(); },
|
||||
room: async () => {
|
||||
c._setMode('plan'); await upd();
|
||||
c._openRoomEdit(c._curSpaceCfg.rooms[0]); await upd();
|
||||
c._roomFill = 'temp'; c._roomTempSrc = ''; c._roomSrcOpen = null; await upd();
|
||||
},
|
||||
marker: async () => {
|
||||
c._setMode('devices'); await upd();
|
||||
const d = c._devices.find((x) => x.id === 'd_light1') || c._devices.find((x) => x.bindingKind === 'device') || c._devices[0];
|
||||
c._openMarkerDialog(d); await upd();
|
||||
c._markerDialog = { ...c._markerDialog, lightRole: 'always', lightRoleTouched: true, glowMode: 'fixed', glowTouched: true, valueBadgeEnabled: true, valueBadgeTouched: true };
|
||||
await upd();
|
||||
},
|
||||
};
|
||||
const wordsOf = (text) => text.trim().split(/\s+/).filter(Boolean).length;
|
||||
for (const lang of ['en', 'ru', 'de', 'fr']) {
|
||||
c._config = { ...c._config, language: lang }; await upd();
|
||||
for (const [kind, opener] of Object.entries(open)) {
|
||||
await closeAll(); await opener();
|
||||
const dlg = sr().querySelector(`hp-dialog[data-kind="${kind}"]`);
|
||||
const labels = [...(dlg?.querySelectorAll('.hpf-seg label') || [])];
|
||||
let broken = [];
|
||||
let outside = [];
|
||||
for (const label of labels) {
|
||||
const span = [...label.querySelectorAll('span')].find((s) => !s.classList.contains('hpf-line'));
|
||||
if (!span) continue;
|
||||
// span — flex-элемент (блок), у блока один прямоугольник даже при переносе:
|
||||
// строки считаются по текстовому узлу через Range.
|
||||
const range = document.createRange(); range.selectNodeContents(span);
|
||||
const lines = [...range.getClientRects()].filter((r) => r.width > 0 && r.height > 0).length;
|
||||
if (lines > wordsOf(span.textContent)) broken.push(`${lang}/${kind}: «${span.textContent.trim()}» в ${lines} строк`);
|
||||
const lb = label.getBoundingClientRect(); const sb = span.getBoundingClientRect();
|
||||
if (sb.left < lb.left - 0.5 || sb.right > lb.right + 0.5) outside.push(`${lang}/${kind}: «${span.textContent.trim()}» шире кнопки`);
|
||||
}
|
||||
o[`${lang}_${kind}_hasSegments`] = labels.length >= 2;
|
||||
o[`${lang}_${kind}_noMidWordBreak`] = broken.length === 0 || broken;
|
||||
o[`${lang}_${kind}_labelsInsideButtons`] = outside.length === 0 || outside;
|
||||
}
|
||||
}
|
||||
await closeAll();
|
||||
c._config = { ...c._config, language: 'en' }; await upd();
|
||||
return o;
|
||||
});
|
||||
|
||||
const normalized = Object.fromEntries(Object.entries(out).map(([k, v]) => [k, v === true]));
|
||||
checkAll(normalized);
|
||||
await finish(browser, out);
|
||||
Vendored
+146
-146
@@ -1,312 +1,312 @@
|
||||
{
|
||||
"schema": 1,
|
||||
"fingerprint": "c6e9a7f9c0e3096b40b9ae51df9d052aeddc8359d008fd86a2e4cbef1aba717f",
|
||||
"fingerprint": "54fcdd48a85ca3f133f7a631e38722f7eb58d88c475a1cfb768130946dffad32",
|
||||
"entry": "houseplan-card.js",
|
||||
"panelEntry": "houseplan-panel.js",
|
||||
"initialViewFiles": [
|
||||
"houseplan-assets/houseplan-card-BWAph8ZF.js",
|
||||
"houseplan-assets/houseplan-card-9fMSy3y3.js",
|
||||
"houseplan-card.js"
|
||||
],
|
||||
"initialViewGzipBytes": 289829,
|
||||
"initialViewGzipBytes": 289852,
|
||||
"initialPanelFiles": [
|
||||
"houseplan-assets/houseplan-card-BWAph8ZF.js",
|
||||
"houseplan-assets/houseplan-card-9fMSy3y3.js",
|
||||
"houseplan-panel.js"
|
||||
],
|
||||
"initialPanelGzipBytes": 291350,
|
||||
"initialPanelGzipBytes": 291374,
|
||||
"initialPanelOnlyFiles": [
|
||||
"houseplan-panel.js"
|
||||
],
|
||||
"initialPanelOnlyGzipBytes": 2323,
|
||||
"initialPanelOnlyGzipBytes": 2325,
|
||||
"lazyFiles": [
|
||||
"houseplan-assets/backdrop-pick-CtZfmF4H.js",
|
||||
"houseplan-assets/de-AkOtg0jq.js",
|
||||
"houseplan-assets/editor-_VTHnoKH.js",
|
||||
"houseplan-assets/form-kit.styles-DcvCvE8g.js",
|
||||
"houseplan-assets/fr-Ds3OdruH.js",
|
||||
"houseplan-assets/furniture-plan-art.generated-Ck1wv9qF.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-BlocE3XU.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-DYojoXE_.js",
|
||||
"houseplan-assets/hp-zigbee-topology-overlay-jGSF0zVB.js",
|
||||
"houseplan-assets/iso-scene-render-BfrsUAJf.js",
|
||||
"houseplan-assets/live-interaction-runtime-CCfHOfT8.js",
|
||||
"houseplan-assets/pdf-export-Bslsp3h0.js",
|
||||
"houseplan-assets/summary-panel-runtime-loaded-BGIJeXIz.js",
|
||||
"houseplan-assets/zigbee-topology-D0gydI7H.js",
|
||||
"houseplan-assets/zigbee-topology-runtime-BXasXMdL.js"
|
||||
"houseplan-assets/backdrop-pick-BJOCHJxe.js",
|
||||
"houseplan-assets/de-DVCIKwC0.js",
|
||||
"houseplan-assets/editor-C694OxAO.js",
|
||||
"houseplan-assets/form-kit.styles-CKUQLdmn.js",
|
||||
"houseplan-assets/fr-DHxhbm5E.js",
|
||||
"houseplan-assets/furniture-plan-art.generated-DaxkO8ol.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-AzCVhtuX.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-Dp2b84fm.js",
|
||||
"houseplan-assets/hp-zigbee-topology-overlay-CbSbT5WT.js",
|
||||
"houseplan-assets/iso-scene-render-fYqz_-Ot.js",
|
||||
"houseplan-assets/live-interaction-runtime-XyTIhKAA.js",
|
||||
"houseplan-assets/pdf-export-D3vmqIY6.js",
|
||||
"houseplan-assets/summary-panel-runtime-loaded-CX2cplA1.js",
|
||||
"houseplan-assets/zigbee-topology-CI6PJorK.js",
|
||||
"houseplan-assets/zigbee-topology-runtime-d-S2Abll.js"
|
||||
],
|
||||
"lazyGzipBytes": 459663,
|
||||
"lazyGzipBytes": 459551,
|
||||
"lazyEditorFiles": [
|
||||
"houseplan-assets/backdrop-pick-CtZfmF4H.js",
|
||||
"houseplan-assets/editor-_VTHnoKH.js",
|
||||
"houseplan-assets/form-kit.styles-DcvCvE8g.js",
|
||||
"houseplan-assets/furniture-plan-art.generated-Ck1wv9qF.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-BlocE3XU.js",
|
||||
"houseplan-assets/zigbee-topology-D0gydI7H.js"
|
||||
"houseplan-assets/backdrop-pick-BJOCHJxe.js",
|
||||
"houseplan-assets/editor-C694OxAO.js",
|
||||
"houseplan-assets/form-kit.styles-CKUQLdmn.js",
|
||||
"houseplan-assets/furniture-plan-art.generated-DaxkO8ol.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-AzCVhtuX.js",
|
||||
"houseplan-assets/zigbee-topology-CI6PJorK.js"
|
||||
],
|
||||
"lazyEditorGzipBytes": 243125,
|
||||
"lazyEditorGzipBytes": 242989,
|
||||
"lazyOnboardingFiles": [
|
||||
"houseplan-assets/backdrop-pick-CtZfmF4H.js",
|
||||
"houseplan-assets/form-kit.styles-DcvCvE8g.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-DYojoXE_.js"
|
||||
"houseplan-assets/backdrop-pick-BJOCHJxe.js",
|
||||
"houseplan-assets/form-kit.styles-CKUQLdmn.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-Dp2b84fm.js"
|
||||
],
|
||||
"lazyOnboardingGzipBytes": 33646,
|
||||
"lazyOnboardingGzipBytes": 33577,
|
||||
"lazyLocaleFiles": [
|
||||
"houseplan-assets/de-AkOtg0jq.js",
|
||||
"houseplan-assets/fr-Ds3OdruH.js"
|
||||
"houseplan-assets/de-DVCIKwC0.js",
|
||||
"houseplan-assets/fr-DHxhbm5E.js"
|
||||
],
|
||||
"lazyLocaleGzipBytes": 55372,
|
||||
"lazyLocaleGzipBytes": 55383,
|
||||
"lazyIsometricFiles": [
|
||||
"houseplan-assets/iso-scene-render-BfrsUAJf.js"
|
||||
"houseplan-assets/iso-scene-render-fYqz_-Ot.js"
|
||||
],
|
||||
"lazyIsometricGzipBytes": 17644,
|
||||
"lazyIsometricGzipBytes": 17643,
|
||||
"lazyFurnitureArtFiles": [
|
||||
"houseplan-assets/furniture-plan-art.generated-Ck1wv9qF.js"
|
||||
"houseplan-assets/furniture-plan-art.generated-DaxkO8ol.js"
|
||||
],
|
||||
"lazyFurnitureArtGzipBytes": 16945,
|
||||
"lazyFurnitureArtGzipBytes": 16942,
|
||||
"lazyPdfFiles": [
|
||||
"houseplan-assets/furniture-plan-art.generated-Ck1wv9qF.js",
|
||||
"houseplan-assets/pdf-export-Bslsp3h0.js"
|
||||
"houseplan-assets/furniture-plan-art.generated-DaxkO8ol.js",
|
||||
"houseplan-assets/pdf-export-D3vmqIY6.js"
|
||||
],
|
||||
"lazyPdfGzipBytes": 126819,
|
||||
"lazyPdfGzipBytes": 126817,
|
||||
"files": [
|
||||
{
|
||||
"path": "houseplan-assets/backdrop-pick-CtZfmF4H.js",
|
||||
"sha256": "0318781a07d46ab4852f6ab7b0fdc44c180a1b0271935e031f9a9f885de62991",
|
||||
"rawBytes": 74764,
|
||||
"gzipBytes": 24114,
|
||||
"path": "houseplan-assets/backdrop-pick-BJOCHJxe.js",
|
||||
"sha256": "c24f2896a89f71e0a4147184f93b0e69e0c22eb705b772e644e9fc131ff879f4",
|
||||
"rawBytes": 74375,
|
||||
"gzipBytes": 24031,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/form-kit.styles-DcvCvE8g.js",
|
||||
"houseplan-assets/houseplan-card-BWAph8ZF.js"
|
||||
"houseplan-assets/form-kit.styles-CKUQLdmn.js",
|
||||
"houseplan-assets/houseplan-card-9fMSy3y3.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/de-AkOtg0jq.js",
|
||||
"sha256": "21cadc32b989295b913052353b5c8049b844474028e72162f8564698c0bdb9db",
|
||||
"path": "houseplan-assets/de-DVCIKwC0.js",
|
||||
"sha256": "6f716933e452260c6e7c0c40d7193e750b6fc443f162cca5cb814c734142dde5",
|
||||
"rawBytes": 92513,
|
||||
"gzipBytes": 27927,
|
||||
"gzipBytes": 27933,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/editor-_VTHnoKH.js",
|
||||
"sha256": "881257f965ba340ab8367a3a0ffbfaf7e4509a38997c7b3b33281ff27b700907",
|
||||
"path": "houseplan-assets/editor-C694OxAO.js",
|
||||
"sha256": "f95242b8000cddf2fe1856a5518883c00a27a90c2983f228003db0189dffc1b4",
|
||||
"rawBytes": 3833,
|
||||
"gzipBytes": 1583,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-BWAph8ZF.js"
|
||||
"houseplan-assets/houseplan-card-9fMSy3y3.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/form-kit.styles-DcvCvE8g.js",
|
||||
"sha256": "5068cd6f5bd37792a593096b142ea5e9b729b0f85a1cf4d3c5722f714ff64eb2",
|
||||
"rawBytes": 23495,
|
||||
"gzipBytes": 4704,
|
||||
"path": "houseplan-assets/form-kit.styles-CKUQLdmn.js",
|
||||
"sha256": "44a654e7c905948ab4bb363514532c13e67e3e54eee37e4af0ec8447f706fbc1",
|
||||
"rawBytes": 23544,
|
||||
"gzipBytes": 4716,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/fr-Ds3OdruH.js",
|
||||
"sha256": "395585192b0478200785d46cb37805871bd0726088ca776e0f95150af595633c",
|
||||
"path": "houseplan-assets/fr-DHxhbm5E.js",
|
||||
"sha256": "f603ade3217ebe9959225379598608583ec29ab654dc257f57ae894d85ca448f",
|
||||
"rawBytes": 94824,
|
||||
"gzipBytes": 27445,
|
||||
"gzipBytes": 27450,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/furniture-plan-art.generated-Ck1wv9qF.js",
|
||||
"sha256": "2f193022979145fe8544c3c498fb8f1e9b3690fa6500fcd70a6c4f34c8a13860",
|
||||
"path": "houseplan-assets/furniture-plan-art.generated-DaxkO8ol.js",
|
||||
"sha256": "86d1074252f182c84d47285560a5b22c26724e21f21d03fbac4583973a9c11a7",
|
||||
"rawBytes": 52033,
|
||||
"gzipBytes": 16945,
|
||||
"gzipBytes": 16942,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-card-BWAph8ZF.js",
|
||||
"sha256": "ded6a4cd113062c60ed2086560b03f1cdba08884b0454c85f7140f5f51b284cb",
|
||||
"path": "houseplan-assets/houseplan-card-9fMSy3y3.js",
|
||||
"sha256": "e475fbae1c25540d2e349d4441bc963a4ff4181b8659fd491309dd1e578f716a",
|
||||
"rawBytes": 1027208,
|
||||
"gzipBytes": 289027,
|
||||
"gzipBytes": 289049,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": [
|
||||
"houseplan-assets/de-AkOtg0jq.js",
|
||||
"houseplan-assets/editor-_VTHnoKH.js",
|
||||
"houseplan-assets/fr-Ds3OdruH.js",
|
||||
"houseplan-assets/furniture-plan-art.generated-Ck1wv9qF.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-BlocE3XU.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-DYojoXE_.js",
|
||||
"houseplan-assets/hp-zigbee-topology-overlay-jGSF0zVB.js",
|
||||
"houseplan-assets/iso-scene-render-BfrsUAJf.js",
|
||||
"houseplan-assets/live-interaction-runtime-CCfHOfT8.js",
|
||||
"houseplan-assets/pdf-export-Bslsp3h0.js",
|
||||
"houseplan-assets/summary-panel-runtime-loaded-BGIJeXIz.js"
|
||||
"houseplan-assets/de-DVCIKwC0.js",
|
||||
"houseplan-assets/editor-C694OxAO.js",
|
||||
"houseplan-assets/fr-DHxhbm5E.js",
|
||||
"houseplan-assets/furniture-plan-art.generated-DaxkO8ol.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-AzCVhtuX.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-Dp2b84fm.js",
|
||||
"houseplan-assets/hp-zigbee-topology-overlay-CbSbT5WT.js",
|
||||
"houseplan-assets/iso-scene-render-fYqz_-Ot.js",
|
||||
"houseplan-assets/live-interaction-runtime-XyTIhKAA.js",
|
||||
"houseplan-assets/pdf-export-D3vmqIY6.js",
|
||||
"houseplan-assets/summary-panel-runtime-loaded-CX2cplA1.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-editor-runtime-BlocE3XU.js",
|
||||
"sha256": "1af11a5d027eec8d8a0793eae9be1713b6387d3a15c239e83f8623f87877f8a1",
|
||||
"rawBytes": 677599,
|
||||
"gzipBytes": 188352,
|
||||
"path": "houseplan-assets/houseplan-editor-runtime-AzCVhtuX.js",
|
||||
"sha256": "e84feb1cf320be8297982134d45a5adceaec5a50f95aaa884e6e53cae2664edd",
|
||||
"rawBytes": 677390,
|
||||
"gzipBytes": 188290,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/backdrop-pick-CtZfmF4H.js",
|
||||
"houseplan-assets/form-kit.styles-DcvCvE8g.js",
|
||||
"houseplan-assets/furniture-plan-art.generated-Ck1wv9qF.js",
|
||||
"houseplan-assets/houseplan-card-BWAph8ZF.js",
|
||||
"houseplan-assets/zigbee-topology-D0gydI7H.js"
|
||||
"houseplan-assets/backdrop-pick-BJOCHJxe.js",
|
||||
"houseplan-assets/form-kit.styles-CKUQLdmn.js",
|
||||
"houseplan-assets/furniture-plan-art.generated-DaxkO8ol.js",
|
||||
"houseplan-assets/houseplan-card-9fMSy3y3.js",
|
||||
"houseplan-assets/zigbee-topology-CI6PJorK.js"
|
||||
],
|
||||
"dynamicImports": [
|
||||
"houseplan-assets/zigbee-topology-runtime-BXasXMdL.js"
|
||||
"houseplan-assets/zigbee-topology-runtime-d-S2Abll.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-onboarding-runtime-DYojoXE_.js",
|
||||
"sha256": "a30a515e61b632b90005e296b23d5cc52d3266c91ce29760fbb7358180956d1c",
|
||||
"path": "houseplan-assets/houseplan-onboarding-runtime-Dp2b84fm.js",
|
||||
"sha256": "64367a8743ea22c4a9a350456878b7006ba01a346cc89eabb786e3c1d944ad3a",
|
||||
"rawBytes": 15667,
|
||||
"gzipBytes": 4828,
|
||||
"gzipBytes": 4830,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/backdrop-pick-CtZfmF4H.js",
|
||||
"houseplan-assets/form-kit.styles-DcvCvE8g.js",
|
||||
"houseplan-assets/houseplan-card-BWAph8ZF.js"
|
||||
"houseplan-assets/backdrop-pick-BJOCHJxe.js",
|
||||
"houseplan-assets/form-kit.styles-CKUQLdmn.js",
|
||||
"houseplan-assets/houseplan-card-9fMSy3y3.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/hp-zigbee-topology-overlay-jGSF0zVB.js",
|
||||
"sha256": "780e78bbb5e04de2042497fdea47f44c31f8abeef03ad7cae3aeaf0e776f0db5",
|
||||
"path": "houseplan-assets/hp-zigbee-topology-overlay-CbSbT5WT.js",
|
||||
"sha256": "b2fa73ad0fc3353630e380abe1f63f483113c7bfc5f1e634150c2f0e12b4e0cf",
|
||||
"rawBytes": 10759,
|
||||
"gzipBytes": 3684,
|
||||
"gzipBytes": 3686,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-BWAph8ZF.js",
|
||||
"houseplan-assets/zigbee-topology-D0gydI7H.js",
|
||||
"houseplan-assets/zigbee-topology-runtime-BXasXMdL.js"
|
||||
"houseplan-assets/houseplan-card-9fMSy3y3.js",
|
||||
"houseplan-assets/zigbee-topology-CI6PJorK.js",
|
||||
"houseplan-assets/zigbee-topology-runtime-d-S2Abll.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/iso-scene-render-BfrsUAJf.js",
|
||||
"sha256": "2806544f1906569d9613087eea4ca3b7017d0394147d6913f9e9998b8b4b456b",
|
||||
"path": "houseplan-assets/iso-scene-render-fYqz_-Ot.js",
|
||||
"sha256": "009a9217d1c522a5c2b6f9d5ea3450e2a77aafe52096d9c1d19902a18c6632f9",
|
||||
"rawBytes": 51983,
|
||||
"gzipBytes": 17644,
|
||||
"gzipBytes": 17643,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-BWAph8ZF.js"
|
||||
"houseplan-assets/houseplan-card-9fMSy3y3.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/live-interaction-runtime-CCfHOfT8.js",
|
||||
"sha256": "5b905320a37ded5bfb1b52a4095e6a5821644d4ce0031d2ba2374b1418be2239",
|
||||
"path": "houseplan-assets/live-interaction-runtime-XyTIhKAA.js",
|
||||
"sha256": "0fd38fd067699ea97f11565db7c4ae86c1bcc867041e7e3377408f40e741f03f",
|
||||
"rawBytes": 8216,
|
||||
"gzipBytes": 3205,
|
||||
"gzipBytes": 3209,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-BWAph8ZF.js"
|
||||
"houseplan-assets/houseplan-card-9fMSy3y3.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/pdf-export-Bslsp3h0.js",
|
||||
"sha256": "c7fc552565f6551b70366350399fbbe9bb849a588be6c293e6fb17602dabd0ae",
|
||||
"path": "houseplan-assets/pdf-export-D3vmqIY6.js",
|
||||
"sha256": "4c60cf0b34a17777c60c4849f1ee42841fb74b69466366adcf94cf97eec9ad2e",
|
||||
"rawBytes": 236247,
|
||||
"gzipBytes": 109874,
|
||||
"gzipBytes": 109875,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/furniture-plan-art.generated-Ck1wv9qF.js",
|
||||
"houseplan-assets/houseplan-card-BWAph8ZF.js"
|
||||
"houseplan-assets/furniture-plan-art.generated-DaxkO8ol.js",
|
||||
"houseplan-assets/houseplan-card-9fMSy3y3.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/summary-panel-editor-1TWzLmMH.js",
|
||||
"sha256": "b6fad5dd728b4b6cfa4b4d54989a2d9d9dd9f37aba52301332a0bf3a4e69a66b",
|
||||
"rawBytes": 14862,
|
||||
"gzipBytes": 3424,
|
||||
"path": "houseplan-assets/summary-panel-editor-CNT_mev4.js",
|
||||
"sha256": "ef5dcf22a38fb5df834dcce277de7967303b8025167527483aab726dd30f3a2c",
|
||||
"rawBytes": 14867,
|
||||
"gzipBytes": 3427,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/form-kit.styles-DcvCvE8g.js",
|
||||
"houseplan-assets/houseplan-card-BWAph8ZF.js",
|
||||
"houseplan-assets/summary-panel-runtime-loaded-BGIJeXIz.js"
|
||||
"houseplan-assets/form-kit.styles-CKUQLdmn.js",
|
||||
"houseplan-assets/houseplan-card-9fMSy3y3.js",
|
||||
"houseplan-assets/summary-panel-runtime-loaded-CX2cplA1.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/summary-panel-metrics-CsJSnPHD.js",
|
||||
"sha256": "a9c4d54e9e1d168a3dd48fd8f09d8470eafa3b9dbc825fe6f9dda5bcb34a7029",
|
||||
"path": "houseplan-assets/summary-panel-metrics-BhoEMuKv.js",
|
||||
"sha256": "0b4f1816c4069cc62f20dccaeeeceb82c139dee339782833e594e46aa768fe06",
|
||||
"rawBytes": 2611,
|
||||
"gzipBytes": 1306,
|
||||
"gzipBytes": 1308,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-BWAph8ZF.js"
|
||||
"houseplan-assets/houseplan-card-9fMSy3y3.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/summary-panel-runtime-loaded-BGIJeXIz.js",
|
||||
"sha256": "e3042c31f4e963a6c91fec76b05b1900e79360f60c246d8ce32291dd71201840",
|
||||
"path": "houseplan-assets/summary-panel-runtime-loaded-CX2cplA1.js",
|
||||
"sha256": "95e65a1d327f9d2f90796b9ae7754e0d8a64c15e44a82cefe329dca8f6115689",
|
||||
"rawBytes": 72733,
|
||||
"gzipBytes": 20171,
|
||||
"gzipBytes": 20172,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/form-kit.styles-DcvCvE8g.js",
|
||||
"houseplan-assets/houseplan-card-BWAph8ZF.js"
|
||||
"houseplan-assets/form-kit.styles-CKUQLdmn.js",
|
||||
"houseplan-assets/houseplan-card-9fMSy3y3.js"
|
||||
],
|
||||
"dynamicImports": [
|
||||
"houseplan-assets/summary-panel-editor-1TWzLmMH.js",
|
||||
"houseplan-assets/summary-panel-metrics-CsJSnPHD.js"
|
||||
"houseplan-assets/summary-panel-editor-CNT_mev4.js",
|
||||
"houseplan-assets/summary-panel-metrics-BhoEMuKv.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/zigbee-topology-D0gydI7H.js",
|
||||
"sha256": "abe70ae6d783881bc6e8bdaac98a7372d1263f206103bf7110348f83f4a8dc2a",
|
||||
"path": "houseplan-assets/zigbee-topology-CI6PJorK.js",
|
||||
"sha256": "6e503b93a48deeda46368588fd4eebf7215aa4a2928e1162747da8b3ffe4b67a",
|
||||
"rawBytes": 18962,
|
||||
"gzipBytes": 7427,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-BWAph8ZF.js"
|
||||
"houseplan-assets/houseplan-card-9fMSy3y3.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/zigbee-topology-runtime-BXasXMdL.js",
|
||||
"sha256": "c7dd23a95592651b462f8ef86d073b4aa98b6fad4ce3395b5bbeb0679bf0c76d",
|
||||
"path": "houseplan-assets/zigbee-topology-runtime-d-S2Abll.js",
|
||||
"sha256": "f6aad0abbf74532abc1c705d1268cce95048e7dbdc81a52a776a996c8b70f969",
|
||||
"rawBytes": 3942,
|
||||
"gzipBytes": 1760,
|
||||
"gzipBytes": 1764,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-BWAph8ZF.js",
|
||||
"houseplan-assets/zigbee-topology-D0gydI7H.js"
|
||||
"houseplan-assets/houseplan-card-9fMSy3y3.js",
|
||||
"houseplan-assets/zigbee-topology-CI6PJorK.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-card.js",
|
||||
"sha256": "d5d8d4cbc7b0a71e4c6ba3f4cffb2fd412a9f8ce922200659ce96ee8f70d0bc0",
|
||||
"sha256": "c796620c6d67c8fb18479291279eb410302ad541ed2b3679d59b780f74e8935b",
|
||||
"rawBytes": 1205,
|
||||
"gzipBytes": 802,
|
||||
"gzipBytes": 803,
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-BWAph8ZF.js"
|
||||
"houseplan-assets/houseplan-card-9fMSy3y3.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-panel.js",
|
||||
"sha256": "a34d397053df4099bce9aca317cfa95619c4e031796d77a1da09c15aab69a132",
|
||||
"sha256": "c134452d829194d8d630e5859f8142d345e15348a706d7a83d5d9328b0df3faa",
|
||||
"rawBytes": 6165,
|
||||
"gzipBytes": 2323,
|
||||
"gzipBytes": 2325,
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-BWAph8ZF.js"
|
||||
"houseplan-assets/houseplan-card-9fMSy3y3.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
}
|
||||
|
||||
Vendored
+16
-16
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+5
-5
@@ -1,14 +1,14 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="c6e9a7f9c0e3096b40b9ae51df9d052aeddc8359d008fd86a2e4cbef1aba717f";import{az as e,l as o,aC as t,e7 as s,A as a,e8 as i,e9 as l,ea as n,E as r,c}from"./houseplan-card-BWAph8ZF.js";class h extends e{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1,this._spacesAuthoritative=!1}setConfig(e){this._config=e}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const e=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(e?.config?.spaces||[]).map(e=>({value:e.id,label:e.title||e.id})),this._spacesAuthoritative=!0}catch{this._spaces=[],this._spacesAuthoritative=!1}finally{this._spacesLoading=!1}}}get _lang(){return o(this.hass,this._config?.language)}get _floorToken(){const e=this._config?.floor;return"number"==typeof e?`__houseplan_yaml_floor_index__:${String(e)}`:null}get _formData(){const e={...this._config},o=this._floorToken;return o?e.floor=o:Object.prototype.hasOwnProperty.call(e,"floor")||(e.floor=""),e}get _schema(){const e=this._spaces||[],o=this._lang,a=[{value:"",label:t(o,"editor.floor_none")}],i=this._floorToken;i&&a.push({value:i,label:t(o,"editor.floor_index",{index:String(this._config?.floor)})});const l="string"==typeof this._config?.floor?this._config.floor:"";l&&!e.some(e=>e.value===l)&&a.push({value:l,label:l}),a.push(...e);const n="string"==typeof this._config?.default_floor?this._config.default_floor:"",r=[...e];return n&&!e.some(e=>e.value===n)&&r.unshift({value:n,label:n}),[{name:"title",selector:{text:{}}},{name:"floor",selector:{select:{mode:"dropdown",options:a}}},e.length?{name:"default_floor",selector:{select:{mode:"dropdown",options:r}}}:{name:"default_floor",selector:{text:{}}},{name:"language",selector:{select:{mode:"dropdown",options:s(t(o,"editor.lang_auto"),this._config?.language)}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}},{name:"kiosk",selector:{boolean:{}}},{name:"cycle",selector:{number:{min:0,max:3600,step:5,mode:"box"}}}]}render(){if(!this.hass||!this._config)return a;const e=i(this,l,o(this.hass,this._config.language));if("cold"===e)return n();if("warm"===e)return r;this._loadSpaces();const s=this._lang,h={title:t(s,"editor.title"),floor:t(s,"editor.floor"),default_floor:t(s,"editor.default_floor"),language:t(s,"editor.language"),icon_size:t(s,"editor.icon_size"),show_temperature:t(s,"editor.show_temperature"),live_states:t(s,"editor.live_states"),show_signal:t(s,"editor.show_signal"),kiosk:t(s,"editor.kiosk"),cycle:t(s,"editor.cycle")},f=this._schema,_=function(e,o,t){if(!t||null===o)return null;const s="string"==typeof e?.default_floor?e.default_floor:"";return!s||o.some(e=>e.value===s)?null:s}(this._config,this._spaces,this._spacesAuthoritative),d=e=>c`<ha-form
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="54fcdd48a85ca3f133f7a631e38722f7eb58d88c475a1cfb768130946dffad32";import{az as e,l as o,aC as t,e7 as s,A as a,e8 as i,e9 as l,ea as n,E as r,c}from"./houseplan-card-9fMSy3y3.js";class f extends e{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1,this._spacesAuthoritative=!1}setConfig(e){this._config=e}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const e=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(e?.config?.spaces||[]).map(e=>({value:e.id,label:e.title||e.id})),this._spacesAuthoritative=!0}catch{this._spaces=[],this._spacesAuthoritative=!1}finally{this._spacesLoading=!1}}}get _lang(){return o(this.hass,this._config?.language)}get _floorToken(){const e=this._config?.floor;return"number"==typeof e?`__houseplan_yaml_floor_index__:${String(e)}`:null}get _formData(){const e={...this._config},o=this._floorToken;return o?e.floor=o:Object.prototype.hasOwnProperty.call(e,"floor")||(e.floor=""),e}get _schema(){const e=this._spaces||[],o=this._lang,a=[{value:"",label:t(o,"editor.floor_none")}],i=this._floorToken;i&&a.push({value:i,label:t(o,"editor.floor_index",{index:String(this._config?.floor)})});const l="string"==typeof this._config?.floor?this._config.floor:"";l&&!e.some(e=>e.value===l)&&a.push({value:l,label:l}),a.push(...e);const n="string"==typeof this._config?.default_floor?this._config.default_floor:"",r=[...e];return n&&!e.some(e=>e.value===n)&&r.unshift({value:n,label:n}),[{name:"title",selector:{text:{}}},{name:"floor",selector:{select:{mode:"dropdown",options:a}}},e.length?{name:"default_floor",selector:{select:{mode:"dropdown",options:r}}}:{name:"default_floor",selector:{text:{}}},{name:"language",selector:{select:{mode:"dropdown",options:s(t(o,"editor.lang_auto"),this._config?.language)}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}},{name:"kiosk",selector:{boolean:{}}},{name:"cycle",selector:{number:{min:0,max:3600,step:5,mode:"box"}}}]}render(){if(!this.hass||!this._config)return a;const e=i(this,l,o(this.hass,this._config.language));if("cold"===e)return n();if("warm"===e)return r;this._loadSpaces();const s=this._lang,f={title:t(s,"editor.title"),floor:t(s,"editor.floor"),default_floor:t(s,"editor.default_floor"),language:t(s,"editor.language"),icon_size:t(s,"editor.icon_size"),show_temperature:t(s,"editor.show_temperature"),live_states:t(s,"editor.live_states"),show_signal:t(s,"editor.show_signal"),kiosk:t(s,"editor.kiosk"),cycle:t(s,"editor.cycle")},h=this._schema,_=function(e,o,t){if(!t||null===o)return null;const s="string"==typeof e?.default_floor?e.default_floor:"";return!s||o.some(e=>e.value===s)?null:s}(this._config,this._spaces,this._spacesAuthoritative),d=e=>c`<ha-form
|
||||
.hass=${this.hass}
|
||||
.data=${this._formData}
|
||||
.schema=${e}
|
||||
.computeLabel=${e=>h[e.name]||e.name}
|
||||
.computeLabel=${e=>f[e.name]||e.name}
|
||||
@value-changed=${this._valueChanged}
|
||||
></ha-form>`;return c`
|
||||
${d(f.slice(0,3))}
|
||||
${d(h.slice(0,3))}
|
||||
${_?c`<div class="default-floor-error" role="alert"
|
||||
style="color:var(--error-color,#db4437);margin:-4px 0 12px;overflow-wrap:anywhere">
|
||||
${t(s,"editor.default_floor_missing",{id:_})}
|
||||
</div>`:a}
|
||||
${d(f.slice(3))}
|
||||
`}_valueChanged(e){const o={...this._config,...e.detail.value};""===o.floor?delete o.floor:o.floor===this._floorToken&&(o.floor=this._config?.floor);const t=new Event("config-changed",{bubbles:!0,composed:!0});t.detail={config:o},this.dispatchEvent(t)}}h.properties={hass:{attribute:!1},_config:{state:!0},_spaces:{state:!0}},customElements.get("houseplan-card-editor")||customElements.define("houseplan-card-editor",h);
|
||||
${d(h.slice(3))}
|
||||
`}_valueChanged(e){const o={...this._config,...e.detail.value};""===o.floor?delete o.floor:o.floor===this._floorToken&&(o.floor=this._config?.floor);const t=new Event("config-changed",{bubbles:!0,composed:!0});t.detail={config:o},this.dispatchEvent(t)}}f.properties={hass:{attribute:!1},_config:{state:!0},_spaces:{state:!0}},customElements.get("houseplan-card-editor")||customElements.define("houseplan-card-editor",f);
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+6
-6
File diff suppressed because one or more lines are too long
+145
-145
File diff suppressed because one or more lines are too long
+3
-3
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+2
-2
File diff suppressed because one or more lines are too long
+52
-52
@@ -1,4 +1,4 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="c6e9a7f9c0e3096b40b9ae51df9d052aeddc8359d008fd86a2e4cbef1aba717f";import{c as a,A as e}from"./houseplan-card-BWAph8ZF.js";import{s,n as t,a as l,m as r,b as o,c as i,d as u}from"./summary-panel-runtime-loaded-BGIJeXIz.js";import"./form-kit.styles-DcvCvE8g.js";const m=m=>{const{host:c,dialog:d,problems:n,t:b}=m,y=n.find(a=>"error"===a.kind),$=d.localShow!==d.baseLocalShow||!d.localOnly&&!s(t(d.draft),d.base),p=$&&!d.busy&&!y,v=a=>n.find(e=>e.path===a),h=a=>a?b(`summary.problem.${a.code}`):"",k=()=>m.close(),g=a`<label class="summary-switch" for="summary-local-show">
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="54fcdd48a85ca3f133f7a631e38722f7eb58d88c475a1cfb768130946dffad32";import{c as a,A as s}from"./houseplan-card-9fMSy3y3.js";import{s as e,n as t,a as l,m as r,b as o,c as i,d as u}from"./summary-panel-runtime-loaded-CX2cplA1.js";import"./form-kit.styles-CKUQLdmn.js";const m=m=>{const{host:c,dialog:d,problems:n,t:b}=m,y=n.find(a=>"error"===a.kind),$=d.localShow!==d.baseLocalShow||!d.localOnly&&!e(t(d.draft),d.base),p=$&&!d.busy&&!y,v=a=>n.find(s=>s.path===a),h=a=>a?b(`summary.problem.${a.code}`):"",k=()=>m.close(),g=a`<label class="summary-switch" for="summary-local-show">
|
||||
<span class="summary-switch-caption"><strong>${b("summary.show_local")}</strong>
|
||||
<small id="summary-local-show-hint">${b("summary.show_local_hint")}</small></span>
|
||||
<input id="summary-local-show" data-summary-local-show type="checkbox"
|
||||
@@ -10,31 +10,31 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="c6e9a7f9c0e3096b40b9ae51df9d052aeddc
|
||||
dismiss-on-scrim aria-busy=${String(d.busy)}
|
||||
@hp-close=${k}>
|
||||
<div class="body summary-editor" @click=${()=>m.closeSource()}>
|
||||
${d.localOnly?a`<p class="summary-local-hint">${b(d.localOnlyHint)}</p>`:e}
|
||||
${d.localOnly?a`<p class="summary-local-hint">${b(d.localOnlyHint)}</p>`:s}
|
||||
<section class="summary-general" aria-labelledby="summary-general-title">
|
||||
<h3 id="summary-general-title">${b("summary.general_settings")}</h3>
|
||||
<div class="summary-general-grid">
|
||||
${d.localOnly?e:a`<div class="summary-field">
|
||||
${d.localOnly?s:a`<div class="summary-field">
|
||||
<label for="summary-panel-title">${b("summary.panel_title")}</label>
|
||||
<input id="summary-panel-title" type="text" .value=${d.draft.title}
|
||||
?disabled=${d.busy}
|
||||
data-summary-error=${String(d.attempted&&"title"===y?.path)}
|
||||
aria-invalid=${"error"===v("title")?.kind?"true":"false"}
|
||||
@input=${a=>m.mutate(e=>{e.title=a.target.value})} />
|
||||
${v("title")?a`<div class="summary-problem error">${h(v("title"))}</div>`:e}
|
||||
@input=${a=>m.mutate(s=>{s.title=a.target.value})} />
|
||||
${v("title")?a`<div class="summary-problem error">${h(v("title"))}</div>`:s}
|
||||
</div>`}
|
||||
${g}
|
||||
${d.localOnly?e:a`<label class="summary-switch" for="summary-mobile-show">
|
||||
${d.localOnly?s:a`<label class="summary-switch" for="summary-mobile-show">
|
||||
<span class="summary-switch-caption"><strong>${b("summary.show_mobile")}</strong>
|
||||
<small id="summary-mobile-show-hint">${b("summary.show_mobile_hint")}</small></span>
|
||||
<input id="summary-mobile-show" data-summary-mobile-show type="checkbox"
|
||||
.checked=${d.draft.show_on_mobile} ?disabled=${!d.localShow||d.busy}
|
||||
aria-label=${b("summary.show_mobile")} aria-describedby="summary-mobile-show-hint"
|
||||
@change=${a=>m.mutate(e=>{e.show_on_mobile=a.target.checked})} /></label>`}
|
||||
@change=${a=>m.mutate(s=>{s.show_on_mobile=a.target.checked})} /></label>`}
|
||||
</div>
|
||||
${m.storageUnavailable?a`<div class="summary-problem warning">${b("summary.storage_unavailable")}</div>`:e}
|
||||
${m.storageUnavailable?a`<div class="summary-problem warning">${b("summary.storage_unavailable")}</div>`:s}
|
||||
</section>
|
||||
${d.localOnly?e:a`
|
||||
${d.localOnly?s:a`
|
||||
<section class="summary-blocks-card" aria-labelledby="summary-blocks-title">
|
||||
<header class="summary-blocks-heading">
|
||||
<div><h3 id="summary-blocks-title">${b("summary.blocks")}</h3>
|
||||
@@ -42,7 +42,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="c6e9a7f9c0e3096b40b9ae51df9d052aeddc
|
||||
<span class="summary-block-count">${b("summary.block_count").replace("{count}",String(d.draft.blocks.length)).replace("{limit}","10")}</span>
|
||||
</header>
|
||||
<div class="summary-editor-blocks">
|
||||
${d.draft.blocks.map((s,t)=>{const u=`blocks.${t}`,n=v(`${u}.scope`);return a`<article class="summary-editor-block"
|
||||
${d.draft.blocks.map((e,t)=>{const u=`blocks.${t}`,n=v(`${u}.scope`);return a`<article class="summary-editor-block"
|
||||
@dragover=${a=>a.preventDefault()}
|
||||
@drop=${a=>m.drop(a,`block:${t}`)}>
|
||||
<div class="summary-block-head">
|
||||
@@ -57,40 +57,40 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="c6e9a7f9c0e3096b40b9ae51df9d052aeddc
|
||||
?disabled=${t===d.draft.blocks.length-1||d.busy}
|
||||
@click=${()=>m.mutate(a=>{a.blocks=r(a.blocks,t,t+1)})}>${l("down")}</button>
|
||||
</div>
|
||||
<input class="summary-block-title" type="text" .value=${s.title}
|
||||
<input class="summary-block-title" type="text" .value=${e.title}
|
||||
placeholder=${b("summary.block_title")} aria-label=${b("summary.block_title")}
|
||||
?disabled=${d.busy}
|
||||
data-summary-error=${String(d.attempted&&y?.path===`${u}.title`)}
|
||||
aria-invalid=${"error"===v(`${u}.title`)?.kind?"true":"false"}
|
||||
@input=${a=>m.mutate(e=>{e.blocks[t].title=a.target.value})} />
|
||||
@input=${a=>m.mutate(s=>{s.blocks[t].title=a.target.value})} />
|
||||
<button class="summary-icon-button summary-visibility" type="button"
|
||||
?disabled=${d.busy} aria-pressed=${String(s.visible)}
|
||||
title=${b(s.visible?"summary.hide_block":"summary.show_block")}
|
||||
aria-label=${b(s.visible?"summary.hide_block":"summary.show_block")}
|
||||
@click=${()=>m.mutate(a=>{a.blocks[t].visible=!a.blocks[t].visible})}>${l(s.visible?"eye":"eyeOff")}</button>
|
||||
${v(`${u}.title`)?a`<div class="summary-problem error summary-block-title-error">${h(v(`${u}.title`))}</div>`:e}
|
||||
?disabled=${d.busy} aria-pressed=${String(e.visible)}
|
||||
title=${b(e.visible?"summary.hide_block":"summary.show_block")}
|
||||
aria-label=${b(e.visible?"summary.hide_block":"summary.show_block")}
|
||||
@click=${()=>m.mutate(a=>{a.blocks[t].visible=!a.blocks[t].visible})}>${l(e.visible?"eye":"eyeOff")}</button>
|
||||
${v(`${u}.title`)?a`<div class="summary-problem error summary-block-title-error">${h(v(`${u}.title`))}</div>`:s}
|
||||
<div class="summary-scope">
|
||||
<select .value=${s.scope.type} ?disabled=${d.busy}
|
||||
<select .value=${e.scope.type} ?disabled=${d.busy}
|
||||
aria-label=${b("summary.scope")}
|
||||
@change=${a=>m.mutate(e=>{e.blocks[t].scope="space"===a.target.value?{type:"space",space_id:c._space}:{type:"all"}})}>
|
||||
<option value="all" ?selected=${"all"===s.scope.type}>${b("summary.scope_all")}</option>
|
||||
<option value="space" ?selected=${"space"===s.scope.type}>${b("summary.scope_space")}</option>
|
||||
@change=${a=>m.mutate(s=>{s.blocks[t].scope="space"===a.target.value?{type:"space",space_id:c._space}:{type:"all"}})}>
|
||||
<option value="all" ?selected=${"all"===e.scope.type}>${b("summary.scope_all")}</option>
|
||||
<option value="space" ?selected=${"space"===e.scope.type}>${b("summary.scope_space")}</option>
|
||||
</select>
|
||||
${"space"===s.scope.type?a`<select .value=${s.scope.space_id}
|
||||
${"space"===e.scope.type?a`<select .value=${e.scope.space_id}
|
||||
?disabled=${d.busy} aria-label=${b("summary.scope_space")}
|
||||
data-summary-error=${String(d.attempted&&y?.path===`${u}.scope`)}
|
||||
aria-invalid=${"error"===n?.kind?"true":"false"}
|
||||
@change=${a=>m.mutate(e=>{const s=e.blocks[t].scope;"space"===s.type&&(s.space_id=a.target.value)})}>
|
||||
${c._model.some(a=>a.id===s.scope.space_id)?e:a`<option value=${s.scope.space_id} selected>${s.scope.space_id}</option>`}
|
||||
${c._model.map(e=>a`<option value=${e.id}
|
||||
?selected=${e.id===s.scope.space_id}>${e.title}</option>`)}
|
||||
</select>`:e}
|
||||
@change=${a=>m.mutate(s=>{const e=s.blocks[t].scope;"space"===e.type&&(e.space_id=a.target.value)})}>
|
||||
${c._model.some(a=>a.id===e.scope.space_id)?s:a`<option value=${e.scope.space_id} selected>${e.scope.space_id}</option>`}
|
||||
${c._model.map(s=>a`<option value=${s.id}
|
||||
?selected=${s.id===e.scope.space_id}>${s.title}</option>`)}
|
||||
</select>`:s}
|
||||
</div>
|
||||
${n?a`<div class="summary-problem summary-scope-problem ${n.kind}">${h(n)}</div>`:e}
|
||||
${n?a`<div class="summary-problem summary-scope-problem ${n.kind}">${h(n)}</div>`:s}
|
||||
</div>
|
||||
<div class="summary-block-body">
|
||||
<div class="summary-editor-values">
|
||||
${s.values.map((i,c)=>{const n=`${u}.values.${c}`,$=v(`${n}.source`),p=m.sourceToken(i.source),k=d.activeSource?.blockId===s.id&&d.activeSource.valueId===i.id,g="system"===i.source.type?b(`summary.system.${i.source.key}`):i.source.entity_id?m.entityIndex.labels.get(i.source.entity_id)||i.source.entity_id:b("summary.select_source"),_="system"===i.source.type?b("summary.system_source"):i.source.entity_id,f=k?o(m.entityIndex,d.entityFilter):null,w="entity"===i.source.type&&!!i.source.entity_id&&!m.entityIndex.labels.has(i.source.entity_id),S=`${s.id}\n${i.id}`;return a`<div class="summary-editor-value"
|
||||
${e.values.map((i,c)=>{const n=`${u}.values.${c}`,$=v(`${n}.source`),p=m.sourceToken(i.source),k=d.activeSource?.blockId===e.id&&d.activeSource.valueId===i.id,g="system"===i.source.type?b(`summary.system.${i.source.key}`):i.source.entity_id?m.entityIndex.labels.get(i.source.entity_id)||i.source.entity_id:b("summary.select_source"),_="system"===i.source.type?b("summary.system_source"):i.source.entity_id,f=k?o(m.entityIndex,d.entityFilter):null,w="entity"===i.source.type&&!!i.source.entity_id&&!m.entityIndex.labels.has(i.source.entity_id),S=`${e.id}\n${i.id}`;return a`<div class="summary-editor-value"
|
||||
@dragover=${a=>{a.preventDefault(),a.stopPropagation()}}
|
||||
@drop=${a=>m.drop(a,`value:${t}:${c}`)}>
|
||||
<span class="summary-drag" draggable=${String(!d.busy)} title=${b("summary.drag")}
|
||||
@@ -101,7 +101,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="c6e9a7f9c0e3096b40b9ae51df9d052aeddc
|
||||
@click=${()=>m.mutate(a=>{a.blocks[t].values=r(a.blocks[t].values,c,c-1)})}>${l("up")}</button>
|
||||
<button class="summary-icon-button" type="button" title=${b("summary.down")}
|
||||
aria-label=${b("summary.down")}
|
||||
?disabled=${c===s.values.length-1||d.busy}
|
||||
?disabled=${c===e.values.length-1||d.busy}
|
||||
@click=${()=>m.mutate(a=>{a.blocks[t].values=r(a.blocks[t].values,c,c+1)})}>${l("down")}</button>
|
||||
</div>
|
||||
<div class="summary-value-label">
|
||||
@@ -109,8 +109,8 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="c6e9a7f9c0e3096b40b9ae51df9d052aeddc
|
||||
placeholder=${b("summary.value_name")} aria-label=${b("summary.value_name")}
|
||||
data-summary-error=${String(d.attempted&&y?.path===`${n}.label`)}
|
||||
aria-invalid=${"error"===v(`${n}.label`)?.kind?"true":"false"}
|
||||
@input=${a=>m.mutate(e=>{e.blocks[t].values[c].label=a.target.value})} />
|
||||
${v(`${n}.label`)?a`<div class="summary-problem error">${h(v(`${n}.label`))}</div>`:e}
|
||||
@input=${a=>m.mutate(s=>{s.blocks[t].values[c].label=a.target.value})} />
|
||||
${v(`${n}.label`)?a`<div class="summary-problem error">${h(v(`${n}.label`))}</div>`:s}
|
||||
</div>
|
||||
<div class="summary-source-field">
|
||||
<button class="summary-source" type="button"
|
||||
@@ -119,9 +119,9 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="c6e9a7f9c0e3096b40b9ae51df9d052aeddc
|
||||
data-summary-error=${String(d.attempted&&y?.path===`${n}.source`)}
|
||||
aria-invalid=${"error"===$?.kind?"true":"false"}
|
||||
aria-haspopup="listbox" aria-expanded=${k?"true":"false"}
|
||||
@click=${a=>{a.stopPropagation(),k?m.closeSource():m.openSource(s.id,i.id)}}>
|
||||
@click=${a=>{a.stopPropagation(),k?m.closeSource():m.openSource(e.id,i.id)}}>
|
||||
<span class="summary-source-caption"><strong>${g}</strong>
|
||||
${_?a`<small>${_}</small>`:e}</span>
|
||||
${_?a`<small>${_}</small>`:s}</span>
|
||||
${l("chevron")}
|
||||
</button>
|
||||
${k&&f?a`<div class="summary-source-picker"
|
||||
@@ -135,39 +135,39 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="c6e9a7f9c0e3096b40b9ae51df9d052aeddc
|
||||
<div class="summary-source-results" role="listbox"
|
||||
aria-label=${b("summary.select_source")}>
|
||||
<div class="summary-source-group">${b("summary.system_group")}</div>
|
||||
${["device_count","total_area","datetime"].map(e=>a`
|
||||
${["device_count","total_area","datetime"].map(s=>a`
|
||||
<button type="button" role="option"
|
||||
?disabled=${d.busy}
|
||||
aria-selected=${p===`system:${e}`?"true":"false"}
|
||||
@click=${()=>m.setSource(s.id,i.id,`system:${e}`)}>
|
||||
${b(`summary.system.${e}`)}
|
||||
aria-selected=${p===`system:${s}`?"true":"false"}
|
||||
@click=${()=>m.setSource(e.id,i.id,`system:${s}`)}>
|
||||
${b(`summary.system.${s}`)}
|
||||
</button>`)}
|
||||
${w?a`<div class="summary-source-group">${b("summary.current_source")}</div>
|
||||
<button type="button" role="option" class="broken" aria-selected="true"
|
||||
?disabled=${d.busy}
|
||||
@click=${()=>m.setSource(s.id,i.id,p)}>
|
||||
@click=${()=>m.setSource(e.id,i.id,p)}>
|
||||
${g}
|
||||
</button>`:e}
|
||||
</button>`:s}
|
||||
<div class="summary-source-group">${b("summary.entities_group")}</div>
|
||||
${f.entries.map(e=>a`<button type="button" role="option"
|
||||
${f.entries.map(s=>a`<button type="button" role="option"
|
||||
?disabled=${d.busy}
|
||||
aria-selected=${p===`entity:${e.id}`?"true":"false"}
|
||||
@click=${()=>m.setSource(s.id,i.id,`entity:${e.id}`)}>
|
||||
<span>${e.label}</span><small>${e.id}</small>
|
||||
aria-selected=${p===`entity:${s.id}`?"true":"false"}
|
||||
@click=${()=>m.setSource(e.id,i.id,`entity:${s.id}`)}>
|
||||
<span>${s.label}</span><small>${s.id}</small>
|
||||
</button>`)}
|
||||
${f.total?e:a`<div class="summary-empty">${b("summary.no_search_results")}</div>`}
|
||||
${f.truncated?a`<div class="summary-refine">${b("summary.refine_search")}</div>`:e}
|
||||
${f.total?s:a`<div class="summary-empty">${b("summary.no_search_results")}</div>`}
|
||||
${f.truncated?a`<div class="summary-refine">${b("summary.refine_search")}</div>`:s}
|
||||
</div>
|
||||
</div>`:e}
|
||||
${$?a`<div class="summary-problem ${$.kind}">${h($)}</div>`:e}
|
||||
</div>`:s}
|
||||
${$?a`<div class="summary-problem ${$.kind}">${h($)}</div>`:s}
|
||||
</div>
|
||||
<button class="summary-icon-button summary-value-remove" type="button"
|
||||
title=${b("btn.delete")} aria-label=${b("btn.delete")} ?disabled=${d.busy}
|
||||
@click=${()=>m.mutate(a=>{a.blocks[t].values.splice(c,1)})}>${l("close")}</button>
|
||||
</div>`})}
|
||||
<button class="summary-add summary-add-value" type="button"
|
||||
?disabled=${s.values.length>=20||d.busy}
|
||||
title=${s.values.length>=20?b("summary.limit_values"):""}
|
||||
?disabled=${e.values.length>=20||d.busy}
|
||||
title=${e.values.length>=20?b("summary.limit_values"):""}
|
||||
@click=${()=>m.mutate(a=>{a.blocks[t].values.push(i())})}>
|
||||
${l("plus")}${b("summary.add_value")}
|
||||
</button>
|
||||
@@ -186,11 +186,11 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="c6e9a7f9c0e3096b40b9ae51df9d052aeddc
|
||||
${l("plus")}${b("summary.add_block")}
|
||||
</button>
|
||||
</section>
|
||||
${d.error?a`<div class="summary-problem error" role="alert">${d.error}</div>`:e}
|
||||
${d.error?a`<div class="summary-problem error" role="alert">${d.error}</div>`:s}
|
||||
${d.conflict?a`<button class="btn ghost summary-reload" type="button"
|
||||
?disabled=${d.busy} @click=${()=>m.reload()}>
|
||||
<ha-icon icon="mdi:reload"></ha-icon>${b("summary.reload_current")}
|
||||
</button>`:e}
|
||||
</button>`:s}
|
||||
`}
|
||||
</div>
|
||||
<div class="row summary-editor-footer" slot="footer">
|
||||
+1
-1
@@ -1 +1 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="c6e9a7f9c0e3096b40b9ae51df9d052aeddc8359d008fd86a2e4cbef1aba717f";import{ed as e,K as t,aX as n,I as i,ab as o,a9 as r,bO as a,bN as s,aW as c,aV as l,aY as d,ee as u,ef as f,bQ as m,eg as g}from"./houseplan-card-BWAph8ZF.js";function v(e){if(!e.registry.authoritative)return null;const t=new Set,n=d(e.markers);for(const i of Object.values(e.registry.devices||{}))i?.id&&"service"!==i.entry_type&&!n.devices.has(i.id)&&i.area_id&&e.areaToSpace[i.area_id]&&t.add(i.id);for(const i of e.markers||[]){if(i.removed||"virtual"===i.binding)continue;const o=String(i.binding||"").indexOf(":");if(o<1)continue;const r=i.binding.slice(0,o),a=i.binding.slice(o+1),s="device"===r?e.registry.devices?.[a]:null,c="entity"===r?e.registry.entities?.[a]:null,l="device"===r?a:c?.device_id,d="device"===r?s?.area_id:c?.area_id||l&&e.registry.devices?.[l]?.area_id,u="string"==typeof i.room_id&&i.room_id.length>0&&null===i.area?"":i.area||d||"",f=u&&e.areaToSpace[u]||i.space||e.firstSpaceId;l&&e.registry.devices?.[l]&&e.spaceIds.has(f)&&(!n.devices.has(l)||"entity"===r&&n.liveEntities.has(a))&&t.add(l)}return t}function y(e,t){return e?.length?t?.length?g(e,t):e:t}function _(e,t){const n=c(e.rooms,t.walls,t.openCuts,[],i,t.cellCm,o,r);return{roomGeom:"ok"===n.status||"degraded-extra"===n.status?n.roomGeom:void 0,multiWallNodes:l(e.rooms,t.walls,t.openCuts,i,t.cellCm,o,r)}}function*h(c,l,d=_){try{let u=0;for(const f of l){const l=c.spaces.find(e=>String(e?.id)===f.id);if(!l)continue;const m=e(l,f),g=d(f,m);let v=null;for(const e of f.rooms){if(!e.id)continue;const s=t(e);if(!s)continue;const c=n(f.rooms,e.id,m.walls,m.openCuts,i,m.cellCm,o,r,g.roomGeom,g.multiWallNodes)||s;v=y(v,a(c,m.physicalBodies)),yield}const _=m.cellCm/o;u+=s(v)*_*_/1e4}return u}catch{return null}}function p(e,t,n=_){const i=h(e,t,n);let o=i.next();for(;!o.done;)o=i.next();return o.value}function b(e,t,n,i){if("system"!==e.type)return null;if("device_count"===e.key)return null===t.deviceCount?null:String(t.deviceCount);if("total_area"===e.key)return null===t.areaM2?null:m(t.areaM2,"mi"===n?.config?.unit_system?.length);try{return new Intl.DateTimeFormat(i||void 0,{dateStyle:"short",timeStyle:"short",timeZone:n?.config?.time_zone||void 0}).format(t.now)}catch{return t.now.toLocaleString()}}function S(e,t){const n=e?.states?.[t];if(!n)return null;const i=u(e,t);return i?f(i,String(n.attributes?.unit_of_measurement||"")):null}export{h as cleanFloorAreaSteps,v as representedHaDeviceIds,_ as spaceWallGeometry,S as summaryEntityValue,b as summarySystemValue,p as totalCleanFloorAreaM2};
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="54fcdd48a85ca3f133f7a631e38722f7eb58d88c475a1cfb768130946dffad32";import{ed as e,J as t,aX as n,H as i,aa as o,a8 as r,bO as a,bN as s,aW as c,aV as l,aY as d,ee as u,ef as f,bQ as m,eg as g}from"./houseplan-card-9fMSy3y3.js";function v(e){if(!e.registry.authoritative)return null;const t=new Set,n=d(e.markers);for(const i of Object.values(e.registry.devices||{}))i?.id&&"service"!==i.entry_type&&!n.devices.has(i.id)&&i.area_id&&e.areaToSpace[i.area_id]&&t.add(i.id);for(const i of e.markers||[]){if(i.removed||"virtual"===i.binding)continue;const o=String(i.binding||"").indexOf(":");if(o<1)continue;const r=i.binding.slice(0,o),a=i.binding.slice(o+1),s="device"===r?e.registry.devices?.[a]:null,c="entity"===r?e.registry.entities?.[a]:null,l="device"===r?a:c?.device_id,d="device"===r?s?.area_id:c?.area_id||l&&e.registry.devices?.[l]?.area_id,u="string"==typeof i.room_id&&i.room_id.length>0&&null===i.area?"":i.area||d||"",f=u&&e.areaToSpace[u]||i.space||e.firstSpaceId;l&&e.registry.devices?.[l]&&e.spaceIds.has(f)&&(!n.devices.has(l)||"entity"===r&&n.liveEntities.has(a))&&t.add(l)}return t}function y(e,t){return e?.length?t?.length?g(e,t):e:t}function _(e,t){const n=c(e.rooms,t.walls,t.openCuts,[],i,t.cellCm,o,r);return{roomGeom:"ok"===n.status||"degraded-extra"===n.status?n.roomGeom:void 0,multiWallNodes:l(e.rooms,t.walls,t.openCuts,i,t.cellCm,o,r)}}function*h(c,l,d=_){try{let u=0;for(const f of l){const l=c.spaces.find(e=>String(e?.id)===f.id);if(!l)continue;const m=e(l,f),g=d(f,m);let v=null;for(const e of f.rooms){if(!e.id)continue;const s=t(e);if(!s)continue;const c=n(f.rooms,e.id,m.walls,m.openCuts,i,m.cellCm,o,r,g.roomGeom,g.multiWallNodes)||s;v=y(v,a(c,m.physicalBodies)),yield}const _=m.cellCm/o;u+=s(v)*_*_/1e4}return u}catch{return null}}function p(e,t,n=_){const i=h(e,t,n);let o=i.next();for(;!o.done;)o=i.next();return o.value}function b(e,t,n,i){if("system"!==e.type)return null;if("device_count"===e.key)return null===t.deviceCount?null:String(t.deviceCount);if("total_area"===e.key)return null===t.areaM2?null:m(t.areaM2,"mi"===n?.config?.unit_system?.length);try{return new Intl.DateTimeFormat(i||void 0,{dateStyle:"short",timeStyle:"short",timeZone:n?.config?.time_zone||void 0}).format(t.now)}catch{return t.now.toLocaleString()}}function S(e,t){const n=e?.states?.[t];if(!n)return null;const i=u(e,t);return i?f(i,String(n.attributes?.unit_of_measurement||"")):null}export{h as cleanFloorAreaSteps,v as representedHaDeviceIds,_ as spaceWallGeometry,S as summaryEntityValue,b as summarySystemValue,p as totalCleanFloorAreaM2};
|
||||
+2
-2
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="c6e9a7f9c0e3096b40b9ae51df9d052aeddc8359d008fd86a2e4cbef1aba717f";import{n as t,b as n}from"./zigbee-topology-D0gydI7H.js";import{aI as e}from"./houseplan-card-BWAph8ZF.js";const o=new WeakMap;function i(t){const n=function(t){const n=t?.connection||t;return!n||"object"!=typeof n&&"function"!=typeof n?null:n}(t);if(!n)return null;let e=o.get(n);return e||(e={revision:0,topologies:[],states:{},listeners:new Set,inflight:new Map},o.set(n,e)),e}function r(t,n,e){t.states={...t.states,[n]:e},function(t){t.revision++;for(const n of t.listeners)n()}(t)}function s(t){const n=t?.code;if("permission"===n||"unsupported"===n||"timeout"===n||"invalid_topic"===n||"invalid_payload"===n)return n;const e=String(t?.message||"").toLowerCase();return e.includes("unauthor")||e.includes("permission")?"permission":e.includes("unknown_command")||e.includes("not found")?"unsupported":"provider"}function a(t){return Object.assign(new Error(t),{code:t})}function c(t,n,e){const o=t.inflight.get(n);if(o)return o;r(t,n,{phase:"loading"});const i=e().then(n=>{if(!n.nodes.length&&n.warnings.some(t=>"invalid_payload"===t.code))throw a("invalid_payload");!function(t,n){t.topologies=[...t.topologies.filter(t=>!(t.provider===n.provider&&t.instanceId===n.instanceId)),n],r(t,"zha"===n.provider?"zha":`z2m:${n.instanceId}`,{phase:"ready",obtainedAt:n.obtainedAt,partial:n.warnings.length>0})}(t,n)}).catch(e=>{r(t,n,{phase:"error",error:s(e)})}).finally(()=>t.inflight.delete(n));return t.inflight.set(n,i),i}function l(t){const n=i(t);return n?{revision:n.revision,topologies:n.topologies,states:n.states}:{revision:0,topologies:[],states:{}}}function u(t,n){const e=i(t);return e?(e.listeners.add(n),()=>e.listeners.delete(n)):()=>{}}function f(t){if(!0!==t?.user?.is_admin)throw a("permission")}function p(n){const e=i(n);return e?c(e,"zha",async()=>{if(f(n),"function"!=typeof n?.callWS)throw a("unsupported");return t(await n.callWS({type:"zha/devices"}))}):Promise.resolve()}function d(t){return null!==t&&"object"==typeof t?t:null}function h(t){const n=d(t),e=n?.payload??t;if("string"!=typeof e)return e;try{return JSON.parse(e)}catch{return null}}async function m(t,n){let e;try{return await Promise.race([t,new Promise((t,o)=>{e=globalThis.setTimeout(()=>o(a("timeout")),Math.max(1,n))})])}finally{void 0!==e&&globalThis.clearTimeout(e)}}function g(t,o,r=15e4){const s=i(t);if(!s)return Promise.resolve();const l=e(o);return c(s,`z2m:${l||String(o)}`,async()=>{if(f(t),!l)throw a("invalid_topic");const e=t.connection,o=e?.subscribeMessage;if("function"!=typeof o||"function"!=typeof t?.callService)throw a("unsupported");const i=function(){const t=globalThis.crypto;return"function"==typeof t?.randomUUID?`houseplan-${t.randomUUID()}`:`houseplan-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}(),s=Date.now()+Math.max(1,r);let c=!1,u=null,p=null,g=null;const y=new Promise(t=>{u=t}),w=new Promise((t,n)=>{p=t,g=n}),b=[];try{const r=await o.call(e,t=>{!0===d(t)?.retain&&h(t)&&u?.()},{type:"mqtt/subscribe",topic:`${l}/bridge/info`});"function"==typeof r&&b.push(r);const f=await o.call(e,t=>{if(!0===d(t)?.retain)return;const n=h(t);null!==n?n&&function(t){const n=d(t),e=n?.transaction??d(n?.data)?.transaction;return"string"==typeof e||"number"==typeof e?String(e):null}(n)===i&&p?.(n):c&&g?.(a("invalid_payload"))},{type:"mqtt/subscribe",topic:`${l}/bridge/response/networkmap`});"function"==typeof f&&b.push(f),await m(y,Math.min(4e3,Math.max(1,s-Date.now()))),c=!0,await t.callService("mqtt","publish",{topic:`${l}/bridge/request/networkmap`,payload:JSON.stringify({type:"raw",routes:!1,transaction:i}),qos:0,retain:!1});const v=await m(w,s-Date.now()),_=d(v)?.status;if(_&&"ok"!==_)throw a("provider");return n(v,l)}finally{for(const t of b)try{t()}catch{}}})}export{p as readZhaTopology,g as refreshZ2mTopology,u as subscribeZigbeeTopology,l as zigbeeTopologyRuntimeSnapshot};
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="54fcdd48a85ca3f133f7a631e38722f7eb58d88c475a1cfb768130946dffad32";import{n as t,b as n}from"./zigbee-topology-CI6PJorK.js";import{aI as e}from"./houseplan-card-9fMSy3y3.js";const o=new WeakMap;function i(t){const n=function(t){const n=t?.connection||t;return!n||"object"!=typeof n&&"function"!=typeof n?null:n}(t);if(!n)return null;let e=o.get(n);return e||(e={revision:0,topologies:[],states:{},listeners:new Set,inflight:new Map},o.set(n,e)),e}function r(t,n,e){t.states={...t.states,[n]:e},function(t){t.revision++;for(const n of t.listeners)n()}(t)}function s(t){const n=t?.code;if("permission"===n||"unsupported"===n||"timeout"===n||"invalid_topic"===n||"invalid_payload"===n)return n;const e=String(t?.message||"").toLowerCase();return e.includes("unauthor")||e.includes("permission")?"permission":e.includes("unknown_command")||e.includes("not found")?"unsupported":"provider"}function a(t){return Object.assign(new Error(t),{code:t})}function c(t,n,e){const o=t.inflight.get(n);if(o)return o;r(t,n,{phase:"loading"});const i=e().then(n=>{if(!n.nodes.length&&n.warnings.some(t=>"invalid_payload"===t.code))throw a("invalid_payload");!function(t,n){t.topologies=[...t.topologies.filter(t=>!(t.provider===n.provider&&t.instanceId===n.instanceId)),n],r(t,"zha"===n.provider?"zha":`z2m:${n.instanceId}`,{phase:"ready",obtainedAt:n.obtainedAt,partial:n.warnings.length>0})}(t,n)}).catch(e=>{r(t,n,{phase:"error",error:s(e)})}).finally(()=>t.inflight.delete(n));return t.inflight.set(n,i),i}function l(t){const n=i(t);return n?{revision:n.revision,topologies:n.topologies,states:n.states}:{revision:0,topologies:[],states:{}}}function u(t,n){const e=i(t);return e?(e.listeners.add(n),()=>e.listeners.delete(n)):()=>{}}function f(t){if(!0!==t?.user?.is_admin)throw a("permission")}function p(n){const e=i(n);return e?c(e,"zha",async()=>{if(f(n),"function"!=typeof n?.callWS)throw a("unsupported");return t(await n.callWS({type:"zha/devices"}))}):Promise.resolve()}function d(t){return null!==t&&"object"==typeof t?t:null}function h(t){const n=d(t),e=n?.payload??t;if("string"!=typeof e)return e;try{return JSON.parse(e)}catch{return null}}async function m(t,n){let e;try{return await Promise.race([t,new Promise((t,o)=>{e=globalThis.setTimeout(()=>o(a("timeout")),Math.max(1,n))})])}finally{void 0!==e&&globalThis.clearTimeout(e)}}function g(t,o,r=15e4){const s=i(t);if(!s)return Promise.resolve();const l=e(o);return c(s,`z2m:${l||String(o)}`,async()=>{if(f(t),!l)throw a("invalid_topic");const e=t.connection,o=e?.subscribeMessage;if("function"!=typeof o||"function"!=typeof t?.callService)throw a("unsupported");const i=function(){const t=globalThis.crypto;return"function"==typeof t?.randomUUID?`houseplan-${t.randomUUID()}`:`houseplan-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}(),s=Date.now()+Math.max(1,r);let c=!1,u=null,p=null,g=null;const y=new Promise(t=>{u=t}),w=new Promise((t,n)=>{p=t,g=n}),b=[];try{const r=await o.call(e,t=>{!0===d(t)?.retain&&h(t)&&u?.()},{type:"mqtt/subscribe",topic:`${l}/bridge/info`});"function"==typeof r&&b.push(r);const f=await o.call(e,t=>{if(!0===d(t)?.retain)return;const n=h(t);null!==n?n&&function(t){const n=d(t),e=n?.transaction??d(n?.data)?.transaction;return"string"==typeof e||"number"==typeof e?String(e):null}(n)===i&&p?.(n):c&&g?.(a("invalid_payload"))},{type:"mqtt/subscribe",topic:`${l}/bridge/response/networkmap`});"function"==typeof f&&b.push(f),await m(y,Math.min(4e3,Math.max(1,s-Date.now()))),c=!0,await t.callService("mqtt","publish",{topic:`${l}/bridge/request/networkmap`,payload:JSON.stringify({type:"raw",routes:!1,transaction:i}),qos:0,retain:!1});const v=await m(w,s-Date.now()),_=d(v)?.status;if(_&&"ok"!==_)throw a("provider");return n(v,l)}finally{for(const t of b)try{t()}catch{}}})}export{p as readZhaTopology,g as refreshZ2mTopology,u as subscribeZigbeeTopology,l as zigbeeTopologyRuntimeSnapshot};
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="c6e9a7f9c0e3096b40b9ae51df9d052aeddc8359d008fd86a2e4cbef1aba717f";try{await import("./houseplan-assets/houseplan-card-BWAph8ZF.js")}catch(e){if(!customElements.get("houseplan-card")){const l=String(navigator.language||"en").toLowerCase();const m=l.startsWith("ru")?"House Plan обновился — перезагрузите страницу (Ctrl+F5).":l.startsWith("de")?"House Plan wurde aktualisiert — bitte laden Sie die Seite neu (Strg+F5).":l.startsWith("fr")?"House Plan a été mis à jour — veuillez recharger la page (Ctrl+F5).":"House Plan was updated — please reload the page (Ctrl+F5).";customElements.define("houseplan-card",class extends HTMLElement{setConfig(){}getCardSize(){return 1}connectedCallback(){this.style.cssText="display:block;box-sizing:border-box;padding:16px;border:1px solid var(--divider-color,#e0e0e0);border-radius:var(--ha-card-border-radius,12px);background:var(--card-background-color,#fff);color:var(--primary-text-color,#212121);font:14px/1.4 var(--paper-font-body1_-_font-family,sans-serif)";this.textContent=m}})}console.error("[houseplan] stale houseplan-card.js: the implementation chunk is unavailable",e)}
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="54fcdd48a85ca3f133f7a631e38722f7eb58d88c475a1cfb768130946dffad32";try{await import("./houseplan-assets/houseplan-card-9fMSy3y3.js")}catch(e){if(!customElements.get("houseplan-card")){const l=String(navigator.language||"en").toLowerCase();const m=l.startsWith("ru")?"House Plan обновился — перезагрузите страницу (Ctrl+F5).":l.startsWith("de")?"House Plan wurde aktualisiert — bitte laden Sie die Seite neu (Strg+F5).":l.startsWith("fr")?"House Plan a été mis à jour — veuillez recharger la page (Ctrl+F5).":"House Plan was updated — please reload the page (Ctrl+F5).";customElements.define("houseplan-card",class extends HTMLElement{setConfig(){}getCardSize(){return 1}connectedCallback(){this.style.cssText="display:block;box-sizing:border-box;padding:16px;border:1px solid var(--divider-color,#e0e0e0);border-radius:var(--ha-card-border-radius,12px);background:var(--card-background-color,#fff);color:var(--primary-text-color,#212121);font:14px/1.4 var(--paper-font-body1_-_font-family,sans-serif)";this.textContent=m}})}console.error("[houseplan] stale houseplan-card.js: the implementation chunk is unavailable",e)}
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+2
-2
@@ -19,8 +19,8 @@
|
||||
switch — turning it off opens a five-mode segment that starts at the space's
|
||||
current mode; comfort bounds are two °C fields with a Cold / Comfort / Hot
|
||||
legend. **Save** is enabled only when something changed, and closing a
|
||||
dialog with unsaved changes asks first; broken values (an inverted or empty
|
||||
bound, a north outside 0–359°, a missing binding, a non-positive glow radius)
|
||||
dialog with unsaved changes asks first; broken values (an empty or
|
||||
non-numeric bound, a north outside 0–359°, a missing binding)
|
||||
are named under the field and a "Review N fields" link in the footer jumps
|
||||
to the first one. The "Ask for confirmation" row is shown only for actions
|
||||
that do something; the Zigbee links card no longer repeats its heading; the
|
||||
|
||||
@@ -27,8 +27,7 @@
|
||||
два поля °C с легендой «Холодно / Комфорт / Жарко». **Сохранить** активна
|
||||
только при изменениях, закрытие с несохранёнными изменениями сначала
|
||||
спрашивает; сломанные значения (пустая или нечисловая граница, север вне
|
||||
0–359°, не выбранная привязка, неположительный радиус свечения) названы под
|
||||
полем, а ссылка «Проверить N полей» в футере ведёт к первому. Строка
|
||||
0–359°, не выбранная привязка) названы под полем, а ссылка «Проверить N полей» в футере ведёт к первому. Строка
|
||||
«Спрашивать подтверждение» показывается только у действий; карточка «Связи
|
||||
Zigbee» больше не повторяет заголовок; ленивый редактор загружается с простым
|
||||
«Загрузка…». Все настройки, ключи и сохранённые значения прежние — переделаны
|
||||
|
||||
+3
-2
@@ -463,7 +463,7 @@ elements:
|
||||
changes". Closing a dialog with unsaved changes — by the close button,
|
||||
**Cancel** or a click outside — asks first whether to discard them. An invalid
|
||||
value — an empty or non-numeric temperature bound, a north outside 0–359°, a
|
||||
missing binding, a non-positive glow radius — is named in red under the field,
|
||||
missing binding — is named in red under the field,
|
||||
and the **Review N fields** link in the footer jumps to the first one.
|
||||
|
||||
### Display settings
|
||||
@@ -793,7 +793,8 @@ chosen, Save stays disabled and the reason is written under the field.
|
||||
**Ask for confirmation** is shown only for actions that do something (toggle or
|
||||
run). The light-source role and the glow mode are segments; with **Never** the
|
||||
whole glow block is dimmed and explains why. The glow radius is a field with a
|
||||
unit — empty means the general radius, and the hint names it. The dialog shows
|
||||
unit — empty means the general radius, and the hint names it; a value that is
|
||||
not a positive number is saved as the general radius too, as before. The dialog shows
|
||||
binding provenance, exact next tap result, skipped targets and a live
|
||||
presentation preview in a tinted **Display preview** block. Icon size and
|
||||
rotation are two sliders with numbers. A saved missing source is shown as
|
||||
|
||||
@@ -409,9 +409,9 @@ Zigbee2MQTT для каждого указанного базового топи
|
||||
написано «Есть несохранённые изменения». Если закрыть диалог крестиком,
|
||||
кнопкой **Отмена** или щелчком мимо него при несохранённых изменениях, House
|
||||
Plan сначала спросит, сбросить ли их. Неверное значение — пустая или нечисловая
|
||||
граница температуры, север вне 0–359°, не выбранная привязка, неположительный
|
||||
радиус свечения — подписано под полем красным, а ссылка **Проверить N полей** в
|
||||
футере ведёт к первому такому полю.
|
||||
граница температуры, север вне 0–359°, не выбранная привязка — подписано под
|
||||
полем красным, а ссылка **Проверить N полей** в футере ведёт к первому такому
|
||||
полю.
|
||||
|
||||
<!-- docs-section: input -->
|
||||
|
||||
@@ -524,9 +524,9 @@ desktop: для точного рисования, Resize, модификато
|
||||
| Масштаб | См или дюймов на клетку | Переводит сетку в реальные размеры и площади; новое пространство начинается с 1 см или 1 дюйма по системе единиц HA |
|
||||
| Внешний вид | Всегда отображать границы комнат | Строка с тумблером: рисует контуры комнат в просмотре |
|
||||
| Внешний вид | Стены нулевой толщины | Сегмент «Пунктирные / Сплошные» с образцом линии |
|
||||
| Внешний вид | Видимые слои | Две строки с тумблерами: **Декоративный слой** и **Двери, окна и ворота**. Включено — видно; выключенный декоративный слой не рисует линии, фигуры, текст и мебель в просмотре, выключенные проёмы скрывают только их символы — свет, солнечные лучи и датчики продолжают работать |
|
||||
| Внешний вид | Видимые слои | Две строки с тумблерами: **Декоративный слой** и **Двери, окна и ворота**. Включено — видно; выключенный декоративный слой не рисует линии, фигуры, текст и мебель в просмотре (в редакторе подложки они остаются видимыми), выключенные проёмы скрывают только их символы — свет, солнечные лучи и датчики продолжают работать |
|
||||
| Карточки комнат | Показывать названия комнат | Рисует карточки комнат в Просмотре, киоске и статической карточке; при выключении не оставляет упрощённых подписей |
|
||||
| Карточки комнат | Сигнал Zigbee рядом с устройствами | Переопределяет базовую настройку карточки для этого пространства |ожки они остаются видимыми |
|
||||
| Карточки комнат | Сигнал Zigbee рядом с устройствами | Переопределяет базовую настройку карточки для этого пространства |
|
||||
| Карточки комнат | Температура / влажность / сигнал / свет | Четыре плитки под тумблером названий добавляют показатели под названием комнаты; без названий плитки неактивны, а сообщение предлагает включить их |
|
||||
| Карточки комнат | Размер шрифта карточек | Слайдер с числом и «Сбросить до 100%»: масштабирует все комнатные карточки пространства, 50–300%; ниже — образец карточки |
|
||||
|
||||
@@ -1071,7 +1071,7 @@ binding tombstone не вырезает её из живого устройст
|
||||
| Использовать температуру climate | Добавляет `current_temperature` термостата/кондиционера в маркер и среднее назначенной ему комнаты |
|
||||
| Скрыть / Показать | Кнопка слева в футере диалога. После сохранения убирает или возвращает значок; LQI и климатические данные скрытого устройства всё ещё могут участвовать в среднем назначенной комнаты |
|
||||
| Удалить | Кнопка рядом со «Скрыть». Общий диалог House Plan называет устройство и объясняет последствия; после подтверждения устройство полностью исчезает с плана и позднее может быть добавлено заново |
|
||||
| Радиус свечения | Поле с единицей; пустое — общий радиус, подсказка называет его. Локально переопределяет общий радиус, 0.1–100 м в хранилище |
|
||||
| Радиус свечения | Поле с единицей; пустое — общий радиус, подсказка называет его; значение, не являющееся положительным числом, тоже сохраняется как общий радиус, как и раньше. Локально переопределяет общий радиус, 0.1–100 м в хранилище |
|
||||
| Иконка | Ручная `mdi:*`; пусто — автоматический подбор. Автовариант показывается в поле как значок с именем `mdi:*`, но не сохраняется как ручная замена |
|
||||
| Отображение | Иконка, иконка + активность или значение вместо иконки. Ниже сразу видны фактический результат, источник и интеграция |
|
||||
| Размер и поворот иконки | Два слайдера с числами: масштаб маркера (×0.5–×3) и угол (шаг 5°) |
|
||||
@@ -1731,7 +1731,7 @@ WebP и безопасный SVG; лимит 2 МиБ относится к со
|
||||
| Толстая внешняя стена, режим «внутренние углы» | Луч начинается с комнатной стороны оконного тоннеля |
|
||||
| Толстая внешняя стена, режим «внешние углы» | Луч начинается с фасадной стороны и проходит к комнате только внутри оконного тоннеля |
|
||||
| Стена нулевой толщины | Оба режима выглядят одинаково |
|
||||
| «Скрыть проёмы» включено | Символ окна скрыт, луч продолжает работать |
|
||||
| Слой «Двери, окна и ворота» выключен | Символ окна скрыт, луч продолжает работать |
|
||||
| Белый план | По бокам луча есть тонкая 1px тёмная кромка для читаемости |
|
||||
| Любая погода, включая дождь и снег | Погода не влияет на лучи |
|
||||
|
||||
|
||||
@@ -25,8 +25,11 @@ Always и фиксированным свечением), раскрывает
|
||||
из архива дизайнера (светлая тема, 1120 px при devicePixelRatio 2).
|
||||
|
||||
Это **диагностические** кадры, а не golden-базы: они не принимаются
|
||||
`golden:accept` и не участвуют в `golden:verify`. Эталоны одиннадцати сцен живут
|
||||
отдельно и закрываются AC10. PNG пережаты в палитру 256 цветов — для сравнения
|
||||
`golden:accept` и не участвуют в `golden:verify`. Эталоны живут отдельно и
|
||||
закрываются AC10: принято **13 сцен** (`ed2af1b1`) — одиннадцать из ТЗ (список
|
||||
AC10 унаследован от #598, где диалог комнаты не менялся) плюс две
|
||||
`room-temperature-dialog-{desktop-en,mobile-ru}`, потому что диалог комнаты в
|
||||
скоупе #600. PNG пережаты в палитру 256 цветов — для сравнения
|
||||
раскладки этого достаточно, а вес папки остаётся в полумегабайте.
|
||||
|
||||
## Статус по диалогам
|
||||
@@ -66,7 +69,7 @@ Always и фиксированным свечением), раскрывает
|
||||
|---|---|---|---|
|
||||
| Образец карточки | убран (§6.1 «Font sizes») | под подсказкой размеров, на тинте | решение владельца Q2 |
|
||||
| «?» у Basics | у поля Home Assistant area | у поля Home Assistant area (перенесён с заголовка карточки) | §6.1 |
|
||||
| Подписи сегмента заливки | None · Zigbee · Lights · Temperature · Custom | None · Zigbee · Lights · Temperature · Custom (короткие ключи `room.fill_seg_*` для двух длинных) | §6.1 |
|
||||
| Подписи сегмента заливки | None · Zigbee · Lights · Temperature · Custom, по одной строке на пункт | те же (короткие ключи `room.fill_seg_*` для двух длинных). Ревью r1 M1: «Temperature» рвалось посреди слова в пяти равных колонках — колонка сегмента больше не сжимается ниже самого длинного слова, слова переносятся только по пробелам, не поместившийся сегмент переносится на вторую строку целыми кнопками; свидетель — `smoke_dialog_segments_i18n` (четыре диалога × en/ru/de/fr) | §6.1, §3.1 «Сегмент» |
|
||||
| Подписи источников | Temperature / Humidity | Temperature source / Humidity source (прежние ключи) | текст, не раскладка |
|
||||
| Поле цвета «Свой цвет» | `input[type=color]` | плашка вокруг `hp-color-opacity` | Q5 |
|
||||
| Кнопка выбора датчика | в потоке, панель с поиском | то же (`sourcePicker` набора) | §3.1 «Кнопка выбора источника» |
|
||||
@@ -83,6 +86,20 @@ Always и фиксированным свечением), раскрывает
|
||||
| Иконка | поле с превью, Clear, Pin в подсказке | то же; в HA — `ha-icon-picker` вместо текстового поля | §7.1 |
|
||||
| Value badge | тумблер, Value, Position сегментом | то же; предупреждения бейджа — заметки и callout'ы | §7.1 |
|
||||
|
||||
## AC8: девять прямых дефектов выпущенного — свидетель на каждый
|
||||
|
||||
| № | Дефект (тело issue) | Чем закрыт | Свидетель |
|
||||
|---|---|---|---|
|
||||
| 1 | дублированный заголовок Zigbee links | карточка рисует заголовок и «?», `hp-zigbee-topology-settings` в режиме `embedded` своего не рисует | `smoke_general_settings_form` → `zigbeeHeadingOnce`; мутант `topology-embedded-draws-its-own-heading` |
|
||||
| 2 | «Fill color» дважды в строке заливки пространства | плашка цвета с одной подписью поля (`colorRow` + `colorField`, у пикера `hide-label`) | `smoke_space_settings_form` → `hexIsPrinted`, `noNativeColorInputs`; `noLegacyMarkup` |
|
||||
| 3 | семь `rhint`-абзацев в четырёх диалогах | пояснения — под «?» (`_help`/`shelp`), сообщения о состоянии — callout'ы (К5) | `noLegacyMarkup` в четырёх фокусных смоках (класс `.rhint` отсутствует); `test/i18n-dead-keys`; мутант `state-callout-hidden-under-help` |
|
||||
| 4 | карточка внутри карточки (`fieldset` в Light and glow, Value badge) | плоские блоки `.hpf-block` с подзаголовком | `smoke_device_settings_form` → `noLegacyMarkup` (`fieldset`, `.markerlightgroup`), `badgeBlock`, `neverDisablesGlowBlock` |
|
||||
| 5 | поповер «?» обрезается границей диалога комнаты | подсказка живёт в top layer (Popover API) либо в портале `.overlay-portal` **вне** поверхности диалога; тело формы без своего скроллера — резать нечем | **`smoke_dialog_help_clipping`**: короткое окно, «?» нижней карточки комнаты, подсказка выходит за край скроллера и остаётся hit-test'ируемой во всех точках; четыре ветки — нативный `<dialog>` и `ha-dialog` × Popover и fallback. Ветка `ha-dialog` — заглушка с ловушками настоящей mwc-поверхности (`transform` + `overflow: hidden` + свой скроллер); настоящий `ha-dialog` (#505, загрузка колеса HA-frontend) — отдельная диагностическая приёмка владельца, `demo/capture_summary_panel_505.mjs` как образец |
|
||||
| 6 | белый инпут на тёмной теме у Glow radius | поле набора `.hpf-unit` на токенах темы | `pairs/device-dark.png`; `smoke_device_settings_form` |
|
||||
| 7 | два скролла (тело формы и оболочка) | скроллер один — `.content` в `hp-dialog`; `.body` без `max-height`/`overflow` | фокусные смоки → `singleScroller` / `bodyHasNoOwnScroller` |
|
||||
| 8 | пустое пространство внизу | `.body` без `max-height` и лишнего `padding-bottom` | те же; кадры `pairs/` |
|
||||
| 9 | «Загружаем редактор…» | `editor.loading` → «Загрузка…» / «Loading…» | `src/i18n/*.json` |
|
||||
|
||||
## Принятые адаптации
|
||||
|
||||
Расхождения, которые **не** являются дефектом, потому что продиктованы
|
||||
|
||||
@@ -10496,6 +10496,23 @@ const MUTANT_DEFINITIONS = [
|
||||
replace: " valueBadgePosition: position,\n valueBadgeTouched: false,",
|
||||
}],
|
||||
},
|
||||
{
|
||||
id: 'form-kit-segment-breaks-words',
|
||||
guard: 'node demo/smoke_dialog_segments_i18n.mjs',
|
||||
because: '#600 ревью r1 M1: пять равных колонок сегмента с overflow-wrap: anywhere рвали '
|
||||
+ '«Temperature» посреди слова, и ни один смок этого не видел — scrollWidth контейнера не '
|
||||
+ 'рос. Колонка не сжимается ниже самого длинного слова, слова переносятся только по '
|
||||
+ 'пробелам; вернуть прежние две строки — вернуть дефект в четырёх локалях',
|
||||
patches: [{
|
||||
file: 'src/styles/form-kit.styles.ts',
|
||||
find: ' min-width: fit-content;\n min-height: 38px;\n flex: 1 1 0;',
|
||||
replace: ' min-height: 38px;\n flex: 1 1 0;',
|
||||
}, {
|
||||
file: 'src/styles/form-kit.styles.ts',
|
||||
find: ' text-align: center;\n overflow-wrap: normal;\n }',
|
||||
replace: ' text-align: center;\n overflow-wrap: anywhere;\n }',
|
||||
}],
|
||||
},
|
||||
{
|
||||
id: 'form-kit-segment-drops-radio-semantics',
|
||||
guard: 'node --test test/form-kit.test.mjs',
|
||||
|
||||
@@ -187,7 +187,6 @@ export function renderMarkerDialog(this: HouseplanEditorRuntime): TemplateResult
|
||||
node?.focus();
|
||||
};
|
||||
const bindingProblem = problemFor('marker-binding');
|
||||
const radiusProblem = problemFor('marker-glow-radius');
|
||||
|
||||
// ------------------------------------------------------------ Basics
|
||||
const bindingBanner = bindingStatus?.kind === 'ha_disabled'
|
||||
@@ -565,12 +564,11 @@ export function renderMarkerDialog(this: HouseplanEditorRuntime): TemplateResult
|
||||
${glowValue}
|
||||
${field({
|
||||
label: t('marker.glow_radius_label'), htmlFor: 'marker-glow-radius', help: this._help('marker.glow_radius.help'),
|
||||
error: radiusProblem ? st(radiusProblem.message) : undefined,
|
||||
hint: d.glowRadius.trim() ? undefined : st('marker.glow_radius_empty_hint', { v: `${this.host._glowRadiusPlaceholder} ${unit}` }),
|
||||
control: unitInput({
|
||||
id: 'marker-glow-radius', unit, min: 0.5, step: 0.5, value: d.glowRadius,
|
||||
placeholder: this.host._glowRadiusPlaceholder, ariaLabel: t('marker.glow_radius_label'),
|
||||
disabled: glowSourceDisabled, invalid: !!radiusProblem,
|
||||
disabled: glowSourceDisabled,
|
||||
describedBy: glowSourceDisabled || passiveSource ? 'marker-glow-disabled-hint' : undefined,
|
||||
onInput: (raw) => (this.host._markerDialog = { ...d, glowRadius: raw }),
|
||||
}),
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* в отпечаток не входят. Флаги `*Touched` и `original*` входят: они меняются
|
||||
* только действием человека, и это тоже изменение.
|
||||
*/
|
||||
import { strictNumber } from '../space-dialog';
|
||||
import type { HouseplanEditorHostPort } from '../houseplan-editor-runtime';
|
||||
import { dialogDirty, forgetDialogBaseline, rememberDialogBaseline, stableKey } from './dialog-baseline';
|
||||
|
||||
@@ -34,28 +33,20 @@ export function markerDirty(host: object, d: MarkerDialogDraft): boolean {
|
||||
|
||||
export interface MarkerProblem {
|
||||
field: string;
|
||||
message: 'marker.error_binding' | 'marker.error_glow_radius';
|
||||
}
|
||||
|
||||
/** Радиус: пусто (общий радиус) либо положительное число — тем же парсером, что и запись. */
|
||||
export function glowRadiusValid(raw: string): boolean {
|
||||
if (!raw.trim()) return true;
|
||||
const n = strictNumber(raw);
|
||||
return n !== null && n > 0;
|
||||
message: 'marker.error_binding';
|
||||
}
|
||||
|
||||
/**
|
||||
* Ошибки черновика (§7 референса): привязка обязательна в режиме HA (прежнее
|
||||
* условие Save, теперь названное словами), радиус свечения — положительное число
|
||||
* либо пусто (общий радиус).
|
||||
* Ошибки черновика: привязка обязательна в режиме HA — прежнее условие Save,
|
||||
* теперь названное словами под полем. Радиус свечения ошибкой **не является**
|
||||
* (ревью #600 r1, M2): как и на `dev`, непустое нечисло или неположительное
|
||||
* значение при сохранении молча становится «общим радиусом» (`null`), и К10
|
||||
* закрытым списком других условий не называет.
|
||||
*/
|
||||
export function markerProblems(d: MarkerDialogDraft): MarkerProblem[] {
|
||||
const problems: MarkerProblem[] = [];
|
||||
if (d.bindingMode === 'ha' && (!d.binding || d.binding === 'virtual')) {
|
||||
problems.push({ field: 'marker-binding', message: 'marker.error_binding' });
|
||||
}
|
||||
if (!glowRadiusValid(d.glowRadius)) {
|
||||
problems.push({ field: 'marker-glow-radius', message: 'marker.error_glow_radius' });
|
||||
}
|
||||
return problems;
|
||||
}
|
||||
|
||||
@@ -85,7 +85,6 @@
|
||||
"marker.size.help.aria": "Hilfe: Symbolgröße und Drehung",
|
||||
"marker.size_short": "Größe",
|
||||
"marker.error_binding": "Wählen Sie ein Gerät oder eine Entität zum Verknüpfen.",
|
||||
"marker.error_glow_radius": "Geben Sie einen Radius größer als 0 ein oder lassen Sie das Feld leer.",
|
||||
"room.fill_seg_lqi": "Zigbee",
|
||||
"room.fill_seg_custom": "Eigene"
|
||||
}
|
||||
|
||||
@@ -85,7 +85,6 @@
|
||||
"marker.size.help.aria": "Help: icon size and rotation",
|
||||
"marker.size_short": "Size",
|
||||
"marker.error_binding": "Choose a device or entity to bind.",
|
||||
"marker.error_glow_radius": "Enter a radius greater than 0, or leave it empty.",
|
||||
"room.fill_seg_lqi": "Zigbee",
|
||||
"room.fill_seg_custom": "Custom"
|
||||
}
|
||||
|
||||
@@ -85,7 +85,6 @@
|
||||
"marker.size.help.aria": "Aide : taille et rotation de l’icône",
|
||||
"marker.size_short": "Taille",
|
||||
"marker.error_binding": "Choisissez un appareil ou une entité à lier.",
|
||||
"marker.error_glow_radius": "Saisissez un rayon supérieur à 0 ou laissez le champ vide.",
|
||||
"room.fill_seg_lqi": "Zigbee",
|
||||
"room.fill_seg_custom": "Perso"
|
||||
}
|
||||
|
||||
@@ -85,7 +85,6 @@
|
||||
"marker.size.help.aria": "Справка: размер и поворот иконки",
|
||||
"marker.size_short": "Размер",
|
||||
"marker.error_binding": "Выберите устройство или сущность для привязки.",
|
||||
"marker.error_glow_radius": "Введите радиус больше 0 или оставьте поле пустым.",
|
||||
"room.fill_seg_lqi": "Zigbee",
|
||||
"room.fill_seg_custom": "Свой цвет"
|
||||
}
|
||||
|
||||
@@ -144,6 +144,13 @@ function sharedCss(options: FormKitCssOptions, withSwitch: boolean): string {
|
||||
* Числа — из §3.1 `SPEC.md` референса; цвета — через переменные темы HA, а не
|
||||
* hex прототипа: тёмная тема обязательна. Всё здесь видит только ленивый
|
||||
* редакторский граф — панель эти правила не получает (#597 К9).
|
||||
*
|
||||
* Сегмент (`-seg`): подпись варианта не рвётся посреди слова (ревью #600 r1,
|
||||
* M1 — «Temperatur/e» в пяти колонках). Колонка не сжимается ниже самого
|
||||
* длинного слова (`min-width: fit-content`; браузер без него берёт `0`
|
||||
* строкой выше), слова переносятся только по пробелам (`overflow-wrap:
|
||||
* normal`), а если варианты не помещаются в ряд — сегмент переносится на
|
||||
* вторую строку целыми кнопками (`flex-wrap`), а не ломает текст.
|
||||
*/
|
||||
function extrasCss(options: FormKitCssOptions): string {
|
||||
const { form, prefix, tokens } = options;
|
||||
@@ -285,6 +292,7 @@ function extrasCss(options: FormKitCssOptions): string {
|
||||
.${p}-toggle > input:disabled::before { opacity: .4; }
|
||||
.${p}-seg {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
min-width: 0;
|
||||
gap: 3px;
|
||||
padding: 3px;
|
||||
@@ -296,6 +304,7 @@ function extrasCss(options: FormKitCssOptions): string {
|
||||
position: relative;
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
min-width: fit-content;
|
||||
min-height: 38px;
|
||||
flex: 1 1 0;
|
||||
align-items: center;
|
||||
@@ -309,7 +318,7 @@ function extrasCss(options: FormKitCssOptions): string {
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
overflow-wrap: anywhere;
|
||||
overflow-wrap: normal;
|
||||
}
|
||||
.${p}-seg input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; pointer-events: none; }
|
||||
.${p}-seg label:has(input:checked) {
|
||||
|
||||
+3
-1
@@ -166,6 +166,7 @@
|
||||
.hpf-toggle > input:disabled::before { opacity: .4; }
|
||||
.hpf-seg {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
min-width: 0;
|
||||
gap: 3px;
|
||||
padding: 3px;
|
||||
@@ -177,6 +178,7 @@
|
||||
position: relative;
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
min-width: fit-content;
|
||||
min-height: 38px;
|
||||
flex: 1 1 0;
|
||||
align-items: center;
|
||||
@@ -190,7 +192,7 @@
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
overflow-wrap: anywhere;
|
||||
overflow-wrap: normal;
|
||||
}
|
||||
.hpf-seg input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; pointer-events: none; }
|
||||
.hpf-seg label:has(input:checked) {
|
||||
|
||||
+3
-1
@@ -152,6 +152,7 @@
|
||||
.hpf-toggle > input:disabled::before { opacity: .4; }
|
||||
.hpf-seg {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
min-width: 0;
|
||||
gap: 3px;
|
||||
padding: 3px;
|
||||
@@ -163,6 +164,7 @@
|
||||
position: relative;
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
min-width: fit-content;
|
||||
min-height: 38px;
|
||||
flex: 1 1 0;
|
||||
align-items: center;
|
||||
@@ -176,7 +178,7 @@
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
overflow-wrap: anywhere;
|
||||
overflow-wrap: normal;
|
||||
}
|
||||
.hpf-seg input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; pointer-events: none; }
|
||||
.hpf-seg label:has(input:checked) {
|
||||
|
||||
Reference in New Issue
Block a user